DB zasob ID * [name] => Table name * [opis] => Table opis * [fields] => array( * [$fieldID] => array( * [name] => name * [perms] => perms (FORM_TREAT) * [opis] => opis * ) * ) * [types] => array( * [$fieldID] => array( * [type] => type * [null] => bool * [default] => default value * ) * ) * ); */ class TableAcl extends Core_AclBase { public $_rootTableName = null; public $_zasobID = ''; public $_db = ''; public $_name = ''; public $_label = ''; public $_opis = ''; public $_executed_fieldsInit = null; public $_fields = array(); public $_types = array(); public $_virtualFieldsIdList = array(); public $_schemaLoaded = false; public function __construct($zasobID) { $this->_zasobID = $zasobID; } public function getNamespace() { return 'default_db/' . $this->getName(); } public function getRootNamespace() { return 'default_db/' . $this->getName(); } public function getSourceName() { return 'default_db'; } public function getName() { return $this->_name; } public function getRootTableName() { if (empty($this->_name)) return null;// throw new Exception("Table name not defined"); if ($this->_rootTableName) return $this->_rootTableName; if (!$this->_db) return null;// throw new Exception("Database not defined in table {$this->_zasobID}"); if (DB::getPDO($this->_db)->getZasobId() === DB::getPDO()->getZasobId()) { $dbName = DB::getPDO($this->_db)->getDatabaseName(); $this->_rootTableName = DB::getPDO()->fetchValue(" select t.TABLE_NAME from `information_schema`.`TABLES` t where t.TABLE_SCHEMA = '{$dbName}' and t.TABLE_NAME LIKE '{$this->_name}' "); if (!$this->_rootTableName) return null;// throw new Exception("Table '{$this->_name}' not exists!"); } else { $this->_rootTableName = $this->_name; // TODO: fix for Postgres } DBG::log("TableAcl({$this->_zasobID})->getRootTableName (\$this->_name='{$this->_name}', \$this->_rootTableName='{$this->_rootTableName}')"); if ($this->_rootTableName != $this->_name) { if ($this->_zasobID) { $affected = DB::getPDO()->update('CRM_LISTA_ZASOBOW', 'ID', $this->_zasobID, [ 'DESC' => $this->_rootTableName ]); DBG::log("TableAcl({$this->_zasobID})->getRootTableName fixed zasob table name (\$affected={$affected})"); } $this->_name = $this->_rootTableName; $this->save(); } return $this->_rootTableName; } public function getID() { return $this->_zasobID; } public function getSqlPrimaryKeyField() { return $this->getPrimaryKeyField(); } // TODO: read from root object schema (_rootTableName) public function setName($name) {// TODO: used only by setNameByTableId DBG::log("setName('{$name}')"); $this->_name = $name; } public function setOpis($opis) { $this->_opis = $opis; } public function getOpis() { return $this->_opis; } public function setLabel($label) { $this->_label = $label; } public function getLabel() { return $this->_label; } public function setNameByTableId($tableID) { //used for init without knowing table name $db = DB::getDB(); $sql = "select `DESC` from CRM_LISTA_ZASOBOW where ID={$tableID} and `TYPE`='TABELA'"; $res = $db->query($sql); $res_ = $db->fetch($res); //DEBUG_S(-3,'setNameByTableId',$res_,__FILE__,__FUNCTION__,__LINE__); self::setName($res->DESC); } public function getRawOpis() { $opis = $this->_opis; if (!$opis) return $this->getRawLabel(100); $opis = strip_tags($opis); return $opis; } public function getRawLabel($posLimit = 20) { // TODO: moved to P5Menu $label = $this->_label; if (empty($label) && !empty($this->_opis)) { $label = $this->_opis; if (mb_strlen($this->_opis) > $posLimit) { $pos = strpos($this->_opis, ' - '); if ($pos > $posLimit || $pos < 5) { $pos = $posLimit; $label = mb_substr($this->_opis, 0, $posLimit, 'utf-8') . '...'; } else { $label = mb_substr($this->_opis, 0, $pos, 'utf-8'); } } } if (empty($label)) { $label = $this->_name; } return $label; } public function getShortLabel($posLimit = 20) { $shortLabel = $this->getRawLabel($posLimit); $opis = $this->_opis; $shortLabel = '' . $shortLabel . ''; return $shortLabel; } public function getLongLabel($posLimit = 30) { // TODO: RMME $longLabel = $this->getRawLabel($posLimit); $opis = $this->_opis; if ($longLabel != $this->_name) { $longLabel .= ' ' . $this->_name . ''; } $longLabel = '' . $longLabel . ''; return $longLabel; } public function getLongRawLabel($posLimit = 30) { $longLabel = $this->getRawLabel($posLimit); $opis = $this->_opis; if ($longLabel != $this->_name) { $longLabel .= ' ' . $this->_name; } return $longLabel; } public function setDB($db) { $this->_db = $db; } public function getDB() { return $this->_db; } public function addField($fieldID, $name, $opis, $sort_prio, $label = '') { $field = array(); $field['name'] = $name; $field['perms'] = ''; $field['opis'] = $opis; $field['sort_prio'] = $sort_prio; $field['label'] = $label; $this->_fields[$fieldID] = $field; } public function getTableDbId($tableID) { return $this->_db; } public function getField($fieldID) { return $this->getFields()[$fieldID]; } public function hasFieldById($fieldID) { return array_key_exists($fieldID, $this->getFields()); } public function getFields() { $this->fieldsInit(); $types = $this->_types; return array_map(function ($field) use ($types) { return array_merge($field, [ 'fieldNamespace' => $field['name'], 'isLocal' => array_key_exists($field['name'], $types), ]); }, $this->_fields); } public function setFieldPerms($fieldID, $perms) { if (array_key_exists($fieldID, $this->getFields())) { $this->_fields[$fieldID]['perms'] .= $perms; } } public function getFieldPerms($fieldID) { if (array_key_exists($fieldID, $this->getFields())) { $perms = V::get('perms', '', $this->_fields[$fieldID]); if ($perms) { return implode(',', array_unique(str_split($perms))); } } return ''; } public function hasFieldPerm($fieldID, $perm) {// TODO: legacy if (array_key_exists($fieldID, $this->getFields())) { if (false !== strpos($this->_fields[$fieldID]['perms'], $perm)) { return true; } return false; } return false; } public function getFieldIdByName($fieldName) { $fieldID = 0; if (empty($fieldName)) { return; } foreach ($this->getFields() as $kID => $vField) { if ($vField['name'] == $fieldName) { $fieldID = $kID; } } return $fieldID; } public function hasEditPerms() { foreach ($this->getFields() as $kFldID => $vFld) { if ($this->hasFieldPerm($kFldID, 'W')) return true; if ($this->hasFieldPerm($kFldID, 'C')) return true; if ($this->hasFieldPerm($kFldID, 'S')) return true; } return false; } public function hasSuperAccessPerms() { foreach ($this->getFields() as $kFldID => $vFld) { if ($this->hasFieldPerm($kFldID, 'S')) { return true; } else if ($this->hasFieldPerm($kFldID, 'V')) { return true; } } return false; } public function hasPermSuperWrite() { foreach ($this->getFields() as $kFldID => $vFld) { if ($this->hasFieldPerm($kFldID, 'S')) { return true; } } return false; } /** * @param $taskPerm - 'C', 'W', 'R' */ public function isAllowed($fieldID, $taskPerm, $record = null) {// TODO: legacy - replace with canWriteField, canReadField, canWriteObjectField, canReadObjectField, canCreateField if (!in_array($taskPerm, array('C', 'W', 'R'))) { return false; } $adminFields = array(); $adminFields[] = 'ID'; $adminFields[] = 'A_RECORD_CREATE_DATE'; $adminFields[] = 'A_RECORD_CREATE_AUTHOR'; $adminFields[] = 'A_RECORD_UPDATE_DATE'; $adminFields[] = 'A_RECORD_UPDATE_AUTHOR'; $fieldName = $this->getFields()[$fieldID]['name']; if ($taskPerm == 'R' && in_array($fieldName, $adminFields)) { return true; } // check perm: allow 'RS', 'WS' - can R/W field even if cant read record // check 'O' - can read field even if cant read field but can read record if(V::get('DBG_ACL', '', $_REQUEST) > 1){ echo'
(' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r(array('Field'=>$fieldID.'('.$fieldName.')'
,'taskPerm'=>$taskPerm
,'fieldPerms'=>V::get('perms', null, V::get($fieldID, null, $this->_fields))
,'canReadRecord'=>'"'.$this->canReadRecord($record).'"'
,'hasFieldPerm(O) || canWriteRecord'=>'"'.$this->hasFieldPerm($fieldID, 'O').'" || "'.$this->canReadRecord($record).'"'
,'hasFieldPerm(S)'=>'"'.$this->hasFieldPerm($fieldID, 'S').'"'
,'hasFieldPerm(V)'=>'"'.$this->hasFieldPerm($fieldID, 'V').'"'
));echo''; }
if (!$this->hasFieldPerm($fieldID, $taskPerm)) {
if ($taskPerm == 'R' && $this->hasFieldPerm($fieldID, 'V')) {
return true;
} else if ($taskPerm == 'R'
&& $record
&& $this->hasFieldPerm($fieldID, 'O')
&& ($this->canReadRecord($record) || $this->canWriteRecord($record))
) {
return true;// 'WO' or 'CO'
}
return false;
}
// check 'R' - require can read record, or V - Super View
if ($taskPerm == 'R') {
if ($this->canReadRecord($record) || $this->hasFieldPerm($fieldID, 'V')) {
return true;
} else {
return false;
}
}
// 'C' and 'W' require colType
$colType = $this->getFieldTypeById($fieldID);
if (!$colType) {
return false;
}
if ($taskPerm == 'W') {
if ($record) {
if(V::get('DBG_ACL', '', $_REQUEST) > 1){echo '(Field: '.$fieldID.', canWriteRecord: ' . $this->canWriteRecord($record) . ' || (hasFieldPerm(S): ' . $this->hasFieldPerm($fieldID, 'S') . ' && hasFieldPerm(W): ' . $this->hasFieldPerm($fieldID, 'W') . '))';}
return ($this->canWriteRecord($record)|| $this->hasFieldPerm($fieldID, 'S'));
}
}
return true;
}
public function canCreateField($fieldName) {
$idZasob = $this->getFieldIdByName($fieldName);
return ($idZasob && $this->hasFieldPerm($idZasob, $taskPerm = 'C'));
}
public function canReadField($fieldName) {
$idZasob = $this->getFieldIdByName($fieldName);
// DBG::log($this->_fields[$idZasob], 'array', "canReadField({$fieldName})");
if (!$idZasob) return false;
if ('ID' == $fieldName) return true;
if ('A_RECORD_CREATE_DATE' == $fieldName) return true;
if ('A_RECORD_CREATE_AUTHOR' == $fieldName) return true;
if ('A_RECORD_UPDATE_DATE' == $fieldName) return true;
if ('A_RECORD_UPDATE_AUTHOR' == $fieldName) return true;
if ($this->hasFieldPerm($idZasob, $taskPerm = 'R')) return true;
if ($this->hasFieldPerm($idZasob, $taskPerm = 'V')) return true;
if ($this->hasFieldPerm($idZasob, $taskPerm = 'O')) return true; // TODO: has 'O' ? @see canReadObjectField
return false;
}
public function canReadObjectField($fieldName, $record) {
// if (!$this->canReadField($fieldName)) return false;
if ('ID' == $fieldName) return true;
if ('A_RECORD_CREATE_DATE' == $fieldName) return true;
if ('A_RECORD_CREATE_AUTHOR' == $fieldName) return true;
if ('A_RECORD_UPDATE_DATE' == $fieldName) return true;
if ('A_RECORD_UPDATE_AUTHOR' == $fieldName) return true;
if (!$record) {
if(V::get('DBG_ACL', '', $_REQUEST) > 2){echo'canReadObjectField('.$fieldName.', $record) - record not set - return false (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): '.var_export($record, true).'';}
return false;
}
$idZasob = $this->getFieldIdByName($fieldName);
if (!$idZasob) {
if(V::get('DBG_ACL', '', $_REQUEST) > 2){echo'canReadObjectField('.$fieldName.', $record) - $idZasob not set - return false (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): '.var_export($record, true).'';}
return false;
}
if (!$this->hasFieldPerm($idZasob, $taskPerm = 'R')) {
if ($this->hasFieldPerm($idZasob, 'V')) return true;
return ($this->hasFieldPerm($idZasob, 'O') && ($this->canReadRecord($record) || $this->canWriteRecord($record)));// 'WO' or 'CO'
}
return ($this->canReadRecord($record) || $this->hasFieldPerm($idZasob, 'V'));// 'R' require
}
public function canWriteField($fieldName) {
$idZasob = $this->getFieldIdByName($fieldName);
if (!$idZasob) return false;
return $this->hasFieldPerm($idZasob, $taskPerm = 'W');
}
public function canWriteObjectField($fieldName, $record) {
if (!$this->canWriteField($fieldName)) return false;
$idZasob = $this->getFieldIdByName($fieldName);
if (!$idZasob) return false;
if(V::get('DBG_ACL', '', $_REQUEST) > 1){echo '(Field: "'.$fieldName.'" ['.$idZasob.'], canWriteRecord: ' . $this->canWriteRecord($record) . ' || (hasFieldPerm(S): ' . $this->hasFieldPerm($idZasob, 'S') . ' && hasFieldPerm(W): ' . $this->hasFieldPerm($idZasob, 'W') . '))';}
return ($this->canWriteRecord($record) || $this->hasFieldPerm($idZasob, 'S'));
}
/**
* @param $taskPerm - 'C', 'W'
*/
public function getFormItem($taskPerm, $fieldID, $fName, $fValue, $params = array(), $record = null) {
$out = '';
if (!$this->isAllowed($fieldID, $taskPerm, $record)) {
if ($taskPerm == 'R') throw new Exception("Brak uprawnień do odczytu");
else if ($taskPerm == 'W') throw new Exception("Brak uprawnień do zapisu");
else throw new Exception("Brak uprawnień do tego pola ({$taskPerm})");
}
$colName = $this->getFields()[$fieldID]['name'];
if ($colName == 'ID') return;
$colType = $this->getFieldTypeById($fieldID);
if (!$colType) throw new Exception("Error - unknown type");
$item = array();
$item['htmlType'] = '';
$item['value'] = $fValue;
$item['canRead'] = $this->isAllowed($fieldID, 'R', $record);
$item['canWrite'] = $this->isAllowed($fieldID, 'W', $record);
$item['rawColType'] = $colType;
return $item;
$html = new stdClass();
$html->_params = array();
$html->tag = 'input';
$html->cnt = '';
$html->attrs = array();
$html->attrs['id'] = $fName;
$html->attrs['name'] = $fName;
$html->attrs['type'] = 'text';
$html->attrs['value'] = htmlspecialchars($fValue);
if (isset($params['tabindex'])) {
$html->attrs['tabindex'] = $params['tabindex'];
}
if (!$this->hasFieldPerm($fieldID, $taskPerm)) {
$html->attrs['disabled'] = 'disabled';
}
$maxGrid = V::get('maxGrid', 10, $params);
if (substr($colType['type'], 0, 3) == 'int'
|| substr($colType['type'], 0, 7) == 'tinyint'
|| substr($colType['type'], 0, 8) == 'smallint'
|| substr($colType['type'], 0, 6) == 'bigint'
) {
//$h->Type_value = (int)str_replace(array(' ','(',')'), '', substr($h->Type, 4));
$html->attrs['type'] = 'number';
$html->attrs['class'][] = 'input-small';
}
else if (substr($colType['type'], 0, 6) == 'double') {
$html->attrs['type'] = 'text';
$html->attrs['class'][] = 'input-small';
}
else if (substr($colType['type'], 0, 7) == 'decimal') {
$html->attrs['type'] = 'text';
$html->attrs['class'][] = 'input-small';
}
else if (substr($colType['type'], 0, 7) == 'varchar'
|| substr($colType['type'], 0, 4) == 'char'
) {
//$h->Type_value = (int)str_replace(array(' ','(',')'), '', substr($h->Type, 8));
$html->attrs['type'] = 'text';
$maxLength = (int)str_replace(array(' ','(',')'), '', substr($colType['type'], strpos($colType['type'], '(') + 1, -1));
if ($maxLength > 0) {
$html->attrs['maxlength'] = $maxLength;
}
$valLength = strlen($fValue);
if (isset($params['widthClass'])) {
if ($params['widthClass'] == 'inside-modal') {
$html->attrs['style'] = 'width:98%;';
} else {
$html->attrs['style'] = 'width:98%;';
}
} else {
/*
if ($maxLength < 11) {
$html->attrs['class'][] = 'span2';
} else if ($maxLength < 31) {
$html->attrs['class'][] = 'span5';
} else if ($maxLength < 51) {
$html->attrs['class'][] = (8 <= $maxGrid)? 'span8' : "span{$maxGrid}";
} else if ($maxLength < 101) {
$html->attrs['class'][] = (10 <= $maxGrid)? 'span10' : "span{$maxGrid}";
} else {
$html->attrs['class'][] = (12 <= $maxGrid)? 'span12' : "span{$maxGrid}";
}
*/
}
if ($maxLength > 255) {// Fix for long varchar - use textarea
$html->tag = 'textarea';
$html->cnt = htmlspecialchars($fValue);
$html->attrs['rows'] = '3';
unset($html->attrs['type']);
unset($html->attrs['value']);
}
}
else if (substr($colType['type'], 0, 4) == 'date') {
$testDatePicker = true;
if ($testDatePicker) {
$html->attrs['type'] = 'text';
$html->_params[] = 'date';
if (substr($colType['type'], 0, 8) == 'datetime') {
$html->attrs['class'][] = 'se_type-datetime';// datetimepicker';
$html->attrs['data-format'] = 'yyyy-MM-dd hh:mm';
$html->attrs['maxlength'] = 19;
} else {
$html->attrs['class'][] = 'se_type-date';// datetimepicker';
$html->attrs['maxlength'] = 10;
}
if (substr($html->attrs['value'], 0, 10) == '0000-00-00') {
$html->attrs['value'] = '';
}
} else {
$html->attrs['type'] = 'date';
}
}
else if ($colType['type'] == 'time') {
$testDatePicker = true;
if ($testDatePicker) {
$html->attrs['type'] = 'text';
$html->_params[] = 'time';
$html->attrs['class'][] = 'se_type-time';// datetimepicker';
$html->attrs['data-format'] = 'hh:mm:ss';
$html->attrs['maxlength'] = 8;
if (substr($html->attrs['value'], 0, 8) == '00:00:00') {
$html->attrs['value'] = '';
}
} else {
$html->attrs['type'] = 'time';
}
}
else if ($colType['type'] == 'timestamp') {
$testDatePicker = true;
if ($testDatePicker) {
$html->attrs['type'] = 'text';
$html->_params[] = 'date';
$html->attrs['class'][] = 'se_type-datetime';// datetimepicker';
$html->attrs['data-format'] = 'yyyy-MM-dd hh:mm';
$html->attrs['maxlength'] = 19;
if (substr($html->attrs['value'], 0, 10) == '0000-00-00') {
$html->attrs['value'] = '';
}
} else {
$html->attrs['type'] = 'date';
}
}
else if (substr($colType['type'], 0, 4) == 'enum') {
unset($html->attrs['type']);
unset($html->attrs['value']);
$html->tag = 'select';
$values = explode(',', str_replace(array('(',')',"'",'"'), '', substr($colType['type'], 5)));
$selValue = $fValue;
if (empty($selValue) && $selValue !== '0' && !empty($colType['default'])) {
if ($taskPerm == 'C') {
$selValue = $colType['default'];
} else if ($taskPerm == 'W' && $this->isAllowed($fieldID, 'R', $record)) {
$selValue = $colType['default'];
}
}
$html->cnt .= '';
if (!empty($selValue) && !in_array($selValue, $values)) {
$html->cnt .= '';
}
foreach ($values as $val) {
$sel = ($selValue == $val)? ' selected="selected"' : '';
$html->cnt .= '';
}
}
else if (substr($colType['type'], 0, 4) == 'text'
|| substr($colType['type'], 0, 8) == 'tinytext'
|| substr($colType['type'], 0, 10) == 'mediumtext'
|| substr($colType['type'], 0, 8) == 'longtext'
) {
$html->tag = 'textarea';
$html->cnt = htmlspecialchars($fValue);
if (isset($params['widthClass'])) {
if ($params['widthClass'] == 'inside-modal') {
$html->attrs['style'] = 'width:98%;';
} else {
$html->attrs['style'] = 'width:98%;';
}
} else {
//$html->attrs['class'][] = (8 <= $maxGrid)? 'span8' : "span{$maxGrid}";
}
$html->attrs['rows'] = '3';
unset($html->attrs['type']);
unset($html->attrs['value']);
}
else if ('polygon' == $colType['type']) { return '...'; }// Wielokąt
else if ('multipolygon' == $colType['type']) { return '...'; }// Zbiór wielokątów
else if ('linestring' == $colType['type']) { return '...'; }// Krzywa z interpolacji liniowej pomiędzy punktami
else if ('point' == $colType['type']) { return '...'; }// Punkt w przestrzeni 2-wymiarowej
else if ('geometry' == $colType['type']) { return '...'; }// Typy, które mogą przechowywać geometrię dowolnego typu
else if ('multipoint' == $colType['type']) { return '...'; }// Zbiór punktów
else if ('multilinestring' == $colType['type']) { return '...'; }// Zbiór krzywych z interpolacji liniowej pomiędzy punktami
else if ('geometrycollection' == $colType['type']) { return '...'; }// Zbiór obiektów geometrycznych dowolnego typu
else throw new Exception("unknown Type '{$colType['type']}'");
$html->attrs['class'][] = 'form-control';
$attrsOut = array();
foreach ($html->attrs as $k => $v) {
if (is_array($v)) $v = implode(' ', $v);
$attrsOut[] = "{$k}=\"{$v}\"";
}
if (in_array($html->tag, array('select', 'textarea'))) {
$out .= '<' . $html->tag . '' . (($attrsOut)? ' ' . implode(' ', $attrsOut) : '') . '>';
$out .= $html->cnt;
$out .= '' . $html->tag . '>';
} else {
$out .= '<' . $html->tag . '' . (($attrsOut)? ' ' . implode(' ', $attrsOut) : '') . ' />';
}
if (in_array('date', $html->_params)) {
$out = '$userPermsForTable('.$idTable.') ';print_r($userPermsForTable);echo'';
// if(0){// TODO: from UserAcl big query
// $foundTbls[$r->ZASOB_PARENT_ID]->addField($r->ID_ZASOB, $r->ZASOB_DESC, $r->ZASOB_OPIS, $r->z__SORT_PRIO, $r->ZASOB_DESC_PL);
// $foundTbls[$r->ZASOB_PARENT_ID]->setFieldPerms($r->ID_ZASOB, $r->FORM_TREAT);
// $tableConfig['fields'];// $this->getFields()
// $tableConfig['virtualFieldsIdList'];// $this->_virtualFieldsIdList
// //$tableConfig['types'];// $this->_types
// }
// }
if (empty($tableConfig)) throw new Exception("Brak danych konfiguracyjnych do tabeli nr {$idTable} #TACL" . __LINE__);
$type = (false !== strpos($tableConfig['name'], '/')) ? 'AntAcl' : 'TableAcl'; // TODO: fix naive check this // $type = DB::getPDO()->fetchValue(" select o._type from `CRM_#CACHE_ACL_OBJECT` o where o.idZasob = '{$idTable}' limit 1 ");
if ('AntAcl' === $type) {
DBG::log("AntAcl save config in TableAcl::buildInstance [{$idTable}] '{$tableConfig['name']}'");
$_SESSION['AntAcl_cache'][$idTable] = true;
} else { // TableAcl
$obj = new TableAcl($idTable);
$obj->fromArray($tableConfig);
$obj->getRootTableName();
$obj->save();
}
$_cache[$idTable] = $obj;
return $_cache[$idTable];
}
public function loadSchema() {
if ($this->_schemaLoaded) return (bool)$this->_schemaClass;
$srvName = $_SERVER['SERVER_NAME'];
$this->_schemaClass = Schema_TableFactory::build($this->_name, $this->_db, $srvName);
$this->_schemaLoaded = true;
return (bool)$this->_schemaClass;
}
public function getLocalFieldList() {
$this->getFields();
return array_keys($this->_types);
}
public function isLocalField($fieldName) {
$this->getFields();
return array_key_exists($fieldName, $this->_types);
}
public function init($force = false) {
// DBG::log("DBG INIT - init ({$this->_zasobID}, {$this->_rootTableName})");
}
public function fieldsInit($force = false) {
$this->loadSchema();
// DBG::log("TableAcl({$this->_rootTableName}) fieldsInit() isDone: '{$this->_executed_fieldsInit}'");
if (null !== $this->_executed_fieldsInit) return;
$this->_executed_fieldsInit = true;
DBG::log("DBG INIT - fieldsInit ({$this->_zasobID}, {$this->_rootTableName})");
if (empty($this->_fields)) {
$this->_types = array();// clear _types @see $this->isInitialized
$userAcl = User::getAcl();
$fieldsConfig = $userAcl->getPermsForTable($this->_zasobID);
// DBG::log($fieldsConfig, 'array', "INIT({$this->_zasobID})::initFieldsFromConfig \$fieldsConfig");
$this->initFieldsFromConfig($fieldsConfig);
//DBG::_('DBG_SCH', '1', "INIT::\$fieldsConfig({$this->_zasobID}) fields(".count($this->_fields).")", $this, __CLASS__, __FUNCTION__, __LINE__ );
}
if ($this->isInitialized() && $force == false) {
return;
}
DBG::simpleLog('auth', "TableAcl::init(name: '{$this->_name}')");
// DBG::log(['$this'=>$this, 'name'=>$this->getName()], 'array', "INIT({$this->_zasobID}):: \$this");
$ds = $this->getDataSource();
// DBG::log($ds, 'array', "INIT({$this->_zasobID})::getDataSource \$ds");
$this->_types = (is_object($this->_schemaClass) && method_exists($this->_schemaClass, 'getLegacyFieldTypes'))
? $this->_schemaClass->getLegacyFieldTypes()
: $ds->getFieldTypes();
// DBG::log($this->_types, 'array', "INIT({$this->_zasobID})::getFieldTypes \$this->_types");
uasort($this->_fields, array($this, 'sortFieldsCallback'));
$this->_fixTypes();
// DBG::log($this->_types, 'array', "INIT({$this->_zasobID})::after fixTypes \$this->_types");
$this->save();
}
public function _fixTypes() {
$this->_fixDateFields();
$this->_sortEnumFields();
$this->_fixProjectType();
if ($this->loadSchema()) $this->_types = $this->_schemaClass->fixTypes($this->_types);
//DBG::_(true, true, "this->_types", $this->_types, __CLASS__, __FUNCTION__, __LINE__);
// fixGeomTypesFromSimpleType
foreach ($this->_types as $fieldName => $field) {
// [the_geom] => Array(
// [type] => geometry
// [null] => 1
// [default] =>
// [simpleType] => linestring
if ('geometry' == $field['type']) {
if (!empty($field['simpleType'])) {
switch ($field['simpleType']) {
case 'gml:LineStringPropertyType': $this->_types[ $fieldName ][ 'type' ] = 'linestring'; break;
}
}
$dbName = DB::getPDO()->getDatabaseName();
$tableName = $this->getName();
$geomType = DB::getPDO()->fetchValue("
select DATA_TYPE
from `information_schema`.`COLUMNS`
where TABLE_SCHEMA='{$dbName}'
and TABLE_NAME='{$tableName}'
and COLUMN_NAME='{$fieldName}'
");
if (!empty($geomType)) $this->_types[ $fieldName ][ 'type' ] = $geomType;
}
}
{// TODO: replace this by $this->_schemaClass (from DataSourceFactory::build(...))
$fieldIds = array_keys($this->_fields);
$vColsIdList = Typespecial::initFields($fieldIds);
if (!empty($vColsIdList)) {
$this->_virtualFieldsIdList = $vColsIdList;
}
}
}
public function initFieldsFromConfig($fieldsConfig) {
foreach ($fieldsConfig as $idField => $vFieldConfig) {
if ((int)$idField <= 0) {
DBG::_('DBG_SCH', '1', "BUG key must be integer - skipping '{$idField}'", $vFieldConfig, __CLASS__, __FUNCTION__, __LINE__ );
trigger_error("BUG " . __CLASS__ . "->" . __FUNCTION__ . "(\$fieldsConfig) key must be integer - skipping '{$idField}'", E_USER_NOTICE);
continue;
}
//echo'INIT::$permField('.$vFieldConfig->ID_CELL.') hasFld('.$this->hasFieldById($vFieldConfig->ID_CELL).') ';echo'';
if (!$this->hasFieldById($vFieldConfig['ID_CELL'])) {
//echo'INIT::$permField('.$vFieldConfig['ID_CELL'].') addFld('.$vFieldConfig['ID_CELL'] . ', ' . $vFieldConfig['CELL_NAME'] . ', ' . $vFieldConfig['CELL_DESC'] . ', ' . $vFieldConfig['SORT_PRIO'] . ', ' . $vFieldConfig['CELL_LABEL'].') ';echo'';
$this->addField($vFieldConfig['ID_CELL'], $vFieldConfig['CELL_NAME'], $vFieldConfig['CELL_DESC'], $vFieldConfig['SORT_PRIO'], $vFieldConfig['CELL_LABEL']);
}
//echo'INIT::$permField('.$vFieldConfig['ID_CELL'].') hasFld('.$this->hasFieldById($vFieldConfig['ID_CELL']).') ';echo'';
if (!isset($vFieldConfig['FORM_TREAT'])) {// TODO: convert to legacy perms
$vFieldConfig['FORM_TREAT'] = '';
if ($vFieldConfig['PERM_R'] > 0) $vFieldConfig['FORM_TREAT'] .= 'R';
if ($vFieldConfig['PERM_W'] > 0) $vFieldConfig['FORM_TREAT'] .= 'W';
if ($vFieldConfig['PERM_X'] > 0) $vFieldConfig['FORM_TREAT'] .= 'X';
if ($vFieldConfig['PERM_C'] > 0) $vFieldConfig['FORM_TREAT'] .= 'C';
if ($vFieldConfig['PERM_S'] > 0) $vFieldConfig['FORM_TREAT'] .= 'S';
if ($vFieldConfig['PERM_O'] > 0) $vFieldConfig['FORM_TREAT'] .= 'O';
if ($vFieldConfig['PERM_V'] > 0) $vFieldConfig['FORM_TREAT'] .= 'V';
if ($vFieldConfig['PERM_E'] > 0) $vFieldConfig['FORM_TREAT'] .= 'E';
}
//echo'INIT::$permField('.$vFieldConfig['ID_CELL'].') ';print_r($vFieldConfig);echo'';
if (!empty($vFieldConfig['FORM_TREAT'])) {
$this->setFieldPerms($vFieldConfig['ID_CELL'], $vFieldConfig['FORM_TREAT']);
}
}
}
private function _fixProjectType() {
$tblName = $this->getName();
$fldName = 'M_DIST_TYPE';
if ($tblName == 'IN7_MK_BAZA_DYSTRYBUCJI') {
foreach ($this->_fields as $kFldId => $vFld) {
if ($vFld['name'] == $fldName) {
$sqlTypes = array();
if (!empty($this->_types[$fldName])) {
if (substr($this->_types[$fldName]['type'], 0, 4) == 'enum') {
$sqlTypes = explode(',', str_replace(array('(',')',"'",'"'), '', substr($this->_types[$fldName]['type'], 5)));
}
}
if (!empty($sqlTypes)) {
$allowedTypes = array();
$db = DB::getDB();
$sql = "select z.DESC
from `CRM_LISTA_ZASOBOW` as z
where z.`A_STATUS`='NORMAL'
and z.`PARENT_ID`={$kFldId}
order by z.`DESC` asc
";
$res = $db->query($sql);
while ($r = $db->fetch($res)) {
if (in_array($r->DESC, $sqlTypes)) {
$allowedTypes[] = $r->DESC;
}
}
sort($allowedTypes);
if (!empty($allowedTypes)) {
$this->_types[$fldName]['type'] = "enum('" . implode("','", $allowedTypes) . "')";
}
}
}
}
}
}
private function _sortEnumFields() {
foreach ($this->_fields as $kFldId => $vFld) {
$type = $this->getFieldTypeById($kFldId);
if (!empty($type['type'])) {
if (substr($type['type'], 0, 4) == 'enum') {
$sqlTypes = explode(',', str_replace(array('(',')',"'",'"'), '', substr($type['type'], 5)));
if (!empty($sqlTypes)) {
sort($sqlTypes);
$this->_types[$vFld['name']]['type'] = "enum('" . implode("','", $sqlTypes) . "')";
}
}
}
}
}
private function _fixDateFields() {
foreach ($this->_types as $kFldName => $vType) {
if ($kFldName == 'L_APPOITMENT_DATE') {
$this->_types[$kFldName]['type'] = 'datetime';
} else if ($kFldName == 'A_PROBLEM_DATE') {
$this->_types[$kFldName]['type'] = 'datetime';
}
}
}
public function getUniqueKeys() {// TODO: RM NOT USED?
$sqlKeys = array();
$dbID = $this->getDB();
$tblName = $this->getName();
$db = DB::getDB($dbID);
if (!$db) {
die('Error - Brak konfiguracji dla bazy danych ID=' . $dbID);
}
$sql = "SHOW KEYS FROM `{$tblName}`";
$res = $db->query($sql);
while ($r = $db->fetch($res)) {
if ($r->Non_unique == '0') {
$sqlKeys[$r->Column_name] = true;
}
}
$sqlKeys = array_keys($sqlKeys);
return $sqlKeys;
}
public function sortFieldsCallback($a, $b) {
if ($a['name'] == 'ID') {
return -1;
}
else if ($b['name'] == 'ID') {
return 1;
}
else if ($a['sort_prio'] < $b['sort_prio']) {
return -1;
}
else if ($a['sort_prio'] > $b['sort_prio']) {
return 1;
}
else {
return 0;
}
}
public function isInitialized() {
return (!empty($this->_types));
}
/**
* Save data in session cache.
*/
function save() {
$_SESSION['TableAcl_cache'][$this->_zasobID] = $this->toArray();
// DBG::log("save(name='{$_SESSION['TableAcl_cache'][$this->_zasobID]['name']}')");
// DBG::simpleLog('auth', "TableAcl::save(name: '{$this->_name}')");
}
public function getFieldTypeById($fieldID) {
if (!array_key_exists($fieldID, $this->getFields())) return null;
$fieldName = $this->_fields[$fieldID]['name'];
if (!array_key_exists($fieldName, $this->_types)) return null;
return $this->_types[$fieldName];
}
public function getFieldType($fieldName) {
if (!array_key_exists($fieldName, $this->_types)) return null;
return $this->_types[$fieldName];
}
public function hasFieldType($fieldName) {
return (array_key_exists($fieldName, $this->_types));
}
public function getVisibleFieldList() { return $this->getVisibleFieldListByIdZasob(); }
public function getVisibleFieldListByIdZasob() {
$primaryKeyField = $this->getSqlPrimaryKeyField();
$cols = array();
$id = 0;
foreach ($this->getFields() as $kFieldID => $vField) {
if ($vField['name'] == $primaryKeyField) {
$id = $kFieldID;
}
}
$cols[$id] = $primaryKeyField;
foreach ($this->getFields() as $kFieldID => $vField) {
if ($vField['name'] == $primaryKeyField) {
continue;
}
$cols[$kFieldID] = $vField['name'];
}
return $cols;
}
public function getExportFieldList() {
$cols = array();
$realFlds = $this->getRealFieldList();
foreach ($realFlds as $vFieldName) {
$fldId = $this->getFieldIdByName($vFieldName);
if ($fldId > 0 && $this->hasFieldPerm($fldId, 'E')) {
$cols[] = $vFieldName;
}
}
return $cols;
}
/**
* List of real fields in database.
*/
public function getRealFieldList() {
$cols = array();
$cols[] = 'ID';
foreach ($this->getFields() as $kFieldID => $vField) {
if ($vField['name'] == 'ID') {
continue;
}
if (array_key_exists($vField['name'], $this->_types)) {
$cols[] = $vField['name'];
}
}
return $cols;
}
public function getFieldListByIdZasob() {
$cols = array();
foreach ($this->getFields() as $idField => $fld) {
if ($fld['name'] == 'ID') {
$cols[$idField] = 'ID';
}
}
foreach ($this->getFields() as $idField => $fld) {
if ($fld['name'] == 'ID') continue;
$cols[$idField] = $fld['name'];
}
return $cols;
}
public function getRealFieldListByIdZasob() {
$cols = array();
foreach ($this->getFields() as $idField => $fld) {
if ($fld['name'] == 'ID') {
$cols[$idField] = 'ID';
}
}
foreach ($this->getFields() as $idField => $fld) {
if ($fld['name'] == 'ID') continue;
if (array_key_exists($fld['name'], $this->_types)) {
$cols[$idField] = $fld['name'];
}
}
return $cols;
}
public function getVirtualFieldListByIdZasob() {
$cols = array();
foreach ($this->getFields() as $kFieldID => $vField) {
if ($vField['name'] == 'ID') {
continue;
}
if (in_array($kFieldID, $this->_virtualFieldsIdList)) {
$cols[$kFieldID] = $vField['name'];
}
else if (!array_key_exists($vField['name'], $this->_types)) {
$cols[$kFieldID] = $vField['name'];
}
}
return $cols;
}
public function getFieldLabel($fieldName) {
$idField = $this->getFieldIdByName($fieldName);
if (array_key_exists($idField, $this->getFields())) {
if (!empty($this->_fields[$idField]['label'])) {
return $this->_fields[$idField]['label'];
}
}
return null;
}
public function getFieldOpis($fieldName) {
$idField = $this->getFieldIdByName($fieldName);
if (array_key_exists($idField, $this->getFields())) {
if (!empty($this->_fields[$idField]['opis'])) {
return $this->_fields[$idField]['opis'];
}
}
return null;
}
public function getTypes() {
return $this->_types;
}
public function fixEmptyValueFromUser($fieldID) {
$value = '';
$type = $this->getFieldTypeById($fieldID);
if ($type) {
if ($type['type'] == 'date') {
$value = $type['default'];
}
if (substr($type['type'], 0, 3) == 'int'
|| substr($type['type'], 0, 7) == 'tinyint'
|| substr($type['type'], 0, 8) == 'smallint'
|| substr($type['type'], 0, 6) == 'bigint'
) {
$value = intval($type['default']);
}
// fix bug when field is unique and is null allowed: change empty string to null
if ($type['null']) {
$value = 'NULL';
}
// fix bug when field is enum and is set to '0': for php '0' is empty
if (substr($type['type'], 0, 4) == 'enum') {// && $args["f{$fieldID}"] === '0') {
if (false !== strpos($type['type'], "''")) {
// enum('', '1','2')
$value = '';
} else if (false !== strpos($type['type'], "'0'")) {
// enum('0', '1','2')
$value = '0';
} else {
$value = $type['default'];
}
}
}
return $value;
}
public function fromArray($arr) {
// DBG::log("fromArray(name='{$arr['name']}')");
$this->_db = $arr['db'];
$this->_name = $arr['name'];
$this->_rootTableName = V::get('_rootTableName', null, $arr);
$this->_label = $arr['label'];
$this->_opis = $arr['opis'];
$this->_executed_fieldsInit = null; // V::get('_executed_fieldsInit', null, $arr);
$this->_fields = V::get('fields', array(), $arr);
$this->_virtualFieldsIdList = V::get('virtualFieldsIdList', array(), $arr);
$this->_types = V::get('types', array(), $arr);
}
public function toArray() {
$arr = array();
$arr['db'] = $this->_db;
$arr['name'] = $this->_name;
$arr['_rootTableName'] = $this->_rootTableName;
$arr['label'] = $this->_label;
$arr['opis'] = $this->_opis;
// if ($this->_executed_fieldsInit) $arr['_executed_fieldsInit'] = $this->_executed_fieldsInit;
$arr['fields'] = $this->_fields;
$arr['virtualFieldsIdList'] = $this->_virtualFieldsIdList;
$arr['types'] = $this->_types;
return $arr;
}
public function convertObjectFromUserInput($userItem, $type = 'array_by_id', $prefix = 'f') {// TODO: rename / Legacy
$item = $this->parseUserItem($userItem, $type = 'array_by_id', $prefix = 'f');
foreach ($item as $fieldName => $value) {
$item[$fieldName] = $this->validateAndFixField($fieldName, $value);
}
DBG::log(['userItem' => $userItem, 'item' => $item], '', "after parseUserItem, validateAndFixField");
return $item;
}
public function parseUserItem($userItem, $type = 'array_by_id', $prefix = 'f') {
$item = [];
foreach ($this->getFieldsMap() as $userKey => $fieldName) {
if (!array_key_exists("f{$userKey}", $userItem)) continue;
$item[$fieldName] = $userItem["f{$userKey}"];
}
return $item;
}
public function getFieldsMap() {// [ $userKey => $fieldName ] // TODO: $this->_fieldsMap
$fieldsMap = [];
foreach ($this->getFields() as $id => $field) $fieldsMap[ $id ] = $field['name'];
return $fieldsMap;
}
public function validateAndFixField($fieldName, $value) {
if (empty($value) && 0 === strlen($value)) {// TODO: fixEmptyValueFromUser
return $this->fixFieldEmptyValue($fieldName);
}
$xsdType = $this->getXsdFieldType($fieldName);
switch ($xsdType) {
case 'xsd:decimal': {
return str_replace([',', ' '], ['.', ''], $value);
} break;
case 'p5:price': {
return V::convert($value, 'price');
} break;
}
return $value;
}
public function fixFieldEmptyValue($fieldName) {// TODO: legacy
$value = '';
$type = $this->getFieldType($fieldName);
if (!$type) return '';
if ('date' == $type['type']) {
$value = $type['default'];
}
if (substr($type['type'], 0, 3) == 'int'
|| substr($type['type'], 0, 7) == 'tinyint'
|| substr($type['type'], 0, 8) == 'smallint'
|| substr($type['type'], 0, 6) == 'bigint'
) {
$value = intval($type['default']);
}
// fix bug when field is unique and is null allowed: change empty string to null
if ($type['null']) {
$value = 'NULL';
}
// fix bug when field is enum and is set to '0': for php '0' is empty
if (substr($type['type'], 0, 4) == 'enum') {// && $args["f{$fieldID}"] === '0') {
// if (false !== strpos($type['type'], "''")) {
// // enum('', '1','2')
// $value = '';
// } else if (false !== strpos($type['type'], "'0'")) {
// // enum('0', '1','2')
// $value = '0';
// } else {
$value = $type['default'];
// }
}
return $value;
}
public function buildQuery($params = []) {
Lib::loadClass('AclQueryFeatures');
return new AclQueryFeatures($this, $params);
}
public function getItem($primaryKey, $params = []) {
$ds = $this->getDataSource();
return $ds->getItem($primaryKey);
}
public function prepareQuery($params = array()) {
DBG::log($params, 'array', 'TableAcl->prepareQuery $params');
$ds = $this->getDataSource();
$filtrIsInstance = []; // TODO: read instances from $params
$filtrIsNotInstance = [];
Lib::loadClass('ACL');
return ACL::query($this)
->isInstance($filtrIsInstance)
->isNotInstance($filtrIsNotInstance)
->whereRaw($ds->_parseSqlWhere($params));
}
public function getItems($params = array()) {
$orderBy = V::get('order_by', '', $params);
$orderDir = V::get('order_dir', '', $params);
$sortBy = (!empty($orderBy))
? ( !empty($orderDir) ? "{$orderBy} {$orderDir}" : $orderBy )
: '';
$limit = V::get('limit', 10, $params, 'int');
$offset = V::get('limitstart', 0, $params, 'int');
$ds = $this->getDataSource();
return $this->prepareQuery($params)
->select([
'rawSelect' => $ds->_getSqlCols()
])
->select(!empty($params['@instances']) ? '@instances' : '')
->limit($limit)
->offset($offset)
->orderBy($sortBy)
->fetchAll();
}
public function getTotal($params = array()) {
return $this->prepareQuery($params)
->select([ 'rawSelect' => "count(1) as cnt" ])
->fetchValue();
}
public function getFieldDefaultValue($fieldName) { // TODO: get dafault value from xsd file - TODO: p5:default attribute
$ds = $this->getDataSource();
return $ds->getColDefault($fieldName);
}
public function getColDefault($fieldName) {
return $this->getFieldDefaultValue($fieldName);
}
public function getSpecialFilters() {
$ds = $this->getDataSource();
return $ds->getSpecialFilters();
}
public function isGeomField($fldName) {
return ('the_geom' === $fldName);
// $ds = $this->getDataSource();
// return $ds->isGeomField($fldName);
}
public function getGeomFieldType($fieldName) {
if (empty($this->_types)) $this->fieldsInit($force = true);
$dbGeomType = $this->getFieldType($fieldName);
$dbGeomType = (!empty($dbGeomType['type']))? $dbGeomType['type'] : '';
$geomType = strtolower($dbGeomType);
return $geomType;
}
public function getSqlTableFrom() {
if ($this->loadSchema() && method_exists($this->_schemaClass, 'getSqlTableFrom')) {
return $this->_schemaClass->getSqlTableFrom();
}
return DB::getPDO( $this->getDB() )->tableNameQuote( $this->getRootTableName() );
}
public function getHistItems($primaryKey) {
if ($this->loadSchema() && method_exists($this->_schemaClass, 'hasGetHistItems') && $this->_schemaClass->hasGetHistItems()) {
return $this->_schemaClass->getHistItems($primaryKey);
}
$ds = $this->getDataSource();
return $ds->getHistItems($primaryKey);
}
public function getHistItem($id, $idHist) {
$ds = $this->getDataSource();
$histItems = $ds->getHistItems($id, ['ID' => $idHist]);
if (empty($histItems)) return null;
return reset($histItems);
}
public function addItem($itemTodo) {
if (is_object($itemTodo)) {
$itemTodo = (array)$itemTodo;
} else if (!is_array($itemTodo)) {
throw new HttpException('Item is not array', 400);
}
$ds = $this->getDataSource();
// from convertObjectFromUserInput - fixEmptyValueFromUser
$item = array();
$fields = $this->getFields();
foreach ($fields as $kID => $vField) {
$vFieldName = $vField['name'];
if (!$this->isAllowed($kID, 'C')) {
continue;
}
if (isset($itemTodo[$vFieldName])) {
$value = $itemTodo[$vFieldName];
if (empty($value) && strlen($value) == 0) {// fix bug in input type date and value="0000-00-00"
$value = $this->fixEmptyValueFromUser($kID);
}
$item[$vFieldName] = $value;
}
}
// add empty record is allowed - empty($item)
{// add DefaultAclGroup if no create perms ('C')
$defaultAclGroup = User::getDefaultAclGroup();
if ($defaultAclGroup) {
$permFields = array('A_ADM_COMPANY', 'A_CLASSIFIED');
foreach ($permFields as $permFldName) {
if (array_key_exists($permFldName, $this->_types)) {
$permFldId = $this->getFieldIdByName($permFldName);
if (0 == $permFldId || !$this->isAllowed($permFldId, 'C')) {
$item[$permFldName] = $defaultAclGroup;
}
}
}
}
}
DBG::_('DBG_DS', '>2', "addItem", $item, __CLASS__, __FUNCTION__, __LINE__);
return $ds->addItem($item);
}
/**
* @param array $itemPatch
*/
public function updateItem($itemPatch) {
if (is_object($itemPatch)) {
$itemPatch = (array)$itemPatch;
} else if (!is_array($itemPatch)) {
throw new HttpException('Item patch is not array', 400);
}
if (empty($itemPatch)) {
//throw new Exception('Item patch is empty');
return 0;// nothing to change
}
$primaryKeyField = $this->getPrimaryKeyField();
if (empty($itemPatch[$primaryKeyField])) throw new HttpException("Item Primary Key not set!", 400);
$primaryKey = $itemPatch[$primaryKeyField];
$itemOld = $this->getItem($primaryKey);
if (!$itemOld) throw new HttpException("Item not exists!", 404);
if (!$this->canWriteRecord($itemOld) && !$this->hasPermSuperWrite()) throw new HttpException("Brak dostępu do rekordu", 403);
// $itemPatch from user input to $itemPatchChecked
$itemPatchChecked = array();
$fields = $this->getFields();
foreach ($fields as $kID => $vField) {
$vFieldName = $vField['name'];
if (!$this->isAllowed($kID, 'W', $itemOld)) {
continue;
}
if (array_key_exists($vFieldName, $itemPatch)) {
if (!$this->isAllowed($kID, 'R', $itemOld) && '*****' == $itemPatch[$vFieldName]) {
// default value for perms 'W' without 'R' is '*****'
}
else {
$value = $itemPatch[$vFieldName];
if (empty($itemPatch[$vFieldName]) && strlen($itemPatch[$vFieldName]) == 0) {// fix bug in input type date and value="0000-00-00"
$value = $this->fixEmptyValueFromUser($kID);
}
if ($value != $itemOld->$vFieldName) {
$itemPatchChecked[$vFieldName] = $value;
}
}
}
}
if (empty($itemPatchChecked)) {
//throw new HttpException("Item Primary Key not set!", 400);
return 0;// nothing to change
}
$itemPatchChecked[$primaryKeyField] = $primaryKey;
if ($this->loadSchema() && method_exists($this->_schemaClass, 'hasUpdateItem') && $this->_schemaClass->hasUpdateItem()) {
$affected = $this->_schemaClass->updateItem($itemPatchChecked);
} else {
$ds = $this->getDataSource();
$affected = $ds->updateItem($itemPatchChecked);
}
return $affected;
}
public function createItemCopy($item) {
$ds = $this->getDataSource();
$types = $this->getTypes();
$uniqKeys = $ds->getUniqueKeys();// TODO: getUniqueFields
$primaryKeyField = $ds->getPrimaryKeyField();
$itemCopy = array();
foreach ($types as $kName => $vType) {
if ($kName == $primaryKeyField) continue;
if (in_array($kName, array('A_RECORD_UPDATE_AUTHOR','A_RECORD_UPDATE_DATE'))) continue;
$value = V::get($kName, '', $item);
if (in_array($kName, $uniqKeys)) {
$value .= '?';
}
if ($ds->isGeomField($kName) && !empty($value)) {
$value = "GeomFromText('{$value}')";
}
$itemCopy[$kName] = $value;
}
return $itemCopy;
}
public function getDataSource() {
$realFieldList = $this->getRealFieldList();
$dataSource = $this->_getDataSource($realFieldList);
$dataSource->setFieldGroupWrite('A_ADM_COMPANY', $this->hasFieldType('A_ADM_COMPANY'));
$dataSource->setFieldGroupRead('A_CLASSIFIED', $this->hasFieldType('A_CLASSIFIED'));
$dataSource->setFieldOwner('L_APPOITMENT_USER', $this->hasFieldType('L_APPOITMENT_USER'));
$adminFields = array('A_RECORD_CREATE_DATE', 'A_RECORD_CREATE_AUTHOR', 'A_RECORD_UPDATE_DATE', 'A_RECORD_UPDATE_AUTHOR');
foreach ($adminFields as $vAdmFld) {
if (!in_array($vAdmFld, $realFieldList) && $this->hasFieldType($vAdmFld)) {
$dataSource->addCol($vAdmFld);
}
}
return $dataSource;
}
private function _getDataSource($cols) {
$dsConfig = array();
$dsConfig['source_id'] = $this->getDB();
$dsConfig['object_name'] = $this->getRootTableName();
$dsConfig['fields'] = $cols;
$dsConfig['field_types'] = $this->getTypes();
$dsConfig['fields_virtual'] = $this->getVirtualFieldListByIdZasob();
$dsConfig['acl_fltr_allowed'] = !$this->hasSuperAccessPerms(); // filtr Access is visible only if user dont have supe access perms. If has then see all rows
return DataSourceFactory::buildFromZasobInfo($dsConfig);
}
public function getPrimaryKeyField() {
if ($this->loadSchema()) {
$pkField = $this->_schemaClass->getPrimaryKeyField();
if ($pkField) return $pkField;
}
$ds = $this->getDataSource();
return $ds->getPrimaryKeyField();
}
public function isIntegerField($fldName) {
$type = $this->getFieldType($fldName);
if (!$type) return false;
if (substr($type['type'], 0, 3) == 'int'
|| substr($type['type'], 0, 7) == 'tinyint'
|| substr($type['type'], 0, 8) == 'smallint'
|| substr($type['type'], 0, 9) == 'mediumint'
|| substr($type['type'], 0, 6) == 'bigint'
) {
return true;
}
return false;
}
public function isDecimalField($fldName) {
$type = $this->getFieldType($fldName);
if (!$type) return false;
if (substr($type['type'], 0, 7) == 'decimal'
|| substr($type['type'], 0, 7) == 'numeric'
|| substr($type['type'], 0, 6) == 'double'
|| substr($type['type'], 0, 5) == 'float'
|| substr($type['type'], 0, 4) == 'real'
) {
return true;
}
return false;
}
public function isDateField($fldName) {
$type = $this->getFieldType($fldName);
if (!$type) return false;
if (substr($type['type'], 0, 4) == 'date' && substr($type['type'], 0, 8) != 'datetime') {
return true;
}
return false;
}
public function isDateTimeField($fldName) {
$type = $this->getFieldType($fldName);
if (!$type) return false;
if (substr($type['type'], 0, 8) == 'datetime') {
return true;
}
return false;
}
public function isTimeField($fldName) {
$type = $this->getFieldType($fldName);
if (!$type) return false;
return ('time' === $type['type']);
}
public function isStringField($fldName) {
$type = $this->getFieldType($fldName);
if (!$type) return false;
if (substr($type['type'], 0, 7) == 'varchar'
|| substr($colType['type'], 0, 4) == 'char'
) {
return true;
}
return false;
}
public function isTextField($fldName) {
$type = $this->getFieldType($fldName);
if (!$type) return false;
if (substr($type['type'], 0, 4) == 'text'
|| substr($type['type'], 0, 8) == 'tinytext'
|| substr($type['type'], 0, 10) == 'mediumtext'
|| substr($type['type'], 0, 8) == 'longtext'
) {
return true;
}
return false;
}
public function isBinaryField($fldName) {
$type = $this->getFieldType($fldName);
if (!$type) return false;
if (substr($type['type'], 0, 4) == 'blob'
|| substr($type['type'], 0, 8) == 'tinyblob'
|| substr($type['type'], 0, 10) == 'mediumblob'
|| substr($type['type'], 0, 8) == 'longblob'
) {
return true;
}
return false;
}
public function isEnumerationField($fldName) {
$type = $this->getFieldType($fldName);
if (!$type) return false;
if (substr($type['type'], 0, 4) == 'enum') {
return true;
}
return false;
}
public function getEnumerations($fldName) {
$type = $this->getFieldType($fldName);
if (!$type) return [];
if (!$this->isEnumerationField($fldName)) return [];
$values = explode(',', str_replace(array('(',')',"'",'"'), '', substr($type['type'], 5)));
$enum = array();
foreach ($values as $val) {
$enum[$val] = $val;
}
return $enum;
}
public function getAttributesFromZasoby() {
$attributes = array();
$db = DB::getDB();
$sql = "
select `ID` as `id_zasob`
, `DESC` as `field_name`
, `DESC_PL` as `label`
, `OPIS` as `description`
from `CRM_LISTA_ZASOBOW`
where `PARENT_ID`={$this->_zasobID}
and `TYPE`='KOMORKA'
";
$res = $db->query($sql);
while ($r = $db->fetch($res)) {
$fldAttr = array();
$fldAttr['id_zasob'] = $r->id_zasob;
if (!empty($r->label)) $fldAttr['label'] = $r->label;
if (!empty($r->description)) $fldAttr['description'] = $r->description;
$attributes[$r->field_name] = $fldAttr;
}
// fetch field values
$sql = "
select z.`ID` as `id_zasob`
, z.`DESC` as `field_name`
, v.`DESC` as `value`
, v.`DESC_PL` as `label`
-- , v.`OPIS` as `description`
from `CRM_LISTA_ZASOBOW` z
join `CRM_LISTA_ZASOBOW` v on(v.`PARENT_ID` = z.`ID`)
where z.`PARENT_ID`={$this->_zasobID}
and z.`TYPE`='KOMORKA'
";
$res = $db->query($sql);
while ($r = $db->fetch($res)) {
if (!empty($r->value) && !empty($r->label)) {
$valuesMap = V::get('valuesMap', array(), $attributes[$r->field_name]);
$valuesMap[$r->value] = $r->label;
$attributes[$r->field_name]['valuesMap'] = $valuesMap;
}
}
return $attributes;
}
public function getXsdFieldType($fieldName) {// @returns string - xsd type, TODO: throw Exception when field not found
static $_xsdStruct = [];
if (array_key_exists($fieldName, $_xsdStruct)) return $_xsdStruct[$fieldName];
$_xsdStruct[$fieldName] = $this->_getXsdFieldType($fieldName);
return $_xsdStruct[$fieldName];
}
public function _getXsdFieldType($fieldName) {// @returns string - xsd type, TODO: throw Exception when field not found
if ($this->loadSchema()) {
$schemaType = $this->_schemaClass->getType($fieldName);
if ($schemaType) return $schemaType;
}
$fldType = 'xsd:string';
if ('A_RECORD_UPDATE_DATE' == $fieldName) return 'xsd:string';
if ('A_RECORD_CREATE_DATE' == $fieldName) return 'xsd:string';
if ($this->isIntegerField($fieldName)) return 'xsd:integer';
else if ($this->isDecimalField($fieldName)) return 'xsd:decimal';
else if ($this->isDateTimeField($fieldName)) return 'xsd:dateTime';
else if ($this->isTimeField($fieldName)) return 'xsd:time';
else if ($this->isDateField($fieldName)) return 'xsd:date';
else if ($this->isTextField($fieldName)) return 'p5:text';
else if ($this->isGeomField($fieldName)) {
//$fldType = 'gml:GeometryPropertyType';
$geomType = $this->getGeomFieldType($fieldName);
// DBG::log("DBG Geom field type ({$fieldName}) type({$geomType})");
if ('polygon' == $geomType) return 'gml:PolygonPropertyType';
else if ('point' == $geomType) return 'gml:PointPropertyType';
else if ('linestring' == $geomType) return 'gml:LineStringPropertyType';
else return 'gml:GeometryPropertyType';
}
else if ($this->isEnumerationField($fieldName)) return 'p5:enum';
else if ($this->isBinaryField($fieldName)) return 'xsd:base64Binary';
return $fldType;
}
public function getXsdFieldParam($fieldName, $paramKey) {
return ($this->loadSchema())
? $this->_schemaClass->getFieldParam($fieldName, $paramKey)
: $this->_getXsdFieldParam($fieldName, $paramKey)
;
}
public function _getXsdFieldParam($fieldName, $paramKey) {
switch ($paramKey) {
case 'maxLength': {
$colType = $this->getFieldType($fieldName);
if (!$colType) return null;
return (int)str_replace(array(' ','(',')'), '', substr($colType['type'], strpos($colType['type'], '(') + 1, -1));
}
}
return null;
}
public function getXsdTypes() { // @returns [ fieldName => xsdType, ... ]
$xsdTypes = [];
foreach ($this->getFields() as $field) {
$fieldName = $field['name'];
$xsdTypes[ $fieldName ] = $this->getXsdFieldType( $fieldName );
}
return $xsdTypes;
}
public function getFieldsWithXsdTypes() {
$xsdTypes = [];
foreach ($this->getFields() as $idZasob => $field) {
$xsdTypes[ $field['name'] ] = [
'name' => $field['name'],
'perms' => $field['perms'],
'idZasob' => $idZasob,
'xsdType' => $this->getXsdFieldType($field['name']),
];
}
return $xsdTypes;
}
public function getSqlFieldName($childName) {
return $childName;
}
public function hasField($fieldName) {// TODO: fix use Core_AclFields or ACL::getObjectFields($namespace) - use cache - one place to store structure
return array_key_exists($fieldName, $this->_types);
}
}