Issue #1932048 by nick_schuch, tim.plunkett, larowlan: Clean up tour ConfigEntity architecture.
parent
6ba3cb12c1
commit
e682328574
|
@ -20,11 +20,12 @@ use Drupal\tour\TipsBag;
|
|||
* label = @Translation("Tour"),
|
||||
* module = "tour",
|
||||
* controller_class = "Drupal\Core\Config\Entity\ConfigStorageController",
|
||||
* render_controller_class = "Drupal\tour\TourRenderController",
|
||||
* config_prefix = "tour.tour",
|
||||
* entity_keys = {
|
||||
* "id" = "id",
|
||||
* "label" = "label",
|
||||
* "uuid" = "uuid",
|
||||
* "uuid" = "uuid"
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
|
@ -34,7 +35,6 @@ class Tour extends ConfigEntityBase {
|
|||
* The name (plugin ID) of the tour.
|
||||
*
|
||||
* @var string
|
||||
* Unique identifier for this tour.
|
||||
*/
|
||||
public $id;
|
||||
|
||||
|
@ -42,7 +42,6 @@ class Tour extends ConfigEntityBase {
|
|||
* The label of the tour.
|
||||
*
|
||||
* @var string
|
||||
* A human readable name for this tour.
|
||||
*/
|
||||
public $label;
|
||||
|
||||
|
@ -50,9 +49,8 @@ class Tour extends ConfigEntityBase {
|
|||
* The paths in which this tip can be displayed.
|
||||
*
|
||||
* @var array
|
||||
* An array of paths.
|
||||
*/
|
||||
protected $paths;
|
||||
protected $paths = array();
|
||||
|
||||
/**
|
||||
* Holds the collection of tips that are attached to this tour.
|
||||
|
@ -66,7 +64,7 @@ class Tour extends ConfigEntityBase {
|
|||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $tips;
|
||||
protected $tips = array();
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\Core\Config\Entity\ConfigEntityBase::__construct();
|
||||
|
@ -108,13 +106,25 @@ class Tour extends ConfigEntityBase {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns a list of tips.
|
||||
* Returns the tips for this tour.
|
||||
*
|
||||
* @return array
|
||||
* A list of tips.
|
||||
* An array of tip plugins.
|
||||
*/
|
||||
public function getTipList() {
|
||||
return array_keys($this->tips);
|
||||
public function getTips() {
|
||||
$tips = array();
|
||||
foreach ($this->tips as $id => $tip) {
|
||||
$tips[] = $this->getTip($id);
|
||||
}
|
||||
uasort($tips, function ($a, $b) {
|
||||
if ($a->getWeight() == $b->getWeight()) {
|
||||
return 0;
|
||||
}
|
||||
return ($a->getWeight() < $b->getWeight()) ? -1 : 1;
|
||||
});
|
||||
|
||||
drupal_container()->get('module_handler')->alter('tour_tips', $tips, $this);
|
||||
return array_values($tips);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -123,15 +133,13 @@ class Tour extends ConfigEntityBase {
|
|||
public function getExportProperties() {
|
||||
$properties = parent::getExportProperties();
|
||||
$names = array(
|
||||
'id',
|
||||
'label',
|
||||
'paths',
|
||||
'tips',
|
||||
'langcode',
|
||||
);
|
||||
foreach ($names as $name) {
|
||||
$properties[$name] = $this->get($name);
|
||||
}
|
||||
return $properties;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\tour\TipPluginText.
|
||||
* Contains \Drupal\tour\Plugin\tour\tip\TipPluginText.
|
||||
*/
|
||||
|
||||
namespace Drupal\tour\Plugin\tour\tip;
|
||||
|
@ -24,7 +24,6 @@ class TipPluginText extends TipPluginBase {
|
|||
* The body text which is used for render of this Text Tip.
|
||||
*
|
||||
* @var string
|
||||
* A string of text used as the body.
|
||||
*/
|
||||
protected $body;
|
||||
|
||||
|
@ -32,7 +31,6 @@ class TipPluginText extends TipPluginBase {
|
|||
* The forced position of where the tip will be located.
|
||||
*
|
||||
* @var string
|
||||
* A string of left|right|top|bottom.
|
||||
*/
|
||||
protected $location;
|
||||
|
||||
|
@ -40,7 +38,7 @@ class TipPluginText extends TipPluginBase {
|
|||
* Returns a ID that is guaranteed uniqueness.
|
||||
*
|
||||
* @return string
|
||||
* A unique string.
|
||||
* A unique id to be used to generate aria attributes.
|
||||
*/
|
||||
public function getAriaId() {
|
||||
static $id;
|
||||
|
@ -54,7 +52,7 @@ class TipPluginText extends TipPluginBase {
|
|||
* Returns body of the text tip.
|
||||
*
|
||||
* @return string
|
||||
* The body of the text tip.
|
||||
* The tip body.
|
||||
*/
|
||||
public function getBody() {
|
||||
return $this->get('body');
|
||||
|
@ -64,14 +62,14 @@ class TipPluginText extends TipPluginBase {
|
|||
* Returns location of the text tip.
|
||||
*
|
||||
* @return string
|
||||
* The location (left|right|top|bottom) of the text tip.
|
||||
* The tip location.
|
||||
*/
|
||||
public function getLocation() {
|
||||
return $this->get('location');
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\tour\Plugin\tour\tour\TipPluginInterface::getAttributes();
|
||||
* Overrides \Drupal\tour\TipPluginBase::getAttributes().
|
||||
*/
|
||||
public function getAttributes() {
|
||||
$attributes = parent::getAttributes();
|
||||
|
@ -84,7 +82,7 @@ class TipPluginText extends TipPluginBase {
|
|||
}
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\tour\Plugin\tour\tour\TipPluginInterface::getOutput();
|
||||
* Implements \Drupal\tour\TipPluginInterface::getOutput().
|
||||
*/
|
||||
public function getOutput() {
|
||||
$output = '<h2 class="tour-tip-label" id="tour-tip-' . $this->getAriaId() . '-label">' . check_plain($this->getLabel()) . '</h2>';
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
namespace Drupal\tour;
|
||||
|
||||
use Drupal\Component\Plugin\PluginBase;
|
||||
use Drupal\Core\Plugin\Discovery\CacheDecorator;
|
||||
use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
|
||||
use Drupal\tour\TipPluginInterface;
|
||||
|
||||
/**
|
||||
|
@ -20,7 +20,6 @@ abstract class TipPluginBase extends PluginBase implements TipPluginInterface {
|
|||
* The label which is used for render of this tip.
|
||||
*
|
||||
* @var string
|
||||
* The label of this tip.
|
||||
*/
|
||||
protected $label;
|
||||
|
||||
|
@ -28,7 +27,6 @@ abstract class TipPluginBase extends PluginBase implements TipPluginInterface {
|
|||
* Allows tips to take more priority that others.
|
||||
*
|
||||
* @var string
|
||||
* A number which pertains to ordering.
|
||||
*/
|
||||
protected $weight;
|
||||
|
||||
|
@ -36,14 +34,13 @@ abstract class TipPluginBase extends PluginBase implements TipPluginInterface {
|
|||
* The attributes that will be applied to the markup of this tip.
|
||||
*
|
||||
* @var array
|
||||
* An array of attributes.
|
||||
*/
|
||||
protected $attributes;
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\Component\Plugin\PluginBase::__construct().
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, CacheDecorator $discovery) {
|
||||
public function __construct(array $configuration, $plugin_id, DiscoveryInterface $discovery) {
|
||||
parent::__construct($configuration, $plugin_id, $discovery);
|
||||
|
||||
$this->definition = $this->discovery->getDefinition($plugin_id);
|
||||
|
@ -51,28 +48,28 @@ abstract class TipPluginBase extends PluginBase implements TipPluginInterface {
|
|||
}
|
||||
|
||||
/**
|
||||
* Implements \Drupal\tour\Plugin\tour\tour\TourInterface::getLabel().
|
||||
* Implements \Drupal\tour\TipPluginInterface::getLabel().
|
||||
*/
|
||||
public function getLabel() {
|
||||
return $this->get('label');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements \Drupal\tour\Plugin\tour\tour\TourInterface::getWeight().
|
||||
* Implements \Drupal\tour\TipPluginInterface::getWeight().
|
||||
*/
|
||||
public function getWeight() {
|
||||
return $this->get('weight');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements \Drupal\tour\Plugin\tour\tour\TourInterface::getAttributes().
|
||||
* Implements \Drupal\tour\TipPluginInterface::getAttributes().
|
||||
*/
|
||||
public function getAttributes() {
|
||||
return $this->get('attributes');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements \Drupal\tour\Plugin\tour\tour\TourInterface::get().
|
||||
* Implements \Drupal\tour\TipPluginInterface::get().
|
||||
*/
|
||||
public function get($key) {
|
||||
if (!empty($this->configuration[$key])) {
|
||||
|
@ -81,7 +78,7 @@ abstract class TipPluginBase extends PluginBase implements TipPluginInterface {
|
|||
}
|
||||
|
||||
/**
|
||||
* Implements \Drupal\tour\Plugin\tour\tour\TourInterface::set().
|
||||
* Implements \Drupal\tour\TipPluginInterface::set().
|
||||
*/
|
||||
public function set($key, $value) {
|
||||
$this->configuration[$key] = $value;
|
||||
|
|
|
@ -65,4 +65,5 @@ interface TipPluginInterface {
|
|||
* A renderable array.
|
||||
*/
|
||||
public function getOutput();
|
||||
|
||||
}
|
||||
|
|
|
@ -27,16 +27,8 @@ class TipPluginManager extends PluginManagerBase {
|
|||
public function __construct(array $namespaces) {
|
||||
$this->discovery = new AnnotatedClassDiscovery('tour', 'tip', $namespaces);
|
||||
$this->discovery = new CacheDecorator($this->discovery, 'tour');
|
||||
|
||||
$this->factory = new DefaultFactory($this->discovery);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\Component\Plugin\PluginManagerBase::createInstance().
|
||||
*
|
||||
* Pass the TipsBag to the plugin constructor.
|
||||
*/
|
||||
public function createInstance($plugin_id, array $configuration = array(), TipsBag $bag = NULL) {
|
||||
$plugin_class = DefaultFactory::getPluginClass($plugin_id, $this->discovery);
|
||||
return new $plugin_class($configuration, $plugin_id, $this->discovery, $bag);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ use Drupal\Component\Utility\NestedArray;
|
|||
* A collection of tips.
|
||||
*/
|
||||
class TipsBag extends PluginBag {
|
||||
|
||||
/**
|
||||
* The initial configuration for each tip in the bag.
|
||||
*
|
||||
|
@ -70,10 +71,11 @@ class TipsBag extends PluginBag {
|
|||
if (isset($this->configurations[$instance_id])) {
|
||||
$configuration = NestedArray::mergeDeep($configuration, $this->configurations[$instance_id]);
|
||||
}
|
||||
$this->pluginInstances[$instance_id] = $this->manager->createInstance($type, $configuration, $this);
|
||||
$this->pluginInstances[$instance_id] = $this->manager->createInstance($type, $configuration);
|
||||
}
|
||||
else {
|
||||
throw new PluginException(format_string("Unknown tip plugin ID '@tip'.", array('@tip' => $instance_id)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,4 +24,5 @@ class TourBundle extends Bundle {
|
|||
$container->register('plugin.manager.tour.tip', 'Drupal\tour\TipPluginManager')
|
||||
->addArgument('%container.namespaces%');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\tour\TourRenderController.
|
||||
*/
|
||||
|
||||
namespace Drupal\tour;
|
||||
|
||||
use Drupal\Core\Entity\EntityRenderController;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
|
||||
/**
|
||||
* Provides a Tour render controller.
|
||||
*/
|
||||
class TourRenderController extends EntityRenderController {
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\Core\Entity\EntityRenderController::viewMultiple().
|
||||
*/
|
||||
public function viewMultiple(array $entities = array(), $view_mode = 'full', $langcode = NULL) {
|
||||
$build = array();
|
||||
foreach ($entities as $entity_id => $entity) {
|
||||
$tips = $entity->getTips();
|
||||
$count = count($tips);
|
||||
$list_items = array();
|
||||
foreach ($tips as $index => $tip) {
|
||||
if ($output = $tip->getOutput()) {
|
||||
$list_items[] = array(
|
||||
'output' => $output,
|
||||
'counter' => array(
|
||||
'#type' => 'container',
|
||||
'#attributes' => array(
|
||||
'class' => array(
|
||||
'tour-progress',
|
||||
),
|
||||
),
|
||||
'#children' => t('!tour_item of !total', array('!tour_item' => $index + 1, '!total' => $count)),
|
||||
),
|
||||
'#wrapper_attributes' => $tip->getAttributes(),
|
||||
);
|
||||
}
|
||||
}
|
||||
// If there is at least one tour item, build the tour.
|
||||
if ($list_items) {
|
||||
end($list_items);
|
||||
$key = key($list_items);
|
||||
$list_items[$key]['#wrapper_attributes']['data-text'] = t('End tour');
|
||||
$build[$entity_id] = array(
|
||||
'#theme' => 'item_list',
|
||||
'#items' => $list_items,
|
||||
'#type' => 'ol',
|
||||
'#attributes' => array(
|
||||
'id' => 'tour',
|
||||
'class' => array(
|
||||
'element-hidden',
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
// If at least one tour was built, attach the tour library.
|
||||
if ($build) {
|
||||
$build['#attached']['library'][] = array('tour', 'tour');
|
||||
}
|
||||
return $build;
|
||||
}
|
||||
|
||||
}
|
|
@ -5,6 +5,8 @@
|
|||
* Provides tests for tour module
|
||||
*/
|
||||
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
|
||||
/**
|
||||
* Implements hook_menu().
|
||||
*/
|
||||
|
@ -76,9 +78,9 @@ function tour_test_2() {
|
|||
}
|
||||
|
||||
/**
|
||||
* Implements hook_tour_alter().
|
||||
* Implements hook_tour_tips_alter().
|
||||
*/
|
||||
function tour_test_tour_tips_alter(array &$tour_tips, $path) {
|
||||
function tour_test_tour_tips_alter(array &$tour_tips, EntityInterface $entity) {
|
||||
foreach ($tour_tips as $tour_tip) {
|
||||
if ($tour_tip->get('id') == 'tour-code-test-1') {
|
||||
$tour_tip->set('body', 'Altered by hook_tour_tips_alter');
|
||||
|
|
|
@ -8,12 +8,12 @@
|
|||
/**
|
||||
* Allow modules to alter tour items before render.
|
||||
*
|
||||
* @param array $tour_items
|
||||
* @param array $tour_tips
|
||||
* Array of \Drupal\tour\TipPluginInterface items.
|
||||
* @param string $path
|
||||
* The path for which the tour is valid.
|
||||
* @param \Drupal\Core\Entity\EntityInterface $entity
|
||||
* The tour which contains the $tour_tips.
|
||||
*/
|
||||
function hook_tour_tips_alter(array &$tour_tips, $path) {
|
||||
function hook_tour_tips_alter(array &$tour_tips, Drupal\Core\Entity\EntityInterface $entity) {
|
||||
foreach ($tour_tips as $tour_tip) {
|
||||
if ($tour_tip->get('id') == 'tour-code-test-1') {
|
||||
$tour_tip->set('body', 'Altered by hook_tour_tips_alter');
|
||||
|
|
|
@ -121,83 +121,18 @@ function tour_preprocess_page(&$variables) {
|
|||
$tours = entity_load_multiple('tour', $tour_ids);
|
||||
|
||||
$path_alias = drupal_strtolower(drupal_container()->get('path.alias_manager')->getPathAlias($path));
|
||||
foreach ($tours as $tour) {
|
||||
foreach ($tours as $tour_id => $tour) {
|
||||
// @todo replace this with an entity_query() that does path matching when
|
||||
// http://drupal.org/node/1918768 lands.
|
||||
$pages = implode("\n", $tour->getPaths());
|
||||
if (drupal_match_path($path_alias, $pages) || (($path != $path_alias) && drupal_match_path($path, $pages))) {
|
||||
foreach ($tour->getTipList() as $id) {
|
||||
$tour_items[] = $tour->getTip($id);
|
||||
}
|
||||
if (!drupal_match_path($path_alias, $pages) && (($path == $path_alias) || drupal_match_path($path, $pages))) {
|
||||
unset($tours[$tour_id]);
|
||||
}
|
||||
}
|
||||
|
||||
// Allow other modules to alter.
|
||||
drupal_container()->get('module_handler')->alter('tour_tips', $tour_items, $path);
|
||||
|
||||
if (empty($tour_items)) {
|
||||
return;
|
||||
if ($tours) {
|
||||
$variables['page']['help']['tour'] = entity_view_multiple($tours, 'full');
|
||||
}
|
||||
|
||||
// Sort by weight.
|
||||
uasort($tour_items, function ($a, $b) {
|
||||
if ($a->getWeight() == $b->getWeight()) {
|
||||
return 0;
|
||||
}
|
||||
return ($a->getWeight() < $b->getWeight()) ? -1 : 1;
|
||||
});
|
||||
|
||||
$index = 1;
|
||||
$count = count($tour_items);
|
||||
foreach ($tour_items as $tour_item) {
|
||||
$list_items[] = array(
|
||||
'output' => $tour_item->getOutput(),
|
||||
'counter' => array(
|
||||
'#type' => 'container',
|
||||
'#attributes' => array(
|
||||
'class' => array(
|
||||
'tour-progress',
|
||||
),
|
||||
),
|
||||
'#children' => t('!tour_item of !total', array('!tour_item' => $index, '!total' => $count)),
|
||||
),
|
||||
'#wrapper_attributes' => $tour_item->getAttributes(),
|
||||
);
|
||||
$index++;
|
||||
}
|
||||
|
||||
// Give the last tip the "End tour" button.
|
||||
end($list_items);
|
||||
$key = key($list_items);
|
||||
$list_items[$key]['#wrapper_attributes']['data-text'] = t('End tour');
|
||||
|
||||
$variables['page']['help']['tour'] = array(
|
||||
'#theme' => 'item_list',
|
||||
'#items' => $list_items,
|
||||
'#type' => 'ol',
|
||||
'#attributes' => array(
|
||||
'id' => 'tour',
|
||||
'class' => array(
|
||||
'element-hidden',
|
||||
),
|
||||
),
|
||||
'#attached' => array(
|
||||
'library' => array(
|
||||
// We must also attach the jquery.joyride library here, because it only
|
||||
// works within the window within which it is loaded. This means that if
|
||||
// we want the Tour module to work inside the Overlay, we must ensure
|
||||
// that jquery.joyride also is loaded there. (And since the Toolbar does
|
||||
// not get loaded inside the Overlay, we cannot rely on it being loaded
|
||||
// that way.)
|
||||
// If this a non-overlay page, then Drupal's dependency checking will
|
||||
// ensure this gets loaded only once.
|
||||
array('tour', 'jquery.joyride'),
|
||||
// Similarly, we must load tour's CSS, in order to style the tour tips
|
||||
// in the desired way inside the Overlay.
|
||||
array('tour', 'tour-styling'),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue