PageRenderTime 44ms CodeModel.GetById 10ms RepoModel.GetById 1ms app.codeStats 0ms

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

https://github.com/nattaphat/hgis
PHP | 344 lines | 205 code | 45 blank | 94 comment | 42 complexity | 0035937b6826f34c6e9150e6464e9343 MD5 | raw file
  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. use Doctrine\Common\Util\Inflector;
  22. use Doctrine\DBAL\Types\Type;
  23. use Symfony\Component\Yaml\Yaml;
  24. /**
  25. * Class to help with converting Doctrine 1 schema files to Doctrine 2 mapping files
  26. *
  27. *
  28. * @link www.doctrine-project.org
  29. * @since 2.0
  30. * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
  31. * @author Jonathan Wage <jonwage@gmail.com>
  32. * @author Roman Borschel <roman@code-factory.org>
  33. */
  34. class ConvertDoctrine1Schema
  35. {
  36. /**
  37. * @var array
  38. */
  39. private $from;
  40. /**
  41. * @var array
  42. */
  43. private $legacyTypeMap = array(
  44. // TODO: This list may need to be updated
  45. 'clob' => 'text',
  46. 'timestamp' => 'datetime',
  47. 'enum' => 'string'
  48. );
  49. /**
  50. * Constructor passes the directory or array of directories
  51. * to convert the Doctrine 1 schema files from.
  52. *
  53. * @param array $from
  54. *
  55. * @author Jonathan Wage
  56. */
  57. public function __construct($from)
  58. {
  59. $this->from = (array) $from;
  60. }
  61. /**
  62. * Gets an array of ClassMetadataInfo instances from the passed
  63. * Doctrine 1 schema.
  64. *
  65. * @return array An array of ClassMetadataInfo instances
  66. */
  67. public function getMetadata()
  68. {
  69. $schema = array();
  70. foreach ($this->from as $path) {
  71. if (is_dir($path)) {
  72. $files = glob($path . '/*.yml');
  73. foreach ($files as $file) {
  74. $schema = array_merge($schema, (array) Yaml::parse($file));
  75. }
  76. } else {
  77. $schema = array_merge($schema, (array) Yaml::parse($path));
  78. }
  79. }
  80. $metadatas = array();
  81. foreach ($schema as $className => $mappingInformation) {
  82. $metadatas[] = $this->convertToClassMetadataInfo($className, $mappingInformation);
  83. }
  84. return $metadatas;
  85. }
  86. /**
  87. * @param string $className
  88. * @param array $mappingInformation
  89. *
  90. * @return \Doctrine\ORM\Mapping\ClassMetadataInfo
  91. */
  92. private function convertToClassMetadataInfo($className, $mappingInformation)
  93. {
  94. $metadata = new ClassMetadataInfo($className);
  95. $this->convertTableName($className, $mappingInformation, $metadata);
  96. $this->convertColumns($className, $mappingInformation, $metadata);
  97. $this->convertIndexes($className, $mappingInformation, $metadata);
  98. $this->convertRelations($className, $mappingInformation, $metadata);
  99. return $metadata;
  100. }
  101. /**
  102. * @param string $className
  103. * @param array $model
  104. * @param ClassMetadataInfo $metadata
  105. *
  106. * @return void
  107. */
  108. private function convertTableName($className, array $model, ClassMetadataInfo $metadata)
  109. {
  110. if (isset($model['tableName']) && $model['tableName']) {
  111. $e = explode('.', $model['tableName']);
  112. if (count($e) > 1) {
  113. $metadata->table['schema'] = $e[0];
  114. $metadata->table['name'] = $e[1];
  115. } else {
  116. $metadata->table['name'] = $e[0];
  117. }
  118. }
  119. }
  120. /**
  121. * @param string $className
  122. * @param array $model
  123. * @param ClassMetadataInfo $metadata
  124. *
  125. * @return void
  126. */
  127. private function convertColumns($className, array $model, ClassMetadataInfo $metadata)
  128. {
  129. $id = false;
  130. if (isset($model['columns']) && $model['columns']) {
  131. foreach ($model['columns'] as $name => $column) {
  132. $fieldMapping = $this->convertColumn($className, $name, $column, $metadata);
  133. if (isset($fieldMapping['id']) && $fieldMapping['id']) {
  134. $id = true;
  135. }
  136. }
  137. }
  138. if ( ! $id) {
  139. $fieldMapping = array(
  140. 'fieldName' => 'id',
  141. 'columnName' => 'id',
  142. 'type' => 'integer',
  143. 'id' => true
  144. );
  145. $metadata->mapField($fieldMapping);
  146. $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
  147. }
  148. }
  149. /**
  150. * @param string $className
  151. * @param string $name
  152. * @param string|array $column
  153. * @param ClassMetadataInfo $metadata
  154. *
  155. * @return array
  156. *
  157. * @throws ToolsException
  158. */
  159. private function convertColumn($className, $name, $column, ClassMetadataInfo $metadata)
  160. {
  161. if (is_string($column)) {
  162. $string = $column;
  163. $column = array();
  164. $column['type'] = $string;
  165. }
  166. if ( ! isset($column['name'])) {
  167. $column['name'] = $name;
  168. }
  169. // check if a column alias was used (column_name as field_name)
  170. if (preg_match("/(\w+)\sas\s(\w+)/i", $column['name'], $matches)) {
  171. $name = $matches[1];
  172. $column['name'] = $name;
  173. $column['alias'] = $matches[2];
  174. }
  175. if (preg_match("/([a-zA-Z]+)\(([0-9]+)\)/", $column['type'], $matches)) {
  176. $column['type'] = $matches[1];
  177. $column['length'] = $matches[2];
  178. }
  179. $column['type'] = strtolower($column['type']);
  180. // check if legacy column type (1.x) needs to be mapped to a 2.0 one
  181. if (isset($this->legacyTypeMap[$column['type']])) {
  182. $column['type'] = $this->legacyTypeMap[$column['type']];
  183. }
  184. if ( ! Type::hasType($column['type'])) {
  185. throw ToolsException::couldNotMapDoctrine1Type($column['type']);
  186. }
  187. $fieldMapping = array();
  188. if (isset($column['primary'])) {
  189. $fieldMapping['id'] = true;
  190. }
  191. $fieldMapping['fieldName'] = isset($column['alias']) ? $column['alias'] : $name;
  192. $fieldMapping['columnName'] = $column['name'];
  193. $fieldMapping['type'] = $column['type'];
  194. if (isset($column['length'])) {
  195. $fieldMapping['length'] = $column['length'];
  196. }
  197. $allowed = array('precision', 'scale', 'unique', 'options', 'notnull', 'version');
  198. foreach ($column as $key => $value) {
  199. if (in_array($key, $allowed)) {
  200. $fieldMapping[$key] = $value;
  201. }
  202. }
  203. $metadata->mapField($fieldMapping);
  204. if (isset($column['autoincrement'])) {
  205. $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
  206. } elseif (isset($column['sequence'])) {
  207. $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_SEQUENCE);
  208. $definition = array(
  209. 'sequenceName' => is_array($column['sequence']) ? $column['sequence']['name']:$column['sequence']
  210. );
  211. if (isset($column['sequence']['size'])) {
  212. $definition['allocationSize'] = $column['sequence']['size'];
  213. }
  214. if (isset($column['sequence']['value'])) {
  215. $definition['initialValue'] = $column['sequence']['value'];
  216. }
  217. $metadata->setSequenceGeneratorDefinition($definition);
  218. }
  219. return $fieldMapping;
  220. }
  221. /**
  222. * @param string $className
  223. * @param array $model
  224. * @param ClassMetadataInfo $metadata
  225. *
  226. * @return void
  227. */
  228. private function convertIndexes($className, array $model, ClassMetadataInfo $metadata)
  229. {
  230. if (empty($model['indexes'])) {
  231. return;
  232. }
  233. foreach ($model['indexes'] as $name => $index) {
  234. $type = (isset($index['type']) && $index['type'] == 'unique')
  235. ? 'uniqueConstraints' : 'indexes';
  236. $metadata->table[$type][$name] = array(
  237. 'columns' => $index['fields']
  238. );
  239. }
  240. }
  241. /**
  242. * @param string $className
  243. * @param array $model
  244. * @param ClassMetadataInfo $metadata
  245. *
  246. * @return void
  247. */
  248. private function convertRelations($className, array $model, ClassMetadataInfo $metadata)
  249. {
  250. if (empty($model['relations'])) {
  251. return;
  252. }
  253. foreach ($model['relations'] as $name => $relation) {
  254. if ( ! isset($relation['alias'])) {
  255. $relation['alias'] = $name;
  256. }
  257. if ( ! isset($relation['class'])) {
  258. $relation['class'] = $name;
  259. }
  260. if ( ! isset($relation['local'])) {
  261. $relation['local'] = Inflector::tableize($relation['class']);
  262. }
  263. if ( ! isset($relation['foreign'])) {
  264. $relation['foreign'] = 'id';
  265. }
  266. if ( ! isset($relation['foreignAlias'])) {
  267. $relation['foreignAlias'] = $className;
  268. }
  269. if (isset($relation['refClass'])) {
  270. $type = 'many';
  271. $foreignType = 'many';
  272. $joinColumns = array();
  273. } else {
  274. $type = isset($relation['type']) ? $relation['type'] : 'one';
  275. $foreignType = isset($relation['foreignType']) ? $relation['foreignType'] : 'many';
  276. $joinColumns = array(
  277. array(
  278. 'name' => $relation['local'],
  279. 'referencedColumnName' => $relation['foreign'],
  280. 'onDelete' => isset($relation['onDelete']) ? $relation['onDelete'] : null,
  281. )
  282. );
  283. }
  284. if ($type == 'one' && $foreignType == 'one') {
  285. $method = 'mapOneToOne';
  286. } elseif ($type == 'many' && $foreignType == 'many') {
  287. $method = 'mapManyToMany';
  288. } else {
  289. $method = 'mapOneToMany';
  290. }
  291. $associationMapping = array();
  292. $associationMapping['fieldName'] = $relation['alias'];
  293. $associationMapping['targetEntity'] = $relation['class'];
  294. $associationMapping['mappedBy'] = $relation['foreignAlias'];
  295. $associationMapping['joinColumns'] = $joinColumns;
  296. $metadata->$method($associationMapping);
  297. }
  298. }
  299. }