1
|
<?php
|
2
|
|
3
|
/**
|
4
|
* @file
|
5
|
* Drush integration for Views.
|
6
|
*
|
7
|
* Useful commands:
|
8
|
* - drush cache-clear views - Clears the views specific caches.
|
9
|
* - views-revert - Drush command to revert views overridden in the system.
|
10
|
*/
|
11
|
|
12
|
/**
|
13
|
* Implements hook_drush_help().
|
14
|
*/
|
15
|
function views_drush_help($section) {
|
16
|
switch ($section) {
|
17
|
case 'drush:views-revert':
|
18
|
$help = dt('Reverts views in the drupal installation that have been overriden. ');
|
19
|
$help .= dt('If no view names are specified, you will be presented with a list of overridden views to choose from. ');
|
20
|
$help .= dt('To revert all views, do not specify any view names, and choose the option "All" from the options presented.');
|
21
|
return $help;
|
22
|
|
23
|
case 'drush:views-list':
|
24
|
return dt('Show a list of available views with information about them.');
|
25
|
|
26
|
case 'drush:views-enable':
|
27
|
return dt('Enable the specified views. Follow the command with a space delimited list of view names');
|
28
|
|
29
|
case 'drush:views-disable':
|
30
|
return dt('Disable the specified views. Follow the command with a space delimited list of view names');
|
31
|
}
|
32
|
}
|
33
|
|
34
|
/**
|
35
|
* Implements hook_drush_command().
|
36
|
*/
|
37
|
function views_drush_command() {
|
38
|
$items = array();
|
39
|
|
40
|
$items['views-revert'] = array(
|
41
|
'callback' => 'views_revert_views',
|
42
|
'drupal dependencies' => array('views'),
|
43
|
'description' => 'Revert overridden views to their default state. Make sure to backup first.',
|
44
|
'arguments' => array(
|
45
|
'views' => 'A space delimited list of view names.',
|
46
|
),
|
47
|
'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_FULL,
|
48
|
'aliases' => array('vr'),
|
49
|
'options' => array(
|
50
|
'all' => 'If provided, all views will be reverted.',
|
51
|
),
|
52
|
'examples' => array(
|
53
|
'drush vr archive' => 'Reverts the "archive" view.',
|
54
|
'drush rln archive frontpage' => 'Reverts the "archive" and "frontpage" view.',
|
55
|
'drush vr' => 'Will present you with a list of overridden views to choose from, and an option to revert all overridden views.',
|
56
|
'drush vr --all' => 'Will revert all overridden views.',
|
57
|
),
|
58
|
);
|
59
|
$items['views-dev'] = array(
|
60
|
'callback' => 'views_development_settings',
|
61
|
'drupal dependencies' => array('views'),
|
62
|
'description' => 'Set the Views settings to more developer-oriented values.',
|
63
|
'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_FULL,
|
64
|
'aliases' => array('vd'),
|
65
|
);
|
66
|
|
67
|
$items['views-list'] = array(
|
68
|
'drupal dependencies' => array('views'),
|
69
|
'description' => 'Get a list of all views in the system.',
|
70
|
'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_FULL,
|
71
|
'aliases' => array('vl'),
|
72
|
'options' => array(
|
73
|
'name' => 'String contained in view\'s name by which filter the results.',
|
74
|
'tags' => 'A comma-separated list of views tags by which to filter the results.',
|
75
|
'status' => 'Status of the views by which to filter the results. Choices: enabled, disabled.',
|
76
|
'type' => 'Type of the views by which to filter the results. Choices: normal, default or overridden.',
|
77
|
),
|
78
|
'examples' => array(
|
79
|
'drush vl' => 'Show a list of all available views.',
|
80
|
'drush vl --name=blog' => 'Show a list of views which names contain "blog".',
|
81
|
'drush vl --tags=tag1,tag2' => 'Show a list of views tagged with "tag1" or "tag2".',
|
82
|
'drush vl --status=enabled' => 'Show a list of enabled views.',
|
83
|
'drush vl --type=overridden' => 'Show a list of overridden views.',
|
84
|
),
|
85
|
);
|
86
|
$items['views-analyze'] = array(
|
87
|
'drupal dependencies' => array('views', 'views_ui'),
|
88
|
'description' => 'Get a list of all Views analyze warnings',
|
89
|
'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_FULL,
|
90
|
'aliases' => array('va'),
|
91
|
);
|
92
|
$items['views-enable'] = array(
|
93
|
'drupal dependencies' => array('views'),
|
94
|
'description' => 'Enable the specified views.',
|
95
|
'arguments' => array(
|
96
|
'views' => 'A space delimited list of view names.',
|
97
|
),
|
98
|
'aliases' => array('ven'),
|
99
|
'examples' => array(
|
100
|
'drush ven frontpage taxonomy_term' => 'Enable the frontpage and taxonomy_term views.',
|
101
|
),
|
102
|
);
|
103
|
$items['views-disable'] = array(
|
104
|
'drupal dependencies' => array('views'),
|
105
|
'description' => 'Disable the specified views.',
|
106
|
'arguments' => array(
|
107
|
'views' => 'A space delimited list of view names.',
|
108
|
),
|
109
|
'aliases' => array('vdis'),
|
110
|
'examples' => array(
|
111
|
'drush vdis frontpage taxonomy_term' => 'Disable the frontpage and taxonomy_term views.',
|
112
|
),
|
113
|
);
|
114
|
|
115
|
return $items;
|
116
|
}
|
117
|
|
118
|
/**
|
119
|
* Callback function for views-revert command.
|
120
|
*/
|
121
|
function views_revert_views() {
|
122
|
$views = views_get_all_views();
|
123
|
$i = 0;
|
124
|
// The provided views names specified in the command.
|
125
|
$viewnames = _convert_csv_to_array(func_get_args());
|
126
|
|
127
|
// Find all overridden views.
|
128
|
foreach ($views as $view) {
|
129
|
if ($view->disabled) {
|
130
|
continue;
|
131
|
}
|
132
|
if ($view->type == dt('Overridden')) {
|
133
|
$overridden[$view->name] = $view->name;
|
134
|
}
|
135
|
}
|
136
|
|
137
|
// If there are no overridden views in the system, report it.
|
138
|
if (empty($overridden)) {
|
139
|
drush_log(dt('There are no overridden views in the system.'), 'ok');
|
140
|
}
|
141
|
|
142
|
// If the user provided the "--all" option, revert all views.
|
143
|
if (drush_get_option('all')) {
|
144
|
$i = views_revert_allviews($views);
|
145
|
}
|
146
|
|
147
|
// If the user specified a list of views on the CLI, revert those.
|
148
|
elseif (!empty($viewnames)) {
|
149
|
foreach ($viewnames as $key => $viewname) {
|
150
|
$is_overridden = array_key_exists($viewname, $overridden);
|
151
|
|
152
|
// Check if the provided view name is in the system.
|
153
|
if ($viewname && !array_key_exists($viewname, $views)) {
|
154
|
drush_set_error(dt("'@viewname' view is not present in the system.", array('@viewname' => $viewname)));
|
155
|
}
|
156
|
// Check if the provided view is overridden.
|
157
|
elseif (!$is_overridden) {
|
158
|
drush_set_error(dt("The view specified '@viewname' is not overridden.", array('@viewname' => $viewname)));
|
159
|
}
|
160
|
// If the view is overriden, revert it.
|
161
|
elseif ($is_overridden) {
|
162
|
views_revert_view($views[$viewname]);
|
163
|
$i++;
|
164
|
}
|
165
|
// We should never get here but well.
|
166
|
else {
|
167
|
drush_set_error(dt(
|
168
|
"The view specified '@viewname' is not provided in code, and thus cannot be reverted.",
|
169
|
array('@viewname' => $viewname)
|
170
|
));
|
171
|
}
|
172
|
}
|
173
|
}
|
174
|
|
175
|
// The user neither selected the "--all" option, nor provided a list of views
|
176
|
// to revert. Prompt the user.
|
177
|
else {
|
178
|
// List of choices for the user.
|
179
|
$overridden['all'] = dt('Revert all overridden views');
|
180
|
// Add a choice at the end.
|
181
|
$choice = drush_choice($overridden, 'Enter a number to choose which view to revert.', '!key');
|
182
|
// Prompt the user.
|
183
|
if ($choice !== FALSE) {
|
184
|
// Revert all views option.
|
185
|
if ($choice == 'all') {
|
186
|
$i = views_revert_allviews($views);
|
187
|
}
|
188
|
// Else the user specified a single view.
|
189
|
else {
|
190
|
views_revert_view($views[$choice]);
|
191
|
$i++;
|
192
|
}
|
193
|
}
|
194
|
|
195
|
}
|
196
|
|
197
|
// Final results output.
|
198
|
if ($i == 0) {
|
199
|
drush_log(dt('No views were reverted.'), 'ok');
|
200
|
}
|
201
|
else {
|
202
|
drush_log(dt('Reverted a total of @count views.', array('@count' => $i)), 'ok');
|
203
|
}
|
204
|
}
|
205
|
|
206
|
/**
|
207
|
* Reverts all views.
|
208
|
*
|
209
|
* @param array $views
|
210
|
* All views in the system as provided by views_get_all_views().
|
211
|
*/
|
212
|
function views_revert_allviews($views) {
|
213
|
$i = 0;
|
214
|
foreach ($views as $view) {
|
215
|
if ($view->disabled) {
|
216
|
continue;
|
217
|
}
|
218
|
|
219
|
if ($view->type == t('Overridden')) {
|
220
|
views_revert_view($view);
|
221
|
$i++;
|
222
|
}
|
223
|
}
|
224
|
return $i;
|
225
|
}
|
226
|
|
227
|
/**
|
228
|
* Revert a specified view.
|
229
|
*
|
230
|
* Checks on wether or not the view is overridden is handled in
|
231
|
* views_revert_views_revert(). We perform a check here anyway in case someone
|
232
|
* somehow calls this function on their own...
|
233
|
*
|
234
|
* @param object $view
|
235
|
* The view object to be reverted.
|
236
|
*/
|
237
|
function views_revert_view($view) {
|
238
|
// Check anyway just in case.
|
239
|
if ($view->type == t('Overridden')) {
|
240
|
// Revert the view.
|
241
|
$view->delete();
|
242
|
// Clear its cache.
|
243
|
ctools_include('object-cache');
|
244
|
ctools_object_cache_clear('view', $view->name);
|
245
|
// Give feedback.
|
246
|
$message = dt("Reverted the view '@viewname'", array('@viewname' => $view->name));
|
247
|
drush_log($message, 'success');
|
248
|
// Reverted one more view.
|
249
|
}
|
250
|
else {
|
251
|
drush_set_error(dt("The view '@viewname' is not overridden.", array('@viewname' => $view->name)));
|
252
|
}
|
253
|
}
|
254
|
|
255
|
/**
|
256
|
* Change the settings to a more developer oriented value.
|
257
|
*/
|
258
|
function views_development_settings() {
|
259
|
variable_set('views_ui_show_listing_filters', TRUE);
|
260
|
variable_set('views_ui_show_master_display', TRUE);
|
261
|
variable_set('views_ui_show_advanced_column', TRUE);
|
262
|
variable_set('views_ui_always_live_preview', FALSE);
|
263
|
variable_set('views_ui_always_live_preview_button', TRUE);
|
264
|
variable_set('views_ui_show_preview_information', TRUE);
|
265
|
variable_set('views_ui_show_sql_query', TRUE);
|
266
|
variable_set('views_ui_show_performance_statistics', TRUE);
|
267
|
variable_set('views_show_additional_queries', TRUE);
|
268
|
variable_set('views_devel_output', TRUE);
|
269
|
variable_set('views_devel_region', 'message');
|
270
|
variable_set('views_ui_display_embed', TRUE);
|
271
|
$message = dt("Setup the new views settings.");
|
272
|
drush_log($message, 'success');
|
273
|
}
|
274
|
|
275
|
|
276
|
/**
|
277
|
* Callback function for views-list command.
|
278
|
*/
|
279
|
function drush_views_list() {
|
280
|
// Initialize stuff.
|
281
|
$rows = array();
|
282
|
$disabled_views = array();
|
283
|
$enabled_views = array();
|
284
|
$overridden = 0;
|
285
|
$indb = 0;
|
286
|
$incode = 0;
|
287
|
$disabled = 0;
|
288
|
$total = 0;
|
289
|
|
290
|
$views = views_get_all_views();
|
291
|
|
292
|
// Get the --name option.
|
293
|
// @todo Take into account the case off a comma-separated list of names.
|
294
|
$name = drush_get_option_list('name');
|
295
|
$with_name = !empty($name) ? TRUE : FALSE;
|
296
|
|
297
|
// Get the --tags option.
|
298
|
$tags = drush_get_option_list('tags');
|
299
|
$with_tags = !empty($tags) ? TRUE : FALSE;
|
300
|
|
301
|
// Get the --status option. Store user input appart to reuse it after.
|
302
|
$status_opt = drush_get_option_list('status');
|
303
|
// Use the same logic than $view->disabled.
|
304
|
if (in_array('disabled', $status_opt)) {
|
305
|
$status = TRUE;
|
306
|
$with_status = TRUE;
|
307
|
}
|
308
|
elseif (in_array('enabled', $status_opt)) {
|
309
|
$status = FALSE;
|
310
|
$with_status = TRUE;
|
311
|
}
|
312
|
else {
|
313
|
$status = NULL;
|
314
|
// Wrong or empty --status option.
|
315
|
$with_status = FALSE;
|
316
|
}
|
317
|
|
318
|
// Get the --type option.
|
319
|
$type = drush_get_option_list('type');
|
320
|
// Use the same logic than $view->type.
|
321
|
$with_type = FALSE;
|
322
|
if (in_array('normal', $type) || in_array('default', $type)|| in_array('overridden', $type)) {
|
323
|
$with_type = TRUE;
|
324
|
}
|
325
|
|
326
|
// Set the table headers.
|
327
|
$header = array(
|
328
|
dt('Machine name'),
|
329
|
dt('Description'),
|
330
|
dt('Type'),
|
331
|
dt('Status'),
|
332
|
dt('Tag'),
|
333
|
);
|
334
|
|
335
|
// Setup a row for each view.
|
336
|
foreach ($views as $id => $view) {
|
337
|
// If options were specified, check that first mismatch push the loop to
|
338
|
// the next view.
|
339
|
if ($with_tags && !in_array($view->tag, $tags)) {
|
340
|
continue;
|
341
|
}
|
342
|
if ($with_status && !$view->disabled == $status) {
|
343
|
continue;
|
344
|
}
|
345
|
if ($with_type && strtolower($view->type) !== $type[0]) {
|
346
|
continue;
|
347
|
}
|
348
|
if ($with_name && !stristr($view->name, $name[0])) {
|
349
|
continue;
|
350
|
}
|
351
|
|
352
|
$row = array();
|
353
|
// Each row entry should be in the same order as the header.
|
354
|
$row[] = $view->name;
|
355
|
$row[] = $view->description;
|
356
|
$row[] = $view->type;
|
357
|
$row[] = $view->disabled ? dt('Disabled') : dt('Enabled');
|
358
|
$row[] = $view->tag;
|
359
|
|
360
|
// Place the row in the appropiate array so we can have disabled views at
|
361
|
// the bottom.
|
362
|
if ($view->disabled) {
|
363
|
$disabled_views[] = $row;
|
364
|
}
|
365
|
else {
|
366
|
$enabled_views[] = $row;
|
367
|
}
|
368
|
unset($row);
|
369
|
|
370
|
// Gather some statistics.
|
371
|
switch ($view->type) {
|
372
|
case dt('Normal'):
|
373
|
$indb++;
|
374
|
break;
|
375
|
|
376
|
case dt('Overridden'):
|
377
|
$overridden++;
|
378
|
break;
|
379
|
|
380
|
case dt('Default'):
|
381
|
$incode++;
|
382
|
break;
|
383
|
}
|
384
|
$total++;
|
385
|
}
|
386
|
|
387
|
$disabled = count($disabled_views);
|
388
|
|
389
|
// Sort alphabeticaly.
|
390
|
asort($disabled_views);
|
391
|
asort($enabled_views);
|
392
|
|
393
|
// If options were used.
|
394
|
$summary = "";
|
395
|
if ($with_name || $with_tags || $with_status || $with_type) {
|
396
|
$summary = "Views";
|
397
|
|
398
|
if ($with_name) {
|
399
|
$summary .= " named $name[0]";
|
400
|
}
|
401
|
|
402
|
if ($with_tags) {
|
403
|
$tags = implode(" or ", $tags);
|
404
|
$summary .= " tagged $tags";
|
405
|
}
|
406
|
|
407
|
if ($with_status) {
|
408
|
$status_opt = implode("", $status_opt);
|
409
|
$summary .= " which status is '$status_opt'";
|
410
|
}
|
411
|
|
412
|
if ($with_type) {
|
413
|
$type = ucfirst($type[0]);
|
414
|
$summary .= " of type '$type'";
|
415
|
}
|
416
|
}
|
417
|
|
418
|
if (!empty($summary)) {
|
419
|
drush_print($summary . "\n");
|
420
|
}
|
421
|
|
422
|
// Print all rows as a table.
|
423
|
if ($total > 0) {
|
424
|
$rows = array_merge($enabled_views, $disabled_views);
|
425
|
// Put the headers as first row.
|
426
|
array_unshift($rows, $header);
|
427
|
|
428
|
drush_print_table($rows, TRUE);
|
429
|
}
|
430
|
|
431
|
// Print the statistics messages.
|
432
|
drush_print(dt("A total of @total views were found in this Drupal installation:", array('@total' => $total)));
|
433
|
drush_print(dt(" @indb views reside only in the database", array('@indb' => $indb)));
|
434
|
drush_print(dt(" @over views are overridden", array('@over' => $overridden)));
|
435
|
drush_print(dt(" @incode views are in their default state", array('@incode' => $incode)));
|
436
|
drush_print(dt(" @dis views are disabled\n", array('@dis' => $disabled)));
|
437
|
}
|
438
|
|
439
|
/**
|
440
|
* Analyze all installed views.
|
441
|
*/
|
442
|
function drush_views_analyze() {
|
443
|
views_include('analyze');
|
444
|
$messages_count = 0;
|
445
|
$total = 0;
|
446
|
|
447
|
foreach (views_get_all_views() as $view_name => $view) {
|
448
|
$total++;
|
449
|
if ($messages = views_analyze_view($view)) {
|
450
|
drush_print($view_name);
|
451
|
foreach ($messages as $message) {
|
452
|
$messages_count++;
|
453
|
drush_print($message['type'] . ': ' . $message['message'], 2);
|
454
|
}
|
455
|
}
|
456
|
}
|
457
|
drush_log(dt('A total of @total views were analyzed and @messages problems were found.', array('@total' => $total, '@messages' => $messages_count)), 'ok');
|
458
|
}
|
459
|
|
460
|
/**
|
461
|
* Enables views.
|
462
|
*/
|
463
|
function drush_views_enable() {
|
464
|
$viewnames = _convert_csv_to_array(func_get_args());
|
465
|
// Return early if no view names were specified.
|
466
|
if (empty($viewnames)) {
|
467
|
return drush_set_error(dt('Please specify a space delimited list of view names to enable'));
|
468
|
}
|
469
|
_views_drush_changestatus($viewnames, FALSE);
|
470
|
}
|
471
|
|
472
|
/**
|
473
|
* Disables views.
|
474
|
*/
|
475
|
function drush_views_disable() {
|
476
|
$viewnames = _convert_csv_to_array(func_get_args());
|
477
|
// Return early if no view names were specified.
|
478
|
if (empty($viewnames)) {
|
479
|
return drush_set_error(dt('Please specify a space delimited list of view names to disable'));
|
480
|
}
|
481
|
_views_drush_changestatus($viewnames, TRUE);
|
482
|
}
|
483
|
|
484
|
/**
|
485
|
* Helper function to enable / disable views.
|
486
|
*
|
487
|
* @param array $viewnames
|
488
|
* Names of the views to process.
|
489
|
* @param bool $status
|
490
|
* TRUE to disable or FALSE to enable the view.
|
491
|
*/
|
492
|
function _views_drush_changestatus($viewnames = array(), $status = NULL) {
|
493
|
if ($status !== NULL && !empty($viewnames)) {
|
494
|
$changed = FALSE;
|
495
|
$processed = $status ? dt('disabled') : dt('enabled');
|
496
|
$views_status = variable_get('views_defaults', array());
|
497
|
|
498
|
foreach ($viewnames as $key => $viewname) {
|
499
|
if ($views_status[$viewname] !== $status) {
|
500
|
$views_status[$viewname] = $status;
|
501
|
$changed = TRUE;
|
502
|
drush_log(dt("The view '!name' has been !processed", array('!name' => $viewname, '!processed' => $processed)), 'success');
|
503
|
}
|
504
|
else {
|
505
|
drush_set_error(dt("The view '!name' is already !processed", array('!name' => $viewname, '!processed' => $processed)));
|
506
|
}
|
507
|
}
|
508
|
// If we made changes to views status, save them and clear caches.
|
509
|
if ($changed) {
|
510
|
variable_set('views_defaults', $views_status);
|
511
|
views_invalidate_cache();
|
512
|
drush_log(dt("Views cache was cleared"), 'ok');
|
513
|
drush_log(dt("Menu cache is set to be rebuilt on the next request."), 'ok');
|
514
|
}
|
515
|
}
|
516
|
}
|
517
|
|
518
|
/**
|
519
|
* Adds a cache clear option for views.
|
520
|
*
|
521
|
* @param array $types
|
522
|
* The list of cache types that are available.
|
523
|
*/
|
524
|
function views_drush_cache_clear(&$types) {
|
525
|
$types['views'] = 'views_invalidate_cache';
|
526
|
}
|