Router::getRoute('Storage_AclStruct')->getLink('', [ 'namespace' => $namespace ]),
'class' => "btn btn-md btn-link",
], " Wróć do struktury"),
" | ",
UI::h('a', [
'href' => $this->getLink('viewXsdSource', [ 'namespace' => $namespace ]),
'class' => "btn btn-md btn-link",
'target' => "_blank",
], "Otwórz plik xsd (źródłowy)"),
]);
if ('reinstall' == V::get('_postTask', '', $_POST)) {
$this->reinstallAcl($namespace);
return;
}
echo UI::hButtonPost("Reinstall", [
'data' => [
'_postTask' => 'reinstall'
],
'class' => 'btn btn-md btn-danger',
'title' => "Reinstall structure"
]);
echo '
';
try {
$this->printReinstallPreview($namespace);
} catch (Exception $e) {
DBG::log($e);
UI::alert('danger', $e->getMessage());
}
} catch (Exception $e) {
UI::alert('danger', "Error #" . $e->getCode() . "|" . $e->getLine() . ": " . $e->getMessage());
DBG::log($e);
}
UI::endContainer();
UI::dol();
}
public function printReinstallPreview($namespace) {
$objectItem = SchemaFactory::loadDefaultObject('SystemObject')->getItem($namespace, [ 'propertyName' => "*,field" ]);
DBG::log($objectItem, 'array', '$objectItem preview');
switch ($objectItem['_type']) {
case 'AntAcl': $this->printReinstallAntAclPreview($objectItem); break;
case 'TableAcl': $this->printReinstallTableAclPreview($objectItem); break;
case 'StorageAcl': $this->printReinstallStorageAclPreview($objectItem); break;
default: throw new Exception("TODO: Not Implemented type '{$objectItem['_type']}'");
}
}
public function printReinstallAntAclPreview($item) {
$antAclPath = Schema_SystemObjectFieldStorageAcl::getAntAclXsdBasePath($item['typeName']);
if (!file_exists("{$antAclPath}/build.xml")) throw new Exception("Ant build file not exists " . str_replace(APP_PATH_ROOT, 'SE', $antAclPath));
Lib::loadClass('XML');
$xsdType = XML::getXsdTypeFromXsdSchema("{$antAclPath}/{$item['name']}.xsd", $namespace = $item['namespace'], $name = $item['name']);
DBG::nicePrint($item, '$item');
$sortPrio = 0;
foreach ($xsdType['struct'] as $fieldName => $fieldItem) {
$xsdType['struct'][$fieldName]['sortPrio'] = $sortPrio++;
}
DBG::nicePrint($xsdType, '$xsdType');
// TODO: fix sortPrio for all fields if not set = 0
echo '
';
echo UI::h('h3', [], "Lista zmian:");
echo ($item['primaryKey'] != $xsdType['primaryKey'])
? UI::h('p', [ 'style' => "" ], "@primaryKey - zmiana z '{$item['primaryKey']}' na '{$xsdType['primaryKey']}'")
: UI::h('p', [ 'style' => "font-style:italic; color:silver" ], "@primaryKey - bez zmian");
if (empty($xsdType['struct'])) throw new Exception("Field list not found for '{$item['namespace']}'");
foreach ($xsdType['struct'] as $fieldName => $x) {
$listEnum = [];
if (!empty($x['restrictions']['enumeration'])) {
$listEnum = $x['restrictions']['enumeration'];
unset($x['restrictions']['enumeration']);
}
if (!empty($listEnum)) {
DBG::log($listEnum, 'array', "\$listEnum for field '{$fieldName}'");
}
}
$old = [
'fields' => array_map(function ($field) { return $field['fieldNamespace']; }, $item['field']),
];
$new = [
'fields' => array_keys($xsdType['struct']),
];
sort($old['fields']);
sort($new['fields']);
$diffFieldsToCreate = array_diff($new['fields'], $old['fields']);
$diffFieldsToRemove = array_diff($old['fields'], $new['fields']);
$sameFields = array_intersect($new['fields'], $old['fields']);
echo (!empty($diffFieldsToCreate))
? UI::h('details', [ 'open' => "open" ], [
UI::h('summary', [], "Pola do dodania (".count($diffFieldsToCreate)."):"),
UI::h('ul', [], array_map(function ($fieldName) {
return UI::h('li', [], $fieldName);
}, $diffFieldsToCreate)),
])
: UI::h('p', [ 'style' => "font-style:italic; color:silver" ], "Brak pól do dodania");
echo (!empty($diffFieldsToRemove))
? UI::h('details', [ 'open' => "open", 'style' => "margin:4px 0; color:#8a6d3b; background-color:#fcf8e3; border:1px solid #faebcc;" ], [
UI::h('summary', [ 'style' => "padding:4px; outline:none; cursor:pointer" ], "Pola do usunięcia (".count($diffFieldsToRemove)."):"),
UI::h('ul', [], array_map(function ($fieldName) {
return UI::h('li', [], $fieldName);
}, $diffFieldsToRemove)),
])
: UI::h('p', [ 'style' => "font-style:italic; color:silver" ], "Brak pól do usunięcia");
foreach ($sameFields as $fieldName) {
// UI::alert('warning', "TODO: is field changed? '{$fieldName}'");
$oldField = array_filter($item['field'], function ($field) use ($fieldName) { return ( $fieldName === $field['fieldNamespace'] ); });
$oldField = ($oldField) ? reset($oldField) : null;
// DBG::nicePrint($oldField, "\$oldField '$fieldName'");
$newField = $xsdType['struct'][$fieldName];
// DBG::nicePrint($newField, "\$newField '$fieldName'");
$fieldDiff = [];
if ($newField['type'] !== $oldField['xsdType']) $fieldDiff[] = 'xsdType';
if ($newField['minOccurs'] != $oldField['minOccurs']) $fieldDiff[] = 'minOccurs';
if ($newField['maxOccurs'] != $oldField['maxOccurs']) $fieldDiff[] = 'maxOccurs';
if (json_encode($newField['restrictions']) !== $oldField['xsdRestrictions']) $fieldDiff[] = 'xsdRestrictions';
if (json_encode($newField['appInfo']) !== $oldField['appInfo']) $fieldDiff[] = 'appInfo';
if (RefConfig::isRefField($item['namespace'], $fieldName)) {
$typeNewField = Type_Field::build($newField);
$typeOldField = Type_Field::build($oldField);
if (RefConfig::needUpdate($item['namespace'], $oldField['fieldNamespace'], $typeNewField, $typeOldField)) {
$fieldDiff[] = 'RefConfig';
}
}
echo (!empty($fieldDiff))
? UI::h('p', [ 'style' => "" ], "Pole '{$fieldName}' - zmiany: " . implode(", ", $fieldDiff))
: UI::h('p', [ 'style' => "font-style:italic; color:silver" ], "Pole '{$fieldName}' - bez zmian");
}
}
public function printReinstallTableAclPreview($item) {
throw new Exception("TODO: Podgląd zmian dla tabeli {$item['namespace']} ...");
}
public function printReinstallStorageAclPreview($item) {
DBG::nicePrint($item, '$item');
$acl = SchemaFactory::loadDefaultObject($item['name']);
DBG::nicePrint($acl, '$acl');
$xsdType = [
'primaryKey' => $acl->getPrimaryKeyField(),
'struct' => $acl->getFieldsWithXsdTypes()
];
DBG::nicePrint($xsdType, '$xsdType');
echo '
';
echo UI::h('h3', [], "Lista zmian:");
echo ($item['primaryKey'] != $xsdType['primaryKey'])
? UI::h('p', [ 'style' => "" ], "@primaryKey - zmiana z '{$item['primaryKey']}' na '{$xsdType['primaryKey']}'")
: UI::h('p', [ 'style' => "font-style:italic; color:silver" ], "@primaryKey - bez zmian");
if (empty($xsdType['struct'])) throw new Exception("Field list not found for '{$item['namespace']}'");
foreach ($xsdType['struct'] as $fieldName => $x) {
$listEnum = [];
if (!empty($x['restrictions']['enumeration'])) {
$listEnum = $x['restrictions']['enumeration'];
unset($x['restrictions']['enumeration']);
}
if (!empty($listEnum)) {
DBG::log($listEnum, 'array', "\$listEnum for field '{$fieldName}'");
}
}
$old = [
'fields' => array_map(function ($field) { return $field['fieldNamespace']; }, $item['field']),
];
$new = [
'fields' => array_keys($xsdType['struct']),
];
sort($old['fields']);
sort($new['fields']);
$diffFieldsToCreate = array_diff($new['fields'], $old['fields']);
$diffFieldsToRemove = array_diff($old['fields'], $new['fields']);
$sameFields = array_intersect($new['fields'], $old['fields']);
echo (!empty($diffFieldsToCreate))
? UI::h('details', [ 'open' => "open" ], [
UI::h('summary', [], "Pola do dodania (".count($diffFieldsToCreate)."):"),
UI::h('ul', [], array_map(function ($fieldName) {
return UI::h('li', [], $fieldName);
}, $diffFieldsToCreate)),
])
: UI::h('p', [ 'style' => "font-style:italic; color:silver" ], "Brak pól do dodania");
echo (!empty($diffFieldsToRemove))
? UI::h('details', [ 'open' => "open", 'style' => "margin:4px 0; color:#8a6d3b; background-color:#fcf8e3; border:1px solid #faebcc;" ], [
UI::h('summary', [ 'style' => "padding:4px; outline:none; cursor:pointer" ], "Pola do usunięcia (".count($diffFieldsToRemove)."):"),
UI::h('ul', [], array_map(function ($fieldName) {
return UI::h('li', [], $fieldName);
}, $diffFieldsToRemove)),
])
: UI::h('p', [ 'style' => "font-style:italic; color:silver" ], "Brak pól do usunięcia");
foreach ($sameFields as $fieldName) {
// UI::alert('warning', "TODO: is field changed? '{$fieldName}'");
$oldField = array_filter($item['field'], function ($field) use ($fieldName) { return ( $fieldName === $field['fieldNamespace'] ); });
$oldField = ($oldField) ? reset($oldField) : null;
// DBG::nicePrint($oldField, "\$oldField '$fieldName'");
$newField = $xsdType['struct'][$fieldName];
// DBG::nicePrint($newField, "\$newField '$fieldName'");
$fieldDiff = [];
if ($newField['type'] !== $oldField['xsdType']) $fieldDiff[] = 'xsdType';
if ($newField['minOccurs'] != $oldField['minOccurs']) $fieldDiff[] = 'minOccurs';
if ($newField['maxOccurs'] != $oldField['maxOccurs']) $fieldDiff[] = 'maxOccurs';
if (json_encode($newField['restrictions']) !== $oldField['xsdRestrictions']) $fieldDiff[] = 'xsdRestrictions';
if (json_encode($newField['appInfo']) !== $oldField['appInfo']) $fieldDiff[] = 'appInfo';
echo (!empty($fieldDiff))
? UI::h('p', [ 'style' => "" ], "Pole '{$fieldName}' - zmiany: " . implode(", ", $fieldDiff))
: UI::h('p', [ 'style' => "font-style:italic; color:silver" ], "Pole '{$fieldName}' - bez zmian");
}
}
public function viewXsdSourceAction() {
try {
$namespace = V::get('namespace', '', $_GET);
if (empty($namespace)) throw new Exception("Missing param namespace");
$objectItem = SchemaFactory::loadDefaultObject('SystemObject')->getItem($namespace, [ 'propertyName' => "*,field" ]);
switch ($objectItem['_type']) {
case 'AntAcl': $this->viewXsdSource($objectItem); break;
// case 'TableAcl': $this->viewXsdSource($objectItem); break;
default: throw new Exception("TODO: Not Implemented type '{$objectItem['_type']}'");
}
} catch (Exception $e) {
DBG::log($e);
echo "Error #" . $e->getCode() . "|" . $e->getLine() . ": " . $e->getMessage();
}
}
function viewXsdSource($objectItem) {
if (empty($objectItem)) throw new Exception("Missing objectItem in viewXsdSource");
DBG::log($objectItem, "viewXsdSource \$objectItem");
$antAclPath = Schema_SystemObjectFieldStorageAcl::getAntAclXsdBasePath($objectItem['typeName']);
if (!file_exists("{$antAclPath}/build.xml")) throw new Exception("Ant build file not exists");
DBG::log(str_replace(APP_PATH_ROOT, '~', $antAclPath), "viewXsdSource \$antAclPath");
$xsdFile = "{$antAclPath}/{$objectItem['name']}.xsd";
if (!file_exists($xsdFile)) throw new Exception("Xsd file not exists");
DBG::log(str_replace(APP_PATH_ROOT, '~', $xsdFile), "viewXsdSource \$xsdFile");
header('Content-Type: application/xml; charset=utf-8');
$fd = fopen($xsdFile, 'r');
fpassthru($fd);
exit;
}
function reinstallAcl($namespace) {
try {
$this->_createOrUpdateTableStructure($namespace);
} catch (Exception $e) {
DBG::log($e);
UI::alert('danger', $e->getMessage());
}
$objFieldAcl = new Schema_SystemObjectFieldStorageAcl();
$objFieldAcl->updateCache($namespace);
try {
$dbgInfo = [
'idInstance' => ACL::getInstanceId($namespace),
// 'rootInstance' => InstanceConfig::getRootNamespace($namespace),
// 'conf' => InstanceConfig::fetchInstanceConfig($namespace),
];
DBG::nicePrint($dbgInfo, "dbg");
} catch (Exception $e) {
DBG::log($e);
UI::alert('warning', $e->getMessage());
}
$childRefList = RefConfig::getChildRefFullList($namespace);
DBG::nicePrint($childRefList, '$childRefList');
DBG::nicePrint($item, '$item');
$activeFields = array_filter($item['field'], function ($field) {
return ($field['isActive'] > 0);
});
$fieldNsList = array_map(function ($field) {
return $field['fieldNamespace'];
}, $activeFields);
DBG::nicePrint($fieldNsList, '$fieldNsList');
if ('AntAcl' === $item['_type']) { // fix ref config status (turn on/off)
foreach ($childRefList as $refConfig) { // [ namespace, A_STATUS ]
if ($refConfig->status !== 'DELETED' && !in_array($refConfig->childName, $fieldNsList)) {
UI::alert('danger', "remove ref config for '{$refConfig->childName}' ...");
if (!$refConfig->id) throw new Exception("Missing ref config ID");
RefConfig::remove($refConfig);
}
else if ($refConfig->status !== 'DELETED' && in_array($refConfig->childName, $fieldNsList)) {
UI::alert('info', "ref config for '{$refConfig->childName}' active - OK");
}
else if ($refConfig->status === 'DELETED' && in_array($refConfig->childName, $fieldNsList)) {
UI::alert('warning', "activate ref config for '{$refConfig->childName}' ...");
if (!$refConfig->id) throw new Exception("Missing ref config ID");
RefConfig::reactivate($refConfig);
}
else if ($refConfig->status === 'DELETED' && !in_array($refConfig->childName, $fieldNsList)) {
UI::alert('info', "ref config for '{$refConfig->childName}' removed - OK");
}
else {
UI::alert('danger', "Not implemented action for '{$refConfig->childName}'");
}
}
// TODO: create missing refConfig - field is not in $childRefList
}
if ('AntAcl' === $item['_type']) { // fix ref tables by appInfo
$activeRefFields = array_filter($item['field'], function ($field) {
return ($field['isActive'] && 'ref:' === substr($field['xsdType'], 0, 4));
});
DBG::log($activeRefFields, 'array', "DBG \$activeRefFields");
foreach ($activeRefFields as $field) {
$typeNewField = Type_Field::build($field);
// if (RefConfig::needUpdate($item['namespace'], $oldField['fieldNamespace'], $typeNewField, $typeOldField))
try {
RefConfig::update($item['namespace'], $field['fieldNamespace'], $typeNewField);
} catch (Exception $e) {
// TODO: deactivate RefConfig if error
DBG::log($e);
UI::alert('danger', $e->getMessage());
}
}
}
{ // TODO: RMME? function is too slow for join query
if ('AntAcl' === $item['_type']) {
$idInstance = ACL::getInstanceId($namespace);
$dbName = DB::getPDO()->getDatabaseName();
DB::getPDO()->execSql(" DROP FUNCTION IF EXISTS `{$dbName}`.`isInstance_{$idInstance}` ");
}
}
{ // TODO: mv to updateCache
if ('AntAcl' === $item['_type']) {
$instConf = InstanceConfig::getInstanceConfig($namespace);
InstanceConfig::createInstanceTable($instConf, $item); // force create instance table event if A_STATUS is NORMAL
}
}
}
function _createOrUpdateTableStructure($namespace) {
$item = SchemaFactory::loadDefaultObject('SystemObject')->getItem($namespace, [ 'propertyName' => '*,field' ]);
DBG::log($item, 'array', 'DBG:_createOrUpdateTableStructure:$item');
$currentStruct = [];
try {
$currentStruct = DB::getStorage($item['idDatabase'])->getTableStruct($item['_rootTableName']);
} catch (Exception $e) {
DBG::log($e);
}
DBG::log($currentStruct, 'array', 'DBG:_createOrUpdateTableStructure:$currentStruct');
if (DB::getPDO()->getZasobId() != $item['idDatabase']) throw new Exception("Not imeplemented Create/Update table structure in non default database");
if (empty($currentStruct)) $this->_createTableStructure($item);
else $this->_updateTableStructure($item, $currentStruct);
}
// $item['idDatabase'] => int idDatabase
// $item['_rootTableName'] => string tableName
// $item['primaryKey'] => string primaryKey fieldName
// $item['field'] => []
// $item['field']['fieldNamespace'] => fieldName,
// $item['field']['xsdRestrictions'] => [] // TODO: handle restrictions like maxLength, etc.
// $item['field']['xsdType'] `select distinct xsdType from `CRM_#CACHE_ACL_OBJECT_FIELD` where xsdType not like 'ref:%'`: [
// default_db__x3A__BADANIA_W_TERENIE:A_STATUS_Type
// default_db__x3A__CRM_PROCES:TYPE_Simple
// gml:AbstractFeatureType
// gml:PolygonPropertyType
// p5:enum
// p5:price
// p5:www_link
// p5Type:date
// p5Type:dateTime
// p5Type:decimal
// p5Type:integer
// p5Type:lineString
// p5Type:point
// p5Type:polygon
// p5Type:string
// p5Type:text
// xsd:date
// xsd:dateTime
// xsd:decimal
// xsd:double
// xsd:float
// xsd:gYear
// xsd:hexBinary
// xsd:int
// xsd:integer
// xsd:long
// xsd:positiveInteger
// xsd:short
// xsd:string
// xsd:time
// xsd:token
// ]
function _createTableStructure($item) {
$expectedStruct = $this->_makeTableStructure($item);
DB::getStorage($item['idDatabase'])->createTableStructure([
'tableName' => $item['_rootTableName'],
'fields' => $expectedStruct,
'primaryKey' => $item['primaryKey'],
'keys' => [],
]);
}
function _updateTableStructure($item, $currentStruct) {
DBG::log($item, 'array', "DBG:update table struct:\$item");
DBG::log($currentStruct, 'array', "DBG:update table struct:\$currentStruct");
$expectedStruct = $this->_makeTableStructure($item);
DBG::log($expectedStruct, 'array', "DBG:update table struct:\$expectedStruct");
// $expectedStruct: [ fieldName => shortStruct ]
// shortStruct:
// 'name' => 'ID',
// 'raw_storage_type' => 'int(11)',
// 'extra' => 'auto_increment',
// $currentStruct: [ fieldName => fullStruct ]
// fullStruct:
// 'name' => 'ID',
// 'type' => 'int',
// 'is_nullable' => '0',
// 'default_value' => NULL,
// 'default_is_null' => '1',
// 'max_length' => NULL,
// 'num_precision' => '10',
// 'num_scale' => '0',
// 'char_encoding' => NULL,
// 'char_collation' => NULL,
// 'extra' => 'auto_increment',
// 'raw_storage_type' => 'int(11)',
$expectedFieldList = array_keys($expectedStruct);
$currentFieldList = array_keys($currentStruct);
// array_diff([ 'a', 'b', 'c' ], [ 'b', 'c', 'd' ]) => [ 'a' ]
// array_diff([ 'b', 'c', 'd' ], [ 'a', 'b', 'c' ]) => [ 'd' ]
// $toRemoveFieldFromStruct = array_diff($currentFieldList, $expectedFieldList); // TODO: not used, fields defined in base object
$toAddFieldToStruct = array_diff($expectedFieldList, $currentFieldList);
DBG::log($toRemoveFieldFromStruct, 'array', "DBG:update table struct:\$toRemoveFieldFromStruct");
DBG::log($toAddFieldToStruct, 'array', "DBG:update table struct:\$toAddFieldToStruct");
if (!empty($toAddFieldToStruct)) {
$rootTableName = $item['_rootTableName'];
array_map(function ($fieldName) use ($rootTableName, $expectedStruct) {
$expectedField = $expectedStruct[$fieldName];
$sqlNotNull = ""; // TODO: "NOT NULL" if field can not be null
$sqlDefault = ""; // TODO: "DEFAULT {$value}"
DB::getPDO()->execSql(" ALTER TABLE {$rootTableName} ADD {$fieldName} {$expectedField['raw_storage_type']} {$sqlNotNull} {$sqlDefault}");
}, $toAddFieldToStruct);
}
$maybeToUpdateFields = array_intersect($currentFieldList, $expectedFieldList);
DBG::log($maybeToUpdateFields, 'array', "DBG:update table struct:\$maybeToUpdateFields");
if (empty($maybeToUpdateFields)) {
UI::alert('info', "No fields to compare");
return;
}
$diffNotes = array_map(function ($fieldName) use ($currentStruct, $expectedStruct) {
$currentField = $currentStruct[$fieldName];
$expectedField = $expectedStruct[$fieldName];
return [
'fieldName' => $fieldName,
'current_raw_type' => $currentField['raw_storage_type'],
'expected_raw_type' => $expectedField['raw_storage_type'],
'diff' => ($currentField['raw_storage_type'] === $expectedField['raw_storage_type']) ? "same" : "diff",
];
}, $maybeToUpdateFields);
UI::table([ 'caption' => "Fields types diff:", 'rows' => $diffNotes ]);
$diffFields = array_filter($diffNotes, function ($item) { return ("diff" === $item['diff']); });
if (empty($diffFields)) {
UI::alert('info', "Struct is ok");
return;
}
DBG::log($diffFields, 'array', "TODO: update table struct by \$diffFields");
throw new Exception("TODO: Not imeplemented Update table structure (Update existing fields)");
}
function _makeTableStructure($item) {
$tryConvertFields = array_map([ $this, '_makeFieldStructure' ], $item['field']);
DBG::log($tryConvertFields, 'array', "DBG:make table struct:\$tryConvertFields");
$toCreateFields = array_filter($tryConvertFields, function ($fieldInfo) { return null !== $fieldInfo; });
DBG::log($toCreateFields, 'array', "DBG:make table struct:\$toCreateFields");
$tblStruct = array_combine(
array_map(V::makePick('name'), $toCreateFields),
array_values($toCreateFields)
);
DBG::log($tblStruct, 'array', "DBG:make table struct:\$tblStruct");
if (!array_key_exists($item['primaryKey'], $tblStruct)) throw new Exception("BUG: primaryKey field definition not exists");
$tblStruct[$item['primaryKey']]['extra'] = "auto_increment";
return $tblStruct;
}
function _makeFieldStructure($fieldInfo) {
// select distinct xsdType from `CRM_#CACHE_ACL_OBJECT_FIELD` where xsdType not like 'ref:%' order by xsdType;
if ('ref:' === substr($fieldInfo['xsdType'], 0, 4)) {
DBG::log("Skipped create ref field '{$fieldInfo['xsdType']}'");
return null;
}
$fieldName = $fieldInfo['fieldNamespace'];
if (!preg_match('/^[a-z_]+$/i', $fieldName)) {
DBG::log("Skipped create: not allowed field name '{$fieldName}'");
return null;
}
switch ($fieldInfo['xsdType']) {
// number
case 'xsd:integer':
case 'p5Type:integer':
case 'xsd:positiveInteger':
case 'xsd:int': return [ 'name' => $fieldInfo['fieldNamespace'], 'raw_storage_type' => "int(11)" ];
case 'xsd:short': return [ 'name' => $fieldInfo['fieldNamespace'], 'raw_storage_type' => "int(11)" ];
case 'xsd:long': return [ 'name' => $fieldInfo['fieldNamespace'], 'raw_storage_type' => "int(11)" ];
case 'xsd:float': return [ 'name' => $fieldInfo['fieldNamespace'], 'raw_storage_type' => "float" ];
case 'xsd:double': return [ 'name' => $fieldInfo['fieldNamespace'], 'raw_storage_type' => "double" ];
case 'xsd:decimal': return [ 'name' => $fieldInfo['fieldNamespace'], 'raw_storage_type' => "decimal(12,2)" ];
case 'p5Type:decimal':
case 'p5:price': return [ 'name' => $fieldInfo['fieldNamespace'], 'raw_storage_type' => "decimal(12,2)" ];
// time
case 'p5Type:date':
case 'xsd:date': return [ 'name' => $fieldInfo['fieldNamespace'], 'raw_storage_type' => "date" ];
case 'p5Type:dateTime':
case 'xsd:datetime': return [ 'name' => $fieldInfo['fieldNamespace'], 'raw_storage_type' => "datetime" ];
case 'xsd:time': return [ 'name' => $fieldInfo['fieldNamespace'], 'raw_storage_type' => "time" ];
// string
case 'xsd:string':
case 'p5Type:string': return [ 'name' => $fieldInfo['fieldNamespace'], 'raw_storage_type' => "varchar(255)" ];
case 'xsd:token': return [ 'name' => $fieldInfo['fieldNamespace'], 'raw_storage_type' => "varchar(255)" ];
case 'p5Type:text': return [ 'name' => $fieldInfo['fieldNamespace'], 'raw_storage_type' => "text" ];
// geom
case 'p5Type:polygon': return [ 'name' => $fieldInfo['fieldNamespace'], 'raw_storage_type' => "polygon", 'default' => "NULL" ];
case 'p5Type:lineString': return [ 'name' => $fieldInfo['fieldNamespace'], 'raw_storage_type' => "linestring", 'default' => "NULL" ];
case 'p5Type:point': return [ 'name' => $fieldInfo['fieldNamespace'], 'raw_storage_type' => "point", 'default' => "NULL" ];
case 'gml:AbstractFeatureType': return [ 'name' => $fieldInfo['fieldNamespace'], 'raw_storage_type' => "polygon", 'default' => "NULL" ];
// TODO: ???: 'gml:PolygonPropertyType'
case 'p5:enum': {
// [A_STATUS] => Array:
// [type] => p5:enum
// [minOccurs] => 0
// [maxOccurs] => 1
// [restrictions] => Array:
// [enumeration] => Array:
// [NORMAL] => NORMAL
// [WAITING] => WAITING
// [MONITOR] => MONITOR
// [DELETED] => DELETED
// [WARNING] => WARNING
// [OFF_SOFT] => OFF_SOFT
// [OFF_HARD] => OFF_HARD
$xsdRestrictions = Schema_SystemObjectFieldStorageAcl::getXsdRestrictionsValue($fieldInfo);
DBG::log($xsdRestrictions, 'array', "DBG: p5:enum xsdRestrictions for field('{$fieldInfo['fieldNamespace']}')");
return [ 'name' => $fieldInfo['fieldNamespace'], 'raw_storage_type' => "enum(" .
implode(",", array_map(function ($value) { return "'{$value}'"; }, array_keys($xsdRestrictions['enumeration']))) .
")" ];
}
// TODO: implement more xsd types:
// case 'default_db__x3A__BADANIA_W_TERENIE:A_STATUS_Type':
// case 'default_db__x3A__CRM_PROCES:TYPE_Simple':
// case 'p5:www_link':
// case 'xsd:gYear':
// case 'xsd:hexBinary':
default: {
DBG::log($fieldInfo, 'array', "TODO: _makeFieldStructure '{$fieldInfo['xsdType']}' (SystemObject/fieldInfo)"); // $fieldInfo = SchemaFactory::loadDefaultObject('SystemObject')->getItem($namespace, [ 'propertyName' => '*,field' ])['field'];
throw new Exception("Not implemented type '{$fieldInfo['xsdType']}'");
}
}
}
}