ConfigEntityRevisionsConverterBase.php in Config Entity Revisions 8.2
Same filename and directory in other branches
Namespace
Drupal\config_entity_revisionsFile
src/ConfigEntityRevisionsConverterBase.phpView source
<?php
namespace Drupal\config_entity_revisions;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\ParamConverter\AdminPathConfigEntityConverter;
use Drupal\Core\ParamConverter\ParamNotConvertedException;
use Drupal\Core\Routing\AdminContext;
use Drupal\Core\TempStore\SharedTempStoreFactory;
/**
* Parameter converter for upcasting entity IDs to full objects.
*
* This is useful in cases where the dynamic elements of the path can't be
* auto-determined; for example, if your path refers to multiple of the same
* type of entity ("example/{node1}/foo/{node2}") or if the path can act on any
* entity type ("example/{entity_type}/{entity}/foo").
*
* In order to use it you should specify some additional options in your route:
*
* @code
* example.route:
* path: foo/{example}
* options:
* parameters:
* example:
* type: entity:node
* @endcode
*
* If you want to have the entity type itself dynamic in the url you can
* specify it like the following:
* @code
* example.route:
* path: foo/{entity_type}/{example}
* options:
* parameters:
* example:
* type: entity:{entity_type}
* @endcode
*
* If your route needs to support pending revisions, you can specify the
* "load_latest_revision" parameter. This will ensure that the latest revision
* is returned, even if it is not the default one:
* @code
* example.route:
* path: foo/{example}
* options:
* parameters:
* example:
* type: entity:node
* load_latest_revision: TRUE
* @endcode
*
* When dealing with translatable entities, the "load_latest_revision" flag will
* make this converter load the latest revision affecting the translation
* matching the content language for the current request. If none can be found
* it will fall back to the latest revision. For instance, if an entity has an
* English default revision (revision 1) and an Italian pending revision
* (revision 2), "/foo/1" will return the former, while "/it/foo/1" will return
* the latter.
*
* @see entities_revisions_translations
*/
abstract class ConfigEntityRevisionsConverterBase extends AdminPathConfigEntityConverter implements ConfigEntityRevisionsConverterBaseInterface {
/**
* Stores the tempstore factory.
*
* @var \Drupal\Core\TempStore\SharedTempStoreFactory
*/
protected $tempStoreFactory;
/**
* A prefix for tempstore keys - empty if tempstore is not used.
*/
protected function tempstorePrefix() {
return '';
}
/**
* Default implementation of containerFor - the container is the object.
*/
protected function containerFor($config_entity) {
return $config_entity;
}
/**
* Constructs a new converter.
*
* @param \Drupal\Core\Entity\EntityManagerInterface $entityManager
* The entity manager.
* @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
* The config factory.
* @param \Drupal\Core\TempStore\SharedTempStoreFactory $tempStoreFactory
* The factory for the temp store object.
* @param \Drupal\Core\Routing\AdminContext $adminContext
* The admin context.
*/
public function __construct(EntityManagerInterface $entityManager, ConfigFactoryInterface $configFactory, SharedTempStoreFactory $tempStoreFactory = NULL, AdminContext $adminContext = NULL) {
// The config factory and admin context are new arguments due to changing
// the parent. Avoid an error on updated sites by falling back to getting
// them from the container.
// @todo Remove in 8.2.x in https://www.drupal.org/node/2674328.
if (!$configFactory) {
$configFactory = \Drupal::configFactory();
}
if (!$adminContext) {
$adminContext = \Drupal::service('router.admin_context');
}
parent::__construct($entityManager, $configFactory, $adminContext);
$this->tempStoreFactory = $tempStoreFactory;
}
/**
* {@inheritdoc}
*/
public function convert($value, $definition, $name, array $defaults) {
/* @var $config_entity \Drupal\config_entity_revisions\ConfigEntityRevisionsConfigEntityInterface */
if (!($config_entity = parent::convert($value, $definition, $name, $defaults))) {
return;
}
// Get the temp store for this variable if it needs one. Attempt to load the
// view from the temp store, synchronize its status with the existing view,
// and store the lock metadata.
$tempstorePrefix = $this
->tempstorePrefix();
$temp_store = $tempstorePrefix ? $this->tempStoreFactory
->get($tempstorePrefix) : NULL;
if (!$config_entity) {
return NULL;
}
/* @var $revisionEntity ConfigEntityRevisionsConfigEntityInterface */
$revisionEntity = NULL;
// Get the config_entity_revisions entity, if one exists.
$revisionsID = $config_entity
->getContentEntityId();
/* @var $content_entity_storage ConfigEntityRevisionsRevisionStorageHandlerInterface */
$content_entity_storage = $this->entityManager
->getStorage('config_entity_revisions');
if (!$revisionsID) {
$revisionsID = $content_entity_storage
->createInitialRevision($config_entity);
}
$content_entity_storage
->setConfigEntity($config_entity);
// If a specific revision is provided or implied by a submission ID, use
// it.
$specific_revision = FALSE;
if (!empty($defaults['revision_id']) && $defaults['revision_id'] != 'default') {
$specific_revision = $defaults['revision_id'];
}
elseif ($config_entity
->hasOwnContent() && !empty($defaults[$config_entity
->revisionsEntityName()])) {
// Load the content entity and get the config entity revision from it
// (if any).
$content_storage = $this->entityManager
->getStorage($config_entity
->revisionsEntityName());
$content = $content_storage
->load($defaults[$config_entity
->contentParameterName()]);
if ($content->{$config_entity
->contentParentReferenceField()}) {
$specific_revision = $content->{$config_entity
->contentParentReferenceField()}->target_id;
}
}
// If no specific revision has been given, check to see whether we should
// use the latest revision or the latest published revision.
if ($specific_revision) {
$revisionEntity = $content_entity_storage
->loadRevision($specific_revision);
}
elseif (array_key_exists('load_latest_revision', $definition)) {
$revisionEntity = $content_entity_storage
->getLatestRevision();
}
else {
$revisionEntity = $content_entity_storage
->getLatestPublishedRevision();
// If there's no latest published revision and the user has admin
// permissions, get the latest revision instead.
if (!$revisionEntity && \Drupal::currentUser()
->hasPermission($config_entity
->adminPermission()) && is_null($revisionEntity)) {
$revisionEntity = $content_entity_storage
->getLatestRevision();
}
}
if (is_null($revisionEntity)) {
return NULL;
}
// Now that we know the revision ID to use, we can check whether we were
// already editing it.
$temp_store_key = $value . '-' . $revisionEntity
->getRevisionId();
if ($temp_store && ($container = $temp_store
->get($temp_store_key))) {
if ($config_entity
->status()) {
$container
->enable();
}
else {
$container
->disable();
}
$container->lock = $temp_store
->getMetadata($temp_store_key);
}
else {
if ($revisionEntity) {
// Otherwise, decorate the existing view for use in the UI.
$config_entity = $content_entity_storage
->getConfigEntity($revisionEntity);
}
$container = $this
->containerFor($config_entity);
}
return $container;
}
/**
* Determines the entity type ID given a route definition and route defaults.
*
* @param mixed $definition
* The parameter definition provided in the route options.
* @param string $name
* The name of the parameter.
* @param array $defaults
* The route defaults array.
*
* @return string
* The entity type ID.
*
* @throws ParamNotConvertedException
* Thrown when the dynamic entity type is not found in the route defaults.
*/
public function getEntityTypeFromDefaults($definition, $name, array $defaults) {
$entity_type_id = substr($definition['type'], strlen('entity:'));
// If the entity type is dynamic, it will be pulled from the route defaults.
if (strpos($entity_type_id, '{') === 0) {
$entity_type_slug = substr($entity_type_id, 1, -1);
if (!isset($defaults[$entity_type_slug])) {
throw new ParamNotConvertedException(sprintf('The "%s" parameter was not converted because the "%s" parameter is missing', $name, $entity_type_slug));
}
$entity_type_id = $defaults[$entity_type_slug];
}
return $entity_type_id;
}
}
Classes
Name![]() |
Description |
---|---|
ConfigEntityRevisionsConverterBase | Parameter converter for upcasting entity IDs to full objects. |