PageRenderTime 46ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/vendor/sensio/generator-bundle/Generator/DoctrineCrudGenerator.php

https://gitlab.com/pr0055/symfonypizza
PHP | 297 lines | 248 code | 15 blank | 34 comment | 2 complexity | c4f3937d21d08aed7e3c52ae97670bea MD5 | raw file
  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. use Doctrine\Common\Inflector\Inflector;
  15. /**
  16. * Generates a CRUD controller.
  17. *
  18. * @author Fabien Potencier <fabien@symfony.com>
  19. */
  20. class DoctrineCrudGenerator extends Generator
  21. {
  22. protected $filesystem;
  23. protected $rootDir;
  24. protected $routePrefix;
  25. protected $routeNamePrefix;
  26. protected $bundle;
  27. protected $entity;
  28. protected $entitySingularized;
  29. protected $entityPluralized;
  30. protected $metadata;
  31. protected $format;
  32. protected $actions;
  33. /**
  34. * Constructor.
  35. *
  36. * @param Filesystem $filesystem A Filesystem instance
  37. * @param string $rootDir The root dir
  38. */
  39. public function __construct(Filesystem $filesystem, $rootDir)
  40. {
  41. $this->filesystem = $filesystem;
  42. $this->rootDir = $rootDir;
  43. }
  44. /**
  45. * Generate the CRUD controller.
  46. *
  47. * @param BundleInterface $bundle A bundle object
  48. * @param string $entity The entity relative class name
  49. * @param ClassMetadataInfo $metadata The entity class metadata
  50. * @param string $format The configuration format (xml, yaml, annotation)
  51. * @param string $routePrefix The route name prefix
  52. * @param array $needWriteActions Whether or not to generate write actions
  53. *
  54. * @throws \RuntimeException
  55. */
  56. public function generate(BundleInterface $bundle, $entity, ClassMetadataInfo $metadata, $format, $routePrefix, $needWriteActions, $forceOverwrite)
  57. {
  58. $this->routePrefix = $routePrefix;
  59. $this->routeNamePrefix = self::getRouteNamePrefix($routePrefix);
  60. $this->actions = $needWriteActions ? array('index', 'show', 'new', 'edit', 'delete') : array('index', 'show');
  61. if (count($metadata->identifier) != 1) {
  62. throw new \RuntimeException('The CRUD generator does not support entity classes with multiple or no primary keys.');
  63. }
  64. $this->entity = $entity;
  65. $this->entitySingularized = lcfirst(Inflector::singularize($entity));
  66. $this->entityPluralized = lcfirst(Inflector::pluralize($entity));
  67. $this->bundle = $bundle;
  68. $this->metadata = $metadata;
  69. $this->setFormat($format);
  70. $this->generateControllerClass($forceOverwrite);
  71. $dir = sprintf('%s/Resources/views/%s', $this->rootDir, str_replace('\\', '/', strtolower($this->entity)));
  72. if (!file_exists($dir)) {
  73. $this->filesystem->mkdir($dir, 0777);
  74. }
  75. $this->generateIndexView($dir);
  76. if (in_array('show', $this->actions)) {
  77. $this->generateShowView($dir);
  78. }
  79. if (in_array('new', $this->actions)) {
  80. $this->generateNewView($dir);
  81. }
  82. if (in_array('edit', $this->actions)) {
  83. $this->generateEditView($dir);
  84. }
  85. $this->generateTestClass();
  86. $this->generateConfiguration();
  87. }
  88. /**
  89. * Sets the configuration format.
  90. *
  91. * @param string $format The configuration format
  92. */
  93. protected function setFormat($format)
  94. {
  95. switch ($format) {
  96. case 'yml':
  97. case 'xml':
  98. case 'php':
  99. case 'annotation':
  100. $this->format = $format;
  101. break;
  102. default:
  103. $this->format = 'yml';
  104. break;
  105. }
  106. }
  107. /**
  108. * Generates the routing configuration.
  109. */
  110. protected function generateConfiguration()
  111. {
  112. if (!in_array($this->format, array('yml', 'xml', 'php'))) {
  113. return;
  114. }
  115. $target = sprintf(
  116. '%s/Resources/config/routing/%s.%s',
  117. $this->bundle->getPath(),
  118. strtolower(str_replace('\\', '_', $this->entity)),
  119. $this->format
  120. );
  121. $this->renderFile('crud/config/routing.'.$this->format.'.twig', $target, array(
  122. 'actions' => $this->actions,
  123. 'route_prefix' => $this->routePrefix,
  124. 'route_name_prefix' => $this->routeNamePrefix,
  125. 'bundle' => $this->bundle->getName(),
  126. 'entity' => $this->entity,
  127. ));
  128. }
  129. /**
  130. * Generates the controller class only.
  131. */
  132. protected function generateControllerClass($forceOverwrite)
  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 (!$forceOverwrite && file_exists($target)) {
  145. throw new \RuntimeException('Unable to generate the controller as it already exists.');
  146. }
  147. $this->renderFile('crud/controller.php.twig', $target, array(
  148. 'actions' => $this->actions,
  149. 'route_prefix' => $this->routePrefix,
  150. 'route_name_prefix' => $this->routeNamePrefix,
  151. 'bundle' => $this->bundle->getName(),
  152. 'entity' => $this->entity,
  153. 'entity_singularized' => $this->entitySingularized,
  154. 'entity_pluralized' => $this->entityPluralized,
  155. 'entity_class' => $entityClass,
  156. 'namespace' => $this->bundle->getNamespace(),
  157. 'entity_namespace' => $entityNamespace,
  158. 'format' => $this->format,
  159. ));
  160. }
  161. /**
  162. * Generates the functional test class only.
  163. */
  164. protected 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('crud/tests/test.php.twig', $target, array(
  172. 'route_prefix' => $this->routePrefix,
  173. 'route_name_prefix' => $this->routeNamePrefix,
  174. 'entity' => $this->entity,
  175. 'bundle' => $this->bundle->getName(),
  176. 'entity_class' => $entityClass,
  177. 'namespace' => $this->bundle->getNamespace(),
  178. 'entity_namespace' => $entityNamespace,
  179. 'actions' => $this->actions,
  180. 'form_type_name' => strtolower(str_replace('\\', '_', $this->bundle->getNamespace()).($parts ? '_' : '').implode('_', $parts).'_'.$entityClass),
  181. ));
  182. }
  183. /**
  184. * Generates the index.html.twig template in the final bundle.
  185. *
  186. * @param string $dir The path to the folder that hosts templates in the bundle
  187. */
  188. protected function generateIndexView($dir)
  189. {
  190. $this->renderFile('crud/views/index.html.twig.twig', $dir.'/index.html.twig', array(
  191. 'bundle' => $this->bundle->getName(),
  192. 'entity' => $this->entity,
  193. 'entity_pluralized' => $this->entityPluralized,
  194. 'entity_singularized' => $this->entitySingularized,
  195. 'identifier' => $this->metadata->identifier[0],
  196. 'fields' => $this->metadata->fieldMappings,
  197. 'actions' => $this->actions,
  198. 'record_actions' => $this->getRecordActions(),
  199. 'route_prefix' => $this->routePrefix,
  200. 'route_name_prefix' => $this->routeNamePrefix,
  201. ));
  202. }
  203. /**
  204. *
  205. * @param string $dir The path to the folder that hosts templates in the bundle
  206. */
  207. /**
  208. * Generates the new.html.twig template in the final bundle.
  209. *
  210. * @param string $dir The path to the folder that hosts templates in the bundle
  211. */
  212. protected function generateNewView($dir)
  213. {
  214. $this->renderFile('crud/views/new.html.twig.twig', $dir.'/new.html.twig', array(
  215. 'bundle' => $this->bundle->getName(),
  216. 'entity' => $this->entity,
  217. 'entity_singularized' => $this->entitySingularized,
  218. 'route_prefix' => $this->routePrefix,
  219. 'route_name_prefix' => $this->routeNamePrefix,
  220. 'actions' => $this->actions,
  221. 'fields' => $this->metadata->fieldMappings,
  222. ));
  223. }
  224. /**
  225. * Generates the edit.html.twig template in the final bundle.
  226. *
  227. * @param string $dir The path to the folder that hosts templates in the bundle
  228. */
  229. protected function generateEditView($dir)
  230. {
  231. $this->renderFile('crud/views/edit.html.twig.twig', $dir.'/edit.html.twig', array(
  232. 'route_prefix' => $this->routePrefix,
  233. 'route_name_prefix' => $this->routeNamePrefix,
  234. 'identifier' => $this->metadata->identifier[0],
  235. 'entity' => $this->entity,
  236. 'entity_singularized' => $this->entitySingularized,
  237. 'fields' => $this->metadata->fieldMappings,
  238. 'bundle' => $this->bundle->getName(),
  239. 'actions' => $this->actions,
  240. ));
  241. }
  242. /**
  243. * Returns an array of record actions to generate (edit, show).
  244. *
  245. * @return array
  246. */
  247. protected function getRecordActions()
  248. {
  249. return array_filter($this->actions, function ($item) {
  250. return in_array($item, array('show', 'edit'));
  251. });
  252. }
  253. public static function getRouteNamePrefix($prefix)
  254. {
  255. $prefix = preg_replace('/{(.*?)}/', '', $prefix); // {foo}_bar -> _bar
  256. $prefix = str_replace('/', '_', $prefix);
  257. $prefix = preg_replace('/_+/', '_', $prefix); // foo__bar -> foo_bar
  258. $prefix = trim($prefix, '_');
  259. return $prefix;
  260. }
  261. }