more module updates

This commit is contained in:
Bachir Soussi Chiadmi
2015-04-20 18:19:49 +02:00
parent 2121a356b3
commit cde7b73a73
39 changed files with 660 additions and 258 deletions

View File

@@ -14,6 +14,12 @@ function views_bulk_operations_delete_action_info() {
'behavior' => array('deletes_property'),
'triggers' => array('any'),
),
'views_bulk_operations_delete_revision' => array(
'type' => 'entity',
'label' => t('Delete revision'),
'configurable' => FALSE,
'behavior' => array('deletes_property'),
),
);
}
@@ -23,3 +29,9 @@ function views_bulk_operations_delete_item($entity, $context) {
entity_delete($context['entity_type'], $entity_id);
}
function views_bulk_operations_delete_revision($entity, $context) {
$info = entity_get_info($context['entity_type']);
$revision_id = $entity->{$info['entity keys']['revision']};
entity_revision_delete($context['entity_type'], $revision_id);
}

View File

@@ -29,15 +29,19 @@ function views_bulk_operations_modify_action_info() {
*/
function views_bulk_operations_modify_action($entity, $context) {
list(,,$bundle_name) = entity_extract_ids($context['entity_type'], $entity);
// Handle Field API fields.
if (!empty($context['selected']['bundle_' . $bundle_name])) {
// The pseudo entity is cloned so that changes to it don't get carried
// over to the next execution.
$pseudo_entity = clone $context['entities'][$bundle_name];
foreach ($context['selected']['bundle_' . $bundle_name] as $key) {
// Get this field's language. We can just pull it from the pseudo entity
// as it was created using field_attach_form and entity_language so it's
// already been figured out if this field is translatable or not and
// applied the appropriate language code to the field
$language = key($pseudo_entity->{$key});
// Replace any tokens that might exist in the field columns.
foreach ($pseudo_entity->{$key}[LANGUAGE_NONE] as $delta => &$item) {
foreach ($pseudo_entity->{$key}[$language] as $delta => &$item) {
foreach ($item as $column => $value) {
if (is_string($value)) {
$item[$column] = token_replace($value, array($context['entity_type'] => $entity), array('sanitize' => FALSE));
@@ -46,11 +50,11 @@ function views_bulk_operations_modify_action($entity, $context) {
}
if (in_array($key, $context['append']['bundle_' . $bundle_name]) && !empty($entity->$key)) {
$entity->{$key}[LANGUAGE_NONE] = array_merge($entity->{$key}[LANGUAGE_NONE], $pseudo_entity->{$key}[LANGUAGE_NONE]);
$entity->{$key}[$language] = array_merge($entity->{$key}[$language], $pseudo_entity->{$key}[$language]);
// Check if we breached cardinality, and notify the user.
$field_info = field_info_field($key);
$field_count = count($entity->{$key}[LANGUAGE_NONE]);
$field_count = count($entity->{$key}[$language]);
if ($field_info['cardinality'] != FIELD_CARDINALITY_UNLIMITED && $field_count > $field_info['cardinality']) {
$entity_label = entity_label($context['entity_type'], $entity);
$warning = t('Tried to set !field_count values for field !field_name that supports a maximum of !cardinality.',
@@ -59,9 +63,14 @@ function views_bulk_operations_modify_action($entity, $context) {
'!cardinality' => $field_info['cardinality']));
drupal_set_message($warning, 'warning', FALSE);
}
// Prevent storing duplicate references.
if (strpos($field_info['type'], 'reference') !== FALSE) {
$entity->{$key}[$language] = array_unique($entity->{$key}[LANGUAGE_NONE], SORT_REGULAR);
}
}
else {
$entity->$key = $pseudo_entity->$key;
$entity->{$key}[$language] = $pseudo_entity->{$key}[$language];
}
}
}
@@ -148,6 +157,11 @@ function views_bulk_operations_modify_action_form($context, &$form_state) {
),
),
);
// The default #maxlength for textfields is 128, while most varchar
// columns hold 255 characters, which makes it a saner default here.
if ($determined_type == 'textfield') {
$form['properties'][$key]['#maxlength'] = 255;
}
if (!empty($property['options list'])) {
$form['properties'][$key]['#type'] = 'select';
@@ -170,6 +184,8 @@ function views_bulk_operations_modify_action_form($context, &$form_state) {
}
}
// Going to need this for multilingual nodes
global $language;
foreach ($bundles as $bundle_name => $bundle) {
$bundle_key = $info['entity keys']['bundle'];
$default_values = array();
@@ -177,6 +193,7 @@ function views_bulk_operations_modify_action_form($context, &$form_state) {
if (!empty($bundle_key)) {
$default_values[$bundle_key] = $bundle_name;
}
$default_values['language'] = $language->language;
$entity = entity_create($context['entity_type'], $default_values);
$form_state['entities'][$bundle_name] = $entity;
@@ -195,7 +212,7 @@ function views_bulk_operations_modify_action_form($context, &$form_state) {
'#title' => $label,
'#parents' => array($form_key),
);
field_attach_form($context['entity_type'], $entity, $form[$form_key], $form_state, LANGUAGE_NONE);
field_attach_form($context['entity_type'], $entity, $form[$form_key], $form_state, entity_language($context['entity_type'], $entity));
// Now that all the widgets have been added, sort them by #weight.
// This ensures that they will stay in the correct order when they get
// assigned new weights.
@@ -206,8 +223,10 @@ function views_bulk_operations_modify_action_form($context, &$form_state) {
$weight = 0;
foreach (element_get_visible_children($form[$form_key]) as $field_name) {
// For our use case it makes no sense for any field widget to be required.
$language = $form[$form_key][$field_name]['#language'];
_views_bulk_operations_modify_action_unset_required($form[$form_key][$field_name][$language]);
if (isset($form[$form_key][$field_name]['#language'])) {
$field_language = $form[$form_key][$field_name]['#language'];
_views_bulk_operations_modify_action_unset_required($form[$form_key][$field_name][$field_language]);
}
// The admin has specified which fields to display, but this field didn't
// make the cut. Hide it with #access => FALSE and move on.
@@ -216,32 +235,34 @@ function views_bulk_operations_modify_action_form($context, &$form_state) {
continue;
}
$field = $instances[$field_name];
$form[$form_key]['show_value'][$field_name] = array(
'#type' => 'checkbox',
'#title' => $field['label'],
);
$form[$form_key][$field_name]['#states'] = array(
'visible' => array(
'#edit-bundle-' . str_replace('_', '-', $bundle_name) . '-show-value-' . str_replace('_', '-', $field_name) => array('checked' => TRUE),
),
);
// All field widgets get reassigned weights so that additional elements
// added between them (such as "_append") can be properly ordered.
$form[$form_key][$field_name]['#weight'] = $weight++;
$field_info = field_info_field($field_name);
if ($field_info['cardinality'] != 1) {
$form[$form_key]['_append::' . $field_name] = array(
if (isset($instances[$field_name])) {
$field = $instances[$field_name];
$form[$form_key]['show_value'][$field_name] = array(
'#type' => 'checkbox',
'#title' => t('Add new value(s) to %label, instead of overwriting the existing values.', array('%label' => $field['label'])),
'#states' => array(
'visible' => array(
'#edit-bundle-' . str_replace('_', '-', $bundle_name) . '-show-value-' . str_replace('_', '-', $field_name) => array('checked' => TRUE),
),
),
'#weight' => $weight++,
'#title' => $field['label'],
);
$form[$form_key][$field_name]['#states'] = array(
'visible' => array(
'#edit-bundle-' . str_replace('_', '-', $bundle_name) . '-show-value-' . str_replace('_', '-', $field_name) => array('checked' => TRUE),
),
);
// All field widgets get reassigned weights so that additional elements
// added between them (such as "_append") can be properly ordered.
$form[$form_key][$field_name]['#weight'] = $weight++;
$field_info = field_info_field($field_name);
if ($field_info['cardinality'] != 1) {
$form[$form_key]['_append::' . $field_name] = array(
'#type' => 'checkbox',
'#title' => t('Add new value(s) to %label, instead of overwriting the existing values.', array('%label' => $field['label'])),
'#states' => array(
'visible' => array(
'#edit-bundle-' . str_replace('_', '-', $bundle_name) . '-show-value-' . str_replace('_', '-', $field_name) => array('checked' => TRUE),
),
),
'#weight' => $weight++,
);
}
}
}
@@ -411,8 +432,12 @@ function _views_bulk_operations_modify_action_get_properties($entity_type, $disp
// List of supported types.
$supported_types = array('text', 'token', 'integer', 'decimal', 'date', 'duration',
'boolean', 'uri', 'list');
$property_info = entity_get_property_info($entity_type);
if (empty($property_info['properties'])) {
// Stop here if no properties were found.
return array();
}
foreach ($property_info['properties'] as $key => $property) {
if (in_array($key, $disabled_properties)) {
continue;
@@ -463,27 +488,38 @@ function _views_bulk_operations_modify_action_get_bundles($entity_type, $context
$bundles = array();
$view = $context['view'];
$vbo = _views_bulk_operations_get_field($view);
$display_values = $context['settings']['display_values'];
$info = entity_get_info($entity_type);
$bundle_key = $info['entity keys']['bundle'];
// Check if this View has a filter on the bundle key and assemble a list
// of allowed bundles according to the filter.
$filtered_bundles = array();
if (!empty($bundle_key) && isset($view->filter[$bundle_key]) && !empty($view->filter[$bundle_key]->value)) {
$operator = $view->filter[$bundle_key]->operator;
if ($operator == 'in') {
$filtered_bundles = $view->filter[$bundle_key]->value;
}
elseif ($operator == 'not in') {
$bundle_names = array_keys($info['bundles']);
$filtered_bundles = array_diff($bundle_names, $view->filter[$bundle_key]->value);
$filtered_bundles = array_keys($info['bundles']);
// Go over all the filters and find any relevant ones.
foreach ($view->filter as $key => $filter) {
// Check it's the right field on the right table.
if ($filter->table == $vbo->table && $filter->field == $bundle_key) {
// Exposed filters may have no bundles, so check that there is a value.
if (empty($filter->value)) {
continue;
}
$operator = $filter->operator;
if ($operator == 'in') {
$filtered_bundles = array_intersect($filtered_bundles, $filter->value);
}
elseif ($operator == 'not in') {
$filtered_bundles = array_diff($filtered_bundles, $filter->value);
}
}
}
foreach ($info['bundles'] as $bundle_name => $bundle) {
// The view is limited to specific bundles, but this bundle isn't one of
// them. Ignore it.
if (!empty($filtered_bundles) && !in_array($bundle_name, $filtered_bundles)) {
if (!in_array($bundle_name, $filtered_bundles)) {
continue;
}
@@ -575,6 +611,7 @@ function views_bulk_operations_modify_action_views_bulk_operations_form($options
'#multiple' => TRUE,
'#description' => t('Select which values the action form should present to the user.'),
'#default_value' => $options['display_values'],
'#size' => 10,
);
return $form;
}

View File

@@ -3,9 +3,9 @@ description = Provides permission-based access control for actions. Used by View
package = Administration
core = 7.x
; Information added by drupal.org packaging script on 2012-12-03
version = "7.x-3.1"
; Information added by Drupal.org packaging script on 2013-12-23
version = "7.x-3.2"
core = "7.x"
project = "views_bulk_operations"
datestamp = "1354500015"
datestamp = "1387798183"

View File

@@ -141,9 +141,11 @@ class ViewsBulkOperationsAction extends ViewsBulkOperationsBaseOperation {
* @param $dom_id
* The dom path to the level where the admin options form is embedded.
* Needed for #dependency.
* @param $field_handler
* The Views field handler object for the VBO field.
*/
public function adminOptionsForm($dom_id) {
$form = parent::adminOptionsForm($dom_id);
public function adminOptionsForm($dom_id, $field_handler) {
$form = parent::adminOptionsForm($dom_id, $field_handler);
$settings_form_callback = $this->operationInfo['callback'] . '_views_bulk_operations_form';
if (function_exists($settings_form_callback)) {

View File

@@ -173,8 +173,10 @@ abstract class ViewsBulkOperationsBaseOperation {
* @param $dom_id
* The dom path to the level where the admin options form is embedded.
* Needed for #dependency.
* @param $field_handler
* The Views field handler object for the VBO field.
*/
public function adminOptionsForm($dom_id) {
public function adminOptionsForm($dom_id, $field_handler) {
$label = $this->getAdminOption('label', '');
$form = array();

View File

@@ -57,15 +57,32 @@ class views_bulk_operations_handler_field_operations extends views_handler_field
'enable_select_all_pages' => array('default' => TRUE),
'force_single' => array('default' => FALSE),
'entity_load_capacity' => array('default' => 10),
'skip_batching' => array('default' => 0),
),
);
$options['vbo_operations'] = array(
'default' => array(),
'unpack_translatable' => 'unpack_operations',
);
return $options;
}
function unpack_operations(&$translatable, $storage, $option, $definition, $parents, $keys) {
$translatable[] = array(
'value' => t('- Choose an operation -'),
'keys' => array_merge($keys, array('noop')),
);
foreach ($storage[$option] as $key => $operation) {
if (!empty($operation['override_label']) && !empty($operation['label'])) {
$translatable[] = array(
'value' => $operation['label'],
'keys' => array_merge($keys, array($key)),
);
}
}
}
function options_form(&$form, &$form_state) {
parent::options_form($form, $form_state);
@@ -102,6 +119,12 @@ class views_bulk_operations_handler_field_operations extends views_handler_field
'#description' => t("Improve execution performance at the cost of memory usage. Set to '1' if you're having problems."),
'#default_value' => $this->options['vbo_settings']['entity_load_capacity'],
);
$form['vbo_settings']['skip_batching'] = array(
'#type' => 'checkbox',
'#title' => t('Skip batching'),
'#default_value' => $this->options['vbo_settings']['skip_batching'],
'#description' => '<b>' . t('Warning:') . '</b> ' . t('This will cause timeouts for larger amounts of selected items.'),
);
// Display operations and their settings.
$form['vbo_operations'] = array(
@@ -142,7 +165,7 @@ class views_bulk_operations_handler_field_operations extends views_handler_field
),
);
$form['vbo_operations'][$operation_id] += $operation->adminOptionsForm($dom_id);
$form['vbo_operations'][$operation_id] += $operation->adminOptionsForm($dom_id, $this);
}
}

View File

@@ -4,13 +4,14 @@ dependencies[] = entity
dependencies[] = views
package = Views
core = 7.x
php = 5.2.9
files[] = plugins/operation_types/base.class.php
files[] = views/views_bulk_operations_handler_field_operations.inc
; Information added by drupal.org packaging script on 2012-12-03
version = "7.x-3.1"
; Information added by Drupal.org packaging script on 2013-12-23
version = "7.x-3.2"
core = "7.x"
project = "views_bulk_operations"
datestamp = "1354500015"
datestamp = "1387798183"

View File

@@ -45,10 +45,12 @@ function views_bulk_operations_load_action_includes() {
$files = array(
'archive.action.inc',
'argument_selector.action.inc',
'book.action.inc',
'delete.action.inc',
'modify.action.inc',
'script.action.inc',
'user_roles.action.inc',
'user_cancel.action.inc',
);
if (!$loaded) {
@@ -110,7 +112,7 @@ function views_bulk_operations_theme() {
'variables' => array('view' => NULL, 'enable_select_all_pages' => TRUE),
),
'views_bulk_operations_confirmation' => array(
'variables' => array('rows' => NULL, 'vbo' => NULL),
'variables' => array('rows' => NULL, 'vbo' => NULL, 'operation' => NULL, 'select_all_pages' => FALSE),
),
);
$files = views_bulk_operations_load_action_includes();
@@ -300,6 +302,29 @@ function views_bulk_operations_form_alter(&$form, &$form_state, $form_id) {
return;
}
// Add basic VBO functionality.
if ($form_state['step'] == 'views_form_views_form') {
// The submit button added by Views Form API might be used by a non-VBO Views
// Form handler. If there's no such handler on the view, hide the button.
$has_other_views_form_handlers = FALSE;
foreach ($vbo->view->field as $field) {
if (property_exists($field, 'views_form_callback') || method_exists($field, 'views_form')) {
if (!($field instanceof views_bulk_operations_handler_field_operations)) {
$has_other_views_form_handlers = TRUE;
}
}
}
if (!$has_other_views_form_handlers) {
$form['actions']['#access'] = FALSE;
}
// The VBO field is excluded from display, stop here.
if (!empty($vbo->options['exclude'])) {
return;
}
$form = views_bulk_operations_form($form, $form_state, $vbo);
}
// Cache the built form to prevent it from being rebuilt prior to validation
// and submission, which could lead to data being processed incorrectly,
// because the views rows (and thus, the form elements as well) have changed
@@ -319,15 +344,25 @@ function views_bulk_operations_form_alter(&$form, &$form_state, $form_id) {
}
}
// Add basic VBO functionality.
if ($form_state['step'] == 'views_form_views_form') {
$form = views_bulk_operations_form($form, $form_state, $vbo);
}
// Give other modules a chance to alter the form.
drupal_alter('views_bulk_operations_form', $form, $form_state, $vbo);
}
/**
* Implements hook_views_post_build().
*
* Hides the VBO field if no operations are available.
* This causes the entire VBO form to be hidden.
*
* @see views_bulk_operations_form_alter().
*/
function views_bulk_operations_views_post_build(&$view) {
$vbo = _views_bulk_operations_get_field($view);
if ($vbo && $vbo->get_selected_operations() < 1) {
$vbo->options['exclude'] = TRUE;
}
}
/**
* Returns the 'select all' div that gets inserted below the table header row
* (for table style plugins with grouping disabled), or above the view results
@@ -409,7 +444,12 @@ function theme_views_bulk_operations_select_all($variables) {
function views_bulk_operations_form($form, &$form_state, $vbo) {
$form['#attached']['js'][] = drupal_get_path('module', 'views_bulk_operations') . '/js/views_bulk_operations.js';
$form['#attached']['css'][] = drupal_get_path('module', 'views_bulk_operations') . '/css/views_bulk_operations.css';
$form['#prefix'] = '<div class="vbo-views-form">';
// Wrap the form in a div with specific classes for JS targeting and theming.
$class = 'vbo-views-form';
if (empty($vbo->view->result)) {
$class .= ' vbo-views-form-empty';
}
$form['#prefix'] = '<div class="' . $class . '">';
$form['#suffix'] = '</div>';
// Force browser to reload the page if Back is hit.
@@ -426,25 +466,10 @@ function views_bulk_operations_form($form, &$form_state, $vbo) {
'#attributes' => array('class' => 'select-all-rows'),
'#default_value' => FALSE,
);
// The submit button added by Views Form API might be used by a non-VBO Views
// Form handler. If there's no such handler on the view, hide the button.
$has_other_views_form_handlers = FALSE;
foreach ($vbo->view->field as $field) {
if (property_exists($field, 'views_form_callback') || method_exists($field, 'views_form')) {
if (!($field instanceof views_bulk_operations_handler_field_operations)) {
$has_other_views_form_handlers = TRUE;
}
}
}
if (!$has_other_views_form_handlers) {
$form['actions']['submit']['#access'] = FALSE;
}
$form['select'] = array(
'#type' => 'fieldset',
'#title' => t('Operations'),
'#collapsible' => TRUE,
'#collapsible' => FALSE,
'#attributes' => array('class' => array('container-inline')),
);
if ($vbo->get_vbo_option('display_type') == 0) {
@@ -573,7 +598,7 @@ function views_bulk_operations_confirm_form($form, &$form_state, $view, $output)
$form = confirm_form($form,
t('Are you sure you want to perform %operation on the selected items?', array('%operation' => $operation->label())),
array('path' => $view->get_url(), 'query' => $query),
theme('views_bulk_operations_confirmation', array('rows' => $rows, 'vbo' => $vbo, 'select_all_pages' => $form_state['select_all_pages']))
theme('views_bulk_operations_confirmation', array('rows' => $rows, 'vbo' => $vbo, 'operation' => $operation, 'select_all_pages' => $form_state['select_all_pages']))
);
// Add VBO's submit handler to the Confirm button added by config_form().
$form['actions']['submit']['#submit'] = array('views_bulk_operations_form_submit');
@@ -676,8 +701,8 @@ function views_bulk_operations_form_submit($form, &$form_state) {
* Entry point for executing the chosen operation upon selected rows.
*
* If the selected operation is an aggregate operation (requiring all selected
* items to be passed at the same time), or the execution is being triggered
* through Drush, the operation is executed directly.
* items to be passed at the same time), restricted to a single value, or has
* the skip_batching option set, the operation is executed directly.
* This means that there is no batching & queueing, the PHP execution
* time limit is ignored (if allowed), all selected entities are loaded and
* processed.
@@ -703,9 +728,13 @@ function views_bulk_operations_form_submit($form, &$form_state) {
function views_bulk_operations_execute($vbo, $operation, $selection, $select_all_pages = FALSE) {
global $user;
// This is an aggregate operation, and it requires all rows to be selected.
// Try to load them without a batch.
if ($operation->aggregate() && $select_all_pages) {
// Determine if the operation needs to be executed directly.
$aggregate = $operation->aggregate();
$skip_batching = $vbo->get_vbo_option('skip_batching');
$force_single = $vbo->get_vbo_option('force_single');
$execute_directly = ($aggregate || $skip_batching || $force_single);
// Try to load all rows without a batch if needed.
if ($execute_directly && $select_all_pages) {
views_bulk_operations_direct_adjust($selection, $vbo);
}
@@ -713,6 +742,15 @@ function views_bulk_operations_execute($vbo, $operation, $selection, $select_all
$options = array(
'revision' => $vbo->revision,
'entity_load_capacity' => $vbo->get_vbo_option('entity_load_capacity', 10),
// The information needed to recreate the view, to avoid serializing the
// whole object. Passed to the executed operation. Also used by
// views_bulk_operations_adjust_selection().
'view_info' => array(
'name' => $vbo->view->name,
'display' => $vbo->view->current_display,
'arguments' => $vbo->view->args,
'exposed_input' => $vbo->view->get_exposed_input(),
),
);
// Create an array of rows in the needed format.
$rows = array();
@@ -735,8 +773,8 @@ function views_bulk_operations_execute($vbo, $operation, $selection, $select_all
}
}
// Aggregate operations can only be executed directly.
if ($operation->aggregate()) {
if ($execute_directly) {
// Execute the operation directly and stop here.
views_bulk_operations_direct_process($operation, $rows, $options);
return;
}
@@ -763,18 +801,8 @@ function views_bulk_operations_execute($vbo, $operation, $selection, $select_all
if ($select_all_pages && $vbo->view->query->pager->has_more_records()) {
$total_rows = $vbo->view->total_rows;
// Pass information needed to recreate the view inside a batch,
// to avoid having to serialize the current object (which is expensive).
$view_info = array(
'name' => $vbo->view->name,
'display' => $vbo->view->current_display,
'arguments' => $vbo->view->args,
'exposed_input' => $vbo->view->get_exposed_input(),
'entity_load_capacity' => $vbo->get_vbo_option('entity_load_capacity', 10),
);
$batch['operations'][] = array(
'views_bulk_operations_adjust_selection', array($view_info, $queue_name, $operation, $options),
'views_bulk_operations_adjust_selection', array($queue_name, $operation, $options),
);
}
else {
@@ -808,22 +836,21 @@ function views_bulk_operations_execute($vbo, $operation, $selection, $select_all
/**
* Batch API callback: loads the view page by page and enqueues all items.
*
* @param $view_info
* An array of information about the view, used to recreate and re-execute it.
* @param $queue_name
* The name of the queue to which the items should be added.
* @param $operation
* The operation object.
* @param $options
* An array of options that affect execution (revision, entity_load_capacity).
* Passed along with each new queue item.
* An array of options that affect execution (revision, entity_load_capacity,
* view_info). Passed along with each new queue item.
*/
function views_bulk_operations_adjust_selection($view_info, $queue_name, $operation, $options, &$context) {
function views_bulk_operations_adjust_selection($queue_name, $operation, $options, &$context) {
if (!isset($context['sandbox']['progress'])) {
$context['sandbox']['progress'] = 0;
$context['sandbox']['max'] = 0;
}
$view_info = $options['view_info'];
$view = views_get_view($view_info['name']);
$view->set_exposed_input($view_info['exposed_input']);
$view->set_arguments($view_info['arguments']);
@@ -927,7 +954,7 @@ function views_bulk_operations_active_queue_process($queue_name, $operation, $to
static $queue;
// It is still possible to hit the time limit.
@set_time_limit(0);
drupal_set_time_limit(0);
// Prepare the sandbox.
if (!isset($context['sandbox']['progress'])) {
@@ -980,19 +1007,35 @@ function views_bulk_operations_queue_item_process($queue_item_data, &$log = NULL
$account = user_load($queue_item_data['uid']);
$entity_type = $operation->entityType;
$entity_ids = array();
foreach ($row_group as $row_id => $row) {
foreach ($row_group as $row_index => $row) {
$entity_ids[] = $row['entity_id'];
}
$entities = _views_bulk_operations_entity_load($entity_type, $entity_ids, $options['revision']);
foreach ($row_group as $row_id => $row) {
foreach ($row_group as $row_index => $row) {
$entity_id = $row['entity_id'];
// A matching entity couldn't be loaded. Skip this item.
if (!isset($entities[$entity_id])) {
continue;
}
$entity = $entities[$entity_id];
if ($options['revision']) {
// Don't reload revisions for now, they are not statically cached and
// usually don't run into the edge case described below.
$entity = $entities[$entity_id];
}
else {
// A previous action might have resulted in the entity being resaved
// (e.g. node synchronization from a prior node in this batch), so try
// to reload it. If no change occurred, the entity will be retrieved
// from the static cache, resulting in no performance penalty.
$entity = entity_load_single($entity_type, $entity_id);
if (empty($entity)) {
// The entity is no longer valid.
continue;
}
}
// If the current entity can't be accessed, skip it and log a notice.
if (!_views_bulk_operations_entity_access($operation, $entity_type, $entity, $account)) {
$message = 'Skipped %operation on @type %title due to insufficient permissions.';
@@ -1014,11 +1057,14 @@ function views_bulk_operations_queue_item_process($queue_item_data, &$log = NULL
$operation_context = array(
'progress' => $row['position'],
'rows' => $row['views_row'],
'view_info' => $options['view_info'],
);
if ($operation->needsRows()) {
$operation_context['rows'] = array($row_index => $row['views_row']);
}
$operation->execute($entity, $operation_context);
unset($row_group[$row_id]);
unset($row_group[$row_index]);
}
}
@@ -1055,11 +1101,11 @@ function views_bulk_operations_direct_adjust(&$selection, $vbo) {
/**
* Processes the passed rows directly (without batching and queueing).
*
* This is a legacy function that is now only used for aggregate operations.
*/
function views_bulk_operations_direct_process($operation, $rows, $options) {
@set_time_limit(0);
global $user;
drupal_set_time_limit(0);
// Prepare an array of status information. Imitates the Batch API naming
// for consistency. Passed to views_bulk_operations_execute_finished().
@@ -1067,42 +1113,56 @@ function views_bulk_operations_direct_process($operation, $rows, $options) {
$context['results']['progress'] = 0;
$context['results']['log'] = array();
$entity_type = $operation->entityType;
$entity_ids = array();
foreach ($rows as $row_index => $row) {
$entity_ids[] = $row['entity_id'];
}
$entities = _views_bulk_operations_entity_load($entity_type, $entity_ids, $options['revision']);
foreach ($entities as $id => $entity) {
if (!_views_bulk_operations_entity_access($operation, $entity_type, $entity)) {
$context['results']['log'][] = t('Skipped %operation on @type %title due to insufficient permissions.', array(
'%operation' => $operation->label(),
'@type' => $entity_type,
'%title' => _views_bulk_operations_entity_label($entity_type, $entity),
));
unset($entities[$id]);
}
}
if (empty($entities)) {
return;
}
// Pass the selected rows to the operation if needed.
$operation_context = array();
if ($operation->needsRows()) {
$operation_context['rows'] = array();
if ($operation->aggregate()) {
// Load all entities.
$entity_type = $operation->entityType;
$entity_ids = array();
foreach ($rows as $row_index => $row) {
$operation_context['rows'][$row_index] = $row['views_row'];
$entity_ids[] = $row['entity_id'];
}
$entities = _views_bulk_operations_entity_load($entity_type, $entity_ids, $options['revision']);
// Filter out entities that can't be accessed.
foreach ($entities as $id => $entity) {
if (!_views_bulk_operations_entity_access($operation, $entity_type, $entity)) {
$context['results']['log'][] = t('Skipped %operation on @type %title due to insufficient permissions.', array(
'%operation' => $operation->label(),
'@type' => $entity_type,
'%title' => _views_bulk_operations_entity_label($entity_type, $entity),
));
unset($entities[$id]);
}
}
// If there are any entities left, execute the operation on them.
if ($entities) {
$operation_context = array(
'view_info' => $options['view_info'],
);
// Pass the selected rows to the operation if needed.
if ($operation->needsRows()) {
$operation_context['rows'] = array();
foreach ($rows as $row_index => $row) {
$operation_context['rows'][$row_index] = $row['views_row'];
}
}
$operation->execute($entities, $operation_context);
}
}
$operation->execute($entities, $operation_context);
else {
// Imitate a queue and process the entities one by one.
$queue_item_data = array(
'uid' => $user->uid,
'arguments' => array($rows, $operation, $options),
);
views_bulk_operations_queue_item_process($queue_item_data, $context['results']['log']);
}
$context['results']['log'][] = t('Performed aggregate %operation on @items.', array(
$context['results']['progress'] += count($rows);
$context['results']['log'][] = t('Performed %operation on @items.', array(
'%operation' => $operation->label(),
'@items' => format_plural(count($entities), '1 item', '@count items'),
'@items' => format_plural(count($rows), '1 item', '@count items'),
));
$context['results']['progress'] += count($entities);
views_bulk_operations_execute_finished(TRUE, $context['results'], array());
}

View File

@@ -113,8 +113,9 @@ function views_bulk_operations_rules_action_info() {
*/
function views_bulk_operations_views_list() {
$selectable_displays = array();
foreach (views_get_enabled_views() as $name => $view) {
foreach ($view->display as $display_name => $display) {
foreach (views_get_enabled_views() as $name => $base_view) {
foreach ($base_view->display as $display_name => $display) {
$view = $base_view->clone_view();
$view->build($display_name);
$vbo = _views_bulk_operations_get_field($view);
if ($vbo) {
@@ -158,13 +159,12 @@ function views_bulk_operations_condition_result_count($view, $args, $minimum) {
function views_bulk_operations_action_load_list($view, $args) {
$vbo = _views_bulk_operations_rules_get_field($view, $args);
// Get all entity ids.
$ids = array();
// Get all entities, pass ids to the wrapper for lazy loading.
$entity_type = $vbo->get_entity_type();
$entities = entity_metadata_wrapper("list<$entity_type>", array());
foreach ($vbo->view->result as $row_index => $result) {
$ids[] = $vbo->get_value($result);
$entities[] = entity_metadata_wrapper($entity_type, $vbo->get_value($result));
}
// And load the entity objects.
$entities = entity_load($vbo->get_entity_type(), $ids);
return array('entity_list' => $entities);
}

View File

@@ -53,7 +53,7 @@ class views_php_plugin_access extends views_plugin_access {
*/
function access($account) {
if (!empty($this->options['php_access'])) {
return views_php_check_access($this->options['php_access'], $this->view->name, $this->view->current_display, $account);
return views_php_check_access($this->options['php_access'], $this->view->name, $this->display->id, $account);
}
return TRUE;
}
@@ -63,7 +63,7 @@ class views_php_plugin_access extends views_plugin_access {
*/
function get_access_callback() {
if (!empty($this->options['php_access'])) {
return array('views_php_check_access', array($this->options['php_access'], $this->view->name, $this->view->current_display));
return array('views_php_check_access', array($this->options['php_access'], $this->view->name, $this->display->id));
}
return TRUE;
}

View File

@@ -43,6 +43,13 @@ class views_php_plugin_cache extends views_plugin_cache {
);
}
/**
* Implements views_plugin#options_submit()
*/
function options_submit(&$form, &$form_state) {
$form_state['values']['cache_options'] += $form_state['values']['options'];
}
/**
* Implements views_plugin_cache#cache_get()
*/

View File

@@ -15,9 +15,9 @@ files[] = plugins/views/views_php_plugin_pager.inc
files[] = plugins/views/views_php_plugin_query.inc
files[] = plugins/views/views_php_plugin_wrapper.inc
; Information added by drupal.org packaging script on 2013-09-11
version = "7.x-1.x-dev"
; Information added by Drupal.org packaging script on 2014-05-08
version = "7.x-1.0-alpha1+2-dev"
core = "7.x"
project = "views_php"
datestamp = "1378900545"
datestamp = "1399543127"

View File

@@ -41,6 +41,7 @@ function views_php_views_plugins() {
'php' => array(
'title' => t('PHP'),
'help' => t('Use PHP code to grant access.'),
'help topic' => '',
'handler' => 'views_php_plugin_access',
'uses options' => TRUE,
),
@@ -49,6 +50,7 @@ function views_php_views_plugins() {
'php' => array(
'title' => t('PHP'),
'help' => t('Use PHP code to determine whether a should be cached.'),
'help topic' => '',
'handler' => 'views_php_plugin_cache',
'uses options' => TRUE,
),