forked from stwe/DatatablesBundle
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Максим Пешехонов
committed
May 25, 2020
1 parent
9767fca
commit ad085a0
Showing
5 changed files
with
353 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,237 @@ | ||
<?php | ||
|
||
namespace Sg\DatatablesBundle\Maker; | ||
|
||
|
||
use Symfony\Bundle\MakerBundle\InputAwareMakerInterface; | ||
use Symfony\Bundle\MakerBundle\Maker\AbstractMaker; | ||
use Symfony\Bundle\MakerBundle\ConsoleStyle; | ||
use Symfony\Bundle\MakerBundle\MakerInterface; | ||
use Symfony\Component\Console\Command\Command; | ||
use Symfony\Component\Console\Input\InputInterface; | ||
use Symfony\Bundle\MakerBundle\InputConfiguration; | ||
use Symfony\Bundle\MakerBundle\DependencyBuilder; | ||
Use Symfony\Bundle\MakerBundle\Generator; | ||
use Symfony\Bundle\MakerBundle\Doctrine\DoctrineHelper; | ||
use Symfony\Component\Console\Input\InputArgument; | ||
use Symfony\Bundle\MakerBundle\Str; | ||
use Symfony\Bundle\MakerBundle\Validator; | ||
use Symfony\Bundle\TwigBundle; | ||
use Doctrine\Bundle\DoctrineBundle; | ||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; | ||
use Symfony\Component\Console\Question\Question; | ||
use Doctrine\ORM\Mapping\ClassMetadataInfo; | ||
|
||
|
||
class MakeDatatable extends AbstractMaker | ||
{ | ||
private $doctrineHelper; | ||
private $baseSleleton; | ||
private $columnTypes = [ 'ActionColumn' => 'ActionColumn']; | ||
|
||
public function __construct(DoctrineHelper $doctrineHelper) | ||
{ | ||
$this->doctrineHelper = $doctrineHelper; | ||
$this->baseSleleton = realpath(__DIR__.'/../Resources/views/skeleton'); | ||
} | ||
|
||
|
||
public static function getCommandName(): string | ||
{ | ||
return 'make:datatable'; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function configureCommand(Command $command, InputConfiguration $inputConfig) | ||
{ | ||
$command | ||
->setDescription('Creates Datable for Doctrine entity class') | ||
->addArgument('entity-class', InputArgument::OPTIONAL, sprintf('The class name of the entity to create CRUD (e.g. <fg=yellow>%s</>)', Str::asClassName(Str::getRandomTerm()))) | ||
->setHelp(file_get_contents(__DIR__.'/../Resources/help/MakeDatatable.txt')) | ||
; | ||
$inputConfig->setArgumentAsNonInteractive('entity-class'); | ||
} | ||
|
||
public function interact(InputInterface $input, ConsoleStyle $io, Command $command) | ||
{ | ||
if (null === $input->getArgument('entity-class')) { | ||
$argument = $command->getDefinition()->getArgument('entity-class'); | ||
$entities = $this->doctrineHelper->getEntitiesForAutocomplete(); | ||
$question = new Question($argument->getDescription()); | ||
$question->setAutocompleterValues($entities); | ||
$value = $io->askQuestion($question); | ||
$input->setArgument('entity-class', $value); | ||
} | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function configureDependencies(DependencyBuilder $dependencies) | ||
{ | ||
} | ||
|
||
public function generate(InputInterface $input, ConsoleStyle $io, Generator $generator) | ||
{ | ||
$entityClassDetails = $generator->createClassNameDetails( | ||
Validator::entityExists($input->getArgument('entity-class'), $this->doctrineHelper->getEntitiesForAutocomplete()), | ||
'Entity\\' | ||
); | ||
|
||
|
||
$entityDoctrineDetails = $this->doctrineHelper->createDoctrineDetails($entityClassDetails->getFullName()); | ||
|
||
$datatableClassDetails = $generator->createClassNameDetails( | ||
$entityClassDetails->getRelativeNameWithoutSuffix(), | ||
'Datatables\\', | ||
'Datatable' | ||
); | ||
|
||
$className = $datatableClassDetails->getShortName(); | ||
$entityClassLowerCase = strtolower($className); | ||
|
||
$metadata = $this->getEntityMetadata($entityClassDetails->getFullName()); | ||
$fields = $this->getFieldsFromMetadata($metadata); | ||
|
||
sort($this->columnTypes); | ||
$generator->generateClass( | ||
$datatableClassDetails->getFullName(), | ||
$this->baseSleleton . '/Datatable.tpl.php', | ||
[ | ||
'bounded_full_class_name' => $entityClassDetails->getFullName(), | ||
'bounded_class_name' => $entityClassDetails->getShortName(), | ||
'fields' => $fields, | ||
'class_name' => $className, | ||
'datatable_name' => $entityClassLowerCase.'_datatable', | ||
'route_pref' => $entityClassLowerCase, | ||
'column_types' => $this->columnTypes, | ||
'id' => $this->getIdentifierFromMetadata($metadata), | ||
] | ||
); | ||
|
||
$generator->writeChanges(); | ||
|
||
} | ||
|
||
//------------------------------------------------- | ||
// Helper | ||
//------------------------------------------------- | ||
|
||
/** | ||
* Parse fields. | ||
* | ||
* @param string $input | ||
* | ||
* @return array | ||
*/ | ||
private static function parseFields($input) | ||
{ | ||
$fields = array(); | ||
|
||
foreach (explode(' ', $input) as $value) { | ||
$elements = explode(':', $value); | ||
|
||
$row = array(); | ||
$row['property'] = $elements[0]; | ||
$row['column_type'] = 'Column::class'; | ||
$row['data'] = null; | ||
$row['title'] = ucwords(str_replace('.', ' ', $elements[0])); | ||
|
||
if (isset($elements[1])) { | ||
switch ($elements[1]) { | ||
case 'datetime': | ||
$row['column_type'] = 'DateTimeColumn::class'; | ||
break; | ||
case 'boolean': | ||
$row['column_type'] = 'BooleanColumn::class'; | ||
break; | ||
} | ||
} | ||
|
||
$fields[] = $row; | ||
} | ||
|
||
return $fields; | ||
} | ||
|
||
private function getEntityMetadata($class) | ||
{ | ||
return $this->doctrineHelper->getMetadata($class, true); | ||
} | ||
|
||
/** | ||
* Get Id from metadata. | ||
* | ||
* @param array $metadata | ||
* | ||
* @return mixed | ||
* @throws Exception | ||
*/ | ||
private function getIdentifierFromMetadata(ClassMetadataInfo $metadata) | ||
{ | ||
if (count($metadata->identifier) > 1) { | ||
throw new Exception('CreateDatatableCommand::getIdentifierFromMetadata(): The Datatable generator does not support entities with multiple primary keys.'); | ||
} | ||
|
||
return $metadata->identifier; | ||
} | ||
|
||
/** | ||
* Returns an array of fields. Fields can be both column fields and | ||
* association fields. | ||
* | ||
* @param ClassMetadataInfo $metadata | ||
* | ||
* @return array $fields | ||
*/ | ||
private function getFieldsFromMetadata(ClassMetadataInfo $metadata) | ||
{ | ||
$fields = array(); | ||
|
||
foreach ($metadata->fieldMappings as $field) { | ||
$row = array(); | ||
$row['property'] = $field['fieldName']; | ||
|
||
switch ($field['type']) { | ||
case 'datetime': | ||
$row['column_type'] = 'DateTimeColumn::class'; | ||
break; | ||
case 'boolean': | ||
$row['column_type'] = 'BooleanColumn::class'; | ||
break; | ||
default: | ||
$row['column_type'] = 'Column::class'; | ||
} | ||
|
||
$row['title'] = ucwords($field['fieldName']); | ||
$row['data'] = null; | ||
$fields[] = $row; | ||
if(!isset($this->columnTypes[$row['column_type']])) { | ||
$this->columnTypes[$row['column_type']] = substr($row['column_type'], 0, -7); | ||
} | ||
|
||
} | ||
|
||
foreach ($metadata->associationMappings as $relation) { | ||
$targetClass = $relation['targetEntity']; | ||
$targetMetadata = $this->getEntityMetadata($targetClass, true); | ||
|
||
foreach ($targetMetadata->fieldMappings as $field) { | ||
$row = array(); | ||
$row['property'] = $relation['fieldName'].'.'.$field['fieldName']; | ||
$row['column_type'] = 'Column::class'; | ||
$row['title'] = ucwords(str_replace('.', ' ', $row['property'])); | ||
if ($relation['type'] === ClassMetadataInfo::ONE_TO_MANY || $relation['type'] === ClassMetadataInfo::MANY_TO_MANY) { | ||
$row['data'] = $relation['fieldName'].'[, ].'.$field['fieldName']; | ||
} else { | ||
$row['data'] = null; | ||
} | ||
$fields[] = $row; | ||
} | ||
} | ||
|
||
return $fields; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
services: | ||
sg_datatables.maker: | ||
class: Sg\DatatablesBundle\Maker\MakeDatatable | ||
public: true | ||
arguments: | ||
- '@maker.doctrine_helper' | ||
tags: | ||
- { name: maker.command } |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
<?= "<?php" . PHP_EOL ?> | ||
|
||
namespace <?= $namespace ?>; | ||
|
||
use Sg\DatatablesBundle\Datatable\AbstractDatatable; | ||
|
||
<?php foreach ($column_types as $type): ?> | ||
use Sg\DatatablesBundle\Datatable\Column\<?= $type ?>; | ||
<?php endforeach; ?> | ||
|
||
/** | ||
* Class <?= $class_name.PHP_EOL ?> | ||
* | ||
* @package <?= $namespace ?>\Datatables | ||
*/ | ||
class <?= $class_name ?> extends AbstractDatatable | ||
{ | ||
|
||
/** | ||
* {@inheritdoc} | ||
* | ||
* @throws \Exception | ||
*/ | ||
public function buildDatatable(array $options = array()) | ||
{ | ||
$this->language->set(array( | ||
'cdn_language_by_locale' => true | ||
//'language' => 'de' | ||
)); | ||
|
||
$this->ajax->set(array( | ||
)); | ||
|
||
$this->options->set(array( | ||
'individual_filtering' => true, | ||
'individual_filtering_position' => 'head', | ||
'order_cells_top' => true, | ||
)); | ||
|
||
$this->features->set(array( | ||
)); | ||
|
||
$this->columnBuilder | ||
<?php foreach ($fields as $field): ?> | ||
->add('<?= $field['property'] ?>', <?= $field['column_type'] ?>, array( | ||
'title' => '<?= $field['title'] ?>', | ||
<?php if (isset($field['data']) && $field['data']!== null ): ?> | ||
'data' => '<?= $field['data'] ?>' | ||
<?php endif ?> | ||
)) | ||
<?php endforeach; ?> | ||
->add(null, ActionColumn::class, array( | ||
'title' => $this->translator->trans('sg.datatables.actions.title'), | ||
'actions' => array( | ||
array( | ||
'route' => '<?= $route_pref ?>_show', | ||
'route_parameters' => array( | ||
'id' => 'id' | ||
), | ||
'label' => $this->translator->trans('sg.datatables.actions.show'), | ||
'icon' => 'glyphicon glyphicon-eye-open', | ||
'attributes' => array( | ||
'rel' => 'tooltip', | ||
'title' => $this->translator->trans('sg.datatables.actions.show'), | ||
'class' => 'btn btn-primary btn-xs', | ||
'role' => 'button' | ||
), | ||
), | ||
array( | ||
'route' => '<?= $route_pref ?>_edit', | ||
'route_parameters' => array( | ||
'id' => 'id' | ||
), | ||
'label' => $this->translator->trans('sg.datatables.actions.edit'), | ||
'icon' => 'glyphicon glyphicon-edit', | ||
'attributes' => array( | ||
'rel' => 'tooltip', | ||
'title' => $this->translator->trans('sg.datatables.actions.edit'), | ||
'class' => 'btn btn-primary btn-xs', | ||
'role' => 'button' | ||
), | ||
) | ||
) | ||
)); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getEntity() | ||
{ | ||
return '<?= $bounded_full_class_name ?>'; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getName() | ||
{ | ||
return '<?= $datatable_name ?>'; | ||
} | ||
} |