views_bulk_operations.drush.inc 7.2 KB

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