443ab5d04090ca8f1e96cd672910b03f2ce49f21
[yaffs-website] / web / core / modules / system / tests / modules / plugin_test / src / Plugin / MockBlockManager.php
1 <?php
2
3 namespace Drupal\plugin_test\Plugin;
4
5 use Drupal\Component\Plugin\PluginManagerBase;
6 use Drupal\Component\Plugin\Discovery\StaticDiscovery;
7 use Drupal\Component\Plugin\Discovery\DerivativeDiscoveryDecorator;
8 use Drupal\Component\Plugin\Factory\ReflectionFactory;
9 use Drupal\Core\Plugin\Context\ContextDefinition;
10
11 /**
12  * Defines a plugin manager used by Plugin API derivative unit tests.
13  */
14 class MockBlockManager extends PluginManagerBase {
15   public function __construct() {
16
17     // Create the object that can be used to return definitions for all the
18     // plugins available for this type. Most real plugin managers use a richer
19     // discovery implementation, but StaticDiscovery lets us add some simple
20     // mock plugins for unit testing.
21     $this->discovery = new StaticDiscovery();
22
23     // Derivative plugins are plugins that are derived from a base plugin
24     // definition and some site configuration (examples below). To allow for
25     // such plugins, we add the DerivativeDiscoveryDecorator to our discovery
26     // object.
27     $this->discovery = new DerivativeDiscoveryDecorator($this->discovery);
28
29     // The plugin definitions that follow are based on work that is in progress
30     // for the Drupal 8 Blocks and Layouts initiative
31     // (http://groups.drupal.org/node/213563). As stated above, we set
32     // definitions here, because this is for unit testing. Real plugin managers
33     // use a discovery implementation that allows for any module to add new
34     // plugins to the system.
35
36     // A simple plugin: the user login block.
37     $this->discovery->setDefinition('user_login', [
38       'id' => 'user_login',
39       'label' => t('User login'),
40       'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockUserLoginBlock',
41     ]);
42
43     // A plugin that requires derivatives: the menu block plugin. We do not want
44     // a generic "Menu" block showing up in the Block administration UI.
45     // Instead, we want a block for each menu, but the number of menus in the
46     // system and each one's title is user configurable. The
47     // MockMenuBlockDeriver class ensures that only derivatives, and not the
48     // base plugin, are available to the system.
49     $this->discovery->setDefinition('menu', [
50       'id' => 'menu',
51       'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockMenuBlock',
52       'deriver' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockMenuBlockDeriver',
53     ]);
54     // A plugin defining itself as a derivative.
55     $this->discovery->setDefinition('menu:foo', [
56       'id' => 'menu',
57       'label' => t('Base label'),
58       'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockMenuBlock',
59     ]);
60
61     // A block plugin that can optionally be derived: the layout block plugin.
62     // A layout is a special kind of block into which other blocks can be
63     // placed. We want both a generic "Layout" block available in the Block
64     // administration UI as well as additional user-created custom layouts. The
65     // MockLayoutBlockDeriver class ensures that both the base plugin and the
66     // derivatives are available to the system.
67     $this->discovery->setDefinition('layout', [
68       'id' => 'layout',
69       'label' => t('Layout'),
70       'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockLayoutBlock',
71       'deriver' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockLayoutBlockDeriver',
72     ]);
73
74     // A block plugin that requires context to function. This block requires a
75     // user object in order to return the user name from the getTitle() method.
76     $this->discovery->setDefinition('user_name', [
77       'id' => 'user_name',
78       'label' => t('User name'),
79       'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockUserNameBlock',
80       'context' => [
81         'user' => $this->createContextDefinition('entity:user', t('User')),
82       ],
83     ]);
84
85     // An optional context version of the previous block plugin.
86     $this->discovery->setDefinition('user_name_optional', [
87       'id' => 'user_name_optional',
88       'label' => t('User name optional'),
89       'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockUserNameBlock',
90       'context' => [
91         'user' => $this->createContextDefinition('entity:user', t('User'), FALSE),
92       ],
93     ]);
94
95     // A block plugin that requires a typed data string context to function.
96     $this->discovery->setDefinition('string_context', [
97       'id' => 'string_context',
98       'label' => t('String typed data'),
99       'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\TypedDataStringBlock',
100     ]);
101
102     // A complex context plugin that requires both a user and node for context.
103     $this->discovery->setDefinition('complex_context', [
104       'id' => 'complex_context',
105       'label' => t('Complex context'),
106       'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockComplexContextBlock',
107       'context' => [
108         'user' => $this->createContextDefinition('entity:user', t('User')),
109         'node' => $this->createContextDefinition('entity:node', t('Node')),
110       ],
111     ]);
112
113     // In addition to finding all of the plugins available for a type, a plugin
114     // type must also be able to create instances of that plugin. For example, a
115     // specific instance of a "Main menu" menu block, configured to show just
116     // the top-level of links. To handle plugin instantiation, plugin managers
117     // can use one of the factory classes included with the plugin system, or
118     // create their own. ReflectionFactory is a general purpose, flexible
119     // factory suitable for many kinds of plugin types. Factories need access to
120     // the plugin definitions (e.g., since that's where the plugin's class is
121     // specified), so we provide it the discovery object.
122     $this->factory = new ReflectionFactory($this->discovery);
123   }
124
125   /**
126    * Creates a new context definition with a label that is cast to string.
127    *
128    * @param string $data_type
129    *   The required data type.
130    * @param mixed|string|null $label
131    *   The label of this context definition for the UI.
132    * @param bool $required
133    *   Whether the context definition is required.
134    *
135    * @return \Drupal\Core\Plugin\Context\ContextDefinition
136    */
137   protected function createContextDefinition($data_type, $label, $required = TRUE) {
138     // We cast the label to string for testing purposes only, as it may be
139     // a TranslatableMarkup and we will do assertEqual() checks on arrays that
140     // include ContextDefinition objects, and var_export() has problems
141     // printing TranslatableMarkup objects.
142     return new ContextDefinition($data_type, (string) $label, $required);
143   }
144
145 }