1
|
<?php
|
2
|
|
3
|
/**
|
4
|
* Implementation of hook_drush_help().
|
5
|
*/
|
6
|
function views_bulk_operations_drush_help($section) {
|
7
|
switch ($section) {
|
8
|
case 'drush:vbo-list':
|
9
|
return dt('List all Views Bulk Operations (VBO) views, along with the operations associated with each.');
|
10
|
case 'drush:vbo-execute':
|
11
|
return dt('Execute a bulk operation based on a Views Bulk Operations (VBO) view.');
|
12
|
}
|
13
|
}
|
14
|
|
15
|
/**
|
16
|
* Implementation of hook_drush_command().
|
17
|
*/
|
18
|
function views_bulk_operations_drush_command() {
|
19
|
$items['vbo-list'] = array(
|
20
|
'callback' => 'views_bulk_operations_drush_list',
|
21
|
'description' => 'List all Views Bulk Operations (VBO) views, along with the operations associated with each.',
|
22
|
);
|
23
|
$items['vbo-execute'] = array(
|
24
|
'callback' => 'views_bulk_operations_drush_execute',
|
25
|
'description' => 'Execute a bulk operation based on a Views Bulk Operations (VBO) view.',
|
26
|
'arguments' => array(
|
27
|
'vid' => 'ID or name of the view to be executed.',
|
28
|
'operation_id' => 'ID of the operation to be applied on the view results.',
|
29
|
'type:[name=]value ...' => 'Parameters to be passed as view input filters, view arguments or operation arguments, where type is respectively {input, argument, operation}.',
|
30
|
),
|
31
|
'examples' => array(
|
32
|
'$ drush vbo-execute action::admin_content node_publish_action' =>
|
33
|
'Publish nodes returned by view admin_content.',
|
34
|
'$ drush vbo-execute 44 action::node_assign_owner_action operation:owner_uid=3' =>
|
35
|
'Change node ownership on nodes returned by view #44, passing argument owner_uid=3 to the action.',
|
36
|
'$ drush vbo-execute admin_content action::node_unpublish_action input:type=expense argument:3' =>
|
37
|
'Unpublish nodes returned by view admin_content, filtering results of type expense and passing value 3 as first view argument.',
|
38
|
),
|
39
|
);
|
40
|
return $items;
|
41
|
}
|
42
|
|
43
|
/**
|
44
|
* Implementation of 'vbo list' command.
|
45
|
*/
|
46
|
function views_bulk_operations_drush_list() {
|
47
|
// Impersonate admin.
|
48
|
global $user;
|
49
|
$user = user_load(1);
|
50
|
drupal_save_session(FALSE);
|
51
|
|
52
|
// Find all VBO views and their associated operations.
|
53
|
$rows = array(array(sprintf('%5s', dt('View ID')), dt('Name'), dt('Description'), dt('Operations')));
|
54
|
foreach (views_get_all_views() as $name => $view) {
|
55
|
$view->build();
|
56
|
$vbo = _views_bulk_operations_get_field($view);
|
57
|
if ($vbo) {
|
58
|
$operations = array();
|
59
|
foreach ($vbo->get_selected_operations() as $operation_id => $operation) {
|
60
|
$operations[] = $operation->label() .' ('. $operation_id .')';
|
61
|
}
|
62
|
$operations[] = "---------------";
|
63
|
$rows[] = array(
|
64
|
sprintf('%5d', $view->vid),
|
65
|
$view->name,
|
66
|
$view->description,
|
67
|
implode("\n", $operations),
|
68
|
);
|
69
|
}
|
70
|
}
|
71
|
drush_print_table($rows, TRUE);
|
72
|
}
|
73
|
|
74
|
/**
|
75
|
* Implementation of 'vbo execute' command.
|
76
|
*/
|
77
|
function views_bulk_operations_drush_execute($vid = NULL, $operation_id = NULL) {
|
78
|
// Parse arguments.
|
79
|
if (is_null($vid)) {
|
80
|
drush_set_error('VIEWS_BULK_OPERATIONS_MISSING_VID', dt('Please specify a view ID to execute.'));
|
81
|
return;
|
82
|
}
|
83
|
if (is_null($operation_id)) {
|
84
|
drush_set_error('VIEWS_BULK_OPERATIONS_MISSING_OPERATION', dt('Please specify an operation to execute.'));
|
85
|
return;
|
86
|
}
|
87
|
$args = func_get_args();
|
88
|
$view_exposed_input = array();
|
89
|
$operation_arguments = array();
|
90
|
$view_arguments = array();
|
91
|
if (count($args) > 2) for ($i=2; $i<count($args); $i++) {
|
92
|
$parts = array();
|
93
|
if (FALSE === preg_match('/^(?<type>\w+):(?:(?<name>\w+)=)?(?<value>(.*?))$/', $args[$i], $parts)) {
|
94
|
drush_set_error('VIEWS_BULK_OPERATIONS_INVALID_PARAMETER', dt('The parameter %arg should be of the form type:[name=]value where type in {input, argument, operation}.', array('%arg' => $args[$i])));
|
95
|
return;
|
96
|
}
|
97
|
switch ($parts['type']) {
|
98
|
case 'input':
|
99
|
$view_exposed_input[$parts['name']] = $parts['value'];
|
100
|
break;
|
101
|
case 'operation':
|
102
|
$operation_arguments[$parts['name']] = $parts['value'];
|
103
|
break;
|
104
|
case 'argument':
|
105
|
$view_arguments[] = $parts['value'];
|
106
|
break;
|
107
|
default:
|
108
|
drush_set_error('VIEWS_BULK_OPERATIONS_UNKNOWN_PARAMETER', dt('The parameter type %type is unknown. Please specify either input, argument or operation.', array('%type' => $parts['type'])));
|
109
|
return;
|
110
|
}
|
111
|
}
|
112
|
|
113
|
// Impersonate admin.
|
114
|
global $user;
|
115
|
$user = user_load(1);
|
116
|
drupal_save_session(FALSE);
|
117
|
|
118
|
// Load the view.
|
119
|
$view = views_get_view($vid);
|
120
|
if (!is_object($view)) {
|
121
|
_views_bulk_operations_report_error('Could not find view %vid.', array('%vid' => $vid));
|
122
|
return;
|
123
|
}
|
124
|
|
125
|
// Build the view, so that the VBO field can be found.
|
126
|
$view->set_exposed_input($view_exposed_input);
|
127
|
$view->set_arguments($view_arguments);
|
128
|
$view->build();
|
129
|
$view->query->set_limit(NULL); // reset the work done by the pager
|
130
|
$view->query->set_offset(NULL);
|
131
|
|
132
|
// Find the VBO field.
|
133
|
$vbo = _views_bulk_operations_get_field($view);
|
134
|
if (!$vbo) {
|
135
|
_views_bulk_operations_report_error('Could not find a VBO field in view %vid.', array('%vid' => $vid));
|
136
|
return;
|
137
|
}
|
138
|
|
139
|
$view->execute();
|
140
|
|
141
|
// Find the selected operation.
|
142
|
$operations = $vbo->get_selected_operations();
|
143
|
if (!isset($operations[$operation_id])) {
|
144
|
_views_bulk_operations_report_error('Could not find operation %operation_id in view %vid.', array('%operation_id' => $operation_id, '%vid' => $vid));
|
145
|
return;
|
146
|
}
|
147
|
$operation = views_bulk_operations_get_operation($operation_id, $vbo->get_entity_type(), $vbo->get_operation_options($operation_id));
|
148
|
if ($operation_arguments) {
|
149
|
$operation->formOptions = $operation_arguments;
|
150
|
}
|
151
|
|
152
|
// Select all rows.
|
153
|
$rows = array();
|
154
|
$current = 1;
|
155
|
foreach ($view->result as $row_index => $result) {
|
156
|
$rows[$row_index] = array(
|
157
|
'entity_id' => $vbo->get_value($result),
|
158
|
'views_row' => array(),
|
159
|
'position' => array(
|
160
|
'current' => $current++,
|
161
|
'total' => $view->total_rows,
|
162
|
),
|
163
|
);
|
164
|
// Some operations require full selected rows.
|
165
|
if ($operation->needsRows()) {
|
166
|
$rows[$row_index]['views_row'] = $result;
|
167
|
}
|
168
|
}
|
169
|
|
170
|
// Enqueue the fetched rows.
|
171
|
$queue_name = 'views_bulk_operations_active_queue_' . db_next_id();
|
172
|
$options = array(
|
173
|
'revision' => $vbo->revision,
|
174
|
'entity_load_capacity' => $vbo->get_vbo_option('entity_load_capacity', 10),
|
175
|
);
|
176
|
views_bulk_operations_enqueue_rows($queue_name, $rows, $operation, $options);
|
177
|
|
178
|
// Process the queue using Batch API.
|
179
|
$batch = array(
|
180
|
'file' => drupal_get_path('module', 'views_bulk_operations') . '/views_bulk_operations.module',
|
181
|
'operations' => array(
|
182
|
array('views_bulk_operations_active_queue_process', array($queue_name, $operation, $vbo->view->total_rows)),
|
183
|
),
|
184
|
'finished' => '_views_bulk_operations_execute_finished',
|
185
|
'title' => t('Performing %operation on the selected items...', array('%operation' => $operation->label())),
|
186
|
);
|
187
|
batch_set($batch);
|
188
|
drush_backend_batch_process();
|
189
|
|
190
|
// Looks like drush has no way to show messages set in subprocesses,
|
191
|
// so all batch messages get lost. Setting a success message manually here.
|
192
|
drush_log(dt('Performed "!operation" on @items.', array(
|
193
|
'!operation' => $operation->label(),
|
194
|
'@items' => format_plural($vbo->view->total_rows, '1 item', '@count items'),
|
195
|
)), 'ok');
|
196
|
}
|