updated contrib modules : translation_views, views_bulk_edit, views_bulk_operations, workflow, addtoany, redis, url_to_video_filter

This commit is contained in:
2018-09-12 14:51:18 +02:00
parent 4caa864a8f
commit b8e8cc8cee
99 changed files with 4762 additions and 954 deletions
@@ -1,19 +1,21 @@
Translation View
Translation Views
=============
## Description:
INTRODUCTION
------------
Provides fields and filter for views to display information about the current row, the **source** translation, in another **target** language. You can also add translation operation links to decide if you want to add/edit the content in the target language.
Configurations for a demo view is impored on installation, named `Content translation jobs` which can be found at path `/translate/content`. If you want to get view for other translatable entities, you should build it yourself using our fields/filters.
Configurations for a demo view is imported on installation, named `Content translation jobs` which can be found at path `/translate/content`. If you want to get view for other translatable entities, you should build it yourself using our fields/filters.
**Notice**: This module provides view's fields/filters only for translatble entity types, this means that until you have enabled content translation support for an entity you'll not get provided any extra fields/filters. The content translations can be enabled at path `admin/config/regional/content-language`
**Notice**: This module provides view's fields/filters only for translatable entity types, this means that until you have enabled content translation support for an entity you'll not get provided any extra fields/filters. The content translations can be enabled at path `admin/config/regional/content-language`
## Features
FEATURES
------------
**Target translation**
- Target language: `field`,`filter`. Should in most cases be an exposed filter.
Also there is an extra filter option: *Remove rows where source language is equal to target language*
Also, there is an extra filter option: *Remove rows where source language is equal to target language*
These fields/filters will display information about the current content in the selected target language:
- Translation outdated: `field`,`filter`
@@ -26,17 +28,23 @@ These fields/filters will display information about the current content in the s
**Source translation**
- Translation counter: `field`,`filter`
## Requirements:
REQUIREMENTS
------------
- Drupal 8
- PHP 5.6+
- PHP 7+
## Installation:
INSTALLATION
------------
Install module as usually.
### Demo view: Content translation jobs:
Upon installation a new view is added named `Content translation jobs` that demonstrate how the fields/filters can be used to create lists of translation jobs. Available at path `/translate/content`.
CONFIGURATION
-------------
No configuration is needed.
If this didn't happened on installation than go to the`admin/config/development/configuration/single/import` and manually import config from the file located in the module folder at: `config/optional/views.view.content_translations.yml`.
### Demo view: Content translation jobs:
Upon installation, a new view is added named `Content translation jobs` that demonstrate how the fields/filters can be used to create lists of translation jobs. Available at path `/translate/content`.
If this didn't happened on installation then go to the`admin/config/development/configuration/single/import` and manually import config from the file located in the module folder at: `config/optional/views.view.content_translations.yml`.
**Fields**
The view display:
@@ -57,9 +65,10 @@ Exposed filters:
Hidden filters
- Source content outdated must be false: Make sure you do not translation from outdated nodes.
- Target language equals default language must be false: As there is no use to check status of original language as a target language.
- The target language must be untranslated or outdated: Make sure translated and updated content disapear from the list.
- The target language must be untranslated or outdated: Make sure translated and updated content disappear from the list.
- The target language must be untranslated or the same as the source language of translation: This makes sure that once there is a translation in target language it will only be displayed if the source language is the correct source language. If target language is not translated you can use different language as source translation.
## Credits
MAINTAINERS
-----------
Developed by [vlad.dancer](https://drupal.org/u/vladdancer)
Designed by [matsbla](https://drupal.org/u/matsbla)
@@ -297,7 +297,7 @@ display:
hide_empty: false
empty_zero: false
hide_alter_empty: true
native_language: 0
native_language: false
entity_type: node
plugin_id: translation_views_target_language
translation_outdated:
@@ -600,7 +600,7 @@ display:
group_type: group
admin_label: ''
operator: '='
value: { }
value: ''
group: 1
exposed: true
expose:
@@ -629,7 +629,7 @@ display:
default_group: All
default_group_multiple: { }
group_items: { }
remove: 1
remove: true
entity_type: node
plugin_id: translation_views_target_language
translation_outdated:
@@ -679,12 +679,12 @@ display:
group_type: group
admin_label: ''
operator: '='
value: '2'
value: 2
group: 1
exposed: true
expose:
operator_id: ''
label: Translation status
label: 'Translation status'
description: ''
use_operator: false
operator: translation_status_op
@@ -708,7 +708,6 @@ display:
default_group: All
default_group_multiple: { }
group_items: { }
translation_target_language: false
entity_type: node
plugin_id: translation_views_status
translation_default:
@@ -755,7 +754,7 @@ display:
group_type: group
admin_label: ''
operator: '='
value: '0'
value: 0
group: 2
exposed: false
expose:
@@ -828,7 +827,7 @@ display:
group_type: group
admin_label: ''
operator: '='
value: '0'
value: 0
group: 3
exposed: false
expose:
@@ -4,3 +4,47 @@ views.filter.translation_views_translation_count:
views.filter_value.translation_views_translation_count:
type: views.filter_value.numeric
label: 'Filter rows by amount of translations (without default language)'
views.filter.translation_views_source_equals_row:
type: views.filter.boolean
value: 'A boolean indicating whether the translation source of target language is same as the row language'
views.filter.translation_views_status:
type: views_filter
label: 'A value indicating whether the node is translated into target language'
mapping:
value:
type: integer
label: 'Value'
views.filter.translation_views_target_language:
type: views_filter
label: 'Target language'
mapping:
value:
type: string
label: 'Value'
remove:
type: boolean
label: 'Remove rows where source language is equal to target language'
views.field.translation_views_translation_count:
type: views.field.numeric
label: 'Amount of translations (without default language)'
views.field.translation_views_operations:
type: views_field
label: 'Provides links to perform translation operations'
views.field.translation_views_source_equals_row:
type: views.field.boolean
label: 'A boolean indicating whether the translation source of target language is same as the row language'
views.field.translation_views_status:
type: views.field.boolean
label: 'A boolean indicating whether the node is translated into target language'
views.field.translation_views_target_language:
type: views.field.language
label: 'The target language'
@@ -19,6 +19,13 @@ use Drupal\views\Plugin\ViewsHandlerManager;
class TranslationCountField extends NumericField implements ContainerFactoryPluginInterface {
use TranslationCountTrait;
/**
* Translation table alias.
*
* @var string
*/
public $tableAlias = 'translations';
/**
* {@inheritdoc}
*/
@@ -37,7 +37,7 @@ class TranslationSourceLangcodeEqualsRowLangcodeField extends Boolean {
*/
public function query() {
$table_alias = $this->ensureMyTable();
$base_table = $this->view->storage->get('base_table');
$base_table = $this->view->storage->get('base_table');
$this->query->addField(
NULL,
@@ -92,4 +92,4 @@ class TranslationStatus extends Boolean implements ContainerFactoryPluginInterfa
);
}
}
}
@@ -21,6 +21,13 @@ use Drupal\views\Plugin\ViewsHandlerManager;
class TranslationCountFilter extends NumericFilter implements ContainerFactoryPluginInterface {
use TranslationCountTrait;
/**
* Translation table alias.
*
* @var string
*/
public $tableAlias = 'translations';
/**
* {@inheritdoc}
*/
@@ -18,7 +18,7 @@ class TranslationSourceLangcodeEqualsRowLangcodeFilter extends BooleanOperator {
*/
public function query() {
$table_alias = $this->ensureMyTable();
$base_table = $this->view->storage->get('base_table');
$base_table = $this->view->storage->get('base_table');
$this->query->addWhereExpression(
$this->options['group'],
@@ -21,12 +21,15 @@ class TranslationLanguageJoin extends JoinPluginBase implements ContainerFactory
*/
protected $database;
protected $eid;
/**
* {@inheritdoc}
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, Connection $database) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->database = $database;
$this->eid = $this->configuration['entity_pk'];
}
/**
@@ -45,21 +48,20 @@ class TranslationLanguageJoin extends JoinPluginBase implements ContainerFactory
* {@inheritdoc}
*/
public function buildJoin($select_query, $table, $view_query) {
$query = $this->database->select($this->table, 'nfd');
$query->fields('nfd', ['nid']);
$query = $this->database->select($this->table, 'efd');
$query->fields('efd', [$this->eid]);
if (!empty($this->configuration['langcodes_as_count'])) {
$query->addExpression("COUNT(nfd.langcode)", 'count_langs');
$query->addExpression("COUNT(efd.langcode)", 'count_langs');
}
else {
$query->addExpression("GROUP_CONCAT(nfd.langcode separator ',')", 'langs');
$query->addExpression("GROUP_CONCAT(efd.langcode separator ',')", 'langs');
}
if (!empty($this->configuration['exclude_default_langcode'])) {
$query->where('nfd.default_langcode != 1');
$query->where('efd.default_langcode != 1');
}
$query->groupBy('nfd.nid');
$query->groupBy('efd.' . $this->eid);
$this->configuration['table formula'] = $query;
parent::buildJoin($select_query, $table, $view_query);
@@ -12,13 +12,6 @@ use Drupal\views\Plugin\views\query\Sql as ViewsSqlQuery;
*/
trait TranslationCountTrait {
/**
* Translation table alias.
*
* @var string
*/
protected $tableAlias = 'translations';
/**
* Ensure that translations table is joined.
*
@@ -43,6 +36,7 @@ trait TranslationCountTrait {
'left_table' => $query_base_table,
'exclude_default_langcode' => TRUE,
'langcodes_as_count' => TRUE,
'entity_pk' => $keys['id'],
];
$tableAlias = $query->ensureTable($query_base_table, $this->relationship);
@@ -0,0 +1,996 @@
langcode: en
status: true
dependencies:
module:
- comment
- node
- translation_views
- user
id: comment_translation
label: 'Comment translation'
module: views
description: ''
tag: ''
base_table: comment_field_data
base_field: cid
core: 8.x
display:
default:
display_plugin: default
id: default
display_title: Master
position: 0
display_options:
access:
type: perm
options:
perm: 'access comments'
cache:
type: tag
options: { }
query:
type: views_query
options:
disable_sql_rewrite: false
distinct: false
replica: false
query_comment: ''
query_tags: { }
exposed_form:
type: basic
options:
submit_button: Apply
reset_button: false
reset_button_label: Reset
exposed_sorts_label: 'Sort by'
expose_sort_order: true
sort_asc_label: Asc
sort_desc_label: Desc
pager:
type: mini
options:
items_per_page: 10
offset: 0
id: 0
total_pages: null
expose:
items_per_page: false
items_per_page_label: 'Items per page'
items_per_page_options: '5, 10, 25, 50'
items_per_page_options_all: false
items_per_page_options_all_label: '- All -'
offset: false
offset_label: Offset
tags:
previous: ‹‹
next: ››
style:
type: table
options:
grouping: { }
row_class: ''
default_row_class: true
override: true
sticky: false
caption: ''
summary: ''
description: ''
columns:
subject: subject
langcode: langcode
translation_target_language: translation_target_language
translation_default: translation_default
translation_changed: translation_changed
translation_count: translation_count
translation_operations: translation_operations
translation_outdated: translation_outdated
translation_source: translation_source
translation_status: translation_status
info:
subject:
sortable: true
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: ''
langcode:
sortable: true
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: ''
translation_target_language:
align: ''
separator: ''
empty_column: false
responsive: ''
translation_default:
sortable: true
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: ''
translation_changed:
sortable: true
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: ''
translation_count:
sortable: true
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: ''
translation_operations:
align: ''
separator: ''
empty_column: false
responsive: ''
translation_outdated:
sortable: true
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: ''
translation_source:
sortable: true
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: ''
translation_status:
sortable: true
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: ''
default: '-1'
empty_table: false
row:
type: fields
relationships:
node:
id: node
table: comment_field_data
field: node
entity_type: comment_field_data
required: true
plugin_id: standard
relationship: none
group_type: group
admin_label: Content
fields:
subject:
id: subject
table: comment_field_data
field: subject
relationship: none
group_type: group
admin_label: ''
label: Title
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: false
ellipsis: false
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
click_sort_column: value
type: string
settings:
link_to_entity: false
group_column: value
group_columns: { }
group_rows: true
delta_limit: 0
delta_offset: 0
delta_reversed: false
delta_first_last: false
multi_type: separator
separator: ', '
field_api_classes: false
entity_type: comment
entity_field: subject
plugin_id: field
langcode:
id: langcode
table: comment_field_data
field: langcode
relationship: none
group_type: group
admin_label: ''
label: 'Translation language'
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
click_sort_column: value
type: language
settings:
link_to_entity: false
native_language: false
group_column: value
group_columns: { }
group_rows: true
delta_limit: 0
delta_offset: 0
delta_reversed: false
delta_first_last: false
multi_type: separator
separator: ', '
field_api_classes: false
entity_type: comment
entity_field: langcode
plugin_id: field
translation_target_language:
id: translation_target_language
table: comment_translation
field: translation_target_language
relationship: none
group_type: group
admin_label: ''
label: 'Target language'
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
native_language: false
entity_type: comment
plugin_id: translation_views_target_language
translation_default:
id: translation_default
table: comment_translation_target
field: translation_default
relationship: none
group_type: group
admin_label: ''
label: 'Target language equals default language'
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
type: yes-no
type_custom_true: ''
type_custom_false: ''
not: false
entity_field: default_langcode
plugin_id: boolean
translation_changed:
id: translation_changed
table: comment_translation_target
field: translation_changed
relationship: none
group_type: group
admin_label: ''
label: 'Translation changed time'
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
date_format: fallback
custom_date_format: ''
timezone: ''
entity_field: changed
plugin_id: date
translation_count:
id: translation_count
table: comment_translation
field: translation_count
relationship: none
group_type: group
admin_label: ''
label: 'Translation counter'
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
set_precision: false
precision: 0
decimal: .
separator: ','
format_plural: false
format_plural_string: !!binary MQNAY291bnQ=
prefix: ''
suffix: ''
entity_type: comment
plugin_id: translation_views_translation_count
translation_outdated:
id: translation_outdated
table: comment_translation_target
field: translation_outdated
relationship: none
group_type: group
admin_label: ''
label: 'Translation outdated'
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
type: yes-no
type_custom_true: ''
type_custom_false: ''
not: false
entity_field: content_translation_outdated
plugin_id: boolean
translation_source:
id: translation_source
table: comment_translation_target
field: translation_source
relationship: none
group_type: group
admin_label: ''
label: 'Translation source equals row language'
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
type: yes-no
type_custom_true: ''
type_custom_false: ''
not: false
entity_field: content_translation_source
plugin_id: translation_views_source_equals_row
translation_status:
id: translation_status
table: comment_translation
field: translation_status
relationship: none
group_type: group
admin_label: ''
label: 'Translation status'
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
type: status
type_custom_true: ''
type_custom_false: ''
not: false
entity_type: comment
plugin_id: translation_views_status
translation_operations:
id: translation_operations
table: comment_translation
field: translation_operations
relationship: none
group_type: group
admin_label: ''
label: 'Translation operations'
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
destination: false
entity_type: comment
plugin_id: translation_views_operations
filters:
status:
value: '1'
table: comment_field_data
field: status
plugin_id: boolean
entity_type: comment
entity_field: status
id: status
expose:
operator: ''
group: 1
status_node:
value: '1'
table: node_field_data
field: status
plugin_id: boolean
relationship: node
entity_type: node
entity_field: status
id: status_node
expose:
operator: ''
group: 1
langcode:
id: langcode
table: comment_field_data
field: langcode
relationship: none
group_type: group
admin_label: ''
operator: in
value: { }
group: 1
exposed: true
expose:
operator_id: langcode_op
label: 'Translation language'
description: ''
use_operator: false
operator: langcode_op
identifier: langcode
required: false
remember: false
multiple: false
remember_roles:
authenticated: authenticated
anonymous: '0'
administrator: '0'
reduce: false
is_grouped: false
group_info:
label: ''
description: ''
identifier: ''
optional: true
widget: select
multiple: false
remember: false
default_group: All
default_group_multiple: { }
group_items: { }
entity_type: comment
entity_field: langcode
plugin_id: language
translation_target_language:
id: translation_target_language
table: comment_translation
field: translation_target_language
relationship: none
group_type: group
admin_label: ''
operator: '='
value: '***LANGUAGE_site_default***'
group: 1
exposed: true
expose:
operator_id: ''
label: 'Target language'
description: ''
use_operator: false
operator: translation_target_language_op
identifier: translation_target_language
required: false
remember: false
multiple: false
remember_roles:
authenticated: authenticated
anonymous: '0'
administrator: '0'
is_grouped: false
group_info:
label: ''
description: ''
identifier: ''
optional: true
widget: select
multiple: false
remember: false
default_group: All
default_group_multiple: { }
group_items: { }
remove: false
entity_type: comment
plugin_id: translation_views_target_language
translation_outdated:
id: translation_outdated
table: comment_translation_target
field: translation_outdated
relationship: none
group_type: group
admin_label: ''
operator: '='
value: All
group: 1
exposed: true
expose:
operator_id: ''
label: 'Translation outdated'
description: ''
use_operator: false
operator: translation_outdated_op
identifier: translation_outdated
required: false
remember: false
multiple: false
remember_roles:
authenticated: authenticated
anonymous: '0'
administrator: '0'
is_grouped: false
group_info:
label: ''
description: ''
identifier: ''
optional: true
widget: select
multiple: false
remember: false
default_group: All
default_group_multiple: { }
group_items: { }
entity_field: content_translation_outdated
plugin_id: boolean
translation_status:
id: translation_status
table: comment_translation
field: translation_status
relationship: none
group_type: group
admin_label: ''
operator: '='
value: 2
group: 1
exposed: true
expose:
operator_id: ''
label: 'Translation status'
description: ''
use_operator: false
operator: translation_status_op
identifier: translation_status
required: false
remember: false
multiple: false
remember_roles:
authenticated: authenticated
anonymous: '0'
administrator: '0'
is_grouped: false
group_info:
label: ''
description: ''
identifier: ''
optional: true
widget: select
multiple: false
remember: false
default_group: All
default_group_multiple: { }
group_items: { }
entity_type: comment
plugin_id: translation_views_status
translation_count:
id: translation_count
table: comment_translation
field: translation_count
relationship: none
group_type: group
admin_label: ''
operator: '='
value:
min: ''
max: ''
value: ''
group: 1
exposed: true
expose:
operator_id: translation_count_op
label: 'Translation counter'
description: ''
use_operator: false
operator: translation_count_op
identifier: translation_count
required: false
remember: false
multiple: false
remember_roles:
authenticated: authenticated
anonymous: '0'
administrator: '0'
placeholder: ''
min_placeholder: ''
max_placeholder: ''
is_grouped: false
group_info:
label: ''
description: ''
identifier: ''
optional: true
widget: select
multiple: false
remember: false
default_group: All
default_group_multiple: { }
group_items: { }
entity_type: comment
plugin_id: translation_views_translation_count
sorts: { }
title: 'Comment translation'
header: { }
footer: { }
empty: { }
arguments: { }
display_extenders: { }
filter_groups:
operator: AND
groups:
1: AND
cache_metadata:
max-age: -1
contexts:
- 'languages:language_content'
- 'languages:language_interface'
- url
- url.query_args
- user.permissions
tags: { }
page_1:
display_plugin: page
id: page_1
display_title: Page
position: 1
display_options:
display_extenders: { }
path: comment-translation
cache_metadata:
max-age: -1
contexts:
- 'languages:language_content'
- 'languages:language_interface'
- url
- url.query_args
- user.permissions
tags: { }
@@ -0,0 +1,924 @@
langcode: en
status: true
dependencies:
module:
- node
- translation_views
- user
id: translation_views_all_filters_and_fields
label: 'Translation views all filters and fields'
module: views
description: ''
tag: ''
base_table: node_field_data
base_field: nid
core: 8.x
display:
default:
display_plugin: default
id: default
display_title: Master
position: 0
display_options:
access:
type: perm
options:
perm: 'access content'
cache:
type: tag
options: { }
query:
type: views_query
options:
disable_sql_rewrite: false
distinct: false
replica: false
query_comment: ''
query_tags: { }
exposed_form:
type: basic
options:
submit_button: Apply
reset_button: false
reset_button_label: Reset
exposed_sorts_label: 'Sort by'
expose_sort_order: true
sort_asc_label: Asc
sort_desc_label: Desc
pager:
type: mini
options:
items_per_page: 10
offset: 0
id: 0
total_pages: null
expose:
items_per_page: false
items_per_page_label: 'Items per page'
items_per_page_options: '5, 10, 25, 50'
items_per_page_options_all: false
items_per_page_options_all_label: '- All -'
offset: false
offset_label: Offset
tags:
previous: ‹‹
next: ››
style:
type: table
options:
grouping: { }
row_class: ''
default_row_class: true
override: true
sticky: false
caption: ''
summary: ''
description: ''
columns:
title: title
langcode: langcode
translation_default: translation_default
translation_changed: translation_changed
translation_count: translation_count
translation_outdated: translation_outdated
translation_source: translation_source
translation_status: translation_status
translation_operations: translation_operations
info:
title:
sortable: true
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: ''
langcode:
sortable: true
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: ''
translation_default:
sortable: true
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: ''
translation_changed:
sortable: true
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: ''
translation_count:
sortable: true
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: ''
translation_outdated:
sortable: true
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: ''
translation_source:
sortable: true
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: ''
translation_status:
sortable: true
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: ''
translation_operations:
align: ''
separator: ''
empty_column: false
responsive: ''
default: '-1'
empty_table: false
row:
type: fields
fields:
title:
id: title
table: node_field_data
field: title
entity_type: node
entity_field: title
alter:
alter_text: false
make_link: false
absolute: false
trim: false
word_boundary: false
ellipsis: false
strip_tags: false
html: false
hide_empty: false
empty_zero: false
settings:
link_to_entity: true
plugin_id: field
relationship: none
group_type: group
admin_label: ''
label: Title
exclude: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_alter_empty: true
click_sort_column: value
type: string
group_column: value
group_columns: { }
group_rows: true
delta_limit: 0
delta_offset: 0
delta_reversed: false
delta_first_last: false
multi_type: separator
separator: ', '
field_api_classes: false
langcode:
id: langcode
table: node_field_data
field: langcode
relationship: none
group_type: group
admin_label: ''
label: 'Translation language'
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
click_sort_column: value
type: language
settings:
link_to_entity: false
native_language: false
group_column: value
group_columns: { }
group_rows: true
delta_limit: 0
delta_offset: 0
delta_reversed: false
delta_first_last: false
multi_type: separator
separator: ', '
field_api_classes: false
entity_type: node
entity_field: langcode
plugin_id: field
translation_target_language:
id: translation_target_language
table: node_translation
field: translation_target_language
relationship: none
group_type: group
admin_label: ''
label: 'Target language'
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
native_language: false
entity_type: node
plugin_id: translation_views_target_language
translation_default:
id: translation_default
table: node_translation_target
field: translation_default
relationship: none
group_type: group
admin_label: ''
label: 'Target language equals default language'
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
type: yes-no
type_custom_true: ''
type_custom_false: ''
not: false
entity_field: default_langcode
plugin_id: boolean
translation_changed:
id: translation_changed
table: node_translation_target
field: translation_changed
relationship: none
group_type: group
admin_label: ''
label: 'Translation changed time'
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
date_format: fallback
custom_date_format: ''
timezone: ''
entity_field: changed
plugin_id: date
translation_count:
id: translation_count
table: node_translation
field: translation_count
relationship: none
group_type: group
admin_label: ''
label: 'Translation counter'
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
set_precision: false
precision: 0
decimal: .
separator: ','
format_plural: false
format_plural_string: !!binary MQNAY291bnQ=
prefix: ''
suffix: ''
entity_type: node
plugin_id: translation_views_translation_count
translation_outdated:
id: translation_outdated
table: node_translation_target
field: translation_outdated
relationship: none
group_type: group
admin_label: ''
label: 'Translation outdated'
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
type: yes-no
type_custom_true: ''
type_custom_false: ''
not: false
entity_field: content_translation_outdated
plugin_id: boolean
translation_source:
id: translation_source
table: node_translation_target
field: translation_source
relationship: none
group_type: group
admin_label: ''
label: 'Translation source equals row language'
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
type: yes-no
type_custom_true: ''
type_custom_false: ''
not: false
entity_field: content_translation_source
plugin_id: translation_views_source_equals_row
translation_status:
id: translation_status
table: node_translation
field: translation_status
relationship: none
group_type: group
admin_label: ''
label: 'Translation status'
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
type: status
type_custom_true: ''
type_custom_false: ''
not: false
entity_type: node
plugin_id: translation_views_status
translation_operations:
id: translation_operations
table: node_translation
field: translation_operations
relationship: none
group_type: group
admin_label: ''
label: 'Translation operations'
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
destination: false
entity_type: node
plugin_id: translation_views_operations
filters:
status:
value: '1'
table: node_field_data
field: status
plugin_id: boolean
entity_type: node
entity_field: status
id: status
expose:
operator: ''
group: 1
content_translation_source:
id: content_translation_source
table: node_field_data
field: content_translation_source
relationship: none
group_type: group
admin_label: ''
operator: in
value: { }
group: 1
exposed: true
expose:
operator_id: content_translation_source_op
label: 'Translation source'
description: ''
use_operator: false
operator: content_translation_source_op
identifier: content_translation_source
required: false
remember: false
multiple: false
remember_roles:
authenticated: authenticated
anonymous: '0'
administrator: '0'
reduce: false
is_grouped: false
group_info:
label: ''
description: ''
identifier: ''
optional: true
widget: select
multiple: false
remember: false
default_group: All
default_group_multiple: { }
group_items: { }
entity_type: node
entity_field: content_translation_source
plugin_id: language
translation_target_language:
id: translation_target_language
table: node_translation
field: translation_target_language
relationship: none
group_type: group
admin_label: ''
operator: '='
value: ''
group: 1
exposed: true
expose:
operator_id: ''
label: 'Target language'
description: ''
use_operator: false
operator: translation_target_language_op
identifier: translation_target_language
required: false
remember: true
multiple: false
remember_roles:
anonymous: anonymous
authenticated: authenticated
administrator: '0'
is_grouped: false
group_info:
label: ''
description: ''
identifier: ''
optional: true
widget: select
multiple: false
remember: false
default_group: All
default_group_multiple: { }
group_items: { }
remove: true
entity_type: node
plugin_id: translation_views_target_language
translation_default:
id: translation_default
table: node_translation_target
field: translation_default
relationship: none
group_type: group
admin_label: ''
operator: '='
value: All
group: 1
exposed: true
expose:
operator_id: ''
label: 'Target language equals default language'
description: ''
use_operator: false
operator: translation_default_op
identifier: translation_default
required: false
remember: false
multiple: false
remember_roles:
authenticated: authenticated
anonymous: '0'
administrator: '0'
is_grouped: false
group_info:
label: 'Target language equals default language'
description: null
identifier: translation_default
optional: true
widget: select
multiple: false
remember: false
default_group: All
default_group_multiple: { }
group_items:
1: { }
2: { }
3: { }
entity_field: default_langcode
plugin_id: boolean
translation_status:
id: translation_status
table: node_translation
field: translation_status
relationship: none
group_type: group
admin_label: ''
operator: '='
value: 2
group: 1
exposed: true
expose:
operator_id: ''
label: 'Translation status'
description: ''
use_operator: false
operator: translation_status_op
identifier: translation_status
required: false
remember: false
multiple: false
remember_roles:
authenticated: authenticated
anonymous: '0'
administrator: '0'
is_grouped: false
group_info:
label: ''
description: ''
identifier: ''
optional: true
widget: select
multiple: false
remember: false
default_group: All
default_group_multiple: { }
group_items: { }
entity_type: node
plugin_id: translation_views_status
sorts:
created:
id: created
table: node_field_data
field: created
order: DESC
entity_type: node
entity_field: created
plugin_id: date
relationship: none
group_type: group
admin_label: ''
exposed: false
expose:
label: ''
granularity: second
title: 'Translation views all filters and fields'
header: { }
footer: { }
empty: { }
relationships: { }
arguments: { }
display_extenders: { }
filter_groups:
operator: AND
groups:
1: AND
cache_metadata:
max-age: -1
contexts:
- 'languages:language_content'
- 'languages:language_interface'
- url
- url.query_args
- 'user.node_grants:view'
- user.permissions
tags: { }
page_1:
display_plugin: page
id: page_1
display_title: Page
position: 1
display_options:
display_extenders: { }
path: translation-views-all-filters-and-fields
cache_metadata:
max-age: -1
contexts:
- 'languages:language_content'
- 'languages:language_interface'
- url
- url.query_args
- 'user.node_grants:view'
- user.permissions
tags: { }
@@ -0,0 +1,17 @@
name: 'Translation views test view'
type: module
description: 'Provides full view for translation_views tests.'
package: Testing
# core: 8.x
dependencies:
- drupal:node
- drupal:views
- drupal:translation_views
- drupal:content_translation
- drupal:language
# Information added by Drupal.org packaging script on 2018-05-23
version: '8.x-1.0-alpha2'
core: '8.x'
project: 'translation_views'
datestamp: 1527090186
@@ -0,0 +1,491 @@
<?php
namespace Drupal\Tests\translation_views\Functional;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\Tests\views\Functional\ViewTestBase;
use Drupal\views\Tests\ViewTestData;
/**
* Tests for fields, filters and sorting for comment entity.
*
* @group translation_views
*/
class CommentFullViewFiltersFieldsTest extends ViewTestBase {
protected $profile = 'standard';
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['translation_views_test_views'];
public $loremIpsum = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum eget mi mi.';
/**
* Views used by this test.
*
* @var array
*/
public static $testViews = ['comment_translation'];
private $viewPath = 'comment-translation';
/**
* Checks that text is in specific row.
*
* @param int $row_number
* Table row order number.
* @param string $css_class
* Part of the css class of required field.
* @param string $text
* Text that should be found in the element.
*
* @throws \Behat\Mink\Exception\ElementTextException
*/
private function assertTextInRow($row_number, $css_class, $text) {
$this->assertSession()
->elementTextContains('css', "table > tbody > tr:nth-child({$row_number}) td.views-field-{$css_class}", $text);
}
/**
* Cyclic check that text is in specific row.
*
* @param string $css_class
* Part of the css class of required field.
* @param array $texts
* Array of texts that should be found in the element
* and rows' order number.
*
* @throws \Behat\Mink\Exception\ElementTextException
*/
private function assertTextInRowOrder($css_class, array $texts) {
foreach ($texts as $id => $text) {
$this->assertTextInRow($id, $css_class, $text);
}
}
/**
* Adds languages to Drupal.
*
* @param array $langcodes
* Langcodes that should be added to Drupal.
*
* @throws \Drupal\Core\Entity\EntityStorageException
*/
private function addLanguages(array $langcodes) {
foreach ($langcodes as $langcode) {
ConfigurableLanguage::createFromLangcode($langcode)->save();
}
}
/**
* Change language settings for entity types.
*
* @param string $category
* Entity category (e.g. Content).
* @param string $subcategory
* Entity subcategory (e.g. Article).
*/
private function enableTranslation($category, $subcategory) {
$this->drupalPostForm('admin/config/regional/content-language', [
"entity_types[$category]" => 1,
"settings[$category][$subcategory][translatable]" => 1,
"settings[$category][$subcategory][settings][language][language_alterable]" => 1,
], t('Save configuration'));
\Drupal::entityTypeManager()->clearCachedDefinitions();
}
/**
* Set column sorting and order.
*
* @param string $orderColumn
* Machine name of the column to be sorted.
* @param string $sort
* Sorting order (asc or desc).
* @param array $default_params
* Langcode and Translation target language.
*
* @throws \Behat\Mink\Exception\ExpectationException
*/
private function assertOrder($orderColumn, $sort, array $default_params = []) {
$this->drupalGet($this->viewPath, [
'query' => [
'langcode' => $default_params[0],
'translation_target_language' => $default_params[1],
'translation_outdated' => 'All',
'translation_status' => 2,
'order' => $orderColumn,
'sort' => $sort,
],
]);
$this->assertSession()->statusCodeEquals(200);
}
/**
* {@inheritdoc}
*/
protected function setUp($import_test_views = TRUE) {
parent::setUp($import_test_views);
$user = $this->drupalCreateUser([
'administer content types',
'edit own comments',
'administer comments',
'administer comment types',
'administer comment fields',
'administer comment display',
'post comments',
'access comments',
'skip comment approval',
'access content',
'administer site configuration',
'administer nodes',
'administer views',
'create article content',
'edit any article content',
'administer content translation',
'translate any entity',
'create content translations',
'administer languages',
]);
$this->drupalLogin($user);
ViewTestData::createTestViews(get_class($this), ['translation_views_test_views']);
// Add two languages.
$this->addLanguages(['de', 'fr']);
// Enable translation for Comment entity type.
$this->enableTranslation('comment', 'comment');
// Add 3 nodes.
$this->drupalPostForm('node/add/article', [
'title[0][value]' => 'node 1',
'created[0][value][date]' => '2018-04-01',
], t('Save'));
$this->drupalPostForm('node/add/article', [
'title[0][value]' => 'node 2',
'created[0][value][date]' => '2018-04-02',
], t('Save'));
$this->drupalPostForm('node/add/article', [
'title[0][value]' => 'node 3',
'created[0][value][date]' => '2018-04-03',
], t('Save'));
// Add comments and translations.
// Comment 1.
$edit = [
'langcode[0][value]' => 'en',
'comment_body[0][value]' => $this->loremIpsum,
'subject[0][value]' => 'node 1 en comment',
];
$this->drupalPostForm('node/1', $edit, 'Save');
// Comment 2.
$edit = [
'langcode[0][value]' => 'de',
'comment_body[0][value]' => $this->loremIpsum,
'subject[0][value]' => 'node 1 de comment',
];
$this->drupalPostForm('node/1', $edit, 'Save');
// Comment 3.
$edit = [
'langcode[0][value]' => 'de',
'comment_body[0][value]' => $this->loremIpsum,
'subject[0][value]' => 'node 2 de comment',
];
$this->drupalPostForm('node/2', $edit, 'Save');
// Comment 4.
$edit = [
'langcode[0][value]' => 'fr',
'comment_body[0][value]' => $this->loremIpsum,
'subject[0][value]' => 'node 2 fr comment',
];
$this->drupalPostForm('node/2', $edit, 'Save');
// Comment 5.
$edit = [
'langcode[0][value]' => 'fr',
'comment_body[0][value]' => $this->loremIpsum,
'subject[0][value]' => 'node 3 fr comment',
];
$this->drupalPostForm('node/3', $edit, 'Save');
// Comment 6.
$edit = [
'content_translation[retranslate]' => 1,
'comment_body[0][value]' => $this->loremIpsum,
'subject[0][value]' => 'node 3 en from fr comment',
];
$this->drupalPostForm('comment/5/translations/add/fr/en', $edit, 'Save');
}
/**
* Tests that the fields show all required information.
*/
public function testFields() {
$this->drupalGet($this->viewPath);
$this->assertSession()->statusCodeEquals(200);
$this->assertTextInRow(1, 'subject', 'node 1 en comment');
$this->assertTextInRow(1, 'langcode', 'English');
$this->assertTextInRow(1, 'translation-target-language', 'English');
$this->assertTextInRow(1, 'translation-default', 'Yes');
$this->assertTextInRow(1, 'translation-changed', ':');
$this->assertTextInRow(1, 'translation-count', '0');
$this->assertTextInRow(1, 'translation-outdated', 'No');
$this->assertTextInRow(1, 'translation-source', 'No');
$this->assertTextInRow(1, 'translation-status', 'Translated');
$this->assertTextInRow(1, 'translation-operations', 'Edit');
}
/**
* Tests columns' sorting.
*/
public function testSorting() {
// Title.
$this->assertOrder('subject', 'asc', ['de', 'fr']);
$this->assertTextInRowOrder('subject', [
1 => 'node 1 de comment',
2 => 'node 2 de comment',
]);
$this->assertSession()->pageTextNotContains('node 1 en comment');
$this->assertSession()->pageTextNotContains('node 2 fr comment');
$this->assertSession()->pageTextNotContains('node 3 fr comment');
$this->assertSession()->pageTextNotContains('node 3 en from fr comment');
$this->assertOrder('subject', 'desc', ['de', 'fr']);
$this->assertTextInRowOrder('subject', [
2 => 'node 1 de comment',
1 => 'node 2 de comment',
]);
$this->assertSession()->pageTextNotContains('node 1 en comment');
$this->assertSession()->pageTextNotContains('node 2 fr comment');
$this->assertSession()->pageTextNotContains('node 3 fr comment');
$this->assertSession()->pageTextNotContains('node 3 en from fr comment');
// Translation language.
$this->assertOrder('langcode', 'asc', ['All', 'de']);
$this->assertTextInRowOrder('langcode', [
1 => 'German',
2 => 'German',
3 => 'English',
4 => 'English',
5 => 'French',
6 => 'French',
]);
$this->assertOrder('langcode', 'desc', ['All', 'de']);
$this->assertTextInRowOrder('langcode', [
6 => 'German',
5 => 'German',
4 => 'English',
3 => 'English',
2 => 'French',
1 => 'French',
]);
// Target language equals default language.
$this->assertOrder('translation_default', 'asc', ['All', 'fr']);
$this->assertTextInRowOrder('translation-default', [
1 => 'No',
2 => 'No',
3 => 'No',
4 => 'Yes',
5 => 'Yes',
6 => 'Yes',
]);
$this->assertOrder('translation_default', 'desc', ['All', 'fr']);
$this->assertTextInRowOrder('translation-default', [
6 => 'No',
5 => 'No',
4 => 'No',
3 => 'Yes',
2 => 'Yes',
1 => 'Yes',
]);
// Translation changed time.
$this->assertOrder('translation_changed', 'asc', ['All', 'fr']);
$this->assertTextInRowOrder('translation-changed', [
4 => ':',
5 => ':',
6 => ':',
]);
$this->assertOrder('translation_changed', 'desc', ['All', 'fr']);
$this->assertTextInRowOrder('translation-changed', [
1 => ':',
2 => ':',
3 => ':',
]);
// Translation counter.
$this->assertOrder('translation_count', 'asc', ['en', 'fr']);
$this->assertTextInRowOrder('translation-count', [
1 => '0',
2 => '1',
]);
$this->assertOrder('translation_count', 'desc', ['en', 'fr']);
$this->assertTextInRowOrder('translation-count', [
2 => '0',
1 => '1',
]);
// Translation outdated.
$this->assertOrder('translation-outdated', 'asc', ['en', 'fr']);
$this->assertTextInRowOrder('translation-outdated', [
1 => 'No',
2 => 'Yes',
]);
$this->assertOrder('translation-outdated', 'desc', ['en', 'fr']);
$this->assertTextInRowOrder('translation-outdated', [
1 => 'No',
2 => 'Yes',
]);
// Translation source equals row language.
$this->assertOrder('translation_source', 'asc', [
'All',
'***LANGUAGE_site_default***',
]);
$this->assertTextInRowOrder('translation-source', [
1 => 'No',
2 => 'No',
3 => 'No',
4 => 'No',
5 => 'No',
6 => 'Yes',
]);
$this->assertOrder('translation_source', 'desc', [
'All',
'***LANGUAGE_site_default***',
]);
$this->assertTextInRowOrder('translation-source', [
6 => 'No',
5 => 'No',
4 => 'No',
3 => 'No',
2 => 'No',
1 => 'Yes',
]);
// Translation status.
$this->assertOrder('translation_status', 'asc', [
'All',
'***LANGUAGE_site_default***',
]);
$this->assertTextInRowOrder('translation-status', [
1 => 'Not translated',
2 => 'Not translated',
3 => 'Not translated',
4 => 'Translated',
5 => 'Translated',
6 => 'Translated',
]);
$this->assertOrder('translation_status', 'desc', [
'All',
'***LANGUAGE_site_default***',
]);
$this->assertTextInRowOrder('translation-status', [
6 => 'Not translated',
5 => 'Not translated',
4 => 'Not translated',
3 => 'Translated',
2 => 'Translated',
1 => 'Translated',
]);
}
/**
* Tests that filters are working correctly.
*/
public function testFilters() {
// Translation language.
$this->drupalGet($this->viewPath, [
'query' => [
'langcode' => 'en',
],
]);
$this->assertTextInRowOrder('subject', [
1 => 'node 1 en comment',
2 => 'node 3 en from fr comment',
]);
$this->assertSession()->pageTextNotContains('node 1 de comment');
$this->assertSession()->pageTextNotContains('node 2 de comment');
$this->assertSession()->pageTextNotContains('node 2 fr comment');
$this->assertSession()->pageTextNotContains('node 3 fr comment');
// Translation language & Target language.
$this->drupalGet($this->viewPath, [
'query' => [
'langcode' => 'en',
'translation_target_language' => 'fr',
],
]);
$this->assertTextInRowOrder('subject', [
1 => 'node 1 en comment',
2 => 'node 3 en from fr comment',
]);
$this->assertSession()->pageTextNotContains('node 1 de comment');
$this->assertSession()->pageTextNotContains('node 2 de comment');
$this->assertSession()->pageTextNotContains('node 2 fr comment');
$this->assertSession()->pageTextNotContains('node 3 fr comment');
// Translation language & Target language & Translation outdated.
$this->drupalGet($this->viewPath, [
'query' => [
'langcode' => 'en',
'translation_target_language' => 'fr',
'translation_outdated' => '1',
],
]);
$this->assertTextInRowOrder('subject', [
1 => 'node 3 en from fr comment',
]);
$this->assertSession()->pageTextNotContains('node 1 en comment');
$this->assertSession()->pageTextNotContains('node 1 de comment');
$this->assertSession()->pageTextNotContains('node 2 de comment');
$this->assertSession()->pageTextNotContains('node 2 fr comment');
$this->assertSession()->pageTextNotContains('node 3 fr comment');
// Translation status #1.
$this->drupalGet($this->viewPath, [
'query' => [
'translation_status' => '0',
],
]);
$this->assertTextInRowOrder('subject', [
1 => 'node 1 de comment',
2 => 'node 2 de comment',
3 => 'node 2 fr comment',
]);
$this->assertSession()->pageTextNotContains('node 1 en comment');
$this->assertSession()->pageTextNotContains('node 3 fr comment');
$this->assertSession()->pageTextNotContains('node 3 en from fr comment');
// Translation status #2.
$this->drupalGet($this->viewPath, [
'query' => [
'translation_status' => '1',
],
]);
$this->assertTextInRowOrder('subject', [
1 => 'node 1 en comment',
2 => 'node 3 en from fr comment',
3 => 'node 3 fr comment',
]);
$this->assertSession()->pageTextNotContains('node 1 de comment');
$this->assertSession()->pageTextNotContains('node 2 de comment');
$this->assertSession()->pageTextNotContains('node 2 fr comment');
}
}
@@ -0,0 +1,471 @@
<?php
namespace Drupal\Tests\translation_views\Functional;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\Tests\views\Functional\ViewTestBase;
use Drupal\views\Tests\ViewTestData;
/**
* Tests for fields, filters and sorting for content entity.
*
* @group translation_views
*/
class ContentFullViewFiltersFieldsTest extends ViewTestBase {
protected $profile = 'standard';
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['translation_views_test_views'];
/**
* Views used by this test.
*
* @var array
*/
public static $testViews = ['translation_views_all_filters_and_fields'];
/**
* {@inheritdoc}
*/
protected function setUp($import_test_views = TRUE) {
parent::setUp($import_test_views);
$user = $this->drupalCreateUser([
'administer site configuration',
'administer nodes',
'administer views',
'create article content',
'access content',
'edit any article content',
'administer content translation',
'translate any entity',
'create content translations',
'administer languages',
'administer content types',
]);
$this->drupalLogin($user);
ViewTestData::createTestViews(get_class($this), ['translation_views_test_views']);
$langcodes = ['de', 'fr'];
foreach ($langcodes as $langcode) {
ConfigurableLanguage::createFromLangcode($langcode)->save();
}
// Enable translation for article.
$edit = [
'entity_types[node]' => 1,
'settings[node][article][translatable]' => 1,
'settings[node][article][settings][language][language_alterable]' => 1,
];
$this->drupalPostForm('admin/config/regional/content-language', $edit, t('Save configuration'));
\Drupal::entityTypeManager()->clearCachedDefinitions();
// Create a node in en (node1).
$edit = [
'title[0][value]' => '001_en_title_node1',
'langcode[0][value]' => 'en',
];
$this->drupalPostForm('node/add/article', $edit, t('Save'));
// Create a translation in fr (node1).
$edit = [
'title[0][value]' => '002_fr_title_node1',
];
$this->drupalPostForm('node/1/translations/add/en/fr', $edit, t('Save (this translation)'));
// Create a translation in de (node1).
$edit = [
'title[0][value]' => '003_de_title_node1',
];
$this->drupalPostForm('node/1/translations/add/en/de', $edit, t('Save (this translation)'));
// Create a node in de (node2).
$edit = [
'title[0][value]' => '004_de_title_node2',
'langcode[0][value]' => 'de',
];
$this->drupalPostForm('node/add/article', $edit, t('Save'));
// Create a translation in fr (node2).
$edit = [
'title[0][value]' => '005_fr_title_node2',
];
$this->drupalPostForm('node/2/translations/add/de/fr', $edit, t('Save (this translation)'));
}
/**
* Tests the filtering.
*/
public function testFilters() {
$this->drupalGet('translation-views-all-filters-and-fields');
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()
->pageTextContains('Translation views all filters and fields');
$this->assertSession()->pageTextNotContains('001_en_title_node1');
$this->assertSession()->pageTextContains('002_fr_title_node1');
$this->assertSession()->pageTextContains('003_de_title_node1');
$this->assertSession()->pageTextContains('004_de_title_node2');
$this->assertSession()->pageTextContains('005_fr_title_node2');
$this->drupalGet('translation-views-all-filters-and-fields', [
'query' => [
'content_translation_source' => '***LANGUAGE_site_default***',
'translation_target_language' => '***LANGUAGE_site_default***',
'translation_default' => 'All',
'translation_status' => 2,
],
]);
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->pageTextNotContains('001_en_title_node1');
$this->assertSession()->pageTextContains('002_fr_title_node1');
$this->assertSession()->pageTextContains('003_de_title_node1');
$this->assertSession()->pageTextNotContains('004_de_title_node2');
$this->assertSession()->pageTextNotContains('005_fr_title_node2');
$this->drupalGet('translation-views-all-filters-and-fields', [
'query' => [
'content_translation_source' => 'de',
'translation_target_language' => '***LANGUAGE_site_default***',
'translation_default' => 'All',
'translation_status' => 2,
],
]);
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->pageTextNotContains('001_en_title_node1');
$this->assertSession()->pageTextNotContains('002_fr_title_node1');
$this->assertSession()->pageTextNotContains('003_de_title_node1');
$this->assertSession()->pageTextNotContains('004_de_title_node2');
$this->assertSession()->pageTextContains('005_fr_title_node2');
$this->drupalGet('translation-views-all-filters-and-fields', [
'query' => [
'content_translation_source' => 'fr',
'translation_target_language' => '***LANGUAGE_site_default***',
'translation_default' => 'All',
'translation_status' => 2,
],
]);
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->pageTextNotContains('001_en_title_node1');
$this->assertSession()->pageTextNotContains('002_fr_title_node1');
$this->assertSession()->pageTextNotContains('003_de_title_node1');
$this->assertSession()->pageTextNotContains('004_de_title_node2');
$this->assertSession()->pageTextNotContains('005_fr_title_node2');
$this->drupalGet('translation-views-all-filters-and-fields', [
'query' => [
'content_translation_source' => 'All',
'translation_target_language' => 'de',
'translation_default' => 'All',
'translation_status' => 2,
],
]);
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->pageTextContains('001_en_title_node1');
$this->assertSession()->pageTextContains('002_fr_title_node1');
$this->assertSession()->pageTextNotContains('003_de_title_node1');
$this->assertSession()->pageTextNotContains('004_de_title_node2');
$this->assertSession()->pageTextContains('005_fr_title_node2');
$this->drupalGet('translation-views-all-filters-and-fields', [
'query' => [
'content_translation_source' => 'All',
'translation_target_language' => 'fr',
'translation_default' => 'All',
'translation_status' => 2,
],
]);
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->pageTextContains('001_en_title_node1');
$this->assertSession()->pageTextNotContains('002_fr_title_node1');
$this->assertSession()->pageTextContains('003_de_title_node1');
$this->assertSession()->pageTextContains('004_de_title_node2');
$this->assertSession()->pageTextNotContains('005_fr_title_node2');
$this->drupalGet('translation-views-all-filters-and-fields', [
'query' => [
'content_translation_source' => 'All',
'translation_target_language' => '***LANGUAGE_site_default***',
'translation_default' => 'All',
'translation_status' => 1,
],
]);
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->pageTextNotContains('001_en_title_node1');
$this->assertSession()->pageTextContains('002_fr_title_node1');
$this->assertSession()->pageTextContains('003_de_title_node1');
$this->assertSession()->pageTextNotContains('004_de_title_node2');
$this->assertSession()->pageTextNotContains('005_fr_title_node2');
$this->drupalGet('translation-views-all-filters-and-fields', [
'query' => [
'content_translation_source' => 'All',
'translation_target_language' => '***LANGUAGE_site_default***',
'translation_default' => 'All',
'translation_status' => 0,
],
]);
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->pageTextNotContains('001_en_title_node1');
$this->assertSession()->pageTextNotContains('002_fr_title_node1');
$this->assertSession()->pageTextNotContains('003_de_title_node1');
$this->assertSession()->pageTextContains('004_de_title_node2');
$this->assertSession()->pageTextContains('005_fr_title_node2');
}
/**
* Test the sorting.
*/
public function testSorting() {
// Title.
$this->drupalGet('translation-views-all-filters-and-fields', [
'query' => [
'content_translation_source' => 'All',
'translation_target_language' => '***LANGUAGE_site_default***',
'translation_default' => 'All',
'translation_status' => 2,
'order' => 'title',
'sort' => 'asc',
],
]);
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(1)', '002_fr_title_node1');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(2)', '003_de_title_node1');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(3)', '004_de_title_node2');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(4)', '005_fr_title_node2');
$this->drupalGet('translation-views-all-filters-and-fields', [
'query' => [
'content_translation_source' => 'All',
'translation_target_language' => '***LANGUAGE_site_default***',
'translation_default' => 'All',
'translation_status' => 2,
'order' => 'title',
'sort' => 'desc',
],
]);
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(4)', '002_fr_title_node1');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(3)', '003_de_title_node1');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(2)', '004_de_title_node2');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(1)', '005_fr_title_node2');
// Translation language.
$this->drupalGet('translation-views-all-filters-and-fields', [
'query' => [
'content_translation_source' => 'All',
'translation_target_language' => '***LANGUAGE_site_default***',
'translation_default' => 'All',
'translation_status' => 2,
'order' => 'langcode',
'sort' => 'asc',
],
]);
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(1)', 'German');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(2)', 'German');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(3)', 'French');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(4)', 'French');
$this->drupalGet('translation-views-all-filters-and-fields', [
'query' => [
'content_translation_source' => 'All',
'translation_target_language' => '***LANGUAGE_site_default***',
'translation_default' => 'All',
'translation_status' => 2,
'order' => 'langcode',
'sort' => 'desc',
],
]);
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(4)', 'German');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(3)', 'German');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(2)', 'French');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(1)', 'French');
// Target language equals default language.
$this->drupalGet('translation-views-all-filters-and-fields', [
'query' => [
'content_translation_source' => 'All',
'translation_target_language' => '***LANGUAGE_site_default***',
'translation_default' => 'All',
'translation_status' => 2,
'order' => 'translation_default',
'sort' => 'asc',
],
]);
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(1)', 'No');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(2)', 'No');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(3)', 'Yes');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(4)', 'Yes');
$this->drupalGet('translation-views-all-filters-and-fields', [
'query' => [
'content_translation_source' => 'All',
'translation_target_language' => '***LANGUAGE_site_default***',
'translation_default' => 'All',
'translation_status' => 2,
'order' => 'translation_default',
'sort' => 'desc',
],
]);
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(4)', 'No');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(3)', 'No');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(2)', 'Yes');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(1)', 'Yes');
// Translation changed time.
$this->drupalGet('translation-views-all-filters-and-fields', [
'query' => [
'content_translation_source' => 'All',
'translation_target_language' => '***LANGUAGE_site_default***',
'translation_default' => 'All',
'translation_status' => 2,
'order' => 'translation_changed',
'sort' => 'asc',
],
]);
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()
->elementTextNotContains('css', 'table > tbody > tr:nth-child(1)', ':');
$this->assertSession()
->elementTextNotContains('css', 'table > tbody > tr:nth-child(2)', ':');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(3)', ':');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(4)', ':');
$this->drupalGet('translation-views-all-filters-and-fields', [
'query' => [
'content_translation_source' => 'All',
'translation_target_language' => '***LANGUAGE_site_default***',
'translation_default' => 'All',
'translation_status' => 2,
'order' => 'translation_changed',
'sort' => 'desc',
],
]);
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()
->elementTextNotContains('css', 'table > tbody > tr:nth-child(4)', ':');
$this->assertSession()
->elementTextNotContains('css', 'table > tbody > tr:nth-child(3)', ':');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(2)', ':');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(1)', ':');
// Translation counter.
$this->drupalGet('translation-views-all-filters-and-fields', [
'query' => [
'content_translation_source' => 'All',
'translation_target_language' => '***LANGUAGE_site_default***',
'translation_default' => 'All',
'translation_status' => 2,
'order' => 'translation_count',
'sort' => 'asc',
],
]);
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(1)', '1');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(2)', '1');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(3)', '2');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(4)', '2');
$this->drupalGet('translation-views-all-filters-and-fields', [
'query' => [
'content_translation_source' => 'All',
'translation_target_language' => '***LANGUAGE_site_default***',
'translation_default' => 'All',
'translation_status' => 2,
'order' => 'translation_count',
'sort' => 'desc',
],
]);
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(4)', '1');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(3)', '1');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(2)', '2');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(1)', '2');
// Translation counter.
$this->drupalGet('translation-views-all-filters-and-fields', [
'query' => [
'content_translation_source' => 'All',
'translation_target_language' => '***LANGUAGE_site_default***',
'translation_default' => 'All',
'translation_status' => 2,
'order' => 'translation_status',
'sort' => 'asc',
],
]);
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(1)', 'Not translated');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(2)', 'Not translated');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(3)', 'Translated');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(4)', 'Translated');
$this->drupalGet('translation-views-all-filters-and-fields', [
'query' => [
'content_translation_source' => 'All',
'translation_target_language' => '***LANGUAGE_site_default***',
'translation_default' => 'All',
'translation_status' => 2,
'order' => 'translation_status',
'sort' => 'desc',
],
]);
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(4)', 'Not translated');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(3)', 'Not translated');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(2)', 'Translated');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(1)', 'Translated');
}
}
@@ -0,0 +1,223 @@
<?php
namespace Drupal\Tests\translation_views\Functional;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\Tests\BrowserTestBase;
/**
* Tests for fields, filters and sorting (Content translation jobs view).
*
* @group translation_views
*/
class ContentTranslationJobsViewTest extends BrowserTestBase {
protected $profile = 'standard';
/**
* Modules to enable.
*
* @var array
*/
public static $modules = [
'node',
'translation_views',
'language',
'content_translation',
];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$langcodes = ['de', 'fr'];
foreach ($langcodes as $langcode) {
ConfigurableLanguage::createFromLangcode($langcode)->save();
}
$user = $this->drupalCreateUser([
'administer site configuration',
'administer nodes',
'create article content',
'access content',
'edit any article content',
'administer content translation',
'translate any entity',
'create content translations',
'administer languages',
'administer content types',
]);
$this->drupalLogin($user);
// Enable translation for article.
$edit = [
'entity_types[node]' => 1,
'settings[node][article][translatable]' => 1,
'settings[node][article][settings][language][language_alterable]' => 1,
];
$this->drupalPostForm('admin/config/regional/content-language', $edit, t('Save configuration'));
\Drupal::entityTypeManager()->clearCachedDefinitions();
// Create node1 in german.
$edit = [
'title[0][value]' => 'node1 de',
'langcode[0][value]' => 'de',
];
$this->drupalPostForm('node/add/article', $edit, t('Save'));
// Create node1 translation in french.
$edit = [
'title[0][value]' => 'node1 fr',
];
$this->drupalPostForm('node/1/translations/add/de/fr', $edit, t('Save (this translation)'));
// Create node2 in english.
$edit = [
'title[0][value]' => 'node2 en',
'langcode[0][value]' => 'en',
];
$this->drupalPostForm('node/add/article', $edit, t('Save'));
// Create node3 in french.
$edit = [
'title[0][value]' => 'node3 fr',
'langcode[0][value]' => 'fr',
];
$this->drupalPostForm('node/add/article', $edit, t('Save'));
}
/**
* Tests that filters works as expected.
*/
public function testNodesFiltering() {
$this->drupalGet('translate/content', ['query' => ['translation_target_language' => '***LANGUAGE_site_default***']]);
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->pageTextContains('node1 de');
$this->assertSession()->pageTextContains('node1 fr');
$this->assertSession()->pageTextNotContains('node2 en');
$this->assertSession()->pageTextContains('node3 fr');
$this->drupalGet('translate/content', ['query' => ['translation_target_language' => 'de']]);
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->pageTextNotContains('node1 de');
$this->assertSession()->pageTextNotContains('node1 fr');
$this->assertSession()->pageTextContains('node2 en');
$this->assertSession()->pageTextContains('node3 fr');
$this->drupalGet('translate/content', ['query' => ['translation_target_language' => 'fr']]);
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->pageTextNotContains('node1 de');
$this->assertSession()->pageTextNotContains('node1 fr');
$this->assertSession()->pageTextContains('node2 en');
$this->assertSession()->pageTextNotContains('node3 fr');
$this->drupalGet('translate/content', [
'query' => [
'translation_target_language' => 'de',
'langcode' => 'en',
],
]);
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->pageTextNotContains('node1 de');
$this->assertSession()->pageTextNotContains('node1 fr');
$this->assertSession()->pageTextContains('node2 en');
$this->assertSession()->pageTextNotContains('node3 fr');
$this->drupalGet('translate/content', [
'query' => [
'translation_target_language' => 'fr',
'langcode' => 'en',
],
]);
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->pageTextNotContains('node1 de');
$this->assertSession()->pageTextNotContains('node1 fr');
$this->assertSession()->pageTextContains('node2 en');
$this->assertSession()->pageTextNotContains('node3 fr');
$this->drupalGet('translate/content', ['query' => ['langcode' => 'fr']]);
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->pageTextNotContains('node1 de');
$this->assertSession()->pageTextContains('node1 fr');
$this->assertSession()->pageTextNotContains('node2 en');
$this->assertSession()->pageTextContains('node3 fr');
$this->drupalGet('translate/content', ['query' => ['langcode' => 'de']]);
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->pageTextContains('node1 de');
$this->assertSession()->pageTextNotContains('node1 fr');
$this->assertSession()->pageTextNotContains('node2 en');
$this->assertSession()->pageTextNotContains('node3 fr');
$this->drupalGet('translate/content', ['query' => ['langcode' => 'en']]);
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->pageTextNotContains('node1 de');
$this->assertSession()->pageTextNotContains('node1 fr');
$this->assertSession()->pageTextNotContains('node2 en');
$this->assertSession()->pageTextNotContains('node3 fr');
}
/**
* Tests that columns' sorting works as expected.
*/
public function testNodesSorting() {
// Check title column asc sorting.
$this->drupalGet('translate/content', [
'query' => [
'order' => 'title',
'sort' => 'asc',
],
]);
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(1)', 'node1 de');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(2)', 'node1 fr');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(3)', 'node3 fr');
// Check title column desc sorting.
$this->drupalGet('translate/content', [
'query' => [
'order' => 'title',
'sort' => 'desc',
],
]);
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(3)', 'node1 de');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(2)', 'node1 fr');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(1)', 'node3 fr');
// Check langcode column asc sorting.
$this->drupalGet('translate/content', [
'query' => [
'order' => 'langcode',
'sort' => 'asc',
],
]);
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(1)', 'node1 de');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(2)', 'node1 fr');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(3)', 'node3 fr');
// Check langcode column desc sorting.
$this->drupalGet('translate/content', [
'query' => [
'order' => 'langcode',
'sort' => 'desc',
],
]);
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(1)', 'node1 fr');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(2)', 'node3 fr');
$this->assertSession()
->elementTextContains('css', 'table > tbody > tr:nth-child(3)', 'node1 de');
}
}
@@ -7,8 +7,8 @@ dependencies:
- drupal:content_translation
- drupal:views
# Information added by Drupal.org packaging script on 2018-02-13
version: '8.x-1.0-alpha1'
# Information added by Drupal.org packaging script on 2018-05-23
version: '8.x-1.0-alpha2'
core: '8.x'
project: 'translation_views'
datestamp: 1518516495
datestamp: 1527090186
@@ -12,6 +12,7 @@ use Drupal\Core\Database\Query\AlterableInterface;
use Drupal\Core\Entity\ContentEntityFormInterface;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatchInterface;
/**
* Implements hook_module_implements_alter().
@@ -112,3 +113,27 @@ function translation_views_query_views_alter(AlterableInterface $query) {
}
}
}
/**
* Implements hook_help().
*
* @inheritdoc
*/
function translation_views_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
case 'help.page.translation_views':
$text = file_get_contents(dirname(__FILE__) . '/README.md');
if (!\Drupal::moduleHandler()->moduleExists('markdown')) {
return '<pre>' . $text . '</pre>';
}
else {
// Use the Markdown filter to render the README.
$filter_manager = \Drupal::service('plugin.manager.filter');
$settings = \Drupal::configFactory()->get('markdown.settings')->getRawData();
$config = ['settings' => $settings];
$filter = $filter_manager->createInstance('markdown', $config);
return $filter->process($text, 'en');
}
}
return NULL;
}
+16 -15
View File
@@ -53,15 +53,16 @@ function translation_views_views_data_alter(array &$data) {
$pk = $entity_type->getKey('id');
$translations_table['table'] = [
'group' => $group,
'group' => $group,
'entity type' => $entity_type_id,
'join' => [
'join' => [
$field_data_table => [
'join_id' => 'translation_views_language_join',
'type' => 'LEFT',
'join_id' => 'translation_views_language_join',
'entity_pk' => $pk,
'type' => 'LEFT',
'left_field' => $pk,
'field' => $pk,
'table' => $field_data_table,
'field' => $pk,
'table' => $field_data_table,
],
],
];
@@ -73,13 +74,13 @@ function translation_views_views_data_alter(array &$data) {
$translations_table_target['table'] = [
'group' => $group,
'join' => [
'join' => [
$field_data_table => [
'type' => 'LEFT',
'type' => 'LEFT',
'left_field' => $pk,
'field' => $pk,
'table' => $field_data_table,
'extra' => [
'field' => $pk,
'table' => $field_data_table,
'extra' => [
[
'field' => 'langcode',
'value' => '***TRANSLATION_VIEWS_TARGET_LANG***',
@@ -90,16 +91,16 @@ function translation_views_views_data_alter(array &$data) {
];
$translations_table_target += FieldDefinitions::buildOutdatedField(
$translations_table['content_translation_outdated']
$data[$field_data_table]['content_translation_outdated']
);
$translations_table_target += FieldDefinitions::buildSourceField(
$translations_table['content_translation_source']
$data[$field_data_table]['content_translation_source']
);
$translations_table_target += FieldDefinitions::buildDefaultLangcodeField(
$translations_table['default_langcode']
$data[$field_data_table]['default_langcode']
);
$translations_table_target += FieldDefinitions::buildChangedField(
$translations_table['changed']
$data[$field_data_table]['changed']
);
}
}
@@ -27,3 +27,9 @@ Configuration
2. Add a "Views bulk operations" field (global), available on
all entity types, if not already added.
3. Check the "Modify field values" action.
4. (Optional) Define a "bulk_edit" form mode for the entity bundles
that you wish to be able to bulk edit. Under the "Form modes" page
at /admin/structure/display-modes/form you can add a new form
mode. If it uses the machine name "bulk_edit", the form for the
"Modify field values" action will use that form mode to determine
what fields are available for bulk editing.
@@ -1,5 +1,5 @@
.views-bulk-edit-form .form-type-checkbox,
.views-bulk-edit-form .js-form-type-checkbox {
.views-bulk-edit-form .vbe-selector-fieldset .form-type-checkbox,
.views-bulk-edit-form .vbe-selector-fieldset .js-form-type-checkbox {
float: left;
margin-right: 20px;
}
@@ -109,9 +109,26 @@ class ModifyEntityValues extends ViewsBulkOperationsActionBase implements Contai
$form['#attributes']['class'] = ['views-bulk-edit-form'];
$form['#attached']['library'][] = 'views_bulk_edit/views_bulk_edit.edit_form';
$form['options'] = [
'#type' => 'fieldset',
'#title' => $this->t('Options'),
];
$form['options']['_add_values'] = [
'#type' => 'checkbox',
'#title' => $this->t('Add values to multi-value fields'),
'#description' => $this->t('New values of multi-value fields will be added to the existing ones instead of overwriting them.'),
];
$bundle_count = 0;
foreach ($bundle_data as $entity_type_id => $bundles) {
foreach ($bundles as $bundle => $label) {
$form = $this->getBundleForm($entity_type_id, $bundle, $label, $form, $form_state);
$bundle_count++;
}
}
foreach ($bundle_data as $entity_type_id => $bundles) {
foreach ($bundles as $bundle => $label) {
$form = $this->getBundleForm($entity_type_id, $bundle, $label, $form, $form_state, $bundle_count);
}
}
@@ -251,11 +268,13 @@ class ModifyEntityValues extends ViewsBulkOperationsActionBase implements Contai
* Form array.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form_state object.
* @param int $bundle_count
* Number of bundles that may be affected.
*
* @return array
* Edit form for the current entity bundle.
*/
protected function getBundleForm($entity_type_id, $bundle, $bundle_label, array $form, FormStateInterface $form_state) {
protected function getBundleForm($entity_type_id, $bundle, $bundle_label, array $form, FormStateInterface $form_state, $bundle_count) {
$entityType = $this->entityTypeManager->getDefinition($entity_type_id);
$entity = $this->entityTypeManager->getStorage($entity_type_id)->create([
$entityType->getKey('bundle') => $bundle,
@@ -273,7 +292,8 @@ class ModifyEntityValues extends ViewsBulkOperationsActionBase implements Contai
$bundle_label = $entityType->getLabel();
}
$form[$entity_type_id][$bundle] = [
'#type' => 'fieldset',
'#type' => 'details',
'#open' => ($bundle_count === 1),
'#title' => $entityType->getLabel() . ' - ' . $bundle_label,
'#parents' => [$entity_type_id, $bundle],
];
@@ -308,6 +328,7 @@ class ModifyEntityValues extends ViewsBulkOperationsActionBase implements Contai
'#title' => $this->t('Select fields to change'),
'#weight' => -50,
'#tree' => TRUE,
'#attributes' => ['class' => ['vbe-selector-fieldset']],
];
foreach (Element::children($form) as $key) {
@@ -325,6 +346,7 @@ class ModifyEntityValues extends ViewsBulkOperationsActionBase implements Contai
$selector['_field_selector'][$key] = [
'#type' => 'checkbox',
'#title' => $element['#title'],
'#weight' => isset($form[$key]['#weight']) ? $form[$key]['#weight'] : 0,
'#tree' => TRUE,
];
@@ -418,6 +440,8 @@ class ModifyEntityValues extends ViewsBulkOperationsActionBase implements Contai
}
}
}
$this->configuration['_add_values'] = $form_state->getValue('_add_values');
}
/**
@@ -430,10 +454,27 @@ class ModifyEntityValues extends ViewsBulkOperationsActionBase implements Contai
$result = $this->t('Skip (field is not present on this bundle)');
if (isset($this->configuration[$type_id][$bundle])) {
foreach ($this->configuration[$type_id][$bundle] as $field => $value) {
if (!empty($this->configuration['_add_values'])) {
/** @var \Drupal\Core\Field\FieldStorageDefinitionInterface $storageDefinition */
$storageDefinition = $entity->{$field}->getFieldDefinition()->getFieldStorageDefinition();
$cardinality = $storageDefinition->getCardinality();
if ($cardinality === $storageDefinition::CARDINALITY_UNLIMITED || $cardinality > 1) {
$current_value = $entity->{$field}->getValue();
$value_count = count($current_value);
foreach ($value as $item) {
if ($cardinality != $storageDefinition::CARDINALITY_UNLIMITED && $value_count >= $cardinality) {
break;
}
$current_value[] = $item;
}
$value = $current_value;
}
}
$entity->{$field}->setValue($value);
}
$entity->save();
$result = $this->t('Modify filed values');
$result = $this->t('Modify field values');
}
return $result;
}
@@ -6,8 +6,8 @@ package: 'Views Bulk Operations'
dependencies:
- drupal:views_bulk_operations
# Information added by Drupal.org packaging script on 2018-03-12
version: '8.x-2.0-rc1'
# Information added by Drupal.org packaging script on 2018-07-27
version: '8.x-2.2'
core: '8.x'
project: 'views_bulk_edit'
datestamp: 1520840585
datestamp: 1532689107
@@ -60,7 +60,10 @@
* @param {bool} state
* @param {string} value
*/
update: function (state, index, value = null) {
update: function (state, index, value) {
if (value === undefined) {
value = null;
}
if (this.view_id.length && this.display_id.length) {
var list = {};
if (value && value != 'on') {
@@ -6,8 +6,8 @@ package: 'Views Bulk Operations'
dependencies:
- drupal:views_bulk_operations
# Information added by Drupal.org packaging script on 2018-03-10
version: '8.x-2.1'
# Information added by Drupal.org packaging script on 2018-07-02
version: '8.x-2.4'
core: '8.x'
project: 'views_bulk_operations'
datestamp: 1520668088
datestamp: 1530516826
@@ -6,8 +6,8 @@ package: 'Examples'
dependencies:
- drupal:views_bulk_operations
# Information added by Drupal.org packaging script on 2018-03-10
version: '8.x-2.1'
# Information added by Drupal.org packaging script on 2018-07-02
version: '8.x-2.4'
core: '8.x'
project: 'views_bulk_operations'
datestamp: 1520668088
datestamp: 1530516826
@@ -114,6 +114,7 @@ class ConfigureAction extends FormBase {
[$this, 'submitForm'],
],
];
$this->addCancelButton($form);
$action = $this->actionManager->createInstance($form_data['action_id']);
@@ -121,9 +122,8 @@ class ConfigureAction extends FormBase {
$action->setContext($form_data);
}
$form = $action->buildConfigurationForm($form, $form_state);
$form_state->set('views_bulk_operations', $form_data);
$form = $action->buildConfigurationForm($form, $form_state);
return $form;
}
@@ -87,8 +87,6 @@ class ConfirmAction extends FormBase {
return;
}
$form_state->setStorage($form_data);
if (!empty($form_data['entity_labels'])) {
$form['list'] = [
'#theme' => 'item_list',
@@ -113,6 +111,9 @@ class ConfirmAction extends FormBase {
[$this, 'submitForm'],
],
];
$this->addCancelButton($form);
$form_state->set('views_bulk_operations', $form_data);
return $form;
}
@@ -121,7 +122,7 @@ class ConfirmAction extends FormBase {
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$form_data = $form_state->getStorage();
$form_data = $form_state->get('views_bulk_operations');
$this->deleteTempstoreData($form_data['view_id'], $form_data['display_id']);
$this->actionProcessor->executeProcessing($form_data);
$form_state->setRedirectUrl($form_data['redirect_url']);
@@ -3,6 +3,7 @@
namespace Drupal\views_bulk_operations\Form;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
/**
* Defines common methods for Views Bulk Operations forms.
@@ -162,4 +163,35 @@ trait ViewsBulkOperationsFormTrait {
return $this->getTempstore($view_id, $display_id)->delete($this->currentUser()->id());
}
/**
* Add a cancel button into a VBO form.
*
* @param array $form
* The form definition.
*/
protected function addCancelButton(array &$form) {
$form['actions']['cancel'] = [
'#type' => 'submit',
'#value' => $this->t('Cancel'),
'#submit' => [
[$this, 'cancelForm'],
],
'#limit_validation_errors' => [],
];
}
/**
* Submit callback to cancel an action and return to the view.
*
* @param array $form
* The form definition.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state.
*/
public function cancelForm(array &$form, FormStateInterface $form_state) {
$form_data = $form_state->get('views_bulk_operations');
drupal_set_message($this->t('Canceled "%action".', ['%action' => $form_data['action_label']]));
$form_state->setRedirectUrl($form_data['redirect_url']);
}
}
@@ -71,11 +71,11 @@ class ViewsBulkOperationsBulkForm extends FieldPluginBase implements CacheableDe
protected $currentUser;
/**
* The current URL object.
* The request stack.
*
* @var \Drupal\Core\Url
* @var \Symfony\Component\HttpFoundation\RequestStack
*/
protected $url;
protected $requestStack;
/**
* An array of actions that can be executed.
@@ -141,7 +141,7 @@ class ViewsBulkOperationsBulkForm extends FieldPluginBase implements CacheableDe
$this->actionProcessor = $actionProcessor;
$this->tempStoreFactory = $tempStoreFactory;
$this->currentUser = $currentUser;
$this->url = Url::createFromRequest($requestStack->getCurrentRequest());
$this->requestStack = $requestStack;
}
/**
@@ -212,7 +212,7 @@ class ViewsBulkOperationsBulkForm extends FieldPluginBase implements CacheableDe
'batch_size' => $this->options['batch'] ? $this->options['batch_size'] : 0,
'total_results' => $this->viewData->getTotalResults(),
'arguments' => $this->view->args,
'redirect_url' => $this->url,
'redirect_url' => Url::createFromRequest(clone $this->requestStack->getCurrentRequest()),
'exposed_input' => $this->view->getExposedInput(),
];
@@ -540,7 +540,6 @@ class ViewsBulkOperationsBulkForm extends FieldPluginBase implements CacheableDe
// Update tempstore data.
$this->updateTempstoreData();
$use_revision = array_key_exists('revision', $this->view->getQuery()->getEntityTableInfo());
$form[$this->options['id']]['#tree'] = TRUE;
// Get pager data if available.
@@ -763,11 +762,15 @@ class ViewsBulkOperationsBulkForm extends FieldPluginBase implements CacheableDe
$this->tempStoreData['preconfiguration'] = isset($this->options['preconfiguration'][$action_id]) ? $this->options['preconfiguration'][$action_id] : [];
if (!$form_state->getValue('select_all')) {
// Update list data with the form selection.
// Update list data with the current form selection.
foreach ($form_state->getValue($this->options['id']) as $row_index => $bulkFormKey) {
if ($bulkFormKey) {
$this->tempStoreData['list'][$bulkFormKey] = $this->getListItem($bulkFormKey, $form[$this->options['id']][$row_index]['#title']);
}
else {
unset($this->tempStoreData['list'][$form[$this->options['id']][$row_index]['#return_value']]);
}
}
}
else {
@@ -193,7 +193,7 @@ class ViewsBulkOperationsViewData implements ViewsBulkOperationsViewDataInterfac
throw new \Exception('Unexpected view result row structure.');
}
if ($entity->isTranslatable()) {
if ($entity instanceof TranslatableInterface && $entity->isTranslatable()) {
// Try to find a field alias for the langcode.
// Assumption: translatable entities always
@@ -216,7 +216,7 @@ class ViewsBulkOperationsViewData implements ViewsBulkOperationsViewDataInterfac
$language_field = $langcode_key;
}
if ($entity instanceof TranslatableInterface && isset($row->{$language_field})) {
if (isset($row->{$language_field})) {
return $entity->getTranslation($row->{$language_field});
}
}
@@ -32,7 +32,7 @@ class ViewsBulkOperationsBulkFormTest extends BrowserTestBase {
$this->drupalCreateContentType(['type' => 'page']);
$this->testNodes = [];
$time = REQUEST_TIME;
$time = $this->container->get('datetime.time')->getRequestTime();
for ($i = 0; $i < 15; $i++) {
// Ensure nodes are sorted in the same order they are inserted in the
// array.
@@ -101,7 +101,8 @@ abstract class ViewsBulkOperationsKernelTestBase extends KernelTestBase {
'language',
]);
// Get VBO view data service.
// Get time and VBO view data services.
$this->time = $this->container->get('datetime.time');
$this->vboDataService = $this->container->get('views_bulk_operations.data');
}
@@ -133,7 +134,7 @@ abstract class ViewsBulkOperationsKernelTestBase extends KernelTestBase {
}
// Create some test nodes.
$time = REQUEST_TIME;
$time = $this->time->getRequestTime();
if (!isset($type_data['count'])) {
$type_data['count'] = 10;
}
@@ -39,9 +39,6 @@ class ViewsBulkOperationsBatchTest extends UnitTestCase {
$actionProcessor = $this->getMockBuilder('Drupal\views_bulk_operations\Service\ViewsBulkOperationsActionProcessor')
->disableOriginalConstructor()
->getMock();
$actionProcessor->expects($this->any())
->method('getEntity')
->will($this->returnValue(new \stdClass()));
$actionProcessor->expects($this->any())
->method('populateQueue')
@@ -7,8 +7,8 @@ dependencies:
- drupal:views_bulk_operations
- drupal:node
# Information added by Drupal.org packaging script on 2018-03-10
version: '8.x-2.1'
# Information added by Drupal.org packaging script on 2018-07-02
version: '8.x-2.4'
core: '8.x'
project: 'views_bulk_operations'
datestamp: 1520668088
datestamp: 1530516826
@@ -6,8 +6,8 @@ package: 'Views'
dependencies:
- drupal:views (>=8.4)
# Information added by Drupal.org packaging script on 2018-03-10
version: '8.x-2.1'
# Information added by Drupal.org packaging script on 2018-07-02
version: '8.x-2.4'
core: '8.x'
project: 'views_bulk_operations'
datestamp: 1520668088
datestamp: 1530516826