Merge branch '8.x' of git.drupal.org:project/drupal into 8.x

8.0.x
Dries 2012-11-21 12:57:09 -05:00
commit 8ca44a65d1
10 changed files with 456 additions and 12 deletions

View File

@ -0,0 +1,44 @@
<?php
/**
* @file
* Provides views data and handlers for action.module.
*
* @ingroup views_module_handlers
*/
/**
* Implements hook_views_data().
*
* @todo hook_views_data() is used instead of hook_views_data_alter(), because
* the alter hook doesn't load the *.views.inc automatically.
*/
function action_views_data() {
$data['views']['action_bulk_form'] = array(
'title' => t('Actions bulk form'),
'help' => t('Add a form element that lets you apply actions to multiple items.'),
'field' => array(
'id' => 'action_bulk_form',
),
);
return $data;
}
/**
* Implements hook_views_form_substitutions().
*/
function action_views_form_substitutions() {
// Views check_plains the column label, so by doing it matches for the
// replacement.
$select_all_placeholder = check_plain('<!--action-bulk-form-select-all-->');
$select_all = array(
'#type' => 'checkbox',
'#default_value' => FALSE,
'#attributes' => array('class' => array('action-table-select-all')),
);
return array(
$select_all_placeholder => drupal_render($select_all),
);
}

View File

@ -0,0 +1,127 @@
<?php
/**
* @file
* Contains \Drupal\action\Plugin\views\field\BulkForm.
*/
namespace Drupal\action\Plugin\views\field;
use Drupal\Core\Annotation\Plugin;
use Drupal\views\Plugin\views\field\FieldPluginBase;
/**
* Defines a simple bulk operation form element.
*
* @Plugin(
* id = "action_bulk_form",
* module = "action"
* )
*/
class BulkForm extends FieldPluginBase {
/**
* Overrides \Drupal\views\Plugin\views\Plugin\field\FieldPluginBase::render().
*/
public function render($values) {
return '<!--form-item-' . $this->options['id'] . '--' . $this->view->row_index . '-->';
}
/**
* Overrides \Drupal\views\Plugin\views\Plugin\field\FieldPluginBase::pre_render().
*/
public function pre_render(&$values) {
parent::pre_render($values);
// If the view is using a table style, provide a placeholder for a
// "select all" checkbox.
if (!empty($this->view->style_plugin) && $this->view->style_plugin instanceof \Drupal\views\Plugin\views\style\Table) {
// Add the tableselect css classes.
$this->options['element_label_class'] .= 'select-all';
// Hide the actual label of the field on the table header.
$this->options['label'] = '';
}
}
/**
* Implements \Drupal\views\Plugin\views\Plugin\field\FieldPluginBase::views_form().
*/
public function views_form(&$form, &$form_state) {
// Add the tableselect javascript.
$form['#attached']['library'][] = array('system', 'drupal.tableselect');
// Render checkboxes for all rows.
foreach ($this->view->result as $row_index => $row) {
$entity_id = $this->get_value($row);
$form[$this->options['id']][$row_index] = array(
'#type' => 'checkbox',
'#default_value' => FALSE,
);
}
$form[$this->options['id']]['#tree'] = TRUE;
// Get all available actions.
$actions = action_get_all_actions();
$entity_type = $this->getEntityType();
// Filter actions by the entity type and build options for the form.
$actions = array_filter($actions, function($action) use ($entity_type) {
return $action['type'] == $entity_type && empty($action['configurable']);
});
$options = array_map(function($action) {
return $action['label'];
}, $actions);
$form['action'] = array(
'#type' => 'select',
'#title' => t('Action'),
'#options' => $options,
'#description' => t('Select the action you want to execute on the content entitites.'),
);
// Move the submit button beside the selection.
$form['actions']['#weight'] = 1;
// Replace the text with Update.
$form['actions']['submit']['#value'] = t('Update');
// Put the submit button both at the top and bottom.
$form['actions_bottom'] = $form['actions'];
$form['actions_bottom']['#weight'] = 100;
}
/**
* Implements \Drupal\views\Plugin\views\Plugin\field\FieldPluginBase::views_form_submit().
*/
public function views_form_submit(&$form, &$form_state) {
if ($form_state['step'] == 'views_form_views_form') {
$action = $form_state['values']['action'];
$action = action_load($action);
$count = 0;
// Filter only selected checkboxes.
$selected = array_filter($form_state['values'][$this->options['id']]);
if (!empty($selected)) {
foreach (array_keys($selected) as $row_index) {
$entity = $this->get_entity($this->view->result[$row_index]);
actions_do($action->aid, $entity);
$entity->save();
$count++;
}
}
if ($count) {
drupal_set_message(t('%action action performed on %count item(s).', array('%action' => $action->label, '%count' => $count)));
}
}
}
/**
* Overrides \Drupal\views\Plugin\views\Plugin\field\FieldPluginBase::query().
*/
public function query() {
}
}

View File

@ -0,0 +1,83 @@
<?php
/**
* @file
* Contains \Drupal\action\Tests\BulkFormTest.
*/
namespace Drupal\action\Tests;
use Drupal\simpletest\WebTestBase;
/**
* Tests the views bulk form test.
*
* @see \Drupal\action\Plugin\views\field\BulkForm
*/
class BulkFormTest extends WebTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('action_bulk_test');
public static function getInfo() {
return array(
'name' => 'Bulk form',
'description' => 'Tests the views bulk form test.',
'group' => 'Action',
);
}
/**
* Tests the bulk form.
*/
public function testBulkForm() {
$nodes = array();
for ($i = 0; $i < 10; $i++) {
$nodes[] = $this->drupalCreateNode(array('sticky' => FALSE));
}
$this->drupalGet('test_bulk_form');
$this->assertFieldById('edit-action', NULL, 'The action select field appears.');
// Make sure a checkbox appears on all rows.
$edit = array();
for ($i = 0; $i < 10; $i++) {
$this->assertFieldById('edit-bulk-form-' . $i, NULL, format_string('The checkbox on row @row appears.', array('@row' => $i)));
$edit["bulk_form[$i]"] = TRUE;
}
// Set all nodes to sticky and check that.
$edit += array('action' => 'node_make_sticky_action');
$this->drupalPost(NULL, $edit, t('Update'));
foreach ($nodes as $node) {
$changed_node = node_load($node->id());
$this->assertTrue($changed_node->sticky, format_string('Node @nid got marked as sticky.', array('@nid' => $node->id())));
}
$this->assertText('Make content sticky action performed on 10 item(s).');
// Unpublish just one node.
$node = node_load($nodes[0]->id());
$this->assertTrue($node->status, 'The node is published.');
$edit = array('bulk_form[0]' => TRUE, 'action' => 'node_unpublish_action');
$this->drupalPost(NULL, $edit, t('Update'));
$this->assertText('Unpublish content action performed on 1 item(s).');
// Load the node again.
$node = node_load($node->id(), TRUE);
$this->assertFalse($node->status, 'A single node has been unpublished.');
// The second node should still be published.
$node = node_load($nodes[1]->id(), TRUE);
$this->assertTrue($node->status, 'An unchecked node is still published.');
}
}

View File

@ -0,0 +1,8 @@
name = Action bulk form test
description = Support module for action bulk form testing.
package = Testing
version = VERSION
core = 8.x
hidden = TRUE
dependencies[] = action
dependencies[] = views

View File

@ -0,0 +1 @@
<?php

View File

@ -0,0 +1,149 @@
base_table: node
name: test_bulk_form
description: ''
tag: ''
human_name: form
core: 8.x
api_version: '3.0'
display:
default:
display_plugin: default
id: default
display_title: Master
position: ''
display_options:
access:
type: perm
cache:
type: none
query:
type: views_query
exposed_form:
type: basic
pager:
type: full
options:
items_per_page: '10'
style:
type: table
options:
grouping: { }
row_class: ''
default_row_class: '1'
row_class_special: '1'
override: '1'
sticky: '0'
summary: ''
columns:
title: title
action_bulk_form: action_bulk_form
info:
title:
sortable: '0'
default_sort_order: asc
align: ''
separator: ''
empty_column: '0'
responsive: ''
bulk_form:
align: ''
separator: ''
empty_column: '0'
responsive: ''
default: '-1'
empty_table: '0'
row:
type: fields
fields:
title:
id: title
table: node
field: title
label: ''
alter:
alter_text: '0'
make_link: '0'
absolute: '0'
trim: '0'
word_boundary: '0'
ellipsis: '0'
strip_tags: '0'
html: '0'
hide_empty: '0'
empty_zero: '0'
link_to_node: '1'
bulk_form:
id: action_bulk_form
table: views
field: action_bulk_form
relationship: none
group_type: group
admin_label: ''
label: 'Bulk form'
exclude: '0'
alter:
alter_text: '0'
text: ''
make_link: '0'
path: ''
absolute: '0'
external: '0'
replace_spaces: '0'
path_case: none
trim_whitespace: '0'
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: '0'
max_length: ''
word_boundary: '1'
ellipsis: '1'
more_link: '0'
more_link_text: ''
more_link_path: ''
strip_tags: '0'
trim: '0'
preserve_tags: ''
html: '0'
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: '1'
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: '1'
empty: ''
hide_empty: '0'
empty_zero: '0'
hide_alter_empty: '1'
filters:
status:
value: '1'
table: node
field: status
id: status
expose:
operator: '0'
group: '1'
sorts:
created:
id: created
table: node
field: created
order: DESC
title: form
page_1:
display_plugin: page
id: page_1
display_title: Page
position: ''
display_options:
path: test_bulk_form
base_field: nid
disabled: '0'
module: views
langcode: und

View File

@ -62,7 +62,7 @@ class VersionTest extends ModuleTestBase {
// Testing extra version. Incompatible.
'common_test (>2.4-rc0)',
);
variable_set('dependencies', $dependencies);
state()->set('system_test.dependencies', $dependencies);
$n = count($dependencies);
for ($i = 0; $i < $n; $i++) {
$this->drupalGet('admin/modules');

View File

@ -247,11 +247,11 @@ function system_test_exit() {
function system_test_system_info_alter(&$info, $file, $type) {
// We need a static otherwise the last test will fail to alter common_test.
static $test;
if (($dependencies = variable_get('dependencies', array())) || $test) {
if (($dependencies = state()->get('system_test.dependencies')) || $test) {
if ($file->name == 'module_test') {
$info['hidden'] = FALSE;
$info['dependencies'][] = array_shift($dependencies);
variable_set('dependencies', $dependencies);
state()->set('system_test.dependencies', $dependencies);
$test = TRUE;
}
if ($file->name == 'common_test') {

View File

@ -813,6 +813,33 @@ abstract class HandlerBase extends PluginBase {
}
}
/**
* Determines the entity type used by this handler.
*
* If this handler uses a relationship, the base class of the relationship is
* taken into account.
*
* @return string
* The machine name of the entity type.
*/
public function getEntityType() {
// If the user has configured a relationship on the handler take that into
// account.
if (!empty($this->options['relationship']) && $this->options['relationship'] != 'none') {
$views_data = views_fetch_data($this->view->relationship->table);
}
else {
$views_data = views_fetch_data($this->view->storage->get('base_table'));
}
if (isset($views_data['table']['entity type'])) {
return $views_data['table']['entity type'];
}
else {
throw new \Exception(format_string('No entity type for field @field on view @view', array('@field' => $this->options['id'], '@view' => $this->view->storage->get('name'))));
}
}
/**
* Breaks x,y,z and x+y+z into an array. Numeric only.
*

View File

@ -1110,9 +1110,15 @@ function views_hook_info() {
$hooks['views_data'] = array(
'group' => 'views',
);
$hooks['views_data_alter'] = array(
'group' => 'views',
);
$hooks['views_query_substitutions'] = array(
'group' => 'views',
);
$hooks['views_form_substitutions'] = array(
'group' => 'views',
);
return $hooks;
}
@ -1641,6 +1647,14 @@ function views_form_views_form($form, &$form_state, ViewExecutable $view, $outpu
'#weight' => 50,
);
$form['actions'] = array(
'#type' => 'actions',
);
$form['actions']['submit'] = array(
'#type' => 'submit',
'#value' => t('Save'),
);
$substitutions = array();
foreach ($view->field as $field_name => $field) {
$form_element_name = $field_name;
@ -1696,15 +1710,6 @@ function views_form_views_form($form, &$form_state, ViewExecutable $view, $outpu
'#type' => 'value',
'#value' => $substitutions,
);
$form['actions'] = array(
'#type' => 'container',
'#attributes' => array('class' => array('form-actions')),
'#weight' => 100,
);
$form['actions']['submit'] = array(
'#type' => 'submit',
'#value' => t('Save'),
);
return $form;
}