082a0130c2
Signed-off-by: Gergely POLONKAI (W00d5t0ck) <polesz@w00d5t0ck.info>
291 lines
9.6 KiB
PHP
291 lines
9.6 KiB
PHP
<?php
|
|
|
|
/*
|
|
* This file is part of the Symfony package.
|
|
*
|
|
* (c) Fabien Potencier <fabien@symfony.com>
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace Sensio\Bundle\GeneratorBundle\Generator;
|
|
|
|
use Symfony\Component\Filesystem\Filesystem;
|
|
use Symfony\Component\HttpKernel\Bundle\BundleInterface;
|
|
use Doctrine\ORM\Mapping\ClassMetadataInfo;
|
|
|
|
/**
|
|
* Generates a CRUD controller.
|
|
*
|
|
* @author Fabien Potencier <fabien@symfony.com>
|
|
*/
|
|
class DoctrineCrudGenerator extends Generator
|
|
{
|
|
protected $filesystem;
|
|
protected $skeletonDir;
|
|
protected $routePrefix;
|
|
protected $routeNamePrefix;
|
|
protected $bundle;
|
|
protected $entity;
|
|
protected $metadata;
|
|
protected $format;
|
|
protected $actions;
|
|
|
|
/**
|
|
* Constructor.
|
|
*
|
|
* @param Filesystem $filesystem A Filesystem instance
|
|
* @param string $skeletonDir Path to the skeleton directory
|
|
*/
|
|
public function __construct(Filesystem $filesystem, $skeletonDir)
|
|
{
|
|
$this->filesystem = $filesystem;
|
|
$this->skeletonDir = $skeletonDir;
|
|
}
|
|
|
|
/**
|
|
* Generate the CRUD controller.
|
|
*
|
|
* @param BundleInterface $bundle A bundle object
|
|
* @param string $entity The entity relative class name
|
|
* @param ClassMetadataInfo $metadata The entity class metadata
|
|
* @param string $format The configuration format (xml, yaml, annotation)
|
|
* @param string $routePrefix The route name prefix
|
|
* @param array $needWriteActions Wether or not to generate write actions
|
|
*
|
|
* @throws \RuntimeException
|
|
*/
|
|
public function generate(BundleInterface $bundle, $entity, ClassMetadataInfo $metadata, $format, $routePrefix, $needWriteActions)
|
|
{
|
|
$this->routePrefix = $routePrefix;
|
|
$this->routeNamePrefix = str_replace('/', '_', $routePrefix);
|
|
$this->actions = $needWriteActions ? array('index', 'show', 'new', 'edit', 'delete') : array('index', 'show');
|
|
|
|
if (count($metadata->identifier) > 1) {
|
|
throw new \RuntimeException('The CRUD generator does not support entity classes with multiple primary keys.');
|
|
}
|
|
|
|
if (!in_array('id', $metadata->identifier)) {
|
|
throw new \RuntimeException('The CRUD generator expects the entity object has a primary key field named "id" with a getId() method.');
|
|
}
|
|
|
|
$this->entity = $entity;
|
|
$this->bundle = $bundle;
|
|
$this->metadata = $metadata;
|
|
$this->setFormat($format);
|
|
|
|
$this->generateControllerClass();
|
|
|
|
$dir = sprintf('%s/Resources/views/%s', $this->bundle->getPath(), str_replace('\\', '/', $this->entity));
|
|
|
|
if (!file_exists($dir)) {
|
|
$this->filesystem->mkdir($dir, 0777);
|
|
}
|
|
|
|
$this->generateIndexView($dir);
|
|
|
|
if (in_array('show', $this->actions)) {
|
|
$this->generateShowView($dir);
|
|
}
|
|
|
|
if (in_array('new', $this->actions)) {
|
|
$this->generateNewView($dir);
|
|
}
|
|
|
|
if (in_array('edit', $this->actions)) {
|
|
$this->generateEditView($dir);
|
|
}
|
|
|
|
$this->generateTestClass();
|
|
$this->generateConfiguration();
|
|
}
|
|
|
|
/**
|
|
* Sets the configuration format.
|
|
*
|
|
* @param string $format The configuration format
|
|
*/
|
|
private function setFormat($format)
|
|
{
|
|
switch ($format) {
|
|
case 'yml':
|
|
case 'xml':
|
|
case 'php':
|
|
case 'annotation':
|
|
$this->format = $format;
|
|
break;
|
|
default:
|
|
$this->format = 'yml';
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Generates the routing configuration.
|
|
*
|
|
*/
|
|
private function generateConfiguration()
|
|
{
|
|
if (!in_array($this->format, array('yml', 'xml', 'php'))) {
|
|
return;
|
|
}
|
|
|
|
$target = sprintf(
|
|
'%s/Resources/config/routing/%s.%s',
|
|
$this->bundle->getPath(),
|
|
strtolower(str_replace('\\', '_', $this->entity)),
|
|
$this->format
|
|
);
|
|
|
|
$this->renderFile($this->skeletonDir, 'config/routing.'.$this->format, $target, array(
|
|
'actions' => $this->actions,
|
|
'route_prefix' => $this->routePrefix,
|
|
'route_name_prefix' => $this->routeNamePrefix,
|
|
'bundle' => $this->bundle->getName(),
|
|
'entity' => $this->entity,
|
|
));
|
|
}
|
|
|
|
/**
|
|
* Generates the controller class only.
|
|
*
|
|
*/
|
|
private function generateControllerClass()
|
|
{
|
|
$dir = $this->bundle->getPath();
|
|
|
|
$parts = explode('\\', $this->entity);
|
|
$entityClass = array_pop($parts);
|
|
$entityNamespace = implode('\\', $parts);
|
|
|
|
$target = sprintf(
|
|
'%s/Controller/%s/%sController.php',
|
|
$dir,
|
|
str_replace('\\', '/', $entityNamespace),
|
|
$entityClass
|
|
);
|
|
|
|
if (file_exists($target)) {
|
|
throw new \RuntimeException('Unable to generate the controller as it already exists.');
|
|
}
|
|
|
|
$this->renderFile($this->skeletonDir, 'controller.php', $target, array(
|
|
'actions' => $this->actions,
|
|
'route_prefix' => $this->routePrefix,
|
|
'route_name_prefix' => $this->routeNamePrefix,
|
|
'dir' => $this->skeletonDir,
|
|
'bundle' => $this->bundle->getName(),
|
|
'entity' => $this->entity,
|
|
'entity_class' => $entityClass,
|
|
'namespace' => $this->bundle->getNamespace(),
|
|
'entity_namespace' => $entityNamespace,
|
|
'format' => $this->format,
|
|
));
|
|
}
|
|
|
|
/**
|
|
* Generates the functional test class only.
|
|
*
|
|
*/
|
|
private function generateTestClass()
|
|
{
|
|
$parts = explode('\\', $this->entity);
|
|
$entityClass = array_pop($parts);
|
|
$entityNamespace = implode('\\', $parts);
|
|
|
|
$dir = $this->bundle->getPath() .'/Tests/Controller';
|
|
$target = $dir .'/'. str_replace('\\', '/', $entityNamespace).'/'. $entityClass .'ControllerTest.php';
|
|
|
|
$this->renderFile($this->skeletonDir, 'tests/test.php', $target, array(
|
|
'route_prefix' => $this->routePrefix,
|
|
'route_name_prefix' => $this->routeNamePrefix,
|
|
'entity' => $this->entity,
|
|
'entity_class' => $entityClass,
|
|
'namespace' => $this->bundle->getNamespace(),
|
|
'entity_namespace' => $entityNamespace,
|
|
'actions' => $this->actions,
|
|
'dir' => $this->skeletonDir,
|
|
));
|
|
}
|
|
|
|
/**
|
|
* Generates the index.html.twig template in the final bundle.
|
|
*
|
|
* @param string $dir The path to the folder that hosts templates in the bundle
|
|
*/
|
|
private function generateIndexView($dir)
|
|
{
|
|
$this->renderFile($this->skeletonDir, 'views/index.html.twig', $dir.'/index.html.twig', array(
|
|
'dir' => $this->skeletonDir,
|
|
'entity' => $this->entity,
|
|
'fields' => $this->metadata->fieldMappings,
|
|
'actions' => $this->actions,
|
|
'record_actions' => $this->getRecordActions(),
|
|
'route_prefix' => $this->routePrefix,
|
|
'route_name_prefix' => $this->routeNamePrefix,
|
|
));
|
|
}
|
|
|
|
/**
|
|
* Generates the show.html.twig template in the final bundle.
|
|
*
|
|
* @param string $dir The path to the folder that hosts templates in the bundle
|
|
*/
|
|
private function generateShowView($dir)
|
|
{
|
|
$this->renderFile($this->skeletonDir, 'views/show.html.twig', $dir.'/show.html.twig', array(
|
|
'dir' => $this->skeletonDir,
|
|
'entity' => $this->entity,
|
|
'fields' => $this->metadata->fieldMappings,
|
|
'actions' => $this->actions,
|
|
'route_prefix' => $this->routePrefix,
|
|
'route_name_prefix' => $this->routeNamePrefix,
|
|
));
|
|
}
|
|
|
|
/**
|
|
* Generates the new.html.twig template in the final bundle.
|
|
*
|
|
* @param string $dir The path to the folder that hosts templates in the bundle
|
|
*/
|
|
private function generateNewView($dir)
|
|
{
|
|
$this->renderFile($this->skeletonDir, 'views/new.html.twig', $dir.'/new.html.twig', array(
|
|
'dir' => $this->skeletonDir,
|
|
'route_prefix' => $this->routePrefix,
|
|
'route_name_prefix' => $this->routeNamePrefix,
|
|
'entity' => $this->entity,
|
|
'actions' => $this->actions,
|
|
));
|
|
}
|
|
|
|
/**
|
|
* Generates the edit.html.twig template in the final bundle.
|
|
*
|
|
* @param string $dir The path to the folder that hosts templates in the bundle
|
|
*/
|
|
private function generateEditView($dir)
|
|
{
|
|
$this->renderFile($this->skeletonDir, 'views/edit.html.twig', $dir.'/edit.html.twig', array(
|
|
'dir' => $this->skeletonDir,
|
|
'route_prefix' => $this->routePrefix,
|
|
'route_name_prefix' => $this->routeNamePrefix,
|
|
'entity' => $this->entity,
|
|
'actions' => $this->actions,
|
|
));
|
|
}
|
|
|
|
/**
|
|
* Returns an array of record actions to generate (edit, show).
|
|
*
|
|
* @return array
|
|
*/
|
|
private function getRecordActions()
|
|
{
|
|
return array_filter($this->actions, function($item) {
|
|
return in_array($item, array('show', 'edit'));
|
|
});
|
|
}
|
|
}
|