Issue #2399219 by amateescu: Allow entity form handlers to determine the entity object they need to work with
parent
28748628b4
commit
eb25fabd8f
|
@ -10,6 +10,7 @@ namespace Drupal\Core\Controller;
|
|||
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
|
||||
use Drupal\Core\Form\FormBuilderInterface;
|
||||
use Drupal\Core\Form\FormState;
|
||||
use Drupal\Core\Routing\RouteMatchInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
|
@ -52,13 +53,15 @@ abstract class FormController {
|
|||
*
|
||||
* @param \Symfony\Component\HttpFoundation\Request $request
|
||||
* The request object.
|
||||
* @param \Drupal\Core\Routing\RouteMatchInterface $route_match
|
||||
* The route match.
|
||||
*
|
||||
* @return array
|
||||
* The render array that results from invoking the controller.
|
||||
*/
|
||||
public function getContentResult(Request $request) {
|
||||
$form_arg = $this->getFormArgument($request);
|
||||
$form_object = $this->getFormObject($request, $form_arg);
|
||||
public function getContentResult(Request $request, RouteMatchInterface $route_match) {
|
||||
$form_arg = $this->getFormArgument($route_match);
|
||||
$form_object = $this->getFormObject($route_match, $form_arg);
|
||||
|
||||
// Add the form and form_state to trick the getArguments method of the
|
||||
// controller resolver.
|
||||
|
@ -88,25 +91,25 @@ abstract class FormController {
|
|||
* _form: Drupal\example\Form\ExampleForm
|
||||
* @endcode
|
||||
*
|
||||
* @param \Symfony\Component\HttpFoundation\Request $request
|
||||
* The request object from which to extract a form definition string.
|
||||
* @param \Drupal\Core\Routing\RouteMatchInterface $route_match
|
||||
* The route match object from which to extract a form definition string.
|
||||
*
|
||||
* @return string
|
||||
* The form definition string.
|
||||
*/
|
||||
abstract protected function getFormArgument(Request $request);
|
||||
abstract protected function getFormArgument(RouteMatchInterface $route_match);
|
||||
|
||||
/**
|
||||
* Returns the object used to build the form.
|
||||
*
|
||||
* @param \Symfony\Component\HttpFoundation\Request $request
|
||||
* The request using this form.
|
||||
* @param \Drupal\Core\Routing\RouteMatchInterface $route_match
|
||||
* The route match.
|
||||
* @param string $form_arg
|
||||
* Either a class name or a service ID.
|
||||
*
|
||||
* @return \Drupal\Core\Form\FormInterface
|
||||
* The form object to use.
|
||||
*/
|
||||
abstract protected function getFormObject(Request $request, $form_arg);
|
||||
abstract protected function getFormObject(RouteMatchInterface $route_match, $form_arg);
|
||||
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
namespace Drupal\Core\Controller;
|
||||
|
||||
use Drupal\Core\Form\FormBuilderInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Drupal\Core\Routing\RouteMatchInterface;
|
||||
use Drupal\Core\DependencyInjection\ClassResolverInterface;
|
||||
|
||||
/**
|
||||
|
@ -39,24 +39,16 @@ class HtmlFormController extends FormController {
|
|||
}
|
||||
|
||||
/**
|
||||
* @{inheritDoc}
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getFormArgument(Request $request) {
|
||||
return $request->attributes->get('_form');
|
||||
protected function getFormArgument(RouteMatchInterface $route_match) {
|
||||
return $route_match->getRouteObject()->getDefault('_form');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the object used to build the form.
|
||||
*
|
||||
* @param \Symfony\Component\HttpFoundation\Request $request
|
||||
* The request using this form.
|
||||
* @param string $form_arg
|
||||
* Either a class name or a service ID.
|
||||
*
|
||||
* @return \Drupal\Core\Form\FormInterface
|
||||
* The form object to use.
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getFormObject(Request $request, $form_arg) {
|
||||
protected function getFormObject(RouteMatchInterface $route_match, $form_arg) {
|
||||
return $this->classResolver->getInstanceFromDefinition($form_arg);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ use Drupal\Core\Form\FormBase;
|
|||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Render\Element;
|
||||
use Drupal\Core\Routing\RouteMatchInterface;
|
||||
|
||||
/**
|
||||
* Base class for entity forms.
|
||||
|
@ -36,6 +37,13 @@ class EntityForm extends FormBase implements EntityFormInterface {
|
|||
*/
|
||||
protected $moduleHandler;
|
||||
|
||||
/**
|
||||
* The entity manager.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityManagerInterface
|
||||
*/
|
||||
protected $entityManager;
|
||||
|
||||
/**
|
||||
* The entity being used by this form.
|
||||
*
|
||||
|
@ -321,6 +329,20 @@ class EntityForm extends FormBase implements EntityFormInterface {
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getEntityFromRouteMatch(RouteMatchInterface $route_match, $entity_type_id) {
|
||||
if ($route_match->getRawParameter($entity_type_id) !== NULL) {
|
||||
$entity = $route_match->getParameter($entity_type_id);
|
||||
}
|
||||
else {
|
||||
$entity = $this->entityManager->getStorage($entity_type_id)->create([]);
|
||||
}
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the entity object before the form is built first.
|
||||
*/
|
||||
|
@ -362,4 +384,12 @@ class EntityForm extends FormBase implements EntityFormInterface {
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setEntityManager(EntityManagerInterface $entity_manager) {
|
||||
$this->entityManager = $entity_manager;
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace Drupal\Core\Entity;
|
|||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\Form\BaseFormIdInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Routing\RouteMatchInterface;
|
||||
use Drupal\Core\StringTranslation\TranslationInterface;
|
||||
|
||||
/**
|
||||
|
@ -40,9 +41,6 @@ interface EntityFormInterface extends BaseFormIdInterface {
|
|||
*
|
||||
* The form entity which has been used for populating form element defaults.
|
||||
*
|
||||
* @param \Drupal\Core\Form\FormStateInterface $form_state
|
||||
* The current state of the form.
|
||||
*
|
||||
* @return \Drupal\Core\Entity\EntityInterface
|
||||
* The current form entity.
|
||||
*/
|
||||
|
@ -64,6 +62,19 @@ interface EntityFormInterface extends BaseFormIdInterface {
|
|||
*/
|
||||
public function setEntity(EntityInterface $entity);
|
||||
|
||||
/**
|
||||
* Determines which entity will be used by this form from a RouteMatch object.
|
||||
*
|
||||
* @param \Drupal\Core\Routing\RouteMatchInterface $route_match
|
||||
* The route match.
|
||||
* @param string $entity_type_id
|
||||
* The entity type identifier.
|
||||
*
|
||||
* @return \Drupal\Core\Entity\EntityInterface
|
||||
* The entity object as determined from the passed-in route match.
|
||||
*/
|
||||
public function getEntityFromRouteMatch(RouteMatchInterface $route_match, $entity_type_id);
|
||||
|
||||
/**
|
||||
* Builds an updated entity object based upon the submitted form values.
|
||||
*
|
||||
|
@ -129,4 +140,14 @@ interface EntityFormInterface extends BaseFormIdInterface {
|
|||
*/
|
||||
public function setModuleHandler(ModuleHandlerInterface $module_handler);
|
||||
|
||||
/**
|
||||
* Sets the entity manager for this form.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setEntityManager(EntityManagerInterface $entity_manager);
|
||||
|
||||
}
|
||||
|
|
|
@ -294,6 +294,7 @@ class EntityManager extends DefaultPluginManager implements EntityManagerInterfa
|
|||
$form_object
|
||||
->setStringTranslation($this->translationManager)
|
||||
->setModuleHandler($this->moduleHandler)
|
||||
->setEntityManager($this)
|
||||
->setOperation($operation);
|
||||
$this->handlers['form'][$operation][$entity_type] = $form_object;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace Drupal\Core\Entity;
|
|||
use Drupal\Core\Controller\ControllerResolverInterface;
|
||||
use Drupal\Core\Controller\FormController;
|
||||
use Drupal\Core\Form\FormBuilderInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Drupal\Core\Routing\RouteMatchInterface;
|
||||
|
||||
/**
|
||||
* Wrapping controller for entity forms that serve as the main page body.
|
||||
|
@ -22,7 +22,7 @@ class HtmlEntityFormController extends FormController {
|
|||
*
|
||||
* @var \Drupal\Core\Entity\EntityManagerInterface
|
||||
*/
|
||||
protected $manager;
|
||||
protected $entityManager;
|
||||
|
||||
/**
|
||||
* Constructs a new \Drupal\Core\Routing\Enhancer\FormEnhancer object.
|
||||
|
@ -36,14 +36,14 @@ class HtmlEntityFormController extends FormController {
|
|||
*/
|
||||
public function __construct(ControllerResolverInterface $resolver, FormBuilderInterface $form_builder, EntityManagerInterface $manager) {
|
||||
parent::__construct($resolver, $form_builder);
|
||||
$this->manager = $manager;
|
||||
$this->entityManager = $manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @{inheritDoc}
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getFormArgument(Request $request) {
|
||||
return $request->attributes->get('_entity_form');
|
||||
protected function getFormArgument(RouteMatchInterface $route_match) {
|
||||
return $route_match->getRouteObject()->getDefault('_entity_form');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -66,19 +66,19 @@ class HtmlEntityFormController extends FormController {
|
|||
* _entity_form: 'node'
|
||||
* @endcode
|
||||
*/
|
||||
protected function getFormObject(Request $request, $form_arg) {
|
||||
protected function getFormObject(RouteMatchInterface $route_match, $form_arg) {
|
||||
// If no operation is provided, use 'default'.
|
||||
$form_arg .= '.default';
|
||||
list ($entity_type, $operation) = explode('.', $form_arg);
|
||||
list ($entity_type_id, $operation) = explode('.', $form_arg);
|
||||
|
||||
if ($request->attributes->has($entity_type)) {
|
||||
$entity = $request->attributes->get($entity_type);
|
||||
}
|
||||
else {
|
||||
$entity = $this->manager->getStorage($entity_type)->create([]);
|
||||
}
|
||||
$form_object = $this->entityManager->getFormObject($entity_type_id, $operation);
|
||||
|
||||
return $this->manager->getFormObject($entity_type, $operation)->setEntity($entity);
|
||||
// Allow the entity form to determine the entity object from a given route
|
||||
// match.
|
||||
$entity = $form_object->getEntityFromRouteMatch($route_match, $entity_type_id);
|
||||
$form_object->setEntity($entity);
|
||||
|
||||
return $form_object;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,14 +10,13 @@ namespace Drupal\Tests\Core\Entity {
|
|||
use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
|
||||
use Drupal\Component\Plugin\Exception\PluginNotFoundException;
|
||||
use Drupal\Core\Config\Entity\ConfigEntityStorage;
|
||||
use Drupal\Core\DependencyInjection\ContainerBuilder;
|
||||
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
|
||||
use Drupal\Core\Entity\ContentEntityBase;
|
||||
use Drupal\Core\Entity\ContentEntityInterface;
|
||||
use Drupal\Core\Entity\EntityHandlerBase;
|
||||
use Drupal\Core\Entity\EntityHandlerInterface;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Entity\EntityManager;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Language\Language;
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
|
@ -1503,6 +1502,13 @@ class TestEntityHandlerInjected implements EntityHandlerInterface {
|
|||
*/
|
||||
class TestEntityForm extends EntityHandlerBase {
|
||||
|
||||
/**
|
||||
* The entity manager.
|
||||
*
|
||||
* @var \Drupal\Tests\Core\Entity\TestEntityManager
|
||||
*/
|
||||
protected $entityManager;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -1531,6 +1537,14 @@ class TestEntityForm extends EntityHandlerBase {
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setEntityManager(EntityManagerInterface $entity_manager) {
|
||||
$this->entityManager = $entity_manager;
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue