View source
<?php
define('VBO_MODIFY_ACTION_ALL', '_all_');
function views_bulk_operations_modify_action_info() {
return array(
'views_bulk_operations_modify_action' => array(
'type' => 'entity',
'label' => t('Modify entity values'),
'behavior' => array(
'changes_property',
),
'configurable' => FALSE,
'vbo_configurable' => TRUE,
'triggers' => array(
'any',
),
),
);
}
function views_bulk_operations_modify_action($entity, $context) {
list(, , $bundle_name) = entity_extract_ids($context['entity_type'], $entity);
if (!empty($context['selected']['bundle_' . $bundle_name])) {
$pseudo_entity = clone $context['entities'][$bundle_name];
foreach ($context['selected']['bundle_' . $bundle_name] as $key) {
$language = key($pseudo_entity->{$key});
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,
));
}
}
}
if (in_array($key, $context['append']['bundle_' . $bundle_name]) && !empty($entity->{$key})) {
$entity->{$key}[$language] = array_merge($entity->{$key}[$language], $pseudo_entity->{$key}[$language]);
$field_info = field_info_field($key);
$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.', array(
'!field_count' => $field_count,
'!field_name' => $field_info['field_name'],
'!cardinality' => $field_info['cardinality'],
));
drupal_set_message($warning, 'warning', FALSE);
}
if (strpos($field_info['type'], 'reference') !== FALSE) {
$entity->{$key}[$language] = array_unique($entity->{$key}[LANGUAGE_NONE], SORT_REGULAR);
}
}
else {
$entity->{$key}[$language] = $pseudo_entity->{$key}[$language];
}
}
}
$wrapper = entity_metadata_wrapper($context['entity_type'], $entity);
if ($context['entity_type'] == 'node' && in_array('revision', variable_get('node_options_' . $bundle_name)) && !in_array('revision', $context['selected']['properties'])) {
$wrapper->revision
->set(1);
}
if (!empty($context['selected']['properties'])) {
foreach ($context['selected']['properties'] as $key) {
if (!$wrapper->{$key}
->access('update')) {
continue;
}
if (in_array($key, $context['append']['properties'])) {
$old_values = $wrapper->{$key}
->value();
$wrapper->{$key}
->set($context['properties'][$key]);
$new_values = $wrapper->{$key}
->value();
$all_values = array_merge($old_values, $new_values);
$wrapper->{$key}
->set($all_values);
}
else {
$value = $context['properties'][$key];
if (is_string($value)) {
$value = token_replace($value, array(
$context['entity_type'] => $entity,
), array(
'sanitize' => FALSE,
));
}
$wrapper->{$key}
->set($value);
}
}
}
}
function views_bulk_operations_modify_action_form($context, &$form_state) {
if (!isset($context['settings'])) {
$context['settings'] = views_bulk_operations_modify_action_views_bulk_operations_form_options();
}
$form_state['entity_type'] = $entity_type = $context['entity_type'];
$form_state['entities'] = array();
$info = entity_get_info($entity_type);
$properties = _views_bulk_operations_modify_action_get_properties($entity_type, $context['settings']['display_values']);
$bundles = _views_bulk_operations_modify_action_get_bundles($entity_type, $context);
$form['#attached']['css'][] = drupal_get_path('module', 'views_bulk_operations') . '/css/modify.action.css';
$form['#tree'] = TRUE;
if (!empty($properties)) {
$form['properties'] = array(
'#type' => 'fieldset',
'#title' => t('Properties'),
);
$form['properties']['show_value'] = array(
'#suffix' => '<div class="clearfix"></div>',
);
foreach ($properties as $key => $property) {
$form['properties']['show_value'][$key] = array(
'#type' => 'checkbox',
'#title' => $property['label'],
);
if (isset($property['options list'])) {
$determined_type = $property['type'] == 'list' ? 'checkboxes' : 'select';
}
else {
$determined_type = $property['type'] == 'boolean' ? 'checkbox' : 'textfield';
}
$form['properties'][$key] = array(
'#type' => $determined_type,
'#title' => $property['label'],
'#description' => $property['description'],
'#states' => array(
'visible' => array(
'#edit-properties-show-value-' . str_replace('_', '-', $key) => array(
'checked' => TRUE,
),
),
),
);
if ($determined_type == 'textfield') {
$form['properties'][$key]['#maxlength'] = 255;
}
if (!empty($property['options list']) && is_callable($property['options list'])) {
$form['properties'][$key]['#type'] = 'select';
$form['properties'][$key]['#options'] = call_user_func_array($property['options list'], array(
$key,
array(),
));
if ($property['type'] == 'list') {
$form['properties'][$key]['#type'] = 'checkboxes';
$form['properties']['_append::' . $key] = array(
'#type' => 'checkbox',
'#title' => t('Add new value(s) to %label, instead of overwriting the existing values.', array(
'%label' => $property['label'],
)),
'#states' => array(
'visible' => array(
'#edit-properties-show-value-' . $key => array(
'checked' => TRUE,
),
),
),
);
}
}
}
}
global $language;
foreach ($bundles as $bundle_name => $bundle) {
$bundle_key = $info['entity keys']['bundle'];
$default_values = array();
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;
if (count($info['bundles']) > 1) {
$label = t('Fields for @bundle_key @label', array(
'@bundle_key' => $bundle_key,
'@label' => $bundle['label'],
));
}
else {
$label = t('Fields');
}
$form_key = 'bundle_' . $bundle_name;
$form[$form_key] = array(
'#type' => 'fieldset',
'#title' => $label,
'#parents' => array(
$form_key,
),
);
field_attach_form($context['entity_type'], $entity, $form[$form_key], $form_state, entity_language($context['entity_type'], $entity));
uasort($form[$form_key], 'element_sort');
$display_values = $context['settings']['display_values'];
$instances = field_info_instances($entity_type, $bundle_name);
$weight = 0;
foreach (element_get_visible_children($form[$form_key]) as $field_name) {
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]);
}
if (empty($display_values[VBO_MODIFY_ACTION_ALL]) && empty($display_values[$bundle_name . '::' . $field_name])) {
$form[$form_key][$field_name]['#access'] = FALSE;
continue;
}
if (isset($instances[$field_name])) {
$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,
),
),
);
$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++,
);
}
}
}
$form[$form_key]['show_value']['#suffix'] = '<div class="clearfix"></div>';
$form[$form_key]['show_value']['#weight'] = -1;
}
$form_elements = element_get_visible_children($form);
if (count($form_elements) == 1) {
$element_key = reset($form_elements);
unset($form[$element_key]['#type']);
unset($form[$element_key]['#title']);
$values = element_get_visible_children($form[$element_key]);
foreach ($values as $index => $key) {
if ($key == 'show_value' || substr($key, 0, 1) == '_') {
unset($values[$index]);
}
}
if (count($values) == 1) {
$value_key = reset($values);
$form[$element_key]['show_value'][$value_key]['#type'] = 'value';
$form[$element_key]['show_value'][$value_key]['#value'] = TRUE;
}
}
if (module_exists('token') && $context['settings']['show_all_tokens']) {
$token_type = str_replace('_', '-', $entity_type);
$form['tokens'] = array(
'#type' => 'fieldset',
'#title' => t('Available tokens'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#weight' => 998,
);
$form['tokens']['tree'] = array(
'#theme' => 'token_tree',
'#token_types' => array(
$token_type,
'site',
),
'#global_types' => array(),
'#dialog' => TRUE,
);
}
return $form;
}
function views_bulk_operations_modify_action_validate($form, &$form_state) {
$search = array(
'properties',
);
foreach ($form_state['entities'] as $bundle => $entity) {
$search[] = 'bundle_' . $bundle;
}
$has_selected = FALSE;
foreach ($search as $group) {
$form_state['selected'][$group] = array();
$form_state['append'][$group] = array();
if (!isset($form_state['values'][$group])) {
continue;
}
foreach ($form_state['values'][$group]['show_value'] as $key => $value) {
if ($value) {
$has_selected = TRUE;
$form_state['selected'][$group][] = $key;
}
if (!empty($form_state['values'][$group]['_append::' . $key])) {
$form_state['append'][$group][] = $key;
unset($form_state['values'][$group]['_append::' . $key]);
}
}
unset($form_state['values'][$group]['show_value']);
}
if (!$has_selected) {
form_set_error('', t('You must select at least one value to modify.'));
return;
}
if (!empty($form_state['selected']['properties'])) {
$info = entity_get_info($form_state['entity_type']);
$bundle_key = $info['entity keys']['bundle'];
$default_values = array();
if (!empty($bundle_key)) {
$bundle_names = array_keys($info['bundles']);
$bundle_name = reset($bundle_names);
$default_values[$bundle_key] = $bundle_name;
}
$entity = entity_create($form_state['entity_type'], $default_values);
$wrapper = entity_metadata_wrapper($form_state['entity_type'], $entity);
$properties = _views_bulk_operations_modify_action_get_properties($form_state['entity_type']);
foreach ($form_state['selected']['properties'] as $key) {
$value = $form_state['values']['properties'][$key];
if (!$wrapper->{$key}
->validate($value)) {
$label = $properties[$key]['label'];
form_set_error('properties][' . $key, t('%label contains an invalid value.', array(
'%label' => $label,
)));
}
}
}
foreach ($form_state['entities'] as $bundle_name => $entity) {
field_attach_form_validate($form_state['entity_type'], $entity, $form['bundle_' . $bundle_name], $form_state);
}
}
function views_bulk_operations_modify_action_submit($form, $form_state) {
foreach ($form_state['entities'] as $bundle_name => $entity) {
field_attach_submit($form_state['entity_type'], $entity, $form['bundle_' . $bundle_name], $form_state);
}
return array(
'append' => $form_state['append'],
'selected' => $form_state['selected'],
'entities' => $form_state['entities'],
'properties' => isset($form_state['values']['properties']) ? $form_state['values']['properties'] : array(),
);
}
function _views_bulk_operations_modify_action_get_properties($entity_type, $display_values = NULL) {
$properties = array();
$info = entity_get_info($entity_type);
$disabled_properties = array(
'created',
'changed',
);
foreach (array(
'id',
'bundle',
'revision',
) as $key) {
if (!empty($info['entity keys'][$key])) {
$disabled_properties[] = $info['entity keys'][$key];
}
}
$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'])) {
return array();
}
foreach ($property_info['properties'] as $key => $property) {
if (in_array($key, $disabled_properties)) {
continue;
}
if (empty($property['setter callback'])) {
continue;
}
$property['type'] = empty($property['type']) ? 'text' : $property['type'];
$type = $property['type'];
if ($list_type = entity_property_list_extract_type($type)) {
$type = $list_type;
$property['type'] = 'list';
}
if (!in_array($type, $supported_types)) {
continue;
}
$properties[$key] = $property;
}
if (isset($display_values) && empty($display_values[VBO_MODIFY_ACTION_ALL])) {
return array_intersect_key($properties, $display_values);
}
return $properties;
}
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'];
$filtered_bundles = array_keys($info['bundles']);
foreach ($view->filter as $key => $filter) {
if ($filter->table == $vbo->table && $filter->field == $bundle_key) {
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) {
if (!in_array($bundle_name, $filtered_bundles)) {
continue;
}
$instances = field_info_instances($entity_type, $bundle_name);
if (empty($instances)) {
continue;
}
$has_enabled_fields = FALSE;
foreach ($display_values as $key) {
if (strpos($key, $bundle_name . '::') === 0) {
$has_enabled_fields = TRUE;
}
}
if (!empty($display_values[VBO_MODIFY_ACTION_ALL]) || $has_enabled_fields) {
$bundles[$bundle_name] = $bundle;
}
}
return $bundles;
}
function _views_bulk_operations_modify_action_unset_required(&$element) {
$element['#required'] = FALSE;
foreach (element_children($element) as $key) {
_views_bulk_operations_modify_action_unset_required($element[$key]);
}
}
function views_bulk_operations_modify_action_views_bulk_operations_form_options() {
$options['show_all_tokens'] = TRUE;
$options['display_values'] = array(
VBO_MODIFY_ACTION_ALL,
);
return $options;
}
function views_bulk_operations_modify_action_views_bulk_operations_form($options, $entity_type, $dom_id) {
if (empty($options)) {
$options = views_bulk_operations_modify_action_views_bulk_operations_form_options();
}
$form['show_all_tokens'] = array(
'#type' => 'checkbox',
'#title' => t('Show available tokens'),
'#description' => t('Check this to show a list of all available tokens in the bottom of the form. Requires the token module.'),
'#default_value' => $options['show_all_tokens'],
);
$info = entity_get_info($entity_type);
$properties = _views_bulk_operations_modify_action_get_properties($entity_type);
$values = array(
VBO_MODIFY_ACTION_ALL => t('- All -'),
);
foreach ($properties as $key => $property) {
$label = t('Properties');
$values[$label][$key] = $property['label'];
}
foreach ($info['bundles'] as $bundle_name => $bundle) {
$bundle_key = $info['entity keys']['bundle'];
if (count($info['bundles']) > 1) {
$label = t('Fields for @bundle_key @label', array(
'@bundle_key' => $bundle_key,
'@label' => $bundle['label'],
));
}
else {
$label = t('Fields');
}
$instances = field_info_instances($entity_type, $bundle_name);
foreach ($instances as $field_name => $field) {
$values[$label][$bundle_name . '::' . $field_name] = $field['label'];
}
}
$form['display_values'] = array(
'#type' => 'select',
'#title' => t('Display values'),
'#options' => $values,
'#multiple' => TRUE,
'#description' => t('Select which values the action form should present to the user.'),
'#default_value' => $options['display_values'],
'#size' => 10,
);
return $form;
}