diff --git a/application/Espo/Core/Application.php b/application/Espo/Core/Application.php index 900ea94590..4e26402246 100644 --- a/application/Espo/Core/Application.php +++ b/application/Espo/Core/Application.php @@ -79,11 +79,11 @@ class Application $this->getMetadata()->init($isNotCached); if ($isNotCached) { - $doctrineConverter = new \Espo\Core\Doctrine\EspoConverter($this->container->get('entityManager'), $this->getMetadata(), $this->container->get('fileManager')); + $doctrineConverter = new \Espo\Core\Doctrine\Converter\Base($this->container->get('entityManager'), $this->getMetadata(), $this->container->get('fileManager')); - if ($doctrineConverter->convertToDoctrine()) { + if ($doctrineConverter->process()) { try{ - $doctrineConverter->rebuildDatabase(); + $doctrineConverter->getDoctrineHelper()->rebuildDatabase(); } catch (\Exception $e) { $GLOBALS['log']->add('EXCEPTION', 'Fault to rebuildDatabase'.'. Details: '.$e->getMessage()); } diff --git a/application/Espo/Core/Doctrine/Converter/Association.php b/application/Espo/Core/Doctrine/Converter/Association.php new file mode 100644 index 0000000000..a4162eeea4 --- /dev/null +++ b/application/Espo/Core/Doctrine/Converter/Association.php @@ -0,0 +1,197 @@ + array( + 'manyToOne' => array( + $params['usLinkName'] => array( + 'targetEntity' => $params['targetEntity'], + 'joinColumn' => array( + 'name' => $params['usLinkName'].'_id', + 'referencedColumnName' => 'id', + ), + ), + ), + ), + ); + } + + + public function oneToManyUnidirectionalWithJoinTable($params, $foreignParams) + { + return array ( + $params['entityName'] => + array ( + 'manyToMany' => + array ( + $params['usLinkName'] => + array ( + 'targetEntity' => $params['targetEntity'], + 'joinTable' => + array ( + 'name' => $params['joinTable'], + 'joinColumns' => + array ( + $params['usEntityName'].'_id' => + array ( + 'referencedColumnName' => 'id', + ), + ), + 'inverseJoinColumns' => + array ( + $foreignParams['usEntityName'].'_id' => + array ( + 'referencedColumnName' => 'id', + 'unique' => true, + ), + ), + ), + ), + ), + ), + ); + } + + + public function manyToManyBidirectional($params, $foreignParams) + { + return array ( + $params['entityName'] => + array ( + 'manyToMany' => + array ( + $params['usLinkName'] => + array ( + 'targetEntity' => $params['targetEntity'], + 'inversedBy' => $foreignParams['usLinkName'], + 'joinTable' => + array ( + 'name' => $params['joinTable'], + 'joinColumns' => + array ( + $params['usEntityName'].'_id' => + array ( + 'referencedColumnName' => 'id', + ), + ), + 'inverseJoinColumns' => + array ( + $foreignParams['usEntityName'].'_id' => + array ( + 'referencedColumnName' => 'id', + ), + ), + ), + ), + ), + ), + + $foreignParams['entityName'] => + array ( + 'manyToMany' => + array ( + $foreignParams['usLinkName'] => + array ( + 'targetEntity' => $foreignParams['targetEntity'], + 'mappedBy' => $params['usLinkName'], + ), + ), + ), + ); + } + + public function oneToOneUnidirectional($params, $foreignParams) + { + return array ( + $params['entityName'] => + array ( + 'oneToOne' => + array ( + $params['usLinkName'] => + array ( + 'targetEntity' => $params['targetEntity'], + 'joinColumn' => + array ( + 'name' => $params['usLinkName'].'_id', + 'referencedColumnName' => 'id', + ), + ), + ), + ), + ); + } + + public function oneToOneBidirectional($params, $foreignParams) + { + return array ( + $params['entityName'] => + array ( + 'oneToOne' => + array ( + $params['usLinkName'] => + array ( + 'targetEntity' => $params['targetEntity'], + 'mappedBy' => $foreignParams['usLinkName'], + ), + ), + ), + + $foreignParams['entityName'] => + array ( + 'oneToOne' => + array ( + $foreignParams['usLinkName'] => + array ( + 'targetEntity' => $foreignParams['targetEntity'], + 'inversedBy' => $params['usLinkName'], + 'joinColumn' => + array ( + 'name' => $params['usLinkName'].'_id', + 'referencedColumnName' => 'id', + ), + ), + ), + ), + ); + } + + public function oneToManySelfReferencing($params, $foreignParams) + { + return array ( + 'Category' => + array ( + 'type' => 'entity', + 'oneToMany' => + array ( + 'children' => + array ( + 'targetEntity' => 'Category', + 'mappedBy' => 'parent', + ), + ), + 'manyToOne' => + array ( + 'parent' => + array ( + 'targetEntity' => 'Category', + 'inversedBy' => 'children', + ), + ), + ), + ); + } + + + + + + + +} \ No newline at end of file diff --git a/application/Espo/Core/Doctrine/Converter/Base.php b/application/Espo/Core/Doctrine/Converter/Base.php new file mode 100644 index 0000000000..b5a81e5f3e --- /dev/null +++ b/application/Espo/Core/Doctrine/Converter/Base.php @@ -0,0 +1,336 @@ + 'type', + 'maxLength' => 'length', + 'default' => array( + 'condition' => '^javascript:', + 'conditionEquals' => false, + 'value' => array( + 'options' => array ( + 'default' => '{0}', + ), + ), + ), + ); + + + /** + * @var array $meta - metadata array + */ + private $meta; + + + public function __construct(\Espo\Core\EntityManager $entityManager, \Espo\Core\Utils\Metadata $metadata, \Espo\Core\Utils\File\Manager $fileManager) + { + $this->entityManager = $entityManager; + $this->metadata = $metadata; + $this->fileManager = $fileManager; + + $this->doctrineHelper = new \Espo\Core\Doctrine\Helper($this->getEntityManager()->getWrapped()); + + $this->linkConverter = new \Espo\Core\Doctrine\Converter\Link($this->metadata); + } + + protected function getEntityManager() + { + return $this->entityManager; + } + + protected function getMetadata() + { + return $this->metadata; + } + + protected function getFileManager() + { + return $this->fileManager; + } + + protected function getDoctrineHelper() + { + return $this->doctrineHelper; + } + + protected function getLinkConverter() + { + return $this->linkConverter; + } + + /** + * Metadata conversion from Espo format into Doctrine + * + * @param object $meta + * + * @return bool + */ + + //public function process() + public function process() + { + //echo '
';
+ $GLOBALS['log']->add('Debug', 'Metadata:get() - converting to doctrine metadata');
+
+ $entityDefs = $this->getMetadata()->get('entityDefs');
+
+ $convertedMeta = array();
+ foreach($entityDefs as $entityName => $entityMeta) {
+
+ //echo '['.$entityName.']
';
+
+ if (empty($entityMeta)) {
+ $GLOBALS['log']->add('ERROR', 'EspoConverter:convert(), Entity:'.$entityName.' - metadata cannot be converted into Doctrine format');
+ continue;
+ }
+
+ $convertedMeta[$entityName] = array(
+ 'type' => 'entity',
+ 'table' => Util::fromCamelCase($entityName, '_'), //TODO: if need to convert to underscore
+ 'id' => array(
+ 'id' => array(
+ 'type' => 'string',
+ 'generator' => array('strategy' => 'UUID'),
+ )
+ ),
+ );
+
+ $convertedMeta[$entityName]['fields'] = $this->convertFields($entityName, $entityMeta);
+
+ $convertedLinks = $this->convertLinks($entityName, $entityMeta, $entityDefs, $convertedMeta);
+
+ //$convertedMeta = Util::merge($convertedMeta, $convertedLinks); //for link is need to define for two entities at once
+ }
+
+
+
+ /*echo '
';
+ print_r($convertedMeta);
+ exit;*/
+
+ return;
+
+ //save doctrine meta to files
+ $cacheDir = $this->getMetadata()->getMetaConfig()->doctrineCache;
+ $this->getFileManager()->removeFilesInDir($cacheDir); //remove all existing files
+
+ $result= true;
+ foreach ($convertedMeta as $entityName => $doctineMeta) {
+ $entityFullName = $this->getMetadata()->getEntityPath($entityName);
+ $doctrineMeta = array($entityFullName => $doctineMeta);
+
+ //create a doctrine metadata file like "Espo.Entities.User.php"
+ $fileName = str_replace('\\', '.', $entityFullName).'.php';
+ $result &= $this->getFileManager()->setContent($this->getFileManager()->getPHPFormat($doctrineMeta), $cacheDir, $fileName);
+ //END: create a doctrine metadata file
+ }
+ //END: save doctrine meta to files
+
+ return $result;
+ }
+
+
+ /**
+ * Metadata conversion from Espo format into Doctrine
+ *
+ * @param string $entityName
+ * @param array $entityMeta
+ *
+ * @return array
+ */
+ protected function convertFields($entityName, $entityMeta)
+ {
+ $outputMeta = array();
+ foreach($entityMeta['fields'] as $fieldName => $fieldParams) {
+
+ $fieldName = Util::fromCamelCase($fieldName, '_');
+
+ //check if "fields" option exists in $fieldMeta
+ $fieldTypeMeta = $this->getMetadata()->get('fields.'.$fieldParams['type']);
+ if (isset($fieldTypeMeta['fields']) && is_array($fieldTypeMeta['fields'])) {
+
+ $namingType = isset($fieldTypeMeta['naming']) ? $fieldTypeMeta['naming'] : $this->defaultNaming;
+ foreach($fieldTypeMeta['fields'] as $subFieldName => $subFieldParams) {
+
+ $subFieldNameNaming = Util::fromCamelCase( Util::getNaming($fieldName, $subFieldName, $namingType, '_'), '_' );
+ if (!isset($entityMeta['fields'][$subFieldNameNaming])) {
+ $subFieldDefs = $this->convertField($entityName, $subFieldName, $subFieldParams);
+ if ($subFieldDefs !== false) {
+ $outputMeta[$subFieldNameNaming] = $subFieldDefs; //push fieldDefs to the main array
+ }
+ }
+
+ }
+
+ } else {
+ $fieldDefs = $this->convertField($entityName, $fieldName, $fieldParams);
+ if ($fieldDefs !== false) {
+ $outputMeta[$fieldName] = $fieldDefs; //push fieldDefs to the main array
+ }
+ }
+
+
+ /*Make actions for different types like "link", "linkMultiple", "linkParent" */
+ }
+
+ return $outputMeta;
+ }
+
+
+
+ /*It can be moved to separate file*/
+ protected function convertField($entityName, $fieldName, array $fieldParams)
+ {
+ //set default type if exists
+ if (!isset($fieldParams['type']) || empty($fieldParams['type'])) {
+ $GLOBALS['log']->add('WARNING', 'Field type does not exist for '.$entityName.':'.$fieldName.'. Use default type ['.$this->defaultFieldType.']');
+ $fieldParams['type'] = $this->defaultFieldType;
+ } //END: set default type if exists
+
+ $fieldTypeMeta = $this->getMetadata()->get('fields.'.$fieldParams['type']);
+
+ //check if field need to be saved in database
+ if ( (isset($fieldParams['db']) && $fieldParams['db'] === false) || (isset($fieldTypeMeta['database']['db']) && !$fieldTypeMeta['database']['db'] === false) ) {
+ return false;
+ } //END: check if field need to be saved in database
+
+ $fieldDefs = $this->getInitValues($fieldParams);
+
+ //merge database options from field definition
+ if (isset($fieldTypeMeta['database'])) {
+ $fieldDefs = Util::merge($fieldDefs, $fieldTypeMeta['database']);
+ }
+
+ return $fieldDefs;
+ }
+
+
+
+ protected function convertLinks($entityName, $entityMeta, array $entityDefs, array $convertedMeta)
+ {
+ if (!isset($entityMeta['links'])) {
+ return array();
+ }
+
+ foreach($entityMeta['links'] as $linkName => $linkParams) {
+ //echo $linkName.'
';
+ //print_r($linkParams);
+
+ $linkEntityName = $this->getLinkConverter()->getLinkEntityName($entityName, $linkParams);
+ //print_r($entityDefs[$linkEntityName]['links']);
+ //print_r($convertedMeta[$linkEntityName]);
+
+ $currentType = $linkParams['type'];
+ $parentType = '';
+
+ $foreignLink = $this->getForeignLink($linkName, $linkParams, $entityDefs[$linkEntityName]);
+
+ $method = $currentType;
+ if ($foreignLink !== false) {
+ $method .= '-'.$foreignLink['params']['type'];
+ }
+ $method = Util::toCamelCase($method);
+
+
+ /*if ($method == 'belongsToParent') {
+ die($entityName.' - '.$linkName);
+ }*/
+
+
+ if (method_exists($this->getLinkConverter(), $method)) {
+ $convertedLink = $this->getLinkConverter()->process($method, $entityName, array('name'=>$linkName, 'params'=>$linkParams), $foreignLink);
+ //print_r($convertedLink);
+ }
+
+ //echo $method.' = '.$currentType.' - '.$foreignLink['type'].'
';
+
+
+ }
+
+ return $convertedMeta;
+ }
+
+
+ /**
+ * Get foreign Link
+ *
+ * @param string $parentLinkName
+ * @param array $parentLinkParams
+ * @param array $currentEntityDefs
+ *
+ * @return array - in format array('name', 'params')
+ */
+ protected function getForeignLink($parentLinkName, $parentLinkParams, $currentEntityDefs)
+ {
+ if (isset($parentLinkParams['foreign']) && isset($currentEntityDefs['links'][$parentLinkParams['foreign']])) {
+ return array(
+ 'name' => $parentLinkParams['foreign'],
+ 'params' => $currentEntityDefs['links'][$parentLinkParams['foreign']],
+ );
+ }
+
+ $parentLinkName = strtolower($parentLinkName);
+
+ foreach($currentEntityDefs['links'] as $linkName => $linkParams) {
+ if (isset($linkParams['foreign']) && strtolower($linkParams['foreign']) == $parentLinkName) {
+ return array(
+ 'name' => $linkName,
+ 'params' => $linkParams,
+ );
+ }
+ }
+
+ return false;
+ }
+
+
+
+ protected function getInitValues(array $fieldParams)
+ {
+ $values = array();
+ foreach($this->fieldAccordances as $espoType => $doctrineType) {
+
+ if (isset($fieldParams[$espoType]) && !empty($fieldParams[$espoType])) {
+
+ if (is_array($doctrineType)) {
+
+ $conditionRes = false;
+ if (!is_array($fieldParams[$espoType])) {
+ $conditionRes = preg_match('/'.$doctrineType['condition'].'/i', $fieldParams[$espoType]);
+ }
+
+ if (!$conditionRes || ($conditionRes && $conditionRes === $doctrineType['conditionEquals']) ) {
+ $value = is_array($fieldParams[$espoType]) ? json_encode($fieldParams[$espoType]) : $fieldParams[$espoType];
+ $values = Util::merge( $values, Util::replaceInArray('{0}', $value, $doctrineType['value']) );
+ }
+ } else {
+ $values[$doctrineType] = $fieldParams[$espoType];
+ }
+
+ }
+ }
+
+ return $values;
+ }
+
+}
+
+
+?>
\ No newline at end of file
diff --git a/application/Espo/Core/Doctrine/Converter/Link.php b/application/Espo/Core/Doctrine/Converter/Link.php
new file mode 100644
index 0000000000..cbf0aae490
--- /dev/null
+++ b/application/Espo/Core/Doctrine/Converter/Link.php
@@ -0,0 +1,169 @@
+metadata = $metadata;
+
+ $this->association = new \Espo\Core\Doctrine\Converter\Association();
+ }
+
+ protected function getMetadata()
+ {
+ return $this->metadata;
+ }
+
+ protected function getAssociation()
+ {
+ return $this->association;
+ }
+
+
+ public function getLinkEntityName($entityName, $link)
+ {
+ if (isset($link['params'])) {
+ return isset($link['params']['entity']) ? $link['params']['entity'] : $entityName;
+ }
+ return isset($link['entity']) ? $link['entity'] : $entityName;
+ }
+
+ public function toUnderScore($name)
+ {
+ return Util::fromCamelCase($name, '_');
+ }
+
+ protected function getJoinTable($tableName1, $tableName2)
+ {
+ $tables = array(
+ $this->toUnderScore($tableName1),
+ $this->toUnderScore($tableName2),
+ );
+
+ asort($tables);
+
+ return implode('_', $tables);
+ }
+
+
+ public function process($method, $entityName, $link, $foreignLink = array())
+ {
+ $params = array();
+ $params['entityName'] = $entityName;
+ $params['usEntityName'] = $this->toUnderScore($entityName);
+ $params['link'] = $link;
+ $params['usLinkName'] = $this->toUnderScore($link['name']);
+
+ $foreignParams = array();
+ $foreignParams['entityName'] = $this->getLinkEntityName($entityName, $link);
+ $foreignParams['usEntityName'] = $this->toUnderScore($foreignParams['entityName']);
+ $foreignParams['link'] = $foreignLink;
+ $foreignParams['usLinkName'] = $this->toUnderScore($foreignParams['link']['name']);
+
+ $params['targetEntity'] = $this->getMetadata()->getEntityPath($foreignParams['entityName']);
+ $foreignParams['targetEntity'] = $this->getMetadata()->getEntityPath($params['entityName']);
+
+ $params['joinTable'] = $foreignParams['targetEntity'] = $this->getJoinTable($params['entityName'], $foreignParams['entityName']);
+
+
+ if (method_exists($this, $method)) {
+ return $this->$method($params, $foreignParams);
+ }
+
+ return false;
+ }
+
+
+
+ protected function belongsTo($params, $foreignParams)
+ {
+ return $this->getAssociation()->manyToOneUnidirectional($params, $foreignParams);
+ }
+
+
+ //TODO: hook for teams
+ protected function hasMany($params, $foreignParams)
+ {
+ return $this->getAssociation()->oneToManyUnidirectionalWithJoinTable($params, $foreignParams);
+ }
+
+
+ protected function hasManyHasMany($params, $foreignParams)
+ {
+ return $this->getAssociation()->manyToManyBidirectional($params, $foreignParams);
+ }
+
+ protected function hasOne($params, $foreignParams)
+ {
+ return $this->getAssociation()->oneToOneUnidirectional($params, $foreignParams);
+ }
+
+ protected function hasOneBelongsTo($params, $foreignParams)
+ {
+ return $this->getAssociation()->oneToOneBidirectional($params, $foreignParams);
+ }
+
+
+ protected function belongsToParent($params, $foreignParams)
+ {
+ return $this->getAssociation()->oneToManySelfReferencing($params, $foreignParams);
+ }
+
+
+
+
+ /*
+ +[0] => belongsTo
+ [1] => belongsToParent
+ [2] => hasManyBelongsToParent
+ +[3] => hasMany
+ [4] => hasChildrenBelongsToParent
+ +[5] => hasOne
+ +[6] => hasManyHasMany
+ [7] => hasManyBelongsTo
+ [8] => hasChildrenHasMany
+ [9] => hasChildren
+ [10] => belongsToHasMany
+ [11] => joint
+
+
+ [0] => belongsTo
+ [1] => belongsToParent
+ [2] => hasManyBelongsToParent
+ [3] => hasMany
+ [4] => hasChildrenBelongsToParent
+ [5] => belongsToParentHasChildren
+ [6] => hasOne
+ [7] => hasManyBelongsTo
+ [8] => hasManyHasMany
+ [9] => belongsToHasMany
+ [10] => joint
+
+
+
+
+ [0] => belongsTo
+ [1] => belongsToParent
+ [2] => hasManyBelongsToParent
+ [3] => hasMany
+ [4] => hasChildrenBelongsToParent
+ [5] => belongsToParentHasChildren
+ [6] => hasOne
+ [7] => hasManyHasMany
+ [8] => hasManyBelongsTo
+ [9] => hasChildrenHasMany
+ [10] => hasChildren
+ [11] => belongsToHasMany
+ [12] => joint
+ */
+
+}
\ No newline at end of file
diff --git a/application/Espo/Core/Doctrine/EspoConverter.php b/application/Espo/Core/Doctrine/EspoConverter.php
deleted file mode 100644
index d68a9ae361..0000000000
--- a/application/Espo/Core/Doctrine/EspoConverter.php
+++ /dev/null
@@ -1,327 +0,0 @@
-entityManager = $entityManager;
- $this->metadata = $metadata;
- $this->fileManager = $fileManager;
-
- $this->doctrineHelper = new \Espo\Core\Doctrine\Helper($this->getEntityManager()->getWrapped());
- }
-
- protected function getEntityManager()
- {
- return $this->entityManager;
- }
-
- protected function getMetadata()
- {
- return $this->metadata;
- }
-
- protected function getFileManager()
- {
- return $this->fileManager;
- }
-
- protected function getSchemaTool()
- {
- return $this->schemaTool;
- }
-
- protected function getDisconnectedClassMetadataFactory()
- {
- return $this->disconnectedClassMetadataFactory;
- }
-
- protected function getEntityGenerator()
- {
- return $this->entityGenerator;
- }
-
-
-
- public function setMeta(array $meta)
- {
- $this->meta = $meta;
- }
-
- protected function getMeta()
- {
- return $this->meta;
- }
-
- protected function getFieldMeta($type = '')
- {
- $meta = $this->getMeta();
- if (empty($type)) {
- return $meta['fields'];
- }
- else if (isset($meta['fields'][$type])) {
- return $meta['fields'][$type];
- }
-
- return false;
- }
-
-
- /**
- * Metadata conversion from Espo format into Doctrine
- *
- * @param object $meta
- *
- * @return bool
- */
- public function convertToDoctrine()
- {
- $GLOBALS['log']->add('Debug', 'Metadata:get() - converting to doctrine metadata');
-
- $meta = $this->getMetadata()->getAll();
-
- return; //TODO
- $this->setMeta($meta);
-
- $cacheDir = $this->getMetadata()->getMetaConfig()->doctrineCache;
- $this->getFileManager()->removeFilesInDir($cacheDir); //remove all existing files
-
- //create files named like "Espo.Entities.User.php"
-
- $convertedMeta = array();
- foreach($meta[$this->getMetadata()->getMetaConfig()->espoMetadataName] as $entityName => $metaRow) {
-
- $convertedMeta[$entityName] = $this->convert($entityName, $metaRow);
- //$convertedMeta = Util::merge($convertedMeta, $this->convert($entityName, $metaRow)); //for link is need to define for two entities at once
- }
-
-
- /*echo '';
- print_r($convertedMeta);
- exit;*/
-
- //save doctrine meta to files
- $result= true;
- foreach ($convertedMeta as $entityName => $doctineMeta) {
- $entityFullName = $this->getMetadata()->getEntityPath($entityName);
- $doctrineMeta = array($entityFullName => $doctineMeta);
-
- //create a doctrine metadata file
- $fileName = str_replace('\\', '.', $entityFullName).'.php';
- $result &= $this->getFileManager()->setContent($this->getFileManager()->getPHPFormat($doctrineMeta), $cacheDir, $fileName);
- //END: create a doctrine metadata file
- }
- //END: save doctrine meta to files
-
- return $result;
- }
-
-
- /**
- * Rebuild a database accordinly to metadata
- *
- * @return bool
- */
- public function rebuildDatabase()
- {
- $GLOBALS['log']->add('DEBUG', 'EspoConverter:rebuildDatabase() - start rebuild database');
-
- $classes = $this->getDisconnectedClassMetadataFactory()->getAllMetadata();
- $this->getSchemaTool()->updateSchema($classes);
-
- $GLOBALS['log']->add('DEBUG', 'EspoConverter:rebuildDatabase() - end rebuild database');
-
- return true; //always true, because updateSchema just returns the VOID
- }
-
- /**
- * Rebuild a database accordinly to metadata
- *
- * @return bool
- */
- public function generateEntities($classNames)
- {
- if (!is_array($classNames)) {
- $classNames= (array) $classNames;
- }
-
- $metadata= array();
- foreach($classNames as $className) {
- $metadata[]= $this->getDisconnectedClassMetadataFactory()->getMetadataFor($className);
- }
-
- if (!empty($metadata)) {
- $GLOBALS['log']->add('DEBUG', 'EspoConverter:generateEntities() - start generate Entities');
-
- $this->getEntityGenerator()->setGenerateAnnotations(false);
- $this->getEntityGenerator()->setGenerateStubMethods(true);
- $this->getEntityGenerator()->setRegenerateEntityIfExists(false);
- $this->getEntityGenerator()->setUpdateEntityIfExists(false);
- $this->getEntityGenerator()->generate($metadata, 'application');
-
- $GLOBALS['log']->add('DEBUG', 'EspoConverter:generateEntities() - end generate Entities');
-
- return true; //always true, because generate just returns the VOID
- }
-
- return false;
- }
-
-
- /**
- * Metadata conversion from Espo format into Doctrine
- *
- * @param string $name
- * @param array $data
- *
- * @return array
- */
- //NEED TO CHANGE
- protected function convert($entityName, $meta)
- {
- if (empty($meta)) {
- $GLOBALS['log']->add('ERROR', 'EspoConverter:convert(), Entity:'.$entityName.' - metadata cannot be converted into Doctrine format');
- }
-
- //conversion functionality
- $outputMeta = array(
- 'type' => 'entity',
- 'table' => $entityName, //TODO: if need to convert to underscore
- 'id' => array(
- 'id' => array(
- 'type' => 'string',
- 'generator' => array('strategy' => 'UUID'),
- )
- ),
- 'fields' => array(
- ),
- );
-
- $outputMeta = Util::merge($outputMeta, $this->convertFields($entityName, $meta));
- //$outputMeta = Util::merge($outputMeta, $this->convertLinks($meta));
- //END: conversion functionality
-
-
- return $outputMeta;
- }
-
-
-
- /*It can be moved to separate file*/
- protected function convertFields($entityName, array $meta)
- {
- $metaFields = $meta['fields'];
-
- $convertedMetaFields = array();
- foreach($meta['fields'] as $fieldName => $fieldParams) {
-
- //set default type if exists
- if (!isset($fieldParams['type']) || !empty($fieldParams['type'])) {
- $GLOBALS['log']->add('WARNING', 'Field type does not exist for '.$entityName.':'.$fieldName.'. Use default type ['.$this->defaultFieldType.']');
- $fieldParams['type'] = $this->defaultFieldType;
- } //END: set default type if exists
-
- $fieldMeta = $this->getFieldMeta($fieldParams['type']);
-
- //check if field need to be saved in database
- if ( (isset($fieldParams['db']) && $fieldParams['db'] === false) || (isset($fieldMeta['database']['db']) && !$fieldMeta['database']['db'] === false) ) {
- continue;
- } //END: check if field need to be saved in database
-
- $convertedMetaFields[$fieldName] = $this->getInitValues($fieldParams);
-
-
- /*echo '';
- print_r($convertedMetaFields[$fieldName]);
- exit;*/
-
- //convert type
- $convertedMetaFields[$fieldName]['type'] = $this->getFieldType($fieldParams['type']);
- //END: convert type
- }
-
-
- /*echo '
'.$entityName.'';
- print_r($convertedMetaFields); */
- }
-
- protected function getFieldType($espoType)
- {
- $fieldMeta = $this->getFieldMeta($espoType);
-
- if (isset($fieldMeta['database']['type']) && !empty($fieldMeta['database']['type'])) {
- return $fieldMeta['database']['type'];
- }
-
- return $espoType;
- }
-
- protected function getInitValues(array $fieldParams)
- {
- //pair espo:doctrine
- $convertRules = array(
- 'type' => 'type',
- 'maxLength' => 'length',
- 'default' => array(
- 'condition' => '!(^javascript)',
- 'json' => '{"options":{"default":{0}}}',
- ),
- );
-
-
- $values = array();
- foreach($convertRules as $espoType => $doctrineType) {
-
- if (isset($fieldParams[$espoType]) && !empty($fieldParams[$espoType])) {
-
- if (is_array($doctrineType)) {
-
- //print_r($fieldParams);
- //echo $doctrineType['condition'].' '.$fieldParams[$espoType];
-
- //if (preg_match('/'.$doctrineType['condition'].'/i', $fieldParams[$espoType])) {
- $jsonValue = json_encode($fieldParams[$espoType]);
- $jsonRes = str_replace('{0}', $jsonValue, $doctrineType['json']);
- $values = Util::merge($values, json_decode($jsonRes, true));
- //}
- } else {
- $values[$doctrineType] = $fieldParams[$espoType];
- }
- }
- }
-
- return $values;
- }
-
-
-
-
- protected function convertLinks(array $meta)
- {
- $metaFields = $meta['links'];
-
- }
-
-}
-
-
-?>
\ No newline at end of file
diff --git a/application/Espo/Core/Doctrine/Helper.php b/application/Espo/Core/Doctrine/Helper.php
index 5a2a75efc6..6ceaab3578 100644
--- a/application/Espo/Core/Doctrine/Helper.php
+++ b/application/Espo/Core/Doctrine/Helper.php
@@ -13,7 +13,7 @@ class Helper
private $entityGenerator;
- public function __construct(\Espo\Core\EntityManager $entityManager)
+ public function __construct(\Doctrine\ORM\EntityManager $entityManager)
{
$this->entityManager = $entityManager;
@@ -45,4 +45,57 @@ class Helper
}
+
+ /**
+ * Rebuild a database accordinly to metadata
+ *
+ * @return bool
+ */
+ public function rebuildDatabase()
+ {
+ $GLOBALS['log']->add('DEBUG', 'EspoConverter:rebuildDatabase() - start rebuild database');
+
+ $classes = $this->getDisconnectedClassMetadataFactory()->getAllMetadata();
+ $this->getSchemaTool()->updateSchema($classes);
+
+ $GLOBALS['log']->add('DEBUG', 'EspoConverter:rebuildDatabase() - end rebuild database');
+
+ return true; //always true, because updateSchema just returns the VOID
+ }
+
+
+ /**
+ * Rebuild a database accordinly to metadata
+ *
+ * @return bool
+ */
+ public function generateEntities($classNames)
+ {
+ if (!is_array($classNames)) {
+ $classNames= (array) $classNames;
+ }
+
+ $metadata= array();
+ foreach($classNames as $className) {
+ $metadata[]= $this->getDisconnectedClassMetadataFactory()->getMetadataFor($className);
+ }
+
+ if (!empty($metadata)) {
+ $GLOBALS['log']->add('DEBUG', 'EspoConverter:generateEntities() - start generate Entities');
+
+ $this->getEntityGenerator()->setGenerateAnnotations(false);
+ $this->getEntityGenerator()->setGenerateStubMethods(true);
+ $this->getEntityGenerator()->setRegenerateEntityIfExists(false);
+ $this->getEntityGenerator()->setUpdateEntityIfExists(false);
+ $this->getEntityGenerator()->generate($metadata, 'application');
+
+ $GLOBALS['log']->add('DEBUG', 'EspoConverter:generateEntities() - end generate Entities');
+
+ return true; //always true, because generate just returns the VOID
+ }
+
+ return false;
+ }
+
+
}
\ No newline at end of file
diff --git a/application/Espo/Core/Utils/Util.php b/application/Espo/Core/Utils/Util.php
index 56655c63b6..909bfea312 100644
--- a/application/Espo/Core/Utils/Util.php
+++ b/application/Espo/Core/Utils/Util.php
@@ -49,13 +49,13 @@ class Util
*
* @return string
*/
- public static function toCamelCase($name, $capitaliseFirstChar=false)
+ public static function toCamelCase($name, $capitaliseFirstChar = false, $symbol = '-')
{
if($capitaliseFirstChar) {
$name[0] = strtoupper($name[0]);
}
$func = create_function('$c', 'return strtoupper($c[1]);');
- return preg_replace_callback('/-([a-z])/', $func, $name);
+ return preg_replace_callback('/'.$symbol.'([a-z])/', $func, $name);
}
/**
@@ -66,10 +66,10 @@ class Util
*
* @return string
*/
- public static function fromCamelCase($name)
+ public static function fromCamelCase($name, $symbol = '-')
{
$name[0] = strtolower($name[0]);
- $func = create_function('$c', 'return "-" . strtolower($c[1]);');
+ $func = create_function('$c', 'return "'.$symbol.'" . strtolower($c[1]);');
return preg_replace_callback('/([A-Z])/', $func, $name);
}
@@ -186,6 +186,58 @@ class Util
return is_array($object) ? array_map("static::objectToArray", $object) : $object;
}
+
+ /**
+ * Get Naming according to prefix or postfix type
+ *
+ * @param string $name
+ * @param string $prePostFix
+ * @param string $type
+ *
+ * @return string
+ */
+ public static function getNaming($name, $prePostFix, $type = 'prefix', $symbol = '-')
+ {
+ if ($type == 'prefix') {
+ return static::toCamelCase($prePostFix.$symbol.$name, false, $symbol);
+ } else if ($type == 'postfix') {
+ return static::toCamelCase($name.$symbol.$prePostFix, false, $symbol);
+ }
+
+ return null;
+ }
+
+
+ /**
+ * Replace $search in array recursively
+ *
+ * @param string $search
+ * @param string $replace
+ * @param string $array
+ * @param string $isKeys
+ *
+ * @return array
+ */
+ public static function replaceInArray($search = '', $replace = '', $array = false, $isKeys = true)
+ {
+ if (!is_array($array)) {
+ return str_replace($search, $replace, $array);
+ }
+
+ $newArr = array();
+ foreach ($array as $key => $value) {
+ $addKey = $key;
+ if ($isKeys) { //Replace keys
+ $addKey = str_replace($search, $replace, $key);
+ }
+
+ // Recurse
+ $newArr[$addKey] = static::replaceInArray($search, $replace, $value, $isKeys);
+ }
+
+ return $newArr;
+ }
+
}
diff --git a/application/Espo/Resources/metadata/fields/array.json b/application/Espo/Resources/metadata/fields/array.json
index a98f0c50a0..e10385bf47 100644
--- a/application/Espo/Resources/metadata/fields/array.json
+++ b/application/Espo/Resources/metadata/fields/array.json
@@ -17,5 +17,8 @@
"search":{
"basic":false,
"advanced":false
+ },
+ "database":{
+ "type":"json_array"
}
}
diff --git a/application/Espo/Resources/metadata/fields/duration.json b/application/Espo/Resources/metadata/fields/duration.json
new file mode 100644
index 0000000000..c936f61d65
--- /dev/null
+++ b/application/Espo/Resources/metadata/fields/duration.json
@@ -0,0 +1,5 @@
+{
+ "database":{
+ "type":"integer"
+ }
+}
diff --git a/testAuth.php b/testAuth.php
index cbf74b5601..15e8a25ceb 100644
--- a/testAuth.php
+++ b/testAuth.php
@@ -11,7 +11,7 @@ class Auth extends \Slim\Middleware
private $container;
- public function __construct(\Doctrine\ORM\EntityManager $entityManager, \Espo\Core\Container $container)
+ public function __construct(\Espo\Core\EntityManager $entityManager, \Espo\Core\Container $container)
{
$this->entityManager = $entityManager;
$this->container = $container;
@@ -49,7 +49,7 @@ class Auth extends \Slim\Middleware
$username = $authKey;
$password = $authSec;
- $user = $this->entityManager->getRepository('\Espo\Entities\User')->findOneBy(array('username' => $username));
+ $user = $this->entityManager->getRepository('User')->findOneBy(array('username' => $username));
if ($user) {
if ($password == $user->getPassword()) {
$this->container->setUser($user);
diff --git a/tests/Espo/Core/Doctrine/EspoConverterTest.php b/tests/Espo/Core/Doctrine/EspoConverterTest.php
new file mode 100644
index 0000000000..9cad46854d
--- /dev/null
+++ b/tests/Espo/Core/Doctrine/EspoConverterTest.php
@@ -0,0 +1,45 @@
+app = $GLOBALS['app'];
+ }
+
+
+ protected function setUp()
+ {
+ $this->fixture = new \Espo\Core\Doctrine\EspoConverter($this->app->getContainer()->get('entityManager'), $this->app->getMetadata(), $this->app->getContainer()->get('fileManager'));
+ }
+
+ protected function tearDown()
+ {
+ $this->fixture = NULL;
+ }
+
+
+
+ function testGetFieldType()
+ {
+ $this->assertEquals('string', $this->fixture->getFieldType('varchar'));
+ $this->assertEquals('float', $this->fixture->getFieldType('float'));
+ }
+
+
+
+
+}
+
+?>
\ No newline at end of file
diff --git a/tests/Espo/Core/Utils/UtilTest.php b/tests/Espo/Core/Utils/UtilTest.php
index c208ad0a0d..4cda010268 100644
--- a/tests/Espo/Core/Utils/UtilTest.php
+++ b/tests/Espo/Core/Utils/UtilTest.php
@@ -180,6 +180,38 @@ class UtilTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($testResult, Util::objectToArray($testObj));
}
+ function testGetNaming()
+ {
+ $this->assertEquals('myPrefixMyName', Util::getNaming('myName', 'myPrefix', 'prefix'));
+
+ $this->assertEquals('myNameMyPostfix', Util::getNaming('myName', 'myPostfix', 'postfix'));
+ $this->assertEquals('myNameMyPostfix', Util::getNaming('my_name', 'myPostfix', 'postfix', '_'));
+ $this->assertEquals('myNameMyPostfix', Util::getNaming('my_name', 'my_postfix', 'postfix', '_'));
+ }
+
+ function testReplaceInArray()
+ {
+ $testArray = array(
+ 'option' => array(
+ 'default' => '{0}',
+ 'testKey' => array(
+ '{0}' => 'testVal',
+ ),
+ ),
+ );
+
+ $testResult = array(
+ 'option' => array(
+ 'default' => 'DONE',
+ 'testKey' => array(
+ 'DONE' => 'testVal',
+ ),
+ ),
+ );
+
+ $this->assertEquals($testResult, Util::replaceInArray('{0}', 'DONE', $testArray, true));
+ }
+
/*function testGetScopeModuleName()
{