-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Showing
6 changed files
with
409 additions
and
293 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* | ||
* This file is part of the Sonata Project package. | ||
* | ||
* (c) Thomas Rabaix <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Sonata\AdminBundle\Form\Extension; | ||
|
||
use Symfony\Component\Form\AbstractTypeExtension; | ||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; | ||
use Symfony\Component\Form\FormInterface; | ||
use Symfony\Component\Form\FormView; | ||
use Symfony\Component\OptionsResolver\OptionsResolver; | ||
|
||
/** | ||
* NEXT_MAJOR: Copy its methods to ChoiceTypeExtension and remove it. | ||
* | ||
* @internal | ||
*/ | ||
abstract class BaseChoiceTypeExtension extends AbstractTypeExtension | ||
{ | ||
public function configureOptions(OptionsResolver $resolver) | ||
{ | ||
$optionalOptions = ['sortable']; | ||
|
||
$resolver->setDefined($optionalOptions); | ||
} | ||
|
||
public function buildView(FormView $view, FormInterface $form, array $options) | ||
{ | ||
$view->vars['sortable'] = \array_key_exists('sortable', $options) && $options['sortable']; | ||
} | ||
|
||
public function getExtendedType() | ||
{ | ||
return ChoiceType::class; | ||
} | ||
} |
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 |
---|---|---|
|
@@ -13,38 +13,36 @@ | |
|
||
namespace Sonata\AdminBundle\Form\Extension; | ||
|
||
use Symfony\Component\Form\AbstractTypeExtension; | ||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; | ||
use Symfony\Component\Form\FormInterface; | ||
use Symfony\Component\Form\FormView; | ||
use Symfony\Component\OptionsResolver\OptionsResolver; | ||
|
||
/** | ||
* @final since sonata-project/admin-bundle 3.52 | ||
* | ||
* @author Amine Zaghdoudi <[email protected]> | ||
*/ | ||
class ChoiceTypeExtension extends AbstractTypeExtension | ||
{ | ||
public function configureOptions(OptionsResolver $resolver) | ||
{ | ||
$optionalOptions = ['sortable']; | ||
|
||
$resolver->setDefined($optionalOptions); | ||
} | ||
|
||
public function buildView(FormView $view, FormInterface $form, array $options) | ||
use Symfony\Component\Form\FormTypeExtensionInterface; | ||
|
||
// NEXT_MAJOR: Remove the "else" part, copy all methods from BaseChoiceTypeExtension in this class and | ||
// extend from AbstractTypeExtension. | ||
if (method_exists(FormTypeExtensionInterface::class, 'getExtendedTypes')) { | ||
/** | ||
* @final since sonata-project/admin-bundle 3.52 | ||
* | ||
* @author Amine Zaghdoudi <[email protected]> | ||
*/ | ||
class ChoiceTypeExtension extends BaseChoiceTypeExtension | ||
{ | ||
$view->vars['sortable'] = \array_key_exists('sortable', $options) && $options['sortable']; | ||
public static function getExtendedTypes(): iterable | ||
{ | ||
return [ChoiceType::class]; | ||
} | ||
} | ||
|
||
public function getExtendedType() | ||
{ | ||
return ChoiceType::class; | ||
} | ||
|
||
public static function getExtendedTypes(): iterable | ||
} else { | ||
/** | ||
* @final since sonata-project/admin-bundle 3.52 | ||
* | ||
* @author Amine Zaghdoudi <[email protected]> | ||
*/ | ||
class ChoiceTypeExtension extends BaseChoiceTypeExtension | ||
{ | ||
return [ChoiceType::class]; | ||
public static function getExtendedTypes() | ||
{ | ||
return [ChoiceType::class]; | ||
} | ||
} | ||
} |
239 changes: 239 additions & 0 deletions
239
src/Form/Extension/Field/Type/BaseFormTypeFieldExtension.php
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,239 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* | ||
* This file is part of the Sonata Project package. | ||
* | ||
* (c) Thomas Rabaix <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Sonata\AdminBundle\Form\Extension\Field\Type; | ||
|
||
use Sonata\AdminBundle\Admin\FieldDescriptionInterface; | ||
use Sonata\AdminBundle\Exception\NoValueException; | ||
use Symfony\Component\Form\AbstractTypeExtension; | ||
use Symfony\Component\Form\Extension\Core\Type\FormType; | ||
use Symfony\Component\Form\FormBuilderInterface; | ||
use Symfony\Component\Form\FormInterface; | ||
use Symfony\Component\Form\FormView; | ||
use Symfony\Component\OptionsResolver\OptionsResolver; | ||
|
||
/** | ||
* NEXT_MAJOR: Copy its methods to FormTypeFieldExtension and remove it. | ||
* | ||
* @internal | ||
*/ | ||
abstract class BaseFormTypeFieldExtension extends AbstractTypeExtension | ||
{ | ||
/** | ||
* @var array | ||
*/ | ||
protected $defaultClasses = []; | ||
|
||
/** | ||
* @var array | ||
*/ | ||
protected $options = []; | ||
|
||
public function __construct(array $defaultClasses, array $options) | ||
{ | ||
$this->defaultClasses = $defaultClasses; | ||
$this->options = $options; | ||
} | ||
|
||
public function buildForm(FormBuilderInterface $builder, array $options) | ||
{ | ||
$sonataAdmin = [ | ||
'name' => null, | ||
'admin' => null, | ||
'value' => null, | ||
'edit' => 'standard', | ||
'inline' => 'natural', | ||
'field_description' => null, | ||
'block_name' => false, | ||
'options' => $this->options, | ||
]; | ||
|
||
$builder->setAttribute('sonata_admin_enabled', false); | ||
// NEXT_MAJOR: Remove this line | ||
$builder->setAttribute('sonata_help', false); | ||
|
||
if ($options['sonata_field_description'] instanceof FieldDescriptionInterface) { | ||
$fieldDescription = $options['sonata_field_description']; | ||
|
||
$sonataAdmin['admin'] = $fieldDescription->getAdmin(); | ||
$sonataAdmin['field_description'] = $fieldDescription; | ||
$sonataAdmin['name'] = $fieldDescription->getName(); | ||
$sonataAdmin['edit'] = $fieldDescription->getOption('edit', 'standard'); | ||
$sonataAdmin['inline'] = $fieldDescription->getOption('inline', 'natural'); | ||
$sonataAdmin['block_name'] = $fieldDescription->getOption('block_name', false); | ||
$sonataAdmin['class'] = $this->getClass($builder); | ||
|
||
$builder->setAttribute('sonata_admin_enabled', true); | ||
} | ||
|
||
$builder->setAttribute('sonata_admin', $sonataAdmin); | ||
} | ||
|
||
public function buildView(FormView $view, FormInterface $form, array $options) | ||
{ | ||
$sonataAdmin = $form->getConfig()->getAttribute('sonata_admin'); | ||
// NEXT_MAJOR: Remove this line | ||
$sonataAdminHelp = $options['sonata_help'] ?? null; | ||
|
||
/* | ||
* We have a child, so we need to upgrade block prefix | ||
*/ | ||
if ($view->parent && $view->parent->vars['sonata_admin_enabled'] && !$sonataAdmin['admin']) { | ||
$blockPrefixes = $view->vars['block_prefixes']; | ||
$baseName = str_replace('.', '_', $view->parent->vars['sonata_admin_code']); | ||
|
||
$baseType = $blockPrefixes[\count($blockPrefixes) - 2]; | ||
$blockSuffix = preg_replace('#^_([a-z0-9]{14})_(.++)$#', '$2', end($blockPrefixes)); | ||
|
||
$blockPrefixes[] = sprintf('%s_%s', $baseName, $baseType); | ||
$blockPrefixes[] = sprintf('%s_%s_%s_%s', $baseName, $baseType, $view->parent->vars['name'], $view->vars['name']); | ||
$blockPrefixes[] = sprintf('%s_%s_%s_%s', $baseName, $baseType, $view->parent->vars['name'], $blockSuffix); | ||
|
||
$view->vars['block_prefixes'] = array_unique($blockPrefixes); | ||
$view->vars['sonata_admin_enabled'] = true; | ||
$view->vars['sonata_admin'] = [ | ||
'admin' => false, | ||
'field_description' => false, | ||
'name' => false, | ||
'edit' => 'standard', | ||
'inline' => 'natural', | ||
'block_name' => false, | ||
'class' => false, | ||
'options' => $this->options, | ||
]; | ||
// NEXT_MAJOR: Remove this line | ||
$view->vars['sonata_help'] = $sonataAdminHelp; | ||
$view->vars['sonata_admin_code'] = $view->parent->vars['sonata_admin_code']; | ||
|
||
return; | ||
} | ||
|
||
// avoid to add extra information not required by non admin field | ||
if ($sonataAdmin && $form->getConfig()->getAttribute('sonata_admin_enabled', true)) { | ||
$sonataAdmin['value'] = $form->getData(); | ||
|
||
// add a new block types, so the Admin Form element can be tweaked based on the admin code | ||
$blockPrefixes = $view->vars['block_prefixes']; | ||
$baseName = str_replace('.', '_', $sonataAdmin['admin']->getCode()); | ||
$baseType = $blockPrefixes[\count($blockPrefixes) - 2]; | ||
$blockSuffix = preg_replace('#^_([a-z0-9]{14})_(.++)$#', '$2', end($blockPrefixes)); | ||
|
||
$blockPrefixes[] = sprintf('%s_%s', $baseName, $baseType); | ||
$blockPrefixes[] = sprintf('%s_%s_%s', $baseName, $sonataAdmin['name'], $baseType); | ||
$blockPrefixes[] = sprintf('%s_%s_%s_%s', $baseName, $sonataAdmin['name'], $baseType, $blockSuffix); | ||
|
||
if (isset($sonataAdmin['block_name']) && false !== $sonataAdmin['block_name']) { | ||
$blockPrefixes[] = $sonataAdmin['block_name']; | ||
} | ||
|
||
$view->vars['block_prefixes'] = array_unique($blockPrefixes); | ||
$view->vars['sonata_admin_enabled'] = true; | ||
$view->vars['sonata_admin'] = $sonataAdmin; | ||
$view->vars['sonata_admin_code'] = $sonataAdmin['admin']->getCode(); | ||
|
||
$attr = $view->vars['attr']; | ||
|
||
if (!isset($attr['class']) && isset($sonataAdmin['class'])) { | ||
$attr['class'] = $sonataAdmin['class']; | ||
} | ||
|
||
$view->vars['attr'] = $attr; | ||
} else { | ||
$view->vars['sonata_admin_enabled'] = false; | ||
} | ||
|
||
// NEXT_MAJOR: Remove this line | ||
$view->vars['sonata_help'] = $sonataAdminHelp; | ||
$view->vars['sonata_admin'] = $sonataAdmin; | ||
} | ||
|
||
public function getExtendedType() | ||
{ | ||
return FormType::class; | ||
} | ||
|
||
public function configureOptions(OptionsResolver $resolver) | ||
{ | ||
$resolver | ||
->setDefaults([ | ||
'sonata_admin' => null, | ||
'sonata_field_description' => null, | ||
|
||
// be compatible with mopa if not installed, avoid generating an exception for invalid option | ||
'label_render' => true, | ||
// NEXT_MAJOR: Remove this property and the deprecation message | ||
'sonata_help' => null, | ||
]) | ||
->setDeprecated( | ||
'sonata_help', | ||
'The "sonata_help" option is deprecated since sonata-project/admin-bundle 3.60, to be removed in 4.0. Use "help" instead.' | ||
); | ||
} | ||
|
||
/** | ||
* return the value related to FieldDescription, if the associated object does no | ||
* exists => a temporary one is created. | ||
* | ||
* @param object|null $object | ||
* | ||
* @return mixed | ||
*/ | ||
public function getValueFromFieldDescription($object, FieldDescriptionInterface $fieldDescription) | ||
{ | ||
$value = null; | ||
|
||
if (!$object) { | ||
return null; | ||
} | ||
|
||
try { | ||
$value = $fieldDescription->getValue($object); | ||
} catch (NoValueException $e) { | ||
if ($fieldDescription->hasAssociationAdmin()) { | ||
$value = $fieldDescription->getAssociationAdmin()->getNewInstance(); | ||
} | ||
} | ||
|
||
return $value; | ||
} | ||
|
||
/** | ||
* @return string | ||
*/ | ||
protected function getClass(FormBuilderInterface $formBuilder) | ||
{ | ||
foreach ($this->getTypes($formBuilder) as $type) { | ||
$name = \get_class($type); | ||
|
||
if (isset($this->defaultClasses[$name])) { | ||
return $this->defaultClasses[$name]; | ||
} | ||
} | ||
|
||
return ''; | ||
} | ||
|
||
/** | ||
* @return array | ||
*/ | ||
protected function getTypes(FormBuilderInterface $formBuilder) | ||
{ | ||
$types = []; | ||
|
||
for ($type = $formBuilder->getType(); null !== $type; $type = $type->getParent()) { | ||
array_unshift($types, $type->getInnerType()); | ||
} | ||
|
||
return $types; | ||
} | ||
} |
Oops, something went wrong.