PageRenderTime 40ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/Command/UpdateCommand.php

https://github.com/genemu/GenemuDoctrineExtraBundle
PHP | 290 lines | 266 code | 13 blank | 11 comment | 6 complexity | 333a1eb3580058f8807f404a5ac09d0e MD5 | raw file
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Olivier Chauvel <olchauvel@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. namespace Genemu\Bundle\DoctrineExtraBundle\Command;
  11. use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
  12. use Symfony\Component\Console\Input\InputInterface;
  13. use Symfony\Component\Console\Output\OutputInterface;
  14. use Symfony\Component\Finder\Finder;
  15. use Genemu\Bundle\DoctrineExtraBundle\Entity\Bundle;
  16. use Genemu\Bundle\DoctrineExtraBundle\Entity\Controller;
  17. use Genemu\Bundle\DoctrineExtraBundle\Entity\Method;
  18. use Genemu\Bundle\DoctrineExtraBundle\Entity\View;
  19. /**
  20. * @author Olivier Chauvel <olchauvel@gmail.com>
  21. */
  22. class UpdateCommand extends ContainerAwareCommand
  23. {
  24. protected function configure()
  25. {
  26. $this
  27. ->setName('router:fixtures:update')
  28. ->setDescription('Update Bundles, controllers and views to bundles');
  29. }
  30. protected function execute(InputInterface $input, OutputInterface $output)
  31. {
  32. $container = $this->getContainer();
  33. $bundles = array();
  34. if ($container->hasParameter('kernel.bundles')) {
  35. $bundles = $container->getParameter('kernel.bundles');
  36. }
  37. $this->em = $container->get('doctrine')->getEntityManager();
  38. $updated = $this->updateBundle(
  39. $this->searchBundle($bundles),
  40. $this->em->getRepository('GenemuDoctrineExtraBundle:Bundle')->findAllByUpdate(),
  41. $output
  42. );
  43. if (!$updated) {
  44. $output->writeln('<info>Nothing changements</info>');
  45. } else {
  46. $this->em->flush();
  47. }
  48. }
  49. protected function searchBundle(array $bundles)
  50. {
  51. $fBundles = array();
  52. foreach ($bundles as $bundleName => $class) {
  53. $class = new $class();
  54. $controllers = array();
  55. if ($dir = realpath($class->getPath().'/Controller')) {
  56. $files = new Finder();
  57. $files->files()->name('*Controller.php')->in($dir);
  58. foreach ($files as $file) {
  59. if ('Controller.php' !== $controllerName = $file->getBasename('Controller.php')) {
  60. $ns = $class->getNamespace().'\\Controller';
  61. if ($relativePath = $file->getRelativePath()) {
  62. $ns .= '\\'.strtr($relativePath, array('/' => '\\'));
  63. }
  64. $reflection = new \ReflectionClass($ns.'\\'.$file->getBasename('.php'));
  65. $methods = array();
  66. foreach ($reflection->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) {
  67. if (preg_match('/^(.+)Action$/', $method->getName(), $matchAction)) {
  68. $methods[$matchAction[1]] = true;
  69. }
  70. }
  71. $parent = $reflection->getParentClass();
  72. if ($parent) {
  73. foreach ($parent->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) {
  74. if (preg_match('/^(.+)Action$/', $method->getName())) {
  75. $methods[strtr($method->getName(), array('Action' => ''))] = true;
  76. }
  77. }
  78. }
  79. $controllers[$controllerName] = array(
  80. 'methods' => $methods
  81. );
  82. }
  83. }
  84. }
  85. $views = array();
  86. if ($dir = realpath($class->getPath().'/Resources/views')) {
  87. $files = new Finder();
  88. $files->files()->in($dir);
  89. foreach ($files as $file) {
  90. $views[$file->getRelativePath().':'.$file->getBasename()] = true;
  91. }
  92. }
  93. $fBundles[$bundleName] = array(
  94. 'controllers' => $controllers,
  95. 'views' => $views
  96. );
  97. }
  98. return $fBundles;
  99. }
  100. protected function updateBundle(array $files, array $bundles, OutputInterface $output)
  101. {
  102. $updated = false;
  103. foreach ($files as $bundleName => $bundleValues) {
  104. if (isset($bundles[$bundleName])) {
  105. $bundle = $bundles[$bundleName];
  106. foreach ($bundleValues['controllers'] as $controllerName => $controllerValues) {
  107. if (isset($bundle['controllers'][$controllerName])) {
  108. $controller = $bundle['controllers'][$controllerName];
  109. foreach ($controllerValues['methods'] as $methodName => $methodValues) {
  110. if (isset($controller['methods'][$methodName])) {
  111. unset($controller['methods'][$methodName]);
  112. } else {
  113. $updated = true;
  114. $this->createMethod($output, $methodName, $controller['entity']);
  115. }
  116. }
  117. foreach ($controller['methods'] as $name => $values) {
  118. $update = true;
  119. $output->writeln('<info>Remove method '.$name.' in '.$controllerName.'</info>');
  120. $this->em->remove($values['entity']);
  121. }
  122. unset($bundle['controllers'][$controllerName]);
  123. } else {
  124. $updated = true;
  125. $this->createController($output, $controllerName, $bundle['entity'], $controllerValues['methods']);
  126. }
  127. }
  128. foreach ($bundle['controllers'] as $name => $values) {
  129. $updated = true;
  130. $output->writeln('<info>Remove controller '.$name.' in '.$bundleName.'</info>');
  131. $this->em->remove($values['entity']);
  132. }
  133. foreach ($bundleValues['views'] as $viewName => $viewValues) {
  134. if (isset($bundle['views'][$viewName])) {
  135. unset($bundle['views'][$viewName]);
  136. } else {
  137. $updated = true;
  138. $this->createView($output, $viewName, $bundle['entity']);
  139. }
  140. }
  141. foreach ($bundle['views'] as $name => $values) {
  142. $updated = true;
  143. $output->writeln('<info>Remove view '.$name.' in '.$bundleName.'</info>');
  144. $this->em->remove($values['entity']);
  145. }
  146. unset($bundles[$bundleName]);
  147. } else {
  148. $updated = true;
  149. $bundle = $this->createBundle($output, $bundleName, $bundleValues['controllers']);
  150. foreach ($bundleValues['views'] as $viewName => $viewValues) {
  151. $this->createView($output, $viewName, $bundle);
  152. }
  153. }
  154. }
  155. foreach ($bundles as $name => $values) {
  156. $updated = true;
  157. $output->writeln('<info>Remove bundle '.$name.'</info>');
  158. $this->em->remove($values['entity']);
  159. }
  160. return $updated;
  161. }
  162. /**
  163. * Create bundle
  164. *
  165. * @param OutputInterface $output
  166. * @param string $name
  167. * @param array $controllers
  168. *
  169. * @return Bundle $bundle
  170. */
  171. protected function createBundle(OutputInterface $output, $name, array $controllers)
  172. {
  173. $bundle = new Bundle();
  174. $bundle->setName($name);
  175. $this->em->persist($bundle);
  176. $output->writeln('<info>Create bundle '.$name.'</info>');
  177. foreach ($controllers as $name => $values) {
  178. $this->createController($output, $name, $bundle, $values['methods']);
  179. }
  180. return $bundle;
  181. }
  182. /**
  183. * Create controller
  184. *
  185. * @param OutputInterface $output
  186. * @param string $name
  187. * @param Bundle $bundle
  188. * @param array $methods
  189. *
  190. * @return Controller $controller
  191. */
  192. protected function createController(OutputInterface $output, $name, Bundle $bundle, array $methods)
  193. {
  194. $controller = new Controller();
  195. $controller->setName($name);
  196. $controller->setBundle($bundle);
  197. $this->em->persist($controller);
  198. $output->writeln('<info>Create controller '.$name.' in '.$bundle->getName().'</info>');
  199. foreach ($methods as $name => $values) {
  200. $this->createMethod($output, $name, $controller);
  201. }
  202. return $controller;
  203. }
  204. /**
  205. * Create method
  206. *
  207. * @param OutputInterface $output
  208. * @param string $name
  209. * @param Controller $controller
  210. *
  211. * @return Method $method
  212. */
  213. protected function createMethod(OutputInterface $output, $name, Controller $controller)
  214. {
  215. $method = new Method();
  216. $method->setName($name);
  217. $method->setController($controller);
  218. $this->em->persist($method);
  219. $output->writeln('<info>Ctreate method '.$name.' in '.$controller->getName().'</info>');
  220. return $method;
  221. }
  222. /**
  223. * Create view
  224. *
  225. * @param OutputInterface $output
  226. * @param string $name
  227. * @param Bundle $bundle
  228. *
  229. * @return View $view
  230. */
  231. protected function createView(OutputInterface $output, $name, Bundle $bundle)
  232. {
  233. list($directory, $file) = explode(':', $name);
  234. list($name, $format, $engine) = explode('.', $file);
  235. $view = new View();
  236. $view->setBundle($bundle);
  237. $view->setDirectory($directory);
  238. $view->setName($name);
  239. $view->setFormat($format);
  240. $view->setEngine($engine);
  241. $this->em->persist($view);
  242. $output->writeln('<info>Create view '.$file.' in '.$bundle->getName().'</info>');
  243. return $view;
  244. }
  245. }