PageRenderTime 39ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 0ms

/symfony2/vendor/bundles/Sensio/Bundle/GeneratorBundle/Generator/DoctrineCrudGenerator.php

http://github.com/eryx/php-framework-benchmark
PHP | 290 lines | 209 code | 21 blank | 60 comment | 2 complexity | 26a8a1971ece5b50c18d466c63abde02 MD5 | raw file
Possible License(s): MIT, BSD-3-Clause, Apache-2.0, LGPL-2.1, LGPL-3.0, BSD-2-Clause
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.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. namespace Sensio\Bundle\GeneratorBundle\Generator;
  11. use Symfony\Component\Filesystem\Filesystem;
  12. use Symfony\Component\HttpKernel\Bundle\BundleInterface;
  13. use Doctrine\ORM\Mapping\ClassMetadataInfo;
  14. /**
  15. * Generates a CRUD controller.
  16. *
  17. * @author Fabien Potencier <fabien@symfony.com>
  18. */
  19. class DoctrineCrudGenerator extends Generator
  20. {
  21. private $filesystem;
  22. private $skeletonDir;
  23. private $routePrefix;
  24. private $routeNamePrefix;
  25. private $bundle;
  26. private $entity;
  27. private $metadata;
  28. private $format;
  29. private $actions;
  30. /**
  31. * Constructor.
  32. *
  33. * @param Filesystem $filesystem A Filesystem instance
  34. * @param string $skeletonDir Path to the skeleton directory
  35. */
  36. public function __construct(Filesystem $filesystem, $skeletonDir)
  37. {
  38. $this->filesystem = $filesystem;
  39. $this->skeletonDir = $skeletonDir;
  40. }
  41. /**
  42. * Generate the CRUD controller.
  43. *
  44. * @param BundleInterface $bundle A bundle object
  45. * @param string $entity The entity relative class name
  46. * @param ClassMetadataInfo $metadata The entity class metadata
  47. * @param string $format The configuration format (xml, yaml, annotation)
  48. * @param string $routePrefix The route name prefix
  49. * @param array $needWriteActions Wether or not to generate write actions
  50. *
  51. * @throws \RuntimeException
  52. */
  53. public function generate(BundleInterface $bundle, $entity, ClassMetadataInfo $metadata, $format, $routePrefix, $needWriteActions)
  54. {
  55. $this->routePrefix = $routePrefix;
  56. $this->routeNamePrefix = str_replace('/', '_', $routePrefix);
  57. $this->actions = $needWriteActions ? array('index', 'show', 'new', 'edit', 'delete') : array('index', 'show');
  58. if (count($metadata->identifier) > 1) {
  59. throw new \RuntimeException('The CRUD generator does not support entity classes with multiple primary keys.');
  60. }
  61. if (!in_array('id', $metadata->identifier)) {
  62. throw new \RuntimeException('The CRUD generator expects the entity object has a primary key field named "id" with a getId() method.');
  63. }
  64. $this->entity = $entity;
  65. $this->bundle = $bundle;
  66. $this->metadata = $metadata;
  67. $this->setFormat($format);
  68. $this->generateControllerClass();
  69. $dir = sprintf('%s/Resources/views/%s', $this->bundle->getPath(), str_replace('\\', '/', $this->entity));
  70. if (!file_exists($dir)) {
  71. $this->filesystem->mkdir($dir, 0777);
  72. }
  73. $this->generateIndexView($dir);
  74. if (in_array('show', $this->actions)) {
  75. $this->generateShowView($dir);
  76. }
  77. if (in_array('new', $this->actions)) {
  78. $this->generateNewView($dir);
  79. }
  80. if (in_array('edit', $this->actions)) {
  81. $this->generateEditView($dir);
  82. }
  83. $this->generateTestClass();
  84. $this->generateConfiguration();
  85. }
  86. /**
  87. * Sets the configuration format.
  88. *
  89. * @param string $format The configuration format
  90. */
  91. private function setFormat($format)
  92. {
  93. switch ($format) {
  94. case 'yml':
  95. case 'xml':
  96. case 'php':
  97. case 'annotation':
  98. $this->format = $format;
  99. break;
  100. default:
  101. $this->format = 'yml';
  102. break;
  103. }
  104. }
  105. /**
  106. * Generates the routing configuration.
  107. *
  108. */
  109. private function generateConfiguration()
  110. {
  111. if (!in_array($this->format, array('yml', 'xml', 'php'))) {
  112. return;
  113. }
  114. $target = sprintf(
  115. '%s/Resources/config/routing/%s.%s',
  116. $this->bundle->getPath(),
  117. strtolower(str_replace('\\', '_', $this->entity)),
  118. $this->format
  119. );
  120. $this->renderFile($this->skeletonDir, 'config/routing.'.$this->format, $target, array(
  121. 'actions' => $this->actions,
  122. 'route_prefix' => $this->routePrefix,
  123. 'route_name_prefix' => $this->routeNamePrefix,
  124. 'bundle' => $this->bundle->getName(),
  125. 'entity' => $this->entity,
  126. ));
  127. }
  128. /**
  129. * Generates the controller class only.
  130. *
  131. */
  132. private function generateControllerClass()
  133. {
  134. $dir = $this->bundle->getPath();
  135. $parts = explode('\\', $this->entity);
  136. $entityClass = array_pop($parts);
  137. $entityNamespace = implode('\\', $parts);
  138. $target = sprintf(
  139. '%s/Controller/%s/%sController.php',
  140. $dir,
  141. str_replace('\\', '/', $entityNamespace),
  142. $entityClass
  143. );
  144. if (file_exists($target)) {
  145. throw new \RuntimeException('Unable to generate the controller as it already exists.');
  146. }
  147. $this->renderFile($this->skeletonDir, 'controller.php', $target, array(
  148. 'actions' => $this->actions,
  149. 'route_prefix' => $this->routePrefix,
  150. 'route_name_prefix' => $this->routeNamePrefix,
  151. 'dir' => $this->skeletonDir,
  152. 'bundle' => $this->bundle->getName(),
  153. 'entity' => $this->entity,
  154. 'entity_class' => $entityClass,
  155. 'namespace' => $this->bundle->getNamespace(),
  156. 'entity_namespace' => $entityNamespace,
  157. 'format' => $this->format,
  158. ));
  159. }
  160. /**
  161. * Generates the functional test class only.
  162. *
  163. */
  164. private function generateTestClass()
  165. {
  166. $parts = explode('\\', $this->entity);
  167. $entityClass = array_pop($parts);
  168. $entityNamespace = implode('\\', $parts);
  169. $dir = $this->bundle->getPath() .'/Tests/Controller';
  170. $target = $dir .'/'. str_replace('\\', '/', $entityNamespace).'/'. $entityClass .'ControllerTest.php';
  171. $this->renderFile($this->skeletonDir, 'tests/test.php', $target, array(
  172. 'route_prefix' => $this->routePrefix,
  173. 'route_name_prefix' => $this->routeNamePrefix,
  174. 'entity' => $this->entity,
  175. 'entity_class' => $entityClass,
  176. 'namespace' => $this->bundle->getNamespace(),
  177. 'entity_namespace' => $entityNamespace,
  178. 'actions' => $this->actions,
  179. 'dir' => $this->skeletonDir,
  180. ));
  181. }
  182. /**
  183. * Generates the index.html.twig template in the final bundle.
  184. *
  185. * @param string $dir The path to the folder that hosts templates in the bundle
  186. */
  187. private function generateIndexView($dir)
  188. {
  189. $this->renderFile($this->skeletonDir, 'views/index.html.twig', $dir.'/index.html.twig', array(
  190. 'dir' => $this->skeletonDir,
  191. 'entity' => $this->entity,
  192. 'fields' => $this->metadata->fieldMappings,
  193. 'actions' => $this->actions,
  194. 'record_actions' => $this->getRecordActions(),
  195. 'route_prefix' => $this->routePrefix,
  196. 'route_name_prefix' => $this->routeNamePrefix,
  197. ));
  198. }
  199. /**
  200. * Generates the show.html.twig template in the final bundle.
  201. *
  202. * @param string $dir The path to the folder that hosts templates in the bundle
  203. */
  204. private function generateShowView($dir)
  205. {
  206. $this->renderFile($this->skeletonDir, 'views/show.html.twig', $dir.'/show.html.twig', array(
  207. 'dir' => $this->skeletonDir,
  208. 'entity' => $this->entity,
  209. 'fields' => $this->metadata->fieldMappings,
  210. 'actions' => $this->actions,
  211. 'route_prefix' => $this->routePrefix,
  212. 'route_name_prefix' => $this->routeNamePrefix,
  213. ));
  214. }
  215. /**
  216. * Generates the new.html.twig template in the final bundle.
  217. *
  218. * @param string $dir The path to the folder that hosts templates in the bundle
  219. */
  220. private function generateNewView($dir)
  221. {
  222. $this->renderFile($this->skeletonDir, 'views/new.html.twig', $dir.'/new.html.twig', array(
  223. 'dir' => $this->skeletonDir,
  224. 'route_prefix' => $this->routePrefix,
  225. 'route_name_prefix' => $this->routeNamePrefix,
  226. 'entity' => $this->entity,
  227. 'actions' => $this->actions,
  228. ));
  229. }
  230. /**
  231. * Generates the edit.html.twig template in the final bundle.
  232. *
  233. * @param string $dir The path to the folder that hosts templates in the bundle
  234. */
  235. private function generateEditView($dir)
  236. {
  237. $this->renderFile($this->skeletonDir, 'views/edit.html.twig', $dir.'/edit.html.twig', array(
  238. 'dir' => $this->skeletonDir,
  239. 'route_prefix' => $this->routePrefix,
  240. 'route_name_prefix' => $this->routeNamePrefix,
  241. 'entity' => $this->entity,
  242. 'actions' => $this->actions,
  243. ));
  244. }
  245. /**
  246. * Returns an array of record actions to generate (edit, show).
  247. *
  248. * @return array
  249. */
  250. private function getRecordActions()
  251. {
  252. return array_filter($this->actions, function($item) {
  253. return in_array($item, array('show', 'edit'));
  254. });
  255. }
  256. }