예제 #1
0
 /**
  * Correct fields defenitions based on \Espo\Custom\Core\Utils\Database\Orm\Fields
  *
  * @param  array  $ormMeta
  *
  * @return array
  */
 protected function correctFields($entityName, array $ormMeta)
 {
     $entityDefs = $this->getEntityDefs();
     $entityMeta = $ormMeta[$entityName];
     //load custom field definitions and customCodes
     foreach ($entityMeta['fields'] as $fieldName => $fieldParams) {
         if (empty($fieldParams['type'])) {
             continue;
         }
         $fieldType = ucfirst($fieldParams['type']);
         $className = '\\Espo\\Custom\\Core\\Utils\\Database\\Orm\\Fields\\' . $fieldType;
         if (!class_exists($className)) {
             $className = '\\Espo\\Core\\Utils\\Database\\Orm\\Fields\\' . $fieldType;
         }
         if (class_exists($className) && method_exists($className, 'load')) {
             $helperClass = new $className($this->metadata, $ormMeta, $entityDefs);
             $fieldResult = $helperClass->process($fieldName, $entityName);
             if (isset($fieldResult['unset'])) {
                 $ormMeta = Util::unsetInArray($ormMeta, $fieldResult['unset']);
                 unset($fieldResult['unset']);
             }
             $ormMeta = Util::merge($ormMeta, $fieldResult);
         }
     }
     //todo move to separate file
     //add a field 'isFollowed' for scopes with 'stream => true'
     $scopeDefs = $this->getMetadata()->get('scopes.' . $entityName);
     if (isset($scopeDefs['stream']) && $scopeDefs['stream']) {
         if (!isset($entityMeta['fields']['isFollowed'])) {
             $ormMeta[$entityName]['fields']['isFollowed'] = array('type' => 'varchar', 'notStorable' => true);
             $ormMeta[$entityName]['fields']['followersIds'] = array('type' => 'jsonArray', 'notStorable' => true);
             $ormMeta[$entityName]['fields']['followersNames'] = array('type' => 'jsonObject', 'notStorable' => true);
         }
     }
     //END: add a field 'isFollowed' for stream => true
     return $ormMeta;
 }
예제 #2
0
 public function testUnsetInArrayByString()
 {
     $input = array('Account' => array('useCache' => true), 'Contact' => array('useCache' => true));
     $unsets = 'Account.useCache';
     $result = array('Account' => array(), 'Contact' => array('useCache' => true));
     $this->assertEquals($result, Util::unsetInArray($input, $unsets));
 }
예제 #3
0
 /**
  * Unset some element of content data
  *
  * @param  string | array $path
  * @param  array | string $unsets
  * @return bool
  */
 public function unsetContents($path, $unsets, $isJSON = true)
 {
     $currentData = $this->getContents($path);
     if ($currentData == false) {
         $GLOBALS['log']->notice('FileManager::unsetContents: File [' . $this->concatPaths($path) . '] does not exist.');
         return false;
     }
     $currentDataArray = Utils\Json::getArrayData($currentData);
     $unsettedData = Utils\Util::unsetInArray($currentDataArray, $unsets, true);
     if (is_null($unsettedData) || is_array($unsettedData) && empty($unsettedData)) {
         $fullPath = $this->concatPaths($path);
         return $this->unlink($fullPath);
     }
     if ($isJSON) {
         return $this->putContentsJson($path, $unsettedData);
     }
     return $this->putContents($path, $unsettedData);
 }
예제 #4
0
 /**
  * Unset some fields and other stuff in metadat
  *
  * @param  string $key1
  * @param  string $key2
  * @param  array | string $unsets Ex. 'fields.name'
  *
  * @return bool
  */
 public function delete($key1, $key2, $unsets)
 {
     if (!is_array($unsets)) {
         $unsets = (array) $unsets;
     }
     $normalizedData = array('__APPEND__');
     $metaUnsetData = array();
     foreach ($unsets as $unsetItem) {
         $normalizedData[] = $unsetItem;
         $metaUnsetData[] = implode('.', array($key1, $key2, $unsetItem));
     }
     $unsetData = array($key1 => array($key2 => $normalizedData));
     $this->deletedData = Util::merge($this->deletedData, $unsetData);
     $this->deletedData = Util::unsetInArrayByValue('__APPEND__', $this->deletedData);
     $this->meta = Util::unsetInArray($this->getData(), $metaUnsetData);
 }
예제 #5
0
 /**
  * Unite file content to the file for one directory [NOW ONLY FOR METADATA, NEED TO CHECK FOR LAYOUTS AND OTHERS]
  *
  * @param string $dirPath
  * @param string $type - name of type array("metadata", "layouts"), ex. $this->name
  * @param bool $recursively - Note: only for first level of sub directory, other levels of sub directories will be ignored
  * @param string $moduleName - name of module if exists
  *
  * @return string - content of the files
  */
 protected function unifySingle($dirPath, $type, $recursively = false, $moduleName = '')
 {
     if (empty($dirPath) || !file_exists($dirPath)) {
         return false;
     }
     $unsetFileName = $this->params['unsetFileName'];
     //get matadata files
     $fileList = $this->getFileManager()->getFileList($dirPath, $recursively, '\\.json$');
     $dirName = $this->getFileManager()->getDirName($dirPath, false);
     $defaultValues = $this->loadDefaultValues($dirName, $type);
     $content = array();
     $unsets = array();
     foreach ($fileList as $dirName => $fileName) {
         if (is_array($fileName)) {
             /*get content from files in a sub directory*/
             $content[$dirName] = $this->unifySingle(Utils\Util::concatPath($dirPath, $dirName), $type, false, $moduleName);
             //only first level of a sub directory
         } else {
             /*get content from a single file*/
             if ($fileName == $unsetFileName) {
                 $fileContent = $this->getFileManager()->getContents(array($dirPath, $fileName));
                 $unsets = Utils\Json::getArrayData($fileContent);
                 continue;
             }
             /*END: Save data from unset.json*/
             $mergedValues = $this->unifyGetContents(array($dirPath, $fileName), $defaultValues);
             if (!empty($mergedValues)) {
                 $name = $this->getFileManager()->getFileName($fileName, '.json');
                 $content[$name] = $mergedValues;
             }
         }
     }
     //unset content
     $content = Utils\Util::unsetInArray($content, $unsets);
     //END: unset content
     return $content;
 }
예제 #6
0
 /**
  * Schema convertation process
  *
  * @param  array  $ormMeta
  * @param  array|null $entityList
  *
  * @return \Doctrine\DBAL\Schema\Schema
  */
 public function process(array $ormMeta, $entityList = null)
 {
     $GLOBALS['log']->debug('Schema\\Converter - Start: building schema');
     //check if exist files in "Tables" directory and merge with ormMetadata
     $ormMeta = Util::merge($ormMeta, $this->getCustomTables($ormMeta));
     //unset some keys in orm
     if (isset($ormMeta['unset'])) {
         $ormMeta = Util::unsetInArray($ormMeta, $ormMeta['unset']);
         unset($ormMeta['unset']);
     }
     //END: unset some keys in orm
     if (isset($entityList)) {
         $entityList = is_string($entityList) ? (array) $entityList : $entityList;
         $dependentEntities = $this->getDependentEntities($entityList, $ormMeta);
         $GLOBALS['log']->debug('Rebuild Database for entities: [' . implode(', ', $entityList) . '] with dependent entities: [' . implode(', ', $dependentEntities) . ']');
         $ormMeta = array_intersect_key($ormMeta, array_flip($dependentEntities));
     }
     $schema = $this->getSchema(true);
     $tables = array();
     foreach ($ormMeta as $entityName => $entityParams) {
         $tableName = Util::toUnderScore($entityName);
         if ($schema->hasTable($tableName)) {
             if (!isset($tables[$entityName])) {
                 $tables[$entityName] = $schema->getTable($tableName);
             }
             $GLOBALS['log']->debug('DBAL: Table [' . $tableName . '] exists.');
             continue;
         }
         $tables[$entityName] = $schema->createTable($tableName);
         $primaryColumns = array();
         $uniqueColumns = array();
         $indexList = array();
         //list of indexes like array( array(comlumn1, column2), array(column3))
         foreach ($entityParams['fields'] as $fieldName => $fieldParams) {
             if (isset($fieldParams['notStorable']) && $fieldParams['notStorable'] || in_array($fieldParams['type'], $this->notStorableTypes)) {
                 continue;
             }
             switch ($fieldParams['type']) {
                 case 'id':
                     $primaryColumns[] = Util::toUnderScore($fieldName);
                     break;
             }
             $fieldType = isset($fieldParams['dbType']) ? $fieldParams['dbType'] : $fieldParams['type'];
             $fieldType = strtolower($fieldType);
             /** doctrine uses strtolower for all field types */
             if (!in_array($fieldType, $this->typeList)) {
                 $GLOBALS['log']->debug('Converters\\Schema::process(): Field type [' . $fieldType . '] does not exist ' . $entityName . ':' . $fieldName);
                 continue;
             }
             $columnName = Util::toUnderScore($fieldName);
             if (!$tables[$entityName]->hasColumn($columnName)) {
                 $tables[$entityName]->addColumn($columnName, $fieldType, $this->getDbFieldParams($fieldParams));
             }
             //add unique
             if ($fieldParams['type'] != 'id' && isset($fieldParams['unique'])) {
                 $uniqueColumns = $this->getKeyList($columnName, $fieldParams['unique'], $uniqueColumns);
             }
             //END: add unique
             //add index. It can be defined in entityDefs as "index"
             if (isset($fieldParams['index'])) {
                 $indexList = $this->getKeyList($columnName, $fieldParams['index'], $indexList);
             }
             //END: add index
         }
         $tables[$entityName]->setPrimaryKey($primaryColumns);
         //add indexes
         if (isset($entityParams['indexes']) && is_array($entityParams['indexes'])) {
             foreach ($entityParams['indexes'] as $indexName => $indexParams) {
                 if (is_array($indexParams['columns'])) {
                     $tableIndexName = $this->generateIndexName($indexName, $entityName);
                     $indexList[$tableIndexName] = Util::toUnderScore($indexParams['columns']);
                 }
             }
         }
         if (!empty($indexList)) {
             foreach ($indexList as $indexName => $indexItem) {
                 $tableIndexName = is_string($indexName) ? $indexName : null;
                 $tables[$entityName]->addIndex($indexItem, $tableIndexName);
             }
         }
         if (!empty($uniqueColumns)) {
             foreach ($uniqueColumns as $uniqueItem) {
                 $tables[$entityName]->addUniqueIndex($uniqueItem);
             }
         }
     }
     //check and create columns/tables for relations
     foreach ($ormMeta as $entityName => $entityParams) {
         if (!isset($entityParams['relations'])) {
             continue;
         }
         foreach ($entityParams['relations'] as $relationName => $relationParams) {
             switch ($relationParams['type']) {
                 case 'manyMany':
                     $tableName = $relationParams['relationName'];
                     //check for duplication tables
                     if (!isset($tables[$tableName])) {
                         //no needs to create the table if it already exists
                         $tables[$tableName] = $this->prepareManyMany($entityName, $relationParams, $tables);
                     }
                     break;
                 case 'belongsTo':
                     $columnName = Util::toUnderScore($relationParams['key']);
                     $tables[$entityName]->addIndex(array($columnName));
                     break;
             }
         }
     }
     //END: check and create columns/tables for relations
     $GLOBALS['log']->debug('Schema\\Converter - End: building schema');
     return $schema;
 }
예제 #7
0
 public function afterProcess(array $ormMeta)
 {
     $entityDefs = $this->getEntityDefs();
     //load custom field definitions and customCodes
     foreach ($ormMeta as $entityName => &$entityParams) {
         foreach ($entityParams['fields'] as $fieldName => $fieldParams) {
             //load custom field definitions
             $fieldType = ucfirst($fieldParams['type']);
             $className = '\\Espo\\Custom\\Core\\Utils\\Database\\Orm\\Fields\\' . $fieldType;
             if (!class_exists($className)) {
                 $className = '\\Espo\\Core\\Utils\\Database\\Orm\\Fields\\' . $fieldType;
             }
             if (class_exists($className) && method_exists($className, 'load')) {
                 $helperClass = new $className($this->metadata, $ormMeta, $entityDefs);
                 $fieldResult = $helperClass->process($fieldName, $entityName);
                 if (isset($fieldResult['unset'])) {
                     $ormMeta = Util::unsetInArray($ormMeta, $fieldResult['unset']);
                     unset($fieldResult['unset']);
                 }
                 $ormMeta = Util::merge($ormMeta, $fieldResult);
             }
             //END: load custom field definitions
             //todo move to separate file
             //add a field 'isFollowed' for scopes with 'stream => true'
             $scopeDefs = $this->getMetadata()->get('scopes.' . $entityName);
             if (isset($scopeDefs['stream']) && $scopeDefs['stream']) {
                 if (!isset($entityParams['fields']['isFollowed'])) {
                     $entityParams['fields']['isFollowed'] = array('type' => 'varchar', 'notStorable' => true);
                 }
             }
             //END: add a field 'isFollowed' for stream => true
         }
     }
     foreach ($ormMeta as $entityName => &$entityParams) {
         foreach ($entityParams['fields'] as $fieldName => &$fieldParams) {
             switch ($fieldParams['type']) {
                 case 'id':
                     if ($fieldParams['dbType'] != 'int') {
                         $fieldParams = array_merge($fieldParams, $this->idParams);
                     }
                     break;
                 case 'foreignId':
                     $fieldParams = array_merge($fieldParams, $this->idParams);
                     $fieldParams['notNull'] = false;
                     break;
                 case 'foreignType':
                     $fieldParams['dbType'] = Entity::VARCHAR;
                     $fieldParams['len'] = $this->defaultLength['varchar'];
                     break;
                 case 'bool':
                     $fieldParams['default'] = isset($fieldParams['default']) ? (bool) $fieldParams['default'] : $this->defaultValue['bool'];
                     break;
             }
         }
     }
     return $ormMeta;
 }