PageRenderTime 47ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/doctrine/orm/lib/Doctrine/ORM/Tools/ConvertDoctrine1Schema.php

https://bitbucket.org/gruenwaldt/loquitur-web
PHP | 271 lines | 201 code | 27 blank | 43 comment | 48 complexity | bf3990845245de5d03ee0d93a5082727 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. /*
  3. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  4. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  5. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  6. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  7. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  9. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  13. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14. *
  15. * This software consists of voluntary contributions made by many individuals
  16. * and is licensed under the MIT license. For more information, see
  17. * <http://www.doctrine-project.org>.
  18. */
  19. namespace Doctrine\ORM\Tools;
  20. use Doctrine\ORM\Mapping\ClassMetadataInfo,
  21. Doctrine\ORM\Tools\Export\Driver\AbstractExporter,
  22. Doctrine\Common\Util\Inflector;
  23. /**
  24. * Class to help with converting Doctrine 1 schema files to Doctrine 2 mapping files
  25. *
  26. *
  27. * @link www.doctrine-project.org
  28. * @since 2.0
  29. * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
  30. * @author Jonathan Wage <jonwage@gmail.com>
  31. * @author Roman Borschel <roman@code-factory.org>
  32. */
  33. class ConvertDoctrine1Schema
  34. {
  35. private $_legacyTypeMap = array(
  36. // TODO: This list may need to be updated
  37. 'clob' => 'text',
  38. 'timestamp' => 'datetime',
  39. 'enum' => 'string'
  40. );
  41. /**
  42. * Constructor passes the directory or array of directories
  43. * to convert the Doctrine 1 schema files from
  44. *
  45. * @param array $from
  46. * @author Jonathan Wage
  47. */
  48. public function __construct($from)
  49. {
  50. $this->_from = (array) $from;
  51. }
  52. /**
  53. * Get an array of ClassMetadataInfo instances from the passed
  54. * Doctrine 1 schema
  55. *
  56. * @return array $metadatas An array of ClassMetadataInfo instances
  57. */
  58. public function getMetadata()
  59. {
  60. $schema = array();
  61. foreach ($this->_from as $path) {
  62. if (is_dir($path)) {
  63. $files = glob($path . '/*.yml');
  64. foreach ($files as $file) {
  65. $schema = array_merge($schema, (array) \Symfony\Component\Yaml\Yaml::parse($file));
  66. }
  67. } else {
  68. $schema = array_merge($schema, (array) \Symfony\Component\Yaml\Yaml::parse($path));
  69. }
  70. }
  71. $metadatas = array();
  72. foreach ($schema as $className => $mappingInformation) {
  73. $metadatas[] = $this->_convertToClassMetadataInfo($className, $mappingInformation);
  74. }
  75. return $metadatas;
  76. }
  77. private function _convertToClassMetadataInfo($className, $mappingInformation)
  78. {
  79. $metadata = new ClassMetadataInfo($className);
  80. $this->_convertTableName($className, $mappingInformation, $metadata);
  81. $this->_convertColumns($className, $mappingInformation, $metadata);
  82. $this->_convertIndexes($className, $mappingInformation, $metadata);
  83. $this->_convertRelations($className, $mappingInformation, $metadata);
  84. return $metadata;
  85. }
  86. private function _convertTableName($className, array $model, ClassMetadataInfo $metadata)
  87. {
  88. if (isset($model['tableName']) && $model['tableName']) {
  89. $e = explode('.', $model['tableName']);
  90. if (count($e) > 1) {
  91. $metadata->table['schema'] = $e[0];
  92. $metadata->table['name'] = $e[1];
  93. } else {
  94. $metadata->table['name'] = $e[0];
  95. }
  96. }
  97. }
  98. private function _convertColumns($className, array $model, ClassMetadataInfo $metadata)
  99. {
  100. $id = false;
  101. if (isset($model['columns']) && $model['columns']) {
  102. foreach ($model['columns'] as $name => $column) {
  103. $fieldMapping = $this->_convertColumn($className, $name, $column, $metadata);
  104. if (isset($fieldMapping['id']) && $fieldMapping['id']) {
  105. $id = true;
  106. }
  107. }
  108. }
  109. if ( ! $id) {
  110. $fieldMapping = array(
  111. 'fieldName' => 'id',
  112. 'columnName' => 'id',
  113. 'type' => 'integer',
  114. 'id' => true
  115. );
  116. $metadata->mapField($fieldMapping);
  117. $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
  118. }
  119. }
  120. private function _convertColumn($className, $name, $column, ClassMetadataInfo $metadata)
  121. {
  122. if (is_string($column)) {
  123. $string = $column;
  124. $column = array();
  125. $column['type'] = $string;
  126. }
  127. if ( ! isset($column['name'])) {
  128. $column['name'] = $name;
  129. }
  130. // check if a column alias was used (column_name as field_name)
  131. if (preg_match("/(\w+)\sas\s(\w+)/i", $column['name'], $matches)) {
  132. $name = $matches[1];
  133. $column['name'] = $name;
  134. $column['alias'] = $matches[2];
  135. }
  136. if (preg_match("/([a-zA-Z]+)\(([0-9]+)\)/", $column['type'], $matches)) {
  137. $column['type'] = $matches[1];
  138. $column['length'] = $matches[2];
  139. }
  140. $column['type'] = strtolower($column['type']);
  141. // check if legacy column type (1.x) needs to be mapped to a 2.0 one
  142. if (isset($this->_legacyTypeMap[$column['type']])) {
  143. $column['type'] = $this->_legacyTypeMap[$column['type']];
  144. }
  145. if ( ! \Doctrine\DBAL\Types\Type::hasType($column['type'])) {
  146. throw ToolsException::couldNotMapDoctrine1Type($column['type']);
  147. }
  148. $fieldMapping = array();
  149. if (isset($column['primary'])) {
  150. $fieldMapping['id'] = true;
  151. }
  152. $fieldMapping['fieldName'] = isset($column['alias']) ? $column['alias'] : $name;
  153. $fieldMapping['columnName'] = $column['name'];
  154. $fieldMapping['type'] = $column['type'];
  155. if (isset($column['length'])) {
  156. $fieldMapping['length'] = $column['length'];
  157. }
  158. $allowed = array('precision', 'scale', 'unique', 'options', 'notnull', 'version');
  159. foreach ($column as $key => $value) {
  160. if (in_array($key, $allowed)) {
  161. $fieldMapping[$key] = $value;
  162. }
  163. }
  164. $metadata->mapField($fieldMapping);
  165. if (isset($column['autoincrement'])) {
  166. $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
  167. } else if (isset($column['sequence'])) {
  168. $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_SEQUENCE);
  169. $definition = array(
  170. 'sequenceName' => is_array($column['sequence']) ? $column['sequence']['name']:$column['sequence']
  171. );
  172. if (isset($column['sequence']['size'])) {
  173. $definition['allocationSize'] = $column['sequence']['size'];
  174. }
  175. if (isset($column['sequence']['value'])) {
  176. $definition['initialValue'] = $column['sequence']['value'];
  177. }
  178. $metadata->setSequenceGeneratorDefinition($definition);
  179. }
  180. return $fieldMapping;
  181. }
  182. private function _convertIndexes($className, array $model, ClassMetadataInfo $metadata)
  183. {
  184. if (isset($model['indexes']) && $model['indexes']) {
  185. foreach ($model['indexes'] as $name => $index) {
  186. $type = (isset($index['type']) && $index['type'] == 'unique')
  187. ? 'uniqueConstraints' : 'indexes';
  188. $metadata->table[$type][$name] = array(
  189. 'columns' => $index['fields']
  190. );
  191. }
  192. }
  193. }
  194. private function _convertRelations($className, array $model, ClassMetadataInfo $metadata)
  195. {
  196. if (isset($model['relations']) && $model['relations']) {
  197. foreach ($model['relations'] as $name => $relation) {
  198. if ( ! isset($relation['alias'])) {
  199. $relation['alias'] = $name;
  200. }
  201. if ( ! isset($relation['class'])) {
  202. $relation['class'] = $name;
  203. }
  204. if ( ! isset($relation['local'])) {
  205. $relation['local'] = Inflector::tableize($relation['class']);
  206. }
  207. if ( ! isset($relation['foreign'])) {
  208. $relation['foreign'] = 'id';
  209. }
  210. if ( ! isset($relation['foreignAlias'])) {
  211. $relation['foreignAlias'] = $className;
  212. }
  213. if (isset($relation['refClass'])) {
  214. $type = 'many';
  215. $foreignType = 'many';
  216. $joinColumns = array();
  217. } else {
  218. $type = isset($relation['type']) ? $relation['type'] : 'one';
  219. $foreignType = isset($relation['foreignType']) ? $relation['foreignType'] : 'many';
  220. $joinColumns = array(
  221. array(
  222. 'name' => $relation['local'],
  223. 'referencedColumnName' => $relation['foreign'],
  224. 'onDelete' => isset($relation['onDelete']) ? $relation['onDelete'] : null,
  225. )
  226. );
  227. }
  228. if ($type == 'one' && $foreignType == 'one') {
  229. $method = 'mapOneToOne';
  230. } else if ($type == 'many' && $foreignType == 'many') {
  231. $method = 'mapManyToMany';
  232. } else {
  233. $method = 'mapOneToMany';
  234. }
  235. $associationMapping = array();
  236. $associationMapping['fieldName'] = $relation['alias'];
  237. $associationMapping['targetEntity'] = $relation['class'];
  238. $associationMapping['mappedBy'] = $relation['foreignAlias'];
  239. $associationMapping['joinColumns'] = $joinColumns;
  240. $metadata->$method($associationMapping);
  241. }
  242. }
  243. }
  244. }