Commit | Line | Data |
---|---|---|
7f254ad8 AE |
1 | <?php |
2 | ||
3 | /** | |
4 | * @file | |
5 | * Describe hooks provided by the Views module. | |
6 | */ | |
7 | ||
8 | /** | |
9 | * @mainpage Views 3 API Manual | |
10 | * | |
11 | * Much of this information is actually stored in the advanced help; please | |
12 | * check the API topic. This help will primarily be aimed at documenting | |
13 | * classes and function calls. | |
14 | * | |
15 | * Topics: | |
16 | * - @link views_lifetime The life of a view @endlink | |
17 | * - @link views_hooks Views hooks @endlink | |
18 | * - @link views_handlers About Views handlers @endlink | |
19 | * - @link views_plugins About Views plugins @endlink | |
20 | * - @link views_templates Views template files @endlink | |
21 | * - @link views_module_handlers Views module handlers @endlink | |
22 | */ | |
23 | ||
24 | /** | |
25 | * @defgroup views_lifetime The life of a view | |
26 | * @{ | |
27 | * This page explains the basic cycle of a view and what processes happen. | |
28 | * | |
29 | * @todo. | |
30 | * @} | |
31 | */ | |
32 | ||
33 | /** | |
34 | * @defgroup views_handlers About Views handlers | |
35 | * @{ | |
36 | * In Views, a handler is an object that is part of the view and is part of the | |
37 | * query building flow. | |
38 | * | |
39 | * Handlers are objects; much of the time, the base handlers will work, but | |
40 | * often you'll need to override the handler to achieve something meaningful. | |
41 | * One typical handler override will be views_handler_filter_operator_in which | |
42 | * allows you to have a filter select from a list of options; you'll need to | |
43 | * override this to provide your list. | |
44 | * | |
45 | * Handlers have two distinct code flows; the UI flow and the view building | |
46 | * flow. | |
47 | * | |
48 | * For the query flow: | |
49 | * - handler->construct() | |
50 | * - Create the initial handler; at this time it is not yet attached to a | |
51 | * view. It is here that you can set basic defaults if needed, but there | |
52 | * will be no knowledge of the environment yet. | |
53 | * - handler->set_definition() | |
54 | * - Set the data from hook_views_data() relevant to the handler. | |
55 | * - handler->init() | |
56 | * - Attach the handler to a view, and usually provides the options from the | |
57 | * display. | |
58 | * - handler->pre_query() | |
59 | * - Run prior to the query() stage to do early processing. | |
60 | * - handler->query() | |
61 | * - Do the bulk of the work this handler needs to do to add itself to the | |
62 | * query. | |
63 | * | |
64 | * Fields, being the only handlers concerned with output, also have an extended | |
65 | * piece of the flow: | |
66 | * | |
67 | * - handler->pre_render(&$values) | |
68 | * - Called prior to the actual rendering, this allows handlers to query for | |
69 | * extra data; the entire resultset is available here, and this is where | |
70 | * items that have "multiple values" per record can do their extra query for | |
71 | * all of the records available. There are several examples of this at work | |
72 | * in the code, see for example views_handler_field_user_roles. | |
73 | * - handler->render() | |
74 | * - This does the actual work of rendering the field. | |
75 | * | |
76 | * Most handlers are just extensions of existing classes with a few tweaks that | |
77 | * are specific to the field in question. For example, | |
78 | * views_handler_filter_in_operator provides a simple mechanism to set a | |
79 | * multiple-value list for setting filter values. Below, | |
80 | * views_handler_filter_node_type overrides the list options, but inherits | |
81 | * everything else. | |
82 | * | |
83 | * @code | |
84 | * class views_handler_filter_node_type extends views_handler_filter_in_operator { | |
85 | * function get_value_options() { | |
86 | * if (!isset($this->value_options)) { | |
87 | * $this->value_title = t('Node type'); | |
88 | * $types = node_get_types(); | |
89 | * foreach ($types as $type => $info) { | |
90 | * $options[$type] = $info->name; | |
91 | * } | |
92 | * $this->value_options = $options; | |
93 | * } | |
94 | * } | |
95 | * } | |
96 | * @endcode | |
97 | * | |
98 | * Handlers are stored in their own files and loaded on demand. Like all other | |
99 | * module files, they must first be registered through the module's info file. | |
100 | * For example: | |
101 | * | |
102 | * @code | |
103 | * name = Example module | |
104 | * description = "Gives an example of a module." | |
105 | * core = 7.x | |
106 | * files[] = example.module | |
107 | * files[] = example.install | |
108 | * | |
109 | * ; Views handlers | |
110 | * files[] = includes/views/handlers/example_handler_argument_string.inc | |
111 | * @endcode | |
112 | * | |
113 | * The best place to learn more about handlers and how they work is to explore | |
114 | * @link views_handlers Views' handlers @endlink and use existing handlers as a | |
115 | * guide and a model. Understanding how views_handler and its child classes work | |
116 | * is handy but you can do a lot just following these models. You can also | |
117 | * explore the views module directory, particularly node.views.inc. | |
118 | * | |
119 | * Please note that while all handler names in views are prefixed with views_, | |
120 | * you should use your own module's name to prefix your handler names in order | |
121 | * to ensure namespace safety. Note that the basic pattern for handler naming | |
122 | * goes like this: | |
123 | * | |
124 | * [module]_handler_[type]_[tablename]_[fieldname]. | |
125 | * | |
126 | * Sometimes table and fieldname are not appropriate, but something that | |
127 | * resembles what the table/field would be can be used. | |
128 | * | |
129 | * See also: | |
130 | * - @link views_field_handlers Views field handlers @endlink | |
131 | * - @link views_sort_handlers Views sort handlers @endlink | |
132 | * - @link views_filter_handlers Views filter handlers @endlink | |
133 | * - @link views_argument_handlers Views argument handlers @endlink | |
134 | * - @link views_relationship_handlers Views relationship handlers @endlink | |
135 | * - @link views_area_handlers Views area handlers @endlink | |
136 | * @} | |
137 | */ | |
138 | ||
139 | /** | |
140 | * @defgroup views_plugins About Views plugins | |
141 | * | |
142 | * In Views, a plugin is a bit like a handler, but plugins are not directly | |
143 | * responsible for building the query. Instead, they are objects that are used | |
144 | * to display the view or make other modifications. | |
145 | * | |
146 | * There are several types of plugins in Views: | |
147 | * - Display: Display plugins are responsible for controlling *where* a view | |
148 | * lives; that is, how they are being exposed to other parts of Drupal. Page | |
149 | * and block are the most common displays, as well as the ubiquitous 'master' | |
150 | * (or 'default') display. | |
151 | * - Style: Style plugins control how a view is displayed. For the most part | |
152 | * they are object wrappers around theme templates. Styles could for example | |
153 | * be HTML lists or tables. | |
154 | * - Row style: Row styles handle each individual record from the main view | |
155 | * table. The two included by default render the entire entity (nodes only), | |
156 | * or selected fields. | |
157 | * - Argument default: Argument default plugins allow pluggable ways of | |
158 | * providing default values for contextual filters (previously 'arguments'). | |
159 | * This is useful for blocks and other display types lacking a natural | |
160 | * argument input. Examples are plugins to extract node and user IDs from the | |
161 | * URL. | |
162 | * - Argument validator: Validator plugins can ensure arguments are valid, and | |
163 | * even do transformations on the arguments. They can also provide replacement | |
164 | * patterns for the view title. For example, the 'content' validator | |
165 | * verifies verifies that the argument value corresponds to a node, loads | |
166 | * that node and provides the node title as a replacement pattern. | |
167 | * - Access: Access plugins are responsible for controlling access to the view. | |
168 | * Views includes plugins for checking user roles and individual permissions. | |
169 | * - Query: Query plugins generate and execute a query, so they can be seen as | |
170 | * a data backend. The default implementation is using SQL. There are | |
171 | * contributed modules reading data from other sources, see for example the | |
172 | * Views XML Backend module. | |
173 | * - Cache: Cache plugins control the storage and loading of caches. Currently | |
174 | * they can do both result and render caching, but maybe one day cache the | |
175 | * generated query. | |
176 | * - Pager plugins: Pager plugins take care of everything regarding pagers. | |
177 | * From getting and setting the total amount of items to render the pager and | |
178 | * setting the global pager arrays. | |
179 | * - Exposed form plugins: Exposed form plugins are responsible for building, | |
180 | * rendering and controlling exposed forms. They can expose new parts of the | |
181 | * view to the user and more. | |
182 | * - Localization plugins: Localization plugins take care how the view options | |
183 | * are translated. There are example implementations for t(), 'no | |
184 | * translation' and i18n. | |
185 | * - Display extenders: Display extender plugins allow scaling of views options | |
186 | * horizontally. This means that you can add options and do stuff on all | |
187 | * views displays. One theoretical example is metatags for views. | |
188 | * | |
189 | * Plugins are registered by implementing hook_views_plugins() in your | |
190 | * modulename.views.inc file and returning an array of data. | |
191 | * For examples please look at views_views_plugins() in | |
192 | * views/includes/plugins.inc as it has examples for all of them. | |
193 | * | |
194 | * Similar to handlers, make sure that you add your plugin files to the | |
195 | * module.info file. | |
196 | * | |
197 | * The array defining plugins will look something like this: | |
198 | * @code | |
199 | * return array( | |
200 | * 'display' => array( | |
201 | * // ... list of display plugins, | |
202 | * ), | |
203 | * 'style' => array( | |
204 | * // ... list of style plugins, | |
205 | * ), | |
206 | * 'row' => array( | |
207 | * // ... list of row style plugins, | |
208 | * ), | |
209 | * 'argument default' => array( | |
210 | * // ... list of argument default plugins, | |
211 | * ), | |
212 | * 'argument validator' => array( | |
213 | * // ... list of argument validator plugins, | |
214 | * ), | |
215 | * 'access' => array( | |
216 | * // ... list of access plugins, | |
217 | * ), | |
218 | * 'query' => array( | |
219 | * // ... list of query plugins, | |
220 | * ),, | |
221 | * 'cache' => array( | |
222 | * // ... list of cache plugins, | |
223 | * ),, | |
224 | * 'pager' => array( | |
225 | * // ... list of pager plugins, | |
226 | * ),, | |
227 | * 'exposed_form' => array( | |
228 | * // ... list of exposed_form plugins, | |
229 | * ),, | |
230 | * 'localization' => array( | |
231 | * // ... list of localization plugins, | |
232 | * ), | |
233 | * 'display_extender' => array( | |
234 | * // ... list of display extender plugins, | |
235 | * ), | |
236 | * ); | |
237 | * @endcode | |
238 | * | |
239 | * Each plugin will be registered with an identifier for the plugin, plus a | |
240 | * fairly lengthy list of items that can define how and where the plugin is | |
241 | * used. Here is an example of a row style plugin from Views core: | |
242 | * @code | |
243 | * 'node' => array( | |
244 | * 'title' => t('Node'), | |
245 | * 'help' => t('Display the node with standard node view.'), | |
246 | * 'handler' => 'views_plugin_row_node_view', | |
247 | * 'path' => drupal_get_path('module', 'views') . '/modules/node', // not necessary for most modules | |
248 | * 'theme' => 'views_view_row_node', | |
249 | * 'base' => array('node'), // only works with 'node' as base. | |
250 | * 'uses options' => TRUE, | |
251 | * 'type' => 'normal', | |
252 | * ), | |
253 | * @endcode | |
254 | * | |
255 | * Of particular interest is the *path* directive, which works a little | |
256 | * differently from handler registration; each plugin must define its own path, | |
257 | * rather than relying on a global info for the paths. For example: | |
258 | * @code | |
259 | * 'feed' => array( | |
260 | * 'title' => t('Feed'), | |
261 | * 'help' => t('Display the view as a feed, such as an RSS feed.'), | |
262 | * 'handler' => 'views_plugin_display_feed', | |
263 | * 'uses hook menu' => TRUE, | |
264 | * 'use ajax' => FALSE, | |
265 | * 'use pager' => FALSE, | |
266 | * 'accept attachments' => FALSE, | |
267 | * 'admin' => t('Feed'), | |
268 | * 'help topic' => 'display-feed', | |
269 | * ), | |
270 | * @endcode | |
271 | * | |
272 | * Please be sure to prefix your plugin identifiers with your module name to | |
273 | * ensure namespace safety; after all, two different modules could try to | |
274 | * implement the 'grid2' plugin, and that would cause one plugin to completely | |
275 | * fail. | |
276 | * | |
277 | * @todo Finish this document. | |
278 | * | |
279 | * See also: | |
280 | * - @link views_display_plugins Views display plugins @endlink | |
281 | * - @link views_style_plugins Views style plugins @endlink | |
282 | * - @link views_row_plugins Views row plugins @endlink | |
283 | */ | |
284 | ||
285 | /** | |
286 | * @defgroup views_hooks Views hooks | |
287 | * @{ | |
288 | * Hooks that can be implemented by other modules in order to implement the | |
289 | * Views API. | |
290 | */ | |
291 | ||
292 | /** | |
293 | * Describes data tables (or the equivalent) to Views. | |
294 | * | |
295 | * This hook should be placed in MODULENAME.views.inc and it will be | |
296 | * auto-loaded. MODULENAME.views.inc must be in the directory specified by the | |
297 | * 'path' key returned by MODULENAME_views_api(), or the same directory as the | |
298 | * .module file, if 'path' is unspecified. | |
299 | * | |
300 | * @return | |
301 | * An associative array describing the data structure. Primary key is the | |
302 | * name used internally by Views for the table(s) – usually the actual table | |
303 | * name. The values for the key entries are described in detail below. | |
304 | */ | |
305 | function hook_views_data() { | |
306 | // This example describes how to write hook_views_data() for the following | |
307 | // table: | |
308 | // | |
309 | // CREATE TABLE example_table ( | |
310 | // nid INT(11) NOT NULL COMMENT 'Primary key; refers to {node}.nid.', | |
311 | // plain_text_field VARCHAR(32) COMMENT 'Just a plain text field.', | |
312 | // numeric_field INT(11) COMMENT 'Just a numeric field.', | |
313 | // boolean_field INT(1) COMMENT 'Just an on/off field.', | |
314 | // timestamp_field INT(8) COMMENT 'Just a timestamp field.', | |
315 | // PRIMARY KEY(nid) | |
316 | // ); | |
317 | ||
318 | // First, the entry $data['example_table']['table'] describes properties of | |
319 | // the actual table – not its content. | |
320 | ||
321 | // The 'group' index will be used as a prefix in the UI for any of this | |
322 | // table's fields, sort criteria, etc. so it's easy to tell where they came | |
323 | // from. | |
324 | $data['example_table']['table']['group'] = t('Example table'); | |
325 | ||
326 | // Define this as a base table – a table that can be described in itself by | |
327 | // views (and not just being brought in as a relationship). In reality this | |
328 | // is not very useful for this table, as it isn't really a distinct object of | |
329 | // its own, but it makes a good example. | |
330 | $data['example_table']['table']['base'] = array( | |
331 | 'field' => 'nid', // This is the identifier field for the view. | |
332 | 'title' => t('Example table'), | |
333 | 'help' => t('Example table contains example content and can be related to nodes.'), | |
334 | 'weight' => -10, | |
335 | ); | |
336 | ||
337 | // This table references the {node} table. The declaration below creates an | |
338 | // 'implicit' relationship to the node table, so that when 'node' is the base | |
339 | // table, the fields are automatically available. | |
340 | $data['example_table']['table']['join'] = array( | |
341 | // Index this array by the table name to which this table refers. | |
342 | // 'left_field' is the primary key in the referenced table. | |
343 | // 'field' is the foreign key in this table. | |
344 | 'node' => array( | |
345 | 'left_field' => 'nid', | |
346 | 'field' => 'nid', | |
347 | ), | |
348 | ); | |
349 | ||
350 | // Next, describe each of the individual fields in this table to Views. This | |
351 | // is done by describing $data['example_table']['FIELD_NAME']. This part of | |
352 | // the array may then have further entries: | |
353 | // - title: The label for the table field, as presented in Views. | |
354 | // - help: The description text for the table field. | |
355 | // - relationship: A description of any relationship handler for the table | |
356 | // field. | |
357 | // - field: A description of any field handler for the table field. | |
358 | // - sort: A description of any sort handler for the table field. | |
359 | // - filter: A description of any filter handler for the table field. | |
360 | // - argument: A description of any argument handler for the table field. | |
361 | // - area: A description of any handler for adding content to header, | |
362 | // footer or as no result behaviour. | |
363 | // | |
364 | // The handler descriptions are described with examples below. | |
365 | ||
366 | // Node ID table field. | |
367 | $data['example_table']['nid'] = array( | |
368 | 'title' => t('Example content'), | |
369 | 'help' => t('Some example content that references a node.'), | |
370 | // Define a relationship to the {node} table, so example_table views can | |
371 | // add a relationship to nodes. If you want to define a relationship the | |
372 | // other direction, use hook_views_data_alter(), or use the 'implicit' join | |
373 | // method described above. | |
374 | 'relationship' => array( | |
375 | 'base' => 'node', // The name of the table to join with. | |
376 | 'base field' => 'nid', // The name of the field on the joined table. | |
377 | // 'field' => 'nid' -- see hook_views_data_alter(); not needed here. | |
378 | 'handler' => 'views_handler_relationship', | |
379 | 'label' => t('Default label for the relationship'), | |
380 | 'title' => t('Title shown when adding the relationship'), | |
381 | 'help' => t('More information on this relationship'), | |
382 | ), | |
383 | ); | |
384 | ||
385 | // Example plain text field. | |
386 | $data['example_table']['plain_text_field'] = array( | |
387 | 'title' => t('Plain text field'), | |
388 | 'help' => t('Just a plain text field.'), | |
389 | 'field' => array( | |
390 | 'handler' => 'views_handler_field', | |
391 | 'click sortable' => TRUE, // This is use by the table display plugin. | |
392 | ), | |
393 | 'sort' => array( | |
394 | 'handler' => 'views_handler_sort', | |
395 | ), | |
396 | 'filter' => array( | |
397 | 'handler' => 'views_handler_filter_string', | |
398 | ), | |
399 | 'argument' => array( | |
400 | 'handler' => 'views_handler_argument_string', | |
401 | ), | |
402 | ); | |
403 | ||
404 | // Example numeric text field. | |
405 | $data['example_table']['numeric_field'] = array( | |
406 | 'title' => t('Numeric field'), | |
407 | 'help' => t('Just a numeric field.'), | |
408 | 'field' => array( | |
409 | 'handler' => 'views_handler_field_numeric', | |
410 | 'click sortable' => TRUE, | |
411 | ), | |
412 | 'filter' => array( | |
413 | 'handler' => 'views_handler_filter_numeric', | |
414 | ), | |
415 | 'sort' => array( | |
416 | 'handler' => 'views_handler_sort', | |
417 | ), | |
418 | ); | |
419 | ||
420 | // Example boolean field. | |
421 | $data['example_table']['boolean_field'] = array( | |
422 | 'title' => t('Boolean field'), | |
423 | 'help' => t('Just an on/off field.'), | |
424 | 'field' => array( | |
425 | 'handler' => 'views_handler_field_boolean', | |
426 | 'click sortable' => TRUE, | |
427 | ), | |
428 | 'filter' => array( | |
429 | 'handler' => 'views_handler_filter_boolean_operator', | |
430 | // Note that you can override the field-wide label: | |
431 | 'label' => t('Published'), | |
432 | // This setting is used by the boolean filter handler, as possible option. | |
433 | 'type' => 'yes-no', | |
434 | // use boolean_field = 1 instead of boolean_field <> 0 in WHERE statement. | |
435 | 'use equal' => TRUE, | |
436 | ), | |
437 | 'sort' => array( | |
438 | 'handler' => 'views_handler_sort', | |
439 | ), | |
440 | ); | |
441 | ||
442 | // Example timestamp field. | |
443 | $data['example_table']['timestamp_field'] = array( | |
444 | 'title' => t('Timestamp field'), | |
445 | 'help' => t('Just a timestamp field.'), | |
446 | 'field' => array( | |
447 | 'handler' => 'views_handler_field_date', | |
448 | 'click sortable' => TRUE, | |
449 | ), | |
450 | 'sort' => array( | |
451 | 'handler' => 'views_handler_sort_date', | |
452 | ), | |
453 | 'filter' => array( | |
454 | 'handler' => 'views_handler_filter_date', | |
455 | ), | |
456 | ); | |
457 | ||
458 | return $data; | |
459 | } | |
460 | ||
461 | /** | |
462 | * Alter table structure. | |
463 | * | |
464 | * You can add/edit/remove existing tables defined by hook_views_data(). | |
465 | * | |
466 | * This hook should be placed in MODULENAME.views.inc and it will be | |
467 | * auto-loaded. MODULENAME.views.inc must be in the directory specified by the | |
468 | * 'path' key returned by MODULENAME_views_api(), or the same directory as the | |
469 | * .module file, if 'path' is unspecified. | |
470 | * | |
471 | * @param $data | |
472 | * An array of all Views data, passed by reference. See hook_views_data() for | |
473 | * structure. | |
474 | * | |
475 | * @see hook_views_data() | |
476 | */ | |
477 | function hook_views_data_alter(&$data) { | |
478 | // This example alters the title of the node:nid field in the Views UI. | |
479 | $data['node']['nid']['title'] = t('Node-Nid'); | |
480 | ||
481 | // This example adds an example field to the users table. | |
482 | $data['users']['example_field'] = array( | |
483 | 'title' => t('Example field'), | |
484 | 'help' => t('Some example content that references a user'), | |
485 | 'field' => array( | |
486 | 'handler' => 'modulename_handler_field_example_field', | |
487 | ), | |
488 | ); | |
489 | ||
490 | // This example changes the handler of the node title field. | |
491 | // In this handler you could do stuff, like preview of the node when clicking | |
492 | // the node title. | |
493 | $data['node']['title']['field']['handler'] = 'modulename_handler_field_node_title'; | |
494 | ||
495 | // This example adds a relationship to table {foo}, so that 'foo' views can | |
496 | // add this table using a relationship. Because we don't want to write over | |
497 | // the primary key field definition for the {foo}.fid field, we use a dummy | |
498 | // field name as the key. | |
499 | $data['foo']['dummy_name'] = array( | |
500 | 'title' => t('Example relationship'), | |
501 | 'help' => t('Example help'), | |
502 | 'relationship' => array( | |
503 | 'base' => 'example_table', // Table we're joining to. | |
504 | 'base field' => 'eid', // Field on the joined table. | |
505 | 'field' => 'fid', // Real field name on the 'foo' table. | |
506 | 'handler' => 'views_handler_relationship', | |
507 | 'label' => t('Default label for relationship'), | |
508 | 'title' => t('Title seen when adding relationship'), | |
509 | 'help' => t('More information about relationship.'), | |
510 | ), | |
511 | ); | |
512 | ||
513 | // Note that the $data array is not returned – it is modified by reference. | |
514 | } | |
515 | ||
516 | /** | |
517 | * Override the default data for a Field API field. | |
518 | * | |
519 | * Field module's implementation of hook_views_data() invokes this for each | |
520 | * field in the module that defines the field type (as declared in the field | |
521 | * array). It is not invoked in other modules. | |
522 | * | |
523 | * If no hook implementation exists, hook_views_data() falls back to | |
524 | * field_views_field_default_views_data(). | |
525 | * | |
526 | * @see field_views_data() | |
527 | * @see hook_field_views_data_alter() | |
528 | * @see hook_field_views_data_views_data_alter() | |
529 | * | |
530 | * @param $field | |
531 | * A field definition array, as returned by field_info_fields(). | |
532 | * | |
533 | * @return | |
534 | * An array of views data, in the same format as the return value of | |
535 | * hook_views_data(). | |
536 | */ | |
537 | function hook_field_views_data($field) { | |
538 | ||
539 | } | |
540 | ||
541 | /** | |
542 | * Alter the views data for a single Field API field. | |
543 | * | |
544 | * This is called even if there is no hook_field_views_data() implementation for | |
545 | * the field, and therefore may be used to alter the default data that | |
546 | * field_views_field_default_views_data() supplies for the field. | |
547 | * | |
548 | * @param $result | |
549 | * An array of views table data provided for a single field. This has the same | |
550 | * format as the return value of hook_views_data(). | |
551 | * @param $field | |
552 | * A field definition array, as returned by field_info_fields(). | |
553 | * @param $module | |
554 | * The module that defines the field type. | |
555 | * | |
556 | * @see field_views_data() | |
557 | * @see hook_field_views_data() | |
558 | * @see hook_field_views_data_views_data_alter() | |
559 | */ | |
560 | function hook_field_views_data_alter(&$result, $field, $module) { | |
561 | ||
562 | } | |
563 | ||
564 | /** | |
565 | * Alter the views data on a per field basis. | |
566 | * | |
567 | * Field module's implementation of hook_views_data_alter() invokes this for | |
568 | * each field in the module that defines the field type (as declared in the | |
569 | * field array). It is not invoked in other modules. | |
570 | * | |
571 | * Unlike hook_field_views_data_alter(), this operates on the whole of the views | |
572 | * data. This allows a field module to add data that concerns its fields to | |
573 | * other tables, which would not yet be defined at the point when | |
574 | * hook_field_views_data() and hook_field_views_data_alter() are invoked. For | |
575 | * example, entityreference adds reverse relationships on the tables for the | |
576 | * entities which are referenced by entityreference fields. | |
577 | * | |
578 | * (Note: this is weirdly named so as not to conflict with | |
579 | * hook_field_views_data_alter().) | |
580 | * | |
581 | * @see hook_field_views_data() | |
582 | * @see hook_field_views_data_alter() | |
583 | * @see field_views_data_alter() | |
584 | */ | |
585 | function hook_field_views_data_views_data_alter(&$data, $field) { | |
586 | $field_name = $field['field_name']; | |
587 | $data_key = 'field_data_' . $field_name; | |
588 | // Views data for this field is in $data[$data_key] | |
589 | } | |
590 | ||
591 | /** | |
592 | * Describes plugins defined by the module. | |
593 | * | |
594 | * This hook should be placed in MODULENAME.views.inc and it will be | |
595 | * auto-loaded. MODULENAME.views.inc must be in the directory specified by the | |
596 | * 'path' key returned by MODULENAME_views_api(), or the same directory as the | |
597 | * .module file, if 'path' is unspecified. All plugin files need to be | |
598 | * referenced in MODULENAME.info with the files[] directive. | |
599 | * | |
600 | * @return | |
601 | * An array on the form $plugins['PLUGIN TYPE']['PLUGIN NAME']. The plugin | |
602 | * must be one of row, display, display_extender, style, argument default, | |
603 | * argument validator, access, query, cache, pager, exposed_form or | |
604 | * localization. The plugin name should be prefixed with your module name. | |
605 | * The value for each entry is an associative array that may contain the | |
606 | * following entries: | |
607 | * - Used by all plugin types: | |
608 | * - title (required): The name of the plugin, as shown in Views. Wrap in | |
609 | * t(). | |
610 | * - handler (required): The name of the file containing the class | |
611 | * describing the handler, which must also be the name of the handler's | |
612 | * class. | |
613 | * - path: Path to the handler. Only required if the handler is not placed | |
614 | * in the same folder as the .module file or in the subfolder 'views'. | |
615 | * - parent: The name of the plugin this plugin extends. Since Drupal 7 this | |
616 | * is no longer required, but may still be useful from a code readability | |
617 | * perspective. | |
618 | * - no ui: Set to TRUE to denote that the plugin doesn't appear to be | |
619 | * selectable in the ui, though on the api side they still exists. | |
620 | * - uses options: Set to TRUE to denote that the plugin has an additional | |
621 | * options form. | |
622 | * - help: A short help text, wrapped in t() used as description on the plugin settings form. | |
623 | * - help topic: The name of an entry by advanced help for the plugin. | |
624 | * - theme: The name of a theme suggestion to use for the display. | |
625 | * - js: An array with paths to js files that should be included for the | |
626 | * display. Note that the path should be relative Drupal root, not module | |
627 | * root. | |
628 | * - type: Each plugin can specify a type parameter to group certain | |
629 | * plugins together. For example all row plugins related to feeds are | |
630 | * grouped together, because a rss style plugin only accepts feed row | |
631 | * plugins. | |
632 | * | |
633 | * - Used by display plugins: | |
634 | * - admin: The administrative name of the display, as displayed on the | |
635 | * Views overview and also used as default name for new displays. Wrap in | |
636 | * t(). | |
637 | * - no remove: Set to TRUE to make the display non-removable. (Basically | |
638 | * only used for the master/default display.) | |
639 | * - use ajax: Set to TRUE to allow AJAX loads in the display. If it's | |
640 | * disabled there will be no ajax option in the ui. | |
641 | * - use pager: Set to TRUE to allow paging in the display. | |
642 | * - use more: Set to TRUE to allow the 'use more' setting in the display. | |
643 | * - accept attachments: Set to TRUE to allow attachment displays to be | |
644 | * attached to this display type. | |
645 | * - contextual links locations: An array with places where contextual links | |
646 | * should be added. Can for example be 'page' or 'block'. If you don't | |
647 | * specify it there will be contextual links around the rendered view. If | |
648 | * this is not set or regions have been specified, views will display an | |
649 | * option to 'hide contextual links'. Use an empty array if you do not want | |
650 | * this. | |
651 | * - uses hook menu: Set to TRUE to have the display included by | |
652 | * views_menu_alter(). views_menu_alter executes then execute_hook_menu | |
653 | * on the display object. | |
654 | * - uses hook block: Set to TRUE to have the display included by | |
655 | * views_block_info(). | |
656 | * - theme: The name of a theme suggestion to use for the display. | |
657 | * - js: An array with paths to js files that should be included for the | |
658 | * display. Note that the path should be relative Drupal root, not module | |
659 | * root. | |
660 | * | |
661 | * - Used by style plugins: | |
662 | * - uses row plugin: Set to TRUE to allow row plugins for this style. | |
663 | * - uses row class: Set to TRUE to allow the CSS class settings for rows. | |
664 | * - uses fields: Set to TRUE to have the style plugin accept field | |
665 | * handlers. | |
666 | * - uses grouping: Set to TRUE to allow the grouping settings for rows. | |
667 | * - even empty: May have the value 'even empty' to tell Views that the style | |
668 | * should be rendered even if there are no results. | |
669 | * | |
670 | * - Used by row plugins: | |
671 | * - uses fields: Set to TRUE to have the row plugin accept field handlers. | |
672 | */ | |
673 | function hook_views_plugins() { | |
674 | $plugins = array(); | |
675 | $plugins['argument validator'] = array( | |
676 | 'taxonomy_term' => array( | |
677 | 'title' => t('Taxonomy term'), | |
678 | 'handler' => 'views_plugin_argument_validate_taxonomy_term', | |
679 | // Declaring path explicitly not necessary for most modules. | |
680 | 'path' => drupal_get_path('module', 'views') . '/modules/taxonomy', | |
681 | ), | |
682 | ); | |
683 | ||
684 | return array( | |
685 | 'module' => 'views', // This just tells our themes are elsewhere. | |
686 | 'argument validator' => array( | |
687 | 'taxonomy_term' => array( | |
688 | 'title' => t('Taxonomy term'), | |
689 | 'handler' => 'views_plugin_argument_validate_taxonomy_term', | |
690 | 'path' => drupal_get_path('module', 'views') . '/modules/taxonomy', // not necessary for most modules | |
691 | ), | |
692 | ), | |
693 | 'argument default' => array( | |
694 | 'taxonomy_tid' => array( | |
695 | 'title' => t('Taxonomy term ID from URL'), | |
696 | 'handler' => 'views_plugin_argument_default_taxonomy_tid', | |
697 | 'path' => drupal_get_path('module', 'views') . '/modules/taxonomy', | |
698 | 'parent' => 'fixed', | |
699 | ), | |
700 | ), | |
701 | ); | |
702 | } | |
703 | ||
704 | /** | |
705 | * Alter existing plugins data, defined by modules. | |
706 | * | |
707 | * @see hook_views_plugins() | |
708 | */ | |
709 | function hook_views_plugins_alter(&$plugins) { | |
710 | // Add apachesolr to the base of the node row plugin. | |
711 | $plugins['row']['node']['base'][] = 'apachesolr'; | |
712 | } | |
713 | ||
714 | /** | |
715 | * Register View API information. | |
716 | * | |
717 | * This is required for your module to have its include files loaded; for | |
718 | * example, when implementing hook_views_default_views(). | |
719 | * | |
720 | * @return | |
721 | * An array with the following possible keys: | |
722 | * - api: (required) The version of the Views API the module implements. | |
723 | * - path: (optional) If includes are stored somewhere other than within the | |
724 | * root module directory, specify its path here. | |
725 | * - template path: (optional) A path where the module has stored it's views | |
726 | * template files. When you have specified this key views automatically | |
727 | * uses the template files for the views. You can use the same naming | |
728 | * conventions like for normal views template files. | |
729 | */ | |
730 | function hook_views_api() { | |
731 | return array( | |
732 | 'api' => 3, | |
733 | 'path' => drupal_get_path('module', 'example') . '/includes/views', | |
734 | 'template path' => drupal_get_path('module', 'example') . '/themes', | |
735 | ); | |
736 | } | |
737 | ||
738 | /** | |
739 | * This hook allows modules to provide their own views which can either be used | |
740 | * as-is or as a "starter" for users to build from. | |
741 | * | |
742 | * This hook should be placed in MODULENAME.views_default.inc and it will be | |
743 | * auto-loaded. MODULENAME.views_default.inc must be in the directory specified | |
744 | * by the 'path' key returned by MODULENAME_views_api(), or the same directory | |
745 | * as the .module file, if 'path' is unspecified. | |
746 | * | |
747 | * The $view->disabled boolean flag indicates whether the View should be | |
748 | * enabled (FALSE) or disabled (TRUE) by default. | |
749 | * | |
750 | * @return | |
751 | * An associative array containing the structures of views, as generated from | |
752 | * the Export tab, keyed by the view name. A best practice is to go through | |
753 | * and add t() to all title and label strings, with the exception of menu | |
754 | * strings. | |
755 | */ | |
756 | function hook_views_default_views() { | |
757 | // Begin copy and paste of output from the Export tab of a view. | |
758 | $view = new view; | |
759 | $view->name = 'frontpage'; | |
760 | $view->description = 'Emulates the default Drupal front page; you may set the default home page path to this view to make it your front page.'; | |
761 | $view->tag = 'default'; | |
762 | $view->base_table = 'node'; | |
763 | $view->human_name = 'Front page'; | |
764 | $view->core = 0; | |
765 | $view->api_version = '3.0'; | |
766 | $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ | |
767 | ||
768 | /* Display: Master */ | |
769 | $handler = $view->new_display('default', 'Master', 'default'); | |
770 | $handler->display->display_options['access']['type'] = 'none'; | |
771 | $handler->display->display_options['cache']['type'] = 'none'; | |
772 | $handler->display->display_options['query']['type'] = 'views_query'; | |
773 | $handler->display->display_options['query']['options']['query_comment'] = FALSE; | |
774 | $handler->display->display_options['exposed_form']['type'] = 'basic'; | |
775 | $handler->display->display_options['pager']['type'] = 'full'; | |
776 | $handler->display->display_options['style_plugin'] = 'default'; | |
777 | $handler->display->display_options['row_plugin'] = 'node'; | |
778 | /* Sort criterion: Content: Sticky */ | |
779 | $handler->display->display_options['sorts']['sticky']['id'] = 'sticky'; | |
780 | $handler->display->display_options['sorts']['sticky']['table'] = 'node'; | |
781 | $handler->display->display_options['sorts']['sticky']['field'] = 'sticky'; | |
782 | $handler->display->display_options['sorts']['sticky']['order'] = 'DESC'; | |
783 | /* Sort criterion: Content: Post date */ | |
784 | $handler->display->display_options['sorts']['created']['id'] = 'created'; | |
785 | $handler->display->display_options['sorts']['created']['table'] = 'node'; | |
786 | $handler->display->display_options['sorts']['created']['field'] = 'created'; | |
787 | $handler->display->display_options['sorts']['created']['order'] = 'DESC'; | |
788 | /* Filter criterion: Content: Promoted to front page */ | |
789 | $handler->display->display_options['filters']['promote']['id'] = 'promote'; | |
790 | $handler->display->display_options['filters']['promote']['table'] = 'node'; | |
791 | $handler->display->display_options['filters']['promote']['field'] = 'promote'; | |
792 | $handler->display->display_options['filters']['promote']['value'] = '1'; | |
793 | $handler->display->display_options['filters']['promote']['group'] = 0; | |
794 | $handler->display->display_options['filters']['promote']['expose']['operator'] = FALSE; | |
795 | /* Filter criterion: Content: Published */ | |
796 | $handler->display->display_options['filters']['status']['id'] = 'status'; | |
797 | $handler->display->display_options['filters']['status']['table'] = 'node'; | |
798 | $handler->display->display_options['filters']['status']['field'] = 'status'; | |
799 | $handler->display->display_options['filters']['status']['value'] = '1'; | |
800 | $handler->display->display_options['filters']['status']['group'] = 0; | |
801 | $handler->display->display_options['filters']['status']['expose']['operator'] = FALSE; | |
802 | ||
803 | /* Display: Page */ | |
804 | $handler = $view->new_display('page', 'Page', 'page'); | |
805 | $handler->display->display_options['path'] = 'frontpage'; | |
806 | ||
807 | /* Display: Feed */ | |
808 | $handler = $view->new_display('feed', 'Feed', 'feed'); | |
809 | $handler->display->display_options['defaults']['title'] = FALSE; | |
810 | $handler->display->display_options['title'] = 'Front page feed'; | |
811 | $handler->display->display_options['pager']['type'] = 'some'; | |
812 | $handler->display->display_options['style_plugin'] = 'rss'; | |
813 | $handler->display->display_options['row_plugin'] = 'node_rss'; | |
814 | $handler->display->display_options['path'] = 'rss.xml'; | |
815 | $handler->display->display_options['displays'] = array( | |
816 | 'default' => 'default', | |
817 | 'page' => 'page', | |
818 | ); | |
819 | $handler->display->display_options['sitename_title'] = '1'; | |
820 | ||
821 | // (Export ends here.) | |
822 | ||
823 | // Add view to list of views to provide. | |
824 | $views[$view->name] = $view; | |
825 | ||
826 | // ...Repeat all of the above for each view the module should provide. | |
827 | ||
828 | // At the end, return array of default views. | |
829 | return $views; | |
830 | } | |
831 | ||
832 | /** | |
833 | * Alter default views defined by other modules. | |
834 | * | |
835 | * This hook is called right before all default views are cached to the | |
836 | * database. It takes a keyed array of views by reference. | |
837 | * | |
838 | * Example usage to add a field to a view: | |
839 | * @code | |
840 | * $handler =& $view->display['DISPLAY_ID']->handler; | |
841 | * // Add the user name field to the view. | |
842 | * $handler->display->display_options['fields']['name']['id'] = 'name'; | |
843 | * $handler->display->display_options['fields']['name']['table'] = 'users'; | |
844 | * $handler->display->display_options['fields']['name']['field'] = 'name'; | |
845 | * $handler->display->display_options['fields']['name']['label'] = 'Author'; | |
846 | * $handler->display->display_options['fields']['name']['link_to_user'] = 1; | |
847 | * @endcode | |
848 | */ | |
849 | function hook_views_default_views_alter(&$views) { | |
850 | if (isset($views['taxonomy_term'])) { | |
851 | $views['taxonomy_term']->display['default']->display_options['title'] = 'Categories'; | |
852 | } | |
853 | } | |
854 | ||
855 | /** | |
856 | * Performs replacements in the query before being performed. | |
857 | * | |
858 | * @param $view | |
859 | * The View being executed. | |
860 | * @return | |
861 | * An array with keys being the strings to replace, and the values the strings | |
862 | * to replace them with. The strings to replace are often surrounded with | |
863 | * '***', as illustrated in the example implementation. | |
864 | */ | |
865 | function hook_views_query_substitutions($view) { | |
866 | // Example from views_views_query_substitutions(). | |
867 | global $language_content; | |
868 | return array( | |
869 | '***CURRENT_VERSION***' => VERSION, | |
870 | '***CURRENT_TIME***' => REQUEST_TIME, | |
871 | '***CURRENT_LANGUAGE***' => $language_content->language, | |
872 | '***DEFAULT_LANGUAGE***' => language_default('language'), | |
873 | ); | |
874 | } | |
875 | ||
876 | /** | |
877 | * This hook is called to get a list of placeholders and their substitutions, | |
878 | * used when preprocessing a View with form elements. | |
879 | * | |
880 | * @return | |
881 | * An array with keys being the strings to replace, and the values the strings | |
882 | * to replace them with. | |
883 | */ | |
884 | function hook_views_form_substitutions() { | |
885 | return array( | |
886 | '<!--views-form-example-substitutions-->' => 'Example Substitution', | |
887 | ); | |
888 | } | |
889 | ||
890 | /** | |
891 | * Allows altering a view at the very beginning of views processing, before | |
892 | * anything is done. | |
893 | * | |
894 | * Adding output to the view can be accomplished by placing text on | |
895 | * $view->attachment_before and $view->attachment_after. | |
896 | * @param $view | |
897 | * The view object about to be processed. | |
898 | * @param $display_id | |
899 | * The machine name of the active display. | |
900 | * @param $args | |
901 | * An array of arguments passed into the view. | |
902 | */ | |
903 | function hook_views_pre_view(&$view, &$display_id, &$args) { | |
904 | // Change the display if the acting user has 'administer site configuration' | |
905 | // permission, to display something radically different. | |
906 | // (Note that this is not necessarily the best way to solve that task. Feel | |
907 | // free to contribute another example!) | |
908 | if ( | |
909 | $view->name == 'my_special_view' && | |
910 | user_access('administer site configuration') && | |
911 | $display_id == 'public_display' | |
912 | ) { | |
913 | $view->set_display('private_display'); | |
914 | } | |
915 | } | |
916 | ||
917 | /** | |
918 | * This hook is called right before the build process, but after displays | |
919 | * are attached and the display performs its pre_execute phase. | |
920 | * | |
921 | * Adding output to the view can be accomplished by placing text on | |
922 | * $view->attachment_before and $view->attachment_after. | |
923 | * @param $view | |
924 | * The view object about to be processed. | |
925 | */ | |
926 | function hook_views_pre_build(&$view) { | |
927 | // Because of some inexplicable business logic, we should remove all | |
928 | // attachments from all views on Mondays. | |
929 | // (This alter could be done later in the execution process as well.) | |
930 | if (date('D') == 'Mon') { | |
931 | unset($view->attachment_before); | |
932 | unset($view->attachment_after); | |
933 | } | |
934 | } | |
935 | ||
936 | /** | |
937 | * This hook is called right after the build process. The query is now fully | |
938 | * built, but it has not yet been run through db_rewrite_sql. | |
939 | * | |
940 | * Adding output to the view can be accomplished by placing text on | |
941 | * $view->attachment_before and $view->attachment_after. | |
942 | * @param $view | |
943 | * The view object about to be processed. | |
944 | */ | |
945 | function hook_views_post_build(&$view) { | |
946 | // If the exposed field 'type' is set, hide the column containing the content | |
947 | // type. (Note that this is a solution for a particular view, and makes | |
948 | // assumptions about both exposed filter settings and the fields in the view. | |
949 | // Also note that this alter could be done at any point before the view being | |
950 | // rendered.) | |
951 | if ($view->name == 'my_view' && isset($view->exposed_raw_input['type']) && $view->exposed_raw_input['type'] != 'All') { | |
952 | // 'Type' should be interpreted as content type. | |
953 | if (isset($view->field['type'])) { | |
954 | $view->field['type']->options['exclude'] = TRUE; | |
955 | } | |
956 | } | |
957 | } | |
958 | ||
959 | /** | |
960 | * This hook is called right before the execute process. The query is now fully | |
961 | * built, but it has not yet been run through db_rewrite_sql. | |
962 | * | |
963 | * Adding output to the view can be accomplished by placing text on | |
964 | * $view->attachment_before and $view->attachment_after. | |
965 | * @param $view | |
966 | * The view object about to be processed. | |
967 | */ | |
968 | function hook_views_pre_execute(&$view) { | |
969 | // Whenever a view queries more than two tables, show a message that notifies | |
970 | // view administrators that the query might be heavy. | |
971 | // (This action could be performed later in the execution process, but not | |
972 | // earlier.) | |
973 | if (count($view->query->tables) > 2 && user_access('administer views')) { | |
974 | drupal_set_message(t('The view %view may be heavy to execute.', array('%view' => $view->name)), 'warning'); | |
975 | } | |
976 | } | |
977 | ||
978 | /** | |
979 | * This hook is called right after the execute process. The query has | |
980 | * been executed, but the pre_render() phase has not yet happened for | |
981 | * handlers. | |
982 | * | |
983 | * Adding output to the view can be accomplished by placing text on | |
984 | * $view->attachment_before and $view->attachment_after. Altering the | |
985 | * content can be achieved by editing the items of $view->result. | |
986 | * @param $view | |
987 | * The view object about to be processed. | |
988 | */ | |
989 | function hook_views_post_execute(&$view) { | |
990 | // If there are more than 100 results, show a message that encourages the user | |
991 | // to change the filter settings. | |
992 | // (This action could be performed later in the execution process, but not | |
993 | // earlier.) | |
994 | if ($view->total_rows > 100) { | |
995 | drupal_set_message(t('You have more than 100 hits. Use the filter settings to narrow down your list.')); | |
996 | } | |
997 | } | |
998 | ||
999 | /** | |
1000 | * This hook is called right before the render process. The query has been | |
1001 | * executed, and the pre_render() phase has already happened for handlers, so | |
1002 | * all data should be available. | |
1003 | * | |
1004 | * Adding output to the view can be accomplished by placing text on | |
1005 | * $view->attachment_before and $view->attachment_after. Altering the content | |
1006 | * can be achieved by editing the items of $view->result. | |
1007 | * | |
1008 | * This hook can be utilized by themes. | |
1009 | * @param $view | |
1010 | * The view object about to be processed. | |
1011 | */ | |
1012 | function hook_views_pre_render(&$view) { | |
1013 | // Scramble the order of the rows shown on this result page. | |
1014 | // Note that this could be done earlier, but not later in the view execution | |
1015 | // process. | |
1016 | shuffle($view->result); | |
1017 | } | |
1018 | ||
1019 | /** | |
1020 | * Post process any rendered data. | |
1021 | * | |
1022 | * This can be valuable to be able to cache a view and still have some level of | |
1023 | * dynamic output. In an ideal world, the actual output will include HTML | |
1024 | * comment based tokens, and then the post process can replace those tokens. | |
1025 | * | |
1026 | * Example usage. If it is known that the view is a node view and that the | |
1027 | * primary field will be a nid, you can do something like this: | |
1028 | * | |
1029 | * <!--post-FIELD-NID--> | |
1030 | * | |
1031 | * And then in the post render, create an array with the text that should | |
1032 | * go there: | |
1033 | * | |
1034 | * strtr($output, array('<!--post-FIELD-1-->' => 'output for FIELD of nid 1'); | |
1035 | * | |
1036 | * All of the cached result data will be available in $view->result, as well, | |
1037 | * so all ids used in the query should be discoverable. | |
1038 | * | |
1039 | * This hook can be utilized by themes. | |
1040 | * @param $view | |
1041 | * The view object about to be processed. | |
1042 | * @param $output | |
1043 | * A flat string with the rendered output of the view. | |
1044 | * @param $cache | |
1045 | * The cache settings. | |
1046 | */ | |
1047 | function hook_views_post_render(&$view, &$output, &$cache) { | |
1048 | // When using full pager, disable any time-based caching if there are less | |
1049 | // then 10 results. | |
1050 | if ($view->query->pager instanceof views_plugin_pager_full && $cache->options['type'] == 'time' && count($view->result) < 10) { | |
1051 | $cache['options']['results_lifespan'] = 0; | |
1052 | $cache['options']['output_lifespan'] = 0; | |
1053 | } | |
1054 | } | |
1055 | ||
1056 | /** | |
1057 | * Alter the query before executing the query. | |
1058 | * | |
1059 | * This hook should be placed in MODULENAME.views.inc and it will be | |
1060 | * auto-loaded. MODULENAME.views.inc must be in the directory specified by the | |
1061 | * 'path' key returned by MODULENAME_views_api(), or the same directory as the | |
1062 | * .module file, if 'path' is unspecified. | |
1063 | * | |
1064 | * @param $view | |
1065 | * The view object about to be processed. | |
1066 | * @param $query | |
1067 | * An object describing the query. | |
1068 | * @see hook_views_query_substitutions() | |
1069 | */ | |
1070 | function hook_views_query_alter(&$view, &$query) { | |
1071 | // (Example assuming a view with an exposed filter on node title.) | |
1072 | // If the input for the title filter is a positive integer, filter against | |
1073 | // node ID instead of node title. | |
1074 | if ($view->name == 'my_view' && is_numeric($view->exposed_raw_input['title']) && $view->exposed_raw_input['title'] > 0) { | |
1075 | // Traverse through the 'where' part of the query. | |
1076 | foreach ($query->where as &$condition_group) { | |
1077 | foreach ($condition_group['conditions'] as &$condition) { | |
1078 | // If this is the part of the query filtering on title, change the | |
1079 | // condition to filter on node ID. | |
1080 | if ($condition['field'] == 'node.title') { | |
1081 | $condition = array( | |
1082 | 'field' => 'node.nid', | |
1083 | 'value' => $view->exposed_raw_input['title'], | |
1084 | 'operator' => '=', | |
1085 | ); | |
1086 | } | |
1087 | } | |
1088 | } | |
1089 | } | |
1090 | } | |
1091 | ||
1092 | /** | |
1093 | * Alter the information box that (optionally) appears with a view preview, | |
1094 | * including query and performance statistics. | |
1095 | * | |
1096 | * This hook should be placed in MODULENAME.views.inc and it will be | |
1097 | * auto-loaded. MODULENAME.views.inc must be in the directory specified by the | |
1098 | * 'path' key returned by MODULENAME_views_api(), or the same directory as the | |
1099 | * .module file, if 'path' is unspecified. | |
1100 | * | |
1101 | * Warning: $view is not a reference in PHP4 and cannot be modified here. But it | |
1102 | * IS a reference in PHP5, and can be modified. Please be careful with it. | |
1103 | * | |
1104 | * @param $rows | |
1105 | * An associative array with two keys: | |
1106 | * - query: An array of rows suitable for theme('table'), containing | |
1107 | * information about the query and the display title and path. | |
1108 | * - statistics: An array of rows suitable for theme('table'), containing | |
1109 | * performance statistics. | |
1110 | * @param $view | |
1111 | * The view object. | |
1112 | * @see theme_table() | |
1113 | */ | |
1114 | function hook_views_preview_info_alter(&$rows, $view) { | |
1115 | // Adds information about the tables being queried by the view to the query | |
1116 | // part of the info box. | |
1117 | $rows['query'][] = array( | |
1118 | t('<strong>Table queue</strong>'), | |
1119 | count($view->query->table_queue) . ': (' . implode(', ', array_keys($view->query->table_queue)) . ')', | |
1120 | ); | |
1121 | } | |
1122 | ||
1123 | /** | |
1124 | * This hooks allows to alter the links at the top of the view edit form. Some | |
1125 | * modules might want to add links there. | |
1126 | * | |
1127 | * @param $links | |
1128 | * An array of links which will be displayed at the top of the view edit form. | |
1129 | * Each entry should be on a form suitable for theme('link'). | |
1130 | * @param view $view | |
1131 | * The full view object which is currently edited. | |
1132 | * @param $display_id | |
1133 | * The current display id which is edited. For example that's 'default' or | |
1134 | * 'page_1'. | |
1135 | */ | |
1136 | function hook_views_ui_display_top_links_alter(&$links, $view, $display_id) { | |
1137 | // Put the export link first in the list. | |
1138 | if (isset($links['export'])) { | |
1139 | $links = array('export' => $links['export']) + $links; | |
1140 | } | |
1141 | } | |
1142 | ||
1143 | /** | |
1144 | * This hook allows to alter the commands which are used on a views ajax | |
1145 | * request. | |
1146 | * | |
1147 | * @param $commands | |
1148 | * An array of ajax commands | |
1149 | * @param $view view | |
1150 | * The view which is requested. | |
1151 | */ | |
1152 | function hook_views_ajax_data_alter(&$commands, $view) { | |
1153 | // Replace Views' method for scrolling to the top of the element with your | |
1154 | // custom scrolling method. | |
1155 | foreach ($commands as &$command) { | |
1156 | if ($command['command'] == 'viewsScrollTop') { | |
1157 | $command['command'] .= 'myScrollTop'; | |
1158 | } | |
1159 | } | |
1160 | } | |
1161 | ||
1162 | /** | |
1163 | * Allow modules to respond to the Views cache being invalidated. | |
1164 | * | |
1165 | * This hook should fire whenever a view is enabled, disabled, created, | |
1166 | * updated, or deleted. | |
1167 | * | |
1168 | * @see views_invalidate_cache() | |
1169 | */ | |
1170 | function hook_views_invalidate_cache() { | |
1171 | cache_clear_all('views:*', 'cache_mymodule', TRUE); | |
1172 | } | |
1173 | ||
1174 | /** | |
1175 | * Allow modules to alter a view prior to being saved. | |
1176 | */ | |
1177 | function hook_views_view_presave($view) { | |
1178 | // Do some adjustments to the view. Handle with care. | |
1179 | if (mymodule_check_view($view)) { | |
1180 | mymodule_do_some_voodoo($view); | |
1181 | } | |
1182 | } | |
1183 | ||
1184 | /** | |
1185 | * Allow modules to respond to a view being saved. | |
1186 | */ | |
1187 | function hook_views_view_save($view) { | |
1188 | // Make a watchdog entry. | |
1189 | watchdog('views', 'The view @name was deleted by @user at @time', array('@name' => $view->name, '@user' => $GLOBALS['user']->name, '@time' => format_date(time()))); | |
1190 | } | |
1191 | ||
1192 | /** | |
1193 | * Allow modules to respond to a view being deleted or reverted. | |
1194 | */ | |
1195 | function hook_views_view_delete($view) { | |
1196 | // Make a watchdog entry. | |
1197 | watchdog('views', 'The view @name was deleted by @user at @time', array('@name' => $view->name, '@user' => $GLOBALS['user']->name, '@time' => format_date(time()))); | |
1198 | } | |
1199 | ||
1200 | /** | |
1201 | * @} | |
1202 | */ | |
1203 | ||
1204 | /** | |
1205 | * @defgroup views_module_handlers Views module handlers | |
1206 | * @{ | |
1207 | * Handlers exposed by various modules to Views. | |
1208 | * @} | |
1209 | */ |