PageRenderTime 37ms CodeModel.GetById 9ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/plugins/sfDoctrinePlugin/lib/task/sfDoctrineBuildModelTask.class.php

https://github.com/bheneka/gitta
PHP | 128 lines | 70 code | 21 blank | 37 comment | 2 complexity | 7d78279263e3ec0b405286b321f62541 MD5 | raw file
  1. <?php
  2. /*
  3. * This file is part of the symfony package.
  4. * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
  5. * (c) Jonathan H. Wage <jonwage@gmail.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. require_once(dirname(__FILE__).'/sfDoctrineBaseTask.class.php');
  11. /**
  12. * Create classes for the current model.
  13. *
  14. * @package symfony
  15. * @subpackage doctrine
  16. * @author Fabien Potencier <fabien.potencier@symfony-project.com>
  17. * @author Jonathan H. Wage <jonwage@gmail.com>
  18. * @version SVN: $Id$
  19. */
  20. class sfDoctrineBuildModelTask extends sfDoctrineBaseTask
  21. {
  22. /**
  23. * @see sfTask
  24. */
  25. protected function configure()
  26. {
  27. $this->addOptions(array(
  28. new sfCommandOption('application', null, sfCommandOption::PARAMETER_OPTIONAL, 'The application name', true),
  29. new sfCommandOption('env', null, sfCommandOption::PARAMETER_REQUIRED, 'The environment', 'dev'),
  30. ));
  31. $this->namespace = 'doctrine';
  32. $this->name = 'build-model';
  33. $this->briefDescription = 'Creates classes for the current model';
  34. $this->detailedDescription = <<<EOF
  35. The [doctrine:build-model|INFO] task creates model classes from the schema:
  36. [./symfony doctrine:build-model|INFO]
  37. The task read the schema information in [config/doctrine/*.yml|COMMENT]
  38. from the project and all enabled plugins.
  39. The model classes files are created in [lib/model/doctrine|COMMENT].
  40. This task never overrides custom classes in [lib/model/doctrine|COMMENT].
  41. It only replaces files in [lib/model/doctrine/base|COMMENT].
  42. EOF;
  43. }
  44. /**
  45. * @see sfTask
  46. */
  47. protected function execute($arguments = array(), $options = array())
  48. {
  49. $this->logSection('doctrine', 'generating model classes');
  50. $config = $this->getCliConfig();
  51. $builderOptions = $this->configuration->getPluginConfiguration('sfDoctrinePlugin')->getModelBuilderOptions();
  52. $stubFinder = sfFinder::type('file')->prune('base')->name('*'.$builderOptions['suffix']);
  53. $before = $stubFinder->in($config['models_path']);
  54. $schema = $this->prepareSchemaFile($config['yaml_schema_path']);
  55. $import = new Doctrine_Import_Schema();
  56. $import->setOptions($builderOptions);
  57. $import->importSchema($schema, 'yml', $config['models_path']);
  58. // markup base classes with magic methods
  59. foreach (sfYaml::load($schema) as $model => $definition)
  60. {
  61. $file = sprintf('%s%s/%s/Base%s%s', $config['models_path'], isset($definition['package']) ? '/'.substr($definition['package'], 0, strpos($definition['package'], '.')) : '', $builderOptions['baseClassesDirectory'], $model, $builderOptions['suffix']);
  62. $code = file_get_contents($file);
  63. // introspect the model without loading the class
  64. if (preg_match_all('/@property (\w+) \$(\w+)/', $code, $matches, PREG_SET_ORDER))
  65. {
  66. $properties = array();
  67. foreach ($matches as $match)
  68. {
  69. $properties[$match[2]] = $match[1];
  70. }
  71. $typePad = max(array_map('strlen', array_merge(array_values($properties), array($model))));
  72. $namePad = max(array_map('strlen', array_keys(array_map(array('sfInflector', 'camelize'), $properties))));
  73. $setters = array();
  74. $getters = array();
  75. foreach ($properties as $name => $type)
  76. {
  77. $camelized = sfInflector::camelize($name);
  78. $collection = 'Doctrine_Collection' == $type;
  79. $getters[] = sprintf('@method %-'.$typePad.'s %s%-'.($namePad + 2).'s Returns the current record\'s "%s" %s', $type, 'get', $camelized.'()', $name, $collection ? 'collection' : 'value');
  80. $setters[] = sprintf('@method %-'.$typePad.'s %s%-'.($namePad + 2).'s Sets the current record\'s "%s" %s', $model, 'set', $camelized.'()', $name, $collection ? 'collection' : 'value');
  81. }
  82. // use the last match as a search string
  83. $code = str_replace($match[0], $match[0].PHP_EOL.' * '.PHP_EOL.' * '.implode(PHP_EOL.' * ', array_merge($getters, $setters)), $code);
  84. file_put_contents($file, $code);
  85. }
  86. }
  87. $properties = parse_ini_file(sfConfig::get('sf_config_dir').'/properties.ini', true);
  88. $tokens = array(
  89. '##PACKAGE##' => isset($properties['symfony']['name']) ? $properties['symfony']['name'] : 'symfony',
  90. '##SUBPACKAGE##' => 'model',
  91. '##NAME##' => isset($properties['symfony']['author']) ? $properties['symfony']['author'] : 'Your name here',
  92. ' <##EMAIL##>' => '',
  93. "{\n\n}" => "{\n}\n",
  94. );
  95. // cleanup new stub classes
  96. $after = $stubFinder->in($config['models_path']);
  97. $this->getFilesystem()->replaceTokens(array_diff($after, $before), '', '', $tokens);
  98. // cleanup base classes
  99. $baseFinder = sfFinder::type('file')->name('Base*'.$builderOptions['suffix']);
  100. $baseDirFinder = sfFinder::type('dir')->name('base');
  101. $this->getFilesystem()->replaceTokens($baseFinder->in($baseDirFinder->in($config['models_path'])), '', '', $tokens);
  102. $this->reloadAutoload();
  103. }
  104. }