Move into nested docroot
This commit is contained in:
parent
83a0d3a149
commit
c8b70abde9
13405 changed files with 0 additions and 0 deletions
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\shortcut\Controller;
|
||||
|
||||
use Drupal\Core\Controller\ControllerBase;
|
||||
use Drupal\shortcut\ShortcutSetInterface;
|
||||
use Drupal\shortcut\ShortcutInterface;
|
||||
|
||||
/**
|
||||
* Provides route responses for taxonomy.module.
|
||||
*/
|
||||
class ShortcutController extends ControllerBase {
|
||||
|
||||
/**
|
||||
* Returns a form to add a new shortcut to a given set.
|
||||
*
|
||||
* @param \Drupal\shortcut\ShortcutSetInterface $shortcut_set
|
||||
* The shortcut set this shortcut will be added to.
|
||||
*
|
||||
* @return array
|
||||
* The shortcut add form.
|
||||
*/
|
||||
public function addForm(ShortcutSetInterface $shortcut_set) {
|
||||
$shortcut = $this->entityManager()->getStorage('shortcut')->create(array('shortcut_set' => $shortcut_set->id()));
|
||||
return $this->entityFormBuilder()->getForm($shortcut, 'add');
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the selected shortcut.
|
||||
*
|
||||
* @param \Drupal\shortcut\ShortcutInterface $shortcut
|
||||
* The shortcut to delete.
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\RedirectResponse
|
||||
* A redirect to the previous location or the front page when destination
|
||||
* is not set.
|
||||
*/
|
||||
public function deleteShortcutLinkInline(ShortcutInterface $shortcut) {
|
||||
$label = $shortcut->label();
|
||||
|
||||
try {
|
||||
$shortcut->delete();
|
||||
drupal_set_message($this->t('The shortcut %title has been deleted.', array('%title' => $label)));
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
drupal_set_message($this->t('Unable to delete the shortcut for %title.', array('%title' => $label)), 'error');
|
||||
}
|
||||
|
||||
return $this->redirect('<front>');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\shortcut\Controller;
|
||||
|
||||
use Drupal\Core\Controller\ControllerBase;
|
||||
use Drupal\Core\Path\PathValidatorInterface;
|
||||
use Drupal\shortcut\ShortcutSetInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||
|
||||
/**
|
||||
* Builds the page for administering shortcut sets.
|
||||
*/
|
||||
class ShortcutSetController extends ControllerBase {
|
||||
|
||||
/**
|
||||
* The path validator.
|
||||
*
|
||||
* @var \Drupal\Core\Path\PathValidatorInterface
|
||||
*/
|
||||
protected $pathValidator;
|
||||
|
||||
/**
|
||||
* Creates a new ShortcutSetController instance.
|
||||
*
|
||||
* @param \Drupal\Core\Path\PathValidatorInterface $path_validator
|
||||
* The path validator.
|
||||
*/
|
||||
public function __construct(PathValidatorInterface $path_validator) {
|
||||
$this->pathValidator = $path_validator;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static($container->get('path.validator'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new link in the provided shortcut set.
|
||||
*
|
||||
* @param \Drupal\shortcut\ShortcutSetInterface $shortcut_set
|
||||
* The shortcut set to add a link to.
|
||||
* @param \Symfony\Component\HttpFoundation\Request $request
|
||||
* The request object.
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\RedirectResponse
|
||||
* A redirect response to the front page, or the previous location.
|
||||
*
|
||||
* @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
|
||||
*/
|
||||
public function addShortcutLinkInline(ShortcutSetInterface $shortcut_set, Request $request) {
|
||||
$link = $request->query->get('link');
|
||||
$name = $request->query->get('name');
|
||||
if (parse_url($link, PHP_URL_SCHEME) === NULL && $this->pathValidator->isValid($link)) {
|
||||
$shortcut = $this->entityManager()->getStorage('shortcut')->create(array(
|
||||
'title' => $name,
|
||||
'shortcut_set' => $shortcut_set->id(),
|
||||
'link' => array(
|
||||
'uri' => 'internal:/' . $link,
|
||||
),
|
||||
));
|
||||
|
||||
try {
|
||||
$shortcut->save();
|
||||
drupal_set_message($this->t('Added a shortcut for %title.', array('%title' => $shortcut->label())));
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
drupal_set_message($this->t('Unable to add a shortcut for %title.', array('%title' => $shortcut->label())), 'error');
|
||||
}
|
||||
|
||||
return $this->redirect('<front>');
|
||||
}
|
||||
|
||||
throw new AccessDeniedHttpException();
|
||||
}
|
||||
|
||||
}
|
184
web/core/modules/shortcut/src/Entity/Shortcut.php
Normal file
184
web/core/modules/shortcut/src/Entity/Shortcut.php
Normal file
|
@ -0,0 +1,184 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\shortcut\Entity;
|
||||
|
||||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\Core\Entity\ContentEntityBase;
|
||||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Field\BaseFieldDefinition;
|
||||
use Drupal\link\LinkItemInterface;
|
||||
use Drupal\shortcut\ShortcutInterface;
|
||||
|
||||
/**
|
||||
* Defines the shortcut entity class.
|
||||
*
|
||||
* @property \Drupal\link\LinkItemInterface link
|
||||
*
|
||||
* @ContentEntityType(
|
||||
* id = "shortcut",
|
||||
* label = @Translation("Shortcut link"),
|
||||
* handlers = {
|
||||
* "access" = "Drupal\shortcut\ShortcutAccessControlHandler",
|
||||
* "form" = {
|
||||
* "default" = "Drupal\shortcut\ShortcutForm",
|
||||
* "add" = "Drupal\shortcut\ShortcutForm",
|
||||
* "edit" = "Drupal\shortcut\ShortcutForm",
|
||||
* "delete" = "Drupal\shortcut\Form\ShortcutDeleteForm"
|
||||
* },
|
||||
* "translation" = "Drupal\content_translation\ContentTranslationHandler"
|
||||
* },
|
||||
* base_table = "shortcut",
|
||||
* data_table = "shortcut_field_data",
|
||||
* translatable = TRUE,
|
||||
* entity_keys = {
|
||||
* "id" = "id",
|
||||
* "uuid" = "uuid",
|
||||
* "bundle" = "shortcut_set",
|
||||
* "label" = "title",
|
||||
* "langcode" = "langcode",
|
||||
* },
|
||||
* links = {
|
||||
* "canonical" = "/admin/config/user-interface/shortcut/link/{shortcut}",
|
||||
* "delete-form" = "/admin/config/user-interface/shortcut/link/{shortcut}/delete",
|
||||
* "edit-form" = "/admin/config/user-interface/shortcut/link/{shortcut}",
|
||||
* },
|
||||
* list_cache_tags = { "config:shortcut_set_list" },
|
||||
* bundle_entity_type = "shortcut_set"
|
||||
* )
|
||||
*/
|
||||
class Shortcut extends ContentEntityBase implements ShortcutInterface {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getTitle() {
|
||||
return $this->get('title')->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setTitle($link_title) {
|
||||
$this->set('title', $link_title);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getWeight() {
|
||||
return $this->get('weight')->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setWeight($weight) {
|
||||
$this->set('weight', $weight);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getUrl() {
|
||||
return $this->link->first()->getUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function postSave(EntityStorageInterface $storage, $update = TRUE) {
|
||||
parent::postSave($storage, $update);
|
||||
|
||||
// Entity::postSave() calls Entity::invalidateTagsOnSave(), which only
|
||||
// handles the regular cases. The Shortcut entity has one special case: a
|
||||
// newly created shortcut is *also* added to a shortcut set, so we must
|
||||
// invalidate the associated shortcut set's cache tag.
|
||||
if (!$update) {
|
||||
Cache::invalidateTags($this->getCacheTagsToInvalidate());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
|
||||
/** @var \Drupal\Core\Field\BaseFieldDefinition[] $fields */
|
||||
$fields = parent::baseFieldDefinitions($entity_type);
|
||||
|
||||
$fields['id']->setDescription(t('The ID of the shortcut.'));
|
||||
|
||||
$fields['uuid']->setDescription(t('The UUID of the shortcut.'));
|
||||
|
||||
$fields['shortcut_set']->setLabel(t('Shortcut set'))
|
||||
->setDescription(t('The bundle of the shortcut.'));
|
||||
|
||||
$fields['langcode']->setDescription(t('The language code of the shortcut.'));
|
||||
|
||||
$fields['title'] = BaseFieldDefinition::create('string')
|
||||
->setLabel(t('Name'))
|
||||
->setDescription(t('The name of the shortcut.'))
|
||||
->setRequired(TRUE)
|
||||
->setTranslatable(TRUE)
|
||||
->setSetting('max_length', 255)
|
||||
->setDisplayOptions('form', array(
|
||||
'type' => 'string_textfield',
|
||||
'weight' => -10,
|
||||
'settings' => array(
|
||||
'size' => 40,
|
||||
),
|
||||
));
|
||||
|
||||
$fields['weight'] = BaseFieldDefinition::create('integer')
|
||||
->setLabel(t('Weight'))
|
||||
->setDescription(t('Weight among shortcuts in the same shortcut set.'));
|
||||
|
||||
$fields['link'] = BaseFieldDefinition::create('link')
|
||||
->setLabel(t('Path'))
|
||||
->setDescription(t('The location this shortcut points to.'))
|
||||
->setRequired(TRUE)
|
||||
->setSettings(array(
|
||||
'link_type' => LinkItemInterface::LINK_INTERNAL,
|
||||
'title' => DRUPAL_DISABLED,
|
||||
))
|
||||
->setDisplayOptions('form', array(
|
||||
'type' => 'link_default',
|
||||
'weight' => 0,
|
||||
))
|
||||
->setDisplayConfigurable('form', TRUE);
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheTagsToInvalidate() {
|
||||
return $this->shortcut_set->entity->getCacheTags();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort shortcut objects.
|
||||
*
|
||||
* Callback for uasort().
|
||||
*
|
||||
* @param \Drupal\shortcut\ShortcutInterface $a
|
||||
* First item for comparison.
|
||||
* @param \Drupal\shortcut\ShortcutInterface $b
|
||||
* Second item for comparison.
|
||||
*
|
||||
* @return int
|
||||
* The comparison result for uasort().
|
||||
*/
|
||||
public static function sort(ShortcutInterface $a, ShortcutInterface $b) {
|
||||
$a_weight = $a->getWeight();
|
||||
$b_weight = $b->getWeight();
|
||||
if ($a_weight == $b_weight) {
|
||||
return strnatcasecmp($a->getTitle(), $b->getTitle());
|
||||
}
|
||||
return ($a_weight < $b_weight) ? -1 : 1;
|
||||
}
|
||||
|
||||
}
|
124
web/core/modules/shortcut/src/Entity/ShortcutSet.php
Normal file
124
web/core/modules/shortcut/src/Entity/ShortcutSet.php
Normal file
|
@ -0,0 +1,124 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\shortcut\Entity;
|
||||
|
||||
use Drupal\Core\Config\Entity\ConfigEntityBundleBase;
|
||||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
use Drupal\shortcut\ShortcutSetInterface;
|
||||
|
||||
/**
|
||||
* Defines the Shortcut set configuration entity.
|
||||
*
|
||||
* @ConfigEntityType(
|
||||
* id = "shortcut_set",
|
||||
* label = @Translation("Shortcut set"),
|
||||
* handlers = {
|
||||
* "storage" = "Drupal\shortcut\ShortcutSetStorage",
|
||||
* "access" = "Drupal\shortcut\ShortcutSetAccessControlHandler",
|
||||
* "list_builder" = "Drupal\shortcut\ShortcutSetListBuilder",
|
||||
* "form" = {
|
||||
* "default" = "Drupal\shortcut\ShortcutSetForm",
|
||||
* "add" = "Drupal\shortcut\ShortcutSetForm",
|
||||
* "edit" = "Drupal\shortcut\ShortcutSetForm",
|
||||
* "customize" = "Drupal\shortcut\Form\SetCustomize",
|
||||
* "delete" = "Drupal\shortcut\Form\ShortcutSetDeleteForm"
|
||||
* }
|
||||
* },
|
||||
* config_prefix = "set",
|
||||
* bundle_of = "shortcut",
|
||||
* entity_keys = {
|
||||
* "id" = "id",
|
||||
* "label" = "label"
|
||||
* },
|
||||
* links = {
|
||||
* "customize-form" = "/admin/config/user-interface/shortcut/manage/{shortcut_set}/customize",
|
||||
* "delete-form" = "/admin/config/user-interface/shortcut/manage/{shortcut_set}/delete",
|
||||
* "edit-form" = "/admin/config/user-interface/shortcut/manage/{shortcut_set}",
|
||||
* "collection" = "/admin/config/user-interface/shortcut",
|
||||
* },
|
||||
* config_export = {
|
||||
* "id",
|
||||
* "label",
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
class ShortcutSet extends ConfigEntityBundleBase implements ShortcutSetInterface {
|
||||
|
||||
/**
|
||||
* The machine name for the configuration entity.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
/**
|
||||
* The human-readable name of the configuration entity.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $label;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function postSave(EntityStorageInterface $storage, $update = TRUE) {
|
||||
parent::postSave($storage, $update);
|
||||
|
||||
if (!$update && !$this->isSyncing()) {
|
||||
// Save a new shortcut set with links copied from the user's default set.
|
||||
$default_set = shortcut_default_set();
|
||||
// This is the default set, do not copy shortcuts.
|
||||
if ($default_set->id() != $this->id()) {
|
||||
foreach ($default_set->getShortcuts() as $shortcut) {
|
||||
$shortcut = $shortcut->createDuplicate();
|
||||
$shortcut->enforceIsNew();
|
||||
$shortcut->shortcut_set->target_id = $this->id();
|
||||
$shortcut->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function preDelete(EntityStorageInterface $storage, array $entities) {
|
||||
parent::preDelete($storage, $entities);
|
||||
|
||||
foreach ($entities as $entity) {
|
||||
$storage->deleteAssignedShortcutSets($entity);
|
||||
|
||||
// Next, delete the shortcuts for this set.
|
||||
$shortcut_ids = \Drupal::entityQuery('shortcut')
|
||||
->condition('shortcut_set', $entity->id(), '=')
|
||||
->execute();
|
||||
|
||||
$controller = \Drupal::entityManager()->getStorage('shortcut');
|
||||
$entities = $controller->loadMultiple($shortcut_ids);
|
||||
$controller->delete($entities);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function resetLinkWeights() {
|
||||
$weight = -50;
|
||||
foreach ($this->getShortcuts() as $shortcut) {
|
||||
$shortcut->setWeight(++$weight);
|
||||
$shortcut->save();
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getShortcuts() {
|
||||
$shortcuts = \Drupal::entityManager()->getStorage('shortcut')->loadByProperties(array('shortcut_set' => $this->id()));
|
||||
uasort($shortcuts, array('\Drupal\shortcut\Entity\Shortcut', 'sort'));
|
||||
return $shortcuts;
|
||||
}
|
||||
|
||||
}
|
110
web/core/modules/shortcut/src/Form/SetCustomize.php
Normal file
110
web/core/modules/shortcut/src/Form/SetCustomize.php
Normal file
|
@ -0,0 +1,110 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\shortcut\Form;
|
||||
|
||||
use Drupal\Core\Entity\EntityForm;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Render\Element;
|
||||
|
||||
/**
|
||||
* Builds the shortcut set customize form.
|
||||
*/
|
||||
class SetCustomize extends EntityForm {
|
||||
|
||||
/**
|
||||
* The entity being used by this form.
|
||||
*
|
||||
* @var \Drupal\shortcut\ShortcutSetInterface
|
||||
*/
|
||||
protected $entity;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function form(array $form, FormStateInterface $form_state) {
|
||||
$form = parent::form($form, $form_state);
|
||||
$form['shortcuts'] = array(
|
||||
'#tree' => TRUE,
|
||||
'#weight' => -20,
|
||||
);
|
||||
|
||||
$form['shortcuts']['links'] = array(
|
||||
'#type' => 'table',
|
||||
'#header' => array(t('Name'), t('Weight'), t('Operations')),
|
||||
'#empty' => $this->t('No shortcuts available. <a href=":link">Add a shortcut</a>', array(':link' => $this->url('shortcut.link_add', array('shortcut_set' => $this->entity->id())))),
|
||||
'#attributes' => array('id' => 'shortcuts'),
|
||||
'#tabledrag' => array(
|
||||
array(
|
||||
'action' => 'order',
|
||||
'relationship' => 'sibling',
|
||||
'group' => 'shortcut-weight',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
foreach ($this->entity->getShortcuts() as $shortcut) {
|
||||
$id = $shortcut->id();
|
||||
$url = $shortcut->getUrl();
|
||||
if (!$url->access()) {
|
||||
continue;
|
||||
}
|
||||
$form['shortcuts']['links'][$id]['#attributes']['class'][] = 'draggable';
|
||||
$form['shortcuts']['links'][$id]['name'] = array(
|
||||
'#type' => 'link',
|
||||
'#title' => $shortcut->getTitle(),
|
||||
) + $url->toRenderArray();
|
||||
unset($form['shortcuts']['links'][$id]['name']['#access_callback']);
|
||||
$form['shortcuts']['links'][$id]['#weight'] = $shortcut->getWeight();
|
||||
$form['shortcuts']['links'][$id]['weight'] = array(
|
||||
'#type' => 'weight',
|
||||
'#title' => t('Weight for @title', array('@title' => $shortcut->getTitle())),
|
||||
'#title_display' => 'invisible',
|
||||
'#default_value' => $shortcut->getWeight(),
|
||||
'#attributes' => array('class' => array('shortcut-weight')),
|
||||
);
|
||||
|
||||
$links['edit'] = array(
|
||||
'title' => t('Edit'),
|
||||
'url' => $shortcut->urlInfo(),
|
||||
);
|
||||
$links['delete'] = array(
|
||||
'title' => t('Delete'),
|
||||
'url' => $shortcut->urlInfo('delete-form'),
|
||||
);
|
||||
$form['shortcuts']['links'][$id]['operations'] = array(
|
||||
'#type' => 'operations',
|
||||
'#links' => $links,
|
||||
'#access' => $url->access(),
|
||||
);
|
||||
}
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function actions(array $form, FormStateInterface $form_state) {
|
||||
// Only includes a Save action for the entity, no direct Delete button.
|
||||
return array(
|
||||
'submit' => array(
|
||||
'#type' => 'submit',
|
||||
'#value' => t('Save'),
|
||||
'#access' => (bool) Element::getVisibleChildren($form['shortcuts']['links']),
|
||||
'#submit' => array('::submitForm', '::save'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function save(array $form, FormStateInterface $form_state) {
|
||||
foreach ($this->entity->getShortcuts() as $shortcut) {
|
||||
$weight = $form_state->getValue(array('shortcuts', 'links', $shortcut->id(), 'weight'));
|
||||
$shortcut->setWeight($weight);
|
||||
$shortcut->save();
|
||||
}
|
||||
drupal_set_message(t('The shortcut set has been updated.'));
|
||||
}
|
||||
|
||||
}
|
36
web/core/modules/shortcut/src/Form/ShortcutDeleteForm.php
Normal file
36
web/core/modules/shortcut/src/Form/ShortcutDeleteForm.php
Normal file
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\shortcut\Form;
|
||||
|
||||
use Drupal\Core\Entity\ContentEntityDeleteForm;
|
||||
use Drupal\Core\Url;
|
||||
|
||||
/**
|
||||
* Builds the shortcut link deletion form.
|
||||
*/
|
||||
class ShortcutDeleteForm extends ContentEntityDeleteForm {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormId() {
|
||||
return 'shortcut_confirm_delete';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCancelUrl() {
|
||||
return new Url('entity.shortcut_set.customize_form', array(
|
||||
'shortcut_set' => $this->entity->bundle(),
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getRedirectUrl() {
|
||||
return $this->getCancelUrl();
|
||||
}
|
||||
|
||||
}
|
75
web/core/modules/shortcut/src/Form/ShortcutSetDeleteForm.php
Normal file
75
web/core/modules/shortcut/src/Form/ShortcutSetDeleteForm.php
Normal file
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\shortcut\Form;
|
||||
|
||||
use Drupal\Core\Entity\EntityDeleteForm;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\shortcut\ShortcutSetStorageInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Drupal\Core\Database\Connection;
|
||||
|
||||
/**
|
||||
* Builds the shortcut set deletion form.
|
||||
*/
|
||||
class ShortcutSetDeleteForm extends EntityDeleteForm {
|
||||
|
||||
/**
|
||||
* The database connection.
|
||||
*
|
||||
* @var \Drupal\Core\Database\Connection
|
||||
*/
|
||||
protected $database;
|
||||
|
||||
/**
|
||||
* The shortcut storage.
|
||||
*
|
||||
* @var \Drupal\shortcut\ShortcutSetStorageInterface
|
||||
*/
|
||||
protected $storage;
|
||||
|
||||
/**
|
||||
* Constructs a ShortcutSetDeleteForm object.
|
||||
*/
|
||||
public function __construct(Connection $database, ShortcutSetStorageInterface $storage) {
|
||||
$this->database = $database;
|
||||
$this->storage = $storage;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('database'),
|
||||
$container->get('entity.manager')->getStorage('shortcut_set')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state) {
|
||||
// Find out how many users are directly assigned to this shortcut set, and
|
||||
// make a message.
|
||||
$number = $this->storage->countAssignedUsers($this->entity);
|
||||
$info = '';
|
||||
if ($number) {
|
||||
$info .= '<p>' . $this->formatPlural($number,
|
||||
'1 user has chosen or been assigned to this shortcut set.',
|
||||
'@count users have chosen or been assigned to this shortcut set.') . '</p>';
|
||||
}
|
||||
|
||||
// Also, if a module implements hook_shortcut_default_set(), it's possible
|
||||
// that this set is being used as a default set. Add a message about that too.
|
||||
if ($this->moduleHandler->getImplementations('shortcut_default_set')) {
|
||||
$info .= '<p>' . t('If you have chosen this shortcut set as the default for some or all users, they may also be affected by deleting it.') . '</p>';
|
||||
}
|
||||
|
||||
$form['info'] = array(
|
||||
'#markup' => $info,
|
||||
);
|
||||
|
||||
return parent::buildForm($form, $form_state);
|
||||
}
|
||||
|
||||
}
|
227
web/core/modules/shortcut/src/Form/SwitchShortcutSet.php
Normal file
227
web/core/modules/shortcut/src/Form/SwitchShortcutSet.php
Normal file
|
@ -0,0 +1,227 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\shortcut\Form;
|
||||
|
||||
use Drupal\Core\Form\FormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\shortcut\Entity\ShortcutSet;
|
||||
use Drupal\shortcut\ShortcutSetStorageInterface;
|
||||
use Drupal\user\UserInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Builds the shortcut set switch form.
|
||||
*/
|
||||
class SwitchShortcutSet extends FormBase {
|
||||
|
||||
/**
|
||||
* The account the shortcut set is for.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $user;
|
||||
|
||||
/**
|
||||
* The shortcut set storage.
|
||||
*
|
||||
* @var \Drupal\shortcut\ShortcutSetStorageInterface
|
||||
*/
|
||||
protected $shortcutSetStorage;
|
||||
|
||||
/**
|
||||
* Constructs a SwitchShortcutSet object.
|
||||
*
|
||||
* @param \Drupal\shortcut\ShortcutSetStorageInterface $shortcut_set_storage
|
||||
* The shortcut set storage.
|
||||
*/
|
||||
public function __construct(ShortcutSetStorageInterface $shortcut_set_storage) {
|
||||
$this->shortcutSetStorage = $shortcut_set_storage;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('entity.manager')->getStorage('shortcut_set')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormId() {
|
||||
return 'shortcut_set_switch';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state, UserInterface $user = NULL) {
|
||||
$account = $this->currentUser();
|
||||
|
||||
$this->user = $user;
|
||||
|
||||
// Prepare the list of shortcut sets.
|
||||
$options = array_map(function (ShortcutSet $set) {
|
||||
return $set->label();
|
||||
}, $this->shortcutSetStorage->loadMultiple());
|
||||
|
||||
$current_set = shortcut_current_displayed_set($this->user);
|
||||
|
||||
// Only administrators can add shortcut sets.
|
||||
$add_access = $account->hasPermission('administer shortcuts');
|
||||
if ($add_access) {
|
||||
$options['new'] = $this->t('New set');
|
||||
}
|
||||
|
||||
$account_is_user = $this->user->id() == $account->id();
|
||||
if (count($options) > 1) {
|
||||
$form['set'] = array(
|
||||
'#type' => 'radios',
|
||||
'#title' => $account_is_user ? $this->t('Choose a set of shortcuts to use') : $this->t('Choose a set of shortcuts for this user'),
|
||||
'#options' => $options,
|
||||
'#default_value' => $current_set->id(),
|
||||
);
|
||||
|
||||
$form['label'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Label'),
|
||||
'#description' => $this->t('The new set is created by copying items from your default shortcut set.'),
|
||||
'#access' => $add_access,
|
||||
'#states' => array(
|
||||
'visible' => array(
|
||||
':input[name="set"]' => array('value' => 'new'),
|
||||
),
|
||||
'required' => array(
|
||||
':input[name="set"]' => array('value' => 'new'),
|
||||
),
|
||||
),
|
||||
);
|
||||
$form['id'] = array(
|
||||
'#type' => 'machine_name',
|
||||
'#machine_name' => array(
|
||||
'exists' => array($this, 'exists'),
|
||||
'replace_pattern' => '[^a-z0-9-]+',
|
||||
'replace' => '-',
|
||||
),
|
||||
// This ID could be used for menu name.
|
||||
'#maxlength' => 23,
|
||||
'#states' => array(
|
||||
'required' => array(
|
||||
':input[name="set"]' => array('value' => 'new'),
|
||||
),
|
||||
),
|
||||
'#required' => FALSE,
|
||||
);
|
||||
|
||||
if (!$account_is_user) {
|
||||
$default_set = $this->shortcutSetStorage->getDefaultSet($this->user);
|
||||
$form['new']['#description'] = $this->t('The new set is created by copying items from the %default set.', array('%default' => $default_set->label()));
|
||||
}
|
||||
|
||||
$form['actions'] = array('#type' => 'actions');
|
||||
$form['actions']['submit'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => $this->t('Change set'),
|
||||
);
|
||||
}
|
||||
else {
|
||||
// There is only 1 option, so output a message in the $form array.
|
||||
$form['info'] = array(
|
||||
'#markup' => '<p>' . $this->t('You are currently using the %set-name shortcut set.', array('%set-name' => $current_set->label())) . '</p>',
|
||||
);
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a shortcut set exists already.
|
||||
*
|
||||
* @param string $id
|
||||
* The set ID to check.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the shortcut set exists, FALSE otherwise.
|
||||
*/
|
||||
public function exists($id) {
|
||||
return (bool) $this->shortcutSetStorage->getQuery()
|
||||
->condition('id', $id)
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validateForm(array &$form, FormStateInterface $form_state) {
|
||||
if ($form_state->getValue('set') == 'new') {
|
||||
// Check to prevent creating a shortcut set with an empty title.
|
||||
if (trim($form_state->getValue('label')) == '') {
|
||||
$form_state->setErrorByName('label', $this->t('The new set label is required.'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||
$account = $this->currentUser();
|
||||
|
||||
$account_is_user = $this->user->id() == $account->id();
|
||||
if ($form_state->getValue('set') == 'new') {
|
||||
// Save a new shortcut set with links copied from the user's default set.
|
||||
/* @var \Drupal\shortcut\Entity\ShortcutSet $set */
|
||||
$set = $this->shortcutSetStorage->create(array(
|
||||
'id' => $form_state->getValue('id'),
|
||||
'label' => $form_state->getValue('label'),
|
||||
));
|
||||
$set->save();
|
||||
$replacements = array(
|
||||
'%user' => $this->user->label(),
|
||||
'%set_name' => $set->label(),
|
||||
':switch-url' => $this->url('<current>'),
|
||||
);
|
||||
if ($account_is_user) {
|
||||
// Only administrators can create new shortcut sets, so we know they have
|
||||
// access to switch back.
|
||||
drupal_set_message($this->t('You are now using the new %set_name shortcut set. You can edit it from this page or <a href=":switch-url">switch back to a different one.</a>', $replacements));
|
||||
}
|
||||
else {
|
||||
drupal_set_message($this->t('%user is now using a new shortcut set called %set_name. You can edit it from this page.', $replacements));
|
||||
}
|
||||
$form_state->setRedirect(
|
||||
'entity.shortcut_set.customize_form',
|
||||
array('shortcut_set' => $set->id())
|
||||
);
|
||||
}
|
||||
else {
|
||||
// Switch to a different shortcut set.
|
||||
/* @var \Drupal\shortcut\Entity\ShortcutSet $set */
|
||||
$set = $this->shortcutSetStorage->load($form_state->getValue('set'));
|
||||
$replacements = array(
|
||||
'%user' => $this->user->getDisplayName(),
|
||||
'%set_name' => $set->label(),
|
||||
);
|
||||
drupal_set_message($account_is_user ? $this->t('You are now using the %set_name shortcut set.', $replacements) : $this->t('%user is now using the %set_name shortcut set.', $replacements));
|
||||
}
|
||||
|
||||
// Assign the shortcut set to the provided user account.
|
||||
$this->shortcutSetStorage->assignUser($set, $this->user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks access for the shortcut set switch form.
|
||||
*
|
||||
* @param \Drupal\user\UserInterface $user
|
||||
* (optional) The owner of the shortcut set.
|
||||
*
|
||||
* @return \Drupal\Core\Access\AccessResultInterface
|
||||
* The access result.
|
||||
*/
|
||||
public function checkAccess(UserInterface $user = NULL) {
|
||||
return shortcut_set_switch_access($user);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\shortcut\Plugin\Block;
|
||||
|
||||
use Drupal\Core\Access\AccessResult;
|
||||
use Drupal\Core\Block\BlockBase;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
|
||||
/**
|
||||
* Provides a 'Shortcut' block.
|
||||
*
|
||||
* @Block(
|
||||
* id = "shortcuts",
|
||||
* admin_label = @Translation("Shortcuts"),
|
||||
* category = @Translation("Menus")
|
||||
* )
|
||||
*/
|
||||
class ShortcutsBlock extends BlockBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function build() {
|
||||
return array(
|
||||
shortcut_renderable_links(shortcut_current_displayed_set()),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function blockAccess(AccountInterface $account) {
|
||||
return AccessResult::allowedIfHasPermission($account, 'access shortcuts');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\shortcut\Plugin\migrate\destination;
|
||||
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\migrate\Plugin\migrate\destination\EntityConfigBase;
|
||||
|
||||
/**
|
||||
* @MigrateDestination(
|
||||
* id = "entity:shortcut_set"
|
||||
* )
|
||||
*/
|
||||
class EntityShortcutSet extends EntityConfigBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getEntity(Row $row, array $old_destination_id_values) {
|
||||
$entity = parent::getEntity($row, $old_destination_id_values);
|
||||
// Set the "syncing" flag to TRUE, to avoid duplication of default
|
||||
// shortcut links
|
||||
$entity->setSyncing(TRUE);
|
||||
return $entity;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\shortcut\Plugin\migrate\destination;
|
||||
|
||||
use Drupal\shortcut\ShortcutSetStorageInterface;
|
||||
use Drupal\user\Entity\User;
|
||||
use Drupal\migrate\Plugin\MigrationInterface;
|
||||
use Drupal\migrate\Row;
|
||||
use Drupal\migrate\Plugin\migrate\destination\DestinationBase;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
|
||||
/**
|
||||
* @MigrateDestination(
|
||||
* id = "shortcut_set_users"
|
||||
* )
|
||||
*/
|
||||
class ShortcutSetUsers extends DestinationBase implements ContainerFactoryPluginInterface {
|
||||
|
||||
/**
|
||||
* The shortcut set storage handler.
|
||||
*
|
||||
* @var \Drupal\shortcut\ShortcutSetStorageInterface
|
||||
*/
|
||||
protected $shortcutSetStorage;
|
||||
|
||||
/**
|
||||
* Constructs an entity destination plugin.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\migrate\Plugin\MigrationInterface $migration
|
||||
* The migration.
|
||||
* @param \Drupal\shortcut\ShortcutSetStorageInterface $shortcut_set_storage
|
||||
* The shortcut_set entity storage handler.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, ShortcutSetStorageInterface $shortcut_set_storage) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition, $migration);
|
||||
$this->shortcutSetStorage = $shortcut_set_storage;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$migration,
|
||||
$container->get('entity.manager')->getStorage('shortcut_set')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
return array(
|
||||
'set_name' => array(
|
||||
'type' => 'string',
|
||||
),
|
||||
'uid' => array(
|
||||
'type' => 'integer',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields(MigrationInterface $migration = NULL) {
|
||||
return [
|
||||
'uid' => 'The users.uid for this set.',
|
||||
'source' => 'The shortcut_set.set_name that will be displayed for this user.',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function import(Row $row, array $old_destination_id_values = array()) {
|
||||
/** @var \Drupal\shortcut\ShortcutSetInterface $set */
|
||||
$set = $this->shortcutSetStorage->load($row->getDestinationProperty('set_name'));
|
||||
/** @var \Drupal\user\UserInterface $account */
|
||||
$account = User::load($row->getDestinationProperty('uid'));
|
||||
$this->shortcutSetStorage->assignUser($set, $account);
|
||||
|
||||
return array($set->id(), $account->id());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\shortcut\Plugin\migrate\source\d7;
|
||||
|
||||
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
||||
|
||||
/**
|
||||
* Drupal 7 shortcut links source from database.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d7_shortcut",
|
||||
* source_provider = "shortcut"
|
||||
* )
|
||||
*/
|
||||
class Shortcut extends DrupalSqlBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() {
|
||||
return $this->select('menu_links', 'ml')
|
||||
->fields('ml', array('mlid', 'menu_name', 'link_path', 'link_title', 'weight'))
|
||||
->condition('hidden', '0')
|
||||
->condition('menu_name', 'shortcut-set-%', 'LIKE')
|
||||
->orderBy('ml.mlid');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields() {
|
||||
return array(
|
||||
'mlid' => $this->t("The menu.mlid primary key for this menu item (= shortcut link)."),
|
||||
'menu_name' => $this->t("The menu_name (= set name) for this shortcut link."),
|
||||
'link_path' => $this->t("The link for this shortcut."),
|
||||
'link_title' => $this->t("The title for this shortcut."),
|
||||
'weight' => $this->t("The weight for this shortcut"),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
$ids['mlid']['type'] = 'integer';
|
||||
return $ids;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\shortcut\Plugin\migrate\source\d7;
|
||||
|
||||
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
||||
|
||||
/**
|
||||
* Drupal 7 shortcut_set source from database.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d7_shortcut_set",
|
||||
* source_provider = "shortcut"
|
||||
* )
|
||||
*/
|
||||
class ShortcutSet extends DrupalSqlBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() {
|
||||
return $this->select('shortcut_set', 'ss')->fields('ss');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields() {
|
||||
return array(
|
||||
'set_name' => $this->t("The name under which the set's links are stored."),
|
||||
'title' => $this->t("The title of the set."),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
$ids['set_name']['type'] = 'string';
|
||||
return $ids;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\shortcut\Plugin\migrate\source\d7;
|
||||
|
||||
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
||||
|
||||
/**
|
||||
* Drupal 7 shortcut_set_users source from database.
|
||||
*
|
||||
* @MigrateSource(
|
||||
* id = "d7_shortcut_set_users",
|
||||
* source_provider = "shortcut"
|
||||
* )
|
||||
*/
|
||||
class ShortcutSetUsers extends DrupalSqlBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() {
|
||||
return $this->select('shortcut_set_users', 'ssu')->fields('ssu');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fields() {
|
||||
return array(
|
||||
'uid' => $this->t('The users.uid for this set.'),
|
||||
'set_name' => $this->t('The shortcut_set.set_name that will be displayed for this user.'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIds() {
|
||||
return array(
|
||||
'set_name' => array(
|
||||
'type' => 'string',
|
||||
),
|
||||
'uid' => array(
|
||||
'type' => 'integer',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\shortcut;
|
||||
|
||||
use Drupal\Core\Access\AccessResult;
|
||||
use Drupal\Core\Entity\EntityAccessControlHandler;
|
||||
use Drupal\Core\Entity\EntityHandlerInterface;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Defines the access control handler for the shortcut entity type.
|
||||
*
|
||||
* @see \Drupal\shortcut\Entity\Shortcut
|
||||
*/
|
||||
class ShortcutAccessControlHandler extends EntityAccessControlHandler implements EntityHandlerInterface {
|
||||
|
||||
/**
|
||||
* The shortcut_set storage.
|
||||
*
|
||||
* @var \Drupal\shortcut\ShortcutSetStorageInterface
|
||||
*/
|
||||
protected $shortcutSetStorage;
|
||||
|
||||
/**
|
||||
* Constructs a ShortcutAccessControlHandler object.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
|
||||
* The entity type definition.
|
||||
* @param \Drupal\shortcut\ShortcutSetStorageInterface $shortcut_set_storage
|
||||
* The shortcut_set storage.
|
||||
*/
|
||||
public function __construct(EntityTypeInterface $entity_type, ShortcutSetStorageInterface $shortcut_set_storage) {
|
||||
parent::__construct($entity_type);
|
||||
$this->shortcutSetStorage = $shortcut_set_storage;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
|
||||
return new static(
|
||||
$entity_type,
|
||||
$container->get('entity.manager')->getStorage('shortcut_set')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
|
||||
if ($shortcut_set = $this->shortcutSetStorage->load($entity->bundle())) {
|
||||
return shortcut_set_edit_access($shortcut_set, $account);
|
||||
}
|
||||
// @todo Fix this bizarre code: how can a shortcut exist without a shortcut
|
||||
// set? The above if-test is unnecessary. See https://www.drupal.org/node/2339903.
|
||||
return AccessResult::neutral()->addCacheableDependency($entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
|
||||
if ($shortcut_set = $this->shortcutSetStorage->load($entity_bundle)) {
|
||||
return shortcut_set_edit_access($shortcut_set, $account);
|
||||
}
|
||||
// @todo Fix this bizarre code: how can a shortcut exist without a shortcut
|
||||
// set? The above if-test is unnecessary. See https://www.drupal.org/node/2339903.
|
||||
return AccessResult::neutral();
|
||||
}
|
||||
|
||||
}
|
51
web/core/modules/shortcut/src/ShortcutForm.php
Normal file
51
web/core/modules/shortcut/src/ShortcutForm.php
Normal file
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\shortcut;
|
||||
|
||||
use Drupal\Core\Entity\ContentEntityForm;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
||||
/**
|
||||
* Form handler for the shortcut entity forms.
|
||||
*/
|
||||
class ShortcutForm extends ContentEntityForm {
|
||||
|
||||
/**
|
||||
* The entity being used by this form.
|
||||
*
|
||||
* @var \Drupal\shortcut\ShortcutInterface
|
||||
*/
|
||||
protected $entity;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function save(array $form, FormStateInterface $form_state) {
|
||||
$entity = $this->entity;
|
||||
$status = $entity->save();
|
||||
$url = $entity->getUrl();
|
||||
// There's an edge case where a user can have permission to
|
||||
// 'link to any content', but has no right to access the linked page. So we
|
||||
// check the access before showing the link.
|
||||
if ($url->access()) {
|
||||
$view_link = \Drupal::l($entity->getTitle(), $url);
|
||||
}
|
||||
else {
|
||||
$view_link = $entity->getTitle();
|
||||
}
|
||||
|
||||
if ($status == SAVED_UPDATED) {
|
||||
$message = $this->t('The shortcut %link has been updated.', array('%link' => $view_link));
|
||||
}
|
||||
else {
|
||||
$message = $this->t('Added a shortcut for %title.', array('%title' => $view_link));
|
||||
}
|
||||
drupal_set_message($message);
|
||||
|
||||
$form_state->setRedirect(
|
||||
'entity.shortcut_set.customize_form',
|
||||
array('shortcut_set' => $entity->bundle())
|
||||
);
|
||||
}
|
||||
|
||||
}
|
58
web/core/modules/shortcut/src/ShortcutInterface.php
Normal file
58
web/core/modules/shortcut/src/ShortcutInterface.php
Normal file
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\shortcut;
|
||||
|
||||
use Drupal\Core\Entity\ContentEntityInterface;
|
||||
|
||||
/**
|
||||
* Provides an interface defining a shortcut entity.
|
||||
*/
|
||||
interface ShortcutInterface extends ContentEntityInterface {
|
||||
|
||||
/**
|
||||
* Returns the title of this shortcut.
|
||||
*
|
||||
* @return string
|
||||
* The title of this shortcut.
|
||||
*/
|
||||
public function getTitle();
|
||||
|
||||
/**
|
||||
* Sets the title of this shortcut.
|
||||
*
|
||||
* @param string $title
|
||||
* The title of this shortcut.
|
||||
*
|
||||
* @return \Drupal\shortcut\ShortcutInterface
|
||||
* The called shortcut entity.
|
||||
*/
|
||||
public function setTitle($title);
|
||||
|
||||
/**
|
||||
* Returns the weight among shortcuts with the same depth.
|
||||
*
|
||||
* @return int
|
||||
* The shortcut weight.
|
||||
*/
|
||||
public function getWeight();
|
||||
|
||||
/**
|
||||
* Sets the weight among shortcuts with the same depth.
|
||||
*
|
||||
* @param int $weight
|
||||
* The shortcut weight.
|
||||
*
|
||||
* @return \Drupal\shortcut\ShortcutInterface
|
||||
* The called shortcut entity.
|
||||
*/
|
||||
public function setWeight($weight);
|
||||
|
||||
/**
|
||||
* Returns the URL object pointing to the configured route.
|
||||
*
|
||||
* @return \Drupal\Core\Url
|
||||
* The URL object.
|
||||
*/
|
||||
public function getUrl();
|
||||
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\shortcut;
|
||||
|
||||
use Drupal\Core\Access\AccessResult;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Entity\EntityAccessControlHandler;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
|
||||
/**
|
||||
* Defines the access control handler for the shortcut set entity type.
|
||||
*
|
||||
* @see \Drupal\shortcut\Entity\ShortcutSet
|
||||
*/
|
||||
class ShortcutSetAccessControlHandler extends EntityAccessControlHandler {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
|
||||
switch ($operation) {
|
||||
case 'update':
|
||||
if ($account->hasPermission('administer shortcuts')) {
|
||||
return AccessResult::allowed()->cachePerPermissions();
|
||||
}
|
||||
if (!$account->hasPermission('access shortcuts')) {
|
||||
return AccessResult::neutral()->cachePerPermissions();
|
||||
}
|
||||
return AccessResult::allowedIf($account->hasPermission('customize shortcut links') && $entity == shortcut_current_displayed_set($account))->cachePerPermissions()->addCacheableDependency($entity);
|
||||
|
||||
case 'delete':
|
||||
return AccessResult::allowedIf($account->hasPermission('administer shortcuts') && $entity->id() != 'default')->cachePerPermissions();
|
||||
|
||||
default:
|
||||
// No opinion.
|
||||
return AccessResult::neutral();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
|
||||
return AccessResult::allowedIfHasPermission($account, 'administer shortcuts')->orIf(AccessResult::allowedIfHasPermissions($account, ['access shortcuts', 'customize shortcut links'], 'AND'));
|
||||
}
|
||||
|
||||
}
|
62
web/core/modules/shortcut/src/ShortcutSetForm.php
Normal file
62
web/core/modules/shortcut/src/ShortcutSetForm.php
Normal file
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\shortcut;
|
||||
|
||||
use Drupal\Core\Entity\BundleEntityFormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
||||
/**
|
||||
* Form handler for the shortcut set entity edit forms.
|
||||
*/
|
||||
class ShortcutSetForm extends BundleEntityFormBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function form(array $form, FormStateInterface $form_state) {
|
||||
$form = parent::form($form, $form_state);
|
||||
|
||||
$entity = $this->entity;
|
||||
$form['label'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('Set name'),
|
||||
'#description' => t('The new set is created by copying items from your default shortcut set.'),
|
||||
'#required' => TRUE,
|
||||
'#default_value' => $entity->label(),
|
||||
);
|
||||
$form['id'] = array(
|
||||
'#type' => 'machine_name',
|
||||
'#machine_name' => array(
|
||||
'exists' => '\Drupal\shortcut\Entity\ShortcutSet::load',
|
||||
'source' => array('label'),
|
||||
'replace_pattern' => '[^a-z0-9-]+',
|
||||
'replace' => '-',
|
||||
),
|
||||
'#default_value' => $entity->id(),
|
||||
// This id could be used for menu name.
|
||||
'#maxlength' => 23,
|
||||
);
|
||||
|
||||
$form['actions']['submit']['#value'] = t('Create new set');
|
||||
|
||||
return $this->protectBundleIdElement($form);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function save(array $form, FormStateInterface $form_state) {
|
||||
$entity = $this->entity;
|
||||
$is_new = !$entity->getOriginalId();
|
||||
$entity->save();
|
||||
|
||||
if ($is_new) {
|
||||
drupal_set_message(t('The %set_name shortcut set has been created. You can edit it from this page.', array('%set_name' => $entity->label())));
|
||||
}
|
||||
else {
|
||||
drupal_set_message(t('Updated set name to %set-name.', array('%set-name' => $entity->label())));
|
||||
}
|
||||
$form_state->setRedirectUrl($this->entity->urlInfo('customize-form'));
|
||||
}
|
||||
|
||||
}
|
32
web/core/modules/shortcut/src/ShortcutSetInterface.php
Normal file
32
web/core/modules/shortcut/src/ShortcutSetInterface.php
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\shortcut;
|
||||
|
||||
use Drupal\Core\Config\Entity\ConfigEntityInterface;
|
||||
|
||||
/**
|
||||
* Provides an interface defining a shortcut set entity.
|
||||
*/
|
||||
interface ShortcutSetInterface extends ConfigEntityInterface {
|
||||
|
||||
/**
|
||||
* Resets the link weights in a shortcut set to match their current order.
|
||||
*
|
||||
* This function can be used, for example, when a new shortcut link is added
|
||||
* to the set. If the link is added to the end of the array and this function
|
||||
* is called, it will force that link to display at the end of the list.
|
||||
*
|
||||
* @return \Drupal\shortcut\ShortcutSetInterface
|
||||
* The shortcut set.
|
||||
*/
|
||||
public function resetLinkWeights();
|
||||
|
||||
/**
|
||||
* Returns all the shortcuts from a shortcut set sorted correctly.
|
||||
*
|
||||
* @return \Drupal\shortcut\ShortcutInterface[]
|
||||
* An array of shortcut entities.
|
||||
*/
|
||||
public function getShortcuts();
|
||||
|
||||
}
|
48
web/core/modules/shortcut/src/ShortcutSetListBuilder.php
Normal file
48
web/core/modules/shortcut/src/ShortcutSetListBuilder.php
Normal file
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\shortcut;
|
||||
|
||||
use Drupal\Core\Config\Entity\ConfigEntityListBuilder;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
|
||||
/**
|
||||
* Defines a class to build a listing of shortcut set entities.
|
||||
*
|
||||
* @see \Drupal\shortcut\Entity\ShortcutSet
|
||||
*/
|
||||
class ShortcutSetListBuilder extends ConfigEntityListBuilder {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildHeader() {
|
||||
$header['name'] = t('Name');
|
||||
return $header + parent::buildHeader();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDefaultOperations(EntityInterface $entity) {
|
||||
$operations = parent::getDefaultOperations($entity);
|
||||
|
||||
if (isset($operations['edit'])) {
|
||||
$operations['edit']['title'] = t('Edit shortcut set');
|
||||
}
|
||||
|
||||
$operations['list'] = array(
|
||||
'title' => t('List links'),
|
||||
'url' => $entity->urlInfo('customize-form'),
|
||||
);
|
||||
return $operations;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildRow(EntityInterface $entity) {
|
||||
$row['name'] = $entity->label();
|
||||
return $row + parent::buildRow($entity);
|
||||
}
|
||||
|
||||
}
|
128
web/core/modules/shortcut/src/ShortcutSetStorage.php
Normal file
128
web/core/modules/shortcut/src/ShortcutSetStorage.php
Normal file
|
@ -0,0 +1,128 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\shortcut;
|
||||
|
||||
use Drupal\Component\Uuid\UuidInterface;
|
||||
use Drupal\Core\Config\ConfigFactoryInterface;
|
||||
use Drupal\Core\Config\Entity\ConfigEntityStorage;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\Language\LanguageManagerInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Defines a storage for shortcut_set entities.
|
||||
*/
|
||||
class ShortcutSetStorage extends ConfigEntityStorage implements ShortcutSetStorageInterface {
|
||||
|
||||
/**
|
||||
* The module handler.
|
||||
*
|
||||
* @var \Drupal\Core\Extension\ModuleHandlerInterface
|
||||
*/
|
||||
protected $moduleHandler;
|
||||
|
||||
/**
|
||||
* Constructs a ShortcutSetStorageController object.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_info
|
||||
* The entity info for the entity type.
|
||||
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
|
||||
* The config factory service.
|
||||
* @param \Drupal\Component\Uuid\UuidInterface $uuid_service
|
||||
* The UUID service.
|
||||
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
|
||||
* The module handler.
|
||||
* @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
|
||||
* The language manager.
|
||||
*/
|
||||
public function __construct(EntityTypeInterface $entity_info, ConfigFactoryInterface $config_factory, UuidInterface $uuid_service, ModuleHandlerInterface $module_handler, LanguageManagerInterface $language_manager) {
|
||||
parent::__construct($entity_info, $config_factory, $uuid_service, $language_manager);
|
||||
|
||||
$this->moduleHandler = $module_handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_info) {
|
||||
return new static(
|
||||
$entity_info,
|
||||
$container->get('config.factory'),
|
||||
$container->get('uuid'),
|
||||
$container->get('module_handler'),
|
||||
$container->get('language_manager')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function deleteAssignedShortcutSets(ShortcutSetInterface $entity) {
|
||||
// First, delete any user assignments for this set, so that each of these
|
||||
// users will go back to using whatever default set applies.
|
||||
db_delete('shortcut_set_users')
|
||||
->condition('set_name', $entity->id())
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function assignUser(ShortcutSetInterface $shortcut_set, $account) {
|
||||
db_merge('shortcut_set_users')
|
||||
->key('uid', $account->id())
|
||||
->fields(array('set_name' => $shortcut_set->id()))
|
||||
->execute();
|
||||
drupal_static_reset('shortcut_current_displayed_set');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function unassignUser($account) {
|
||||
$deleted = db_delete('shortcut_set_users')
|
||||
->condition('uid', $account->id())
|
||||
->execute();
|
||||
return (bool) $deleted;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAssignedToUser($account) {
|
||||
$query = db_select('shortcut_set_users', 'ssu');
|
||||
$query->fields('ssu', array('set_name'));
|
||||
$query->condition('ssu.uid', $account->id());
|
||||
return $query->execute()->fetchField();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function countAssignedUsers(ShortcutSetInterface $shortcut_set) {
|
||||
return db_query('SELECT COUNT(*) FROM {shortcut_set_users} WHERE set_name = :name', array(':name' => $shortcut_set->id()))->fetchField();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDefaultSet(AccountInterface $account) {
|
||||
// Allow modules to return a default shortcut set name. Since we can only
|
||||
// have one, we allow the last module which returns a valid result to take
|
||||
// precedence. If no module returns a valid set, fall back on the site-wide
|
||||
// default, which is the lowest-numbered shortcut set.
|
||||
$suggestions = array_reverse($this->moduleHandler->invokeAll('shortcut_default_set', array($account)));
|
||||
$suggestions[] = 'default';
|
||||
$shortcut_set = NULL;
|
||||
foreach ($suggestions as $name) {
|
||||
if ($shortcut_set = $this->load($name)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $shortcut_set;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\shortcut;
|
||||
|
||||
use Drupal\Core\Config\Entity\ConfigEntityStorageInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
|
||||
/**
|
||||
* Defines an interface for shortcut_set entity storage classes.
|
||||
*/
|
||||
interface ShortcutSetStorageInterface extends ConfigEntityStorageInterface {
|
||||
|
||||
/**
|
||||
* Assigns a user to a particular shortcut set.
|
||||
*
|
||||
* @param \Drupal\shortcut\ShortcutSetInterface $shortcut_set
|
||||
* An object representing the shortcut set.
|
||||
* @param $account
|
||||
* A user account that will be assigned to use the set.
|
||||
*/
|
||||
public function assignUser(ShortcutSetInterface $shortcut_set, $account);
|
||||
|
||||
/**
|
||||
* Unassigns a user from any shortcut set they may have been assigned to.
|
||||
*
|
||||
* The user will go back to using whatever default set applies.
|
||||
*
|
||||
* @param $account
|
||||
* A user account that will be removed from the shortcut set assignment.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the user was previously assigned to a shortcut set and has been
|
||||
* successfully removed from it. FALSE if the user was already not assigned
|
||||
* to any set.
|
||||
*/
|
||||
public function unassignUser($account);
|
||||
|
||||
/**
|
||||
* Delete shortcut sets assigned to users.
|
||||
*
|
||||
* @param \Drupal\shortcut\ShortcutSetInterface $entity
|
||||
* Delete the user assigned sets belonging to this shortcut.
|
||||
*/
|
||||
public function deleteAssignedShortcutSets(ShortcutSetInterface $entity);
|
||||
|
||||
/**
|
||||
* Get the name of the set assigned to this user.
|
||||
*
|
||||
* @param \Drupal\user\Entity\User $account
|
||||
* The user account.
|
||||
*
|
||||
* @return string
|
||||
* The name of the shortcut set assigned to this user.
|
||||
*/
|
||||
public function getAssignedToUser($account);
|
||||
|
||||
/**
|
||||
* Get the number of users who have this set assigned to them.
|
||||
*
|
||||
* @param \Drupal\shortcut\ShortcutSetInterface $shortcut_set
|
||||
* The shortcut to count the users assigned to.
|
||||
*
|
||||
* @return int
|
||||
* The number of users who have this set assigned to them.
|
||||
*/
|
||||
public function countAssignedUsers(ShortcutSetInterface $shortcut_set);
|
||||
|
||||
/**
|
||||
* Gets the default shortcut set for a given user account.
|
||||
*
|
||||
* @param \Drupal\Core\Session\AccountInterface $account
|
||||
* The user account whose default shortcut set will be returned.
|
||||
*
|
||||
* @return \Drupal\shortcut\ShortcutSetInterface
|
||||
* An object representing the default shortcut set.
|
||||
*/
|
||||
public function getDefaultSet(AccountInterface $account);
|
||||
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\shortcut\Tests;
|
||||
|
||||
use Drupal\Core\Cache\CacheBackendInterface;
|
||||
use Drupal\shortcut\Entity\Shortcut;
|
||||
use Drupal\system\Tests\Entity\EntityCacheTagsTestBase;
|
||||
use Drupal\user\Entity\Role;
|
||||
use Drupal\user\RoleInterface;
|
||||
|
||||
/**
|
||||
* Tests the Shortcut entity's cache tags.
|
||||
*
|
||||
* @group shortcut
|
||||
*/
|
||||
class ShortcutCacheTagsTest extends EntityCacheTagsTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = array('shortcut');
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Give anonymous users permission to customize shortcut links, so that we
|
||||
// can verify the cache tags of cached versions of shortcuts.
|
||||
$user_role = Role::load(RoleInterface::ANONYMOUS_ID);
|
||||
$user_role->grantPermission('customize shortcut links');
|
||||
$user_role->grantPermission('access shortcuts');
|
||||
$user_role->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function createEntity() {
|
||||
// Create a "Llama" shortcut.
|
||||
$shortcut = Shortcut::create(array(
|
||||
'shortcut_set' => 'default',
|
||||
'title' => t('Llama'),
|
||||
'weight' => 0,
|
||||
'link' => [['uri' => 'internal:/admin']],
|
||||
));
|
||||
$shortcut->save();
|
||||
|
||||
return $shortcut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that when creating a shortcut, the shortcut set tag is invalidated.
|
||||
*/
|
||||
public function testEntityCreation() {
|
||||
// Create a cache entry that is tagged with a shortcut set cache tag.
|
||||
$cache_tags = ['config:shortcut.set.default'];
|
||||
\Drupal::cache('render')->set('foo', 'bar', CacheBackendInterface::CACHE_PERMANENT, $cache_tags);
|
||||
|
||||
// Verify a cache hit.
|
||||
$this->verifyRenderCache('foo', $cache_tags);
|
||||
|
||||
// Now create a shortcut entity in that shortcut set.
|
||||
$this->createEntity();
|
||||
|
||||
// Verify a cache miss.
|
||||
$this->assertFalse(\Drupal::cache('render')->get('foo'), 'Creating a new shortcut invalidates the cache tag of the shortcut set.');
|
||||
}
|
||||
|
||||
}
|
462
web/core/modules/shortcut/src/Tests/ShortcutLinksTest.php
Normal file
462
web/core/modules/shortcut/src/Tests/ShortcutLinksTest.php
Normal file
|
@ -0,0 +1,462 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\shortcut\Tests;
|
||||
|
||||
use Drupal\block_content\Entity\BlockContentType;
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\shortcut\Entity\Shortcut;
|
||||
use Drupal\shortcut\Entity\ShortcutSet;
|
||||
use Drupal\views\Entity\View;
|
||||
|
||||
/**
|
||||
* Create, view, edit, delete, and change shortcut links.
|
||||
*
|
||||
* @group shortcut
|
||||
*/
|
||||
class ShortcutLinksTest extends ShortcutTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('router_test', 'views', 'block');
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->drupalPlaceBlock('page_title_block');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that creating a shortcut works properly.
|
||||
*/
|
||||
public function testShortcutLinkAdd() {
|
||||
$set = $this->set;
|
||||
|
||||
// Create an alias for the node so we can test aliases.
|
||||
$path = array(
|
||||
'source' => '/node/' . $this->node->id(),
|
||||
'alias' => '/' . $this->randomMachineName(8),
|
||||
);
|
||||
$this->container->get('path.alias_storage')->save($path['source'], $path['alias']);
|
||||
|
||||
// Create some paths to test.
|
||||
$test_cases = [
|
||||
'/',
|
||||
'/admin',
|
||||
'/admin/config/system/site-information',
|
||||
'/node/' . $this->node->id() . '/edit',
|
||||
$path['alias'],
|
||||
'/router_test/test2',
|
||||
'/router_test/test3/value',
|
||||
];
|
||||
|
||||
$test_cases_non_access = [
|
||||
'/admin',
|
||||
'/admin/config/system/site-information',
|
||||
];
|
||||
|
||||
// Check that each new shortcut links where it should.
|
||||
foreach ($test_cases as $test_path) {
|
||||
$title = $this->randomMachineName();
|
||||
$form_data = array(
|
||||
'title[0][value]' => $title,
|
||||
'link[0][uri]' => $test_path,
|
||||
);
|
||||
$this->drupalPostForm('admin/config/user-interface/shortcut/manage/' . $set->id() . '/add-link', $form_data, t('Save'));
|
||||
$this->assertResponse(200);
|
||||
$this->assertText(t('Added a shortcut for @title.', array('@title' => $title)));
|
||||
$saved_set = ShortcutSet::load($set->id());
|
||||
$paths = $this->getShortcutInformation($saved_set, 'link');
|
||||
$this->assertTrue(in_array('internal:' . $test_path, $paths), 'Shortcut created: ' . $test_path);
|
||||
|
||||
if (in_array($test_path, $test_cases_non_access)) {
|
||||
$this->assertNoLink($title, SafeMarkup::format('Shortcut link %url not accessible on the page.', ['%url' => $test_path]));
|
||||
}
|
||||
else {
|
||||
$this->assertLink($title, 0, SafeMarkup::format('Shortcut link %url found on the page.', ['%url' => $test_path]));
|
||||
}
|
||||
}
|
||||
$saved_set = ShortcutSet::load($set->id());
|
||||
// Test that saving and re-loading a shortcut preserves its values.
|
||||
$shortcuts = $saved_set->getShortcuts();
|
||||
foreach ($shortcuts as $entity) {
|
||||
// Test the node routes with parameters.
|
||||
$entity->save();
|
||||
$loaded = Shortcut::load($entity->id());
|
||||
$this->assertEqual($entity->link->uri, $loaded->link->uri);
|
||||
$this->assertEqual($entity->link->options, $loaded->link->options);
|
||||
}
|
||||
|
||||
// Log in as non admin user, to check that access is checked when creating
|
||||
// shortcuts.
|
||||
$this->drupalLogin($this->shortcutUser);
|
||||
$title = $this->randomMachineName();
|
||||
$form_data = [
|
||||
'title[0][value]' => $title,
|
||||
'link[0][uri]' => '/admin',
|
||||
];
|
||||
$this->drupalPostForm('admin/config/user-interface/shortcut/manage/' . $set->id() . '/add-link', $form_data, t('Save'));
|
||||
$this->assertResponse(200);
|
||||
$this->assertRaw(t("The path '@link_path' is inaccessible.", ['@link_path' => '/admin']));
|
||||
|
||||
$form_data = [
|
||||
'title[0][value]' => $title,
|
||||
'link[0][uri]' => '/node',
|
||||
];
|
||||
$this->drupalPostForm('admin/config/user-interface/shortcut/manage/' . $set->id() . '/add-link', $form_data, t('Save'));
|
||||
$this->assertLink($title, 0, 'Shortcut link found on the page.');
|
||||
|
||||
// Create a new shortcut set and add a link to it.
|
||||
$this->drupalLogin($this->adminUser);
|
||||
$edit = array(
|
||||
'label' => $this->randomMachineName(),
|
||||
'id' => strtolower($this->randomMachineName()),
|
||||
);
|
||||
$this->drupalPostForm('admin/config/user-interface/shortcut/add-set', $edit, t('Save'));
|
||||
$title = $this->randomMachineName();
|
||||
$form_data = [
|
||||
'title[0][value]' => $title,
|
||||
'link[0][uri]' => '/admin',
|
||||
];
|
||||
$this->drupalPostForm('admin/config/user-interface/shortcut/manage/' . $edit['id'] . '/add-link', $form_data, t('Save'));
|
||||
$this->assertResponse(200);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the "add to shortcut" and "remove from shortcut" links work.
|
||||
*/
|
||||
public function testShortcutQuickLink() {
|
||||
\Drupal::service('theme_handler')->install(array('seven'));
|
||||
$this->config('system.theme')->set('admin', 'seven')->save();
|
||||
$this->config('node.settings')->set('use_admin_theme', '1')->save();
|
||||
$this->container->get('router.builder')->rebuild();
|
||||
|
||||
$this->drupalLogin($this->rootUser);
|
||||
$this->drupalGet('admin/config/system/cron');
|
||||
|
||||
// Test the "Add to shortcuts" link.
|
||||
$this->clickLink('Add to Default shortcuts');
|
||||
$this->assertText('Added a shortcut for Cron.');
|
||||
$this->assertLink('Cron', 0, 'Shortcut link found on page');
|
||||
|
||||
$this->drupalGet('admin/structure');
|
||||
$this->assertLink('Cron', 0, 'Shortcut link found on different page');
|
||||
|
||||
// Test the "Remove from shortcuts" link.
|
||||
$this->clickLink('Cron');
|
||||
$this->clickLink('Remove from Default shortcuts');
|
||||
$this->assertText('The shortcut Cron has been deleted.');
|
||||
$this->assertNoLink('Cron', 'Shortcut link removed from page');
|
||||
|
||||
$this->drupalGet('admin/structure');
|
||||
$this->assertNoLink('Cron', 'Shortcut link removed from different page');
|
||||
|
||||
$this->drupalGet('admin/people');
|
||||
|
||||
// Test the "Add to shortcuts" link for a page generated by views.
|
||||
$this->clickLink('Add to Default shortcuts');
|
||||
$this->assertText('Added a shortcut for People.');
|
||||
$this->assertShortcutQuickLink('Remove from Default shortcuts');
|
||||
|
||||
// Test the "Remove from shortcuts" link for a page generated by views.
|
||||
$this->clickLink('Remove from Default shortcuts');
|
||||
$this->assertText('The shortcut People has been deleted.');
|
||||
$this->assertShortcutQuickLink('Add to Default shortcuts');
|
||||
|
||||
// Test two pages which use same route name but different route parameters.
|
||||
$this->drupalGet('node/add/page');
|
||||
// Add Shortcut for Basic Page.
|
||||
$this->clickLink('Add to Default shortcuts');
|
||||
$this->assertText('Added a shortcut for Create Basic page.');
|
||||
// Assure that Article does not have its shortcut indicated as set.
|
||||
$this->drupalGet('node/add/article');
|
||||
$link = $this->xpath('//a[normalize-space()=:label]', array(':label' => 'Remove from Default shortcuts'));
|
||||
$this->assertTrue(empty($link), 'Link Remove to Default shortcuts not found for Create Article page.');
|
||||
// Add Shortcut for Article.
|
||||
$this->clickLink('Add to Default shortcuts');
|
||||
$this->assertText('Added a shortcut for Create Article.');
|
||||
|
||||
$this->config('system.theme')->set('default', 'seven')->save();
|
||||
$this->drupalGet('node/' . $this->node->id());
|
||||
$title = $this->node->getTitle();
|
||||
|
||||
// Test the "Add to shortcuts" link for node view route.
|
||||
$this->clickLink('Add to Default shortcuts');
|
||||
$this->assertText(new FormattableMarkup('Added a shortcut for @title.', ['@title' => $title]));
|
||||
$this->assertShortcutQuickLink('Remove from Default shortcuts');
|
||||
|
||||
// Test the "Remove from shortcuts" link for node view route.
|
||||
$this->clickLink('Remove from Default shortcuts');
|
||||
$this->assertText(new FormattableMarkup('The shortcut @title has been deleted.', ['@title' => $title]));
|
||||
$this->assertShortcutQuickLink('Add to Default shortcuts');
|
||||
|
||||
\Drupal::service('module_installer')->install(['block_content']);
|
||||
BlockContentType::create(array(
|
||||
'id' => 'basic',
|
||||
'label' => 'Basic block',
|
||||
'revision' => FALSE,
|
||||
))->save();
|
||||
// Test page with HTML tags in title.
|
||||
$this->drupalGet('admin/structure/block/block-content/manage/basic');
|
||||
$page_title = new FormattableMarkup('Edit %label custom block type', ['%label' => 'Basic block']);
|
||||
$this->assertRaw($page_title);
|
||||
// Add shortcut to this page.
|
||||
$this->clickLink('Add to Default shortcuts');
|
||||
$this->assertRaw(new FormattableMarkup('Added a shortcut for %title.', [
|
||||
'%title' => trim(strip_tags($page_title)),
|
||||
]));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that shortcut links can be renamed.
|
||||
*/
|
||||
public function testShortcutLinkRename() {
|
||||
$set = $this->set;
|
||||
|
||||
// Attempt to rename shortcut link.
|
||||
$new_link_name = $this->randomMachineName();
|
||||
|
||||
$shortcuts = $set->getShortcuts();
|
||||
$shortcut = reset($shortcuts);
|
||||
$this->drupalPostForm('admin/config/user-interface/shortcut/link/' . $shortcut->id(), array('title[0][value]' => $new_link_name), t('Save'));
|
||||
$saved_set = ShortcutSet::load($set->id());
|
||||
$titles = $this->getShortcutInformation($saved_set, 'title');
|
||||
$this->assertTrue(in_array($new_link_name, $titles), 'Shortcut renamed: ' . $new_link_name);
|
||||
$this->assertLink($new_link_name, 0, 'Renamed shortcut link appears on the page.');
|
||||
$this->assertText(t('The shortcut @link has been updated.', array('@link' => $new_link_name)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that changing the path of a shortcut link works.
|
||||
*/
|
||||
public function testShortcutLinkChangePath() {
|
||||
$set = $this->set;
|
||||
|
||||
// Tests changing a shortcut path.
|
||||
$new_link_path = '/admin/config';
|
||||
|
||||
$shortcuts = $set->getShortcuts();
|
||||
$shortcut = reset($shortcuts);
|
||||
$this->drupalPostForm('admin/config/user-interface/shortcut/link/' . $shortcut->id(), array('title[0][value]' => $shortcut->getTitle(), 'link[0][uri]' => $new_link_path), t('Save'));
|
||||
$saved_set = ShortcutSet::load($set->id());
|
||||
$paths = $this->getShortcutInformation($saved_set, 'link');
|
||||
$this->assertTrue(in_array('internal:' . $new_link_path, $paths), 'Shortcut path changed: ' . $new_link_path);
|
||||
$this->assertLinkByHref($new_link_path, 0, 'Shortcut with new path appears on the page.');
|
||||
$this->assertText(t('The shortcut @link has been updated.', array('@link' => $shortcut->getTitle())));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that changing the route of a shortcut link works.
|
||||
*/
|
||||
public function testShortcutLinkChangeRoute() {
|
||||
$this->drupalLogin($this->rootUser);
|
||||
$this->drupalGet('admin/content');
|
||||
$this->assertResponse(200);
|
||||
// Disable the view.
|
||||
View::load('content')->disable()->save();
|
||||
/** @var \Drupal\Core\Routing\RouteBuilderInterface $router_builder */
|
||||
$router_builder = \Drupal::service('router.builder');
|
||||
$router_builder->rebuildIfNeeded();
|
||||
$this->drupalGet('admin/content');
|
||||
$this->assertResponse(200);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests deleting a shortcut link.
|
||||
*/
|
||||
public function testShortcutLinkDelete() {
|
||||
$set = $this->set;
|
||||
|
||||
$shortcuts = $set->getShortcuts();
|
||||
$shortcut = reset($shortcuts);
|
||||
$this->drupalPostForm('admin/config/user-interface/shortcut/link/' . $shortcut->id() . '/delete', array(), 'Delete');
|
||||
$saved_set = ShortcutSet::load($set->id());
|
||||
$ids = $this->getShortcutInformation($saved_set, 'id');
|
||||
$this->assertFalse(in_array($shortcut->id(), $ids), 'Successfully deleted a shortcut.');
|
||||
|
||||
// Delete all the remaining shortcut links.
|
||||
entity_delete_multiple('shortcut', array_filter($ids));
|
||||
|
||||
// Get the front page to check that no exceptions occur.
|
||||
$this->drupalGet('');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the add shortcut link is not displayed for 404/403 errors.
|
||||
*
|
||||
* Tests that the "Add to shortcuts" link is not displayed on a page not
|
||||
* found or a page the user does not have access to.
|
||||
*/
|
||||
public function testNoShortcutLink() {
|
||||
// Change to a theme that displays shortcuts.
|
||||
\Drupal::service('theme_handler')->install(array('seven'));
|
||||
$this->config('system.theme')
|
||||
->set('default', 'seven')
|
||||
->save();
|
||||
|
||||
$this->drupalGet('page-that-does-not-exist');
|
||||
$result = $this->xpath('//a[contains(@class, "shortcut-action--add")]');
|
||||
$this->assertTrue(empty($result), 'Add to shortcuts link was not shown on a page not found.');
|
||||
|
||||
// The user does not have access to this path.
|
||||
$this->drupalGet('admin/modules');
|
||||
$result = $this->xpath('//a[contains(@class, "shortcut-action--add")]');
|
||||
$this->assertTrue(empty($result), 'Add to shortcuts link was not shown on a page the user does not have access to.');
|
||||
|
||||
// Verify that the testing mechanism works by verifying the shortcut link
|
||||
// appears on admin/content.
|
||||
$this->drupalGet('admin/content');
|
||||
$result = $this->xpath('//a[contains(@class, "shortcut-action--remove")]');
|
||||
$this->assertTrue(!empty($result), 'Remove from shortcuts link was shown on a page the user does have access to.');
|
||||
|
||||
// Verify that the shortcut link appears on routing only pages.
|
||||
$this->drupalGet('router_test/test2');
|
||||
$result = $this->xpath('//a[contains(@class, "shortcut-action--add")]');
|
||||
$this->assertTrue(!empty($result), 'Add to shortcuts link was shown on a page the user does have access to.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the 'access shortcuts' permissions works properly.
|
||||
*/
|
||||
public function testAccessShortcutsPermission() {
|
||||
// Change to a theme that displays shortcuts.
|
||||
\Drupal::service('theme_handler')->install(array('seven'));
|
||||
$this->config('system.theme')
|
||||
->set('default', 'seven')
|
||||
->save();
|
||||
|
||||
// Add cron to the default shortcut set.
|
||||
$this->drupalLogin($this->rootUser);
|
||||
$this->drupalGet('admin/config/system/cron');
|
||||
$this->clickLink('Add to Default shortcuts');
|
||||
|
||||
// Verify that users without the 'access shortcuts' permission can't see the
|
||||
// shortcuts.
|
||||
$this->drupalLogin($this->drupalCreateUser(array('access toolbar')));
|
||||
$this->assertNoLink('Shortcuts', 'Shortcut link not found on page.');
|
||||
|
||||
// Verify that users without the 'administer site configuration' permission
|
||||
// can't see the cron shortcuts.
|
||||
$this->drupalLogin($this->drupalCreateUser(array('access toolbar', 'access shortcuts')));
|
||||
$this->assertNoLink('Shortcuts', 'Shortcut link not found on page.');
|
||||
$this->assertNoLink('Cron', 'Cron shortcut link not found on page.');
|
||||
|
||||
// Verify that users with the 'access shortcuts' permission can see the
|
||||
// shortcuts.
|
||||
$this->drupalLogin($this->drupalCreateUser(array(
|
||||
'access toolbar', 'access shortcuts', 'administer site configuration',
|
||||
)));
|
||||
$this->clickLink('Shortcuts', 0, 'Shortcut link found on page.');
|
||||
$this->assertLink('Cron', 0, 'Cron shortcut link found on page.');
|
||||
|
||||
$this->verifyAccessShortcutsPermissionForEditPages();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the shortcuts are correctly ordered by weight in the toolbar.
|
||||
*/
|
||||
public function testShortcutLinkOrder() {
|
||||
// Ensure to give permissions to access the shortcuts.
|
||||
$this->drupalLogin($this->drupalCreateUser(array('access toolbar', 'access shortcuts', 'access content overview', 'administer content types')));
|
||||
$this->drupalGet(Url::fromRoute('<front>'));
|
||||
$shortcuts = $this->cssSelect('#toolbar-item-shortcuts-tray .toolbar-menu a');
|
||||
$this->assertEqual((string) $shortcuts[0], 'Add content');
|
||||
$this->assertEqual((string) $shortcuts[1], 'All content');
|
||||
foreach ($this->set->getShortcuts() as $shortcut) {
|
||||
$shortcut->setWeight($shortcut->getWeight() * -1)->save();
|
||||
}
|
||||
$this->drupalGet(Url::fromRoute('<front>'));
|
||||
$shortcuts = $this->cssSelect('#toolbar-item-shortcuts-tray .toolbar-menu a');
|
||||
$this->assertEqual((string) $shortcuts[0], 'All content');
|
||||
$this->assertEqual((string) $shortcuts[1], 'Add content');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the 'access shortcuts' permission is required for shortcut set
|
||||
* administration page access.
|
||||
*/
|
||||
private function verifyAccessShortcutsPermissionForEditPages() {
|
||||
// Create a user with customize links and switch sets permissions but
|
||||
// without the 'access shortcuts' permission.
|
||||
$test_permissions = array(
|
||||
'customize shortcut links',
|
||||
'switch shortcut sets',
|
||||
);
|
||||
$noaccess_user = $this->drupalCreateUser($test_permissions);
|
||||
$this->drupalLogin($noaccess_user);
|
||||
|
||||
// Verify that set administration pages are inaccessible without the
|
||||
// 'access shortcuts' permission.
|
||||
$edit_paths = array(
|
||||
'admin/config/user-interface/shortcut/manage/default/customize',
|
||||
'admin/config/user-interface/shortcut/manage/default',
|
||||
'user/' . $noaccess_user->id() . '/shortcuts',
|
||||
);
|
||||
|
||||
foreach ($edit_paths as $path) {
|
||||
$this->drupalGet($path);
|
||||
$message = format_string('Access is denied on %s', array('%s' => $path));
|
||||
$this->assertResponse(403, $message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the 'access shortcuts' permission is required to access the
|
||||
* shortcut block.
|
||||
*/
|
||||
public function testShortcutBlockAccess() {
|
||||
// Creates a block instance and place in a region through api.
|
||||
$block = $this->drupalPlaceBlock('shortcuts');
|
||||
|
||||
// Verify that users with the 'access shortcuts' permission can see the
|
||||
// shortcut block.
|
||||
$this->drupalLogin($this->shortcutUser);
|
||||
$this->drupalGet('');
|
||||
$this->assertBlockAppears($block);
|
||||
|
||||
$this->drupalLogout();
|
||||
|
||||
// Verify that users without the 'access shortcuts' permission can see the
|
||||
// shortcut block.
|
||||
$this->drupalLogin($this->drupalCreateUser(array()));
|
||||
$this->drupalGet('');
|
||||
$this->assertNoBlockAppears($block);
|
||||
}
|
||||
|
||||
/**
|
||||
* Passes if a shortcut quick link with the specified label is found.
|
||||
*
|
||||
* An optional link index may be passed.
|
||||
*
|
||||
* @param string $label
|
||||
* Text between the anchor tags.
|
||||
* @param int $index
|
||||
* Link position counting from zero.
|
||||
* @param string $message
|
||||
* (optional) A message to display with the assertion. Do not translate
|
||||
* messages: use format_string() to embed variables in the message text, not
|
||||
* t(). If left blank, a default message will be displayed.
|
||||
* @param string $group
|
||||
* (optional) The group this message is in, which is displayed in a column
|
||||
* in test output. Use 'Debug' to indicate this is debugging output. Do not
|
||||
* translate this string. Defaults to 'Other'; most tests do not override
|
||||
* this default.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the assertion succeeded, FALSE otherwise.
|
||||
*/
|
||||
protected function assertShortcutQuickLink($label, $index = 0, $message = '', $group = 'Other') {
|
||||
$links = $this->xpath('//a[normalize-space()=:label]', array(':label' => $label));
|
||||
$message = ($message ? $message : SafeMarkup::format('Shortcut quick link with label %label found.', array('%label' => $label)));
|
||||
return $this->assert(isset($links[$index]), $message, $group);
|
||||
}
|
||||
|
||||
}
|
211
web/core/modules/shortcut/src/Tests/ShortcutSetsTest.php
Normal file
211
web/core/modules/shortcut/src/Tests/ShortcutSetsTest.php
Normal file
|
@ -0,0 +1,211 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\shortcut\Tests;
|
||||
|
||||
use Drupal\shortcut\Entity\ShortcutSet;
|
||||
|
||||
/**
|
||||
* Create, view, edit, delete, and change shortcut sets.
|
||||
*
|
||||
* @group shortcut
|
||||
*/
|
||||
class ShortcutSetsTest extends ShortcutTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
public static $modules = ['block'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->drupalPlaceBlock('local_actions_block');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests creating a shortcut set.
|
||||
*/
|
||||
function testShortcutSetAdd() {
|
||||
$this->drupalGet('admin/config/user-interface/shortcut');
|
||||
$this->clickLink(t('Add shortcut set'));
|
||||
$edit = array(
|
||||
'label' => $this->randomMachineName(),
|
||||
'id' => strtolower($this->randomMachineName()),
|
||||
);
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
$new_set = $this->container->get('entity.manager')->getStorage('shortcut_set')->load($edit['id']);
|
||||
$this->assertIdentical($new_set->id(), $edit['id'], 'Successfully created a shortcut set.');
|
||||
$this->drupalGet('user/' . $this->adminUser->id() . '/shortcuts');
|
||||
$this->assertText($new_set->label(), 'Generated shortcut set was listed as a choice on the user account page.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests editing a shortcut set.
|
||||
*/
|
||||
function testShortcutSetEdit() {
|
||||
$set = $this->set;
|
||||
$shortcuts = $set->getShortcuts();
|
||||
|
||||
// Visit the shortcut set edit admin ui.
|
||||
$this->drupalGet('admin/config/user-interface/shortcut/manage/' . $set->id() . '/customize');
|
||||
|
||||
// Test for the page title.
|
||||
$this->assertTitle(t('List links') . ' | Drupal');
|
||||
|
||||
// Test for the table.
|
||||
$element = $this->xpath('//div[@class="layout-content"]//table');
|
||||
$this->assertTrue($element, 'Shortcut entity list table found.');
|
||||
|
||||
// Test the table header.
|
||||
$elements = $this->xpath('//div[@class="layout-content"]//table/thead/tr/th');
|
||||
$this->assertEqual(count($elements), 3, 'Correct number of table header cells found.');
|
||||
|
||||
// Test the contents of each th cell.
|
||||
$expected_items = array(t('Name'), t('Weight'), t('Operations'));
|
||||
foreach ($elements as $key => $element) {
|
||||
$this->assertEqual((string) $element[0], $expected_items[$key]);
|
||||
}
|
||||
|
||||
// Look for test shortcuts in the table.
|
||||
$weight = count($shortcuts);
|
||||
$edit = array();
|
||||
foreach ($shortcuts as $shortcut) {
|
||||
$title = $shortcut->getTitle();
|
||||
|
||||
// Confirm that a link to the shortcut is found within the table.
|
||||
$this->assertLink($title);
|
||||
|
||||
// Look for a test shortcut weight select form element.
|
||||
$this->assertFieldByName('shortcuts[links][' . $shortcut->id() . '][weight]');
|
||||
|
||||
// Change the weight of the shortcut.
|
||||
$edit['shortcuts[links][' . $shortcut->id() . '][weight]'] = $weight;
|
||||
$weight--;
|
||||
}
|
||||
|
||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||
$this->assertRaw(t('The shortcut set has been updated.'));
|
||||
|
||||
\Drupal::entityManager()->getStorage('shortcut')->resetCache();
|
||||
// Check to ensure that the shortcut weights have changed and that
|
||||
// ShortcutSet::.getShortcuts() returns shortcuts in the new order.
|
||||
$this->assertIdentical(array_reverse(array_keys($shortcuts)), array_keys($set->getShortcuts()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests switching a user's own shortcut set.
|
||||
*/
|
||||
function testShortcutSetSwitchOwn() {
|
||||
$new_set = $this->generateShortcutSet($this->randomMachineName());
|
||||
|
||||
// Attempt to switch the default shortcut set to the newly created shortcut
|
||||
// set.
|
||||
$this->drupalPostForm('user/' . $this->adminUser->id() . '/shortcuts', array('set' => $new_set->id()), t('Change set'));
|
||||
$this->assertResponse(200);
|
||||
$current_set = shortcut_current_displayed_set($this->adminUser);
|
||||
$this->assertTrue($new_set->id() == $current_set->id(), 'Successfully switched own shortcut set.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests switching another user's shortcut set.
|
||||
*/
|
||||
function testShortcutSetAssign() {
|
||||
$new_set = $this->generateShortcutSet($this->randomMachineName());
|
||||
|
||||
\Drupal::entityManager()->getStorage('shortcut_set')->assignUser($new_set, $this->shortcutUser);
|
||||
$current_set = shortcut_current_displayed_set($this->shortcutUser);
|
||||
$this->assertTrue($new_set->id() == $current_set->id(), "Successfully switched another user's shortcut set.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests switching a user's shortcut set and creating one at the same time.
|
||||
*/
|
||||
function testShortcutSetSwitchCreate() {
|
||||
$edit = array(
|
||||
'set' => 'new',
|
||||
'id' => strtolower($this->randomMachineName()),
|
||||
'label' => $this->randomString(),
|
||||
);
|
||||
$this->drupalPostForm('user/' . $this->adminUser->id() . '/shortcuts', $edit, t('Change set'));
|
||||
$current_set = shortcut_current_displayed_set($this->adminUser);
|
||||
$this->assertNotEqual($current_set->id(), $this->set->id(), 'A shortcut set can be switched to at the same time as it is created.');
|
||||
$this->assertEqual($current_set->label(), $edit['label'], 'The new set is correctly assigned to the user.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests switching a user's shortcut set without providing a new set name.
|
||||
*/
|
||||
function testShortcutSetSwitchNoSetName() {
|
||||
$edit = array('set' => 'new');
|
||||
$this->drupalPostForm('user/' . $this->adminUser->id() . '/shortcuts', $edit, t('Change set'));
|
||||
$this->assertText(t('The new set label is required.'));
|
||||
$current_set = shortcut_current_displayed_set($this->adminUser);
|
||||
$this->assertEqual($current_set->id(), $this->set->id(), 'Attempting to switch to a new shortcut set without providing a set name does not succeed.');
|
||||
$this->assertFieldByXPath("//input[@name='label' and contains(concat(' ', normalize-space(@class), ' '), ' error ')]", NULL, 'The new set label field has the error class');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests renaming a shortcut set.
|
||||
*/
|
||||
function testShortcutSetRename() {
|
||||
$set = $this->set;
|
||||
|
||||
$new_label = $this->randomMachineName();
|
||||
$this->drupalGet('admin/config/user-interface/shortcut');
|
||||
$this->clickLink(t('Edit shortcut set'));
|
||||
$this->drupalPostForm(NULL, array('label' => $new_label), t('Save'));
|
||||
$set = ShortcutSet::load($set->id());
|
||||
$this->assertTrue($set->label() == $new_label, 'Shortcut set has been successfully renamed.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests unassigning a shortcut set.
|
||||
*/
|
||||
function testShortcutSetUnassign() {
|
||||
$new_set = $this->generateShortcutSet($this->randomMachineName());
|
||||
|
||||
$shortcut_set_storage = \Drupal::entityManager()->getStorage('shortcut_set');
|
||||
$shortcut_set_storage->assignUser($new_set, $this->shortcutUser);
|
||||
$shortcut_set_storage->unassignUser($this->shortcutUser);
|
||||
$current_set = shortcut_current_displayed_set($this->shortcutUser);
|
||||
$default_set = shortcut_default_set($this->shortcutUser);
|
||||
$this->assertTrue($current_set->id() == $default_set->id(), "Successfully unassigned another user's shortcut set.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests deleting a shortcut set.
|
||||
*/
|
||||
function testShortcutSetDelete() {
|
||||
$new_set = $this->generateShortcutSet($this->randomMachineName());
|
||||
|
||||
$this->drupalPostForm('admin/config/user-interface/shortcut/manage/' . $new_set->id() . '/delete', array(), t('Delete'));
|
||||
$sets = ShortcutSet::loadMultiple();
|
||||
$this->assertFalse(isset($sets[$new_set->id()]), 'Successfully deleted a shortcut set.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests deleting the default shortcut set.
|
||||
*/
|
||||
function testShortcutSetDeleteDefault() {
|
||||
$this->drupalGet('admin/config/user-interface/shortcut/manage/default/delete');
|
||||
$this->assertResponse(403);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests creating a new shortcut set with a defined set name.
|
||||
*/
|
||||
function testShortcutSetCreateWithSetName() {
|
||||
$random_name = $this->randomMachineName();
|
||||
$new_set = $this->generateShortcutSet($random_name, $random_name);
|
||||
$sets = ShortcutSet::loadMultiple();
|
||||
$this->assertTrue(isset($sets[$random_name]), 'Successfully created a shortcut set with a defined set name.');
|
||||
$this->drupalGet('user/' . $this->adminUser->id() . '/shortcuts');
|
||||
$this->assertText($new_set->label(), 'Generated shortcut set was listed as a choice on the user account page.');
|
||||
}
|
||||
|
||||
}
|
133
web/core/modules/shortcut/src/Tests/ShortcutTestBase.php
Normal file
133
web/core/modules/shortcut/src/Tests/ShortcutTestBase.php
Normal file
|
@ -0,0 +1,133 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\shortcut\Tests;
|
||||
|
||||
use Drupal\shortcut\Entity\Shortcut;
|
||||
use Drupal\shortcut\Entity\ShortcutSet;
|
||||
use Drupal\shortcut\ShortcutSetInterface;
|
||||
use Drupal\simpletest\WebTestBase;
|
||||
|
||||
/**
|
||||
* Defines base class for shortcut test cases.
|
||||
*/
|
||||
abstract class ShortcutTestBase extends WebTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('node', 'toolbar', 'shortcut');
|
||||
|
||||
/**
|
||||
* User with permission to administer shortcuts.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $adminUser;
|
||||
|
||||
/**
|
||||
* User with permission to use shortcuts, but not administer them.
|
||||
*
|
||||
* @var \Drupal\user\UserInterface
|
||||
*/
|
||||
protected $shortcutUser;
|
||||
|
||||
/**
|
||||
* Generic node used for testing.
|
||||
*
|
||||
* @var \Drupal\node\NodeInterface
|
||||
*/
|
||||
protected $node;
|
||||
|
||||
/**
|
||||
* Site-wide default shortcut set.
|
||||
*
|
||||
* @var \Drupal\shortcut\ShortcutSetInterface
|
||||
*/
|
||||
protected $set;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
if ($this->profile != 'standard') {
|
||||
// Create Basic page and Article node types.
|
||||
$this->drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page'));
|
||||
$this->drupalCreateContentType(array('type' => 'article', 'name' => 'Article'));
|
||||
|
||||
// Populate the default shortcut set.
|
||||
$shortcut = Shortcut::create(array(
|
||||
'shortcut_set' => 'default',
|
||||
'title' => t('Add content'),
|
||||
'weight' => -20,
|
||||
'link' => array(
|
||||
'uri' => 'internal:/node/add',
|
||||
),
|
||||
));
|
||||
$shortcut->save();
|
||||
|
||||
$shortcut = Shortcut::create(array(
|
||||
'shortcut_set' => 'default',
|
||||
'title' => t('All content'),
|
||||
'weight' => -19,
|
||||
'link' => array(
|
||||
'uri' => 'internal:/admin/content',
|
||||
),
|
||||
));
|
||||
$shortcut->save();
|
||||
}
|
||||
|
||||
// Create users.
|
||||
$this->adminUser = $this->drupalCreateUser(array('access toolbar', 'administer shortcuts', 'view the administration theme', 'create article content', 'create page content', 'access content overview', 'administer users', 'link to any page', 'edit any article content'));
|
||||
$this->shortcutUser = $this->drupalCreateUser(array('customize shortcut links', 'switch shortcut sets', 'access shortcuts', 'access content'));
|
||||
|
||||
// Create a node.
|
||||
$this->node = $this->drupalCreateNode(array('type' => 'article'));
|
||||
|
||||
// Log in as admin and grab the default shortcut set.
|
||||
$this->drupalLogin($this->adminUser);
|
||||
$this->set = ShortcutSet::load('default');
|
||||
\Drupal::entityManager()->getStorage('shortcut_set')->assignUser($this->set, $this->adminUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a generic shortcut set.
|
||||
*/
|
||||
function generateShortcutSet($label = '', $id = NULL) {
|
||||
$set = ShortcutSet::create(array(
|
||||
'id' => isset($id) ? $id : strtolower($this->randomMachineName()),
|
||||
'label' => empty($label) ? $this->randomString() : $label,
|
||||
));
|
||||
$set->save();
|
||||
return $set;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts information from shortcut set links.
|
||||
*
|
||||
* @param \Drupal\shortcut\ShortcutSetInterface $set
|
||||
* The shortcut set object to extract information from.
|
||||
* @param string $key
|
||||
* The array key indicating what information to extract from each link:
|
||||
* - 'title': Extract shortcut titles.
|
||||
* - 'link': Extract shortcut paths.
|
||||
* - 'id': Extract the shortcut ID.
|
||||
*
|
||||
* @return array
|
||||
* Array of the requested information from each link.
|
||||
*/
|
||||
function getShortcutInformation(ShortcutSetInterface $set, $key) {
|
||||
$info = array();
|
||||
\Drupal::entityManager()->getStorage('shortcut')->resetCache();
|
||||
foreach ($set->getShortcuts() as $shortcut) {
|
||||
if ($key == 'link') {
|
||||
$info[] = $shortcut->link->uri;
|
||||
}
|
||||
else {
|
||||
$info[] = $shortcut->{$key}->value;
|
||||
}
|
||||
}
|
||||
return $info;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\shortcut\Tests;
|
||||
|
||||
use Drupal\content_translation\Tests\ContentTranslationUITestBase;
|
||||
use Drupal\Core\Entity\EntityChangedInterface;
|
||||
use Drupal\Core\Language\Language;
|
||||
|
||||
/**
|
||||
* Tests the shortcut translation UI.
|
||||
*
|
||||
* @group Shortcut
|
||||
*/
|
||||
class ShortcutTranslationUITest extends ContentTranslationUITestBase {
|
||||
|
||||
/**
|
||||
* {inheritdoc}
|
||||
*/
|
||||
protected $defaultCacheContexts = ['languages:language_interface', 'session', 'theme', 'user', 'url.path', 'url.query_args', 'url.site'];
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array(
|
||||
'language',
|
||||
'content_translation',
|
||||
'link',
|
||||
'shortcut',
|
||||
'toolbar'
|
||||
);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
$this->entityTypeId = 'shortcut';
|
||||
$this->bundle = 'default';
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getTranslatorPermissions() {
|
||||
return array_merge(parent::getTranslatorPermissions(), array('access shortcuts', 'administer shortcuts', 'access toolbar'));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function createEntity($values, $langcode, $bundle_name = NULL) {
|
||||
$values['link']['uri'] = 'internal:/user';
|
||||
return parent::createEntity($values, $langcode, $bundle_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getNewEntityValues($langcode) {
|
||||
return array('title' => array(array('value' => $this->randomMachineName()))) + parent::getNewEntityValues($langcode);
|
||||
}
|
||||
|
||||
protected function doTestBasicTranslation() {
|
||||
parent::doTestBasicTranslation();
|
||||
|
||||
$storage = $this->container->get('entity_type.manager')
|
||||
->getStorage($this->entityTypeId);
|
||||
$storage->resetCache([$this->entityId]);
|
||||
$entity = $storage->load($this->entityId);
|
||||
foreach ($this->langcodes as $langcode) {
|
||||
if ($entity->hasTranslation($langcode)) {
|
||||
$language = new Language(array('id' => $langcode));
|
||||
// Request the front page in this language and assert that the right
|
||||
// translation shows up in the shortcut list with the right path.
|
||||
$this->drupalGet('<front>', array('language' => $language));
|
||||
$expected_path = \Drupal::urlGenerator()->generateFromRoute('user.page', array(), array('language' => $language));
|
||||
$label = $entity->getTranslation($langcode)->label();
|
||||
$elements = $this->xpath('//nav[contains(@class, "toolbar-lining")]/ul[@class="toolbar-menu"]/li/a[contains(@href, :href) and normalize-space(text())=:label]', array(':href' => $expected_path, ':label' => $label));
|
||||
$this->assertTrue(!empty($elements), format_string('Translated @language shortcut link @label found.', array('@label' => $label, '@language' => $language->getName())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function doTestTranslationEdit() {
|
||||
$storage = $this->container->get('entity_type.manager')
|
||||
->getStorage($this->entityTypeId);
|
||||
$storage->resetCache([$this->entityId]);
|
||||
$entity = $storage->load($this->entityId);
|
||||
$languages = $this->container->get('language_manager')->getLanguages();
|
||||
|
||||
foreach ($this->langcodes as $langcode) {
|
||||
// We only want to test the title for non-english translations.
|
||||
if ($langcode != 'en') {
|
||||
$options = array('language' => $languages[$langcode]);
|
||||
$url = $entity->urlInfo('edit-form', $options);
|
||||
$this->drupalGet($url);
|
||||
|
||||
$title = t('@title [%language translation]', array(
|
||||
'@title' => $entity->getTranslation($langcode)->label(),
|
||||
'%language' => $languages[$langcode]->getName(),
|
||||
));
|
||||
$this->assertRaw($title);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the basic translation workflow.
|
||||
*/
|
||||
protected function doTestTranslationChanged() {
|
||||
$storage = $this->container->get('entity_type.manager')
|
||||
->getStorage($this->entityTypeId);
|
||||
$storage->resetCache([$this->entityId]);
|
||||
$entity = $storage->load($this->entityId);
|
||||
|
||||
$this->assertFalse(
|
||||
$entity instanceof EntityChangedInterface,
|
||||
format_string('%entity is not implementing EntityChangedInterface.', array('%entity' => $this->entityTypeId))
|
||||
);
|
||||
}
|
||||
|
||||
}
|
Reference in a new issue