Router::getRoute('Storage_AclStruct')->getLink('', [ 'namespace' => $namespace ]), 'class' => "btn btn-md btn-link", ], " Wróć do struktury"), ]); if ('reinstall' !== V::get('_postTask', '', $_POST)) { 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()); } return; } Lib::loadClass('Schema_SystemObjectFieldStorageAcl'); $objFieldAcl = new Schema_SystemObjectFieldStorageAcl(); $objFieldAcl->updateCache($namespace); DBG::nicePrint([ 'idInstance' => ACL::getInstanceId($namespace), 'rootInstance' => ACL::getRootNamespace($namespace), 'conf' => ACL::fetchInstanceConfig($namespace), 'table' => ACL::getInstanceTable($namespace), ], "dbg"); { $item = SchemaFactory::loadDefaultObject('SystemObject')->getItem($namespace, [ 'propertyName' => '*,field' ]); if ('AntAcl' === $item['_type']) { $dbName = DB::getPDO()->getDatabaseName(); $sqlFunBody = ACL::generateIsInstanceFunctionBody($namespace, $item); DBG::nicePrint($sqlFunBody, "\$sqlFunBody"); DB::getPDO()->execSql(" DROP FUNCTION IF EXISTS `{$dbName}`.`isInstance_{$namespace}` "); // CREATE // [DEFINER = { user | CURRENT_USER }] // FUNCTION sp_name ([func_parameter[,...]]) // RETURNS type // [characteristic ...] routine_body DB::getPDO()->execSql(" CREATE DEFINER=`root`@`localhost` FUNCTION `{$dbName}`.`isInstance_{$namespace}` ( pk INT(11) ) RETURNS TINYINT(1) {$sqlFunBody} "); } } } 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; default: throw new Exception("TODO: Not Implemented type '{$objectItem['_type']}'"); } } public function printReinstallAntAclPreview($item) { $antAclPath = APP_PATH_SCHEMA . DS . 'ant-object' . DS . str_replace(['__x3A__', ':'], ['.', '/'], $item['typeName']); if (!file_exists("{$antAclPath}/build.xml")) throw new Exception("Ant build file not exists"); Lib::loadClass('XML'); $xsdType = XML::getXsdTypeFromXsdSchema("{$antAclPath}/{$item['name']}.xsd", $namespace = $item['namespace'], $name = $item['name']); DBG::nicePrint($xsdType, '$xsdType'); 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', [], [ 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" ], "Brak pól do dodania"); echo (!empty($diffFieldsToRemove)) ? UI::h('details', [], [ UI::h('summary', [], "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" ], "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" ], "Pole '{$fieldName}' - bez zmian"); } throw new Exception("TODO: Podgląd zmian dla AntAcl {$item['namespace']} ..."); } public function printReinstallTableAclPreview($item) { throw new Exception("TODO: Podgląd zmian dla tabeli {$item['namespace']} ..."); } }