more module updates
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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"
|
||||
|
||||
|
@@ -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)) {
|
||||
|
@@ -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();
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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"
|
||||
|
||||
|
@@ -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());
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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()
|
||||
*/
|
||||
|
@@ -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"
|
||||
|
||||
|
@@ -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,
|
||||
),
|
||||
|
Reference in New Issue
Block a user