Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 /**
|
Chris@0
|
4 * @file
|
Chris@0
|
5 * Hooks provided by the Block module.
|
Chris@0
|
6 */
|
Chris@0
|
7
|
Chris@0
|
8 use Drupal\Core\Access\AccessResult;
|
Chris@0
|
9
|
Chris@0
|
10 /**
|
Chris@0
|
11 * @defgroup block_api Block API
|
Chris@0
|
12 * @{
|
Chris@0
|
13 * Information about the classes and interfaces that make up the Block API.
|
Chris@0
|
14 *
|
Chris@0
|
15 * Blocks are a combination of a configuration entity and a plugin. The
|
Chris@0
|
16 * configuration entity stores placement information (theme, region, weight) and
|
Chris@0
|
17 * any other configuration that is specific to the block. The block plugin does
|
Chris@0
|
18 * the work of rendering the block's content for display.
|
Chris@0
|
19 *
|
Chris@0
|
20 * To define a block in a module you need to:
|
Chris@0
|
21 * - Define a Block plugin by creating a new class that implements the
|
Chris@0
|
22 * \Drupal\Core\Block\BlockPluginInterface, in namespace Plugin\Block under your
|
Chris@0
|
23 * module namespace. For more information about creating plugins, see the
|
Chris@0
|
24 * @link plugin_api Plugin API topic. @endlink
|
Chris@0
|
25 * - Usually you will want to extend the \Drupal\Core\Block\BlockBase class, which
|
Chris@0
|
26 * provides a common configuration form and utility methods for getting and
|
Chris@0
|
27 * setting configuration in the block configuration entity.
|
Chris@0
|
28 * - Block plugins use the annotations defined by
|
Chris@0
|
29 * \Drupal\Core\Block\Annotation\Block. See the
|
Chris@0
|
30 * @link annotation Annotations topic @endlink for more information about
|
Chris@0
|
31 * annotations.
|
Chris@0
|
32 *
|
Chris@0
|
33 * The Block API also makes use of Condition plugins, for conditional block
|
Chris@0
|
34 * placement. Condition plugins have interface
|
Chris@0
|
35 * \Drupal\Core\Condition\ConditionInterface, base class
|
Chris@0
|
36 * \Drupal\Core\Condition\ConditionPluginBase, and go in plugin namespace
|
Chris@0
|
37 * Plugin\Condition. Again, see the Plugin API and Annotations topics for
|
Chris@0
|
38 * details of how to create a plugin class and annotate it.
|
Chris@0
|
39 *
|
Chris@0
|
40 * There are also several block-related hooks, which allow you to affect
|
Chris@0
|
41 * the content and access permissions for blocks:
|
Chris@0
|
42 * - hook_block_view_alter()
|
Chris@0
|
43 * - hook_block_view_BASE_BLOCK_ID_alter()
|
Chris@0
|
44 * - hook_block_access()
|
Chris@0
|
45 *
|
Chris@0
|
46 * Further information and examples:
|
Chris@0
|
47 * - \Drupal\system\Plugin\Block\SystemPoweredByBlock provides a simple example
|
Chris@0
|
48 * of defining a block.
|
Chris@0
|
49 * - \Drupal\user\Plugin\Condition\UserRole is a straightforward example of a
|
Chris@0
|
50 * block placement condition plugin.
|
Chris@0
|
51 * - \Drupal\book\Plugin\Block\BookNavigationBlock is an example of a block with
|
Chris@0
|
52 * a custom configuration form.
|
Chris@0
|
53 * - For a more in-depth discussion of the Block API, see
|
Chris@0
|
54 * https://www.drupal.org/developing/api/8/block_api.
|
Chris@0
|
55 * - The Examples for Developers project also provides a Block example in
|
Chris@0
|
56 * https://www.drupal.org/project/examples.
|
Chris@0
|
57 * @}
|
Chris@0
|
58 */
|
Chris@0
|
59
|
Chris@0
|
60 /**
|
Chris@0
|
61 * @addtogroup hooks
|
Chris@0
|
62 * @{
|
Chris@0
|
63 */
|
Chris@0
|
64
|
Chris@0
|
65 /**
|
Chris@0
|
66 * Alter the result of \Drupal\Core\Block\BlockBase::build().
|
Chris@0
|
67 *
|
Chris@0
|
68 * This hook is called after the content has been assembled in a structured
|
Chris@0
|
69 * array and may be used for doing processing which requires that the complete
|
Chris@0
|
70 * block content structure has been built.
|
Chris@0
|
71 *
|
Chris@0
|
72 * If the module wishes to act on the rendered HTML of the block rather than
|
Chris@0
|
73 * the structured content array, it may use this hook to add a #post_render
|
Chris@0
|
74 * callback. Alternatively, it could also implement hook_preprocess_HOOK() for
|
Chris@0
|
75 * block.html.twig. See drupal_render() documentation or the
|
Chris@0
|
76 * @link themeable Default theme implementations topic @endlink for details.
|
Chris@0
|
77 *
|
Chris@0
|
78 * In addition to hook_block_view_alter(), which is called for all blocks, there
|
Chris@0
|
79 * is hook_block_view_BASE_BLOCK_ID_alter(), which can be used to target a
|
Chris@0
|
80 * specific block or set of similar blocks.
|
Chris@0
|
81 *
|
Chris@0
|
82 * @param array &$build
|
Chris@0
|
83 * A renderable array of data, as returned from the build() implementation of
|
Chris@0
|
84 * the plugin that defined the block:
|
Chris@0
|
85 * - #title: The default localized title of the block.
|
Chris@0
|
86 * @param \Drupal\Core\Block\BlockPluginInterface $block
|
Chris@0
|
87 * The block plugin instance.
|
Chris@0
|
88 *
|
Chris@0
|
89 * @see hook_block_view_BASE_BLOCK_ID_alter()
|
Chris@0
|
90 * @see entity_crud
|
Chris@0
|
91 *
|
Chris@0
|
92 * @ingroup block_api
|
Chris@0
|
93 */
|
Chris@0
|
94 function hook_block_view_alter(array &$build, \Drupal\Core\Block\BlockPluginInterface $block) {
|
Chris@0
|
95 // Remove the contextual links on all blocks that provide them.
|
Chris@0
|
96 if (isset($build['#contextual_links'])) {
|
Chris@0
|
97 unset($build['#contextual_links']);
|
Chris@0
|
98 }
|
Chris@0
|
99 }
|
Chris@0
|
100
|
Chris@0
|
101 /**
|
Chris@0
|
102 * Provide a block plugin specific block_view alteration.
|
Chris@0
|
103 *
|
Chris@0
|
104 * In this hook name, BASE_BLOCK_ID refers to the block implementation's plugin
|
Chris@0
|
105 * id, regardless of whether the plugin supports derivatives. For example, for
|
Chris@0
|
106 * the \Drupal\system\Plugin\Block\SystemPoweredByBlock block, this would be
|
Chris@0
|
107 * 'system_powered_by_block' as per that class's annotation. And for the
|
Chris@0
|
108 * \Drupal\system\Plugin\Block\SystemMenuBlock block, it would be
|
Chris@0
|
109 * 'system_menu_block' as per that class's annotation, regardless of which menu
|
Chris@0
|
110 * the derived block is for.
|
Chris@0
|
111 *
|
Chris@0
|
112 * @param array $build
|
Chris@0
|
113 * A renderable array of data, as returned from the build() implementation of
|
Chris@0
|
114 * the plugin that defined the block:
|
Chris@0
|
115 * - #title: The default localized title of the block.
|
Chris@0
|
116 * @param \Drupal\Core\Block\BlockPluginInterface $block
|
Chris@0
|
117 * The block plugin instance.
|
Chris@0
|
118 *
|
Chris@0
|
119 * @see hook_block_view_alter()
|
Chris@0
|
120 * @see entity_crud
|
Chris@0
|
121 *
|
Chris@0
|
122 * @ingroup block_api
|
Chris@0
|
123 */
|
Chris@0
|
124 function hook_block_view_BASE_BLOCK_ID_alter(array &$build, \Drupal\Core\Block\BlockPluginInterface $block) {
|
Chris@0
|
125 // Change the title of the specific block.
|
Chris@0
|
126 $build['#title'] = t('New title of the block');
|
Chris@0
|
127 }
|
Chris@0
|
128
|
Chris@0
|
129 /**
|
Chris@0
|
130 * Alter the result of \Drupal\Core\Block\BlockBase::build().
|
Chris@0
|
131 *
|
Chris@0
|
132 * Unlike hook_block_view_alter(), this hook is called very early, before the
|
Chris@0
|
133 * block is being assembled. Therefore, it is early enough to alter the
|
Chris@0
|
134 * cacheability metadata (change #cache), or to explicitly placeholder the block
|
Chris@0
|
135 * (set #create_placeholder).
|
Chris@0
|
136 *
|
Chris@0
|
137 * In addition to hook_block_build_alter(), which is called for all blocks,
|
Chris@0
|
138 * there is hook_block_build_BASE_BLOCK_ID_alter(), which can be used to target
|
Chris@0
|
139 * a specific block or set of similar blocks.
|
Chris@0
|
140 *
|
Chris@0
|
141 * @param array &$build
|
Chris@0
|
142 * A renderable array of data, only containing #cache.
|
Chris@0
|
143 * @param \Drupal\Core\Block\BlockPluginInterface $block
|
Chris@0
|
144 * The block plugin instance.
|
Chris@0
|
145 *
|
Chris@0
|
146 * @see hook_block_build_BASE_BLOCK_ID_alter()
|
Chris@0
|
147 * @see entity_crud
|
Chris@0
|
148 *
|
Chris@0
|
149 * @ingroup block_api
|
Chris@0
|
150 */
|
Chris@0
|
151 function hook_block_build_alter(array &$build, \Drupal\Core\Block\BlockPluginInterface $block) {
|
Chris@0
|
152 // Add the 'user' cache context to some blocks.
|
Chris@16
|
153 if ($block->label() === 'some condition') {
|
Chris@0
|
154 $build['#cache']['contexts'][] = 'user';
|
Chris@0
|
155 }
|
Chris@0
|
156 }
|
Chris@0
|
157
|
Chris@0
|
158 /**
|
Chris@0
|
159 * Provide a block plugin specific block_build alteration.
|
Chris@0
|
160 *
|
Chris@0
|
161 * In this hook name, BASE_BLOCK_ID refers to the block implementation's plugin
|
Chris@0
|
162 * id, regardless of whether the plugin supports derivatives. For example, for
|
Chris@0
|
163 * the \Drupal\system\Plugin\Block\SystemPoweredByBlock block, this would be
|
Chris@0
|
164 * 'system_powered_by_block' as per that class's annotation. And for the
|
Chris@0
|
165 * \Drupal\system\Plugin\Block\SystemMenuBlock block, it would be
|
Chris@0
|
166 * 'system_menu_block' as per that class's annotation, regardless of which menu
|
Chris@0
|
167 * the derived block is for.
|
Chris@0
|
168 *
|
Chris@0
|
169 * @param array $build
|
Chris@0
|
170 * A renderable array of data, only containing #cache.
|
Chris@0
|
171 * @param \Drupal\Core\Block\BlockPluginInterface $block
|
Chris@0
|
172 * The block plugin instance.
|
Chris@0
|
173 *
|
Chris@0
|
174 * @see hook_block_build_alter()
|
Chris@0
|
175 * @see entity_crud
|
Chris@0
|
176 *
|
Chris@0
|
177 * @ingroup block_api
|
Chris@0
|
178 */
|
Chris@0
|
179 function hook_block_build_BASE_BLOCK_ID_alter(array &$build, \Drupal\Core\Block\BlockPluginInterface $block) {
|
Chris@0
|
180 // Explicitly enable placeholdering of the specific block.
|
Chris@0
|
181 $build['#create_placeholder'] = TRUE;
|
Chris@0
|
182 }
|
Chris@0
|
183
|
Chris@0
|
184 /**
|
Chris@0
|
185 * Control access to a block instance.
|
Chris@0
|
186 *
|
Chris@0
|
187 * Modules may implement this hook if they want to have a say in whether or not
|
Chris@0
|
188 * a given user has access to perform a given operation on a block instance.
|
Chris@0
|
189 *
|
Chris@0
|
190 * @param \Drupal\block\Entity\Block $block
|
Chris@0
|
191 * The block instance.
|
Chris@0
|
192 * @param string $operation
|
Chris@0
|
193 * The operation to be performed; for instance, 'view', 'create', 'delete', or
|
Chris@0
|
194 * 'update'.
|
Chris@0
|
195 * @param \Drupal\Core\Session\AccountInterface $account
|
Chris@0
|
196 * The user object to perform the access check operation on.
|
Chris@0
|
197 *
|
Chris@0
|
198 * @return \Drupal\Core\Access\AccessResultInterface
|
Chris@0
|
199 * The access result. If all implementations of this hook return
|
Chris@0
|
200 * AccessResultInterface objects whose value is !isAllowed() and
|
Chris@0
|
201 * !isForbidden(), then default access rules from
|
Chris@0
|
202 * \Drupal\block\BlockAccessControlHandler::checkAccess() are used.
|
Chris@0
|
203 *
|
Chris@0
|
204 * @see \Drupal\Core\Entity\EntityAccessControlHandler::access()
|
Chris@0
|
205 * @see \Drupal\block\BlockAccessControlHandler::checkAccess()
|
Chris@0
|
206 * @ingroup block_api
|
Chris@0
|
207 */
|
Chris@0
|
208 function hook_block_access(\Drupal\block\Entity\Block $block, $operation, \Drupal\Core\Session\AccountInterface $account) {
|
Chris@0
|
209 // Example code that would prevent displaying the 'Powered by Drupal' block in
|
Chris@0
|
210 // a region different than the footer.
|
Chris@0
|
211 if ($operation == 'view' && $block->getPluginId() == 'system_powered_by_block') {
|
Chris@0
|
212 return AccessResult::forbiddenIf($block->getRegion() != 'footer')->addCacheableDependency($block);
|
Chris@0
|
213 }
|
Chris@0
|
214
|
Chris@0
|
215 // No opinion.
|
Chris@0
|
216 return AccessResult::neutral();
|
Chris@0
|
217 }
|
Chris@0
|
218
|
Chris@0
|
219 /**
|
Chris@0
|
220 * @} End of "addtogroup hooks".
|
Chris@0
|
221 */
|