updated contrib modules : pathauto, token, entity_api, search_api, redirect, features
This commit is contained in:
@@ -5,8 +5,8 @@ type: module
|
||||
dependencies:
|
||||
- drupal:system (>=8.5.0)
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-03-12
|
||||
version: '8.x-1.0-beta2'
|
||||
# Information added by Drupal.org packaging script on 2018-06-08
|
||||
version: '8.x-1.0-beta4'
|
||||
core: '8.x'
|
||||
project: 'entity'
|
||||
datestamp: 1520873296
|
||||
datestamp: 1528452194
|
||||
|
||||
+14
-1
@@ -69,6 +69,20 @@ class EntityRevisionRouteAccessChecker implements AccessInterface {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs access checks.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\ContentEntityInterface $entity
|
||||
* The entity for which to check access.
|
||||
* @param \Drupal\Core\Session\AccountInterface $account
|
||||
* The user for which to check access.
|
||||
* @param string $operation
|
||||
* The entity operation. Usually one of 'view', 'view label', 'update' or
|
||||
* 'delete'.
|
||||
*
|
||||
* @return bool
|
||||
* The access result.
|
||||
*/
|
||||
protected function checkAccess(ContentEntityInterface $entity, AccountInterface $account, $operation = 'view') {
|
||||
$entity_type = $entity->getEntityType();
|
||||
$entity_type_id = $entity->getEntityTypeId();
|
||||
@@ -126,7 +140,6 @@ class EntityRevisionRouteAccessChecker implements AccessInterface {
|
||||
return $this->accessCache[$cid];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Counts the number of revisions in the default language.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\entity;
|
||||
|
||||
use Drupal\Core\Access\AccessResult;
|
||||
use Drupal\Core\Entity\EntityAccessControlHandler as CoreEntityAccessControlHandler;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
|
||||
/**
|
||||
* Controls access to bundle entities.
|
||||
*
|
||||
* Allows the bundle entity label to be viewed if the account has
|
||||
* access to view entities of that bundle.
|
||||
*/
|
||||
class BundleEntityAccessControlHandler extends CoreEntityAccessControlHandler {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $viewLabelOperation = TRUE;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
|
||||
if ($operation === 'view label') {
|
||||
$bundle = $entity->id();
|
||||
$entity_type_id = $this->entityType->getBundleOf();
|
||||
$permissions = [
|
||||
"administer $entity_type_id",
|
||||
// View permissions provided by EntityPermissionProvider.
|
||||
"view $entity_type_id",
|
||||
"view $bundle $entity_type_id",
|
||||
// View permissions provided by UncacheableEntityPermissionProvider.
|
||||
"view own $entity_type_id",
|
||||
"view any $entity_type_id",
|
||||
"view own $bundle $entity_type_id",
|
||||
"view any $bundle $entity_type_id",
|
||||
];
|
||||
|
||||
return AccessResult::allowedIfHasPermissions($account, $permissions, 'OR');
|
||||
}
|
||||
else {
|
||||
return parent::checkAccess($entity, $operation, $account);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -60,7 +60,7 @@ class BundlePluginUninstallValidator implements ModuleUninstallValidatorInterfac
|
||||
});
|
||||
|
||||
$bundles_with_content = array_intersect_key($bundles_filtered_by_module, array_flip($bundle_keys_with_content));
|
||||
|
||||
|
||||
foreach ($bundles_with_content as $bundle) {
|
||||
$reasons[] = $this->t('There is data for the bundle @bundle on the entity type @entity_type. Please remove all content before uninstalling the module.', [
|
||||
'@bundle' => $bundle['label'],
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\entity\Entity;
|
||||
|
||||
use Drupal\Core\Entity\RevisionableEntityBundleInterface as CoreRevisionableEntityBundleInterface;
|
||||
|
||||
@trigger_error('\Drupal\entity\Entity\RevisionableEntityBundleInterface has been deprecated in favor of \Drupal\Core\Entity\RevisionableEntityBundleInterface. Use that instead.');
|
||||
|
||||
/**
|
||||
* @deprecated in favor of
|
||||
* \Drupal\Core\Entity\RevisionableEntityBundleInterface. Use that instead.
|
||||
*/
|
||||
interface RevisionableEntityBundleInterface extends CoreRevisionableEntityBundleInterface {
|
||||
}
|
||||
@@ -3,19 +3,17 @@
|
||||
namespace Drupal\entity;
|
||||
|
||||
use Drupal\Core\Access\AccessResult;
|
||||
use Drupal\Core\Entity\EntityAccessControlHandler as CoreEntityAccessControlHandler;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Entity\EntityPublishedInterface;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\user\EntityOwnerInterface;
|
||||
|
||||
/**
|
||||
* Controls access based on the generic entity permissions.
|
||||
*
|
||||
* @see \Drupal\entity\UncacheableEntityPermissionProvider
|
||||
*/
|
||||
class EntityAccessControlHandler extends CoreEntityAccessControlHandler {
|
||||
class EntityAccessControlHandler extends EntityAccessControlHandlerBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
@@ -24,126 +22,36 @@ class EntityAccessControlHandler extends CoreEntityAccessControlHandler {
|
||||
parent::__construct($entity_type);
|
||||
|
||||
if (!$entity_type->hasHandlerClass('permission_provider') || !is_a($entity_type->getHandlerClass('permission_provider'), EntityPermissionProvider::class, TRUE)) {
|
||||
throw new \Exception("This entity access control handler requires the entity permissions provider: {EntityPermissionProvider::class}");
|
||||
throw new \Exception('\Drupal\entity\EntityAccessControlHandler requires the \Drupal\entity\EntityPermissionProvider permission provider.');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
|
||||
$account = $this->prepareUser($account);
|
||||
/** @var \Drupal\Core\Access\AccessResult $result */
|
||||
$result = parent::checkAccess($entity, $operation, $account);
|
||||
|
||||
if ($result->isNeutral()) {
|
||||
if ($entity instanceof EntityOwnerInterface) {
|
||||
$result = $this->checkEntityOwnerPermissions($entity, $operation, $account);
|
||||
}
|
||||
else {
|
||||
$result = $this->checkEntityPermissions($entity, $operation, $account);
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that access is evaluated again when the entity changes.
|
||||
return $result->addCacheableDependency($entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the entity operation and bundle permissions.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityInterface $entity
|
||||
* The entity for which to check access.
|
||||
* @param string $operation
|
||||
* The entity operation. Usually one of 'view', 'view label', 'update' or
|
||||
* 'delete'.
|
||||
* @param \Drupal\Core\Session\AccountInterface $account
|
||||
* The user for which to check access.
|
||||
*
|
||||
* @return \Drupal\Core\Access\AccessResultInterface
|
||||
* The access result.
|
||||
*/
|
||||
protected function checkEntityPermissions(EntityInterface $entity, $operation, AccountInterface $account) {
|
||||
if ($operation === 'view') {
|
||||
$permissions = [
|
||||
"view {$entity->getEntityTypeId()}"
|
||||
];
|
||||
}
|
||||
else {
|
||||
$permissions = [
|
||||
"$operation {$entity->getEntityTypeId()}",
|
||||
"$operation {$entity->bundle()} {$entity->getEntityTypeId()}",
|
||||
];
|
||||
}
|
||||
return AccessResult::allowedIfHasPermissions($account, $permissions, 'OR');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the entity operation and bundle permissions, with owners.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityInterface $entity
|
||||
* The entity for which to check access.
|
||||
* @param string $operation
|
||||
* The entity operation. Usually one of 'view', 'view label', 'update' or
|
||||
* 'delete'.
|
||||
* @param \Drupal\Core\Session\AccountInterface $account
|
||||
* The user for which to check access.
|
||||
*
|
||||
* @return \Drupal\Core\Access\AccessResultInterface
|
||||
* The access result.
|
||||
*/
|
||||
protected function checkEntityOwnerPermissions(EntityInterface $entity, $operation, AccountInterface $account) {
|
||||
/** @var \Drupal\user\EntityOwnerInterface $entity */
|
||||
if ($operation === 'view') {
|
||||
if ($entity instanceof EntityPublishedInterface && !$entity->isPublished()) {
|
||||
if (($account->id() == $entity->getOwnerId())) {
|
||||
$permissions = [
|
||||
"view own unpublished {$entity->getEntityTypeId()}",
|
||||
];
|
||||
return AccessResult::allowedIfHasPermissions($account, $permissions)->cachePerUser();
|
||||
if ($account->id() != $entity->getOwnerId()) {
|
||||
// There's no permission for viewing other user's unpublished entity.
|
||||
return AccessResult::neutral()->cachePerUser();
|
||||
}
|
||||
return AccessResult::neutral()->cachePerUser();
|
||||
|
||||
$permissions = [
|
||||
"view own unpublished {$entity->getEntityTypeId()}",
|
||||
];
|
||||
$result = AccessResult::allowedIfHasPermissions($account, $permissions)->cachePerUser();
|
||||
}
|
||||
else {
|
||||
return AccessResult::allowedIfHasPermissions($account, [
|
||||
$result = AccessResult::allowedIfHasPermissions($account, [
|
||||
"view {$entity->getEntityTypeId()}",
|
||||
]);
|
||||
"view {$entity->bundle()} {$entity->getEntityTypeId()}",
|
||||
], 'OR');
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (($account->id() == $entity->getOwnerId())) {
|
||||
$result = AccessResult::allowedIfHasPermissions($account, [
|
||||
"$operation own {$entity->getEntityTypeId()}",
|
||||
"$operation any {$entity->getEntityTypeId()}",
|
||||
"$operation own {$entity->bundle()} {$entity->getEntityTypeId()}",
|
||||
"$operation any {$entity->bundle()} {$entity->getEntityTypeId()}",
|
||||
], 'OR');
|
||||
}
|
||||
else {
|
||||
$result = AccessResult::allowedIfHasPermissions($account, [
|
||||
"$operation any {$entity->getEntityTypeId()}",
|
||||
"$operation any {$entity->bundle()} {$entity->getEntityTypeId()}",
|
||||
], 'OR');
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
|
||||
$result = parent::checkCreateAccess($account, $context, $entity_bundle);
|
||||
if ($result->isNeutral()) {
|
||||
$permissions = [
|
||||
'administer ' . $this->entityTypeId,
|
||||
'create ' . $this->entityTypeId,
|
||||
];
|
||||
if ($entity_bundle) {
|
||||
$permissions[] = 'create ' . $entity_bundle . ' ' . $this->entityTypeId;
|
||||
}
|
||||
|
||||
$result = AccessResult::allowedIfHasPermissions($account, $permissions, 'OR');
|
||||
$result = parent::checkEntityOwnerPermissions($entity, $operation, $account);
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\entity;
|
||||
|
||||
use Drupal\Core\Access\AccessResult;
|
||||
use Drupal\Core\Entity\EntityAccessControlHandler as CoreEntityAccessControlHandler;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\user\EntityOwnerInterface;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class EntityAccessControlHandlerBase extends CoreEntityAccessControlHandler {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
|
||||
$account = $this->prepareUser($account);
|
||||
/** @var \Drupal\Core\Access\AccessResult $result */
|
||||
$result = parent::checkAccess($entity, $operation, $account);
|
||||
|
||||
if ($result->isNeutral()) {
|
||||
if ($entity instanceof EntityOwnerInterface) {
|
||||
$result = $this->checkEntityOwnerPermissions($entity, $operation, $account);
|
||||
}
|
||||
else {
|
||||
$result = $this->checkEntityPermissions($entity, $operation, $account);
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that access is evaluated again when the entity changes.
|
||||
return $result->addCacheableDependency($entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the entity operation and bundle permissions.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityInterface $entity
|
||||
* The entity for which to check access.
|
||||
* @param string $operation
|
||||
* The entity operation. Usually one of 'view', 'view label', 'update' or
|
||||
* 'delete'.
|
||||
* @param \Drupal\Core\Session\AccountInterface $account
|
||||
* The user for which to check access.
|
||||
*
|
||||
* @return \Drupal\Core\Access\AccessResultInterface
|
||||
* The access result.
|
||||
*/
|
||||
protected function checkEntityPermissions(EntityInterface $entity, $operation, AccountInterface $account) {
|
||||
$permissions = [
|
||||
"$operation {$entity->getEntityTypeId()}",
|
||||
"$operation {$entity->bundle()} {$entity->getEntityTypeId()}",
|
||||
];
|
||||
|
||||
return AccessResult::allowedIfHasPermissions($account, $permissions, 'OR');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the entity operation and bundle permissions, with owners.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityInterface $entity
|
||||
* The entity for which to check access.
|
||||
* @param string $operation
|
||||
* The entity operation. Usually one of 'view', 'view label', 'update' or
|
||||
* 'delete'.
|
||||
* @param \Drupal\Core\Session\AccountInterface $account
|
||||
* The user for which to check access.
|
||||
*
|
||||
* @return \Drupal\Core\Access\AccessResultInterface
|
||||
* The access result.
|
||||
*/
|
||||
protected function checkEntityOwnerPermissions(EntityInterface $entity, $operation, AccountInterface $account) {
|
||||
/** @var \Drupal\user\EntityOwnerInterface $entity */
|
||||
if ($account->id() == $entity->getOwnerId()) {
|
||||
$permissions = [
|
||||
"$operation own {$entity->getEntityTypeId()}",
|
||||
"$operation any {$entity->getEntityTypeId()}",
|
||||
"$operation own {$entity->bundle()} {$entity->getEntityTypeId()}",
|
||||
"$operation any {$entity->bundle()} {$entity->getEntityTypeId()}",
|
||||
];
|
||||
}
|
||||
else {
|
||||
$permissions = [
|
||||
"$operation any {$entity->getEntityTypeId()}",
|
||||
"$operation any {$entity->bundle()} {$entity->getEntityTypeId()}",
|
||||
];
|
||||
}
|
||||
$result = AccessResult::allowedIfHasPermissions($account, $permissions, 'OR')->cachePerUser();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
|
||||
$result = parent::checkCreateAccess($account, $context, $entity_bundle);
|
||||
if ($result->isNeutral()) {
|
||||
$permissions = [
|
||||
'administer ' . $this->entityTypeId,
|
||||
'create ' . $this->entityTypeId,
|
||||
];
|
||||
if ($entity_bundle) {
|
||||
$permissions[] = 'create ' . $entity_bundle . ' ' . $this->entityTypeId;
|
||||
}
|
||||
|
||||
$result = AccessResult::allowedIfHasPermissions($account, $permissions, 'OR');
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,24 +5,25 @@ namespace Drupal\entity;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
|
||||
/**
|
||||
* Provides generic entity permissions which are still cacheable.
|
||||
* Provides generic entity permissions.
|
||||
*
|
||||
* This includes:
|
||||
* Intended for content entity types, since config entity types usually rely
|
||||
* on a single "administer" permission.
|
||||
*
|
||||
* Provided permissions:
|
||||
* - administer $entity_type
|
||||
* - access $entity_type overview
|
||||
* - view $entity_type
|
||||
* - view ($bundle) $entity_type
|
||||
* - view own unpublished $entity_type
|
||||
* - update (own|any) ($bundle) $entity_type
|
||||
* - delete (own|any) ($bundle) $entity_type
|
||||
* - create $bundle $entity_type
|
||||
*
|
||||
* This class does not support "view own ($bundle) $entity_type", because this
|
||||
* results in caching per user. If you need this use case, please use
|
||||
* \Drupal\entity\UncacheableEntityPermissionProvider instead.
|
||||
* Does not provide "view own ($bundle) $entity_type" permissions, because
|
||||
* they require caching pages per user. Please use
|
||||
* \Drupal\entity\UncacheableEntityPermissionProvider if those permissions
|
||||
* are necessary.
|
||||
*
|
||||
* Intended for content entity types, since config entity types usually rely
|
||||
* on a single "administer" permission.
|
||||
* Example annotation:
|
||||
* @code
|
||||
* handlers = {
|
||||
@@ -37,23 +38,58 @@ use Drupal\Core\Entity\EntityTypeInterface;
|
||||
class EntityPermissionProvider extends EntityPermissionProviderBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* Builds permissions for the entity_type granularity.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
|
||||
* The entity type.
|
||||
*
|
||||
* @return array
|
||||
* The permissions.
|
||||
*/
|
||||
public function buildPermissions(EntityTypeInterface $entity_type) {
|
||||
protected function buildEntityTypePermissions(EntityTypeInterface $entity_type) {
|
||||
$permissions = parent::buildEntityTypePermissions($entity_type);
|
||||
$entity_type_id = $entity_type->id();
|
||||
$plural_label = $entity_type->getPluralLabel();
|
||||
|
||||
$permissions = parent::buildPermissions($entity_type);
|
||||
|
||||
// View permissions are the same for both granularities.
|
||||
$permissions["view {$entity_type_id}"] = [
|
||||
'title' => $this->t('View @type', [
|
||||
'@type' => $plural_label,
|
||||
]),
|
||||
];
|
||||
|
||||
return $this->processPermissions($permissions, $entity_type);
|
||||
return $permissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds permissions for the bundle granularity.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
|
||||
* The entity type.
|
||||
*
|
||||
* @return array
|
||||
* The permissions.
|
||||
*/
|
||||
protected function buildBundlePermissions(EntityTypeInterface $entity_type) {
|
||||
$permissions = parent::buildBundlePermissions($entity_type);
|
||||
$entity_type_id = $entity_type->id();
|
||||
$bundles = $this->entityTypeBundleInfo->getBundleInfo($entity_type_id);
|
||||
$plural_label = $entity_type->getPluralLabel();
|
||||
|
||||
$permissions["view {$entity_type_id}"] = [
|
||||
'title' => $this->t('View @type', [
|
||||
'@type' => $plural_label,
|
||||
]),
|
||||
];
|
||||
foreach ($bundles as $bundle_name => $bundle_info) {
|
||||
$permissions["view {$bundle_name} {$entity_type_id}"] = [
|
||||
'title' => $this->t('@bundle: View @type', [
|
||||
'@bundle' => $bundle_info['label'],
|
||||
'@type' => $plural_label,
|
||||
]),
|
||||
];
|
||||
}
|
||||
|
||||
return $permissions;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -56,9 +56,11 @@ class EntityPermissionProviderBase implements EntityPermissionProviderInterface,
|
||||
'title' => $this->t('Administer @type', ['@type' => $plural_label]),
|
||||
'restrict access' => TRUE,
|
||||
];
|
||||
$permissions["access {$entity_type_id} overview"] = [
|
||||
'title' => $this->t('Access the @type overview page', ['@type' => $plural_label]),
|
||||
];
|
||||
if ($entity_type->hasLinkTemplate('collection')) {
|
||||
$permissions["access {$entity_type_id} overview"] = [
|
||||
'title' => $this->t('Access the @type overview page', ['@type' => $plural_label]),
|
||||
];
|
||||
}
|
||||
if ($has_owner && $entity_type->entityClassImplements(EntityPublishedInterface::class)) {
|
||||
$permissions["view own unpublished {$entity_type_id}"] = [
|
||||
'title' => $this->t('View own unpublished @type', [
|
||||
@@ -82,7 +84,7 @@ class EntityPermissionProviderBase implements EntityPermissionProviderInterface,
|
||||
* Adds the provider and converts the titles to strings to allow sorting.
|
||||
*
|
||||
* @param array $permissions
|
||||
* The array of permissions
|
||||
* The array of permissions.
|
||||
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
|
||||
* The entity type.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\entity;
|
||||
|
||||
use Drupal\Core\Entity\EntityViewBuilder as CoreEntityViewBuilder;
|
||||
|
||||
@trigger_error('\Drupal\entity\EntityViewBuilder has been deprecated in favor of \Drupal\Core\Entity\EntityViewBuilder. Use that instead.');
|
||||
|
||||
/**
|
||||
* Provides a entity view builder with contextual links support.
|
||||
*
|
||||
* @deprecated in favor of \Drupal\Core\Entity\EntityViewBuilder. Use that
|
||||
* instead.
|
||||
*/
|
||||
class EntityViewBuilder extends CoreEntityViewBuilder {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\entity\Form;
|
||||
|
||||
use Drupal\Core\Entity\ContentEntityForm;
|
||||
use Drupal\Core\Entity\RevisionableEntityBundleInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
||||
@trigger_error('\Drupal\entity\Form\RevisionableContentEntityForm has been deprecated in favor of \Drupal\Core\Entity\ContentEntityForm. Use that instead.');
|
||||
|
||||
/**
|
||||
* Extends the base entity form with revision support in the UI.
|
||||
*
|
||||
* @deprecated in favor of \Drupal\Core\Entity\ContentEntityForm. Use that
|
||||
* instead.
|
||||
*/
|
||||
class RevisionableContentEntityForm extends ContentEntityForm {
|
||||
|
||||
/**
|
||||
* The entity being used by this form.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityInterface|\Drupal\Core\Entity\RevisionableInterface|\Drupal\entity\Revision\EntityRevisionLogInterface
|
||||
*/
|
||||
protected $entity;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function prepareEntity() {
|
||||
parent::prepareEntity();
|
||||
|
||||
$bundle_entity = $this->getBundleEntity();
|
||||
|
||||
// Set up default values, if required.
|
||||
if (!$this->entity->isNew()) {
|
||||
$this->entity->setRevisionLogMessage(NULL);
|
||||
}
|
||||
|
||||
if ($bundle_entity instanceof RevisionableEntityBundleInterface) {
|
||||
// Always use the default revision setting.
|
||||
$this->entity->setNewRevision($bundle_entity && $bundle_entity->shouldCreateNewRevision());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bundle entity of the current entity.
|
||||
*
|
||||
* @return \Drupal\Core\Entity\EntityInterface|null
|
||||
* The bundle entity, or NULL if there is none.
|
||||
*/
|
||||
protected function getBundleEntity() {
|
||||
if ($bundle_key = $this->entity->getEntityType()->getKey('bundle')) {
|
||||
return $this->entity->{$bundle_key}->referencedEntities()[0];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function form(array $form, FormStateInterface $form_state) {
|
||||
$entity_type = $this->entity->getEntityType();
|
||||
$bundle_entity = $this->getBundleEntity();
|
||||
$account = $this->currentUser();
|
||||
|
||||
if ($this->operation == 'edit') {
|
||||
$form['#title'] = $this->t('Edit %bundle_label @label', [
|
||||
'%bundle_label' => $bundle_entity ? $bundle_entity->label() : '',
|
||||
'@label' => $this->entity->label(),
|
||||
]);
|
||||
}
|
||||
|
||||
$form['advanced'] = [
|
||||
'#type' => 'vertical_tabs',
|
||||
'#weight' => 99,
|
||||
];
|
||||
|
||||
// Add a log field if the "Create new revision" option is checked, or if the
|
||||
// current user has the ability to check that option.
|
||||
// @todo Could we autogenerate this form by using some widget on the
|
||||
// revision info field.
|
||||
$form['revision_information'] = [
|
||||
'#type' => 'details',
|
||||
'#title' => $this->t('Revision information'),
|
||||
// Open by default when "Create new revision" is checked.
|
||||
'#open' => $this->entity->isNewRevision(),
|
||||
'#group' => 'advanced',
|
||||
'#weight' => 20,
|
||||
'#access' => $this->entity->isNewRevision() || $account->hasPermission($entity_type->get('admin_permission')),
|
||||
];
|
||||
|
||||
$form['revision_information']['revision'] = [
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $this->t('Create new revision'),
|
||||
'#default_value' => $this->entity->isNewRevision(),
|
||||
'#access' => $account->hasPermission($entity_type->get('admin_permission')),
|
||||
];
|
||||
|
||||
// Check the revision log checkbox when the log textarea is filled in.
|
||||
// This must not happen if "Create new revision" is enabled by default,
|
||||
// since the state would auto-disable the checkbox otherwise.
|
||||
if (!$this->entity->isNewRevision()) {
|
||||
$form['revision_information']['revision']['#states'] = [
|
||||
'checked' => [
|
||||
'textarea[name="revision_log"]' => ['empty' => FALSE],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
$form['revision_information']['revision_log'] = [
|
||||
'#type' => 'textarea',
|
||||
'#title' => $this->t('Revision log message'),
|
||||
'#rows' => 4,
|
||||
'#default_value' => $this->entity->getRevisionLogMessage(),
|
||||
'#description' => $this->t('Briefly describe the changes you have made.'),
|
||||
];
|
||||
|
||||
return parent::form($form, $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function save(array $form, FormStateInterface $form_state) {
|
||||
// Save as a new revision if requested to do so.
|
||||
if (!$form_state->isValueEmpty('revision')) {
|
||||
$this->entity->setNewRevision();
|
||||
}
|
||||
|
||||
$insert = $this->entity->isNew();
|
||||
$this->entity->save();
|
||||
$context = ['@type' => $this->entity->bundle(), '%info' => $this->entity->label()];
|
||||
$logger = $this->logger('content');
|
||||
$bundle_entity = $this->getBundleEntity();
|
||||
$t_args = ['@type' => $bundle_entity ? $bundle_entity->label() : 'None', '%info' => $this->entity->label()];
|
||||
|
||||
if ($insert) {
|
||||
$logger->notice('@type: added %info.', $context);
|
||||
drupal_set_message($this->t('@type %info has been created.', $t_args));
|
||||
}
|
||||
else {
|
||||
$logger->notice('@type: updated %info.', $context);
|
||||
drupal_set_message($this->t('@type %info has been updated.', $t_args));
|
||||
}
|
||||
|
||||
if ($this->entity->id()) {
|
||||
$form_state->setValue('id', $this->entity->id());
|
||||
$form_state->set('id', $this->entity->id());
|
||||
|
||||
if ($this->entity->getEntityType()->hasLinkTemplate('collection')) {
|
||||
$form_state->setRedirectUrl($this->entity->toUrl('collection'));
|
||||
}
|
||||
else {
|
||||
$form_state->setRedirectUrl($this->entity->toUrl('canonical'));
|
||||
}
|
||||
}
|
||||
else {
|
||||
// In the unlikely case something went wrong on save, the entity will be
|
||||
// rebuilt and entity form redisplayed.
|
||||
drupal_set_message($this->t('The entity could not be saved.'), 'error');
|
||||
$form_state->setRebuild();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -44,7 +44,7 @@ class DeleteAction extends ActionBase implements ContainerFactoryPluginInterface
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\Core\TempStore\PrivateTempStoreFactory $temp_store_factory
|
||||
* The tempstore factory.
|
||||
* @param AccountInterface $current_user
|
||||
* @param \Drupal\Core\Session\AccountInterface $current_user
|
||||
* Current user.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, PrivateTempStoreFactory $temp_store_factory, AccountInterface $current_user) {
|
||||
|
||||
+13
-97
@@ -3,12 +3,10 @@
|
||||
namespace Drupal\entity;
|
||||
|
||||
use Drupal\Core\Access\AccessResult;
|
||||
use Drupal\Core\Entity\EntityAccessControlHandler as CoreEntityAccessControlHandler;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Entity\EntityPublishedInterface;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\user\EntityOwnerInterface;
|
||||
|
||||
/**
|
||||
* Controls access based on the uncacheable entity permissions.
|
||||
@@ -17,7 +15,7 @@ use Drupal\user\EntityOwnerInterface;
|
||||
*
|
||||
* Note: this access control handler will cause pages to be cached per user.
|
||||
*/
|
||||
class UncacheableEntityAccessControlHandler extends CoreEntityAccessControlHandler {
|
||||
class UncacheableEntityAccessControlHandler extends EntityAccessControlHandlerBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
@@ -26,110 +24,28 @@ class UncacheableEntityAccessControlHandler extends CoreEntityAccessControlHandl
|
||||
parent::__construct($entity_type);
|
||||
|
||||
if (!$entity_type->hasHandlerClass('permission_provider') || !is_a($entity_type->getHandlerClass('permission_provider'), UncacheableEntityPermissionProvider::class, TRUE)) {
|
||||
throw new \Exception("This entity access control handler requires the entity permissions provider: {EntityPermissionProvider::class}");
|
||||
throw new \Exception('\Drupal\entity\UncacheableEntityAccessControlHandler requires the \Drupal\entity\UncacheableEntityPermissionProvider permission provider.');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
|
||||
$account = $this->prepareUser($account);
|
||||
/** @var \Drupal\Core\Access\AccessResult $result */
|
||||
$result = parent::checkAccess($entity, $operation, $account);
|
||||
|
||||
if ($result->isNeutral()) {
|
||||
if ($entity instanceof EntityOwnerInterface) {
|
||||
$result = $this->checkEntityOwnerPermissions($entity, $operation, $account);
|
||||
}
|
||||
else {
|
||||
$result = $this->checkEntityPermissions($entity, $operation, $account);
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that access is evaluated again when the entity changes.
|
||||
return $result->addCacheableDependency($entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the entity operation and bundle permissions.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityInterface $entity
|
||||
* The entity for which to check access.
|
||||
* @param string $operation
|
||||
* The entity operation. Usually one of 'view', 'view label', 'update' or
|
||||
* 'delete'.
|
||||
* @param \Drupal\Core\Session\AccountInterface $account
|
||||
* The user for which to check access.
|
||||
*
|
||||
* @return \Drupal\Core\Access\AccessResultInterface
|
||||
* The access result.
|
||||
*/
|
||||
protected function checkEntityPermissions(EntityInterface $entity, $operation, AccountInterface $account) {
|
||||
return AccessResult::allowedIfHasPermissions($account, [
|
||||
"$operation {$entity->getEntityTypeId()}",
|
||||
"$operation {$entity->bundle()} {$entity->getEntityTypeId()}",
|
||||
], 'OR');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the entity operation and bundle permissions, with owners.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityInterface $entity
|
||||
* The entity for which to check access.
|
||||
* @param string $operation
|
||||
* The entity operation. Usually one of 'view', 'view label', 'update' or
|
||||
* 'delete'.
|
||||
* @param \Drupal\Core\Session\AccountInterface $account
|
||||
* The user for which to check access.
|
||||
*
|
||||
* @return \Drupal\Core\Access\AccessResultInterface
|
||||
* The access result.
|
||||
*/
|
||||
protected function checkEntityOwnerPermissions(EntityInterface $entity, $operation, AccountInterface $account) {
|
||||
/** @var \Drupal\Core\Entity\EntityInterface|\Drupal\user\EntityOwnerInterface $entity */
|
||||
if (($account->id() == $entity->getOwnerId())) {
|
||||
if ($operation === 'view' && $entity instanceof EntityPublishedInterface && !$entity->isPublished()) {
|
||||
$permissions = [
|
||||
"view own unpublished {$entity->getEntityTypeId()}",
|
||||
];
|
||||
/** @var \Drupal\user\EntityOwnerInterface $entity */
|
||||
if ($operation === 'view' && $entity instanceof EntityPublishedInterface && !$entity->isPublished()) {
|
||||
if ($account->id() != $entity->getOwnerId()) {
|
||||
// There's no permission for viewing other user's unpublished entity.
|
||||
return AccessResult::neutral()->cachePerUser();
|
||||
}
|
||||
else {
|
||||
$permissions = [
|
||||
"$operation own {$entity->getEntityTypeId()}",
|
||||
"$operation any {$entity->getEntityTypeId()}",
|
||||
"$operation own {$entity->bundle()} {$entity->getEntityTypeId()}",
|
||||
"$operation any {$entity->bundle()} {$entity->getEntityTypeId()}",
|
||||
];
|
||||
}
|
||||
$result = AccessResult::allowedIfHasPermissions($account, $permissions, 'OR');
|
||||
|
||||
$permissions = [
|
||||
"view own unpublished {$entity->getEntityTypeId()}",
|
||||
];
|
||||
$result = AccessResult::allowedIfHasPermissions($account, $permissions)->cachePerUser();
|
||||
}
|
||||
else {
|
||||
$result = AccessResult::allowedIfHasPermissions($account, [
|
||||
"$operation any {$entity->getEntityTypeId()}",
|
||||
"$operation any {$entity->bundle()} {$entity->getEntityTypeId()}",
|
||||
], 'OR');
|
||||
}
|
||||
|
||||
return $result->cachePerUser();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
|
||||
$result = parent::checkCreateAccess($account, $context, $entity_bundle);
|
||||
if ($result->isNeutral()) {
|
||||
$permissions = [
|
||||
'administer ' . $this->entityTypeId,
|
||||
'create ' . $this->entityTypeId,
|
||||
];
|
||||
if ($entity_bundle) {
|
||||
$permissions[] = 'create ' . $entity_bundle . ' ' . $this->entityTypeId;
|
||||
}
|
||||
|
||||
$result = AccessResult::allowedIfHasPermissions($account, $permissions, 'OR');
|
||||
$result = parent::checkEntityOwnerPermissions($entity, $operation, $account);
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
||||
@@ -8,24 +8,25 @@ use Drupal\user\EntityOwnerInterface;
|
||||
/**
|
||||
* Provides generic entity permissions which are cached per user.
|
||||
*
|
||||
* This includes:
|
||||
* Intended for content entity types, since config entity types usually rely
|
||||
* on a single "administer" permission.
|
||||
*
|
||||
* Provided permissions:
|
||||
* - administer $entity_type
|
||||
* - access $entity_type overview
|
||||
* - view an ($bundle) $entity_type
|
||||
* - view any ($bundle) $entity_type
|
||||
* - view own ($bundle) $entity_type
|
||||
* - view own unpublished $entity_type
|
||||
* - update (own|any) ($bundle) $entity_type
|
||||
* - delete (own|any) ($bundle) $entity_type
|
||||
* - create $bundle $entity_type
|
||||
*
|
||||
* As this class supports "view own ($bundle) $entity_type" it is just cacheable
|
||||
* per user, which might harm performance of sites. Given that please use
|
||||
* \Drupal\entity\EntityPermissionProvider unless you need the feature, or your
|
||||
* entity type is not really user facing (commerce orders for example).
|
||||
* Important:
|
||||
* Provides "view own ($bundle) $entity_type" permissions, which require
|
||||
* caching pages per user. This can significantly increase the size of caches,
|
||||
* impacting site performance. Use \Drupal\entity\EntityPermissionProvider
|
||||
* if those permissions are not necessary.
|
||||
*
|
||||
* Intended for content entity types, since config entity types usually rely
|
||||
* on a single "administer" permission.
|
||||
* Example annotation:
|
||||
* @code
|
||||
* handlers = {
|
||||
|
||||
+3
-3
@@ -6,8 +6,8 @@ package: Testing
|
||||
dependencies:
|
||||
- entity
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-03-12
|
||||
version: '8.x-1.0-beta2'
|
||||
# Information added by Drupal.org packaging script on 2018-06-08
|
||||
version: '8.x-1.0-beta4'
|
||||
core: '8.x'
|
||||
project: 'entity'
|
||||
datestamp: 1520873296
|
||||
datestamp: 1528452194
|
||||
|
||||
+3
-3
@@ -6,8 +6,8 @@ package: Testing
|
||||
dependencies:
|
||||
- entity
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-03-12
|
||||
version: '8.x-1.0-beta2'
|
||||
# Information added by Drupal.org packaging script on 2018-06-08
|
||||
version: '8.x-1.0-beta4'
|
||||
core: '8.x'
|
||||
project: 'entity'
|
||||
datestamp: 1520873296
|
||||
datestamp: 1528452194
|
||||
|
||||
+3
-3
@@ -3,8 +3,8 @@ type: module
|
||||
package: Testing
|
||||
# core: 8.x
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-03-12
|
||||
version: '8.x-1.0-beta2'
|
||||
# Information added by Drupal.org packaging script on 2018-06-08
|
||||
version: '8.x-1.0-beta4'
|
||||
core: '8.x'
|
||||
project: 'entity'
|
||||
datestamp: 1520873296
|
||||
datestamp: 1528452194
|
||||
|
||||
+2
-2
@@ -24,8 +24,8 @@ use Drupal\entity\Revision\RevisionableContentEntityBase;
|
||||
* "access" = "\Drupal\Core\Entity\EntityAccessControlHandler",
|
||||
* "permission_provider" = "\Drupal\entity\EntityPermissionProvider",
|
||||
* "form" = {
|
||||
* "add" = "\Drupal\Core\Entity\ContentEntityForm",
|
||||
* "edit" = "\Drupal\Core\Entity\ContentEntityForm",
|
||||
* "add" = "\Drupal\entity\Form\RevisionableContentEntityForm",
|
||||
* "edit" = "\Drupal\entity\Form\RevisionableContentEntityForm",
|
||||
* "delete" = "\Drupal\Core\Entity\EntityDeleteForm",
|
||||
* },
|
||||
* "route_provider" = {
|
||||
|
||||
+3
@@ -15,6 +15,9 @@ use Drupal\Core\Entity\RevisionableEntityBundleInterface;
|
||||
* admin_permission = "administer entity_test_enhanced",
|
||||
* config_prefix = "entity_test_enhanced_bundle",
|
||||
* bundle_of = "entity_test_enhanced",
|
||||
* handlers = {
|
||||
* "access" = "\Drupal\entity\BundleEntityAccessControlHandler",
|
||||
* },
|
||||
* entity_keys = {
|
||||
* "id" = "id",
|
||||
* "label" = "label"
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ class RevisionRouteAccessTest extends BrowserTestBase {
|
||||
/**
|
||||
* The current user.
|
||||
*
|
||||
* @var \Drupal\Core\Session\AccountInterface;
|
||||
* @var \Drupal\Core\Session\AccountInterface
|
||||
*/
|
||||
protected $account;
|
||||
|
||||
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\entity\Kernel;
|
||||
|
||||
use Drupal\entity_module_test\Entity\EnhancedEntityBundle;
|
||||
use Drupal\KernelTests\Core\Entity\EntityKernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests the bundle entity access control handler.
|
||||
*
|
||||
* @group entity
|
||||
*/
|
||||
class BundleEntityAccessControlHandlerTest extends EntityKernelTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = [
|
||||
'entity',
|
||||
'entity_module_test',
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->installEntitySchema('entity_test_enhanced');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the "view label" access checking.
|
||||
*/
|
||||
public function testAccess() {
|
||||
$bundle = EnhancedEntityBundle::create([
|
||||
'id' => 'default',
|
||||
'label' => 'Default',
|
||||
]);
|
||||
$bundle->save();
|
||||
|
||||
// The default user has no permissions related to entity_test_enhanced.
|
||||
$this->assertFalse($bundle->access('view label'));
|
||||
|
||||
$permissions = [
|
||||
'administer entity_test_enhanced',
|
||||
'view entity_test_enhanced',
|
||||
'view default entity_test_enhanced',
|
||||
];
|
||||
foreach ($permissions as $permission) {
|
||||
$account = $this->createUser([], [$permission]);
|
||||
$this->assertTrue($bundle->access('view label', $account));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,6 +11,7 @@ use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests the delete entity action.
|
||||
*
|
||||
* @group entity
|
||||
*/
|
||||
class DeleteActionTest extends KernelTestBase {
|
||||
@@ -25,8 +26,9 @@ class DeleteActionTest extends KernelTestBase {
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['action', 'node', 'entity_module_test', 'entity',
|
||||
'user', 'system'];
|
||||
public static $modules = [
|
||||
'action', 'node', 'entity_module_test', 'entity', 'user', 'system',
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
||||
+2
@@ -10,6 +10,8 @@ use Symfony\Component\Routing\Route;
|
||||
*
|
||||
* - Are the routes added properly.
|
||||
* - Are the local tasks added properly.
|
||||
*
|
||||
* @group entity
|
||||
*/
|
||||
class RevisionOverviewIntegrationTest extends KernelTestBase {
|
||||
|
||||
+74
-82
@@ -77,84 +77,71 @@ class EntityAccessControlHandlerTest extends UnitTestCase {
|
||||
* A list of testAccess method arguments.
|
||||
*/
|
||||
public function accessProvider() {
|
||||
$data = [];
|
||||
|
||||
$entity_type = $this->prophesize(ContentEntityTypeInterface::class);
|
||||
$entity_type->id()->willReturn('green_entity');
|
||||
$entity_type->getAdminPermission()->willReturn('administer green_entity');
|
||||
$entity_type->hasHandlerClass('permission_provider')->willReturn(TRUE);
|
||||
$entity_type->getHandlerClass('permission_provider')->willReturn(EntityPermissionProvider::class);
|
||||
|
||||
// User with the admin permission can do anything.
|
||||
$entity = $this->buildMockEntity($entity_type->reveal());
|
||||
$account = $this->prophesize(AccountInterface::class);
|
||||
$account->id()->willReturn(6);
|
||||
$account->hasPermission('administer green_entity')->willReturn(TRUE);
|
||||
$data[] = [$entity->reveal(), 'view', $account->reveal(), TRUE];
|
||||
$data[] = [$entity->reveal(), 'update', $account->reveal(), TRUE];
|
||||
$data[] = [$entity->reveal(), 'delete', $account->reveal(), TRUE];
|
||||
|
||||
// Entity with no owner.
|
||||
$entity = $this->buildMockEntity($entity_type->reveal());
|
||||
// User who has access.
|
||||
$first_account = $this->prophesize(AccountInterface::class);
|
||||
$first_account->id()->willReturn(6);
|
||||
$first_account->hasPermission('view green_entity')->willReturn(TRUE);
|
||||
$first_account->hasPermission(Argument::any())->willReturn(FALSE);
|
||||
// User who doesn't have access.
|
||||
$second_account = $this->prophesize(AccountInterface::class);
|
||||
$second_account->id()->willReturn(7);
|
||||
$second_account->hasPermission('view green_entity')->willReturn(FALSE);
|
||||
$second_account->hasPermission(Argument::any())->willReturn(FALSE);
|
||||
$data[] = [$entity->reveal(), 'view', $first_account->reveal(), TRUE];
|
||||
$data[] = [$entity->reveal(), 'view', $second_account->reveal(), FALSE];
|
||||
|
||||
// Entity with owner.
|
||||
$entity = $this->buildMockEntity($entity_type->reveal(), 6);
|
||||
// Owner.
|
||||
$first_account = $this->prophesize(AccountInterface::class);
|
||||
$first_account->id()->willReturn(6);
|
||||
$first_account->hasPermission('update own green_entity')->willReturn(TRUE);
|
||||
$first_account->hasPermission(Argument::any())->willReturn(FALSE);
|
||||
// Non-owner.
|
||||
$second_account = $this->prophesize(AccountInterface::class);
|
||||
$second_account->id()->willReturn(7);
|
||||
$second_account->hasPermission('update own green_entity')->willReturn(TRUE);
|
||||
$second_account->hasPermission(Argument::any())->willReturn(FALSE);
|
||||
// User who can update any.
|
||||
$third_account = $this->prophesize(AccountInterface::class);
|
||||
$third_account->id()->willReturn(8);
|
||||
$third_account->hasPermission('update any green_entity')->willReturn(TRUE);
|
||||
$third_account->hasPermission(Argument::any())->willReturn(FALSE);
|
||||
$data[] = [$entity->reveal(), 'update', $first_account->reveal(), TRUE];
|
||||
$data[] = [$entity->reveal(), 'update', $second_account->reveal(), FALSE];
|
||||
$data[] = [$entity->reveal(), 'update', $third_account->reveal(), TRUE];
|
||||
|
||||
// Test the unpublished permissions.
|
||||
$entity_first_other_up = $this->buildMockEntity($entity_type->reveal(), 9999, 'first', FALSE);
|
||||
$entity_first_own_up = $this->buildMockEntity($entity_type->reveal(), 14, 'first', FALSE);
|
||||
$entity_first_own_bundle_up = $this->buildMockEntity($entity_type->reveal(), 15, 'first', FALSE);
|
||||
$data = [];
|
||||
// Admin permission.
|
||||
$admin_user = $this->buildMockUser(5, 'administer green_entity');
|
||||
$data[] = [$entity->reveal(), 'view', $admin_user->reveal(), TRUE];
|
||||
$data[] = [$entity->reveal(), 'update', $admin_user->reveal(), TRUE];
|
||||
$data[] = [$entity->reveal(), 'delete', $admin_user->reveal(), TRUE];
|
||||
|
||||
$entity_second_other_up = $this->buildMockEntity($entity_type->reveal(), 9999, 'second', FALSE);
|
||||
$entity_second_own_up = $this->buildMockEntity($entity_type->reveal(), 14, 'second', FALSE);
|
||||
$entity_second_own_bundle_up = $this->buildMockEntity($entity_type->reveal(), 15, 'second', FALSE);
|
||||
// View, Update, delete permissions, entity without an owner.
|
||||
$second_entity = $this->buildMockEntity($entity_type->reveal());
|
||||
foreach (['view', 'update', 'delete'] as $operation) {
|
||||
$first_user = $this->buildMockUser(6, $operation . ' green_entity');
|
||||
$second_user = $this->buildMockUser(7, 'access content');
|
||||
|
||||
$user_view_own_up = $this->buildMockUser(14, 'view own unpublished green_entity');
|
||||
$user_view_other = $this->buildMockUser(15, 'view green_entity');
|
||||
$data[] = [$second_entity->reveal(), $operation, $first_user->reveal(), TRUE];
|
||||
$data[] = [$second_entity->reveal(), $operation, $second_user->reveal(), FALSE];
|
||||
}
|
||||
|
||||
$data['entity_first_other_up user_view_own_up'] = [$entity_first_other_up->reveal(), 'view', $user_view_own_up->reveal(), FALSE];
|
||||
$data['entity_first_own_up user_view_own_up'] = [$entity_first_own_up->reveal(), 'view', $user_view_own_up->reveal(), TRUE];
|
||||
$data['entity_first_own_bundle_up user_view_own_up'] = [$entity_first_own_bundle_up->reveal(), 'view', $user_view_own_up->reveal(), FALSE];
|
||||
$data['entity_second_other_up user_view_own_up'] = [$entity_second_other_up->reveal(), 'view', $user_view_own_up->reveal(), FALSE];
|
||||
$data['entity_second_own_up user_view_own_up'] = [$entity_second_own_up->reveal(), 'view', $user_view_own_up->reveal(), TRUE];
|
||||
$data['entity_second_own_bundle_up user_view_own_up'] = [$entity_second_own_bundle_up->reveal(), 'view', $user_view_own_up->reveal(), FALSE];
|
||||
// Update and delete permissions.
|
||||
foreach (['update', 'delete'] as $operation) {
|
||||
// Owner, non-owner, user with "any" permission.
|
||||
$first_user = $this->buildMockUser(6, $operation . ' own green_entity');
|
||||
$second_user = $this->buildMockUser(7, $operation . ' own green_entity');
|
||||
$third_user = $this->buildMockUser(8, $operation . ' any green_entity');
|
||||
|
||||
$data['entity_first_other_up user_view_other'] = [$entity_first_other_up->reveal(), 'view', $user_view_other->reveal(), FALSE];
|
||||
$data['entity_first_own_up user_view_other'] = [$entity_first_own_up->reveal(), 'view', $user_view_other->reveal(), FALSE];
|
||||
$data['entity_first_own_bundle_up user_view_other'] = [$entity_first_own_bundle_up->reveal(), 'view', $user_view_other->reveal(), FALSE];
|
||||
$data['entity_second_other_up user_view_other'] = [$entity_second_other_up->reveal(), 'view', $user_view_other->reveal(), FALSE];
|
||||
$data['entity_second_own_up user_view_other'] = [$entity_second_own_up->reveal(), 'view', $user_view_other->reveal(), FALSE];
|
||||
$data['entity_second_own_bundle_up user_view_other'] = [$entity_second_own_bundle_up->reveal(), 'view', $user_view_other->reveal(), FALSE];
|
||||
$data[] = [$entity->reveal(), $operation, $first_user->reveal(), TRUE];
|
||||
$data[] = [$entity->reveal(), $operation, $second_user->reveal(), FALSE];
|
||||
$data[] = [$entity->reveal(), $operation, $third_user->reveal(), TRUE];
|
||||
}
|
||||
|
||||
// View permissions.
|
||||
$first_user = $this->buildMockUser(9, 'view green_entity');
|
||||
$second_user = $this->buildMockUser(10, 'view first green_entity');
|
||||
$third_user = $this->buildMockUser(14, 'view own unpublished green_entity');
|
||||
$fourth_user = $this->buildMockUser(14, 'access content');
|
||||
|
||||
$first_entity = $this->buildMockEntity($entity_type->reveal(), 1, 'first');
|
||||
$second_entity = $this->buildMockEntity($entity_type->reveal(), 1, 'second');
|
||||
$third_entity = $this->buildMockEntity($entity_type->reveal(), 14, 'first', FALSE);
|
||||
|
||||
// The first user can view the two published entities.
|
||||
$data[] = [$first_entity->reveal(), 'view', $first_user->reveal(), TRUE];
|
||||
$data[] = [$second_entity->reveal(), 'view', $first_user->reveal(), TRUE];
|
||||
$data[] = [$third_entity->reveal(), 'view', $first_user->reveal(), FALSE];
|
||||
|
||||
// The second user can only view published entities of bundle "first".
|
||||
$data[] = [$first_entity->reveal(), 'view', $second_user->reveal(), TRUE];
|
||||
$data[] = [$second_entity->reveal(), 'view', $second_user->reveal(), FALSE];
|
||||
$data[] = [$third_entity->reveal(), 'view', $second_user->reveal(), FALSE];
|
||||
|
||||
// The third user can view their own unpublished entity.
|
||||
$data[] = [$first_entity->reveal(), 'view', $third_user->reveal(), FALSE];
|
||||
$data[] = [$second_entity->reveal(), 'view', $third_user->reveal(), FALSE];
|
||||
$data[] = [$third_entity->reveal(), 'view', $third_user->reveal(), TRUE];
|
||||
|
||||
// The fourth user can't view anything.
|
||||
$data[] = [$first_entity->reveal(), 'view', $fourth_user->reveal(), FALSE];
|
||||
$data[] = [$second_entity->reveal(), 'view', $fourth_user->reveal(), FALSE];
|
||||
$data[] = [$third_entity->reveal(), 'view', $fourth_user->reveal(), FALSE];
|
||||
|
||||
return $data;
|
||||
}
|
||||
@@ -175,29 +162,19 @@ class EntityAccessControlHandlerTest extends UnitTestCase {
|
||||
$entity_type->getHandlerClass('permission_provider')->willReturn(EntityPermissionProvider::class);
|
||||
|
||||
// User with the admin permission.
|
||||
$account = $this->prophesize(AccountInterface::class);
|
||||
$account->id()->willReturn(6);
|
||||
$account->hasPermission('administer green_entity')->willReturn(TRUE);
|
||||
$account = $this->buildMockUser('6', 'administer green_entity');
|
||||
$data[] = [$entity_type->reveal(), NULL, $account->reveal(), TRUE];
|
||||
|
||||
// Ordinary user.
|
||||
$account = $this->prophesize(AccountInterface::class);
|
||||
$account->id()->willReturn(6);
|
||||
$account->hasPermission('create green_entity')->willReturn(TRUE);
|
||||
$account->hasPermission(Argument::any())->willReturn(FALSE);
|
||||
$account = $this->buildMockUser('6', 'create green_entity');
|
||||
$data[] = [$entity_type->reveal(), NULL, $account->reveal(), TRUE];
|
||||
|
||||
// Ordinary user, entity with a bundle.
|
||||
$account = $this->prophesize(AccountInterface::class);
|
||||
$account->id()->willReturn(6);
|
||||
$account->hasPermission('create first_bundle green_entity')->willReturn(TRUE);
|
||||
$account->hasPermission(Argument::any())->willReturn(FALSE);
|
||||
$account = $this->buildMockUser('6', 'create first_bundle green_entity');
|
||||
$data[] = [$entity_type->reveal(), 'first_bundle', $account->reveal(), TRUE];
|
||||
|
||||
// User with no permissions.
|
||||
$account = $this->prophesize(AccountInterface::class);
|
||||
$account->id()->willReturn(6);
|
||||
$account->hasPermission(Argument::any())->willReturn(FALSE);
|
||||
$account = $this->buildMockUser('6', 'access content');
|
||||
$data[] = [$entity_type->reveal(), NULL, $account->reveal(), FALSE];
|
||||
|
||||
return $data;
|
||||
@@ -210,6 +187,10 @@ class EntityAccessControlHandlerTest extends UnitTestCase {
|
||||
* The entity type.
|
||||
* @param string $owner_id
|
||||
* The owner ID.
|
||||
* @param string $bundle
|
||||
* The bundle.
|
||||
* @param bool $published
|
||||
* Whether the entity is published.
|
||||
*
|
||||
* @return \Prophecy\Prophecy\ObjectProphecy
|
||||
* The entity mock.
|
||||
@@ -242,15 +223,26 @@ class EntityAccessControlHandlerTest extends UnitTestCase {
|
||||
$entity->getCacheTags()->willReturn([]);
|
||||
$entity->getCacheMaxAge()->willReturn(Cache::PERMANENT);
|
||||
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a mock user.
|
||||
*
|
||||
* @param int $uid
|
||||
* The user ID.
|
||||
* @param string $permission
|
||||
* The permission to grant.
|
||||
*
|
||||
* @return \Prophecy\Prophecy\ObjectProphecy
|
||||
* The user mock.
|
||||
*/
|
||||
protected function buildMockUser($uid, $permission) {
|
||||
$account = $this->prophesize(AccountInterface::class);
|
||||
$account->id()->willReturn($uid);
|
||||
$account->hasPermission($permission)->willReturn(TRUE);
|
||||
$account->hasPermission(Argument::any())->willReturn(FALSE);
|
||||
|
||||
return $account;
|
||||
}
|
||||
|
||||
|
||||
+9
-1
@@ -72,12 +72,12 @@ class EntityPermissionProviderTest extends UnitTestCase {
|
||||
$entity_type->id()->willReturn('green_entity');
|
||||
$entity_type->getSingularLabel()->willReturn('green entity');
|
||||
$entity_type->getPluralLabel()->willReturn('green entities');
|
||||
$entity_type->hasLinkTemplate('collection')->willReturn(FALSE);
|
||||
$entity_type->entityClassImplements(EntityOwnerInterface::class)->willReturn(FALSE);
|
||||
$entity_type->entityClassImplements(EntityPublishedInterface::class)->willReturn(FALSE);
|
||||
$entity_type->getPermissionGranularity()->willReturn('entity_type');
|
||||
$expected_permissions = [
|
||||
'administer green_entity' => 'Administer green entities',
|
||||
'access green_entity overview' => 'Access the green entities overview page',
|
||||
'create green_entity' => 'Create green entities',
|
||||
'update green_entity' => 'Update green entities',
|
||||
'delete green_entity' => 'Delete green entities',
|
||||
@@ -91,6 +91,7 @@ class EntityPermissionProviderTest extends UnitTestCase {
|
||||
$entity_type->id()->willReturn('blue_entity');
|
||||
$entity_type->getSingularLabel()->willReturn('blue entity');
|
||||
$entity_type->getPluralLabel()->willReturn('blue entities');
|
||||
$entity_type->hasLinkTemplate('collection')->willReturn(TRUE);
|
||||
$entity_type->entityClassImplements(EntityOwnerInterface::class)->willReturn(TRUE);
|
||||
$entity_type->entityClassImplements(EntityPublishedInterface::class)->willReturn(FALSE);
|
||||
$entity_type->getPermissionGranularity()->willReturn('entity_type');
|
||||
@@ -112,6 +113,7 @@ class EntityPermissionProviderTest extends UnitTestCase {
|
||||
$entity_type->id()->willReturn('white_entity');
|
||||
$entity_type->getSingularLabel()->willReturn('white entity');
|
||||
$entity_type->getPluralLabel()->willReturn('white entities');
|
||||
$entity_type->hasLinkTemplate('collection')->willReturn(TRUE);
|
||||
$entity_type->entityClassImplements(EntityOwnerInterface::class)->willReturn(FALSE);
|
||||
$entity_type->entityClassImplements(EntityPublishedInterface::class)->willReturn(FALSE);
|
||||
$entity_type->getPermissionGranularity()->willReturn('bundle');
|
||||
@@ -125,6 +127,8 @@ class EntityPermissionProviderTest extends UnitTestCase {
|
||||
'update second white_entity' => 'Second: Update white entities',
|
||||
'delete second white_entity' => 'Second: Delete white entities',
|
||||
'view white_entity' => 'View white entities',
|
||||
'view first white_entity' => 'First: View white entities',
|
||||
'view second white_entity' => 'Second: View white entities',
|
||||
];
|
||||
$data[] = [$entity_type->reveal(), $expected_permissions];
|
||||
|
||||
@@ -134,6 +138,7 @@ class EntityPermissionProviderTest extends UnitTestCase {
|
||||
$entity_type->id()->willReturn('black_entity');
|
||||
$entity_type->getSingularLabel()->willReturn('black entity');
|
||||
$entity_type->getPluralLabel()->willReturn('black entities');
|
||||
$entity_type->hasLinkTemplate('collection')->willReturn(TRUE);
|
||||
$entity_type->entityClassImplements(EntityOwnerInterface::class)->willReturn(TRUE);
|
||||
$entity_type->entityClassImplements(EntityPublishedInterface::class)->willReturn(FALSE);
|
||||
$entity_type->getPermissionGranularity()->willReturn('bundle');
|
||||
@@ -146,6 +151,7 @@ class EntityPermissionProviderTest extends UnitTestCase {
|
||||
'delete any third black_entity' => 'Third: Delete any black entity',
|
||||
'delete own third black_entity' => 'Third: Delete own black entities',
|
||||
'view black_entity' => 'View black entities',
|
||||
'view third black_entity' => 'Third: View black entities',
|
||||
];
|
||||
$data[] = [$entity_type->reveal(), $expected_permissions];
|
||||
|
||||
@@ -155,6 +161,7 @@ class EntityPermissionProviderTest extends UnitTestCase {
|
||||
$entity_type->id()->willReturn('pink_entity');
|
||||
$entity_type->getSingularLabel()->willReturn('pink entity');
|
||||
$entity_type->getPluralLabel()->willReturn('pink entities');
|
||||
$entity_type->hasLinkTemplate('collection')->willReturn(TRUE);
|
||||
$entity_type->entityClassImplements(EntityOwnerInterface::class)->willReturn(TRUE);
|
||||
$entity_type->entityClassImplements(EntityPublishedInterface::class)->willReturn(TRUE);
|
||||
$entity_type->getPermissionGranularity()->willReturn('bundle');
|
||||
@@ -168,6 +175,7 @@ class EntityPermissionProviderTest extends UnitTestCase {
|
||||
'delete any third pink_entity' => 'Third: Delete any pink entity',
|
||||
'delete own third pink_entity' => 'Third: Delete own pink entities',
|
||||
'view pink_entity' => 'View pink entities',
|
||||
'view third pink_entity' => 'Third: View pink entities',
|
||||
];
|
||||
$data[] = [$entity_type->reveal(), $expected_permissions];
|
||||
|
||||
|
||||
+74
-120
@@ -21,7 +21,7 @@ use Drupal\user\EntityOwnerInterface;
|
||||
use Prophecy\Argument;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\entity\EntityAccessControlHandler
|
||||
* @coversDefaultClass \Drupal\entity\UncacheableEntityAccessControlHandler
|
||||
* @group entity
|
||||
*/
|
||||
class UncacheableEntityAccessControlHandlerTest extends UnitTestCase {
|
||||
@@ -77,126 +77,75 @@ class UncacheableEntityAccessControlHandlerTest extends UnitTestCase {
|
||||
* A list of testAccess method arguments.
|
||||
*/
|
||||
public function accessProvider() {
|
||||
$data = [];
|
||||
|
||||
$entity_type = $this->prophesize(ContentEntityTypeInterface::class);
|
||||
$entity_type->id()->willReturn('green_entity');
|
||||
$entity_type->getAdminPermission()->willReturn('administer green_entity');
|
||||
$entity_type->hasHandlerClass('permission_provider')->willReturn(TRUE);
|
||||
$entity_type->getHandlerClass('permission_provider')->willReturn(UncacheableEntityPermissionProvider::class);
|
||||
|
||||
// User with the admin permission can do anything.
|
||||
$entity = $this->buildMockEntity($entity_type->reveal());
|
||||
$account = $this->prophesize(AccountInterface::class);
|
||||
$account->id()->willReturn(6);
|
||||
$account->hasPermission('administer green_entity')->willReturn(TRUE);
|
||||
$data[] = [$entity->reveal(), 'view', $account->reveal(), TRUE];
|
||||
$data[] = [$entity->reveal(), 'update', $account->reveal(), TRUE];
|
||||
$data[] = [$entity->reveal(), 'delete', $account->reveal(), TRUE];
|
||||
|
||||
// Entity with no owner.
|
||||
$entity = $this->buildMockEntity($entity_type->reveal());
|
||||
// User who has access.
|
||||
$first_account = $this->prophesize(AccountInterface::class);
|
||||
$first_account->id()->willReturn(6);
|
||||
$first_account->hasPermission('view green_entity')->willReturn(TRUE);
|
||||
$first_account->hasPermission(Argument::any())->willReturn(FALSE);
|
||||
// User who doesn't have access.
|
||||
$second_account = $this->prophesize(AccountInterface::class);
|
||||
$second_account->id()->willReturn(7);
|
||||
$second_account->hasPermission('view green_entity')->willReturn(FALSE);
|
||||
$second_account->hasPermission(Argument::any())->willReturn(FALSE);
|
||||
$data[] = [$entity->reveal(), 'view', $first_account->reveal(), TRUE];
|
||||
$data[] = [$entity->reveal(), 'view', $second_account->reveal(), FALSE];
|
||||
|
||||
// Entity with owner.
|
||||
$entity = $this->buildMockEntity($entity_type->reveal(), 6);
|
||||
// Owner.
|
||||
$first_account = $this->prophesize(AccountInterface::class);
|
||||
$first_account->id()->willReturn(6);
|
||||
$first_account->hasPermission('update own green_entity')->willReturn(TRUE);
|
||||
$first_account->hasPermission(Argument::any())->willReturn(FALSE);
|
||||
// Non-owner.
|
||||
$second_account = $this->prophesize(AccountInterface::class);
|
||||
$second_account->id()->willReturn(7);
|
||||
$second_account->hasPermission('update own green_entity')->willReturn(TRUE);
|
||||
$second_account->hasPermission(Argument::any())->willReturn(FALSE);
|
||||
// User who can update any.
|
||||
$third_account = $this->prophesize(AccountInterface::class);
|
||||
$third_account->id()->willReturn(8);
|
||||
$third_account->hasPermission('update any green_entity')->willReturn(TRUE);
|
||||
$third_account->hasPermission(Argument::any())->willReturn(FALSE);
|
||||
$data[] = [$entity->reveal(), 'update', $first_account->reveal(), TRUE];
|
||||
$data[] = [$entity->reveal(), 'update', $second_account->reveal(), FALSE];
|
||||
$data[] = [$entity->reveal(), 'update', $third_account->reveal(), TRUE];
|
||||
|
||||
// Per bundle permissions.
|
||||
$entity_first_other = $this->buildMockEntity($entity_type->reveal(), 9999, 'first');
|
||||
$entity_first_own = $this->buildMockEntity($entity_type->reveal(), 10, 'first');
|
||||
$entity_first_own_bundle = $this->buildMockEntity($entity_type->reveal(), 12, 'first');
|
||||
$data = [];
|
||||
// Admin permission.
|
||||
$admin_user = $this->buildMockUser(5, 'administer green_entity');
|
||||
$data[] = [$entity->reveal(), 'view', $admin_user->reveal(), TRUE];
|
||||
$data[] = [$entity->reveal(), 'update', $admin_user->reveal(), TRUE];
|
||||
$data[] = [$entity->reveal(), 'delete', $admin_user->reveal(), TRUE];
|
||||
|
||||
$entity_second_other = $this->buildMockEntity($entity_type->reveal(), 9999, 'second');
|
||||
$entity_second_own = $this->buildMockEntity($entity_type->reveal(), 10, 'second');
|
||||
$entity_second_own_bundle = $this->buildMockEntity($entity_type->reveal(), 12, 'second');
|
||||
|
||||
$user_view_any = $this->buildMockUser(9, 'view any green_entity');
|
||||
$user_view_own = $this->buildMockUser(10, 'view own green_entity');
|
||||
$user_view_bundle_any = $this->buildMockUser(11, 'view any first green_entity');
|
||||
$user_view_bundle_own = $this->buildMockUser(12, 'view own first green_entity');
|
||||
// View, update, delete permissions, entity without an owner.
|
||||
$second_entity = $this->buildMockEntity($entity_type->reveal());
|
||||
foreach (['view', 'update', 'delete'] as $operation) {
|
||||
$first_user = $this->buildMockUser(6, $operation . ' green_entity');
|
||||
$second_user = $this->buildMockUser(7, 'access content');
|
||||
|
||||
$data['entity_first_other user_view_any'] = [$entity_first_other->reveal(), 'view', $user_view_any->reveal(), TRUE];
|
||||
$data['entity_first_own user_view_any'] = [$entity_first_own->reveal(), 'view', $user_view_any->reveal(), TRUE];
|
||||
$data['entity_first_own_bundle user_view_any'] = [$entity_first_own_bundle->reveal(), 'view', $user_view_any->reveal(), TRUE];
|
||||
$data['entity_second_other user_view_any'] = [$entity_second_other->reveal(), 'view', $user_view_any->reveal(), TRUE];
|
||||
$data['entity_second_own user_view_any'] = [$entity_second_own->reveal(), 'view', $user_view_any->reveal(), TRUE];
|
||||
$data['entity_second_own_bundle user_view_any'] = [$entity_second_own_bundle->reveal(), 'view', $user_view_any->reveal(), TRUE];
|
||||
$data[] = [$second_entity->reveal(), $operation, $first_user->reveal(), TRUE];
|
||||
$data[] = [$second_entity->reveal(), $operation, $second_user->reveal(), FALSE];
|
||||
}
|
||||
|
||||
$data['entity_first_other user_view_own'] = [$entity_first_other->reveal(), 'view', $user_view_own->reveal(), FALSE];
|
||||
$data['entity_first_own user_view_own'] = [$entity_first_own->reveal(), 'view', $user_view_own->reveal(), TRUE];
|
||||
$data['entity_first_own_bundle user_view_own'] = [$entity_first_own_bundle->reveal(), 'view', $user_view_own->reveal(), FALSE];
|
||||
$data['entity_second_other user_view_own'] = [$entity_second_other->reveal(), 'view', $user_view_own->reveal(), FALSE];
|
||||
$data['entity_second_own user_view_own'] = [$entity_second_own->reveal(), 'view', $user_view_own->reveal(), TRUE];
|
||||
$data['entity_second_own_bundle user_view_own'] = [$entity_second_own_bundle->reveal(), 'view', $user_view_own->reveal(), FALSE];
|
||||
// View, update, delete permissions.
|
||||
foreach (['view', 'update', 'delete'] as $operation) {
|
||||
// Owner, non-owner, user with "any" permission.
|
||||
$first_user = $this->buildMockUser(6, $operation . ' own green_entity');
|
||||
$second_user = $this->buildMockUser(7, $operation . ' own green_entity');
|
||||
$third_user = $this->buildMockUser(8, $operation . ' any green_entity');
|
||||
|
||||
$data['entity_first_other user_view_bundle_any'] = [$entity_first_other->reveal(), 'view', $user_view_bundle_any->reveal(), TRUE];
|
||||
$data['entity_first_own user_view_bundle_any'] = [$entity_first_own->reveal(), 'view', $user_view_bundle_any->reveal(), TRUE];
|
||||
$data['entity_first_own_bundle user_view_bundle_any'] = [$entity_first_own_bundle->reveal(), 'view', $user_view_bundle_any->reveal(), TRUE];
|
||||
$data['entity_second_other user_view_bundle_any'] = [$entity_second_other->reveal(), 'view', $user_view_bundle_any->reveal(), FALSE];
|
||||
$data['entity_second_own user_view_bundle_any'] = [$entity_second_own->reveal(), 'view', $user_view_bundle_any->reveal(), FALSE];
|
||||
$data['entity_second_own_bundle user_view_bundle_any'] = [$entity_second_own_bundle->reveal(), 'view', $user_view_bundle_any->reveal(), FALSE];
|
||||
$data[] = [$entity->reveal(), $operation, $first_user->reveal(), TRUE];
|
||||
$data[] = [$entity->reveal(), $operation, $second_user->reveal(), FALSE];
|
||||
$data[] = [$entity->reveal(), $operation, $third_user->reveal(), TRUE];
|
||||
}
|
||||
|
||||
$data['entity_first_other user_view_bundle_any'] = [$entity_first_other->reveal(), 'view', $user_view_bundle_own->reveal(), FALSE];
|
||||
$data['entity_first_own user_view_bundle_any'] = [$entity_first_own->reveal(), 'view', $user_view_bundle_own->reveal(), FALSE];
|
||||
$data['entity_first_own_bundle user_view_bundle_any'] = [$entity_first_own_bundle->reveal(), 'view', $user_view_bundle_own->reveal(), TRUE];
|
||||
$data['entity_second_other user_view_bundle_any'] = [$entity_second_other->reveal(), 'view', $user_view_bundle_own->reveal(), FALSE];
|
||||
$data['entity_second_own user_view_bundle_any'] = [$entity_second_own->reveal(), 'view', $user_view_bundle_own->reveal(), FALSE];
|
||||
$data['entity_second_own_bundle user_view_bundle_any'] = [$entity_second_own_bundle->reveal(), 'view', $user_view_bundle_own->reveal(), FALSE];
|
||||
// Per bundle and unpublished view permissions.
|
||||
$first_user = $this->buildMockUser(11, 'view any first green_entity');
|
||||
$second_user = $this->buildMockUser(12, 'view own first green_entity');
|
||||
$third_user = $this->buildMockUser(13, 'view own unpublished green_entity');
|
||||
|
||||
// Test the unpublished permissions.
|
||||
$entity_first_other_up = $this->buildMockEntity($entity_type->reveal(), 9999, 'first', FALSE);
|
||||
$entity_first_own_up = $this->buildMockEntity($entity_type->reveal(), 14, 'first', FALSE);
|
||||
$entity_first_own_bundle_up = $this->buildMockEntity($entity_type->reveal(), 15, 'first', FALSE);
|
||||
$first_entity = $this->buildMockEntity($entity_type->reveal(), 9999, 'first');
|
||||
$second_entity = $this->buildMockEntity($entity_type->reveal(), 12, 'first');
|
||||
$third_entity = $this->buildMockEntity($entity_type->reveal(), 9999, 'second');
|
||||
$fourth_entity = $this->buildMockEntity($entity_type->reveal(), 10, 'second');
|
||||
$fifth_entity = $this->buildMockEntity($entity_type->reveal(), 13, 'first', FALSE);
|
||||
|
||||
$entity_second_other_up = $this->buildMockEntity($entity_type->reveal(), 9999, 'second', FALSE);
|
||||
$entity_second_own_up = $this->buildMockEntity($entity_type->reveal(), 14, 'second', FALSE);
|
||||
$entity_second_own_bundle_up = $this->buildMockEntity($entity_type->reveal(), 15, 'second', FALSE);
|
||||
// The first user can view the two entities of bundle "first".
|
||||
$data[] = [$first_entity->reveal(), 'view', $first_user->reveal(), TRUE];
|
||||
$data[] = [$second_entity->reveal(), 'view', $first_user->reveal(), TRUE];
|
||||
$data[] = [$third_entity->reveal(), 'view', $first_user->reveal(), FALSE];
|
||||
$data[] = [$fourth_entity->reveal(), 'view', $first_user->reveal(), FALSE];
|
||||
$data[] = [$fifth_entity->reveal(), 'view', $first_user->reveal(), FALSE];
|
||||
|
||||
$user_view_own_up = $this->buildMockUser(14, 'view own unpublished green_entity');
|
||||
$user_view_other = $this->buildMockUser(15, 'view green_entity');
|
||||
// The second user can view their own entity of bundle "first".
|
||||
$data[] = [$first_entity->reveal(), 'view', $second_user->reveal(), FALSE];
|
||||
$data[] = [$second_entity->reveal(), 'view', $second_user->reveal(), TRUE];
|
||||
$data[] = [$third_entity->reveal(), 'view', $second_user->reveal(), FALSE];
|
||||
$data[] = [$fourth_entity->reveal(), 'view', $second_user->reveal(), FALSE];
|
||||
$data[] = [$fourth_entity->reveal(), 'view', $second_user->reveal(), FALSE];
|
||||
$data[] = [$fifth_entity->reveal(), 'view', $second_user->reveal(), FALSE];
|
||||
|
||||
$data['entity_first_other_up user_view_own_up'] = [$entity_first_other_up->reveal(), 'view', $user_view_own_up->reveal(), FALSE];
|
||||
$data['entity_first_own_up user_view_own_up'] = [$entity_first_own_up->reveal(), 'view', $user_view_own_up->reveal(), TRUE];
|
||||
$data['entity_first_own_bundle_up user_view_own_up'] = [$entity_first_own_bundle_up->reveal(), 'view', $user_view_own_up->reveal(), FALSE];
|
||||
$data['entity_second_other_up user_view_own_up'] = [$entity_second_other_up->reveal(), 'view', $user_view_own_up->reveal(), FALSE];
|
||||
$data['entity_second_own_up user_view_own_up'] = [$entity_second_own_up->reveal(), 'view', $user_view_own_up->reveal(), TRUE];
|
||||
$data['entity_second_own_bundle_up user_view_own_up'] = [$entity_second_own_bundle_up->reveal(), 'view', $user_view_own_up->reveal(), FALSE];
|
||||
|
||||
$data['entity_first_other_up user_view_other'] = [$entity_first_other_up->reveal(), 'view', $user_view_other->reveal(), FALSE];
|
||||
$data['entity_first_own_up user_view_other'] = [$entity_first_own_up->reveal(), 'view', $user_view_other->reveal(), FALSE];
|
||||
$data['entity_first_own_bundle_up user_view_other'] = [$entity_first_own_bundle_up->reveal(), 'view', $user_view_other->reveal(), FALSE];
|
||||
$data['entity_second_other_up user_view_other'] = [$entity_second_other_up->reveal(), 'view', $user_view_other->reveal(), FALSE];
|
||||
$data['entity_second_own_up user_view_other'] = [$entity_second_own_up->reveal(), 'view', $user_view_other->reveal(), FALSE];
|
||||
$data['entity_second_own_bundle_up user_view_other'] = [$entity_second_own_bundle_up->reveal(), 'view', $user_view_other->reveal(), FALSE];
|
||||
// The third user can only view their own unpublished entity.
|
||||
$data[] = [$first_entity->reveal(), 'view', $third_user->reveal(), FALSE];
|
||||
$data[] = [$second_entity->reveal(), 'view', $third_user->reveal(), FALSE];
|
||||
$data[] = [$third_entity->reveal(), 'view', $third_user->reveal(), FALSE];
|
||||
$data[] = [$fourth_entity->reveal(), 'view', $third_user->reveal(), FALSE];
|
||||
$data[] = [$fourth_entity->reveal(), 'view', $third_user->reveal(), FALSE];
|
||||
$data[] = [$fifth_entity->reveal(), 'view', $third_user->reveal(), TRUE];
|
||||
|
||||
return $data;
|
||||
}
|
||||
@@ -217,29 +166,19 @@ class UncacheableEntityAccessControlHandlerTest extends UnitTestCase {
|
||||
$entity_type->getHandlerClass('permission_provider')->willReturn(UncacheableEntityPermissionProvider::class);
|
||||
|
||||
// User with the admin permission.
|
||||
$account = $this->prophesize(AccountInterface::class);
|
||||
$account->id()->willReturn(6);
|
||||
$account->hasPermission('administer green_entity')->willReturn(TRUE);
|
||||
$account = $this->buildMockUser('6', 'administer green_entity');
|
||||
$data[] = [$entity_type->reveal(), NULL, $account->reveal(), TRUE];
|
||||
|
||||
// Ordinary user.
|
||||
$account = $this->prophesize(AccountInterface::class);
|
||||
$account->id()->willReturn(6);
|
||||
$account->hasPermission('create green_entity')->willReturn(TRUE);
|
||||
$account->hasPermission(Argument::any())->willReturn(FALSE);
|
||||
$account = $this->buildMockUser('6', 'create green_entity');
|
||||
$data[] = [$entity_type->reveal(), NULL, $account->reveal(), TRUE];
|
||||
|
||||
// Ordinary user, entity with a bundle.
|
||||
$account = $this->prophesize(AccountInterface::class);
|
||||
$account->id()->willReturn(6);
|
||||
$account->hasPermission('create first_bundle green_entity')->willReturn(TRUE);
|
||||
$account->hasPermission(Argument::any())->willReturn(FALSE);
|
||||
$account = $this->buildMockUser('6', 'create first_bundle green_entity');
|
||||
$data[] = [$entity_type->reveal(), 'first_bundle', $account->reveal(), TRUE];
|
||||
|
||||
// User with no permissions.
|
||||
$account = $this->prophesize(AccountInterface::class);
|
||||
$account->id()->willReturn(6);
|
||||
$account->hasPermission(Argument::any())->willReturn(FALSE);
|
||||
$account = $this->buildMockUser('6', 'access content');
|
||||
$data[] = [$entity_type->reveal(), NULL, $account->reveal(), FALSE];
|
||||
|
||||
return $data;
|
||||
@@ -252,6 +191,10 @@ class UncacheableEntityAccessControlHandlerTest extends UnitTestCase {
|
||||
* The entity type.
|
||||
* @param string $owner_id
|
||||
* The owner ID.
|
||||
* @param string $bundle
|
||||
* The bundle.
|
||||
* @param bool $published
|
||||
* Whether the entity is published.
|
||||
*
|
||||
* @return \Prophecy\Prophecy\ObjectProphecy
|
||||
* The entity mock.
|
||||
@@ -284,15 +227,26 @@ class UncacheableEntityAccessControlHandlerTest extends UnitTestCase {
|
||||
$entity->getCacheTags()->willReturn([]);
|
||||
$entity->getCacheMaxAge()->willReturn(Cache::PERMANENT);
|
||||
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a mock user.
|
||||
*
|
||||
* @param int $uid
|
||||
* The user ID.
|
||||
* @param string $permission
|
||||
* The permission to grant.
|
||||
*
|
||||
* @return \Prophecy\Prophecy\ObjectProphecy
|
||||
* The user mock.
|
||||
*/
|
||||
protected function buildMockUser($uid, $permission) {
|
||||
$account = $this->prophesize(AccountInterface::class);
|
||||
$account->id()->willReturn($uid);
|
||||
$account->hasPermission($permission)->willReturn(TRUE);
|
||||
$account->hasPermission(Argument::any())->willReturn(FALSE);
|
||||
|
||||
return $account;
|
||||
}
|
||||
|
||||
|
||||
+5
-1
@@ -72,12 +72,12 @@ class UncacheableEntityPermissionProviderTest extends UnitTestCase {
|
||||
$entity_type->id()->willReturn('green_entity');
|
||||
$entity_type->getSingularLabel()->willReturn('green entity');
|
||||
$entity_type->getPluralLabel()->willReturn('green entities');
|
||||
$entity_type->hasLinkTemplate('collection')->willReturn(FALSE);
|
||||
$entity_type->entityClassImplements(EntityOwnerInterface::class)->willReturn(FALSE);
|
||||
$entity_type->entityClassImplements(EntityPublishedInterface::class)->willReturn(FALSE);
|
||||
$entity_type->getPermissionGranularity()->willReturn('entity_type');
|
||||
$expected_permissions = [
|
||||
'administer green_entity' => 'Administer green entities',
|
||||
'access green_entity overview' => 'Access the green entities overview page',
|
||||
'create green_entity' => 'Create green entities',
|
||||
'update green_entity' => 'Update green entities',
|
||||
'delete green_entity' => 'Delete green entities',
|
||||
@@ -91,6 +91,7 @@ class UncacheableEntityPermissionProviderTest extends UnitTestCase {
|
||||
$entity_type->id()->willReturn('blue_entity');
|
||||
$entity_type->getSingularLabel()->willReturn('blue entity');
|
||||
$entity_type->getPluralLabel()->willReturn('blue entities');
|
||||
$entity_type->hasLinkTemplate('collection')->willReturn(TRUE);
|
||||
$entity_type->entityClassImplements(EntityOwnerInterface::class)->willReturn(TRUE);
|
||||
$entity_type->entityClassImplements(EntityPublishedInterface::class)->willReturn(FALSE);
|
||||
$entity_type->getPermissionGranularity()->willReturn('entity_type');
|
||||
@@ -113,6 +114,7 @@ class UncacheableEntityPermissionProviderTest extends UnitTestCase {
|
||||
$entity_type->id()->willReturn('white_entity');
|
||||
$entity_type->getSingularLabel()->willReturn('white entity');
|
||||
$entity_type->getPluralLabel()->willReturn('white entities');
|
||||
$entity_type->hasLinkTemplate('collection')->willReturn(TRUE);
|
||||
$entity_type->entityClassImplements(EntityOwnerInterface::class)->willReturn(FALSE);
|
||||
$entity_type->entityClassImplements(EntityPublishedInterface::class)->willReturn(FALSE);
|
||||
$entity_type->getPermissionGranularity()->willReturn('bundle');
|
||||
@@ -137,6 +139,7 @@ class UncacheableEntityPermissionProviderTest extends UnitTestCase {
|
||||
$entity_type->id()->willReturn('black_entity');
|
||||
$entity_type->getSingularLabel()->willReturn('black entity');
|
||||
$entity_type->getPluralLabel()->willReturn('black entities');
|
||||
$entity_type->hasLinkTemplate('collection')->willReturn(TRUE);
|
||||
$entity_type->entityClassImplements(EntityOwnerInterface::class)->willReturn(TRUE);
|
||||
$entity_type->entityClassImplements(EntityPublishedInterface::class)->willReturn(FALSE);
|
||||
$entity_type->getPermissionGranularity()->willReturn('bundle');
|
||||
@@ -161,6 +164,7 @@ class UncacheableEntityPermissionProviderTest extends UnitTestCase {
|
||||
$entity_type->id()->willReturn('pink_entity');
|
||||
$entity_type->getSingularLabel()->willReturn('pink entity');
|
||||
$entity_type->getPluralLabel()->willReturn('pink entities');
|
||||
$entity_type->hasLinkTemplate('collection')->willReturn(TRUE);
|
||||
$entity_type->entityClassImplements(EntityOwnerInterface::class)->willReturn(TRUE);
|
||||
$entity_type->entityClassImplements(EntityPublishedInterface::class)->willReturn(TRUE);
|
||||
$entity_type->getPermissionGranularity()->willReturn('bundle');
|
||||
|
||||
Regular → Executable
+24
-5
@@ -1,3 +1,13 @@
|
||||
CONTENTS OF THIS FILE
|
||||
---------------------
|
||||
|
||||
* Introduction
|
||||
* Recommended modules
|
||||
* Installation
|
||||
* Configuration
|
||||
* Troubleshooting
|
||||
* Maintainers
|
||||
|
||||
INTRODUCTION
|
||||
------------
|
||||
|
||||
@@ -9,20 +19,28 @@ INTRODUCTION
|
||||
* To submit bug reports and feature suggestions, or to track changes:
|
||||
https://drupal.org/project/issues/token
|
||||
|
||||
RECOMMENDED MODULES
|
||||
-------------------
|
||||
|
||||
* No extra module is required.
|
||||
|
||||
INSTALLATION
|
||||
------------
|
||||
|
||||
Install as usual, see
|
||||
https://www.drupal.org/docs/8/extending-drupal-8/installing-contributed-modules-find-import-enable-configure-drupal-8 for further
|
||||
information.
|
||||
* Install as usual, see
|
||||
https://www.drupal.org/docs/8/extending-drupal-8/installing-contributed-modules-find-import-enable-configure-drupal-8 for further
|
||||
information.
|
||||
|
||||
CONFIGURATION
|
||||
-------------
|
||||
|
||||
* No configuration is needed.
|
||||
|
||||
TROUBLESHOOTING
|
||||
---------------
|
||||
|
||||
Token module doesn't provide any visible functions to the user on its own, it
|
||||
just provides token handling services for other modules.
|
||||
* Token module doesn't provide any visible functions to the user on its own, it
|
||||
just provides token handling services for other modules.
|
||||
|
||||
|
||||
MAINTAINERS
|
||||
@@ -31,3 +49,4 @@ MAINTAINERS
|
||||
Current maintainers:
|
||||
|
||||
* Dave Reid (https://drupal.org/user/53892)
|
||||
* Sascha Grossenbacher (Berdir) (https://www.drupal.org/user/214652)
|
||||
|
||||
@@ -35,6 +35,12 @@
|
||||
else if (typeof(CKEDITOR) != 'undefined' && CKEDITOR.currentInstance) {
|
||||
CKEDITOR.currentInstance.insertHtml(content);
|
||||
}
|
||||
// Direct CodeMirror support.
|
||||
else if (typeof(CodeMirror) != 'undefined' && drupalSettings.tokenFocusedField && $(drupalSettings.tokenFocusedField).parents('.CodeMirror').length) {
|
||||
var editor = $(drupalSettings.tokenFocusedField).parents('.CodeMirror')[0].CodeMirror;
|
||||
editor.replaceSelection(content);
|
||||
editor.focus();
|
||||
}
|
||||
// WYSIWYG support, should work in all editors if available.
|
||||
else if (Drupal.wysiwyg && Drupal.wysiwyg.activeId) {
|
||||
Drupal.wysiwyg.instances[Drupal.wysiwyg.activeId].insert(content)
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Drupal\token\Controller;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\Controller\ControllerBase;
|
||||
use Drupal\token\TreeBuilderInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
@@ -48,9 +47,9 @@ class TokenAutocompleteController extends ControllerBase {
|
||||
public function autocomplete($token_type, $filter, Request $request) {
|
||||
$filter = substr($filter, strrpos($filter, '['));
|
||||
|
||||
$matches = array();
|
||||
$matches = [];
|
||||
|
||||
if (!Unicode::strlen($filter)) {
|
||||
if (!mb_strlen($filter)) {
|
||||
$matches["[{$token_type}:"] = 0;
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -7,14 +7,14 @@ use Drupal\Core\Controller\ControllerBase;
|
||||
/**
|
||||
* Clears cache for tokens.
|
||||
*/
|
||||
class TokenCacheController extends ControllerBase {
|
||||
class TokenCacheController extends ControllerBase {
|
||||
|
||||
/**
|
||||
* Clear caches and redirect back to the frontpage.
|
||||
*/
|
||||
public function flush() {
|
||||
token_clear_cache();
|
||||
drupal_set_message(t('Token registry caches cleared.'));
|
||||
$this->messenger()->addMessage($this->t('Token registry caches cleared.'));
|
||||
return $this->redirect('<front>');
|
||||
}
|
||||
|
||||
|
||||
@@ -71,4 +71,5 @@ class RouteSubscriber extends RouteSubscriberBase {
|
||||
$events[RoutingEvents::ALTER] = array('onAlterRoutes', 100);
|
||||
return $events;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\token\Tests;
|
||||
|
||||
use Drupal\block_content\Entity\BlockContent;
|
||||
use Drupal\block_content\Entity\BlockContentType;
|
||||
|
||||
@@ -21,38 +22,38 @@ class TokenBlockTest extends TokenTestBase {
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setUp($modules = array()) {
|
||||
public function setUp($modules = []) {
|
||||
parent::setUp();
|
||||
$this->admin_user = $this->drupalCreateUser(array('access content', 'administer blocks'));
|
||||
$this->admin_user = $this->drupalCreateUser(['access content', 'administer blocks']);
|
||||
$this->drupalLogin($this->admin_user);
|
||||
}
|
||||
|
||||
public function testBlockTitleTokens() {
|
||||
$label = 'tokenblock';
|
||||
$bundle = BlockContentType::create(array(
|
||||
$bundle = BlockContentType::create([
|
||||
'id' => $label,
|
||||
'label' => $label,
|
||||
'revision' => FALSE
|
||||
));
|
||||
]);
|
||||
$bundle->save();
|
||||
|
||||
$block_content = BlockContent::create(array(
|
||||
$block_content = BlockContent::create([
|
||||
'type' => $label,
|
||||
'label' => '[current-page:title] block title',
|
||||
'info' => 'Test token title block',
|
||||
'body[value]' => 'This is the test token title block.',
|
||||
));
|
||||
]);
|
||||
$block_content->save();
|
||||
|
||||
$block = $this->drupalPlaceBlock('block_content:' . $block_content->uuid(), array(
|
||||
$block = $this->drupalPlaceBlock('block_content:' . $block_content->uuid(), [
|
||||
'label' => '[user:name]',
|
||||
));
|
||||
$this->drupalGet($block->urlInfo());
|
||||
]);
|
||||
$this->drupalGet($block->toUrl());
|
||||
// Ensure that the link to available tokens is present and correctly
|
||||
// positioned.
|
||||
$this->assertLink('Browse available tokens.');
|
||||
$this->assertText('This field supports tokens. Browse available tokens.');
|
||||
$this->drupalPostForm(NULL, array(), t('Save block'));
|
||||
$this->drupalPostForm(NULL, [], t('Save block'));
|
||||
// Ensure token validation is working on the block.
|
||||
$this->assertText('Title is using the following invalid tokens: [user:name].');
|
||||
|
||||
@@ -63,8 +64,8 @@ class TokenBlockTest extends TokenTestBase {
|
||||
$block->save();
|
||||
|
||||
// Ensure that tokens are not double-escaped when output as a block title.
|
||||
$this->drupalCreateContentType(array('type' => 'page'));
|
||||
$node = $this->drupalCreateNode(array('title' => "Site's first node"));
|
||||
$this->drupalCreateContentType(['type' => 'page']);
|
||||
$node = $this->drupalCreateNode(['title' => "Site's first node"]);
|
||||
$this->drupalGet('node/' . $node->id());
|
||||
// The apostraphe should only be escaped once.
|
||||
$this->assertRaw("Site's first node block title");
|
||||
|
||||
@@ -16,19 +16,19 @@ class TokenCurrentPageTest extends TokenTestBase {
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('node');
|
||||
public static $modules = ['node'];
|
||||
|
||||
function testCurrentPageTokens() {
|
||||
$tokens = array(
|
||||
$tokens = [
|
||||
'[current-page:title]' => t('Log in'),
|
||||
'[current-page:url]' => Url::fromRoute('user.login', [], array('absolute' => TRUE))->toString(),
|
||||
'[current-page:url:absolute]' => Url::fromRoute('user.login', [], array('absolute' => TRUE))->toString(),
|
||||
'[current-page:url]' => Url::fromRoute('user.login', [], ['absolute' => TRUE])->toString(),
|
||||
'[current-page:url:absolute]' => Url::fromRoute('user.login', [], ['absolute' => TRUE])->toString(),
|
||||
'[current-page:url:relative]' => Url::fromRoute('user.login')->toString(),
|
||||
'[current-page:url:path]' => '/user/login',
|
||||
'[current-page:url:args:value:0]' => 'user',
|
||||
'[current-page:url:args:value:1]' => 'login',
|
||||
'[current-page:url:args:value:2]' => NULL,
|
||||
'[current-page:url:unaliased]' => Url::fromRoute('user.login', [], array('absolute' => TRUE, 'alias' => TRUE))->toString(),
|
||||
'[current-page:url:unaliased]' => Url::fromRoute('user.login', [], ['absolute' => TRUE, 'alias' => TRUE])->toString(),
|
||||
'[current-page:page-number]' => 1,
|
||||
'[current-page:query:foo]' => NULL,
|
||||
'[current-page:query:bar]' => NULL,
|
||||
@@ -36,20 +36,20 @@ class TokenCurrentPageTest extends TokenTestBase {
|
||||
'[current-page:arg:0]' => 'user',
|
||||
'[current-page:arg:1]' => 'login',
|
||||
'[current-page:arg:2]' => NULL,
|
||||
);
|
||||
];
|
||||
$this->assertPageTokens('user/login', $tokens);
|
||||
|
||||
$this->drupalCreateContentType(array('type' => 'page'));
|
||||
$node = $this->drupalCreateNode(array('title' => 'Node title', 'path' => array('alias' => '/node-alias')));
|
||||
$tokens = array(
|
||||
$this->drupalCreateContentType(['type' => 'page']);
|
||||
$node = $this->drupalCreateNode(['title' => 'Node title', 'path' => ['alias' => '/node-alias']]);
|
||||
$tokens = [
|
||||
'[current-page:title]' => 'Node title',
|
||||
'[current-page:url]' => $node->url('canonical', array('absolute' => TRUE)),
|
||||
'[current-page:url:absolute]' => $node->url('canonical', array('absolute' => TRUE)),
|
||||
'[current-page:url:relative]' => $node->url(),
|
||||
'[current-page:url]' => $node->toUrl('canonical', ['absolute' => TRUE])->toString(),
|
||||
'[current-page:url:absolute]' => $node->toUrl('canonical', ['absolute' => TRUE])->toString(),
|
||||
'[current-page:url:relative]' => $node->toUrl()->toString(),
|
||||
'[current-page:url:alias]' => '/node-alias',
|
||||
'[current-page:url:args:value:0]' => 'node-alias',
|
||||
'[current-page:url:args:value:1]' => NULL,
|
||||
'[current-page:url:unaliased]' => $node->url('canonical', array('absolute' => TRUE, 'alias' => TRUE)),
|
||||
'[current-page:url:unaliased]' => $node->toUrl('canonical', ['absolute' => TRUE, 'alias' => TRUE])->toString(),
|
||||
'[current-page:url:unaliased:args:value:0]' => 'node',
|
||||
'[current-page:url:unaliased:args:value:1]' => $node->id(),
|
||||
'[current-page:url:unaliased:args:value:2]' => NULL,
|
||||
@@ -60,7 +60,7 @@ class TokenCurrentPageTest extends TokenTestBase {
|
||||
'[current-page:arg:0]' => 'node',
|
||||
'[current-page:arg:1]' => 1,
|
||||
'[current-page:arg:2]' => NULL,
|
||||
);
|
||||
$this->assertPageTokens("/node/{$node->id()}", $tokens, array(), array('url_options' => array('query' => array('foo' => 'bar'))));
|
||||
];
|
||||
$this->assertPageTokens("/node/{$node->id()}", $tokens, [], ['url_options' => ['query' => ['foo' => 'bar']]]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace Drupal\token\Tests;
|
||||
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\file\Entity\File;
|
||||
@@ -41,50 +43,50 @@ class TokenFieldUiTest extends TokenTestBase {
|
||||
]);
|
||||
$node_type->save();
|
||||
|
||||
entity_create('field_storage_config', array(
|
||||
FieldStorageConfig::create([
|
||||
'field_name' => 'field_body',
|
||||
'entity_type' => 'node',
|
||||
'type' => 'text_with_summary',
|
||||
))->save();
|
||||
entity_create('field_config', array(
|
||||
])->save();
|
||||
FieldConfig::create([
|
||||
'field_name' => 'field_body',
|
||||
'label' => 'Body',
|
||||
'entity_type' => 'node',
|
||||
'bundle' => 'article',
|
||||
))->save();
|
||||
entity_create('field_storage_config', array(
|
||||
])->save();
|
||||
FieldStorageConfig::create([
|
||||
'field_name' => 'field_image',
|
||||
'entity_type' => 'node',
|
||||
'type' => 'image',
|
||||
))->save();
|
||||
entity_create('field_config', array(
|
||||
])->save();
|
||||
FieldConfig::create([
|
||||
'field_name' => 'field_image',
|
||||
'label' => 'Image',
|
||||
'entity_type' => 'node',
|
||||
'bundle' => 'article',
|
||||
))->save();
|
||||
entity_create('field_storage_config', array(
|
||||
])->save();
|
||||
FieldStorageConfig::create([
|
||||
'field_name' => 'field_image_2',
|
||||
'entity_type' => 'node',
|
||||
'type' => 'image',
|
||||
))->save();
|
||||
entity_create('field_config', array(
|
||||
])->save();
|
||||
FieldConfig::create([
|
||||
'field_name' => 'field_image_2',
|
||||
'label' => 'Image 2',
|
||||
'entity_type' => 'node',
|
||||
'bundle' => 'article',
|
||||
))->save();
|
||||
entity_create('field_storage_config', array(
|
||||
])->save();
|
||||
FieldStorageConfig::create([
|
||||
'field_name' => 'multivalued_field_image',
|
||||
'entity_type' => 'node',
|
||||
'type' => 'image',
|
||||
))->save();
|
||||
entity_create('field_config', array(
|
||||
])->save();
|
||||
FieldConfig::create([
|
||||
'field_name' => 'multivalued_field_image',
|
||||
'label' => 'Multivalued field image',
|
||||
'entity_type' => 'node',
|
||||
'bundle' => 'article',
|
||||
))->save();
|
||||
])->save();
|
||||
|
||||
entity_get_form_display('node', 'article', 'default')
|
||||
->setComponent('field_body', [
|
||||
|
||||
@@ -35,11 +35,11 @@ class TokenMenuTest extends TokenTestBase {
|
||||
// Make sure we have a body field on the node type.
|
||||
$this->drupalCreateContentType(['type' => 'page']);
|
||||
// Add a menu.
|
||||
$menu = entity_create('menu', array(
|
||||
$menu = Menu::create([
|
||||
'id' => 'main-menu',
|
||||
'label' => 'Main menu',
|
||||
'description' => 'The <em>Main</em> menu is used on many sites to show the major sections of the site, often in a top navigation bar.',
|
||||
));
|
||||
]);
|
||||
$menu->save();
|
||||
|
||||
// Place the menu block.
|
||||
@@ -47,25 +47,25 @@ class TokenMenuTest extends TokenTestBase {
|
||||
|
||||
// Add a root link.
|
||||
/** @var \Drupal\menu_link_content\Plugin\Menu\MenuLinkContent $root_link */
|
||||
$root_link = entity_create('menu_link_content', array(
|
||||
$root_link = MenuLinkContent::create([
|
||||
'link' => ['uri' => 'internal:/admin'],
|
||||
'title' => 'Administration',
|
||||
'menu_name' => 'main-menu',
|
||||
));
|
||||
]);
|
||||
$root_link->save();
|
||||
|
||||
// Add another link with the root link as the parent.
|
||||
/** @var \Drupal\menu_link_content\Plugin\Menu\MenuLinkContent $parent_link */
|
||||
$parent_link = entity_create('menu_link_content', array(
|
||||
$parent_link = MenuLinkContent::create([
|
||||
'link' => ['uri' => 'internal:/admin/config'],
|
||||
'title' => 'Configuration',
|
||||
'menu_name' => 'main-menu',
|
||||
'parent' => $root_link->getPluginId(),
|
||||
));
|
||||
]);
|
||||
$parent_link->save();
|
||||
|
||||
// Test menu link tokens.
|
||||
$tokens = array(
|
||||
$tokens = [
|
||||
'id' => $parent_link->getPluginId(),
|
||||
'title' => 'Configuration',
|
||||
'menu' => 'Main menu',
|
||||
@@ -73,13 +73,13 @@ class TokenMenuTest extends TokenTestBase {
|
||||
'menu:machine-name' => $menu->id(),
|
||||
'menu:description' => 'The <em>Main</em> menu is used on many sites to show the major sections of the site, often in a top navigation bar.',
|
||||
'menu:menu-link-count' => '2',
|
||||
'menu:edit-url' => Url::fromRoute('entity.menu.edit_form', ['menu' => 'main-menu'], array('absolute' => TRUE))->toString(),
|
||||
'url' => Url::fromRoute('system.admin_config', [], array('absolute' => TRUE))->toString(),
|
||||
'url:absolute' => Url::fromRoute('system.admin_config', [], array('absolute' => TRUE))->toString(),
|
||||
'url:relative' => Url::fromRoute('system.admin_config', [], array('absolute' => FALSE))->toString(),
|
||||
'menu:edit-url' => Url::fromRoute('entity.menu.edit_form', ['menu' => 'main-menu'], ['absolute' => TRUE])->toString(),
|
||||
'url' => Url::fromRoute('system.admin_config', [], ['absolute' => TRUE])->toString(),
|
||||
'url:absolute' => Url::fromRoute('system.admin_config', [], ['absolute' => TRUE])->toString(),
|
||||
'url:relative' => Url::fromRoute('system.admin_config', [], ['absolute' => FALSE])->toString(),
|
||||
'url:path' => '/admin/config',
|
||||
'url:alias' => '/admin/config',
|
||||
'edit-url' => Url::fromRoute('entity.menu_link_content.canonical', ['menu_link_content' => $parent_link->id()], array('absolute' => TRUE))->toString(),
|
||||
'edit-url' => Url::fromRoute('entity.menu_link_content.canonical', ['menu_link_content' => $parent_link->id()], ['absolute' => TRUE])->toString(),
|
||||
'parent' => 'Administration',
|
||||
'parent:id' => $root_link->getPluginId(),
|
||||
'parent:title' => 'Administration',
|
||||
@@ -92,32 +92,32 @@ class TokenMenuTest extends TokenTestBase {
|
||||
'root:id' => $root_link->getPluginId(),
|
||||
'root:parent' => NULL,
|
||||
'root:root' => NULL,
|
||||
);
|
||||
$this->assertTokens('menu-link', array('menu-link' => $parent_link), $tokens);
|
||||
];
|
||||
$this->assertTokens('menu-link', ['menu-link' => $parent_link], $tokens);
|
||||
|
||||
// Add a node.
|
||||
$node = $this->drupalCreateNode();
|
||||
|
||||
// Allow main menu for this node type.
|
||||
//$this->config('menu.entity.node.' . $node->getType())->set('available_menus', array('main-menu'))->save();
|
||||
//$this->config('menu.entity.node.' . $node->getType())->set('available_menus', ['main-menu'])->save();
|
||||
|
||||
// Add a node menu link.
|
||||
/** @var \Drupal\menu_link_content\Plugin\Menu\MenuLinkContent $node_link */
|
||||
$node_link = entity_create('menu_link_content', array(
|
||||
'link' => ['uri' =>'entity:node/' . $node->id()],
|
||||
$node_link = MenuLinkContent::create([
|
||||
'link' => ['uri' => 'entity:node/' . $node->id()],
|
||||
'title' => 'Node link',
|
||||
'parent' => $parent_link->getPluginId(),
|
||||
'menu_name' => 'main-menu',
|
||||
));
|
||||
]);
|
||||
$node_link->save();
|
||||
|
||||
// Test [node:menu] tokens.
|
||||
$tokens = array(
|
||||
$tokens = [
|
||||
'menu-link' => 'Node link',
|
||||
'menu-link:id' => $node_link->getPluginId(),
|
||||
'menu-link:title' => 'Node link',
|
||||
'menu-link:menu' => 'Main menu',
|
||||
'menu-link:url' => $node->url('canonical', ['absolute' => TRUE]),
|
||||
'menu-link:url' => $node->toUrl('canonical', ['absolute' => TRUE])->toString(),
|
||||
'menu-link:url:path' => '/node/' . $node->id(),
|
||||
'menu-link:edit-url' => $node_link->url('edit-form', ['absolute' => TRUE]),
|
||||
'menu-link:parent' => 'Configuration',
|
||||
@@ -127,12 +127,12 @@ class TokenMenuTest extends TokenTestBase {
|
||||
'menu-link:parents:keys' => $root_link->getPluginId() . ', ' . $parent_link->getPluginId(),
|
||||
'menu-link:root' => 'Administration',
|
||||
'menu-link:root:id' => $root_link->getPluginId(),
|
||||
);
|
||||
$this->assertTokens('node', array('node' => $node), $tokens);
|
||||
];
|
||||
$this->assertTokens('node', ['node' => $node], $tokens);
|
||||
|
||||
// Reload the node which will not have $node->menu defined and re-test.
|
||||
$loaded_node = Node::load($node->id());
|
||||
$this->assertTokens('node', array('node' => $loaded_node), $tokens);
|
||||
$this->assertTokens('node', ['node' => $loaded_node], $tokens);
|
||||
|
||||
// Regression test for http://drupal.org/node/1317926 to ensure the
|
||||
// original node object is not changed when calling menu_node_prepare().
|
||||
@@ -148,11 +148,11 @@ class TokenMenuTest extends TokenTestBase {
|
||||
'access administration pages',
|
||||
]));
|
||||
// Setup node type menu options.
|
||||
$edit = array(
|
||||
$edit = [
|
||||
'menu_options[main-menu]' => 1,
|
||||
'menu_options[main]' => 1,
|
||||
'menu_parent' => 'main-menu:',
|
||||
);
|
||||
];
|
||||
$this->drupalPostForm('admin/structure/types/manage/page', $edit, t('Save content type'));
|
||||
|
||||
// Use a menu-link token in the body.
|
||||
@@ -186,7 +186,7 @@ class TokenMenuTest extends TokenTestBase {
|
||||
$select = reset($selects);
|
||||
$options = $this->getAllOptions($select);
|
||||
// Filter to items with title containing 'Test preview'.
|
||||
$options = array_filter($options, function(\SimpleXMLElement $item) {
|
||||
$options = array_filter($options, function (\SimpleXMLElement $item) {
|
||||
return strpos((string) $item[0], 'Test preview') !== FALSE;
|
||||
});
|
||||
$this->assertEqual(1, count($options));
|
||||
@@ -195,14 +195,14 @@ class TokenMenuTest extends TokenTestBase {
|
||||
'body[0][value]' => 'This is a [node:menu-link:parent:url:path] token to the menu link parent',
|
||||
'menu[enabled]' => 1,
|
||||
'menu[title]' => 'Child link',
|
||||
'menu[menu_parent]' => 'main-menu:' . $parent_link->getPluginId(),
|
||||
'menu[menu_parent]' => 'main-menu:' . $parent_link->getPluginId(),
|
||||
], t('Save'));
|
||||
$node = $this->drupalGetNodeByTitle('Node menu title parent path test');
|
||||
$this->assertEqual('This is a /admin/config token to the menu link parent', $node->body->value);
|
||||
|
||||
// Now edit the node and update the parent and title.
|
||||
$this->drupalPostForm('node/' . $node->id() . '/edit', [
|
||||
'menu[menu_parent]' => 'main-menu:' . $node_link->getPluginId(),
|
||||
'menu[menu_parent]' => 'main-menu:' . $node_link->getPluginId(),
|
||||
'title[0][value]' => 'Node menu title edit parent path test',
|
||||
'body[0][value]' => 'This is a [node:menu-link:parent:url:path] token to the menu link parent',
|
||||
], t('Save'));
|
||||
@@ -218,7 +218,7 @@ class TokenMenuTest extends TokenTestBase {
|
||||
$select = reset($selects);
|
||||
$options = $this->getAllOptions($select);
|
||||
// Filter to items with title containing 'Test preview'.
|
||||
$options = array_filter($options, function(\SimpleXMLElement $item) {
|
||||
$options = array_filter($options, function (\SimpleXMLElement $item) {
|
||||
return strpos((string) $item[0], 'Child link') !== FALSE;
|
||||
});
|
||||
$this->assertEqual(1, count($options));
|
||||
@@ -238,7 +238,7 @@ class TokenMenuTest extends TokenTestBase {
|
||||
'body[0][value]' => 'This is a [node:menu-link:parent:url:path] token to the menu link parent',
|
||||
'menu[enabled]' => 1,
|
||||
'menu[title]' => 'Child link',
|
||||
'menu[menu_parent]' => 'main-menu:' . $parent_link->getPluginId(),
|
||||
'menu[menu_parent]' => 'main-menu:' . $parent_link->getPluginId(),
|
||||
], t('Save'));
|
||||
$node = $this->drupalGetNodeByTitle('Node menu adding menu later test', TRUE);
|
||||
$this->assertEqual('This is a /admin/config token to the menu link parent', $node->body->value);
|
||||
@@ -264,14 +264,14 @@ class TokenMenuTest extends TokenTestBase {
|
||||
$this->assertText('page ' . $node_title . ' has been created');
|
||||
$node = $this->drupalGetNodeByTitle($node_title);
|
||||
|
||||
$menu_ui_link1 = entity_create('menu_link_content', [
|
||||
$menu_ui_link1 = MenuLinkContent::create([
|
||||
'link' => ['uri' => 'entity:node/' . $node->id()],
|
||||
'title' => 'menu link 1 provided by menu ui',
|
||||
'menu_name' => 'main-menu',
|
||||
]);
|
||||
$menu_ui_link1->save();
|
||||
|
||||
$menu_ui_link2 = entity_create('menu_link_content', [
|
||||
$menu_ui_link2 = MenuLinkContent::create([
|
||||
'link' => ['uri' => 'entity:node/' . $node->id()],
|
||||
'title' => 'menu link 2 provided by menu ui',
|
||||
'menu_name' => 'main-menu',
|
||||
@@ -306,7 +306,7 @@ class TokenMenuTest extends TokenTestBase {
|
||||
]);
|
||||
$node_type->save();
|
||||
|
||||
$permissions = array(
|
||||
$permissions = [
|
||||
'access administration pages',
|
||||
'administer content translation',
|
||||
'administer content types',
|
||||
@@ -316,18 +316,18 @@ class TokenMenuTest extends TokenTestBase {
|
||||
'edit any article content',
|
||||
'translate any entity',
|
||||
'administer menu',
|
||||
);
|
||||
];
|
||||
$this->drupalLogin($this->drupalCreateUser($permissions));
|
||||
|
||||
// Enable translation for articles and menu links.
|
||||
$this->drupalGet('admin/config/regional/content-language');
|
||||
$edit = array(
|
||||
$edit = [
|
||||
'entity_types[node]' => TRUE,
|
||||
'entity_types[menu_link_content]' => TRUE,
|
||||
'settings[node][article][translatable]' => TRUE,
|
||||
'settings[node][article][fields][title]' => TRUE,
|
||||
'settings[menu_link_content][menu_link_content][translatable]' => TRUE,
|
||||
);
|
||||
];
|
||||
$this->drupalPostForm(NULL, $edit, t('Save configuration'));
|
||||
$this->assertText('Settings successfully updated.');
|
||||
|
||||
@@ -411,10 +411,10 @@ class TokenMenuTest extends TokenTestBase {
|
||||
// - parent
|
||||
// - child-1
|
||||
// - child-1-1
|
||||
Menu::create(array(
|
||||
Menu::create([
|
||||
'id' => 'menu_test',
|
||||
'label' => 'Test menu',
|
||||
))->save();
|
||||
])->save();
|
||||
$base_options = [
|
||||
'provider' => 'menu_test',
|
||||
'menu_name' => 'menu_test',
|
||||
|
||||
@@ -16,6 +16,6 @@ abstract class TokenTestBase extends WebTestBase {
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('path', 'token', 'token_module_test');
|
||||
public static $modules = ['path', 'token', 'token_module_test'];
|
||||
|
||||
}
|
||||
|
||||
@@ -11,57 +11,57 @@ use Drupal\Core\Render\BubbleableMetadata;
|
||||
*/
|
||||
trait TokenTestTrait {
|
||||
|
||||
function assertToken($type, array $data, $token, $expected, array $options = array()) {
|
||||
return $this->assertTokens($type, $data, array($token => $expected), $options);
|
||||
function assertToken($type, array $data, $token, $expected, array $options = []) {
|
||||
return $this->assertTokens($type, $data, [$token => $expected], $options);
|
||||
}
|
||||
|
||||
function assertTokens($type, array $data, array $tokens, array $options = array()) {
|
||||
function assertTokens($type, array $data, array $tokens, array $options = []) {
|
||||
$input = $this->mapTokenNames($type, array_keys($tokens));
|
||||
$bubbleable_metadata = new BubbleableMetadata();
|
||||
$replacements = \Drupal::token()->generate($type, $input, $data, $options, $bubbleable_metadata);
|
||||
foreach ($tokens as $name => $expected) {
|
||||
$token = $input[$name];
|
||||
if (!isset($expected)) {
|
||||
$this->assertTrue(!isset($replacements[$token]), t("Token value for @token was not generated.", array('@type' => $type, '@token' => $token)));
|
||||
$this->assertTrue(!isset($replacements[$token]), t("Token value for @token was not generated.", ['@type' => $type, '@token' => $token]));
|
||||
}
|
||||
elseif (!isset($replacements[$token])) {
|
||||
$this->fail(t("Token value for @token was not generated.", array('@type' => $type, '@token' => $token)));
|
||||
$this->fail(t("Token value for @token was not generated.", ['@type' => $type, '@token' => $token]));
|
||||
}
|
||||
elseif (!empty($options['regex'])) {
|
||||
$this->assertTrue(preg_match('/^' . $expected . '$/', $replacements[$token]), t("Token value for @token was '@actual', matching regular expression pattern '@expected'.", array('@type' => $type, '@token' => $token, '@actual' => $replacements[$token], '@expected' => $expected)));
|
||||
$this->assertTrue(preg_match('/^' . $expected . '$/', $replacements[$token]), t("Token value for @token was '@actual', matching regular expression pattern '@expected'.", ['@type' => $type, '@token' => $token, '@actual' => $replacements[$token], '@expected' => $expected]));
|
||||
}
|
||||
else {
|
||||
$this->assertEqual($replacements[$token], $expected, t("Token value for @token was '@actual', expected value '@expected'.", array('@type' => $type, '@token' => $token, '@actual' => $replacements[$token], '@expected' => $expected)));
|
||||
$this->assertEqual($replacements[$token], $expected, t("Token value for @token was '@actual', expected value '@expected'.", ['@type' => $type, '@token' => $token, '@actual' => $replacements[$token], '@expected' => $expected]));
|
||||
}
|
||||
}
|
||||
|
||||
return $replacements;
|
||||
}
|
||||
|
||||
function mapTokenNames($type, array $tokens = array()) {
|
||||
$return = array();
|
||||
function mapTokenNames($type, array $tokens = []) {
|
||||
$return = [];
|
||||
foreach ($tokens as $token) {
|
||||
$return[$token] = "[$type:$token]";
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
function assertNoTokens($type, array $data, array $tokens, array $options = array()) {
|
||||
function assertNoTokens($type, array $data, array $tokens, array $options = []) {
|
||||
$input = $this->mapTokenNames($type, $tokens);
|
||||
$bubbleable_metadata = new BubbleableMetadata();
|
||||
$replacements = \Drupal::token()->generate($type, $input, $data, $options, $bubbleable_metadata);
|
||||
foreach ($tokens as $name) {
|
||||
$token = $input[$name];
|
||||
$this->assertTrue(!isset($replacements[$token]), t("Token value for @token was not generated.", array('@type' => $type, '@token' => $token)));
|
||||
$this->assertTrue(!isset($replacements[$token]), t("Token value for @token was not generated.", ['@type' => $type, '@token' => $token]));
|
||||
}
|
||||
}
|
||||
|
||||
function saveAlias($source, $alias, $language = Language::LANGCODE_NOT_SPECIFIED) {
|
||||
$alias = array(
|
||||
$alias = [
|
||||
'source' => $source,
|
||||
'alias' => $alias,
|
||||
'language' => $language,
|
||||
);
|
||||
];
|
||||
\Drupal::service('path.alias_storage')->save($alias['source'], $alias['alias']);
|
||||
return $alias;
|
||||
}
|
||||
@@ -74,22 +74,22 @@ trait TokenTestTrait {
|
||||
/**
|
||||
* Make a page request and test for token generation.
|
||||
*/
|
||||
function assertPageTokens($url, array $tokens, array $data = array(), array $options = array()) {
|
||||
function assertPageTokens($url, array $tokens, array $data = [], array $options = []) {
|
||||
if (empty($tokens)) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
$token_page_tokens = array(
|
||||
$token_page_tokens = [
|
||||
'tokens' => $tokens,
|
||||
'data' => $data,
|
||||
'options' => $options,
|
||||
);
|
||||
];
|
||||
\Drupal::state()->set('token_page_tokens', $token_page_tokens);
|
||||
|
||||
$options += array('url_options' => array());
|
||||
$options += ['url_options' => []];
|
||||
$this->drupalGet($url, $options['url_options']);
|
||||
$this->refreshVariables();
|
||||
$result = \Drupal::state()->get('token_page_tokens', array());
|
||||
$result = \Drupal::state()->get('token_page_tokens', []);
|
||||
|
||||
if (!isset($result['values']) || !is_array($result['values'])) {
|
||||
return $this->fail('Failed to generate tokens.');
|
||||
@@ -97,13 +97,13 @@ trait TokenTestTrait {
|
||||
|
||||
foreach ($tokens as $token => $expected) {
|
||||
if (!isset($expected)) {
|
||||
$this->assertTrue(!isset($result['values'][$token]) || $result['values'][$token] === $token, t("Token value for @token was not generated.", array('@token' => $token)));
|
||||
$this->assertTrue(!isset($result['values'][$token]) || $result['values'][$token] === $token, t("Token value for @token was not generated.", ['@token' => $token]));
|
||||
}
|
||||
elseif (!isset($result['values'][$token])) {
|
||||
$this->fail(t('Failed to generate token @token.', array('@token' => $token)));
|
||||
$this->fail(t('Failed to generate token @token.', ['@token' => $token]));
|
||||
}
|
||||
else {
|
||||
$this->assertIdentical($result['values'][$token], (string) $expected, t("Token value for @token was '@actual', expected value '@expected'.", array('@token' => $token, '@actual' => $result['values'][$token], '@expected' => $expected)));
|
||||
$this->assertIdentical($result['values'][$token], (string) $expected, t("Token value for @token was '@actual', expected value '@expected'.", ['@token' => $token, '@actual' => $result['values'][$token], '@expected' => $expected]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ class TokenURLTest extends TokenTestBase {
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('node');
|
||||
public static $modules = ['node'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
@@ -27,25 +27,25 @@ class TokenURLTest extends TokenTestBase {
|
||||
}
|
||||
|
||||
function testURLTokens() {
|
||||
$url = new Url('entity.node.canonical', array('node' => 1));
|
||||
$tokens = array(
|
||||
$url = new Url('entity.node.canonical', ['node' => 1]);
|
||||
$tokens = [
|
||||
'absolute' => $url->setAbsolute()->toString(),
|
||||
'relative' => $url->setAbsolute(FALSE)->toString(),
|
||||
'path' => '/first-node',
|
||||
'brief' => preg_replace(array('!^https?://!', '!/$!'), '', $url->setAbsolute()->toString()),
|
||||
'brief' => preg_replace(['!^https?://!', '!/$!'], '', $url->setAbsolute()->toString()),
|
||||
'args:value:0' => 'first-node',
|
||||
'args:value:1' => NULL,
|
||||
'args:value:N' => NULL,
|
||||
'unaliased' => $url->setAbsolute()->setOption('alias', TRUE)->toString(),
|
||||
'unaliased:relative' => $url->setAbsolute(FALSE)->setOption('alias', TRUE)->toString(),
|
||||
'unaliased:path' => '/node/1',
|
||||
'unaliased:brief' => preg_replace(array('!^https?://!', '!/$!'), '', $url->setAbsolute()->setOption('alias', TRUE)->toString()),
|
||||
'unaliased:brief' => preg_replace(['!^https?://!', '!/$!'], '', $url->setAbsolute()->setOption('alias', TRUE)->toString()),
|
||||
'unaliased:args:value:0' => 'node',
|
||||
'unaliased:args:value:1' => '1',
|
||||
'unaliased:args:value:2' => NULL,
|
||||
// Deprecated tokens.
|
||||
'alias' => '/first-node',
|
||||
);
|
||||
$this->assertTokens('url', array('url' => new Url('entity.node.canonical', array('node' => 1))), $tokens);
|
||||
];
|
||||
$this->assertTokens('url', ['url' => new Url('entity.node.canonical', ['node' => 1])], $tokens);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Drupal\token\Tests;
|
||||
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\Session\AnonymousUserSession;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
|
||||
@@ -24,7 +25,7 @@ class TokenUserTest extends TokenTestBase {
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('token_user_picture');
|
||||
public static $modules = ['token_user_picture'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
@@ -32,10 +33,17 @@ class TokenUserTest extends TokenTestBase {
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->account = $this->drupalCreateUser(['administer users', 'administer account settings', 'access content']);
|
||||
$this->account = $this->drupalCreateUser([
|
||||
'administer users',
|
||||
'administer account settings',
|
||||
'access content',
|
||||
]);
|
||||
$this->drupalLogin($this->account);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the user releated tokens.
|
||||
*/
|
||||
public function testUserTokens() {
|
||||
// Enable user pictures.
|
||||
\Drupal::state()->set('user_pictures', 1);
|
||||
@@ -49,7 +57,7 @@ class TokenUserTest extends TokenTestBase {
|
||||
|
||||
// Add a user picture to the account.
|
||||
$image = current($this->drupalGetTestFiles('image'));
|
||||
$edit = array('files[user_picture_0]' => drupal_realpath($image->uri));
|
||||
$edit = ['files[user_picture_0]' => \Drupal::service('file_system')->realpath($image->uri)];
|
||||
$this->drupalPostForm('user/' . $this->account->id() . '/edit', $edit, t('Save'));
|
||||
|
||||
$storage = \Drupal::entityTypeManager()->getStorage('user');
|
||||
@@ -65,14 +73,14 @@ class TokenUserTest extends TokenTestBase {
|
||||
];
|
||||
/** @var \Drupal\Core\Render\RendererInterface $renderer */
|
||||
$renderer = \Drupal::service('renderer');
|
||||
$user_tokens = array(
|
||||
$user_tokens = [
|
||||
'picture' => $renderer->renderPlain($picture),
|
||||
'picture:fid' => $this->account->user_picture->target_id,
|
||||
'picture:size-raw' => 125,
|
||||
'ip-address' => NULL,
|
||||
'roles' => implode(', ', $this->account->getRoles()),
|
||||
);
|
||||
$this->assertTokens('user', array('user' => $this->account), $user_tokens);
|
||||
];
|
||||
$this->assertTokens('user', ['user' => $this->account], $user_tokens);
|
||||
|
||||
// Remove the simpletest-created user role.
|
||||
$roles = $this->account->getRoles();
|
||||
@@ -84,29 +92,32 @@ class TokenUserTest extends TokenTestBase {
|
||||
$storage->resetCache();
|
||||
$this->account = $storage->load($this->account->id());
|
||||
|
||||
$user_tokens = array(
|
||||
$user_tokens = [
|
||||
'picture' => NULL,
|
||||
'picture:fid' => NULL,
|
||||
'ip-address' => NULL,
|
||||
'roles' => 'authenticated',
|
||||
'roles:keys' => (string) DRUPAL_AUTHENTICATED_RID,
|
||||
);
|
||||
$this->assertTokens('user', array('user' => $this->account), $user_tokens);
|
||||
'roles:keys' => AccountInterface::AUTHENTICATED_ROLE,
|
||||
];
|
||||
$this->assertTokens('user', ['user' => $this->account], $user_tokens);
|
||||
|
||||
// The ip address token should work for the current user token type.
|
||||
$tokens = array(
|
||||
$tokens = [
|
||||
'ip-address' => \Drupal::request()->getClientIp(),
|
||||
);
|
||||
$this->assertTokens('current-user', array(), $tokens);
|
||||
];
|
||||
$this->assertTokens('current-user', [], $tokens);
|
||||
|
||||
$anonymous = new AnonymousUserSession();
|
||||
$tokens = array(
|
||||
$tokens = [
|
||||
'roles' => 'anonymous',
|
||||
'roles:keys' => (string) DRUPAL_ANONYMOUS_RID,
|
||||
);
|
||||
$this->assertTokens('user', array('user' => $anonymous), $tokens);
|
||||
'roles:keys' => AccountInterface::ANONYMOUS_ROLE,
|
||||
];
|
||||
$this->assertTokens('user', ['user' => $anonymous], $tokens);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test user account settings.
|
||||
*/
|
||||
public function testUserAccountSettings() {
|
||||
$this->drupalGet('admin/config/people/accounts');
|
||||
$this->assertText('The list of available tokens that can be used in e-mails is provided below.');
|
||||
|
||||
@@ -137,7 +137,7 @@ class TreeTest extends TokenTestBase {
|
||||
protected function getTokenTreeUrl($options = []) {
|
||||
$this->drupalGet('token_module_test/browse');
|
||||
$this->assertTitle('Available Tokens | Drupal');
|
||||
$links = $this->xpath('//a[contains(@href, :href)]/@href', array(':href' => 'token/tree'));
|
||||
$links = $this->xpath('//a[contains(@href, :href)]/@href', [':href' => 'token/tree']);
|
||||
$link = $this->getAbsoluteUrl((string) current($links));
|
||||
if (!empty($options)) {
|
||||
$options = Json::encode($options);
|
||||
|
||||
@@ -65,9 +65,9 @@ class Token extends TokenBase implements TokenInterface {
|
||||
}
|
||||
|
||||
$this->tokenInfo = $token_info;
|
||||
$this->cache->set($cache_id, $this->tokenInfo, CacheBackendInterface::CACHE_PERMANENT, array(
|
||||
$this->cache->set($cache_id, $this->tokenInfo, CacheBackendInterface::CACHE_PERMANENT, [
|
||||
static::TOKEN_INFO_CACHE_TAG,
|
||||
));
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ class Token extends TokenBase implements TokenInterface {
|
||||
*/
|
||||
function getInvalidTokens($type, $tokens) {
|
||||
$token_info = $this->getInfo();
|
||||
$invalid_tokens = array();
|
||||
$invalid_tokens = [];
|
||||
|
||||
foreach ($tokens as $token => $full_token) {
|
||||
if (isset($token_info['tokens'][$type][$token])) {
|
||||
@@ -162,7 +162,7 @@ class Token extends TokenBase implements TokenInterface {
|
||||
}
|
||||
else {
|
||||
// Recursively check the chained tokens.
|
||||
$sub_tokens = $this->findWithPrefix(array($token => $full_token), $parts[0]);
|
||||
$sub_tokens = $this->findWithPrefix([$token => $full_token], $parts[0]);
|
||||
$invalid_tokens = array_merge($invalid_tokens, $this->getInvalidTokens($sub_token_info['type'], $sub_tokens));
|
||||
}
|
||||
}
|
||||
@@ -184,7 +184,7 @@ class Token extends TokenBase implements TokenInterface {
|
||||
$valid_types = array_merge($valid_types, $this->getGlobalTokenTypes());
|
||||
}
|
||||
|
||||
$invalid_tokens = array();
|
||||
$invalid_tokens = [];
|
||||
$value_tokens = is_string($value) ? $this->scan($value) : $value;
|
||||
|
||||
foreach ($value_tokens as $type => $tokens) {
|
||||
|
||||
@@ -61,12 +61,12 @@ class TreeBuilder implements TreeBuilderInterface {
|
||||
$token_types = array_merge($token_types, $this->tokenService->getGlobalTokenTypes());
|
||||
}
|
||||
|
||||
$element = array(
|
||||
/*'#cache' => array(
|
||||
'cid' => 'tree-rendered:' . hash('sha256', serialize(array('token_types' => $token_types, 'global_types' => NULL) + $variables)),
|
||||
'tags' => array(Token::TOKEN_INFO_CACHE_TAG),
|
||||
),*/
|
||||
);
|
||||
$element = [
|
||||
/*'#cache' => [
|
||||
'cid' => 'tree-rendered:' . hash('sha256', serialize(['token_types' => $token_types, 'global_types' => NULL] + $variables)),
|
||||
'tags' => [Token::TOKEN_INFO_CACHE_TAG],
|
||||
],*/
|
||||
];
|
||||
|
||||
// @todo Find a way to use the render cache for this.
|
||||
/*if ($cached_output = token_render_cache_get($element)) {
|
||||
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- user
|
||||
id: token_views_test
|
||||
label: token_views_test
|
||||
module: views
|
||||
description: ''
|
||||
tag: ''
|
||||
base_table: users_field_data
|
||||
base_field: uid
|
||||
core: 8.x
|
||||
display:
|
||||
default:
|
||||
display_plugin: default
|
||||
id: default
|
||||
display_title: Master
|
||||
position: 0
|
||||
display_options:
|
||||
access:
|
||||
type: none
|
||||
options: { }
|
||||
cache:
|
||||
type: tag
|
||||
options: { }
|
||||
query:
|
||||
type: views_query
|
||||
options:
|
||||
disable_sql_rewrite: false
|
||||
distinct: false
|
||||
replica: false
|
||||
query_comment: ''
|
||||
query_tags: { }
|
||||
exposed_form:
|
||||
type: basic
|
||||
options:
|
||||
submit_button: Apply
|
||||
reset_button: false
|
||||
reset_button_label: Reset
|
||||
exposed_sorts_label: 'Sort by'
|
||||
expose_sort_order: true
|
||||
sort_asc_label: Asc
|
||||
sort_desc_label: Desc
|
||||
pager:
|
||||
type: some
|
||||
options:
|
||||
items_per_page: 5
|
||||
offset: 0
|
||||
style:
|
||||
type: default
|
||||
row:
|
||||
type: fields
|
||||
options:
|
||||
default_field_elements: true
|
||||
inline: { }
|
||||
separator: ''
|
||||
hide_empty: false
|
||||
fields:
|
||||
name:
|
||||
id: name
|
||||
table: users_field_data
|
||||
field: name
|
||||
entity_type: user
|
||||
entity_field: name
|
||||
label: ''
|
||||
alter:
|
||||
alter_text: false
|
||||
make_link: false
|
||||
absolute: false
|
||||
trim: false
|
||||
word_boundary: false
|
||||
ellipsis: false
|
||||
strip_tags: false
|
||||
html: false
|
||||
hide_empty: false
|
||||
empty_zero: false
|
||||
plugin_id: field
|
||||
relationship: none
|
||||
group_type: group
|
||||
admin_label: ''
|
||||
exclude: false
|
||||
element_type: ''
|
||||
element_class: ''
|
||||
element_label_type: ''
|
||||
element_label_class: ''
|
||||
element_label_colon: true
|
||||
element_wrapper_type: ''
|
||||
element_wrapper_class: ''
|
||||
element_default_classes: true
|
||||
empty: ''
|
||||
hide_alter_empty: true
|
||||
click_sort_column: value
|
||||
type: user_name
|
||||
settings: { }
|
||||
group_column: value
|
||||
group_columns: { }
|
||||
group_rows: true
|
||||
delta_limit: 0
|
||||
delta_offset: 0
|
||||
delta_reversed: false
|
||||
delta_first_last: false
|
||||
multi_type: separator
|
||||
separator: ', '
|
||||
field_api_classes: false
|
||||
filters: { }
|
||||
sorts: { }
|
||||
title: token_views_test
|
||||
header: { }
|
||||
footer: { }
|
||||
empty: { }
|
||||
relationships: { }
|
||||
arguments: { }
|
||||
display_extenders: { }
|
||||
filter_groups:
|
||||
operator: AND
|
||||
groups: { }
|
||||
cache_metadata:
|
||||
max-age: -1
|
||||
contexts:
|
||||
- 'languages:language_content'
|
||||
- 'languages:language_interface'
|
||||
tags: { }
|
||||
block_1:
|
||||
display_plugin: block
|
||||
id: block_1
|
||||
display_title: Block
|
||||
position: 1
|
||||
display_options:
|
||||
display_extenders: { }
|
||||
+3
-3
@@ -5,8 +5,8 @@ package: Testing
|
||||
# core: 8.x
|
||||
hidden: TRUE
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-12-20
|
||||
version: '8.x-1.1'
|
||||
# Information added by Drupal.org packaging script on 2018-09-08
|
||||
version: '8.x-1.4'
|
||||
core: '8.x'
|
||||
project: 'token'
|
||||
datestamp: 1513810387
|
||||
datestamp: 1536408485
|
||||
|
||||
+3
-2
@@ -4,14 +4,15 @@
|
||||
* @file
|
||||
* Helper module for token tests.
|
||||
*/
|
||||
|
||||
use Drupal\node\NodeInterface;
|
||||
|
||||
/**
|
||||
* Implements hook_page_attachments().
|
||||
*/
|
||||
function token_module_test_page_attachments() {
|
||||
if ($debug = \Drupal::state()->get('token_page_tokens', array())) {
|
||||
$debug += array('tokens' => array(), 'data' => array(), 'options' => array());
|
||||
if ($debug = \Drupal::state()->get('token_page_tokens', [])) {
|
||||
$debug += ['tokens' => [], 'data' => [], 'options' => []];
|
||||
foreach (array_keys($debug['tokens']) as $token) {
|
||||
$debug['values'][$token] = \Drupal::token()->replace($token, $debug['data'], $debug['options']);
|
||||
}
|
||||
|
||||
+2
-2
@@ -4,10 +4,10 @@
|
||||
* Implements hook_token_info()
|
||||
*/
|
||||
function token_module_test_token_info() {
|
||||
$info['tokens']['node']['colons:in:name'] = array(
|
||||
$info['tokens']['node']['colons:in:name'] = [
|
||||
'name' => t('A test token with colons in the name'),
|
||||
'description' => NULL,
|
||||
);
|
||||
];
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
+3
-3
@@ -7,8 +7,8 @@ hidden: TRUE
|
||||
dependencies:
|
||||
- image
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-12-20
|
||||
version: '8.x-1.1'
|
||||
# Information added by Drupal.org packaging script on 2018-09-08
|
||||
version: '8.x-1.4'
|
||||
core: '8.x'
|
||||
project: 'token'
|
||||
datestamp: 1513810387
|
||||
datestamp: 1536408485
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\token\Functional;
|
||||
|
||||
use Drupal\block\Entity\Block;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\Tests\system\Functional\Cache\AssertPageCacheContextsAndTagsTrait;
|
||||
|
||||
/**
|
||||
* Tests URL tokens.
|
||||
*
|
||||
* @group token
|
||||
*/
|
||||
class UrlTest extends BrowserTestBase {
|
||||
|
||||
use AssertPageCacheContextsAndTagsTrait;
|
||||
|
||||
/**
|
||||
* The first testing node.
|
||||
*
|
||||
* @var \Drupal\node\NodeInterface
|
||||
*/
|
||||
protected $node1;
|
||||
|
||||
/**
|
||||
* The second testing node.
|
||||
*
|
||||
* @var \Drupal\node\NodeInterface
|
||||
*/
|
||||
protected $node2;
|
||||
|
||||
/**
|
||||
* Modules to install.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
public static $modules = ['node', 'token', 'block'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$node_type = NodeType::create(['type' => 'article', 'name' => 'Article']);
|
||||
$node_type->save();
|
||||
|
||||
$this->node1 = Node::create([
|
||||
'type' => 'article',
|
||||
'title' => 'Test Node 1',
|
||||
]);
|
||||
$this->node1->save();
|
||||
|
||||
$this->node2 = Node::create([
|
||||
'type' => 'article',
|
||||
'title' => 'Test Node 2',
|
||||
]);
|
||||
$this->node2->save();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a block with token for title and tests cache contexts.
|
||||
*
|
||||
* @throws \Behat\Mink\Exception\ElementHtmlException
|
||||
* @throws \Drupal\Core\Entity\EntityStorageException
|
||||
*/
|
||||
public function testBlockUrlTokenReplacement() {
|
||||
|
||||
$node1_url = $this->node1->toUrl();
|
||||
$node2_url = $this->node2->toUrl();
|
||||
|
||||
// Using a @dataprovider causes repeated database installations and takes a
|
||||
// very long time.
|
||||
$tests = [];
|
||||
$tests[] = [
|
||||
'token' => 'prefix_[current-page:url:path]_suffix',
|
||||
'expected1' => 'prefix_/' . $node1_url->getInternalPath() . '_suffix',
|
||||
'expected2' => 'prefix_/' . $node2_url->getInternalPath() . '_suffix',
|
||||
// A path can only be generated from a routed path.
|
||||
'expected3' => 'prefix_/_suffix',
|
||||
];
|
||||
$tests[] = [
|
||||
'token' => 'prefix_[current-page:url]_suffix',
|
||||
'expected1' => 'prefix_' . $node1_url->setAbsolute()->toString() . '_suffix',
|
||||
'expected2' => 'prefix_' . $node2_url->setAbsolute()->toString() . '_suffix',
|
||||
'expected3' => 'prefix_' . $this->getAbsoluteUrl('does-not-exist') . '_suffix',
|
||||
];
|
||||
|
||||
// Place a standard block and use a token in the label.
|
||||
$edit = [
|
||||
'id' => 'token_url_test_block',
|
||||
'label' => 'label',
|
||||
'label_display' => TRUE,
|
||||
];
|
||||
$this->placeBlock('system_powered_by_block', $edit);
|
||||
$block = Block::load('token_url_test_block');
|
||||
|
||||
$assert_session = $this->assertSession();
|
||||
|
||||
foreach ($tests as $test) {
|
||||
// Set the block label.
|
||||
$block->getPlugin()->setConfigurationValue('label', $test['token']);
|
||||
$block->save();
|
||||
|
||||
// Go to the first node page and test that the token is correct.
|
||||
$this->drupalGet($node1_url);
|
||||
$assert_session->elementContains('css', '#block-token-url-test-block', $test['expected1']);
|
||||
|
||||
// Go to the second node page and check that the block title has changed.
|
||||
$this->drupalGet($node2_url);
|
||||
$assert_session->elementContains('css', '#block-token-url-test-block', $test['expected2']);
|
||||
|
||||
// Test the current page url on a 404 page.
|
||||
$this->drupalGet('does-not-exist');
|
||||
$assert_session->statusCodeEquals(404);
|
||||
$assert_session->elementContains('css', '#block-token-url-test-block', $test['expected3']);
|
||||
}
|
||||
|
||||
|
||||
// Can't do this test in the for loop above, it's too different.
|
||||
$block->getPlugin()->setConfigurationValue('label', 'prefix_[current-page:query:unicorns]_suffix');
|
||||
$block->save();
|
||||
|
||||
// Test the parameter token.
|
||||
$this->drupalGet($node1_url->setOption('query', ['unicorns' => 'fluffy']));
|
||||
$this->assertCacheContext('url.query_args');
|
||||
$assert_session->elementContains('css', '#block-token-url-test-block', 'prefix_fluffy_suffix');
|
||||
|
||||
// Change the parameter on the same page.
|
||||
$this->drupalGet($node1_url->setOption('query', ['unicorns' => 'dead']));
|
||||
$assert_session->elementContains('css', '#block-token-url-test-block', 'prefix_dead_suffix');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,8 +11,8 @@ class ArrayTest extends KernelTestBase {
|
||||
|
||||
function testArrayTokens() {
|
||||
// Test a simple array.
|
||||
$array = array(0 => 'a', 1 => 'b', 2 => 'c', 4 => 'd');
|
||||
$tokens = array(
|
||||
$array = [0 => 'a', 1 => 'b', 2 => 'c', 4 => 'd'];
|
||||
$tokens = [
|
||||
'first' => 'a',
|
||||
'last' => 'd',
|
||||
'value:0' => 'a',
|
||||
@@ -27,19 +27,19 @@ class ArrayTest extends KernelTestBase {
|
||||
'join' => 'abcd',
|
||||
'join:, ' => 'a, b, c, d',
|
||||
'join: ' => 'a b c d',
|
||||
);
|
||||
$this->assertTokens('array', array('array' => $array), $tokens);
|
||||
];
|
||||
$this->assertTokens('array', ['array' => $array], $tokens);
|
||||
|
||||
// Test a mixed simple and render array.
|
||||
// 2 => c, 0 => a, 4 => d, 1 => b
|
||||
$array = array(
|
||||
$array = [
|
||||
'#property' => 'value',
|
||||
0 => 'a',
|
||||
1 => array('#markup' => 'b', '#weight' => 0.01),
|
||||
2 => array('#markup' => 'c', '#weight' => -10),
|
||||
4 => array('#markup' => 'd', '#weight' => 0),
|
||||
);
|
||||
$tokens = array(
|
||||
1 => ['#markup' => 'b', '#weight' => 0.01],
|
||||
2 => ['#markup' => 'c', '#weight' => -10],
|
||||
4 => ['#markup' => 'd', '#weight' => 0],
|
||||
];
|
||||
$tokens = [
|
||||
'first' => 'c',
|
||||
'last' => 'b',
|
||||
'value:0' => 'a',
|
||||
@@ -54,7 +54,8 @@ class ArrayTest extends KernelTestBase {
|
||||
'join' => 'cadb',
|
||||
'join:, ' => 'c, a, d, b',
|
||||
'join: ' => 'c a d b',
|
||||
);
|
||||
$this->assertTokens('array', array('array' => $array), $tokens);
|
||||
];
|
||||
$this->assertTokens('array', ['array' => $array], $tokens);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,9 +27,9 @@ class BookTest extends KernelTestBase {
|
||||
|
||||
$this->installEntitySchema('user');
|
||||
$this->installEntitySchema('node');
|
||||
$this->installSchema('book', array('book'));
|
||||
$this->installSchema('node', array('node_access'));
|
||||
$this->installConfig(array('node', 'book', 'field'));
|
||||
$this->installSchema('book', ['book']);
|
||||
$this->installSchema('node', ['node_access']);
|
||||
$this->installConfig(['node', 'book', 'field']);
|
||||
}
|
||||
|
||||
function testBookTokens() {
|
||||
@@ -63,12 +63,12 @@ class BookTest extends KernelTestBase {
|
||||
'book:root' => $book_title,
|
||||
'book:root:nid' => $book->id(),
|
||||
'book:root:title' => $book_title,
|
||||
'book:root:url' => Url::fromRoute('entity.node.canonical', ['node' => $book->id()], array('absolute' => TRUE))->toString(),
|
||||
'book:root:url' => Url::fromRoute('entity.node.canonical', ['node' => $book->id()], ['absolute' => TRUE])->toString(),
|
||||
'book:root:content-type' => 'Book page',
|
||||
'book:parent' => null,
|
||||
'book:parents' => null,
|
||||
];
|
||||
$this->assertTokens('node', array('node' => $book), $tokens);
|
||||
$this->assertTokens('node', ['node' => $book], $tokens);
|
||||
|
||||
$tokens = [
|
||||
'nid' => $page1->id(),
|
||||
@@ -77,15 +77,15 @@ class BookTest extends KernelTestBase {
|
||||
'book:root' => $book_title,
|
||||
'book:root:nid' => $book->id(),
|
||||
'book:root:title' => $book_title,
|
||||
'book:root:url' => Url::fromRoute('entity.node.canonical', ['node' => $book->id()], array('absolute' => TRUE))->toString(),
|
||||
'book:root:url' => Url::fromRoute('entity.node.canonical', ['node' => $book->id()], ['absolute' => TRUE])->toString(),
|
||||
'book:root:content-type' => 'Book page',
|
||||
'book:parent:nid' => $book->id(),
|
||||
'book:parent:title' => $book_title,
|
||||
'book:parent:url' => Url::fromRoute('entity.node.canonical', ['node' => $book->id()], array('absolute' => TRUE))->toString(),
|
||||
'book:parent:url' => Url::fromRoute('entity.node.canonical', ['node' => $book->id()], ['absolute' => TRUE])->toString(),
|
||||
'book:parents:count' => 1,
|
||||
'book:parents:join:/' => $book_title,
|
||||
];
|
||||
$this->assertTokens('node', array('node' => $page1), $tokens);
|
||||
$this->assertTokens('node', ['node' => $page1], $tokens);
|
||||
|
||||
$tokens = [
|
||||
'nid' => $page2->id(),
|
||||
@@ -94,14 +94,15 @@ class BookTest extends KernelTestBase {
|
||||
'book:root' => $book_title,
|
||||
'book:root:nid' => $book->id(),
|
||||
'book:root:title' => $book_title,
|
||||
'book:root:url' => Url::fromRoute('entity.node.canonical', ['node' => $book->id()], array('absolute' => TRUE))->toString(),
|
||||
'book:root:url' => Url::fromRoute('entity.node.canonical', ['node' => $book->id()], ['absolute' => TRUE])->toString(),
|
||||
'book:root:content-type' => 'Book page',
|
||||
'book:parent:nid' => $page1->id(),
|
||||
'book:parent:title' => $page1->getTitle(),
|
||||
'book:parent:url' => Url::fromRoute('entity.node.canonical', ['node' => $page1->id()], array('absolute' => TRUE))->toString(),
|
||||
'book:parent:url' => Url::fromRoute('entity.node.canonical', ['node' => $page1->id()], ['absolute' => TRUE])->toString(),
|
||||
'book:parents:count' => 2,
|
||||
'book:parents:join:/' => $book_title . '/' . $page1->getTitle(),
|
||||
];
|
||||
$this->assertTokens('node', array('node' => $page2), $tokens);
|
||||
$this->assertTokens('node', ['node' => $page2], $tokens);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -64,14 +64,14 @@ class CommentTest extends KernelTestBase {
|
||||
// Fix http://example.com/index.php/comment/1 fails 'url:path' test.
|
||||
$parent_comment_path = $parent_comment->url();
|
||||
|
||||
$tokens = array(
|
||||
'url' => $parent_comment->urlInfo('canonical', ['fragment' => "comment-{$parent_comment->id()}"])->setAbsolute()->toString(),
|
||||
'url:absolute' => $parent_comment->urlInfo('canonical', ['fragment' => "comment-{$parent_comment->id()}"])->setAbsolute()->toString(),
|
||||
'url:relative' => $parent_comment->urlInfo('canonical', ['fragment' => "comment-{$parent_comment->id()}"])->toString(),
|
||||
$tokens = [
|
||||
'url' => $parent_comment->toUrl('canonical', ['fragment' => "comment-{$parent_comment->id()}"])->setAbsolute()->toString(),
|
||||
'url:absolute' => $parent_comment->toUrl('canonical', ['fragment' => "comment-{$parent_comment->id()}"])->setAbsolute()->toString(),
|
||||
'url:relative' => $parent_comment->toUrl('canonical', ['fragment' => "comment-{$parent_comment->id()}"])->toString(),
|
||||
'url:path' => $parent_comment_path,
|
||||
'parent:url:absolute' => NULL,
|
||||
);
|
||||
$this->assertTokens('comment', array('comment' => $parent_comment), $tokens);
|
||||
];
|
||||
$this->assertTokens('comment', ['comment' => $parent_comment], $tokens);
|
||||
|
||||
$comment = Comment::create([
|
||||
'entity_id' => $node->id(),
|
||||
@@ -86,16 +86,16 @@ class CommentTest extends KernelTestBase {
|
||||
$comment->save();
|
||||
|
||||
// Fix http://example.com/index.php/comment/1 fails 'url:path' test.
|
||||
$comment_path = Url::fromRoute('entity.comment.canonical', array('comment' => $comment->id()))->toString();
|
||||
$comment_path = Url::fromRoute('entity.comment.canonical', ['comment' => $comment->id()])->toString();
|
||||
|
||||
$tokens = array(
|
||||
'url' => $comment->urlInfo('canonical', ['fragment' => "comment-{$comment->id()}"])->setAbsolute()->toString(),
|
||||
'url:absolute' => $comment->urlInfo('canonical', ['fragment' => "comment-{$comment->id()}"])->setAbsolute()->toString(),
|
||||
'url:relative' => $comment->urlInfo('canonical', ['fragment' => "comment-{$comment->id()}"])->toString(),
|
||||
$tokens = [
|
||||
'url' => $comment->toUrl('canonical', ['fragment' => "comment-{$comment->id()}"])->setAbsolute()->toString(),
|
||||
'url:absolute' => $comment->toUrl('canonical', ['fragment' => "comment-{$comment->id()}"])->setAbsolute()->toString(),
|
||||
'url:relative' => $comment->toUrl('canonical', ['fragment' => "comment-{$comment->id()}"])->toString(),
|
||||
'url:path' => $comment_path,
|
||||
'parent:url:absolute' => $parent_comment->urlInfo('canonical', ['fragment' => "comment-{$parent_comment->id()}"])->setAbsolute()->toString(),
|
||||
);
|
||||
$this->assertTokens('comment', array('comment' => $comment), $tokens);
|
||||
'parent:url:absolute' => $parent_comment->toUrl('canonical', ['fragment' => "comment-{$parent_comment->id()}"])->setAbsolute()->toString(),
|
||||
];
|
||||
$this->assertTokens('comment', ['comment' => $comment], $tokens);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,11 +25,12 @@ class DateTest extends KernelTestBase {
|
||||
}
|
||||
|
||||
function testDateTokens() {
|
||||
$tokens = array(
|
||||
$tokens = [
|
||||
'token_module_test' => '1984',
|
||||
'invalid_format' => NULL,
|
||||
);
|
||||
];
|
||||
|
||||
$this->assertTokens('date', array('date' => 453859200), $tokens);
|
||||
$this->assertTokens('date', ['date' => 453859200], $tokens);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
namespace Drupal\Tests\token\Kernel;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\taxonomy\Entity\Term;
|
||||
use Drupal\taxonomy\Entity\Vocabulary;
|
||||
use Drupal\taxonomy\VocabularyInterface;
|
||||
|
||||
@@ -55,20 +55,21 @@ class EntityTest extends KernelTestBase {
|
||||
$this->assertIdentical($mapper->getTokenTypeForEntityType('invalid'), FALSE);
|
||||
$this->assertIdentical($mapper->getTokenTypeForEntityType('invalid', TRUE), 'invalid');
|
||||
|
||||
// Test that when we send the mis-matched entity type into token_replace()
|
||||
// that we still get the tokens replaced.
|
||||
$vocabulary = entity_load('taxonomy_vocabulary', 'tags');
|
||||
// Test that when we send the mis-matched entity type into
|
||||
// Drupal\Core\Utility\Token::replace() that we still get the tokens
|
||||
// replaced.
|
||||
$vocabulary = Vocabulary::load('tags');
|
||||
$term = $this->addTerm($vocabulary);
|
||||
$this->assertIdentical(\Drupal::token()->replace('[vocabulary:name]', array('taxonomy_vocabulary' => $vocabulary)), $vocabulary->label());
|
||||
$this->assertIdentical(\Drupal::token()->replace('[term:name][term:vocabulary:name]', array('taxonomy_term' => $term)), $term->label() . $vocabulary->label());
|
||||
$this->assertIdentical(\Drupal::token()->replace('[vocabulary:name]', ['taxonomy_vocabulary' => $vocabulary]), $vocabulary->label());
|
||||
$this->assertIdentical(\Drupal::token()->replace('[term:name][term:vocabulary:name]', ['taxonomy_term' => $term]), $term->label() . $vocabulary->label());
|
||||
}
|
||||
|
||||
function addTerm(VocabularyInterface $vocabulary, array $term = array()) {
|
||||
$term += array(
|
||||
'name' => Unicode::strtolower($this->randomMachineName(5)),
|
||||
function addTerm(VocabularyInterface $vocabulary, array $term = []) {
|
||||
$term += [
|
||||
'name' => mb_strtolower($this->randomMachineName(5)),
|
||||
'vid' => $vocabulary->id(),
|
||||
);
|
||||
$term = entity_create('taxonomy_term', $term);
|
||||
];
|
||||
$term = Term::create($term);
|
||||
$term->save();
|
||||
return $term;
|
||||
}
|
||||
@@ -80,25 +81,26 @@ class EntityTest extends KernelTestBase {
|
||||
$node = Node::create(['type' => 'page', 'title' => 'Original title']);
|
||||
$node->save();
|
||||
|
||||
$tokens = array(
|
||||
$tokens = [
|
||||
'nid' => $node->id(),
|
||||
'title' => 'Original title',
|
||||
'original' => NULL,
|
||||
'original:nid' => NULL,
|
||||
);
|
||||
$this->assertTokens('node', array('node' => $node), $tokens);
|
||||
];
|
||||
$this->assertTokens('node', ['node' => $node], $tokens);
|
||||
|
||||
// Emulate the original entity property that would be available from
|
||||
// node_save() and change the title for the node.
|
||||
$node->original = entity_load_unchanged('node', $node->id());
|
||||
$node->original = \Drupal::entityTypeManager()->getStorage('node')->loadUnchanged($node->id());
|
||||
$node->title = 'New title';
|
||||
|
||||
$tokens = array(
|
||||
$tokens = [
|
||||
'nid' => $node->id(),
|
||||
'title' => 'New title',
|
||||
'original' => 'Original title',
|
||||
'original:nid' => $node->id(),
|
||||
);
|
||||
$this->assertTokens('node', array('node' => $node), $tokens);
|
||||
];
|
||||
$this->assertTokens('node', ['node' => $node], $tokens);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Drupal\Tests\token\Kernel;
|
||||
|
||||
use Drupal\file\Entity\File;
|
||||
/**
|
||||
* Tests file tokens.
|
||||
*
|
||||
@@ -14,7 +15,7 @@ class FileTest extends KernelTestBase {
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('file');
|
||||
public static $modules = ['file'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
@@ -26,30 +27,31 @@ class FileTest extends KernelTestBase {
|
||||
|
||||
function testFileTokens() {
|
||||
// Create a test file object.
|
||||
$file = entity_create('file', array(
|
||||
$file = File::create([
|
||||
'fid' => 1,
|
||||
'filename' => 'test.png',
|
||||
'filesize' => 100,
|
||||
'uri' => 'public://images/test.png',
|
||||
'filemime' => 'image/png',
|
||||
));
|
||||
]);
|
||||
|
||||
$tokens = array(
|
||||
$tokens = [
|
||||
'basename' => 'test.png',
|
||||
'extension' => 'png',
|
||||
'size-raw' => 100,
|
||||
);
|
||||
$this->assertTokens('file', array('file' => $file), $tokens);
|
||||
];
|
||||
$this->assertTokens('file', ['file' => $file], $tokens);
|
||||
|
||||
// Test a file with no extension and a fake name.
|
||||
$file->filename = 'Test PNG image';
|
||||
$file->uri = 'public://images/test';
|
||||
|
||||
$tokens = array(
|
||||
$tokens = [
|
||||
'basename' => 'test',
|
||||
'extension' => '',
|
||||
'size-raw' => 100,
|
||||
);
|
||||
$this->assertTokens('file', array('file' => $file), $tokens);
|
||||
];
|
||||
$this->assertTokens('file', ['file' => $file], $tokens);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -48,52 +48,53 @@ class NodeTest extends KernelTestBase {
|
||||
'type' => 'page',
|
||||
'title' => 'Source Title',
|
||||
'revision_log' => $this->randomMachineName(),
|
||||
'path' => array('alias' => '/content/source-node')
|
||||
'path' => ['alias' => '/content/source-node']
|
||||
]);
|
||||
$page->save();
|
||||
$tokens = array(
|
||||
$tokens = [
|
||||
'log' => $page->revision_log->value,
|
||||
'url:path' => '/content/source-node',
|
||||
'url:absolute' => Url::fromRoute('entity.node.canonical', ['node' => $page->id()], array('absolute' => TRUE))->toString(),
|
||||
'url:relative' => Url::fromRoute('entity.node.canonical', ['node' => $page->id()], array('absolute' => FALSE))->toString(),
|
||||
'url:absolute' => Url::fromRoute('entity.node.canonical', ['node' => $page->id()], ['absolute' => TRUE])->toString(),
|
||||
'url:relative' => Url::fromRoute('entity.node.canonical', ['node' => $page->id()], ['absolute' => FALSE])->toString(),
|
||||
'url:unaliased:path' => "/node/{$page->id()}",
|
||||
'content-type' => 'Basic page',
|
||||
'content-type:name' => 'Basic page',
|
||||
'content-type:machine-name' => 'page',
|
||||
'content-type:description' => "Use <em>basic pages</em> for your static content, such as an 'About us' page.",
|
||||
'content-type:node-count' => 1,
|
||||
'content-type:edit-url' => Url::fromRoute('entity.node_type.edit_form', ['node_type' => 'page'], array('absolute' => TRUE))->toString(),
|
||||
'content-type:edit-url' => Url::fromRoute('entity.node_type.edit_form', ['node_type' => 'page'], ['absolute' => TRUE])->toString(),
|
||||
'source:title' => 'Source Title',
|
||||
// Deprecated tokens.
|
||||
'type' => 'page',
|
||||
'type-name' => 'Basic page',
|
||||
'url:alias' => '/content/source-node',
|
||||
);
|
||||
$this->assertTokens('node', array('node' => $page), $tokens);
|
||||
];
|
||||
$this->assertTokens('node', ['node' => $page], $tokens);
|
||||
|
||||
$article = Node::create([
|
||||
'type' => 'article',
|
||||
'title' => 'Source Title',
|
||||
]);
|
||||
$article->save();
|
||||
$tokens = array(
|
||||
$tokens = [
|
||||
'log' => '',
|
||||
'url:path' => "/node/{$article->id()}",
|
||||
'url:absolute' => Url::fromRoute('entity.node.canonical', ['node' => $article->id()], array('absolute' => TRUE))->toString(),
|
||||
'url:relative' => Url::fromRoute('entity.node.canonical', ['node' => $article->id()], array('absolute' => FALSE))->toString(),
|
||||
'url:absolute' => Url::fromRoute('entity.node.canonical', ['node' => $article->id()], ['absolute' => TRUE])->toString(),
|
||||
'url:relative' => Url::fromRoute('entity.node.canonical', ['node' => $article->id()], ['absolute' => FALSE])->toString(),
|
||||
'url:unaliased:path' => "/node/{$article->id()}",
|
||||
'content-type' => 'Article',
|
||||
'content-type:name' => 'Article',
|
||||
'content-type:machine-name' => 'article',
|
||||
'content-type:description' => "Use <em>articles</em> for time-sensitive content like news, press releases or blog posts.",
|
||||
'content-type:node-count' => 1,
|
||||
'content-type:edit-url' => Url::fromRoute('entity.node_type.edit_form', ['node_type' => 'article'], array('absolute' => TRUE))->toString(),
|
||||
'content-type:edit-url' => Url::fromRoute('entity.node_type.edit_form', ['node_type' => 'article'], ['absolute' => TRUE])->toString(),
|
||||
'source:title' => 'Source Title',
|
||||
// Deprecated tokens.
|
||||
'type' => 'article',
|
||||
'type-name' => 'Article',
|
||||
'url:alias' => "/node/{$article->id()}",
|
||||
);
|
||||
$this->assertTokens('node', array('node' => $article), $tokens);
|
||||
];
|
||||
$this->assertTokens('node', ['node' => $article], $tokens);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,18 +10,19 @@ namespace Drupal\Tests\token\Kernel;
|
||||
class RandomTest extends KernelTestBase {
|
||||
|
||||
function testRandomTokens() {
|
||||
$tokens = array(
|
||||
$tokens = [
|
||||
'number' => '[0-9]{1,}',
|
||||
'hash:md5' => '[0-9a-f]{32}',
|
||||
'hash:sha1' => '[0-9a-f]{40}',
|
||||
'hash:sha256' => '[0-9a-f]{64}',
|
||||
'hash:invalid-algo' => NULL,
|
||||
);
|
||||
];
|
||||
|
||||
$first_set = $this->assertTokens('random', array(), $tokens, array('regex' => TRUE));
|
||||
$second_set = $this->assertTokens('random', array(), $tokens, array('regex' => TRUE));
|
||||
$first_set = $this->assertTokens('random', [], $tokens, ['regex' => TRUE]);
|
||||
$second_set = $this->assertTokens('random', [], $tokens, ['regex' => TRUE]);
|
||||
foreach ($first_set as $token => $value) {
|
||||
$this->assertNotIdentical($first_set[$token], $second_set[$token]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace Drupal\Tests\token\Kernel;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\taxonomy\Entity\Term;
|
||||
use Drupal\taxonomy\Entity\Vocabulary;
|
||||
use Drupal\language\Entity\ConfigurableLanguage;
|
||||
use Drupal\Core\Url;
|
||||
@@ -13,6 +13,7 @@ use Drupal\Core\Url;
|
||||
* @group token
|
||||
*/
|
||||
class TaxonomyTest extends KernelTestBase {
|
||||
|
||||
protected $vocab;
|
||||
|
||||
/**
|
||||
@@ -20,7 +21,7 @@ class TaxonomyTest extends KernelTestBase {
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('taxonomy', 'text', 'language');
|
||||
public static $modules = ['taxonomy', 'text', 'language'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
@@ -43,31 +44,31 @@ class TaxonomyTest extends KernelTestBase {
|
||||
* Test the additional taxonomy term tokens.
|
||||
*/
|
||||
function testTaxonomyTokens() {
|
||||
$root_term = $this->addTerm($this->vocab, array('name' => 'Root term', 'path' => array('alias' => '/root-term')));
|
||||
$tokens = array(
|
||||
'url' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $root_term->id()], array('absolute' => TRUE))->toString(),
|
||||
'url:absolute' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $root_term->id()], array('absolute' => TRUE))->toString(),
|
||||
'url:relative' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $root_term->id()], array('absolute' => FALSE))->toString(),
|
||||
$root_term = $this->addTerm($this->vocab, ['name' => 'Root term', 'path' => ['alias' => '/root-term']]);
|
||||
$tokens = [
|
||||
'url' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $root_term->id()], ['absolute' => TRUE])->toString(),
|
||||
'url:absolute' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $root_term->id()], ['absolute' => TRUE])->toString(),
|
||||
'url:relative' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $root_term->id()], ['absolute' => FALSE])->toString(),
|
||||
'url:path' => '/root-term',
|
||||
'url:unaliased:path' => "/taxonomy/term/{$root_term->id()}",
|
||||
'edit-url' => Url::fromRoute('entity.taxonomy_term.edit_form', ['taxonomy_term' => $root_term->id()], array('absolute' => TRUE))->toString(),
|
||||
'edit-url' => Url::fromRoute('entity.taxonomy_term.edit_form', ['taxonomy_term' => $root_term->id()], ['absolute' => TRUE])->toString(),
|
||||
'parents' => NULL,
|
||||
'parents:count' => NULL,
|
||||
'parents:keys' => NULL,
|
||||
'root' => NULL,
|
||||
// Deprecated tokens
|
||||
'url:alias' => '/root-term',
|
||||
);
|
||||
$this->assertTokens('term', array('term' => $root_term), $tokens);
|
||||
];
|
||||
$this->assertTokens('term', ['term' => $root_term], $tokens);
|
||||
|
||||
$parent_term = $this->addTerm($this->vocab, array('name' => 'Parent term', 'parent' => $root_term->id()));
|
||||
$tokens = array(
|
||||
'url' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $parent_term->id()], array('absolute' => TRUE))->toString(),
|
||||
'url:absolute' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $parent_term->id()], array('absolute' => TRUE))->toString(),
|
||||
'url:relative' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $parent_term->id()], array('absolute' => FALSE))->toString(),
|
||||
$parent_term = $this->addTerm($this->vocab, ['name' => 'Parent term', 'parent' => $root_term->id()]);
|
||||
$tokens = [
|
||||
'url' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $parent_term->id()], ['absolute' => TRUE])->toString(),
|
||||
'url:absolute' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $parent_term->id()], ['absolute' => TRUE])->toString(),
|
||||
'url:relative' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $parent_term->id()], ['absolute' => FALSE])->toString(),
|
||||
'url:path' => "/taxonomy/term/{$parent_term->id()}",
|
||||
'url:unaliased:path' => "/taxonomy/term/{$parent_term->id()}",
|
||||
'edit-url' => Url::fromRoute('entity.taxonomy_term.edit_form', ['taxonomy_term' => $parent_term->id()], array('absolute' => TRUE))->toString(),
|
||||
'edit-url' => Url::fromRoute('entity.taxonomy_term.edit_form', ['taxonomy_term' => $parent_term->id()], ['absolute' => TRUE])->toString(),
|
||||
'parents' => 'Root term',
|
||||
'parents:count' => 1,
|
||||
'parents:keys' => $root_term->id(),
|
||||
@@ -75,16 +76,16 @@ class TaxonomyTest extends KernelTestBase {
|
||||
'root:tid' => $root_term->id(),
|
||||
// Deprecated tokens
|
||||
'url:alias' => "/taxonomy/term/{$parent_term->id()}",
|
||||
);
|
||||
$this->assertTokens('term', array('term' => $parent_term), $tokens);
|
||||
];
|
||||
$this->assertTokens('term', ['term' => $parent_term], $tokens);
|
||||
|
||||
$term = $this->addTerm($this->vocab, array('name' => 'Test term', 'parent' => $parent_term->id()));
|
||||
$tokens = array(
|
||||
$term = $this->addTerm($this->vocab, ['name' => 'Test term', 'parent' => $parent_term->id()]);
|
||||
$tokens = [
|
||||
'parents' => 'Root term, Parent term',
|
||||
'parents:count' => 2,
|
||||
'parents:keys' => implode(', ', array($root_term->id(), $parent_term->id())),
|
||||
);
|
||||
$this->assertTokens('term', array('term' => $term), $tokens);
|
||||
'parents:keys' => implode(', ', [$root_term->id(), $parent_term->id()]),
|
||||
];
|
||||
$this->assertTokens('term', ['term' => $term], $tokens);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -92,28 +93,28 @@ class TaxonomyTest extends KernelTestBase {
|
||||
*/
|
||||
function testVocabularyTokens() {
|
||||
$vocabulary = $this->vocab;
|
||||
$tokens = array(
|
||||
$tokens = [
|
||||
'machine-name' => 'tags',
|
||||
'edit-url' => Url::fromRoute('entity.taxonomy_vocabulary.edit_form', ['taxonomy_vocabulary' => $vocabulary->id()], array('absolute' => TRUE))->toString(),
|
||||
);
|
||||
$this->assertTokens('vocabulary', array('vocabulary' => $vocabulary), $tokens);
|
||||
'edit-url' => Url::fromRoute('entity.taxonomy_vocabulary.edit_form', ['taxonomy_vocabulary' => $vocabulary->id()], ['absolute' => TRUE])->toString(),
|
||||
];
|
||||
$this->assertTokens('vocabulary', ['vocabulary' => $vocabulary], $tokens);
|
||||
}
|
||||
|
||||
function addVocabulary(array $vocabulary = array()) {
|
||||
$vocabulary += array(
|
||||
'name' => Unicode::strtolower($this->randomMachineName(5)),
|
||||
'nodes' => array('article' => 'article'),
|
||||
);
|
||||
$vocabulary = entity_create('taxonomy_vocabulary', $vocabulary)->save();
|
||||
function addVocabulary(array $vocabulary = []) {
|
||||
$vocabulary += [
|
||||
'name' => mb_strtolower($this->randomMachineName(5)),
|
||||
'nodes' => ['article' => 'article'],
|
||||
];
|
||||
$vocabulary = Vocabulary::create($vocabulary)->save();
|
||||
return $vocabulary;
|
||||
}
|
||||
|
||||
function addTerm($vocabulary, array $term = array()) {
|
||||
$term += array(
|
||||
'name' => Unicode::strtolower($this->randomMachineName(5)),
|
||||
function addTerm($vocabulary, array $term = []) {
|
||||
$term += [
|
||||
'name' => mb_strtolower($this->randomMachineName(5)),
|
||||
'vid' => $vocabulary->id(),
|
||||
);
|
||||
$term = entity_create('taxonomy_term', $term);
|
||||
];
|
||||
$term = Term::create($term);
|
||||
$term->save();
|
||||
return $term;
|
||||
}
|
||||
@@ -146,6 +147,8 @@ class TaxonomyTest extends KernelTestBase {
|
||||
])->save();
|
||||
|
||||
// Expect the parent term to be in the specified language.
|
||||
$this->assertTokens('term', array('term' => $child_term), ['parents' => 'german-parent-term'], ['langcode' => 'de']);
|
||||
$this->assertTokens('term', ['term' => $child_term], ['parents' => 'german-parent-term'], ['langcode' => 'de']);
|
||||
$this->assertTokens('term', ['term' => $child_term], ['root' => 'german-parent-term'], ['langcode' => 'de']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -33,9 +33,9 @@ class UnitTest extends KernelTestBase {
|
||||
* Test invalid tokens.
|
||||
*/
|
||||
public function testGetInvalidTokens() {
|
||||
$tests = array();
|
||||
$tests[] = array(
|
||||
'valid tokens' => array(
|
||||
$tests = [];
|
||||
$tests[] = [
|
||||
'valid tokens' => [
|
||||
'[node:title]',
|
||||
'[node:created:short]',
|
||||
'[node:created:custom:invalid]',
|
||||
@@ -46,8 +46,8 @@ class UnitTest extends KernelTestBase {
|
||||
'[current-date:short]',
|
||||
'[current-user:uid]',
|
||||
'[current-user:ip-address]',
|
||||
),
|
||||
'invalid tokens' => array(
|
||||
],
|
||||
'invalid tokens' => [
|
||||
'[node:title:invalid]',
|
||||
'[node:created:invalid]',
|
||||
'[node:created:short:invalid]',
|
||||
@@ -62,11 +62,11 @@ class UnitTest extends KernelTestBase {
|
||||
'[node:type]',
|
||||
'[node:type-name]',
|
||||
'[date:short]',
|
||||
),
|
||||
'types' => array('node'),
|
||||
);
|
||||
$tests[] = array(
|
||||
'valid tokens' => array(
|
||||
],
|
||||
'types' => ['node'],
|
||||
];
|
||||
$tests[] = [
|
||||
'valid tokens' => [
|
||||
'[node:title]',
|
||||
'[node:created:short]',
|
||||
'[node:created:custom:invalid]',
|
||||
@@ -77,8 +77,8 @@ class UnitTest extends KernelTestBase {
|
||||
'[user:uid]',
|
||||
'[current-date:short]',
|
||||
'[current-user:uid]',
|
||||
),
|
||||
'invalid tokens' => array(
|
||||
],
|
||||
'invalid tokens' => [
|
||||
'[node:title:invalid]',
|
||||
'[node:created:invalid]',
|
||||
'[node:created:short:invalid]',
|
||||
@@ -91,9 +91,9 @@ class UnitTest extends KernelTestBase {
|
||||
'[node:tnid]',
|
||||
'[node:type]',
|
||||
'[node:type-name]',
|
||||
),
|
||||
'types' => array('all'),
|
||||
);
|
||||
],
|
||||
'types' => ['all'],
|
||||
];
|
||||
|
||||
foreach ($tests as $test) {
|
||||
$tokens = array_merge($test['valid tokens'], $test['invalid tokens']);
|
||||
@@ -116,4 +116,5 @@ class UnitTest extends KernelTestBase {
|
||||
$this->assertNull($this->tokenService->getTokenInfo('user_role', 'url'));
|
||||
$this->assertNull($this->tokenService->getTypeInfo('user_role'));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\token\Kernel;
|
||||
|
||||
use Drupal\Core\Url;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* Test generic url token replacements.
|
||||
*
|
||||
* @group token
|
||||
*/
|
||||
class UrlTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* The token service.
|
||||
*
|
||||
* @var \Drupal\Core\Utility\Token
|
||||
*/
|
||||
protected $token;
|
||||
|
||||
/**
|
||||
* The current request stack.
|
||||
*
|
||||
* @var \Symfony\Component\HttpFoundation\RequestStack
|
||||
*/
|
||||
protected $requestStack;
|
||||
|
||||
/**
|
||||
* The current route match.
|
||||
*
|
||||
* @var \Drupal\Core\Routing\CurrentRouteMatch
|
||||
*/
|
||||
protected $currentRouteMatch;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->token = $this->container->get('token');
|
||||
$this->requestStack = $this->container->get('request_stack');
|
||||
$this->currentRouteMatch = $this->container->get('current_route_match');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the url token replacements for current requests.
|
||||
*
|
||||
* The method ::expectedCurrentRequestUrlResults() is not declared
|
||||
* as a regular data provider, because it might use services from
|
||||
* the global Drupal container, which is not initialized yet during
|
||||
* the invocation of data providers.
|
||||
*/
|
||||
public function testCurrentRequestUrls() {
|
||||
foreach ($this->expectedCurrentRequestUrlResults() as $data_set) {
|
||||
list ($request, $text, $data, $options, $expected_output) = $data_set;
|
||||
// Set the request as the current one.
|
||||
$this->requestStack->pop();
|
||||
$this->requestStack->push($request);
|
||||
$this->currentRouteMatch->resetRouteMatch();
|
||||
|
||||
$this->assertEquals($expected_output, $this->token->replace($text, $data, $options));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a list of results to expect for ::testRequestUrls().
|
||||
*
|
||||
* Each data set of this array holds the following order:
|
||||
* - The request object to test for.
|
||||
* - The input text as string.
|
||||
* - The token data as array.
|
||||
* - Further options for the token replacement as array.
|
||||
* - The output to expect after token replacement.
|
||||
*
|
||||
* @return array
|
||||
* The list of results to expect.
|
||||
*/
|
||||
public function expectedCurrentRequestUrlResults() {
|
||||
return [
|
||||
[Request::createFromGlobals(), '[current-page:url]', [], [], Url::createFromRequest(Request::createFromGlobals())->setAbsolute()->toString()],
|
||||
[Request::create('/should-not-exist'), '[current-page:url:path]', [], [], '/'],
|
||||
[Request::create('/https://drupal.org/'), '[current-page:url:absolute]', [], [], '[current-page:url:absolute]'],
|
||||
[Request::create('/https://drupal.org/'), '[current-page:url:absolute]', [], ['clear' => TRUE], ''],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\token\Kernel;
|
||||
|
||||
use Drupal\views\Tests\ViewTestData;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
* Test the views tokens.
|
||||
*
|
||||
* @group token
|
||||
*/
|
||||
class ViewsTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['views', 'block'];
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $testViews = ['token_views_test'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installEntitySchema('user');
|
||||
ViewTestData::createTestViews(get_class($this), ['token_module_test']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests path token replacements generated from a view without a path.
|
||||
*/
|
||||
public function testTokenReplacementNoPath() {
|
||||
$token_handler = \Drupal::token();
|
||||
$view = Views::getView('token_views_test');
|
||||
$view->setDisplay('block_1');
|
||||
$view->execute();
|
||||
|
||||
$this->assertSame('', $token_handler->replace('[view:url]', ['view' => $view]), 'Token [view:url] is empty for views without path.');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,9 +2,11 @@ type: module
|
||||
name: Token
|
||||
description: Provides a user interface for the Token API and some missing core tokens.
|
||||
# core: 8.x
|
||||
dependencies:
|
||||
- drupal:system (>= 8.5)
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-12-20
|
||||
version: '8.x-1.1'
|
||||
# Information added by Drupal.org packaging script on 2018-09-08
|
||||
version: '8.x-1.4'
|
||||
core: '8.x'
|
||||
project: 'token'
|
||||
datestamp: 1513810387
|
||||
datestamp: 1536408485
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* Implements hook_requirements().
|
||||
*/
|
||||
function token_requirements($phase = 'runtime') {
|
||||
$requirements = array();
|
||||
$requirements = [];
|
||||
|
||||
if ($phase == 'runtime') {
|
||||
// Check for various token definition problems.
|
||||
@@ -24,11 +24,11 @@ function token_requirements($phase = 'runtime') {
|
||||
'#items' => $problems,
|
||||
];
|
||||
|
||||
$requirements['token-' . $problem_key] = array(
|
||||
$requirements['token-' . $problem_key] = [
|
||||
'title' => $problem['label'],
|
||||
'value' => \Drupal::service('renderer')->renderPlain($build),
|
||||
'severity' => $problem['severity'],
|
||||
);
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -51,12 +51,12 @@ function token_install() {
|
||||
$storage = \Drupal::entityTypeManager()->getStorage('entity_view_mode');
|
||||
// Add a token view mode if it does not already exist.
|
||||
if (!$storage->load("$entity_type.token")) {
|
||||
$storage->create(array(
|
||||
$storage->create([
|
||||
'targetEntityType' => $entity_type,
|
||||
'id' => "$entity_type.token",
|
||||
'status' => TRUE,
|
||||
'label' => t('Token'),
|
||||
))->save();
|
||||
])->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,7 +65,7 @@ function token_install() {
|
||||
* Build a list of Drupal 6 tokens and their Drupal 7 token names.
|
||||
*/
|
||||
function _token_upgrade_token_list() {
|
||||
$tokens = array(
|
||||
$tokens = [
|
||||
// Global tokens
|
||||
'user-name' => 'current-user:name',
|
||||
'user-id' => 'current-user:id',
|
||||
@@ -142,7 +142,7 @@ function _token_upgrade_token_list() {
|
||||
//'date-in-tz' => '',
|
||||
'account-url' => 'user:url',
|
||||
'account-edit' => 'user:edit-url',
|
||||
);
|
||||
];
|
||||
|
||||
// Account for date tokens which need to be expanded.
|
||||
$tokens += _token_upgrade_token_date_list('site-', 'site:date');
|
||||
@@ -160,8 +160,8 @@ function _token_upgrade_token_list() {
|
||||
* Build a list of Drupal 6 date tokens and their Drupal 7 token names.
|
||||
*/
|
||||
function _token_upgrade_token_date_list($old_token, $new_token) {
|
||||
$tokens = array();
|
||||
$formats = array(
|
||||
$tokens = [];
|
||||
$formats = [
|
||||
'yyyy' => 'Y',
|
||||
'yy' => 'y',
|
||||
'month' => 'F',
|
||||
@@ -174,7 +174,7 @@ function _token_upgrade_token_date_list($old_token, $new_token) {
|
||||
'ddd' => 'D',
|
||||
'dd' => 'd',
|
||||
'd' => 'j',
|
||||
);
|
||||
];
|
||||
foreach ($formats as $token_format => $date_format) {
|
||||
$tokens[$old_token . $token_format] = "$new_token:custom:$date_format";
|
||||
}
|
||||
@@ -198,7 +198,7 @@ function _token_upgrade_token_date_list($old_token, $new_token) {
|
||||
*
|
||||
* @see _token_upgrade_token_list()
|
||||
*/
|
||||
function token_update_token_text($text, $updates = array(), $leading = '[', $trailing = ']') {
|
||||
function token_update_token_text($text, $updates = [], $leading = '[', $trailing = ']') {
|
||||
$updates += _token_upgrade_token_list();
|
||||
$regex = '/' . preg_quote($leading, '/') . '([^\s]*)' . preg_quote($trailing, '/') . '/';
|
||||
preg_match_all($regex, $text, $matches);
|
||||
@@ -220,7 +220,7 @@ function token_update_token_text($text, $updates = array(), $leading = '[', $tra
|
||||
*/
|
||||
function token_get_token_problems() {
|
||||
// @todo Improve the duplicate checking to report which modules are the offenders.
|
||||
//$token_info = array();
|
||||
//$token_info = [];
|
||||
//foreach (module_implements('token_info') as $module) {
|
||||
// $module_token_info = module_invoke($module, 'token_info');
|
||||
// if (in_array($module, _token_core_supported_modules())) {
|
||||
@@ -230,7 +230,7 @@ function token_get_token_problems() {
|
||||
// if (is_array($module_token_info['types'])) {
|
||||
// foreach (array_keys($module_token_info['types']) as $type) {
|
||||
// if (is_array($module_token_info['types'][$type])) {
|
||||
// $module_token_info['types'][$type] += array('module' => $module);
|
||||
// $module_token_info['types'][$type] += ['module' => $module];
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
@@ -246,28 +246,28 @@ function token_get_token_problems() {
|
||||
//}
|
||||
|
||||
$token_info = \Drupal::token()->getInfo();
|
||||
$token_problems = array(
|
||||
'not-array' => array(
|
||||
$token_problems = [
|
||||
'not-array' => [
|
||||
'label' => t('Tokens or token types not defined as arrays'),
|
||||
'severity' => REQUIREMENT_ERROR,
|
||||
),
|
||||
'missing-info' => array(
|
||||
],
|
||||
'missing-info' => [
|
||||
'label' => t('Tokens or token types missing name property'),
|
||||
'severity' => REQUIREMENT_WARNING,
|
||||
),
|
||||
'type-no-tokens' => array(
|
||||
],
|
||||
'type-no-tokens' => [
|
||||
'label' => t('Token types do not have any tokens defined'),
|
||||
'severity' => REQUIREMENT_INFO,
|
||||
),
|
||||
'tokens-no-type' => array(
|
||||
],
|
||||
'tokens-no-type' => [
|
||||
'label' => t('Token types are not defined but have tokens'),
|
||||
'severity' => REQUIREMENT_INFO,
|
||||
),
|
||||
'duplicate' => array(
|
||||
],
|
||||
'duplicate' => [
|
||||
'label' => t('Token or token types are defined by multiple modules'),
|
||||
'severity' => REQUIREMENT_ERROR,
|
||||
),
|
||||
);
|
||||
],
|
||||
];
|
||||
|
||||
// Check token types for problems.
|
||||
foreach ($token_info['types'] as $type => $type_info) {
|
||||
@@ -313,4 +313,4 @@ function token_get_token_problems() {
|
||||
}
|
||||
|
||||
return $token_problems;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
*/
|
||||
|
||||
use Drupal\Component\Render\PlainTextOutput;
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\Block\BlockPluginInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Menu\MenuLinkInterface;
|
||||
@@ -47,7 +46,7 @@ function token_help($route_name, RouteMatchInterface $route_match) {
|
||||
* Return an array of the core modules supported by token.module.
|
||||
*/
|
||||
function _token_core_supported_modules() {
|
||||
return array('book', 'field', 'menu_ui');
|
||||
return ['book', 'field', 'menu_ui'];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,9 +96,9 @@ function token_form_block_form_alter(&$form, FormStateInterface $form_state) {
|
||||
'#token_types' => [],
|
||||
];
|
||||
$rendered_token_tree = \Drupal::service('renderer')->render($token_tree);
|
||||
$form['settings']['label']['#description'] =
|
||||
t('This field supports tokens. @browse_tokens_link', ['@browse_tokens_link' => $rendered_token_tree])
|
||||
;
|
||||
$form['settings']['label']['#description'] = t('This field supports tokens. @browse_tokens_link', [
|
||||
'@browse_tokens_link' => $rendered_token_tree,
|
||||
]);
|
||||
$form['settings']['label']['#element_validate'][] = 'token_element_validate';
|
||||
$form['settings']['label'] += ['#token_types' => []];
|
||||
}
|
||||
@@ -108,7 +107,7 @@ function token_form_block_form_alter(&$form, FormStateInterface $form_state) {
|
||||
* Implements hook_field_info_alter().
|
||||
*/
|
||||
function token_field_info_alter(&$info) {
|
||||
$defaults = array(
|
||||
$defaults = [
|
||||
'taxonomy_term_reference' => 'taxonomy_term_reference_plain',
|
||||
'number_integer' => 'number_unformatted',
|
||||
'number_decimal' => 'number_unformatted',
|
||||
@@ -122,10 +121,10 @@ function token_field_info_alter(&$info) {
|
||||
'list_float' => 'list_default',
|
||||
'list_string' => 'list_default',
|
||||
'list_boolean' => 'list_default',
|
||||
);
|
||||
];
|
||||
foreach ($defaults as $field_type => $default_token_formatter) {
|
||||
if (isset($info[$field_type])) {
|
||||
$info[$field_type] += array('default_token_formatter' => $default_token_formatter);
|
||||
$info[$field_type] += ['default_token_formatter' => $default_token_formatter];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -228,7 +227,7 @@ function token_module_implements_alter(&$implementations, $hook) {
|
||||
// other modules.
|
||||
if (isset($implementations['token'])) {
|
||||
unset($implementations['token']);
|
||||
$implementations = array_merge(array('token' => 'tokens'), $implementations);
|
||||
$implementations = array_merge(['token' => 'tokens'], $implementations);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -258,21 +257,21 @@ function _token_module($type, $name) {
|
||||
*
|
||||
* For example:
|
||||
* @code
|
||||
* $form['my_node_text_element'] = array(
|
||||
* $form['my_node_text_element'] = [
|
||||
* '#type' => 'textfield',
|
||||
* '#title' => t('Some text to token-ize that has a node context.'),
|
||||
* '#default_value' => 'The title of this node is [node:title].',
|
||||
* '#element_validate' => array('token_element_validate'),
|
||||
* '#token_types' => array('node'),
|
||||
* '#element_validate' => ['token_element_validate'],
|
||||
* '#token_types' => ['node'],
|
||||
* '#min_tokens' => 1,
|
||||
* '#max_tokens' => 10,
|
||||
* );
|
||||
* ];
|
||||
* @endcode
|
||||
*/
|
||||
function token_element_validate($element, FormStateInterface $form_state) {
|
||||
$value = isset($element['#value']) ? $element['#value'] : $element['#default_value'];
|
||||
|
||||
if (!Unicode::strlen($value)) {
|
||||
if (!mb_strlen($value)) {
|
||||
// Empty value needs no further validation since the element should depend
|
||||
// on using the '#required' FAPI property.
|
||||
return $element;
|
||||
@@ -283,13 +282,13 @@ function token_element_validate($element, FormStateInterface $form_state) {
|
||||
|
||||
// Validate if an element must have a minimum number of tokens.
|
||||
if (isset($element['#min_tokens']) && count($tokens) < $element['#min_tokens']) {
|
||||
$error = \Drupal::translation()->formatPlural($element['#min_tokens'], '%name must contain at least one token.', '%name must contain at least @count tokens.', array('%name' => $title));
|
||||
$error = \Drupal::translation()->formatPlural($element['#min_tokens'], '%name must contain at least one token.', '%name must contain at least @count tokens.', ['%name' => $title]);
|
||||
$form_state->setError($element, $error);
|
||||
}
|
||||
|
||||
// Validate if an element must have a maximum number of tokens.
|
||||
if (isset($element['#max_tokens']) && count($tokens) > $element['#max_tokens']) {
|
||||
$error = \Drupal::translation()->formatPlural($element['#max_tokens'], '%name must contain at most one token.', '%name must contain at most @count tokens.', array('%name' => $title));
|
||||
$error = \Drupal::translation()->formatPlural($element['#max_tokens'], '%name must contain at most one token.', '%name must contain at most @count tokens.', ['%name' => $title]);
|
||||
$form_state->setError($element, $error);
|
||||
}
|
||||
|
||||
@@ -297,7 +296,7 @@ function token_element_validate($element, FormStateInterface $form_state) {
|
||||
if (isset($element['#token_types'])) {
|
||||
$invalid_tokens = \Drupal::token()->getInvalidTokensByContext($tokens, $element['#token_types']);
|
||||
if ($invalid_tokens) {
|
||||
$form_state->setError($element, t('%name is using the following invalid tokens: @invalid-tokens.', array('%name' => $title, '@invalid-tokens' => implode(', ', $invalid_tokens))));
|
||||
$form_state->setError($element, t('%name is using the following invalid tokens: @invalid-tokens.', ['%name' => $title, '@invalid-tokens' => implode(', ', $invalid_tokens)]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -320,19 +319,19 @@ function token_form_field_config_edit_form_alter(&$form, FormStateInterface $for
|
||||
// Date support needs to be implicitly added, as while technically it's not
|
||||
// a global token, it is a not only used but is the default value.
|
||||
// https://www.drupal.org/node/2642160
|
||||
$form['settings']['file_directory'] += array('#token_types' => array('date'));
|
||||
$form['settings']['file_directory'] += ['#token_types' => ['date']];
|
||||
$form['settings']['file_directory']['#description'] .= ' ' . t('This field supports tokens.');
|
||||
}
|
||||
|
||||
// Note that the description is tokenized via token_field_widget_form_alter().
|
||||
$form['description']['#element_validate'][] = 'token_element_validate';
|
||||
$form['description'] += array('#token_types' => array());
|
||||
$form['description'] += ['#token_types' => []];
|
||||
|
||||
$form['token_tree'] = array(
|
||||
$form['token_tree'] = [
|
||||
'#theme' => 'token_tree_link',
|
||||
'#token_types' => array(),
|
||||
'#token_types' => [],
|
||||
'#weight' => $form['description']['#weight'] + 0.5,
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -384,6 +383,7 @@ function token_form_user_admin_settings_alter(&$form, FormStateInterface $form_s
|
||||
case 'email_cancel_confirm':
|
||||
// Do nothing, but allow execution to continue.
|
||||
break;
|
||||
|
||||
case 'email_activated':
|
||||
case 'email_blocked':
|
||||
case 'email_canceled':
|
||||
@@ -391,6 +391,7 @@ function token_form_user_admin_settings_alter(&$form, FormStateInterface $form_s
|
||||
// sub-element, so switch to that element instead.
|
||||
$element = &$form[$key]['settings'];
|
||||
break;
|
||||
|
||||
default:
|
||||
continue 2;
|
||||
}
|
||||
@@ -402,24 +403,24 @@ function token_form_user_admin_settings_alter(&$form, FormStateInterface $form_s
|
||||
elseif ($element[$sub_key]['#type'] == 'textfield' && substr($sub_key, -8) === '_subject') {
|
||||
// Add validation to subject textfields.
|
||||
$element[$sub_key]['#element_validate'][] = 'token_element_validate';
|
||||
$element[$sub_key] += array('#token_types' => array('user'));
|
||||
$element[$sub_key] += ['#token_types' => ['user']];
|
||||
}
|
||||
elseif ($element[$sub_key]['#type'] == 'textarea' && substr($sub_key, -5) === '_body') {
|
||||
// Add validation to body textareas.
|
||||
$element[$sub_key]['#element_validate'][] = 'token_element_validate';
|
||||
$element[$sub_key] += array('#token_types' => array('user'));
|
||||
$element[$sub_key] += ['#token_types' => ['user']];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add the token tree UI.
|
||||
$form['email']['token_tree'] = array(
|
||||
$form['email']['token_tree'] = [
|
||||
'#theme' => 'token_tree_link',
|
||||
'#token_types' => array('user'),
|
||||
'#token_types' => ['user'],
|
||||
'#show_restricted' => TRUE,
|
||||
'#show_nested' => FALSE,
|
||||
'#weight' => 90,
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -431,10 +432,10 @@ function token_form_user_admin_settings_alter(&$form, FormStateInterface $form_s
|
||||
* The cleaned token name.
|
||||
*/
|
||||
function token_clean_token_name($name) {
|
||||
static $names = array();
|
||||
static $names = [];
|
||||
|
||||
if (!isset($names[$name])) {
|
||||
$cleaned_name = strtr($name, array(' ' => '-', '_' => '-', '/' => '-', '[' => '-', ']' => ''));
|
||||
$cleaned_name = strtr($name, [' ' => '-', '_' => '-', '/' => '-', '[' => '-', ']' => '']);
|
||||
$cleaned_name = preg_replace('/[^\w\-]/i', '', $cleaned_name);
|
||||
$cleaned_name = trim($cleaned_name, '-');
|
||||
$names[$name] = $cleaned_name;
|
||||
@@ -446,8 +447,8 @@ function token_clean_token_name($name) {
|
||||
/**
|
||||
* Do not use this function yet. Its API has not been finalized.
|
||||
*/
|
||||
function token_render_array(array $array, array $options = array()) {
|
||||
$rendered = array();
|
||||
function token_render_array(array $array, array $options = []) {
|
||||
$rendered = [];
|
||||
|
||||
/** @var \Drupal\Core\Render\RendererInterface $renderer */
|
||||
$renderer = \Drupal::service('renderer');
|
||||
@@ -463,7 +464,7 @@ function token_render_array(array $array, array $options = array()) {
|
||||
/**
|
||||
* Do not use this function yet. Its API has not been finalized.
|
||||
*/
|
||||
function token_render_array_value($value, array $options = array()) {
|
||||
function token_render_array_value($value, array $options = []) {
|
||||
/** @var \Drupal\Core\Render\RendererInterface $renderer */
|
||||
$renderer = \Drupal::service('renderer');
|
||||
|
||||
@@ -497,7 +498,7 @@ function token_render_cache_get($elements) {
|
||||
*/
|
||||
function token_render_cache_set(&$markup, $elements) {
|
||||
// This should only run of drupal_render_cache_set() did not.
|
||||
if (in_array(\Drupal::request()->server->get('REQUEST_METHOD'), array('GET', 'HEAD'))) {
|
||||
if (in_array(\Drupal::request()->server->get('REQUEST_METHOD'), ['GET', 'HEAD'])) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -519,10 +520,10 @@ function token_render_cache_set(&$markup, $elements) {
|
||||
* List of menu link parent titles.
|
||||
*/
|
||||
function token_menu_link_load_all_parents($plugin_id, $langcode) {
|
||||
$cache = &drupal_static(__FUNCTION__, array());
|
||||
$cache = &drupal_static(__FUNCTION__, []);
|
||||
|
||||
if (!isset($cache[$plugin_id][$langcode])) {
|
||||
$cache[$plugin_id][$langcode] = array();
|
||||
$cache[$plugin_id][$langcode] = [];
|
||||
/** @var \Drupal\Core\Menu\MenuLinkManagerInterface $menu_link_manager */
|
||||
$menu_link_manager = \Drupal::service('plugin.manager.menu.link');
|
||||
$parent_ids = $menu_link_manager->getParentIds($plugin_id);
|
||||
@@ -530,7 +531,7 @@ function token_menu_link_load_all_parents($plugin_id, $langcode) {
|
||||
unset($parent_ids[$plugin_id]);
|
||||
foreach ($parent_ids as $parent_id) {
|
||||
$parent = $menu_link_manager->createInstance($parent_id);
|
||||
$cache[$plugin_id][$langcode] = array($parent_id => token_menu_link_translated_title($parent, $langcode)) + $cache[$plugin_id][$langcode];
|
||||
$cache[$plugin_id][$langcode] = [$parent_id => token_menu_link_translated_title($parent, $langcode)] + $cache[$plugin_id][$langcode];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -577,14 +578,14 @@ function token_menu_link_translated_title(MenuLinkInterface $menu_link, $langcod
|
||||
* The term parents collection.
|
||||
*/
|
||||
function token_taxonomy_term_load_all_parents($tid, $langcode) {
|
||||
$cache = &drupal_static(__FUNCTION__, array());
|
||||
$cache = &drupal_static(__FUNCTION__, []);
|
||||
|
||||
if (!is_numeric($tid)) {
|
||||
return array();
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!isset($cache[$langcode][$tid])) {
|
||||
$cache[$langcode][$tid] = array();
|
||||
$cache[$langcode][$tid] = [];
|
||||
/** @var \Drupal\taxonomy\TermStorageInterface $term_storage */
|
||||
$term_storage = \Drupal::entityTypeManager()->getStorage('taxonomy_term');
|
||||
$parents = $term_storage->loadAllParents($tid);
|
||||
@@ -605,7 +606,7 @@ function token_element_children(&$elements, $sort = FALSE) {
|
||||
$sort = isset($elements['#sorted']) ? !$elements['#sorted'] : $sort;
|
||||
|
||||
// Filter out properties from the element, leaving only children.
|
||||
$children = array();
|
||||
$children = [];
|
||||
$sortable = FALSE;
|
||||
foreach ($elements as $key => $value) {
|
||||
if ($key === '' || $key[0] !== '#') {
|
||||
@@ -643,15 +644,15 @@ function token_element_children(&$elements, $sort = FALSE) {
|
||||
* List of node titles of the book parents.
|
||||
*/
|
||||
function token_book_load_all_parents(array $book) {
|
||||
$cache = &drupal_static(__FUNCTION__, array());
|
||||
$cache = &drupal_static(__FUNCTION__, []);
|
||||
|
||||
if (empty($book['nid'])) {
|
||||
return array();
|
||||
return [];
|
||||
}
|
||||
$nid = $book['nid'];
|
||||
|
||||
if (!isset($cache[$nid])) {
|
||||
$cache[$nid] = array();
|
||||
$cache[$nid] = [];
|
||||
$i = 1;
|
||||
while ($book["p$i"] != $nid) {
|
||||
$cache[$nid][] = Node::load($book["p$i"])->getTitle();
|
||||
@@ -666,7 +667,7 @@ function token_book_load_all_parents(array $book) {
|
||||
* Implements hook_entity_base_field_info().
|
||||
*/
|
||||
function token_entity_base_field_info(EntityTypeInterface $entity_type) {
|
||||
// We add a psuedo entity-reference field to track the menu entry created
|
||||
// We add a pseudo entity-reference field to track the menu entry created
|
||||
// from the node add/edit form so that tokens generated at that time that
|
||||
// reference the menu link can access the yet to be saved menu link.
|
||||
// @todo Revisit when https://www.drupal.org/node/2315773 is resolved.
|
||||
@@ -677,14 +678,14 @@ function token_entity_base_field_info(EntityTypeInterface $entity_type) {
|
||||
->setRevisionable(TRUE)
|
||||
->setSetting('target_type', 'menu_link_content')
|
||||
->setTranslatable(TRUE)
|
||||
->setDisplayOptions('view', array(
|
||||
->setDisplayOptions('view', [
|
||||
'label' => 'hidden',
|
||||
'region' => 'hidden',
|
||||
))
|
||||
])
|
||||
->setComputed(TRUE)
|
||||
->setDisplayOptions('form', array(
|
||||
->setDisplayOptions('form', [
|
||||
'region' => 'hidden',
|
||||
));
|
||||
]);
|
||||
|
||||
return $fields;
|
||||
}
|
||||
@@ -744,19 +745,19 @@ function token_node_menu_link_submit($entity_type, NodeInterface $node, &$form,
|
||||
else {
|
||||
if ($node->isNew()) {
|
||||
// Create a new menu_link_content entity.
|
||||
$entity = MenuLinkContent::create(array(
|
||||
$entity = MenuLinkContent::create([
|
||||
// Lets just reference the UUID for now, the link is not important for
|
||||
// token generation.
|
||||
'link' => ['uri' => 'internal:/node/' . $node->uuid()],
|
||||
'langcode' => $node->language()->getId(),
|
||||
));
|
||||
]);
|
||||
}
|
||||
else {
|
||||
// Create a new menu_link_content entity.
|
||||
$entity = MenuLinkContent::create(array(
|
||||
$entity = MenuLinkContent::create([
|
||||
'link' => ['uri' => 'entity:node/' . $node->id()],
|
||||
'langcode' => $node->language()->getId(),
|
||||
));
|
||||
]);
|
||||
}
|
||||
}
|
||||
$entity->title->value = trim($values['title']);
|
||||
@@ -779,7 +780,7 @@ function token_node_menu_link_submit($entity_type, NodeInterface $node, &$form,
|
||||
function token_node_insert(NodeInterface $node) {
|
||||
if ($node->hasField('menu_link') && $menu_link = $node->menu_link->entity) {
|
||||
// Update the menu-link to point to the now saved node.
|
||||
$menu_link->link = 'entity:node/' . $node->id();
|
||||
$menu_link->link = 'entity:node/' . $node->id();
|
||||
$menu_link->save();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ function template_preprocess_token_tree_link(&$variables) {
|
||||
'draggable' => TRUE,
|
||||
'autoResize' => FALSE,
|
||||
]),
|
||||
];
|
||||
];
|
||||
|
||||
$variables['link'] = Link::createFromRoute($variables['text'], 'token.tree', [], $variables['options'])->toRenderable();
|
||||
$variables['url'] = new Url('token.tree', [], $variables['options']);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user