upgrades core to 8.4.2
This commit is contained in:
@@ -49,9 +49,6 @@ views.display.page:
|
||||
context:
|
||||
type: string
|
||||
label: 'Context'
|
||||
expanded:
|
||||
type: boolean
|
||||
label: 'Expanded'
|
||||
tab_options:
|
||||
type: mapping
|
||||
label: 'Tab options'
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Schema for the views entity reference selection plugins.
|
||||
# Schema for the entity reference 'views' selection handler settings.
|
||||
|
||||
entity_reference_selection.views:
|
||||
type: mapping
|
||||
label: 'View handler settings'
|
||||
type: entity_reference_selection
|
||||
label: 'Views selection handler settings'
|
||||
mapping:
|
||||
view:
|
||||
type: mapping
|
||||
|
||||
@@ -31,14 +31,6 @@ views.filter.combine:
|
||||
type: string
|
||||
label: 'Field'
|
||||
|
||||
views.filter_value.date:
|
||||
type: views.filter_value.numeric
|
||||
label: 'Date'
|
||||
mapping:
|
||||
type:
|
||||
type: string
|
||||
label: 'Type'
|
||||
|
||||
views.filter_value.groupby_numeric:
|
||||
type: views.filter_value.numeric
|
||||
label: 'Group by numeric'
|
||||
@@ -150,6 +142,10 @@ views.filter.language:
|
||||
type: views.filter.in_operator
|
||||
label: 'Language'
|
||||
|
||||
views.filter.latest_revision:
|
||||
type: views_filter
|
||||
label: 'Latest revision'
|
||||
|
||||
views.filter_value.date:
|
||||
type: views.filter_value.numeric
|
||||
label: 'Date'
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
/**
|
||||
* @file
|
||||
* Handles AJAX fetching of views, including filter submission and response.
|
||||
*/
|
||||
|
||||
(function ($, Drupal, drupalSettings) {
|
||||
/**
|
||||
* Attaches the AJAX behavior to exposed filters forms and key View links.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*
|
||||
* @prop {Drupal~behaviorAttach} attach
|
||||
* Attaches ajaxView functionality to relevant elements.
|
||||
*/
|
||||
Drupal.behaviors.ViewsAjaxView = {};
|
||||
Drupal.behaviors.ViewsAjaxView.attach = function () {
|
||||
if (drupalSettings && drupalSettings.views && drupalSettings.views.ajaxViews) {
|
||||
const ajaxViews = drupalSettings.views.ajaxViews;
|
||||
for (const i in ajaxViews) {
|
||||
if (ajaxViews.hasOwnProperty(i)) {
|
||||
Drupal.views.instances[i] = new Drupal.views.ajaxView(ajaxViews[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @namespace
|
||||
*/
|
||||
Drupal.views = {};
|
||||
|
||||
/**
|
||||
* @type {object.<string, Drupal.views.ajaxView>}
|
||||
*/
|
||||
Drupal.views.instances = {};
|
||||
|
||||
/**
|
||||
* Javascript object for a certain view.
|
||||
*
|
||||
* @constructor
|
||||
*
|
||||
* @param {object} settings
|
||||
* Settings object for the ajax view.
|
||||
* @param {string} settings.view_dom_id
|
||||
* The DOM id of the view.
|
||||
*/
|
||||
Drupal.views.ajaxView = function (settings) {
|
||||
const selector = `.js-view-dom-id-${settings.view_dom_id}`;
|
||||
this.$view = $(selector);
|
||||
|
||||
// Retrieve the path to use for views' ajax.
|
||||
let ajax_path = drupalSettings.views.ajax_path;
|
||||
|
||||
// If there are multiple views this might've ended up showing up multiple
|
||||
// times.
|
||||
if (ajax_path.constructor.toString().indexOf('Array') !== -1) {
|
||||
ajax_path = ajax_path[0];
|
||||
}
|
||||
|
||||
// Check if there are any GET parameters to send to views.
|
||||
let queryString = window.location.search || '';
|
||||
if (queryString !== '') {
|
||||
// Remove the question mark and Drupal path component if any.
|
||||
queryString = queryString.slice(1).replace(/q=[^&]+&?|&?render=[^&]+/, '');
|
||||
if (queryString !== '') {
|
||||
// If there is a '?' in ajax_path, clean url are on and & should be
|
||||
// used to add parameters.
|
||||
queryString = ((/\?/.test(ajax_path)) ? '&' : '?') + queryString;
|
||||
}
|
||||
}
|
||||
|
||||
this.element_settings = {
|
||||
url: ajax_path + queryString,
|
||||
submit: settings,
|
||||
setClick: true,
|
||||
event: 'click',
|
||||
selector,
|
||||
progress: { type: 'fullscreen' },
|
||||
};
|
||||
|
||||
this.settings = settings;
|
||||
|
||||
// Add the ajax to exposed forms.
|
||||
this.$exposed_form = $(`form#views-exposed-form-${settings.view_name.replace(/_/g, '-')}-${settings.view_display_id.replace(/_/g, '-')}`);
|
||||
this.$exposed_form.once('exposed-form').each($.proxy(this.attachExposedFormAjax, this));
|
||||
|
||||
// Add the ajax to pagers.
|
||||
this.$view
|
||||
// Don't attach to nested views. Doing so would attach multiple behaviors
|
||||
// to a given element.
|
||||
.filter($.proxy(this.filterNestedViews, this))
|
||||
.once('ajax-pager').each($.proxy(this.attachPagerAjax, this));
|
||||
|
||||
// Add a trigger to update this view specifically. In order to trigger a
|
||||
// refresh use the following code.
|
||||
//
|
||||
// @code
|
||||
// $('.view-name').trigger('RefreshView');
|
||||
// @endcode
|
||||
const self_settings = $.extend({}, this.element_settings, {
|
||||
event: 'RefreshView',
|
||||
base: this.selector,
|
||||
element: this.$view.get(0),
|
||||
});
|
||||
this.refreshViewAjax = Drupal.ajax(self_settings);
|
||||
};
|
||||
|
||||
/**
|
||||
* @method
|
||||
*/
|
||||
Drupal.views.ajaxView.prototype.attachExposedFormAjax = function () {
|
||||
const that = this;
|
||||
this.exposedFormAjax = [];
|
||||
// Exclude the reset buttons so no AJAX behaviours are bound. Many things
|
||||
// break during the form reset phase if using AJAX.
|
||||
$('input[type=submit], input[type=image]', this.$exposed_form).not('[data-drupal-selector=edit-reset]').each(function (index) {
|
||||
const self_settings = $.extend({}, that.element_settings, {
|
||||
base: $(this).attr('id'),
|
||||
element: this,
|
||||
});
|
||||
that.exposedFormAjax[index] = Drupal.ajax(self_settings);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {bool}
|
||||
* If there is at least one parent with a view class return false.
|
||||
*/
|
||||
Drupal.views.ajaxView.prototype.filterNestedViews = function () {
|
||||
// If there is at least one parent with a view class, this view
|
||||
// is nested (e.g., an attachment). Bail.
|
||||
return !this.$view.parents('.view').length;
|
||||
};
|
||||
|
||||
/**
|
||||
* Attach the ajax behavior to each link.
|
||||
*/
|
||||
Drupal.views.ajaxView.prototype.attachPagerAjax = function () {
|
||||
this.$view.find('ul.js-pager__items > li > a, th.views-field a, .attachment .views-summary a')
|
||||
.each($.proxy(this.attachPagerLinkAjax, this));
|
||||
};
|
||||
|
||||
/**
|
||||
* Attach the ajax behavior to a singe link.
|
||||
*
|
||||
* @param {string} [id]
|
||||
* The ID of the link.
|
||||
* @param {HTMLElement} link
|
||||
* The link element.
|
||||
*/
|
||||
Drupal.views.ajaxView.prototype.attachPagerLinkAjax = function (id, link) {
|
||||
const $link = $(link);
|
||||
const viewData = {};
|
||||
const href = $link.attr('href');
|
||||
// Construct an object using the settings defaults and then overriding
|
||||
// with data specific to the link.
|
||||
$.extend(
|
||||
viewData,
|
||||
this.settings,
|
||||
Drupal.Views.parseQueryString(href),
|
||||
// Extract argument data from the URL.
|
||||
Drupal.Views.parseViewArgs(href, this.settings.view_base_path),
|
||||
);
|
||||
|
||||
const self_settings = $.extend({}, this.element_settings, {
|
||||
submit: viewData,
|
||||
base: false,
|
||||
element: link,
|
||||
});
|
||||
this.pagerAjax = Drupal.ajax(self_settings);
|
||||
};
|
||||
|
||||
/**
|
||||
* Views scroll to top ajax command.
|
||||
*
|
||||
* @param {Drupal.Ajax} [ajax]
|
||||
* A {@link Drupal.ajax} object.
|
||||
* @param {object} response
|
||||
* Ajax response.
|
||||
* @param {string} response.selector
|
||||
* Selector to use.
|
||||
*/
|
||||
Drupal.AjaxCommands.prototype.viewsScrollTop = function (ajax, response) {
|
||||
// Scroll to the top of the view. This will allow users
|
||||
// to browse newly loaded content after e.g. clicking a pager
|
||||
// link.
|
||||
const offset = $(response.selector).offset();
|
||||
// We can't guarantee that the scrollable object should be
|
||||
// the body, as the view could be embedded in something
|
||||
// more complex such as a modal popup. Recurse up the DOM
|
||||
// and scroll the first element that has a non-zero top.
|
||||
let scrollTarget = response.selector;
|
||||
while ($(scrollTarget).scrollTop() === 0 && $(scrollTarget).parent()) {
|
||||
scrollTarget = $(scrollTarget).parent();
|
||||
}
|
||||
// Only scroll upward.
|
||||
if (offset.top - 10 < $(scrollTarget).scrollTop()) {
|
||||
$(scrollTarget).animate({ scrollTop: (offset.top - 10) }, 500);
|
||||
}
|
||||
};
|
||||
}(jQuery, Drupal, drupalSettings));
|
||||
@@ -1,20 +1,11 @@
|
||||
/**
|
||||
* @file
|
||||
* Handles AJAX fetching of views, including filter submission and response.
|
||||
*/
|
||||
* DO NOT EDIT THIS FILE.
|
||||
* See the following change record for more information,
|
||||
* https://www.drupal.org/node/2815083
|
||||
* @preserve
|
||||
**/
|
||||
|
||||
(function ($, Drupal, drupalSettings) {
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Attaches the AJAX behavior to exposed filters forms and key View links.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*
|
||||
* @prop {Drupal~behaviorAttach} attach
|
||||
* Attaches ajaxView functionality to relevant elements.
|
||||
*/
|
||||
Drupal.behaviors.ViewsAjaxView = {};
|
||||
Drupal.behaviors.ViewsAjaxView.attach = function () {
|
||||
if (drupalSettings && drupalSettings.views && drupalSettings.views.ajaxViews) {
|
||||
@@ -27,48 +18,25 @@
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @namespace
|
||||
*/
|
||||
Drupal.views = {};
|
||||
|
||||
/**
|
||||
* @type {object.<string, Drupal.views.ajaxView>}
|
||||
*/
|
||||
Drupal.views.instances = {};
|
||||
|
||||
/**
|
||||
* Javascript object for a certain view.
|
||||
*
|
||||
* @constructor
|
||||
*
|
||||
* @param {object} settings
|
||||
* Settings object for the ajax view.
|
||||
* @param {string} settings.view_dom_id
|
||||
* The DOM id of the view.
|
||||
*/
|
||||
Drupal.views.ajaxView = function (settings) {
|
||||
var selector = '.js-view-dom-id-' + settings.view_dom_id;
|
||||
this.$view = $(selector);
|
||||
|
||||
// Retrieve the path to use for views' ajax.
|
||||
var ajax_path = drupalSettings.views.ajax_path;
|
||||
|
||||
// If there are multiple views this might've ended up showing up multiple
|
||||
// times.
|
||||
if (ajax_path.constructor.toString().indexOf('Array') !== -1) {
|
||||
ajax_path = ajax_path[0];
|
||||
}
|
||||
|
||||
// Check if there are any GET parameters to send to views.
|
||||
var queryString = window.location.search || '';
|
||||
if (queryString !== '') {
|
||||
// Remove the question mark and Drupal path component if any.
|
||||
queryString = queryString.slice(1).replace(/q=[^&]+&?|&?render=[^&]+/, '');
|
||||
if (queryString !== '') {
|
||||
// If there is a '?' in ajax_path, clean url are on and & should be
|
||||
// used to add parameters.
|
||||
queryString = ((/\?/.test(ajax_path)) ? '&' : '?') + queryString;
|
||||
queryString = (/\?/.test(ajax_path) ? '&' : '?') + queryString;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,28 +46,16 @@
|
||||
setClick: true,
|
||||
event: 'click',
|
||||
selector: selector,
|
||||
progress: {type: 'fullscreen'}
|
||||
progress: { type: 'fullscreen' }
|
||||
};
|
||||
|
||||
this.settings = settings;
|
||||
|
||||
// Add the ajax to exposed forms.
|
||||
this.$exposed_form = $('form#views-exposed-form-' + settings.view_name.replace(/_/g, '-') + '-' + settings.view_display_id.replace(/_/g, '-'));
|
||||
this.$exposed_form.once('exposed-form').each($.proxy(this.attachExposedFormAjax, this));
|
||||
|
||||
// Add the ajax to pagers.
|
||||
this.$view
|
||||
// Don't attach to nested views. Doing so would attach multiple behaviors
|
||||
// to a given element.
|
||||
.filter($.proxy(this.filterNestedViews, this))
|
||||
.once('ajax-pager').each($.proxy(this.attachPagerAjax, this));
|
||||
this.$view.filter($.proxy(this.filterNestedViews, this)).once('ajax-pager').each($.proxy(this.attachPagerAjax, this));
|
||||
|
||||
// Add a trigger to update this view specifically. In order to trigger a
|
||||
// refresh use the following code.
|
||||
//
|
||||
// @code
|
||||
// $('.view-name').trigger('RefreshView');
|
||||
// @endcode
|
||||
var self_settings = $.extend({}, this.element_settings, {
|
||||
event: 'RefreshView',
|
||||
base: this.selector,
|
||||
@@ -108,14 +64,10 @@
|
||||
this.refreshViewAjax = Drupal.ajax(self_settings);
|
||||
};
|
||||
|
||||
/**
|
||||
* @method
|
||||
*/
|
||||
Drupal.views.ajaxView.prototype.attachExposedFormAjax = function () {
|
||||
var that = this;
|
||||
this.exposedFormAjax = [];
|
||||
// Exclude the reset buttons so no AJAX behaviours are bound. Many things
|
||||
// break during the form reset phase if using AJAX.
|
||||
|
||||
$('input[type=submit], input[type=image]', this.$exposed_form).not('[data-drupal-selector=edit-reset]').each(function (index) {
|
||||
var self_settings = $.extend({}, that.element_settings, {
|
||||
base: $(this).attr('id'),
|
||||
@@ -125,45 +77,20 @@
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {bool}
|
||||
* If there is at least one parent with a view class return false.
|
||||
*/
|
||||
Drupal.views.ajaxView.prototype.filterNestedViews = function () {
|
||||
// If there is at least one parent with a view class, this view
|
||||
// is nested (e.g., an attachment). Bail.
|
||||
return !this.$view.parents('.view').length;
|
||||
};
|
||||
|
||||
/**
|
||||
* Attach the ajax behavior to each link.
|
||||
*/
|
||||
Drupal.views.ajaxView.prototype.attachPagerAjax = function () {
|
||||
this.$view.find('ul.js-pager__items > li > a, th.views-field a, .attachment .views-summary a')
|
||||
.each($.proxy(this.attachPagerLinkAjax, this));
|
||||
this.$view.find('ul.js-pager__items > li > a, th.views-field a, .attachment .views-summary a').each($.proxy(this.attachPagerLinkAjax, this));
|
||||
};
|
||||
|
||||
/**
|
||||
* Attach the ajax behavior to a singe link.
|
||||
*
|
||||
* @param {string} [id]
|
||||
* The ID of the link.
|
||||
* @param {HTMLElement} link
|
||||
* The link element.
|
||||
*/
|
||||
Drupal.views.ajaxView.prototype.attachPagerLinkAjax = function (id, link) {
|
||||
var $link = $(link);
|
||||
var viewData = {};
|
||||
var href = $link.attr('href');
|
||||
// Construct an object using the settings defaults and then overriding
|
||||
// with data specific to the link.
|
||||
$.extend(
|
||||
viewData,
|
||||
this.settings,
|
||||
Drupal.Views.parseQueryString(href),
|
||||
// Extract argument data from the URL.
|
||||
Drupal.Views.parseViewArgs(href, this.settings.view_base_path)
|
||||
);
|
||||
|
||||
$.extend(viewData, this.settings, Drupal.Views.parseQueryString(href), Drupal.Views.parseViewArgs(href, this.settings.view_base_path));
|
||||
|
||||
var self_settings = $.extend({}, this.element_settings, {
|
||||
submit: viewData,
|
||||
@@ -173,33 +100,16 @@
|
||||
this.pagerAjax = Drupal.ajax(self_settings);
|
||||
};
|
||||
|
||||
/**
|
||||
* Views scroll to top ajax command.
|
||||
*
|
||||
* @param {Drupal.Ajax} [ajax]
|
||||
* A {@link Drupal.ajax} object.
|
||||
* @param {object} response
|
||||
* Ajax response.
|
||||
* @param {string} response.selector
|
||||
* Selector to use.
|
||||
*/
|
||||
Drupal.AjaxCommands.prototype.viewsScrollTop = function (ajax, response) {
|
||||
// Scroll to the top of the view. This will allow users
|
||||
// to browse newly loaded content after e.g. clicking a pager
|
||||
// link.
|
||||
var offset = $(response.selector).offset();
|
||||
// We can't guarantee that the scrollable object should be
|
||||
// the body, as the view could be embedded in something
|
||||
// more complex such as a modal popup. Recurse up the DOM
|
||||
// and scroll the first element that has a non-zero top.
|
||||
|
||||
var scrollTarget = response.selector;
|
||||
while ($(scrollTarget).scrollTop() === 0 && $(scrollTarget).parent()) {
|
||||
scrollTarget = $(scrollTarget).parent();
|
||||
}
|
||||
// Only scroll upward.
|
||||
|
||||
if (offset.top - 10 < $(scrollTarget).scrollTop()) {
|
||||
$(scrollTarget).animate({scrollTop: (offset.top - 10)}, 500);
|
||||
$(scrollTarget).animate({ scrollTop: offset.top - 10 }, 500);
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery, Drupal, drupalSettings);
|
||||
})(jQuery, Drupal, drupalSettings);
|
||||
@@ -0,0 +1,106 @@
|
||||
/**
|
||||
* @file
|
||||
* Some basic behaviors and utility functions for Views.
|
||||
*/
|
||||
|
||||
(function ($, Drupal, drupalSettings) {
|
||||
/**
|
||||
* @namespace
|
||||
*/
|
||||
Drupal.Views = {};
|
||||
|
||||
/**
|
||||
* Helper function to parse a querystring.
|
||||
*
|
||||
* @param {string} query
|
||||
* The querystring to parse.
|
||||
*
|
||||
* @return {object}
|
||||
* A map of query parameters.
|
||||
*/
|
||||
Drupal.Views.parseQueryString = function (query) {
|
||||
const args = {};
|
||||
const pos = query.indexOf('?');
|
||||
if (pos !== -1) {
|
||||
query = query.substring(pos + 1);
|
||||
}
|
||||
let pair;
|
||||
const pairs = query.split('&');
|
||||
for (let i = 0; i < pairs.length; i++) {
|
||||
pair = pairs[i].split('=');
|
||||
// Ignore the 'q' path argument, if present.
|
||||
if (pair[0] !== 'q' && pair[1]) {
|
||||
args[decodeURIComponent(pair[0].replace(/\+/g, ' '))] = decodeURIComponent(pair[1].replace(/\+/g, ' '));
|
||||
}
|
||||
}
|
||||
return args;
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper function to return a view's arguments based on a path.
|
||||
*
|
||||
* @param {string} href
|
||||
* The href to check.
|
||||
* @param {string} viewPath
|
||||
* The views path to check.
|
||||
*
|
||||
* @return {object}
|
||||
* An object containing `view_args` and `view_path`.
|
||||
*/
|
||||
Drupal.Views.parseViewArgs = function (href, viewPath) {
|
||||
const returnObj = {};
|
||||
const path = Drupal.Views.getPath(href);
|
||||
// Get viewPath url without baseUrl portion.
|
||||
const viewHref = Drupal.url(viewPath).substring(drupalSettings.path.baseUrl.length);
|
||||
// Ensure we have a correct path.
|
||||
if (viewHref && path.substring(0, viewHref.length + 1) === `${viewHref}/`) {
|
||||
returnObj.view_args = decodeURIComponent(path.substring(viewHref.length + 1, path.length));
|
||||
returnObj.view_path = path;
|
||||
}
|
||||
return returnObj;
|
||||
};
|
||||
|
||||
/**
|
||||
* Strip off the protocol plus domain from an href.
|
||||
*
|
||||
* @param {string} href
|
||||
* The href to strip.
|
||||
*
|
||||
* @return {string}
|
||||
* The href without the protocol and domain.
|
||||
*/
|
||||
Drupal.Views.pathPortion = function (href) {
|
||||
// Remove e.g. http://example.com if present.
|
||||
const protocol = window.location.protocol;
|
||||
if (href.substring(0, protocol.length) === protocol) {
|
||||
// 2 is the length of the '//' that normally follows the protocol.
|
||||
href = href.substring(href.indexOf('/', protocol.length + 2));
|
||||
}
|
||||
return href;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the Drupal path portion of an href.
|
||||
*
|
||||
* @param {string} href
|
||||
* The href to check.
|
||||
*
|
||||
* @return {string}
|
||||
* An internal path.
|
||||
*/
|
||||
Drupal.Views.getPath = function (href) {
|
||||
href = Drupal.Views.pathPortion(href);
|
||||
href = href.substring(drupalSettings.path.baseUrl.length, href.length);
|
||||
// 3 is the length of the '?q=' added to the url without clean urls.
|
||||
if (href.substring(0, 3) === '?q=') {
|
||||
href = href.substring(3, href.length);
|
||||
}
|
||||
const chars = ['#', '?', '&'];
|
||||
for (let i = 0; i < chars.length; i++) {
|
||||
if (href.indexOf(chars[i]) > -1) {
|
||||
href = href.substr(0, href.indexOf(chars[i]));
|
||||
}
|
||||
}
|
||||
return href;
|
||||
};
|
||||
}(jQuery, Drupal, drupalSettings));
|
||||
@@ -1,37 +1,24 @@
|
||||
/**
|
||||
* @file
|
||||
* Some basic behaviors and utility functions for Views.
|
||||
*/
|
||||
* DO NOT EDIT THIS FILE.
|
||||
* See the following change record for more information,
|
||||
* https://www.drupal.org/node/2815083
|
||||
* @preserve
|
||||
**/
|
||||
|
||||
(function ($, Drupal, drupalSettings) {
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @namespace
|
||||
*/
|
||||
Drupal.Views = {};
|
||||
|
||||
/**
|
||||
* Helper function to parse a querystring.
|
||||
*
|
||||
* @param {string} query
|
||||
* The querystring to parse.
|
||||
*
|
||||
* @return {object}
|
||||
* A map of query parameters.
|
||||
*/
|
||||
Drupal.Views.parseQueryString = function (query) {
|
||||
var args = {};
|
||||
var pos = query.indexOf('?');
|
||||
if (pos !== -1) {
|
||||
query = query.substring(pos + 1);
|
||||
}
|
||||
var pair;
|
||||
var pair = void 0;
|
||||
var pairs = query.split('&');
|
||||
for (var i = 0; i < pairs.length; i++) {
|
||||
pair = pairs[i].split('=');
|
||||
// Ignore the 'q' path argument, if present.
|
||||
|
||||
if (pair[0] !== 'q' && pair[1]) {
|
||||
args[decodeURIComponent(pair[0].replace(/\+/g, ' '))] = decodeURIComponent(pair[1].replace(/\+/g, ' '));
|
||||
}
|
||||
@@ -39,23 +26,12 @@
|
||||
return args;
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper function to return a view's arguments based on a path.
|
||||
*
|
||||
* @param {string} href
|
||||
* The href to check.
|
||||
* @param {string} viewPath
|
||||
* The views path to check.
|
||||
*
|
||||
* @return {object}
|
||||
* An object containing `view_args` and `view_path`.
|
||||
*/
|
||||
Drupal.Views.parseViewArgs = function (href, viewPath) {
|
||||
var returnObj = {};
|
||||
var path = Drupal.Views.getPath(href);
|
||||
// Get viewPath url without baseUrl portion.
|
||||
|
||||
var viewHref = Drupal.url(viewPath).substring(drupalSettings.path.baseUrl.length);
|
||||
// Ensure we have a correct path.
|
||||
|
||||
if (viewHref && path.substring(0, viewHref.length + 1) === viewHref + '/') {
|
||||
returnObj.view_args = decodeURIComponent(path.substring(viewHref.length + 1, path.length));
|
||||
returnObj.view_path = path;
|
||||
@@ -63,38 +39,18 @@
|
||||
return returnObj;
|
||||
};
|
||||
|
||||
/**
|
||||
* Strip off the protocol plus domain from an href.
|
||||
*
|
||||
* @param {string} href
|
||||
* The href to strip.
|
||||
*
|
||||
* @return {string}
|
||||
* The href without the protocol and domain.
|
||||
*/
|
||||
Drupal.Views.pathPortion = function (href) {
|
||||
// Remove e.g. http://example.com if present.
|
||||
var protocol = window.location.protocol;
|
||||
if (href.substring(0, protocol.length) === protocol) {
|
||||
// 2 is the length of the '//' that normally follows the protocol.
|
||||
href = href.substring(href.indexOf('/', protocol.length + 2));
|
||||
}
|
||||
return href;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the Drupal path portion of an href.
|
||||
*
|
||||
* @param {string} href
|
||||
* The href to check.
|
||||
*
|
||||
* @return {string}
|
||||
* An internal path.
|
||||
*/
|
||||
Drupal.Views.getPath = function (href) {
|
||||
href = Drupal.Views.pathPortion(href);
|
||||
href = href.substring(drupalSettings.path.baseUrl.length, href.length);
|
||||
// 3 is the length of the '?q=' added to the url without clean urls.
|
||||
|
||||
if (href.substring(0, 3) === '?q=') {
|
||||
href = href.substring(3, href.length);
|
||||
}
|
||||
@@ -106,5 +62,4 @@
|
||||
}
|
||||
return href;
|
||||
};
|
||||
|
||||
})(jQuery, Drupal, drupalSettings);
|
||||
})(jQuery, Drupal, drupalSettings);
|
||||
@@ -77,7 +77,7 @@ class Analyzer {
|
||||
'#theme' => 'item_list',
|
||||
'#items' => $messages,
|
||||
];
|
||||
$message = drupal_render($item_list);
|
||||
$message = \Drupal::service('renderer')->render($item_list);
|
||||
}
|
||||
elseif ($messages) {
|
||||
$message = array_shift($messages);
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Drupal\views\Annotation;
|
||||
|
||||
|
||||
/**
|
||||
* Defines a Plugin annotation object for views access plugins.
|
||||
*
|
||||
|
||||
@@ -142,7 +142,7 @@ class ViewAjaxController implements ContainerInjectionInterface {
|
||||
throw new NotFoundHttpException();
|
||||
}
|
||||
$view = $this->executableFactory->get($entity);
|
||||
if ($view && $view->access($display_id) && $view->setDisplay($display_id) && $view->display_handler->getOption('use_ajax')) {
|
||||
if ($view && $view->access($display_id) && $view->setDisplay($display_id) && $view->display_handler->ajaxEnabled()) {
|
||||
$response->setView($view);
|
||||
// Fix the current path for paging.
|
||||
if (!empty($path)) {
|
||||
@@ -181,7 +181,7 @@ class ViewAjaxController implements ContainerInjectionInterface {
|
||||
$view->dom_id = $dom_id;
|
||||
|
||||
$context = new RenderContext();
|
||||
$preview = $this->renderer->executeInRenderContext($context, function() use ($view, $display_id, $args) {
|
||||
$preview = $this->renderer->executeInRenderContext($context, function () use ($view, $display_id, $args) {
|
||||
return $view->preview($display_id, $args);
|
||||
});
|
||||
if (!$context->isEmpty()) {
|
||||
|
||||
@@ -28,15 +28,54 @@ class TranslationLanguageRenderer extends EntityTranslationRendererBase {
|
||||
if (!$this->languageManager->isMultilingual() || !$this->entityType->hasKey('langcode')) {
|
||||
return;
|
||||
}
|
||||
$langcode_key = $this->entityType->getKey('langcode');
|
||||
$storage = \Drupal::entityManager()->getStorage($this->entityType->id());
|
||||
|
||||
if ($table = $storage->getTableMapping()->getFieldTableName($langcode_key)) {
|
||||
$table_alias = $query->ensureTable($table, $relationship);
|
||||
$langcode_table = $this->getLangcodeTable($query, $relationship);
|
||||
if ($langcode_table) {
|
||||
/** @var \Drupal\views\Plugin\views\query\Sql $query */
|
||||
$table_alias = $query->ensureTable($langcode_table, $relationship);
|
||||
$langcode_key = $this->entityType->getKey('langcode');
|
||||
$this->langcodeAlias = $query->addField($table_alias, $langcode_key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the table holding the "langcode" field.
|
||||
*
|
||||
* @param \Drupal\views\Plugin\views\query\QueryPluginBase $query
|
||||
* The query being executed.
|
||||
* @param string $relationship
|
||||
* The relationship used by the entity type.
|
||||
*
|
||||
* @return string
|
||||
* A table name.
|
||||
*/
|
||||
protected function getLangcodeTable(QueryPluginBase $query, $relationship) {
|
||||
/** @var \Drupal\Core\Entity\Sql\SqlContentEntityStorage $storage */
|
||||
$storage = \Drupal::entityTypeManager()->getStorage($this->entityType->id());
|
||||
$langcode_key = $this->entityType->getKey('langcode');
|
||||
$langcode_table = $storage->getTableMapping()->getFieldTableName($langcode_key);
|
||||
|
||||
// If the entity type is revisionable, we need to take into account views of
|
||||
// entity revisions. Usually the view will use the entity data table as the
|
||||
// query base table, however, in case of an entity revision view, we need to
|
||||
// use the revision table or the revision data table, depending on which one
|
||||
// is being used as query base table.
|
||||
if ($this->entityType->isRevisionable()) {
|
||||
$query_base_table = isset($query->relationships[$relationship]['base']) ?
|
||||
$query->relationships[$relationship]['base'] :
|
||||
$this->view->storage->get('base_table');
|
||||
$revision_table = $storage->getRevisionTable();
|
||||
$revision_data_table = $storage->getRevisionDataTable();
|
||||
if ($query_base_table === $revision_table) {
|
||||
$langcode_table = $revision_table;
|
||||
}
|
||||
elseif ($query_base_table === $revision_data_table) {
|
||||
$langcode_table = $revision_data_table;
|
||||
}
|
||||
}
|
||||
|
||||
return $langcode_table;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -5,8 +5,11 @@ namespace Drupal\views\Entity;
|
||||
use Drupal\Component\Utility\NestedArray;
|
||||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\Core\Config\Entity\ConfigEntityBase;
|
||||
use Drupal\Core\Entity\ContentEntityTypeInterface;
|
||||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
use Drupal\Core\Entity\FieldableEntityInterface;
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\views\Plugin\DependentWithRemovalPluginInterface;
|
||||
use Drupal\views\Views;
|
||||
use Drupal\views\ViewEntityInterface;
|
||||
|
||||
@@ -16,9 +19,6 @@ use Drupal\views\ViewEntityInterface;
|
||||
* @ConfigEntityType(
|
||||
* id = "view",
|
||||
* label = @Translation("View", context = "View entity type"),
|
||||
* handlers = {
|
||||
* "access" = "Drupal\views\ViewAccessControlHandler"
|
||||
* },
|
||||
* admin_permission = "administer views",
|
||||
* entity_keys = {
|
||||
* "id" = "id",
|
||||
@@ -290,10 +290,13 @@ class View extends ConfigEntityBase implements ViewEntityInterface {
|
||||
public function preSave(EntityStorageInterface $storage) {
|
||||
parent::preSave($storage);
|
||||
|
||||
$displays = $this->get('display');
|
||||
|
||||
$this->fixTableNames($displays);
|
||||
|
||||
// Sort the displays.
|
||||
$display = $this->get('display');
|
||||
ksort($display);
|
||||
$this->set('display', ['default' => $display['default']] + $display);
|
||||
ksort($displays);
|
||||
$this->set('display', ['default' => $displays['default']] + $displays);
|
||||
|
||||
// @todo Check whether isSyncing is needed.
|
||||
if (!$this->isSyncing()) {
|
||||
@@ -301,6 +304,45 @@ class View extends ConfigEntityBase implements ViewEntityInterface {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fixes table names for revision metadata fields of revisionable entities.
|
||||
*
|
||||
* Views for revisionable entity types using revision metadata fields might
|
||||
* be using the wrong table to retrieve the fields after system_update_8300
|
||||
* has moved them correctly to the revision table. This method updates the
|
||||
* views to use the correct tables.
|
||||
*
|
||||
* @param array &$displays
|
||||
* An array containing display handlers of a view.
|
||||
*
|
||||
* @deprecated in Drupal 8.3.0, will be removed in Drupal 9.0.0.
|
||||
*/
|
||||
private function fixTableNames(array &$displays) {
|
||||
// Fix wrong table names for entity revision metadata fields.
|
||||
foreach ($displays as $display => $display_data) {
|
||||
if (isset($display_data['display_options']['fields'])) {
|
||||
foreach ($display_data['display_options']['fields'] as $property_name => $property_data) {
|
||||
if (isset($property_data['entity_type']) && isset($property_data['field']) && isset($property_data['table'])) {
|
||||
$entity_type = $this->entityTypeManager()->getDefinition($property_data['entity_type']);
|
||||
// We need to update the table name only for revisionable entity
|
||||
// types, otherwise the view is already using the correct table.
|
||||
if (($entity_type instanceof ContentEntityTypeInterface) && is_subclass_of($entity_type->getClass(), FieldableEntityInterface::class) && $entity_type->isRevisionable()) {
|
||||
$revision_metadata_fields = $entity_type->getRevisionMetadataKeys();
|
||||
// @see \Drupal\Core\Entity\Sql\SqlContentEntityStorage::initTableLayout()
|
||||
$revision_table = $entity_type->getRevisionTable() ?: $entity_type->id() . '_revision';
|
||||
|
||||
// Check if this is a revision metadata field and if it uses the
|
||||
// wrong table.
|
||||
if (in_array($property_data['field'], $revision_metadata_fields) && $property_data['table'] != $revision_table) {
|
||||
$displays[$display]['display_options']['fields'][$property_name]['table'] = $revision_table;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills in the cache metadata of this view.
|
||||
*
|
||||
@@ -468,4 +510,61 @@ class View extends ConfigEntityBase implements ViewEntityInterface {
|
||||
\Drupal::service('cache_tags.invalidator')->invalidateTags($tags);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function onDependencyRemoval(array $dependencies) {
|
||||
$changed = FALSE;
|
||||
|
||||
// Don't intervene if the views module is removed.
|
||||
if (isset($dependencies['module']) && in_array('views', $dependencies['module'])) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// If the base table for the View is provided by a module being removed, we
|
||||
// delete the View because this is not something that can be fixed manually.
|
||||
$views_data = Views::viewsData();
|
||||
$base_table = $this->get('base_table');
|
||||
$base_table_data = $views_data->get($base_table);
|
||||
if (!empty($base_table_data['table']['provider']) && in_array($base_table_data['table']['provider'], $dependencies['module'])) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$current_display = $this->getExecutable()->current_display;
|
||||
$handler_types = Views::getHandlerTypes();
|
||||
|
||||
// Find all the handlers and check whether they want to do something on
|
||||
// dependency removal.
|
||||
foreach ($this->display as $display_id => $display_plugin_base) {
|
||||
$this->getExecutable()->setDisplay($display_id);
|
||||
$display = $this->getExecutable()->getDisplay();
|
||||
|
||||
foreach (array_keys($handler_types) as $handler_type) {
|
||||
$handlers = $display->getHandlers($handler_type);
|
||||
foreach ($handlers as $handler_id => $handler) {
|
||||
if ($handler instanceof DependentWithRemovalPluginInterface) {
|
||||
if ($handler->onDependencyRemoval($dependencies)) {
|
||||
// Remove the handler and indicate we made changes.
|
||||
unset($this->display[$display_id]['display_options'][$handler_types[$handler_type]['plural']][$handler_id]);
|
||||
$changed = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Disable the View if we made changes.
|
||||
// @todo https://www.drupal.org/node/2832558 Give better feedback for
|
||||
// disabled config.
|
||||
if ($changed) {
|
||||
// Force a recalculation of the dependencies if we made changes.
|
||||
$this->getExecutable()->current_display = NULL;
|
||||
$this->calculateDependencies();
|
||||
$this->disable();
|
||||
}
|
||||
|
||||
$this->getExecutable()->setDisplay($current_display);
|
||||
return $changed;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -236,6 +236,13 @@ class EntityViewsData implements EntityHandlerInterface, EntityViewsDataInterfac
|
||||
'type' => 'INNER',
|
||||
];
|
||||
}
|
||||
|
||||
// Add a filter for showing only the latest revisions of an entity.
|
||||
$data[$revision_table]['latest_revision'] = [
|
||||
'title' => $this->t('Is Latest Revision'),
|
||||
'help' => $this->t('Restrict the view to only revisions that are the latest revision of their entity.'),
|
||||
'filter' => ['id' => 'latest_revision'],
|
||||
];
|
||||
}
|
||||
|
||||
$this->addEntityLinks($data[$base_table]);
|
||||
@@ -300,7 +307,7 @@ class EntityViewsData implements EntityHandlerInterface, EntityViewsDataInterfac
|
||||
|
||||
// Add the entity type key to each table generated.
|
||||
$entity_type_id = $this->entityType->id();
|
||||
array_walk($data, function(&$table_data) use ($entity_type_id){
|
||||
array_walk($data, function (&$table_data) use ($entity_type_id) {
|
||||
$table_data['table']['entity type'] = $entity_type_id;
|
||||
});
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Drupal\views;
|
||||
|
||||
use Drupal\Core\Database\Query\Condition;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\views\Plugin\views\HandlerBase;
|
||||
|
||||
@@ -268,8 +269,8 @@ class ManyToOneHelper {
|
||||
$options['group'] = 0;
|
||||
}
|
||||
|
||||
// add_condition determines whether a single expression is enough(FALSE) or the
|
||||
// conditions should be added via an db_or()/db_and() (TRUE).
|
||||
// If $add_condition is set to FALSE, a single expression is enough. If it
|
||||
// is set to TRUE, conditions will be added.
|
||||
$add_condition = TRUE;
|
||||
if ($operator == 'not') {
|
||||
$value = NULL;
|
||||
@@ -326,7 +327,7 @@ class ManyToOneHelper {
|
||||
|
||||
if ($add_condition) {
|
||||
$field = $this->handler->realField;
|
||||
$clause = $operator == 'or' ? db_or() : db_and();
|
||||
$clause = $operator == 'or' ? new Condition('OR') : new Condition('AND');
|
||||
foreach ($this->handler->tableAliases as $value => $alias) {
|
||||
$clause->condition("$alias.$field", $value);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\views\Plugin\Block;
|
||||
|
||||
use Drupal\Core\Cache\Cache;
|
||||
|
||||
/**
|
||||
@@ -24,9 +25,23 @@ class ViewsExposedFilterBlock extends ViewsBlockBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return array
|
||||
* A renderable array representing the content of the block with additional
|
||||
* context of current view and display ID.
|
||||
*/
|
||||
public function build() {
|
||||
$output = $this->view->display_handler->viewExposedFormBlocks();
|
||||
// Provide the context for block build and block view alter hooks.
|
||||
// \Drupal\views\Plugin\Block\ViewsBlock::build() adds the same context in
|
||||
// \Drupal\views\ViewExecutable::buildRenderable() using
|
||||
// \Drupal\views\Plugin\views\display\DisplayPluginBase::buildRenderable().
|
||||
if (is_array($output) && !empty($output)) {
|
||||
$output += [
|
||||
'#view' => $this->view,
|
||||
'#display_id' => $this->displayID,
|
||||
];
|
||||
}
|
||||
|
||||
// Before returning the block output, convert it to a renderable array with
|
||||
// contextual links.
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\views\Plugin;
|
||||
|
||||
/**
|
||||
* Provides an interface for a plugin that has dependencies that can be removed.
|
||||
*
|
||||
* @ingroup views_plugins
|
||||
*/
|
||||
interface DependentWithRemovalPluginInterface {
|
||||
|
||||
/**
|
||||
* Allows a plugin to define whether it should be removed.
|
||||
*
|
||||
* If this method returns TRUE then the plugin should be removed.
|
||||
*
|
||||
* @param array $dependencies
|
||||
* An array of dependencies that will be deleted keyed by dependency type.
|
||||
* Dependency types are, for example, entity, module and theme.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the plugin instance should be removed.
|
||||
*
|
||||
* @see \Drupal\Core\Config\Entity\ConfigDependencyManager
|
||||
* @see \Drupal\Core\Config\ConfigEntityBase::preDelete()
|
||||
* @see \Drupal\Core\Config\ConfigManager::uninstall()
|
||||
* @see \Drupal\Core\Entity\EntityDisplayBase::onDependencyRemoval()
|
||||
*/
|
||||
public function onDependencyRemoval(array $dependencies);
|
||||
|
||||
}
|
||||
@@ -2,17 +2,12 @@
|
||||
|
||||
namespace Drupal\views\Plugin\EntityReferenceSelection;
|
||||
|
||||
use Drupal\Core\Database\Query\SelectInterface;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginBase;
|
||||
use Drupal\Core\Entity\EntityReferenceSelection\SelectionTrait;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\Core\Plugin\PluginBase;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\views\Views;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Plugin implementation of the 'selection' entity_reference.
|
||||
@@ -24,66 +19,9 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
* weight = 0
|
||||
* )
|
||||
*/
|
||||
class ViewsSelection extends PluginBase implements SelectionInterface, ContainerFactoryPluginInterface {
|
||||
class ViewsSelection extends SelectionPluginBase implements ContainerFactoryPluginInterface {
|
||||
|
||||
/**
|
||||
* The entity manager.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityManagerInterface
|
||||
*/
|
||||
protected $entityManager;
|
||||
|
||||
/**
|
||||
* The module handler service.
|
||||
*
|
||||
* @var \Drupal\Core\Extension\ModuleHandlerInterface
|
||||
*/
|
||||
protected $moduleHandler;
|
||||
|
||||
/**
|
||||
* The current user.
|
||||
*
|
||||
* @var \Drupal\Core\Session\AccountInterface
|
||||
*/
|
||||
protected $currentUser;
|
||||
|
||||
/**
|
||||
* Constructs a new SelectionBase object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager service.
|
||||
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
|
||||
* The module handler service.
|
||||
* @param \Drupal\Core\Session\AccountInterface $current_user
|
||||
* The current user.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityManagerInterface $entity_manager, ModuleHandlerInterface $module_handler, AccountInterface $current_user) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
|
||||
$this->entityManager = $entity_manager;
|
||||
$this->moduleHandler = $module_handler;
|
||||
$this->currentUser = $current_user;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$container->get('entity.manager'),
|
||||
$container->get('module_handler'),
|
||||
$container->get('current_user')
|
||||
);
|
||||
}
|
||||
use SelectionTrait;
|
||||
|
||||
/**
|
||||
* The loaded View object.
|
||||
@@ -92,12 +30,26 @@ class ViewsSelection extends PluginBase implements SelectionInterface, Container
|
||||
*/
|
||||
protected $view;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function defaultConfiguration() {
|
||||
return [
|
||||
'view' => [
|
||||
'view_name' => NULL,
|
||||
'display_name' => NULL,
|
||||
'arguments' => [],
|
||||
],
|
||||
] + parent::defaultConfiguration();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
|
||||
$selection_handler_settings = $this->configuration['handler_settings'];
|
||||
$view_settings = !empty($selection_handler_settings['view']) ? $selection_handler_settings['view'] : [];
|
||||
$form = parent::buildConfigurationForm($form, $form_state);
|
||||
|
||||
$view_settings = $this->getConfiguration()['view'];
|
||||
$displays = Views::getApplicableViews('entity_reference_display');
|
||||
// Filter views that list the entity type we want, and group the separate
|
||||
// displays by view.
|
||||
@@ -156,16 +108,6 @@ class ViewsSelection extends PluginBase implements SelectionInterface, Container
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { }
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { }
|
||||
|
||||
/**
|
||||
* Initializes a view.
|
||||
*
|
||||
@@ -184,9 +126,8 @@ class ViewsSelection extends PluginBase implements SelectionInterface, Container
|
||||
* Return TRUE if the view was initialized, FALSE otherwise.
|
||||
*/
|
||||
protected function initializeView($match = NULL, $match_operator = 'CONTAINS', $limit = 0, $ids = NULL) {
|
||||
$handler_settings = $this->configuration['handler_settings'];
|
||||
$view_name = $handler_settings['view']['view_name'];
|
||||
$display_name = $handler_settings['view']['display_name'];
|
||||
$view_name = $this->getConfiguration()['view']['view_name'];
|
||||
$display_name = $this->getConfiguration()['view']['display_name'];
|
||||
|
||||
// Check that the view is valid and the display still exists.
|
||||
$this->view = Views::getView($view_name);
|
||||
@@ -211,9 +152,8 @@ class ViewsSelection extends PluginBase implements SelectionInterface, Container
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getReferenceableEntities($match = NULL, $match_operator = 'CONTAINS', $limit = 0) {
|
||||
$handler_settings = $this->configuration['handler_settings'];
|
||||
$display_name = $handler_settings['view']['display_name'];
|
||||
$arguments = $handler_settings['view']['arguments'];
|
||||
$display_name = $this->getConfiguration()['view']['display_name'];
|
||||
$arguments = $this->getConfiguration()['view']['arguments'];
|
||||
$result = [];
|
||||
if ($this->initializeView($match, $match_operator, $limit)) {
|
||||
// Get the results.
|
||||
@@ -242,9 +182,8 @@ class ViewsSelection extends PluginBase implements SelectionInterface, Container
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validateReferenceableEntities(array $ids) {
|
||||
$handler_settings = $this->configuration['handler_settings'];
|
||||
$display_name = $handler_settings['view']['display_name'];
|
||||
$arguments = $handler_settings['view']['arguments'];
|
||||
$display_name = $this->getConfiguration()['view']['display_name'];
|
||||
$arguments = $this->getConfiguration()['view']['arguments'];
|
||||
$result = [];
|
||||
if ($this->initializeView(NULL, 'CONTAINS', 0, $ids)) {
|
||||
// Get the results.
|
||||
@@ -283,9 +222,4 @@ class ViewsSelection extends PluginBase implements SelectionInterface, Container
|
||||
$form_state->setValueForElement($element, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function entityQueryAlter(SelectInterface $query) { }
|
||||
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ trait BrokenHandlerTrait {
|
||||
}
|
||||
}
|
||||
|
||||
$description_bottom = t('Enabling the appropriate module will may solve this issue. Otherwise, check to see if there is a module update available.');
|
||||
$description_bottom = t('Enabling the appropriate module may solve this issue. Otherwise, check to see if there is a module update available.');
|
||||
|
||||
$form['description'] = [
|
||||
'#type' => 'container',
|
||||
|
||||
@@ -214,16 +214,16 @@ abstract class HandlerBase extends PluginBase implements ViewsHandlerInterface {
|
||||
* Transform a string by a certain method.
|
||||
*
|
||||
* @param $string
|
||||
* The input you want to transform.
|
||||
* The input you want to transform.
|
||||
* @param $option
|
||||
* How do you want to transform it, possible values:
|
||||
* - upper: Uppercase the string.
|
||||
* - lower: lowercase the string.
|
||||
* - ucfirst: Make the first char uppercase.
|
||||
* - ucwords: Make each word in the string uppercase.
|
||||
* How do you want to transform it, possible values:
|
||||
* - upper: Uppercase the string.
|
||||
* - lower: lowercase the string.
|
||||
* - ucfirst: Make the first char uppercase.
|
||||
* - ucwords: Make each word in the string uppercase.
|
||||
*
|
||||
* @return string
|
||||
* The transformed string.
|
||||
* The transformed string.
|
||||
*/
|
||||
protected function caseTransform($string, $option) {
|
||||
switch ($option) {
|
||||
@@ -350,80 +350,84 @@ abstract class HandlerBase extends PluginBase implements ViewsHandlerInterface {
|
||||
* If a handler has 'extra options' it will get a little settings widget and
|
||||
* another form called extra_options.
|
||||
*/
|
||||
public function hasExtraOptions() { return FALSE; }
|
||||
public function hasExtraOptions() {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide defaults for the handler.
|
||||
*/
|
||||
public function defineExtraOptions(&$option) { }
|
||||
public function defineExtraOptions(&$option) {}
|
||||
|
||||
/**
|
||||
* Provide a form for setting options.
|
||||
*/
|
||||
public function buildExtraOptionsForm(&$form, FormStateInterface $form_state) { }
|
||||
public function buildExtraOptionsForm(&$form, FormStateInterface $form_state) {}
|
||||
|
||||
/**
|
||||
* Validate the options form.
|
||||
*/
|
||||
public function validateExtraOptionsForm($form, FormStateInterface $form_state) { }
|
||||
public function validateExtraOptionsForm($form, FormStateInterface $form_state) {}
|
||||
|
||||
/**
|
||||
* Perform any necessary changes to the form values prior to storage.
|
||||
* There is no need for this function to actually store the data.
|
||||
*/
|
||||
public function submitExtraOptionsForm($form, FormStateInterface $form_state) { }
|
||||
public function submitExtraOptionsForm($form, FormStateInterface $form_state) {}
|
||||
|
||||
/**
|
||||
* Determine if a handler can be exposed.
|
||||
*/
|
||||
public function canExpose() { return FALSE; }
|
||||
public function canExpose() {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set new exposed option defaults when exposed setting is flipped
|
||||
* on.
|
||||
*/
|
||||
public function defaultExposeOptions() { }
|
||||
public function defaultExposeOptions() {}
|
||||
|
||||
/**
|
||||
* Get information about the exposed form for the form renderer.
|
||||
*/
|
||||
public function exposedInfo() { }
|
||||
public function exposedInfo() {}
|
||||
|
||||
/**
|
||||
* Render our chunk of the exposed handler form when selecting
|
||||
*/
|
||||
public function buildExposedForm(&$form, FormStateInterface $form_state) { }
|
||||
public function buildExposedForm(&$form, FormStateInterface $form_state) {}
|
||||
|
||||
/**
|
||||
* Validate the exposed handler form
|
||||
*/
|
||||
public function validateExposed(&$form, FormStateInterface $form_state) { }
|
||||
public function validateExposed(&$form, FormStateInterface $form_state) {}
|
||||
|
||||
/**
|
||||
* Submit the exposed handler form
|
||||
*/
|
||||
public function submitExposed(&$form, FormStateInterface $form_state) { }
|
||||
public function submitExposed(&$form, FormStateInterface $form_state) {}
|
||||
|
||||
/**
|
||||
* Form for exposed handler options.
|
||||
*/
|
||||
public function buildExposeForm(&$form, FormStateInterface $form_state) { }
|
||||
public function buildExposeForm(&$form, FormStateInterface $form_state) {}
|
||||
|
||||
/**
|
||||
* Validate the options form.
|
||||
*/
|
||||
public function validateExposeForm($form, FormStateInterface $form_state) { }
|
||||
public function validateExposeForm($form, FormStateInterface $form_state) {}
|
||||
|
||||
/**
|
||||
* Perform any necessary changes to the form exposes prior to storage.
|
||||
* There is no need for this function to actually store the data.
|
||||
*/
|
||||
public function submitExposeForm($form, FormStateInterface $form_state) { }
|
||||
public function submitExposeForm($form, FormStateInterface $form_state) {}
|
||||
|
||||
/**
|
||||
* Shortcut to display the expose/hide button.
|
||||
*/
|
||||
public function showExposeButton(&$form, FormStateInterface $form_state) { }
|
||||
public function showExposeButton(&$form, FormStateInterface $form_state) {}
|
||||
|
||||
/**
|
||||
* Shortcut to display the exposed options form.
|
||||
@@ -477,7 +481,7 @@ abstract class HandlerBase extends PluginBase implements ViewsHandlerInterface {
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function postExecute(&$values) { }
|
||||
public function postExecute(&$values) {}
|
||||
|
||||
/**
|
||||
* Provides a unique placeholders for handlers.
|
||||
@@ -531,7 +535,7 @@ abstract class HandlerBase extends PluginBase implements ViewsHandlerInterface {
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function adminSummary() { }
|
||||
public function adminSummary() {}
|
||||
|
||||
/**
|
||||
* Determine if this item is 'exposed', meaning it provides form elements
|
||||
@@ -546,24 +550,32 @@ abstract class HandlerBase extends PluginBase implements ViewsHandlerInterface {
|
||||
/**
|
||||
* Returns TRUE if the exposed filter works like a grouped filter.
|
||||
*/
|
||||
public function isAGroup() { return FALSE; }
|
||||
public function isAGroup() {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define if the exposed input has to be submitted multiple times.
|
||||
* This is TRUE when exposed filters grouped are using checkboxes as
|
||||
* widgets.
|
||||
*/
|
||||
public function multipleExposedInput() { return FALSE; }
|
||||
public function multipleExposedInput() {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Take input from exposed handlers and assign to this handler, if necessary.
|
||||
*/
|
||||
public function acceptExposedInput($input) { return TRUE; }
|
||||
public function acceptExposedInput($input) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* If set to remember exposed input in the session, store it there.
|
||||
*/
|
||||
public function storeExposedInput($input, $status) { return TRUE; }
|
||||
public function storeExposedInput($input, $status) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
@@ -587,7 +599,9 @@ abstract class HandlerBase extends PluginBase implements ViewsHandlerInterface {
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validate() { return []; }
|
||||
public function validate() {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
||||
@@ -155,7 +155,9 @@ abstract class PluginBase extends ComponentPluginBase implements ContainerFactor
|
||||
* @return array
|
||||
* Returns the options of this handler/plugin.
|
||||
*/
|
||||
protected function defineOptions() { return []; }
|
||||
protected function defineOptions() {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills up the options of the plugin with defaults.
|
||||
@@ -271,17 +273,17 @@ abstract class PluginBase extends ComponentPluginBase implements ContainerFactor
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validateOptionsForm(&$form, FormStateInterface $form_state) { }
|
||||
public function validateOptionsForm(&$form, FormStateInterface $form_state) {}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitOptionsForm(&$form, FormStateInterface $form_state) { }
|
||||
public function submitOptionsForm(&$form, FormStateInterface $form_state) {}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() { }
|
||||
public function query() {}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
@@ -293,7 +295,9 @@ abstract class PluginBase extends ComponentPluginBase implements ContainerFactor
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validate() { return []; }
|
||||
public function validate() {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
@@ -351,7 +355,7 @@ abstract class PluginBase extends ComponentPluginBase implements ContainerFactor
|
||||
foreach ($tokens as $token => $replacement) {
|
||||
// Twig wants a token replacement array stripped of curly-brackets.
|
||||
// Some Views tokens come with curly-braces, others do not.
|
||||
//@todo: https://www.drupal.org/node/2544392
|
||||
// @todo: https://www.drupal.org/node/2544392
|
||||
if (strpos($token, '{{') !== FALSE) {
|
||||
// Twig wants a token replacement array stripped of curly-brackets.
|
||||
$token = trim(str_replace(['{{', '}}'], '', $token));
|
||||
|
||||
@@ -107,7 +107,7 @@ abstract class AreaPluginBase extends HandlerBase {
|
||||
* @return array
|
||||
* In any case we need a valid Drupal render array to return.
|
||||
*/
|
||||
public abstract function render($empty = FALSE);
|
||||
abstract public function render($empty = FALSE);
|
||||
|
||||
/**
|
||||
* Does that area have nothing to show.
|
||||
|
||||
@@ -42,7 +42,7 @@ class HTTPStatusCode extends AreaPluginBase {
|
||||
] + $options;
|
||||
|
||||
// Add the HTTP status code, so it's easier for people to find it.
|
||||
array_walk($options, function($title, $code) use(&$options) {
|
||||
array_walk($options, function ($title, $code) use (&$options) {
|
||||
$options[$code] = $this->t('@code (@title)', ['@code' => $code, '@title' => $title]);
|
||||
});
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ class Result extends AreaPluginBase {
|
||||
'@page_count -- the total page count',
|
||||
],
|
||||
];
|
||||
$list = drupal_render($item_list);
|
||||
$list = \Drupal::service('renderer')->render($item_list);
|
||||
$form['content'] = [
|
||||
'#title' => $this->t('Display'),
|
||||
'#type' => 'textarea',
|
||||
|
||||
@@ -325,7 +325,8 @@ abstract class ArgumentPluginBase extends HandlerBase implements CacheableDepend
|
||||
'#suffix' => '</div>',
|
||||
'#type' => 'item',
|
||||
// Even if the plugin has no options add the key to the form_state.
|
||||
'#input' => TRUE, // trick it into checking input to make #process run
|
||||
// trick it into checking input to make #process run.
|
||||
'#input' => TRUE,
|
||||
'#states' => [
|
||||
'visible' => [
|
||||
':input[name="options[specify_validation]"]' => ['checked' => TRUE],
|
||||
@@ -498,12 +499,14 @@ abstract class ArgumentPluginBase extends HandlerBase implements CacheableDepend
|
||||
'method' => 'defaultDefault',
|
||||
'form method' => 'defaultArgumentForm',
|
||||
'has default argument' => TRUE,
|
||||
'default only' => TRUE, // this can only be used for missing argument, not validation failure
|
||||
// This can only be used for missing argument, not validation failure.
|
||||
'default only' => TRUE,
|
||||
],
|
||||
'not found' => [
|
||||
'title' => $this->t('Hide view'),
|
||||
'method' => 'defaultNotFound',
|
||||
'hard fail' => TRUE, // This is a hard fail condition
|
||||
// This is a hard fail condition.
|
||||
'hard fail' => TRUE,
|
||||
],
|
||||
'summary' => [
|
||||
'title' => $this->t('Display a summary'),
|
||||
@@ -669,7 +672,8 @@ abstract class ArgumentPluginBase extends HandlerBase implements CacheableDepend
|
||||
'#suffix' => '</div>',
|
||||
'#id' => 'edit-options-summary-options-' . $id,
|
||||
'#type' => 'item',
|
||||
'#input' => TRUE, // trick it into checking input to make #process run
|
||||
// Trick it into checking input to make #process run.
|
||||
'#input' => TRUE,
|
||||
'#states' => [
|
||||
'visible' => [
|
||||
':input[name="options[default_action]"]' => ['value' => 'summary'],
|
||||
|
||||
@@ -24,7 +24,7 @@ class MonthDate extends Date {
|
||||
*/
|
||||
public function summaryName($data) {
|
||||
$month = str_pad($data->{$this->name_alias}, 2, '0', STR_PAD_LEFT);
|
||||
return format_date(strtotime("2005" . $month . "15" . " 00:00:00 UTC" ), 'custom', $this->format, 'UTC');
|
||||
return format_date(strtotime("2005" . $month . "15" . " 00:00:00 UTC"), 'custom', $this->format, 'UTC');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -86,7 +86,7 @@ class NumericArgument extends ArgumentPluginBase {
|
||||
/**
|
||||
* Override for specific title lookups.
|
||||
* @return array
|
||||
* Returns all titles, if it's just one title it's an array with one entry.
|
||||
* Returns all titles, if it's just one title it's an array with one entry.
|
||||
*/
|
||||
public function titleQuery() {
|
||||
return $this->value;
|
||||
|
||||
@@ -42,7 +42,7 @@ abstract class ArgumentDefaultPluginBase extends PluginBase {
|
||||
*
|
||||
* This needs to be overridden by every default argument handler to properly do what is needed.
|
||||
*/
|
||||
public function getArgument() { }
|
||||
public function getArgument() {}
|
||||
|
||||
/**
|
||||
* Sets the parent argument this plugin is associated with.
|
||||
@@ -58,28 +58,32 @@ abstract class ArgumentDefaultPluginBase extends PluginBase {
|
||||
* Retrieve the options when this is a new access
|
||||
* control plugin
|
||||
*/
|
||||
protected function defineOptions() { return []; }
|
||||
protected function defineOptions() {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide the default form for setting options.
|
||||
*/
|
||||
public function buildOptionsForm(&$form, FormStateInterface $form_state) { }
|
||||
public function buildOptionsForm(&$form, FormStateInterface $form_state) {}
|
||||
|
||||
/**
|
||||
* Provide the default form form for validating options
|
||||
*/
|
||||
public function validateOptionsForm(&$form, FormStateInterface $form_state) { }
|
||||
public function validateOptionsForm(&$form, FormStateInterface $form_state) {}
|
||||
|
||||
/**
|
||||
* Provide the default form form for submitting options
|
||||
*/
|
||||
public function submitOptionsForm(&$form, FormStateInterface $form_state, &$options = []) { }
|
||||
public function submitOptionsForm(&$form, FormStateInterface $form_state, &$options = []) {}
|
||||
|
||||
/**
|
||||
* Determine if the administrator has the privileges to use this
|
||||
* plugin
|
||||
*/
|
||||
public function access() { return TRUE; }
|
||||
public function access() {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* If we don't have access to the form but are showing it anyway, ensure that
|
||||
|
||||
+14
-8
@@ -53,27 +53,31 @@ abstract class ArgumentValidatorPluginBase extends PluginBase {
|
||||
/**
|
||||
* Retrieves the options when this is a new access control plugin.
|
||||
*/
|
||||
protected function defineOptions() { return []; }
|
||||
protected function defineOptions() {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the default form for setting options.
|
||||
*/
|
||||
public function buildOptionsForm(&$form, FormStateInterface $form_state) { }
|
||||
public function buildOptionsForm(&$form, FormStateInterface $form_state) {}
|
||||
|
||||
/**
|
||||
* Provides the default form for validating options.
|
||||
*/
|
||||
public function validateOptionsForm(&$form, FormStateInterface $form_state) { }
|
||||
public function validateOptionsForm(&$form, FormStateInterface $form_state) {}
|
||||
|
||||
/**
|
||||
* Provides the default form for submitting options.
|
||||
*/
|
||||
public function submitOptionsForm(&$form, FormStateInterface $form_state, &$options = []) { }
|
||||
public function submitOptionsForm(&$form, FormStateInterface $form_state, &$options = []) {}
|
||||
|
||||
/**
|
||||
* Determines if the administrator has the privileges to use this plugin.
|
||||
*/
|
||||
public function access() { return TRUE; }
|
||||
public function access() {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Blocks user input when the form is shown but we don´t have access.
|
||||
@@ -92,7 +96,9 @@ abstract class ArgumentValidatorPluginBase extends PluginBase {
|
||||
/**
|
||||
* Performs validation for a given argument.
|
||||
*/
|
||||
public function validateArgument($arg) { return TRUE; }
|
||||
public function validateArgument($arg) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the summary arguments for displaying.
|
||||
@@ -102,7 +108,7 @@ abstract class ArgumentValidatorPluginBase extends PluginBase {
|
||||
* for a faster query. But there are use cases where you want to use
|
||||
* the old value again, for example the summary.
|
||||
*/
|
||||
public function processSummaryArguments(&$args) { }
|
||||
public function processSummaryArguments(&$args) {}
|
||||
|
||||
/**
|
||||
* Returns a context definition for this argument.
|
||||
@@ -111,7 +117,7 @@ abstract class ArgumentValidatorPluginBase extends PluginBase {
|
||||
* A context definition that represents the argument or NULL if that is
|
||||
* not possible.
|
||||
*/
|
||||
public function getContextDefinition() { }
|
||||
public function getContextDefinition() {}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -171,7 +171,7 @@ abstract class CachePluginBase extends PluginBase {
|
||||
* All of the cached result data will be available in $view->result, as well,
|
||||
* so all ids used in the query should be discoverable.
|
||||
*/
|
||||
public function postRender(&$output) { }
|
||||
public function postRender(&$output) {}
|
||||
|
||||
/**
|
||||
* Calculates and sets a cache ID used for the result cache.
|
||||
@@ -190,7 +190,7 @@ abstract class CachePluginBase extends PluginBase {
|
||||
$query = clone $build_info[$index];
|
||||
$query->preExecute();
|
||||
$build_info[$index] = [
|
||||
'query' => (string)$query,
|
||||
'query' => (string) $query,
|
||||
'arguments' => $query->getArguments(),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -28,7 +28,9 @@ class DefaultDisplay extends DisplayPluginBase {
|
||||
* Determine if this display is the 'default' display which contains
|
||||
* fallback settings
|
||||
*/
|
||||
public function isDefaultDisplay() { return TRUE; }
|
||||
public function isDefaultDisplay() {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* The default execute handler fully renders the view.
|
||||
|
||||
@@ -234,7 +234,9 @@ abstract class DisplayPluginBase extends PluginBase implements DisplayPluginInte
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isDefaultDisplay() { return FALSE; }
|
||||
public function isDefaultDisplay() {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
@@ -394,7 +396,7 @@ abstract class DisplayPluginBase extends PluginBase implements DisplayPluginInte
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function attachTo(ViewExecutable $view, $display_id, array &$build) { }
|
||||
public function attachTo(ViewExecutable $view, $display_id, array &$build) {}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
@@ -665,17 +667,23 @@ abstract class DisplayPluginBase extends PluginBase implements DisplayPluginInte
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasPath() { return FALSE; }
|
||||
public function hasPath() {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function usesLinkDisplay() { return !$this->hasPath(); }
|
||||
public function usesLinkDisplay() {
|
||||
return !$this->hasPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function usesExposedFormInBlock() { return $this->hasPath(); }
|
||||
public function usesExposedFormInBlock() {
|
||||
return $this->hasPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
@@ -772,7 +780,7 @@ abstract class DisplayPluginBase extends PluginBase implements DisplayPluginInte
|
||||
return $this->default_display->getOption($option);
|
||||
}
|
||||
|
||||
if (array_key_exists($option, $this->options)) {
|
||||
if (isset($this->options[$option]) || array_key_exists($option, $this->options)) {
|
||||
return $this->options[$option];
|
||||
}
|
||||
}
|
||||
@@ -2051,7 +2059,7 @@ abstract class DisplayPluginBase extends PluginBase implements DisplayPluginInte
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function renderFilters() { }
|
||||
public function renderFilters() {}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
@@ -2115,7 +2123,7 @@ abstract class DisplayPluginBase extends PluginBase implements DisplayPluginInte
|
||||
'#cache' => &$this->view->element['#cache'],
|
||||
];
|
||||
|
||||
$this->applyDisplayCachablityMetadata($this->view->element);
|
||||
$this->applyDisplayCacheabilityMetadata($this->view->element);
|
||||
|
||||
return $element;
|
||||
}
|
||||
@@ -2126,7 +2134,7 @@ abstract class DisplayPluginBase extends PluginBase implements DisplayPluginInte
|
||||
* @param array $element
|
||||
* The render array with updated cacheability metadata.
|
||||
*/
|
||||
protected function applyDisplayCachablityMetadata(array &$element) {
|
||||
protected function applyDisplayCacheabilityMetadata(array &$element) {
|
||||
/** @var \Drupal\views\Plugin\views\cache\CachePluginBase $cache */
|
||||
$cache = $this->getPlugin('cache');
|
||||
|
||||
@@ -2138,6 +2146,22 @@ abstract class DisplayPluginBase extends PluginBase implements DisplayPluginInte
|
||||
->applyTo($element);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the cacheability of the current display to the given render array.
|
||||
*
|
||||
* @param array $element
|
||||
* The render array with updated cacheability metadata.
|
||||
*
|
||||
* @deprecated in Drupal 8.4.0, will be removed before Drupal 9.0. Use
|
||||
* DisplayPluginBase::applyDisplayCacheabilityMetadata instead.
|
||||
*
|
||||
* @see \Drupal\views\Plugin\views\display\DisplayPluginBase::applyDisplayCacheabilityMetadata()
|
||||
*/
|
||||
protected function applyDisplayCachablityMetadata(array &$element) {
|
||||
@trigger_error('The DisplayPluginBase::applyDisplayCachablityMetadata method is deprecated since version 8.4 and will be removed in 9.0. Use DisplayPluginBase::applyDisplayCacheabilityMetadata instead.', E_USER_DEPRECATED);
|
||||
$this->applyDisplayCacheabilityMetadata($element);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -2309,7 +2333,7 @@ abstract class DisplayPluginBase extends PluginBase implements DisplayPluginInte
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function execute() { }
|
||||
public function execute() {}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
@@ -2330,7 +2354,7 @@ abstract class DisplayPluginBase extends PluginBase implements DisplayPluginInte
|
||||
// of cacheability metadata (e.g.: cache contexts), so they can bubble up.
|
||||
// Thus, we add the cacheability metadata first, then modify / remove the
|
||||
// cache keys depending on the $cache argument.
|
||||
$this->applyDisplayCachablityMetadata($this->view->element);
|
||||
$this->applyDisplayCacheabilityMetadata($this->view->element);
|
||||
if ($cache) {
|
||||
$this->view->element['#cache'] += ['keys' => []];
|
||||
// Places like \Drupal\views\ViewExecutable::setCurrentPage() set up an
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace Drupal\views\Plugin\views\display;
|
||||
|
||||
use Drupal\Core\Database\Query\Condition;
|
||||
|
||||
/**
|
||||
* The plugin that handles an EntityReference display.
|
||||
*
|
||||
@@ -88,13 +90,16 @@ class EntityReference extends DisplayPluginBase {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* Builds the view result as a renderable array.
|
||||
*
|
||||
* @return array
|
||||
* Renderable array or empty array.
|
||||
*/
|
||||
public function render() {
|
||||
if (!empty($this->view->result) && $this->view->style_plugin->evenEmpty()) {
|
||||
return $this->view->style_plugin->render($this->view->result);
|
||||
}
|
||||
return '';
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,7 +136,7 @@ class EntityReference extends DisplayPluginBase {
|
||||
}
|
||||
|
||||
// Multiple search fields are OR'd together.
|
||||
$conditions = db_or();
|
||||
$conditions = new Condition('OR');
|
||||
|
||||
// Build the condition using the selected search fields.
|
||||
foreach ($style_options['options']['search_fields'] as $field_id) {
|
||||
|
||||
@@ -106,7 +106,7 @@ class Feed extends PathPluginBase implements ResponseDisplayPluginInterface {
|
||||
public function render() {
|
||||
$build = $this->view->style_plugin->render($this->view->result);
|
||||
|
||||
$this->applyDisplayCachablityMetadata($build);
|
||||
$this->applyDisplayCacheabilityMetadata($build);
|
||||
|
||||
return $build;
|
||||
}
|
||||
|
||||
@@ -36,45 +36,45 @@ abstract class DisplayExtenderPluginBase extends PluginBase {
|
||||
/**
|
||||
* Provide a form to edit options for this plugin.
|
||||
*/
|
||||
public function defineOptionsAlter(&$options) { }
|
||||
public function defineOptionsAlter(&$options) {}
|
||||
|
||||
/**
|
||||
* Provide a form to edit options for this plugin.
|
||||
*/
|
||||
public function buildOptionsForm(&$form, FormStateInterface $form_state) { }
|
||||
public function buildOptionsForm(&$form, FormStateInterface $form_state) {}
|
||||
|
||||
/**
|
||||
* Validate the options form.
|
||||
*/
|
||||
public function validateOptionsForm(&$form, FormStateInterface $form_state) { }
|
||||
public function validateOptionsForm(&$form, FormStateInterface $form_state) {}
|
||||
|
||||
/**
|
||||
* Handle any special handling on the validate form.
|
||||
*/
|
||||
public function submitOptionsForm(&$form, FormStateInterface $form_state) { }
|
||||
public function submitOptionsForm(&$form, FormStateInterface $form_state) {}
|
||||
|
||||
/**
|
||||
* Set up any variables on the view prior to execution.
|
||||
*/
|
||||
public function preExecute() { }
|
||||
public function preExecute() {}
|
||||
|
||||
/**
|
||||
* Inject anything into the query that the display_extender handler needs.
|
||||
*/
|
||||
public function query() { }
|
||||
public function query() {}
|
||||
|
||||
/**
|
||||
* Provide the default summary for options in the views UI.
|
||||
*
|
||||
* This output is returned as an array.
|
||||
*/
|
||||
public function optionsSummary(&$categories, &$options) { }
|
||||
public function optionsSummary(&$categories, &$options) {}
|
||||
|
||||
/**
|
||||
* Static member function to list which sections are defaultable
|
||||
* and what items each section contains.
|
||||
*/
|
||||
public function defaultableSections(&$sections, $section = NULL) { }
|
||||
public function defaultableSections(&$sections, $section = NULL) {}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -179,22 +179,22 @@ abstract class ExposedFormPluginBase extends PluginBase implements CacheableDepe
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function preRender($values) { }
|
||||
public function preRender($values) {}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function postRender(&$output) { }
|
||||
public function postRender(&$output) {}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function preExecute() { }
|
||||
public function preExecute() {}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function postExecute() { }
|
||||
public function postExecute() {}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
||||
@@ -119,7 +119,7 @@ class Date extends FieldPluginBase {
|
||||
'#type' => 'select',
|
||||
'#title' => $this->t('Timezone'),
|
||||
'#description' => $this->t('Timezone to be used for date output.'),
|
||||
'#options' => ['' => $this->t('- Default site/user timezone -')] + system_time_zones(FALSE),
|
||||
'#options' => ['' => $this->t('- Default site/user timezone -')] + system_time_zones(FALSE, TRUE),
|
||||
'#default_value' => $this->options['timezone'],
|
||||
];
|
||||
foreach (array_merge(['custom'], array_keys($date_formats)) as $timezone_date_formats) {
|
||||
@@ -143,7 +143,9 @@ class Date extends FieldPluginBase {
|
||||
|
||||
if ($value) {
|
||||
$timezone = !empty($this->options['timezone']) ? $this->options['timezone'] : NULL;
|
||||
$time_diff = REQUEST_TIME - $value; // will be positive for a datetime in the past (ago), and negative for a datetime in the future (hence)
|
||||
// Will be positive for a datetime in the past (ago), and negative for a
|
||||
// datetime in the future (hence).
|
||||
$time_diff = REQUEST_TIME - $value;
|
||||
switch ($format) {
|
||||
case 'raw time ago':
|
||||
return $this->dateFormatter->formatTimeDiffSince($value, ['granularity' => is_numeric($custom_format) ? $custom_format : 2]);
|
||||
|
||||
@@ -23,6 +23,7 @@ use Drupal\Core\TypedData\TypedDataInterface;
|
||||
use Drupal\views\FieldAPIHandlerTrait;
|
||||
use Drupal\views\Entity\Render\EntityFieldRenderer;
|
||||
use Drupal\views\Plugin\views\display\DisplayPluginBase;
|
||||
use Drupal\views\Plugin\DependentWithRemovalPluginInterface;
|
||||
use Drupal\views\ResultRow;
|
||||
use Drupal\views\ViewExecutable;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
@@ -34,7 +35,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
*
|
||||
* @ViewsField("field")
|
||||
*/
|
||||
class EntityField extends FieldPluginBase implements CacheableDependencyInterface, MultiItemsFieldHandlerInterface {
|
||||
class EntityField extends FieldPluginBase implements CacheableDependencyInterface, MultiItemsFieldHandlerInterface, DependentWithRemovalPluginInterface {
|
||||
|
||||
use FieldAPIHandlerTrait;
|
||||
use PluginDependencyTrait;
|
||||
@@ -315,24 +316,33 @@ class EntityField extends FieldPluginBase implements CacheableDependencyInterfac
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the field storage of the used field.
|
||||
* Gets the field storage definition.
|
||||
*
|
||||
* @return \Drupal\Core\Field\FieldStorageDefinitionInterface
|
||||
* The field storage definition used by this handler.
|
||||
*/
|
||||
protected function getFieldStorageDefinition() {
|
||||
$entity_type_id = $this->definition['entity_type'];
|
||||
$field_storage_definitions = $this->entityManager->getFieldStorageDefinitions($entity_type_id);
|
||||
|
||||
$field_storage = NULL;
|
||||
// @todo Unify 'entity field'/'field_name' instead of converting back and
|
||||
// forth. https://www.drupal.org/node/2410779
|
||||
if (isset($this->definition['field_name'])) {
|
||||
$field_storage = $field_storage_definitions[$this->definition['field_name']];
|
||||
if (isset($this->definition['field_name']) && isset($field_storage_definitions[$this->definition['field_name']])) {
|
||||
return $field_storage_definitions[$this->definition['field_name']];
|
||||
}
|
||||
elseif (isset($this->definition['entity field'])) {
|
||||
$field_storage = $field_storage_definitions[$this->definition['entity field']];
|
||||
|
||||
if (isset($this->definition['entity field']) && isset($field_storage_definitions[$this->definition['entity field']])) {
|
||||
return $field_storage_definitions[$this->definition['entity field']];
|
||||
}
|
||||
|
||||
// The list of field storage definitions above does not include computed
|
||||
// base fields, so we need to explicitly fetch a list of all base fields in
|
||||
// order to support them.
|
||||
// @see \Drupal\Core\Entity\EntityFieldManager::getFieldStorageDefinitions()
|
||||
$base_fields = $this->entityManager->getBaseFieldDefinitions($entity_type_id);
|
||||
if (isset($this->definition['field_name']) && isset($base_fields[$this->definition['field_name']])) {
|
||||
return $base_fields[$this->definition['field_name']]->getFieldStorageDefinition();
|
||||
}
|
||||
return $field_storage;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1042,10 +1052,13 @@ class EntityField extends FieldPluginBase implements CacheableDependencyInterfac
|
||||
*/
|
||||
public function getValue(ResultRow $values, $field = NULL) {
|
||||
$entity = $this->getEntity($values);
|
||||
// Retrieve the translated object.
|
||||
$translated_entity = $this->getEntityFieldRenderer()->getEntityTranslation($entity, $values);
|
||||
|
||||
// Some bundles might not have a specific field, in which case the entity
|
||||
// (potentially a fake one) doesn't have it either.
|
||||
/** @var \Drupal\Core\Field\FieldItemListInterface $field_item_list */
|
||||
$field_item_list = isset($entity->{$this->definition['field_name']}) ? $entity->{$this->definition['field_name']} : NULL;
|
||||
$field_item_list = isset($translated_entity->{$this->definition['field_name']}) ? $translated_entity->{$this->definition['field_name']} : NULL;
|
||||
|
||||
if (!isset($field_item_list)) {
|
||||
// There isn't anything we can do without a valid field.
|
||||
@@ -1077,4 +1090,29 @@ class EntityField extends FieldPluginBase implements CacheableDependencyInterfac
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function onDependencyRemoval(array $dependencies) {
|
||||
// See if this handler is responsible for any of the dependencies being
|
||||
// removed. If this is the case, indicate that this handler needs to be
|
||||
// removed from the View.
|
||||
$remove = FALSE;
|
||||
// Get all the current dependencies for this handler.
|
||||
$current_dependencies = $this->calculateDependencies();
|
||||
foreach ($current_dependencies as $group => $dependency_list) {
|
||||
// Check if any of the handler dependencies match the dependencies being
|
||||
// removed.
|
||||
foreach ($dependency_list as $config_key) {
|
||||
if (isset($dependencies[$group]) && array_key_exists($config_key, $dependencies[$group])) {
|
||||
// This handlers dependency matches a dependency being removed,
|
||||
// indicate that this handler needs to be removed.
|
||||
$remove = TRUE;
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $remove;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ class EntityOperations extends FieldPluginBase {
|
||||
* @param array $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager.
|
||||
* The entity manager.
|
||||
* @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
|
||||
* The language manager.
|
||||
*/
|
||||
|
||||
@@ -865,10 +865,10 @@ abstract class FieldPluginBase extends HandlerBase implements FieldHandlerInterf
|
||||
$optgroup_arguments = (string) t('Arguments');
|
||||
$optgroup_fields = (string) t('Fields');
|
||||
foreach ($previous as $id => $label) {
|
||||
$options[$optgroup_fields]["{{ $id }}"] = substr(strrchr($label, ":"), 2 );
|
||||
$options[$optgroup_fields]["{{ $id }}"] = substr(strrchr($label, ":"), 2);
|
||||
}
|
||||
// Add the field to the list of options.
|
||||
$options[$optgroup_fields]["{{ {$this->options['id']} }}"] = substr(strrchr($this->adminLabel(), ":"), 2 );
|
||||
$options[$optgroup_fields]["{{ {$this->options['id']} }}"] = substr(strrchr($this->adminLabel(), ":"), 2);
|
||||
|
||||
foreach ($this->view->display_handler->getHandlers('argument') as $arg => $handler) {
|
||||
$options[$optgroup_arguments]["{{ arguments.$arg }}"] = $this->t('@argument title', ['@argument' => $handler->adminLabel()]);
|
||||
@@ -1105,7 +1105,7 @@ abstract class FieldPluginBase extends HandlerBase implements FieldHandlerInterf
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function preRender(&$values) { }
|
||||
public function preRender(&$values) {}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
@@ -1713,14 +1713,14 @@ abstract class FieldPluginBase extends HandlerBase implements FieldHandlerInterf
|
||||
* field ID is terms, then the tokens might be {{ terms__tid }} and
|
||||
* {{ terms__name }}.
|
||||
*/
|
||||
protected function addSelfTokens(&$tokens, $item) { }
|
||||
protected function addSelfTokens(&$tokens, $item) {}
|
||||
|
||||
/**
|
||||
* Document any special tokens this field might use for itself.
|
||||
*
|
||||
* @see addSelfTokens()
|
||||
*/
|
||||
protected function documentSelfTokens(&$tokens) { }
|
||||
protected function documentSelfTokens(&$tokens) {}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
||||
@@ -90,7 +90,7 @@ abstract class PrerenderList extends FieldPluginBase implements MultiItemsFieldH
|
||||
'#list_type' => $this->options['type'],
|
||||
];
|
||||
}
|
||||
return drupal_render($render);
|
||||
return \Drupal::service('renderer')->render($render);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ class RenderedEntity extends FieldPluginBase implements CacheableDependencyInter
|
||||
* @param array $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager.
|
||||
* The entity manager.
|
||||
* @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
|
||||
* The language manager.
|
||||
*/
|
||||
|
||||
@@ -49,7 +49,6 @@ class BooleanOperator extends FilterPluginBase {
|
||||
public $accept_null = FALSE;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -56,6 +56,8 @@ class Bundle extends InOperator {
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager.
|
||||
* @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $bundle_info_service
|
||||
* The bundle info service.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityManagerInterface $entity_manager, EntityTypeBundleInfoInterface $bundle_info_service) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
|
||||
@@ -166,8 +166,10 @@ class Date extends NumericFilter {
|
||||
$b = intval(strtotime($this->value['max'], 0));
|
||||
|
||||
if ($this->value['type'] == 'offset') {
|
||||
$a = '***CURRENT_TIME***' . sprintf('%+d', $a); // keep sign
|
||||
$b = '***CURRENT_TIME***' . sprintf('%+d', $b); // keep sign
|
||||
// Keep sign.
|
||||
$a = '***CURRENT_TIME***' . sprintf('%+d', $a);
|
||||
// Keep sign.
|
||||
$b = '***CURRENT_TIME***' . sprintf('%+d', $b);
|
||||
}
|
||||
// This is safe because we are manually scrubbing the values.
|
||||
// It is necessary to do it this way because $a and $b are formulas when using an offset.
|
||||
@@ -178,7 +180,8 @@ class Date extends NumericFilter {
|
||||
protected function opSimple($field) {
|
||||
$value = intval(strtotime($this->value['value'], 0));
|
||||
if (!empty($this->value['type']) && $this->value['type'] == 'offset') {
|
||||
$value = '***CURRENT_TIME***' . sprintf('%+d', $value); // keep sign
|
||||
// Keep sign.
|
||||
$value = '***CURRENT_TIME***' . sprintf('%+d', $value);
|
||||
}
|
||||
// This is safe because we are manually scrubbing the value.
|
||||
// It is necessary to do it this way because $value is a formula when using an offset.
|
||||
|
||||
@@ -131,9 +131,11 @@ abstract class FilterPluginBase extends HandlerBase implements CacheableDependen
|
||||
'required' => ['default' => FALSE],
|
||||
'remember' => ['default' => FALSE],
|
||||
'multiple' => ['default' => FALSE],
|
||||
'remember_roles' => ['default' => [
|
||||
RoleInterface::AUTHENTICATED_ID => RoleInterface::AUTHENTICATED_ID,
|
||||
]],
|
||||
'remember_roles' => [
|
||||
'default' => [
|
||||
RoleInterface::AUTHENTICATED_ID => RoleInterface::AUTHENTICATED_ID,
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
@@ -174,7 +176,9 @@ abstract class FilterPluginBase extends HandlerBase implements CacheableDependen
|
||||
/**
|
||||
* Determine if a filter can be exposed.
|
||||
*/
|
||||
public function canExpose() { return TRUE; }
|
||||
public function canExpose() {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a filter can be converted into a group.
|
||||
@@ -302,18 +306,20 @@ abstract class FilterPluginBase extends HandlerBase implements CacheableDependen
|
||||
* Provide a list of options for the default operator form.
|
||||
* Should be overridden by classes that don't override operatorForm
|
||||
*/
|
||||
public function operatorOptions() { return []; }
|
||||
public function operatorOptions() {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the operator form.
|
||||
*/
|
||||
protected function operatorValidate($form, FormStateInterface $form_state) { }
|
||||
protected function operatorValidate($form, FormStateInterface $form_state) {}
|
||||
|
||||
/**
|
||||
* Perform any necessary changes to the form values prior to storage.
|
||||
* There is no need for this function to actually store the data.
|
||||
*/
|
||||
public function operatorSubmit($form, FormStateInterface $form_state) { }
|
||||
public function operatorSubmit($form, FormStateInterface $form_state) {}
|
||||
|
||||
/**
|
||||
* Shortcut to display the value form.
|
||||
@@ -341,13 +347,13 @@ abstract class FilterPluginBase extends HandlerBase implements CacheableDependen
|
||||
/**
|
||||
* Validate the options form.
|
||||
*/
|
||||
protected function valueValidate($form, FormStateInterface $form_state) { }
|
||||
protected function valueValidate($form, FormStateInterface $form_state) {}
|
||||
|
||||
/**
|
||||
* Perform any necessary changes to the form values prior to storage.
|
||||
* There is no need for this function to actually store the data.
|
||||
*/
|
||||
protected function valueSubmit($form, FormStateInterface $form_state) { }
|
||||
protected function valueSubmit($form, FormStateInterface $form_state) {}
|
||||
|
||||
/**
|
||||
* Shortcut to display the exposed options form.
|
||||
@@ -989,7 +995,9 @@ abstract class FilterPluginBase extends HandlerBase implements CacheableDependen
|
||||
'#default_value' => $this->options['group_info']['remember'],
|
||||
];
|
||||
|
||||
$groups = ['All' => $this->t('- Any -')]; // The string '- Any -' will not be rendered see @theme_views_ui_build_group_filter_form
|
||||
// The string '- Any -' will not be rendered.
|
||||
// @see theme_views_ui_build_group_filter_form()
|
||||
$groups = ['All' => $this->t('- Any -')];
|
||||
|
||||
// Provide 3 options to start when we are in a new group.
|
||||
if (count($this->options['group_info']['group_items']) == 0) {
|
||||
@@ -1199,7 +1207,6 @@ abstract class FilterPluginBase extends HandlerBase implements CacheableDependen
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Sanitizes the HTML select element's options.
|
||||
*
|
||||
|
||||
@@ -52,6 +52,8 @@ class GroupByNumeric extends NumericFilter {
|
||||
return $this->getField(parent::adminLabel($short));
|
||||
}
|
||||
|
||||
public function canGroup() { return FALSE; }
|
||||
public function canGroup() {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -88,7 +88,8 @@ class InOperator extends FilterPluginBase {
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $this->t('Limit list to selected items'),
|
||||
'#description' => $this->t('If checked, the only items presented to the user will be the ones selected here.'),
|
||||
'#default_value' => !empty($this->options['expose']['reduce']), // safety
|
||||
// Safety.
|
||||
'#default_value' => !empty($this->options['expose']['reduce']),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\views\Plugin\views\filter;
|
||||
|
||||
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\views\Plugin\ViewsHandlerManager;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Filter to show only the latest revision of an entity.
|
||||
*
|
||||
* @ingroup views_filter_handlers
|
||||
*
|
||||
* @ViewsFilter("latest_revision")
|
||||
*/
|
||||
class LatestRevision extends FilterPluginBase implements ContainerFactoryPluginInterface {
|
||||
|
||||
/**
|
||||
* Entity Type Manager service.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
|
||||
*/
|
||||
protected $entityTypeManager;
|
||||
|
||||
/**
|
||||
* Views Handler Plugin Manager.
|
||||
*
|
||||
* @var \Drupal\views\Plugin\ViewsHandlerManager
|
||||
*/
|
||||
protected $joinHandler;
|
||||
|
||||
/**
|
||||
* Constructs a new LatestRevision.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
* @param string $plugin_id
|
||||
* The plugin_id for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
|
||||
* Entity Type Manager Service.
|
||||
* @param \Drupal\views\Plugin\ViewsHandlerManager $join_handler
|
||||
* Views Handler Plugin Manager.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, ViewsHandlerManager $join_handler) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
|
||||
$this->entityTypeManager = $entity_type_manager;
|
||||
$this->joinHandler = $join_handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$configuration, $plugin_id, $plugin_definition,
|
||||
$container->get('entity_type.manager'),
|
||||
$container->get('plugin.manager.views.join')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function adminSummary() {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function operatorForm(&$form, FormStateInterface $form_state) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function canExpose() {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() {
|
||||
/** @var \Drupal\views\Plugin\views\query\Sql $query */
|
||||
$query = $this->query;
|
||||
$query_base_table = $this->relationship ?: $this->view->storage->get('base_table');
|
||||
|
||||
$entity_type = $this->entityTypeManager->getDefinition($this->getEntityType());
|
||||
$keys = $entity_type->getKeys();
|
||||
|
||||
$definition = [
|
||||
'table' => $query_base_table,
|
||||
'type' => 'LEFT',
|
||||
'field' => $keys['id'],
|
||||
'left_table' => $query_base_table,
|
||||
'left_field' => $keys['id'],
|
||||
'extra' => [
|
||||
['left_field' => $keys['revision'], 'field' => $keys['revision'], 'operator' => '>'],
|
||||
],
|
||||
];
|
||||
|
||||
$join = $this->joinHandler->createInstance('standard', $definition);
|
||||
|
||||
$join_table_alias = $query->addTable($query_base_table, $this->relationship, $join);
|
||||
$query->addWhere($this->options['group'], "$join_table_alias.{$keys['id']}", NULL, 'IS NULL');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -129,6 +129,9 @@ class ManyToOne extends InOperator {
|
||||
if (empty($this->value)) {
|
||||
return;
|
||||
}
|
||||
// Form API returns unchecked options in the form of option_id => 0. This
|
||||
// breaks the generated query for "is all of" filters so we remove them.
|
||||
$this->value = array_filter($this->value, 'static::arrayFilterZero');
|
||||
$this->helper->addFilter();
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Drupal\views\Plugin\views\filter;
|
||||
|
||||
use Drupal\Core\Database\Query\Condition;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
||||
/**
|
||||
@@ -265,7 +266,7 @@ class StringFilter extends FilterPluginBase {
|
||||
}
|
||||
|
||||
protected function opContainsWord($field) {
|
||||
$where = $this->operator == 'word' ? db_or() : db_and();
|
||||
$where = $this->operator == 'word' ? new Condition('OR') : new Condition('AND');
|
||||
|
||||
// Don't filter on empty strings.
|
||||
if (empty($this->value)) {
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\views\Plugin\views\join;
|
||||
|
||||
use Drupal\Core\Database\Query\SelectInterface;
|
||||
|
||||
/**
|
||||
* Implementation for the "field OR language" join.
|
||||
*
|
||||
* If the extra conditions contain either ".langcode" or ".bundle", they will be
|
||||
* grouped and joined with OR instead of AND. The entire group will then be
|
||||
* joined to the other conditions with AND.
|
||||
*
|
||||
* This is needed for configurable fields that are translatable on some bundles
|
||||
* and untranslatable on others. The correct field values to fetch in this case
|
||||
* have a langcode that matches the entity record *or* have a bundle on which
|
||||
* the field is untranslatable. Thus, the entity base table (or data table, or
|
||||
* revision data table, respectively) must join the field data table (or field
|
||||
* revision table) on a matching langcode *or* a bundle where the field is
|
||||
* untranslatable. The following example views data achieves this for a node
|
||||
* field named 'field_tags' which is translatable on an 'article' node type, but
|
||||
* not on the 'news' and 'page' node types:
|
||||
*
|
||||
* @code
|
||||
* $data['node__field_tags']['table']['join']['node_field_data'] = [
|
||||
* 'join_id' => 'field_or_language_join',
|
||||
* 'table' => 'node__field_tags',
|
||||
* 'left_field' => 'nid',
|
||||
* 'field' => 'entity_id',
|
||||
* 'extra' => [
|
||||
* [
|
||||
* 'field' => 'deleted',
|
||||
* 'value' => 0,
|
||||
* 'numeric' => TRUE,
|
||||
* ],
|
||||
* [
|
||||
* 'left_field' => 'langcode',
|
||||
* 'field' => 'langcode',
|
||||
* ],
|
||||
* [
|
||||
* 'field' => 'bundle',
|
||||
* 'value' => ['news', 'page'],
|
||||
* ],
|
||||
* ],
|
||||
* ];
|
||||
* @endcode
|
||||
*
|
||||
* The resulting join condition for this example would be the following:
|
||||
*
|
||||
* @code
|
||||
* ON node__field_tags.deleted = 0
|
||||
* AND (
|
||||
* node_field_data.langcode = node__field_tags.langcode
|
||||
* OR node__field.tags.bundle IN ['news', 'page']
|
||||
* )
|
||||
* @endcode
|
||||
*
|
||||
* @see views_field_default_views_data()
|
||||
*
|
||||
* @ingroup views_join_handlers
|
||||
*
|
||||
* @ViewsJoin("field_or_language_join")
|
||||
*/
|
||||
class FieldOrLanguageJoin extends JoinPluginBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function joinAddExtra(&$arguments, &$condition, $table, SelectInterface $select_query, $left_table = NULL) {
|
||||
if (empty($this->extra)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_array($this->extra)) {
|
||||
$extras = [];
|
||||
foreach ($this->extra as $extra) {
|
||||
$extras[] = $this->buildExtra($extra, $arguments, $table, $select_query, $left_table);
|
||||
}
|
||||
|
||||
// Remove and store the langcode OR bundle join condition extra.
|
||||
$language_bundle_conditions = [];
|
||||
foreach ($extras as $key => $extra) {
|
||||
if (strpos($extra, '.langcode') !== FALSE || strpos($extra, '.bundle') !== FALSE) {
|
||||
$language_bundle_conditions[] = $extra;
|
||||
unset($extras[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
if (count($extras) > 1) {
|
||||
$condition .= ' AND (' . implode(' ' . $this->extraOperator . ' ', $extras) . ')';
|
||||
}
|
||||
elseif ($extras) {
|
||||
$condition .= ' AND ' . array_shift($extras);
|
||||
}
|
||||
|
||||
// Tack on the langcode OR bundle join condition extra.
|
||||
if (!empty($language_bundle_conditions)) {
|
||||
$condition .= ' AND (' . implode(' OR ', $language_bundle_conditions) . ')';
|
||||
}
|
||||
}
|
||||
elseif (is_string($this->extra)) {
|
||||
$condition .= " AND ($this->extra)";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Drupal\views\Plugin\views\join;
|
||||
|
||||
use Drupal\Core\Database\Query\SelectInterface;
|
||||
use Drupal\Core\Plugin\PluginBase;
|
||||
|
||||
/**
|
||||
@@ -261,12 +262,13 @@ class JoinPluginBase extends PluginBase implements JoinPluginInterface {
|
||||
}
|
||||
|
||||
if ($this->leftTable) {
|
||||
$left = $view_query->getTableInfo($this->leftTable);
|
||||
$left_field = "$left[alias].$this->leftField";
|
||||
$left_table = $view_query->getTableInfo($this->leftTable);
|
||||
$left_field = "$left_table[alias].$this->leftField";
|
||||
}
|
||||
else {
|
||||
// This can be used if left_field is a formula or something. It should be used only *very* rarely.
|
||||
$left_field = $this->leftField;
|
||||
$left_table = NULL;
|
||||
}
|
||||
|
||||
$condition = "$left_field = $table[alias].$this->field";
|
||||
@@ -274,89 +276,123 @@ class JoinPluginBase extends PluginBase implements JoinPluginInterface {
|
||||
|
||||
// Tack on the extra.
|
||||
if (isset($this->extra)) {
|
||||
if (is_array($this->extra)) {
|
||||
$extras = [];
|
||||
foreach ($this->extra as $info) {
|
||||
// Do not require 'value' to be set; allow for field syntax instead.
|
||||
$info += [
|
||||
'value' => NULL,
|
||||
];
|
||||
// Figure out the table name. Remember, only use aliases provided
|
||||
// if at all possible.
|
||||
$join_table = '';
|
||||
if (!array_key_exists('table', $info)) {
|
||||
$join_table = $table['alias'] . '.';
|
||||
}
|
||||
elseif (isset($info['table'])) {
|
||||
// If we're aware of a table alias for this table, use the table
|
||||
// alias instead of the table name.
|
||||
if (isset($left) && $left['table'] == $info['table']) {
|
||||
$join_table = $left['alias'] . '.';
|
||||
}
|
||||
else {
|
||||
$join_table = $info['table'] . '.';
|
||||
}
|
||||
}
|
||||
|
||||
// Convert a single-valued array of values to the single-value case,
|
||||
// and transform from IN() notation to = notation
|
||||
if (is_array($info['value']) && count($info['value']) == 1) {
|
||||
$info['value'] = array_shift($info['value']);
|
||||
}
|
||||
if (is_array($info['value'])) {
|
||||
// We use an SA-CORE-2014-005 conformant placeholder for our array
|
||||
// of values. Also, note that the 'IN' operator is implicit.
|
||||
// @see https://www.drupal.org/node/2401615.
|
||||
$operator = !empty($info['operator']) ? $info['operator'] : 'IN';
|
||||
$placeholder = ':views_join_condition_' . $select_query->nextPlaceholder() . '[]';
|
||||
$placeholder_sql = "( $placeholder )";
|
||||
}
|
||||
else {
|
||||
// With a single value, the '=' operator is implicit.
|
||||
$operator = !empty($info['operator']) ? $info['operator'] : '=';
|
||||
$placeholder = $placeholder_sql = ':views_join_condition_' . $select_query->nextPlaceholder();
|
||||
}
|
||||
// Set 'field' as join table field if available or set 'left field' as
|
||||
// join table field is not set.
|
||||
if (isset($info['field'])) {
|
||||
$join_table_field = "$join_table$info[field]";
|
||||
// Allow the value to be set either with the 'value' element or
|
||||
// with 'left_field'.
|
||||
if (isset($info['left_field'])) {
|
||||
$placeholder_sql = "$left[alias].$info[left_field]";
|
||||
}
|
||||
else {
|
||||
$arguments[$placeholder] = $info['value'];
|
||||
}
|
||||
}
|
||||
// Set 'left field' as join table field is not set.
|
||||
else {
|
||||
$join_table_field = "$left[alias].$info[left_field]";
|
||||
$arguments[$placeholder] = $info['value'];
|
||||
}
|
||||
// Render out the SQL fragment with parameters.
|
||||
$extras[] = "$join_table_field $operator $placeholder_sql";
|
||||
}
|
||||
|
||||
if ($extras) {
|
||||
if (count($extras) == 1) {
|
||||
$condition .= ' AND ' . array_shift($extras);
|
||||
}
|
||||
else {
|
||||
$condition .= ' AND (' . implode(' ' . $this->extraOperator . ' ', $extras) . ')';
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif ($this->extra && is_string($this->extra)) {
|
||||
$condition .= " AND ($this->extra)";
|
||||
}
|
||||
$this->joinAddExtra($arguments, $condition, $table, $select_query, $left_table);
|
||||
}
|
||||
|
||||
$select_query->addJoin($this->type, $right_table, $table['alias'], $condition, $arguments);
|
||||
}
|
||||
/**
|
||||
* Adds the extras to the join condition.
|
||||
*
|
||||
* @param array $arguments
|
||||
* Array of query arguments.
|
||||
* @param string $condition
|
||||
* The condition to be built.
|
||||
* @param array $table
|
||||
* The right table.
|
||||
* @param \Drupal\Core\Database\Query\SelectInterface $select_query
|
||||
* The current select query being built.
|
||||
* @param array $left_table
|
||||
* The left table.
|
||||
*/
|
||||
protected function joinAddExtra(&$arguments, &$condition, $table, SelectInterface $select_query, $left_table = NULL) {
|
||||
if (is_array($this->extra)) {
|
||||
$extras = [];
|
||||
foreach ($this->extra as $info) {
|
||||
$extras[] = $this->buildExtra($info, $arguments, $table, $select_query, $left_table);
|
||||
}
|
||||
|
||||
if ($extras) {
|
||||
if (count($extras) == 1) {
|
||||
$condition .= ' AND ' . array_shift($extras);
|
||||
}
|
||||
else {
|
||||
$condition .= ' AND (' . implode(' ' . $this->extraOperator . ' ', $extras) . ')';
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif ($this->extra && is_string($this->extra)) {
|
||||
$condition .= " AND ($this->extra)";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a single extra condition.
|
||||
*
|
||||
* @param array $info
|
||||
* The extra information. See JoinPluginBase::$extra for details.
|
||||
* @param array $arguments
|
||||
* Array of query arguments.
|
||||
* @param array $table
|
||||
* The right table.
|
||||
* @param \Drupal\Core\Database\Query\SelectInterface $select_query
|
||||
* The current select query being built.
|
||||
* @param array $left
|
||||
* The left table.
|
||||
*
|
||||
* @return string
|
||||
* The extra condition
|
||||
*/
|
||||
protected function buildExtra($info, &$arguments, $table, SelectInterface $select_query, $left) {
|
||||
// Do not require 'value' to be set; allow for field syntax instead.
|
||||
$info += [
|
||||
'value' => NULL,
|
||||
];
|
||||
// Figure out the table name. Remember, only use aliases provided
|
||||
// if at all possible.
|
||||
$join_table = '';
|
||||
if (!array_key_exists('table', $info)) {
|
||||
$join_table = $table['alias'] . '.';
|
||||
}
|
||||
elseif (isset($info['table'])) {
|
||||
// If we're aware of a table alias for this table, use the table
|
||||
// alias instead of the table name.
|
||||
if (isset($left) && $left['table'] == $info['table']) {
|
||||
$join_table = $left['alias'] . '.';
|
||||
}
|
||||
else {
|
||||
$join_table = $info['table'] . '.';
|
||||
}
|
||||
}
|
||||
|
||||
// Convert a single-valued array of values to the single-value case,
|
||||
// and transform from IN() notation to = notation
|
||||
if (is_array($info['value']) && count($info['value']) == 1) {
|
||||
$info['value'] = array_shift($info['value']);
|
||||
}
|
||||
if (is_array($info['value'])) {
|
||||
// We use an SA-CORE-2014-005 conformant placeholder for our array
|
||||
// of values. Also, note that the 'IN' operator is implicit.
|
||||
// @see https://www.drupal.org/node/2401615.
|
||||
$operator = !empty($info['operator']) ? $info['operator'] : 'IN';
|
||||
$placeholder = ':views_join_condition_' . $select_query->nextPlaceholder() . '[]';
|
||||
$placeholder_sql = "( $placeholder )";
|
||||
}
|
||||
else {
|
||||
// With a single value, the '=' operator is implicit.
|
||||
$operator = !empty($info['operator']) ? $info['operator'] : '=';
|
||||
$placeholder = $placeholder_sql = ':views_join_condition_' . $select_query->nextPlaceholder();
|
||||
}
|
||||
// Set 'field' as join table field if available or set 'left field' as
|
||||
// join table field is not set.
|
||||
if (isset($info['field'])) {
|
||||
$join_table_field = "$join_table$info[field]";
|
||||
// Allow the value to be set either with the 'value' element or
|
||||
// with 'left_field'.
|
||||
if (isset($info['left_field'])) {
|
||||
$placeholder_sql = "$left[alias].$info[left_field]";
|
||||
}
|
||||
else {
|
||||
$arguments[$placeholder] = $info['value'];
|
||||
}
|
||||
}
|
||||
// Set 'left field' as join table field is not set.
|
||||
else {
|
||||
$join_table_field = "$left[alias].$info[left_field]";
|
||||
$arguments[$placeholder] = $info['value'];
|
||||
}
|
||||
// Render out the SQL fragment with parameters.
|
||||
return "$join_table_field $operator $placeholder_sql";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -114,12 +114,12 @@ abstract class PagerPluginBase extends PluginBase {
|
||||
/**
|
||||
* Provide the default form form for validating options
|
||||
*/
|
||||
public function validateOptionsForm(&$form, FormStateInterface $form_state) { }
|
||||
public function validateOptionsForm(&$form, FormStateInterface $form_state) {}
|
||||
|
||||
/**
|
||||
* Provide the default form form for submitting options
|
||||
*/
|
||||
public function submitOptionsForm(&$form, FormStateInterface $form_state) { }
|
||||
public function submitOptionsForm(&$form, FormStateInterface $form_state) {}
|
||||
|
||||
/**
|
||||
* Return a string to display as the clickable title for the
|
||||
@@ -156,6 +156,8 @@ abstract class PagerPluginBase extends PluginBase {
|
||||
if (!empty($this->options['offset'])) {
|
||||
$this->total_items -= $this->options['offset'];
|
||||
}
|
||||
// Prevent from being negative.
|
||||
$this->total_items = max(0, $this->total_items);
|
||||
|
||||
return $this->total_items;
|
||||
}
|
||||
@@ -173,22 +175,22 @@ abstract class PagerPluginBase extends PluginBase {
|
||||
*
|
||||
* This is called during the build phase and can directly modify the query.
|
||||
*/
|
||||
public function query() { }
|
||||
public function query() {}
|
||||
|
||||
/**
|
||||
* Perform any needed actions just prior to the query executing.
|
||||
*/
|
||||
public function preExecute(&$query) { }
|
||||
public function preExecute(&$query) {}
|
||||
|
||||
/**
|
||||
* Perform any needed actions just after the query executing.
|
||||
*/
|
||||
public function postExecute(&$result) { }
|
||||
public function postExecute(&$result) {}
|
||||
|
||||
/**
|
||||
* Perform any needed actions just before rendering.
|
||||
*/
|
||||
public function preRender(&$result) { }
|
||||
public function preRender(&$result) {}
|
||||
|
||||
/**
|
||||
* Return the renderable array of the pager.
|
||||
@@ -199,7 +201,7 @@ abstract class PagerPluginBase extends PluginBase {
|
||||
* Any extra GET parameters that should be retained, such as exposed
|
||||
* input.
|
||||
*/
|
||||
public function render($input) { }
|
||||
public function render($input) {}
|
||||
|
||||
/**
|
||||
* Determine if there are more records available.
|
||||
@@ -211,11 +213,11 @@ abstract class PagerPluginBase extends PluginBase {
|
||||
&& $this->total_items > (intval($this->current_page) + 1) * $this->getItemsPerPage();
|
||||
}
|
||||
|
||||
public function exposedFormAlter(&$form, FormStateInterface $form_state) { }
|
||||
public function exposedFormAlter(&$form, FormStateInterface $form_state) {}
|
||||
|
||||
public function exposedFormValidate(&$form, FormStateInterface $form_state) { }
|
||||
public function exposedFormValidate(&$form, FormStateInterface $form_state) {}
|
||||
|
||||
public function exposedFormSubmit(&$form, FormStateInterface $form_state, &$exclude) { }
|
||||
public function exposedFormSubmit(&$form, FormStateInterface $form_state, &$exclude) {}
|
||||
|
||||
public function usesExposed() {
|
||||
return FALSE;
|
||||
|
||||
@@ -362,7 +362,7 @@ abstract class SqlBase extends PagerPluginBase implements CacheableDependencyInt
|
||||
public function exposedFormValidate(&$form, FormStateInterface $form_state) {
|
||||
if (!$form_state->isValueEmpty('offset') && trim($form_state->getValue('offset'))) {
|
||||
if (!is_numeric($form_state->getValue('offset')) || $form_state->getValue('offset') < 0) {
|
||||
$form_state->setErrorByName('offset', $this->t('Offset must be an number greater or equal than 0.'));
|
||||
$form_state->setErrorByName('offset', $this->t('Offset must be a number greater than or equal to 0.'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ abstract class QueryPluginBase extends PluginBase implements CacheableDependency
|
||||
* @param $get_count
|
||||
* Provide a countquery if this is true, otherwise provide a normal query.
|
||||
*/
|
||||
public function query($get_count = FALSE) { }
|
||||
public function query($get_count = FALSE) {}
|
||||
|
||||
/**
|
||||
* Let modules modify the query just prior to finalizing it.
|
||||
@@ -62,7 +62,7 @@ abstract class QueryPluginBase extends PluginBase implements CacheableDependency
|
||||
* @param view $view
|
||||
* The view which is executed.
|
||||
*/
|
||||
public function alter(ViewExecutable $view) { }
|
||||
public function alter(ViewExecutable $view) {}
|
||||
|
||||
/**
|
||||
* Builds the necessary info to execute the query.
|
||||
@@ -70,7 +70,7 @@ abstract class QueryPluginBase extends PluginBase implements CacheableDependency
|
||||
* @param view $view
|
||||
* The view which is executed.
|
||||
*/
|
||||
public function build(ViewExecutable $view) { }
|
||||
public function build(ViewExecutable $view) {}
|
||||
|
||||
/**
|
||||
* Executes the query and fills the associated view object with according
|
||||
@@ -85,7 +85,7 @@ abstract class QueryPluginBase extends PluginBase implements CacheableDependency
|
||||
* @param view $view
|
||||
* The view which is executed.
|
||||
*/
|
||||
public function execute(ViewExecutable $view) { }
|
||||
public function execute(ViewExecutable $view) {}
|
||||
|
||||
/**
|
||||
* Add a signature to the query, if such a thing is feasible.
|
||||
@@ -96,18 +96,18 @@ abstract class QueryPluginBase extends PluginBase implements CacheableDependency
|
||||
* @param view $view
|
||||
* The view which is executed.
|
||||
*/
|
||||
public function addSignature(ViewExecutable $view) { }
|
||||
public function addSignature(ViewExecutable $view) {}
|
||||
|
||||
/**
|
||||
* Get aggregation info for group by queries.
|
||||
*
|
||||
* If NULL, aggregation is not allowed.
|
||||
*/
|
||||
public function getAggregationInfo() { }
|
||||
public function getAggregationInfo() {}
|
||||
|
||||
public function validateOptionsForm(&$form, FormStateInterface $form_state) { }
|
||||
public function validateOptionsForm(&$form, FormStateInterface $form_state) {}
|
||||
|
||||
public function submitOptionsForm(&$form, FormStateInterface $form_state) { }
|
||||
public function submitOptionsForm(&$form, FormStateInterface $form_state) {}
|
||||
|
||||
public function summaryTitle() {
|
||||
return $this->t('Settings');
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace Drupal\views\Plugin\views\query;
|
||||
use Drupal\Component\Utility\NestedArray;
|
||||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Core\Database\Query\Condition;
|
||||
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\views\Plugin\views\display\DisplayPluginBase;
|
||||
@@ -830,7 +831,7 @@ class Sql extends QueryPluginBase {
|
||||
* @code
|
||||
* $this->query->addWhere(
|
||||
* $this->options['group'],
|
||||
* db_or()
|
||||
* (new Condition('OR'))
|
||||
* ->condition($field, $value, 'NOT IN')
|
||||
* ->condition($field, $value, 'IS NULL')
|
||||
* );
|
||||
@@ -1056,13 +1057,13 @@ class Sql extends QueryPluginBase {
|
||||
$has_arguments = FALSE;
|
||||
$has_filter = FALSE;
|
||||
|
||||
$main_group = db_and();
|
||||
$filter_group = $this->groupOperator == 'OR' ? db_or() : db_and();
|
||||
$main_group = new Condition('AND');
|
||||
$filter_group = $this->groupOperator == 'OR' ? new Condition('OR') : new Condition('AND');
|
||||
|
||||
foreach ($this->$where as $group => $info) {
|
||||
|
||||
if (!empty($info['conditions'])) {
|
||||
$sub_group = $info['type'] == 'OR' ? db_or() : db_and();
|
||||
$sub_group = $info['type'] == 'OR' ? new Condition('OR') : new Condition('AND');
|
||||
foreach ($info['conditions'] as $clause) {
|
||||
if ($clause['operator'] == 'formula') {
|
||||
$has_condition = TRUE;
|
||||
@@ -1468,7 +1469,7 @@ class Sql extends QueryPluginBase {
|
||||
|
||||
// Setup the result row objects.
|
||||
$view->result = iterator_to_array($result);
|
||||
array_walk($view->result, function(ResultRow $row, $index) {
|
||||
array_walk($view->result, function (ResultRow $row, $index) {
|
||||
$row->index = $index;
|
||||
});
|
||||
|
||||
|
||||
@@ -178,7 +178,7 @@ class GroupwiseMax extends RelationshipPluginBase {
|
||||
* - subquery_order: either ASC or DESC.
|
||||
*
|
||||
* @return string
|
||||
* The subquery SQL string, ready for use in the main query.
|
||||
* The subquery SQL string, ready for use in the main query.
|
||||
*/
|
||||
protected function leftQuery($options) {
|
||||
// Either load another view, or create one on the fly.
|
||||
|
||||
@@ -37,7 +37,7 @@ class EntityReference extends Fields {
|
||||
parent::buildOptionsForm($form, $form_state);
|
||||
|
||||
// Expand the description of the 'Inline field' checkboxes.
|
||||
$form['inline']['#description'] .= '<br />' . $this->t("<strong>Note:</strong> In 'Entity Reference' displays, all fields will be displayed inline unless an explicit selection of inline fields is made here." );
|
||||
$form['inline']['#description'] .= '<br />' . $this->t("<strong>Note:</strong> In 'Entity Reference' displays, all fields will be displayed inline unless an explicit selection of inline fields is made here.");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -122,13 +122,13 @@ abstract class RowPluginBase extends PluginBase {
|
||||
/**
|
||||
* Validate the options form.
|
||||
*/
|
||||
public function validateOptionsForm(&$form, FormStateInterface $form_state) { }
|
||||
public function validateOptionsForm(&$form, FormStateInterface $form_state) {}
|
||||
|
||||
/**
|
||||
* Perform any necessary changes to the form values prior to storage.
|
||||
* There is no need for this function to actually store the data.
|
||||
*/
|
||||
public function submitOptionsForm(&$form, FormStateInterface $form_state) { }
|
||||
public function submitOptionsForm(&$form, FormStateInterface $form_state) {}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
@@ -151,7 +151,7 @@ abstract class RowPluginBase extends PluginBase {
|
||||
* @param $result
|
||||
* The full array of results from the query.
|
||||
*/
|
||||
public function preRender($result) { }
|
||||
public function preRender($result) {}
|
||||
|
||||
/**
|
||||
* Render a row object. This usually passes through to a theme template
|
||||
|
||||
@@ -28,7 +28,9 @@ abstract class SortPluginBase extends HandlerBase implements CacheableDependency
|
||||
/**
|
||||
* Determine if a sort can be exposed.
|
||||
*/
|
||||
public function canExpose() { return TRUE; }
|
||||
public function canExpose() {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to add the sort to a query.
|
||||
@@ -175,9 +177,9 @@ abstract class SortPluginBase extends HandlerBase implements CacheableDependency
|
||||
}
|
||||
}
|
||||
|
||||
protected function sortValidate(&$form, FormStateInterface $form_state) { }
|
||||
protected function sortValidate(&$form, FormStateInterface $form_state) {}
|
||||
|
||||
public function sortSubmit(&$form, FormStateInterface $form_state) { }
|
||||
public function sortSubmit(&$form, FormStateInterface $form_state) {}
|
||||
|
||||
/**
|
||||
* Provide a list of options for the default sort form.
|
||||
|
||||
@@ -385,7 +385,7 @@ abstract class StylePluginBase extends PluginBase {
|
||||
* @param \Drupal\Core\Form\FormStateInterface $form_state
|
||||
* The current state of the form.
|
||||
* @param string $type
|
||||
* The display type, either block or page.
|
||||
* The display type, either block or page.
|
||||
*/
|
||||
public function wizardForm(&$form, FormStateInterface $form_state, $type) {
|
||||
}
|
||||
@@ -413,13 +413,15 @@ abstract class StylePluginBase extends PluginBase {
|
||||
* interfere with the sorts. If so it should build; if it returns
|
||||
* any non-TRUE value, normal sorting will NOT be added to the query.
|
||||
*/
|
||||
public function buildSort() { return TRUE; }
|
||||
public function buildSort() {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the view builder to let the style build a second set of
|
||||
* sorts that will come after any other sorts in the view.
|
||||
*/
|
||||
public function buildSortPost() { }
|
||||
public function buildSortPost() {}
|
||||
|
||||
/**
|
||||
* Allow the style to do stuff before each row is rendered.
|
||||
@@ -788,7 +790,7 @@ abstract class StylePluginBase extends PluginBase {
|
||||
* @param $index
|
||||
* The index count of the row.
|
||||
* @param $field
|
||||
* The id of the field.
|
||||
* The id of the field.
|
||||
*/
|
||||
public function getFieldValue($index, $field) {
|
||||
$this->view->row_index = $index;
|
||||
|
||||
@@ -160,7 +160,7 @@ class Table extends StylePluginBase implements CacheableDependencyInterface {
|
||||
* display has listed due to access control or other changes.
|
||||
*
|
||||
* @return array
|
||||
* An array of all the sanitized columns.
|
||||
* An array of all the sanitized columns.
|
||||
*/
|
||||
public function sanitizeColumns($columns, $fields = NULL) {
|
||||
$sanitized = [];
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace Drupal\views\Tests;
|
||||
|
||||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\system\Tests\Cache\AssertPageCacheContextsAndTagsTrait;
|
||||
use Drupal\Tests\system\Functional\Cache\AssertPageCacheContextsAndTagsTrait;
|
||||
use Drupal\views\Plugin\views\display\DisplayPluginBase;
|
||||
use Drupal\views\ViewExecutable;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
@@ -5,6 +5,11 @@ namespace Drupal\views\Tests;
|
||||
use Drupal\Component\Render\MarkupInterface;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Tests\Views\FieldTestBase;
|
||||
use Drupal\language\Entity\ConfigurableLanguage;
|
||||
use Drupal\language\Entity\ContentLanguageSettings;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\node\Entity\NodeType;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
* Tests the Field Views data.
|
||||
@@ -13,10 +18,27 @@ use Drupal\field\Tests\Views\FieldTestBase;
|
||||
*/
|
||||
class FieldApiDataTest extends FieldTestBase {
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['language'];
|
||||
|
||||
$field_names = $this->setUpFieldStorages(1);
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $testViews = ['test_field_config_translation_filter'];
|
||||
|
||||
/**
|
||||
* The nodes used by the translation filter tests.
|
||||
*
|
||||
* @var \Drupal\node\NodeInterface[]
|
||||
*/
|
||||
protected $translationNodes;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp(FALSE);
|
||||
|
||||
$field_names = $this->setUpFieldStorages(4);
|
||||
|
||||
// Attach the field to nodes only.
|
||||
$field = [
|
||||
@@ -43,6 +65,109 @@ class FieldApiDataTest extends FieldTestBase {
|
||||
];
|
||||
$nodes[] = $this->drupalCreateNode($edit);
|
||||
}
|
||||
|
||||
$bundles = [];
|
||||
$bundles[] = $bundle = NodeType::create(['type' => 'bundle1']);
|
||||
$bundle->save();
|
||||
$bundles[] = $bundle = NodeType::create(['type' => 'bundle2']);
|
||||
$bundle->save();
|
||||
|
||||
// Make the first field translatable on all bundles.
|
||||
$field = FieldConfig::create([
|
||||
'field_name' => $field_names[1],
|
||||
'entity_type' => 'node',
|
||||
'bundle' => $bundles[0]->id(),
|
||||
'translatable' => TRUE,
|
||||
]);
|
||||
$field->save();
|
||||
$field = FieldConfig::create([
|
||||
'field_name' => $field_names[1],
|
||||
'entity_type' => 'node',
|
||||
'bundle' => $bundles[1]->id(),
|
||||
'translatable' => TRUE,
|
||||
]);
|
||||
$field->save();
|
||||
|
||||
// Make the second field not translatable on any bundle.
|
||||
$field = FieldConfig::create([
|
||||
'field_name' => $field_names[2],
|
||||
'entity_type' => 'node',
|
||||
'bundle' => $bundles[0]->id(),
|
||||
'translatable' => FALSE,
|
||||
]);
|
||||
$field->save();
|
||||
$field = FieldConfig::create([
|
||||
'field_name' => $field_names[2],
|
||||
'entity_type' => 'node',
|
||||
'bundle' => $bundles[1]->id(),
|
||||
'translatable' => FALSE,
|
||||
]);
|
||||
$field->save();
|
||||
|
||||
// Make the last field translatable on some bundles.
|
||||
$field = FieldConfig::create([
|
||||
'field_name' => $field_names[3],
|
||||
'entity_type' => 'node',
|
||||
'bundle' => $bundles[0]->id(),
|
||||
'translatable' => TRUE,
|
||||
]);
|
||||
$field->save();
|
||||
$field = FieldConfig::create([
|
||||
'field_name' => $field_names[3],
|
||||
'entity_type' => 'node',
|
||||
'bundle' => $bundles[1]->id(),
|
||||
'translatable' => FALSE,
|
||||
]);
|
||||
$field->save();
|
||||
|
||||
// Create some example content.
|
||||
ConfigurableLanguage::create([
|
||||
'id' => 'es',
|
||||
])->save();
|
||||
ConfigurableLanguage::create([
|
||||
'id' => 'fr',
|
||||
])->save();
|
||||
|
||||
$config = ContentLanguageSettings::loadByEntityTypeBundle('node', $bundles[0]->id());
|
||||
$config->setDefaultLangcode('es')
|
||||
->setLanguageAlterable(TRUE)
|
||||
->save();
|
||||
$config = ContentLanguageSettings::loadByEntityTypeBundle('node', $bundles[1]->id());
|
||||
$config->setDefaultLangcode('es')
|
||||
->setLanguageAlterable(TRUE)
|
||||
->save();
|
||||
|
||||
$node = Node::create([
|
||||
'title' => 'Test title ' . $bundles[0]->id(),
|
||||
'type' => $bundles[0]->id(),
|
||||
'langcode' => 'es',
|
||||
$field_names[1] => 'field name 1: es',
|
||||
$field_names[2] => 'field name 2: es',
|
||||
$field_names[3] => 'field name 3: es',
|
||||
]);
|
||||
$node->save();
|
||||
$this->translationNodes[] = $node;
|
||||
$translation = $node->addTranslation('fr');
|
||||
$translation->{$field_names[1]}->value = 'field name 1: fr';
|
||||
$translation->{$field_names[3]}->value = 'field name 3: fr';
|
||||
$translation->title->value = $node->title->value;
|
||||
$translation->save();
|
||||
|
||||
$node = Node::create([
|
||||
'title' => 'Test title ' . $bundles[1]->id(),
|
||||
'type' => $bundles[1]->id(),
|
||||
'langcode' => 'es',
|
||||
$field_names[1] => 'field name 1: es',
|
||||
$field_names[2] => 'field name 2: es',
|
||||
$field_names[3] => 'field name 3: es',
|
||||
]);
|
||||
$node->save();
|
||||
$this->translationNodes[] = $node;
|
||||
$translation = $node->addTranslation('fr');
|
||||
$translation->{$field_names[1]}->value = 'field name 1: fr';
|
||||
$translation->title->value = $node->title->value;
|
||||
$translation->save();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -137,4 +262,118 @@ class FieldApiDataTest extends FieldTestBase {
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests filtering entries with different translatabilty.
|
||||
*/
|
||||
public function testEntityFieldFilter() {
|
||||
$map = [
|
||||
'nid' => 'nid',
|
||||
'langcode' => 'langcode',
|
||||
];
|
||||
|
||||
$view = Views::getView('test_field_config_translation_filter');
|
||||
|
||||
// Filter by 'field name 1: es'.
|
||||
$view->setDisplay('embed_1');
|
||||
$this->executeView($view);
|
||||
$expected = [
|
||||
[
|
||||
'nid' => $this->translationNodes[0]->id(),
|
||||
'langcode' => 'es',
|
||||
],
|
||||
[
|
||||
'nid' => $this->translationNodes[1]->id(),
|
||||
'langcode' => 'es',
|
||||
],
|
||||
];
|
||||
|
||||
$this->assertIdenticalResultset($view, $expected, $map);
|
||||
$view->destroy();
|
||||
|
||||
// Filter by 'field name 1: fr'.
|
||||
$view->setDisplay('embed_2');
|
||||
$this->executeView($view);
|
||||
$expected = [
|
||||
[
|
||||
'nid' => $this->translationNodes[0]->id(),
|
||||
'langcode' => 'fr',
|
||||
],
|
||||
[
|
||||
'nid' => $this->translationNodes[1]->id(),
|
||||
'langcode' => 'fr',
|
||||
],
|
||||
];
|
||||
|
||||
$this->assertIdenticalResultset($view, $expected, $map);
|
||||
$view->destroy();
|
||||
|
||||
// Filter by 'field name 2: es'.
|
||||
$view->setDisplay('embed_3');
|
||||
$this->executeView($view);
|
||||
$expected = [
|
||||
[
|
||||
'nid' => $this->translationNodes[0]->id(),
|
||||
'langcode' => 'es',
|
||||
],
|
||||
[
|
||||
'nid' => $this->translationNodes[0]->id(),
|
||||
'langcode' => 'fr',
|
||||
],
|
||||
[
|
||||
'nid' => $this->translationNodes[1]->id(),
|
||||
'langcode' => 'es',
|
||||
],
|
||||
[
|
||||
'nid' => $this->translationNodes[1]->id(),
|
||||
'langcode' => 'fr',
|
||||
],
|
||||
];
|
||||
|
||||
$this->assertIdenticalResultset($view, $expected, $map);
|
||||
$view->destroy();
|
||||
|
||||
// Filter by 'field name 2: fr', which doesn't exist.
|
||||
$view->setDisplay('embed_4');
|
||||
$this->executeView($view);
|
||||
$expected = [];
|
||||
|
||||
$this->assertIdenticalResultset($view, $expected, $map);
|
||||
$view->destroy();
|
||||
|
||||
// Filter by 'field name 3: es'.
|
||||
$view->setDisplay('embed_5');
|
||||
$this->executeView($view);
|
||||
$expected = [
|
||||
[
|
||||
'nid' => $this->translationNodes[0]->id(),
|
||||
'langcode' => 'es',
|
||||
],
|
||||
[
|
||||
'nid' => $this->translationNodes[1]->id(),
|
||||
'langcode' => 'es',
|
||||
],
|
||||
// Why is this one returned?
|
||||
[
|
||||
'nid' => $this->translationNodes[1]->id(),
|
||||
'langcode' => 'fr',
|
||||
],
|
||||
];
|
||||
|
||||
$this->assertIdenticalResultset($view, $expected, $map);
|
||||
$view->destroy();
|
||||
|
||||
// Filter by 'field name 3: fr'.
|
||||
$view->setDisplay('embed_6');
|
||||
$this->executeView($view);
|
||||
$expected = [
|
||||
[
|
||||
'nid' => $this->translationNodes[0]->id(),
|
||||
'langcode' => 'fr',
|
||||
],
|
||||
];
|
||||
|
||||
$this->assertIdenticalResultset($view, $expected, $map);
|
||||
$view->destroy();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\views\Tests\Handler;
|
||||
|
||||
@trigger_error('\Drupal\views\Tests\Handler\HandlerTestBase is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\views\Functional\ViewTestBase', E_USER_DEPRECATED);
|
||||
|
||||
use Drupal\views\Tests\ViewTestBase;
|
||||
|
||||
@@ -45,10 +45,12 @@ class DisplayFeedTest extends PluginTestBase {
|
||||
$node_title = 'This "cool" & "neat" article\'s title';
|
||||
$node = $this->drupalCreateNode([
|
||||
'title' => $node_title,
|
||||
'body' => [0 => [
|
||||
'value' => 'A paragraph',
|
||||
'format' => filter_default_format(),
|
||||
]],
|
||||
'body' => [
|
||||
0 => [
|
||||
'value' => 'A paragraph',
|
||||
'format' => filter_default_format(),
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
// Test the site name setting.
|
||||
@@ -103,10 +105,12 @@ class DisplayFeedTest extends PluginTestBase {
|
||||
$node_title = 'This "cool" & "neat" article\'s title';
|
||||
$this->drupalCreateNode([
|
||||
'title' => $node_title,
|
||||
'body' => [0 => [
|
||||
'value' => 'A paragraph',
|
||||
'format' => filter_default_format(),
|
||||
]],
|
||||
'body' => [
|
||||
0 => [
|
||||
'value' => 'A paragraph',
|
||||
'format' => filter_default_format(),
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
$this->drupalGet('test-feed-display-fields.xml');
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\views\Tests\Plugin;
|
||||
|
||||
@trigger_error('\Drupal\views\Tests\Plugin\PluginTestBase is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\views\Functional\ViewTestBase', E_USER_DEPRECATED);
|
||||
|
||||
use Drupal\views\Tests\ViewTestBase;
|
||||
|
||||
@@ -126,6 +126,8 @@ abstract class ViewKernelTestBase extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* Returns the schema definition.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
protected function schemaDefinition() {
|
||||
return ViewTestData::schemaDefinition();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\views\Tests;
|
||||
|
||||
@trigger_error('\Drupal\views\Tests\ViewTestBase is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\views\Functional\ViewTestBase', E_USER_DEPRECATED);
|
||||
|
||||
use Drupal\Core\Database\Query\SelectInterface;
|
||||
@@ -95,7 +96,7 @@ abstract class ViewTestBase extends WebTestBase {
|
||||
*
|
||||
* @param string $id
|
||||
* The HTML ID of the button
|
||||
* @param string $label
|
||||
* @param string $expected_label
|
||||
* The expected label for the button.
|
||||
* @param string $message
|
||||
* (optional) A custom message to display with the assertion. If no custom
|
||||
@@ -131,6 +132,8 @@ abstract class ViewTestBase extends WebTestBase {
|
||||
|
||||
/**
|
||||
* Returns the schema definition.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
protected function schemaDefinition() {
|
||||
return ViewTestData::schemaDefinition();
|
||||
|
||||
@@ -58,6 +58,8 @@ class ViewTestData {
|
||||
|
||||
/**
|
||||
* Returns the schema definition.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public static function schemaDefinition() {
|
||||
$schema['views_test_data'] = [
|
||||
@@ -80,7 +82,8 @@ class ViewTestData {
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'default' => 0],
|
||||
'default' => 0,
|
||||
],
|
||||
'job' => [
|
||||
'description' => "The person's job",
|
||||
'type' => 'varchar',
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\views\Tests\Wizard;
|
||||
|
||||
@trigger_error('\Drupal\views\Tests\Wizard\WizardTestBase is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\views\Functional\Wizard\WizardTestBase', E_USER_DEPRECATED);
|
||||
|
||||
use Drupal\views\Tests\ViewTestBase;
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
namespace Drupal\views;
|
||||
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Component\Utility\Tags;
|
||||
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
|
||||
use Drupal\Core\Routing\RouteProviderInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\views\Plugin\views\display\DisplayRouterInterface;
|
||||
@@ -17,9 +17,14 @@ use Symfony\Component\Routing\Exception\RouteNotFoundException;
|
||||
*
|
||||
* An object to contain all of the data to generate a view, plus the member
|
||||
* functions to build the view query, execute the query and render the output.
|
||||
*
|
||||
* This class does not implement the Serializable interface since problems
|
||||
* occurred when using the serialize method.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2849674
|
||||
* @see https://bugs.php.net/bug.php?id=66052
|
||||
*/
|
||||
class ViewExecutable implements \Serializable {
|
||||
use DependencySerializationTrait;
|
||||
class ViewExecutable {
|
||||
|
||||
/**
|
||||
* The config entity in which the view is stored.
|
||||
@@ -434,6 +439,13 @@ class ViewExecutable implements \Serializable {
|
||||
*/
|
||||
protected $baseEntityType;
|
||||
|
||||
/**
|
||||
* Holds all necessary data for proper unserialization.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $serializationData;
|
||||
|
||||
/**
|
||||
* Constructs a new ViewExecutable object.
|
||||
*
|
||||
@@ -788,7 +800,7 @@ class ViewExecutable implements \Serializable {
|
||||
|
||||
// Ensure the requested display exists.
|
||||
if (!$this->displayHandlers->has($display_id)) {
|
||||
debug(format_string('setDisplay() called with invalid display ID "@display".', ['@display' => $display_id]));
|
||||
trigger_error(new FormattableMarkup('setDisplay() called with invalid display ID "@display".', ['@display' => $display_id]), E_USER_WARNING);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1327,8 +1339,8 @@ class ViewExecutable implements \Serializable {
|
||||
* @todo Some filter needs this function, even it is internal.
|
||||
*
|
||||
* @param string $key
|
||||
* The type of handlers (filter etc.) which should be iterated over to
|
||||
* build the relationship and query information.
|
||||
* The type of handlers (filter etc.) which should be iterated over to build
|
||||
* the relationship and query information.
|
||||
*/
|
||||
public function _build($key) {
|
||||
$handlers = &$this->$key;
|
||||
@@ -1746,7 +1758,7 @@ class ViewExecutable implements \Serializable {
|
||||
|
||||
// We can't use choose_display() here because that function
|
||||
// calls this one.
|
||||
$displays = (array)$displays;
|
||||
$displays = (array) $displays;
|
||||
foreach ($displays as $display_id) {
|
||||
if ($this->displayHandlers->has($display_id)) {
|
||||
if (($display = $this->displayHandlers->get($display_id)) && $display->access($account)) {
|
||||
@@ -2466,52 +2478,68 @@ class ViewExecutable implements \Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* Magic method implementation to serialize the view executable.
|
||||
*
|
||||
* @return array
|
||||
* The names of all variables that should be serialized.
|
||||
*/
|
||||
public function serialize() {
|
||||
return serialize([
|
||||
// Only serialize the storage entity ID.
|
||||
$this->storage->id(),
|
||||
$this->current_display,
|
||||
$this->args,
|
||||
$this->current_page,
|
||||
$this->exposed_input,
|
||||
$this->exposed_raw_input,
|
||||
$this->exposed_data,
|
||||
$this->dom_id,
|
||||
$this->executed,
|
||||
]);
|
||||
public function __sleep() {
|
||||
// Limit to only the required data which is needed to properly restore the
|
||||
// state during unserialization.
|
||||
$this->serializationData = [
|
||||
'storage' => $this->storage->id(),
|
||||
'views_data' => $this->viewsData->_serviceId,
|
||||
'route_provider' => $this->routeProvider->_serviceId,
|
||||
'current_display' => $this->current_display,
|
||||
'args' => $this->args,
|
||||
'current_page' => $this->current_page,
|
||||
'exposed_input' => $this->exposed_input,
|
||||
'exposed_raw_input' => $this->exposed_raw_input,
|
||||
'exposed_data' => $this->exposed_data,
|
||||
'dom_id' => $this->dom_id,
|
||||
'executed' => $this->executed,
|
||||
];
|
||||
return ['serializationData'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* Magic method implementation to unserialize the view executable.
|
||||
*/
|
||||
public function unserialize($serialized) {
|
||||
list($storage, $current_display, $args, $current_page, $exposed_input, $exposed_raw_input, $exposed_data, $dom_id, $executed) = unserialize($serialized);
|
||||
|
||||
// There are cases, like in testing, where we don't have a container
|
||||
public function __wakeup() {
|
||||
// There are cases, like in testing where we don't have a container
|
||||
// available.
|
||||
if (\Drupal::hasContainer()) {
|
||||
$this->setRequest(\Drupal::request());
|
||||
if (\Drupal::hasContainer() && !empty($this->serializationData)) {
|
||||
// Load and reference the storage.
|
||||
$this->storage = \Drupal::entityTypeManager()->getStorage('view')
|
||||
->load($this->serializationData['storage']);
|
||||
$this->storage->set('executable', $this);
|
||||
|
||||
// Attach all necessary services.
|
||||
$this->user = \Drupal::currentUser();
|
||||
$this->viewsData = \Drupal::service($this->serializationData['views_data']);
|
||||
$this->routeProvider = \Drupal::service($this->serializationData['route_provider']);
|
||||
|
||||
$this->storage = \Drupal::entityManager()->getStorage('view')->load($storage);
|
||||
|
||||
$this->setDisplay($current_display);
|
||||
$this->setArguments($args);
|
||||
$this->setCurrentPage($current_page);
|
||||
$this->setExposedInput($exposed_input);
|
||||
$this->exposed_data = $exposed_data;
|
||||
$this->exposed_raw_input = $exposed_raw_input;
|
||||
$this->dom_id = $dom_id;
|
||||
// Restore the state of this executable.
|
||||
if ($request = \Drupal::request()) {
|
||||
$this->setRequest($request);
|
||||
}
|
||||
$this->setDisplay($this->serializationData['current_display']);
|
||||
$this->setArguments($this->serializationData['args']);
|
||||
$this->setCurrentPage($this->serializationData['current_page']);
|
||||
$this->setExposedInput($this->serializationData['exposed_input']);
|
||||
$this->exposed_data = $this->serializationData['exposed_data'];
|
||||
$this->exposed_raw_input = $this->serializationData['exposed_raw_input'];
|
||||
$this->dom_id = $this->serializationData['dom_id'];
|
||||
|
||||
$this->initHandlers();
|
||||
|
||||
// If the display was previously executed, execute it now.
|
||||
if ($executed) {
|
||||
if ($this->serializationData['executed']) {
|
||||
$this->execute($this->current_display);
|
||||
}
|
||||
}
|
||||
// Unset serializationData since it serves no further purpose.
|
||||
unset($this->serializationData);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -283,8 +283,8 @@ class Views {
|
||||
* Filters the views on status. Can either be 'all' (default), 'enabled' or
|
||||
* 'disabled'
|
||||
* @param mixed $exclude_view
|
||||
* view or current display to exclude
|
||||
* either a
|
||||
* View or current display to exclude.
|
||||
* Either a:
|
||||
* - views object (containing $exclude_view->storage->name and $exclude_view->current_display)
|
||||
* - views name as string: e.g. my_view
|
||||
* - views name and display id (separated by ':'): e.g. my_view:default
|
||||
@@ -512,7 +512,7 @@ class Views {
|
||||
throw new \Exception('Invalid plugin type used. Valid types are "plugin" or "handler".');
|
||||
}
|
||||
|
||||
return array_keys(array_filter(static::$plugins, function($plugin_type) use ($type) {
|
||||
return array_keys(array_filter(static::$plugins, function ($plugin_type) use ($type) {
|
||||
return $plugin_type == $type;
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@ dependencies:
|
||||
- views
|
||||
- entity_test
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
# Information added by Drupal.org packaging script on 2017-11-03
|
||||
version: '8.4.2'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1502903957
|
||||
datestamp: 1509719929
|
||||
|
||||
@@ -12,7 +12,6 @@ use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
|
||||
|
||||
/**
|
||||
* Implements hook_entity_bundle_field_info().
|
||||
*/
|
||||
|
||||
+171
@@ -0,0 +1,171 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- entity_test
|
||||
id: computed_field_view
|
||||
label: 'Computed Field View'
|
||||
module: views
|
||||
description: ''
|
||||
tag: ''
|
||||
base_table: entity_test_computed_field
|
||||
base_field: id
|
||||
core: 8.x
|
||||
display:
|
||||
default:
|
||||
display_plugin: default
|
||||
id: default
|
||||
display_title: Master
|
||||
position: 0
|
||||
display_options:
|
||||
access:
|
||||
type: none
|
||||
options: { }
|
||||
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: default
|
||||
options:
|
||||
grouping: { }
|
||||
row_class: ''
|
||||
default_row_class: true
|
||||
uses_fields: false
|
||||
row:
|
||||
type: fields
|
||||
options:
|
||||
inline: { }
|
||||
separator: ''
|
||||
hide_empty: false
|
||||
default_field_elements: true
|
||||
fields:
|
||||
computed_string_field:
|
||||
id: computed_string_field
|
||||
table: entity_test_computed_field
|
||||
field: computed_string_field
|
||||
relationship: none
|
||||
group_type: group
|
||||
admin_label: ''
|
||||
label: ''
|
||||
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: false
|
||||
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: entity_test_computed_field
|
||||
plugin_id: field
|
||||
filters: { }
|
||||
sorts: { }
|
||||
header: { }
|
||||
footer: { }
|
||||
empty: { }
|
||||
relationships: { }
|
||||
arguments: { }
|
||||
display_extenders: { }
|
||||
cache_metadata:
|
||||
max-age: -1
|
||||
contexts:
|
||||
- 'languages:language_content'
|
||||
- 'languages:language_interface'
|
||||
- url.query_args
|
||||
tags: { }
|
||||
page_1:
|
||||
display_plugin: page
|
||||
id: page_1
|
||||
display_title: Page
|
||||
position: 1
|
||||
display_options:
|
||||
display_extenders: { }
|
||||
path: foo
|
||||
cache_metadata:
|
||||
max-age: -1
|
||||
contexts:
|
||||
- 'languages:language_content'
|
||||
- 'languages:language_interface'
|
||||
- url.query_args
|
||||
tags: { }
|
||||
+213
@@ -0,0 +1,213 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- user.role.authenticated
|
||||
module:
|
||||
- node
|
||||
- rest
|
||||
- user
|
||||
id: rest_export_with_authorization_correction
|
||||
label: 'Rest Export'
|
||||
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: role
|
||||
options:
|
||||
role:
|
||||
authenticated: authenticated
|
||||
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: Filter
|
||||
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: full
|
||||
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: '‹ Previous'
|
||||
next: 'Next ›'
|
||||
first: '« First'
|
||||
last: 'Last »'
|
||||
quantity: 9
|
||||
style:
|
||||
type: default
|
||||
row:
|
||||
type: 'fields'
|
||||
fields:
|
||||
title:
|
||||
id: title
|
||||
table: node_field_data
|
||||
field: title
|
||||
entity_type: node
|
||||
entity_field: title
|
||||
label: ''
|
||||
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: ''
|
||||
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
|
||||
filters:
|
||||
status:
|
||||
id: status
|
||||
table: node_field_data
|
||||
field: status
|
||||
relationship: none
|
||||
group_type: group
|
||||
admin_label: ''
|
||||
operator: '='
|
||||
value: '0'
|
||||
group: 1
|
||||
exposed: false
|
||||
expose:
|
||||
operator_id: ''
|
||||
label: ''
|
||||
description: ''
|
||||
use_operator: false
|
||||
operator: ''
|
||||
identifier: ''
|
||||
required: false
|
||||
remember: false
|
||||
multiple: false
|
||||
remember_roles:
|
||||
authenticated: authenticated
|
||||
is_grouped: false
|
||||
group_info:
|
||||
label: ''
|
||||
description: ''
|
||||
identifier: ''
|
||||
optional: true
|
||||
widget: select
|
||||
multiple: false
|
||||
remember: false
|
||||
default_group: All
|
||||
default_group_multiple: { }
|
||||
group_items: { }
|
||||
plugin_id: boolean
|
||||
entity_type: node
|
||||
entity_field: 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: 'Rest Export'
|
||||
header: { }
|
||||
footer: { }
|
||||
empty: { }
|
||||
relationships: { }
|
||||
arguments: { }
|
||||
display_extenders: { }
|
||||
cache_metadata:
|
||||
max-age: -1
|
||||
contexts:
|
||||
- 'languages:language_content'
|
||||
- 'languages:language_interface'
|
||||
- url.query_args
|
||||
- 'user.node_grants:view'
|
||||
- user.roles
|
||||
tags: { }
|
||||
rest_export_1:
|
||||
display_plugin: rest_export
|
||||
id: rest_export_1
|
||||
display_title: 'REST export'
|
||||
position: 2
|
||||
display_options:
|
||||
display_extenders: { }
|
||||
path: unpublished-content
|
||||
auth:
|
||||
- user
|
||||
cache_metadata:
|
||||
max-age: -1
|
||||
contexts:
|
||||
- 'languages:language_content'
|
||||
- 'languages:language_interface'
|
||||
- request_format
|
||||
- 'user.node_grants:view'
|
||||
- user.roles
|
||||
tags: { }
|
||||
+225
@@ -0,0 +1,225 @@
|
||||
uuid: b133bd43-c494-4db6-83f0-24380fe3964b
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- user
|
||||
id: test_entity_row_renderers_revisions_base
|
||||
label: test_entity_row_renderers_revisions_base
|
||||
module: views
|
||||
description: ''
|
||||
tag: ''
|
||||
base_table: node_field_revision
|
||||
base_field: vid
|
||||
core: 8.x
|
||||
display:
|
||||
default:
|
||||
display_plugin: default
|
||||
id: default
|
||||
display_title: Master
|
||||
position: 0
|
||||
display_options:
|
||||
access:
|
||||
type: perm
|
||||
options:
|
||||
perm: 'view all revisions'
|
||||
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: none
|
||||
options:
|
||||
offset: 0
|
||||
style:
|
||||
type: default
|
||||
options:
|
||||
grouping: { }
|
||||
row_class: ''
|
||||
default_row_class: true
|
||||
uses_fields: false
|
||||
row:
|
||||
type: fields
|
||||
options:
|
||||
inline: { }
|
||||
separator: ''
|
||||
hide_empty: false
|
||||
default_field_elements: true
|
||||
fields:
|
||||
nid:
|
||||
id: nid
|
||||
table: node_field_revision
|
||||
field: nid
|
||||
relationship: none
|
||||
group_type: group
|
||||
admin_label: ''
|
||||
label: ''
|
||||
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: false
|
||||
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: number_integer
|
||||
settings:
|
||||
thousand_separator: ''
|
||||
prefix_suffix: true
|
||||
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: nid
|
||||
plugin_id: field
|
||||
uid:
|
||||
id: uid
|
||||
table: users_field_data
|
||||
field: uid
|
||||
relationship: revision_uid
|
||||
group_type: group
|
||||
admin_label: ''
|
||||
label: ''
|
||||
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: false
|
||||
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: number_integer
|
||||
settings:
|
||||
thousand_separator: ''
|
||||
prefix_suffix: true
|
||||
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: user
|
||||
entity_field: uid
|
||||
plugin_id: field
|
||||
filters: { }
|
||||
sorts: { }
|
||||
header: { }
|
||||
footer: { }
|
||||
empty: { }
|
||||
relationships:
|
||||
revision_uid:
|
||||
id: revision_uid
|
||||
table: node_revision
|
||||
field: revision_uid
|
||||
relationship: none
|
||||
group_type: group
|
||||
admin_label: 'revision user'
|
||||
required: false
|
||||
entity_type: node
|
||||
entity_field: revision_uid
|
||||
plugin_id: standard
|
||||
arguments: { }
|
||||
display_extenders: { }
|
||||
cache_metadata:
|
||||
max-age: -1
|
||||
contexts:
|
||||
- 'languages:language_content'
|
||||
- 'languages:language_interface'
|
||||
- 'user.node_grants:view'
|
||||
- user.permissions
|
||||
tags: { }
|
||||
|
||||
+155
@@ -0,0 +1,155 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
config:
|
||||
- taxonomy.vocabulary.test_exposed_checkboxes
|
||||
module:
|
||||
- node
|
||||
- taxonomy
|
||||
id: test_exposed_form_checkboxes
|
||||
label: ''
|
||||
module: views
|
||||
description: ''
|
||||
tag: ''
|
||||
base_table: node_field_data
|
||||
base_field: nid
|
||||
core: '8'
|
||||
display:
|
||||
default:
|
||||
display_options:
|
||||
access:
|
||||
type: none
|
||||
cache:
|
||||
type: tag
|
||||
exposed_form:
|
||||
options:
|
||||
reset_button: true
|
||||
type: basic
|
||||
filters:
|
||||
type:
|
||||
id: type
|
||||
table: node_field_data
|
||||
field: type
|
||||
relationship: none
|
||||
group_type: group
|
||||
admin_label: ''
|
||||
operator: in
|
||||
value: { }
|
||||
group: 1
|
||||
exposed: true
|
||||
expose:
|
||||
operator_id: type_op
|
||||
label: 'Content: Type'
|
||||
description: 'Exposed description'
|
||||
use_operator: false
|
||||
operator: ''
|
||||
identifier: type
|
||||
required: false
|
||||
remember: false
|
||||
multiple: true
|
||||
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: { }
|
||||
plugin_id: in_operator
|
||||
entity_type: node
|
||||
entity_field: type
|
||||
tid:
|
||||
id: tid
|
||||
table: taxonomy_index
|
||||
field: tid
|
||||
relationship: none
|
||||
group_type: group
|
||||
admin_label: ''
|
||||
operator: and
|
||||
value: { }
|
||||
group: 1
|
||||
exposed: true
|
||||
expose:
|
||||
operator_id: tid_op
|
||||
label: 'Has taxonomy term'
|
||||
description: ''
|
||||
use_operator: false
|
||||
operator: tid_op
|
||||
identifier: tid
|
||||
required: false
|
||||
remember: false
|
||||
multiple: true
|
||||
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: { }
|
||||
reduce_duplicates: false
|
||||
type: select
|
||||
limit: true
|
||||
vid: test_exposed_checkboxes
|
||||
hierarchy: false
|
||||
error_message: true
|
||||
plugin_id: taxonomy_index_tid
|
||||
pager:
|
||||
type: full
|
||||
query:
|
||||
options:
|
||||
query_comment: ''
|
||||
type: views_query
|
||||
style:
|
||||
type: default
|
||||
row:
|
||||
type: 'entity:node'
|
||||
display_extenders: { }
|
||||
display_plugin: default
|
||||
display_title: Master
|
||||
id: default
|
||||
position: 0
|
||||
cache_metadata:
|
||||
max-age: -1
|
||||
contexts:
|
||||
- 'languages:language_interface'
|
||||
- url
|
||||
- url.query_args
|
||||
- user
|
||||
- 'user.node_grants:view'
|
||||
tags: { }
|
||||
page_1:
|
||||
display_options:
|
||||
path: test_exposed_form_checkboxes
|
||||
display_extenders: { }
|
||||
display_plugin: page
|
||||
display_title: Page
|
||||
id: page_1
|
||||
position: 0
|
||||
cache_metadata:
|
||||
max-age: -1
|
||||
contexts:
|
||||
- 'languages:language_interface'
|
||||
- url
|
||||
- url.query_args
|
||||
- user
|
||||
- 'user.node_grants:view'
|
||||
tags: { }
|
||||
+187
@@ -0,0 +1,187 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies: { }
|
||||
id: test_field_config_translation_filter
|
||||
module: views
|
||||
description: ''
|
||||
tag: ''
|
||||
base_table: node_field_data
|
||||
base_field: id
|
||||
core: '8'
|
||||
display:
|
||||
default:
|
||||
display_options:
|
||||
access:
|
||||
type: none
|
||||
cache:
|
||||
type: none
|
||||
fields:
|
||||
nid:
|
||||
id: nid
|
||||
field: nid
|
||||
table: node_field_data
|
||||
plugin_id: field
|
||||
entity_type: node
|
||||
entity_field: nid
|
||||
langcode:
|
||||
id: langcode
|
||||
field: langcode
|
||||
table: node_field_data
|
||||
plugin_id: field
|
||||
entity_type: node
|
||||
entity_field: langcode
|
||||
field_name_1:
|
||||
id: field_name_1
|
||||
table: node__field_name_1
|
||||
field: field_name_1
|
||||
plugin_id: field
|
||||
entity_type: node
|
||||
entity_field: field_name_1
|
||||
field_name_2:
|
||||
id: field_name_2
|
||||
table: node__field_name_2
|
||||
field: field_name_2
|
||||
plugin_id: field
|
||||
entity_type: node
|
||||
entity_field: field_name_2
|
||||
field_name_3:
|
||||
id: field_name_3
|
||||
table: node__field_name_3
|
||||
field: field_name_3
|
||||
plugin_id: field
|
||||
entity_type: node
|
||||
entity_field: field_name_3
|
||||
sorts:
|
||||
nid:
|
||||
id: nid
|
||||
table: node_field_data
|
||||
field: nid
|
||||
order: ASC
|
||||
plugin_id: standard
|
||||
entity_type: node
|
||||
entity_field: nid
|
||||
langcode:
|
||||
id: langcode
|
||||
table: node_field_data
|
||||
field: langcode
|
||||
relationship: none
|
||||
group_type: group
|
||||
admin_label: ''
|
||||
order: ASC
|
||||
exposed: false
|
||||
expose:
|
||||
label: ''
|
||||
entity_type: node
|
||||
entity_field: langcode
|
||||
plugin_id: standard
|
||||
style:
|
||||
type: html_list
|
||||
row:
|
||||
type: fields
|
||||
display_plugin: default
|
||||
display_title: Master
|
||||
id: default
|
||||
position: 0
|
||||
embed_1:
|
||||
display_options:
|
||||
defaults:
|
||||
fields: true
|
||||
filters: false
|
||||
filters:
|
||||
field_name_1_value:
|
||||
id: field_name_1_value
|
||||
table: node__field_name_1
|
||||
field: field_name_1_value
|
||||
value: 'field name 1: es'
|
||||
plugin_id: string
|
||||
entity_type: node
|
||||
entity_field: field_name_1
|
||||
display_plugin: embed
|
||||
display_title: Embed 1
|
||||
id: embed_1
|
||||
position: 1
|
||||
embed_2:
|
||||
display_options:
|
||||
defaults:
|
||||
filters: false
|
||||
filters:
|
||||
field_name_1_value:
|
||||
id: field_name_1_value
|
||||
table: node__field_name_1
|
||||
field: field_name_1_value
|
||||
value: 'field name 1: fr'
|
||||
plugin_id: string
|
||||
entity_type: node
|
||||
entity_field: field_name_1
|
||||
display_plugin: embed
|
||||
display_title: Embed 2
|
||||
id: embed_2
|
||||
position: 2
|
||||
embed_3:
|
||||
display_options:
|
||||
defaults:
|
||||
filters: false
|
||||
filters:
|
||||
field_name_2_value:
|
||||
id: field_name_2_value
|
||||
table: node__field_name_2
|
||||
field: field_name_2_value
|
||||
value: 'field name 2: es'
|
||||
plugin_id: string
|
||||
entity_type: node
|
||||
entity_field: field_name_2
|
||||
display_plugin: embed
|
||||
display_title: Embed 3
|
||||
id: embed_3
|
||||
position: 3
|
||||
embed_4:
|
||||
display_options:
|
||||
defaults:
|
||||
filters: false
|
||||
filters:
|
||||
field_name_2_value:
|
||||
id: field_name_2_value
|
||||
table: node__field_name_2
|
||||
field: field_name_2_value
|
||||
value: 'field name 2: fr'
|
||||
plugin_id: string
|
||||
entity_type: node
|
||||
entity_field: field_name_2
|
||||
display_plugin: embed
|
||||
display_title: Embed 4
|
||||
id: embed_4
|
||||
position: 4
|
||||
embed_5:
|
||||
display_options:
|
||||
defaults:
|
||||
filters: false
|
||||
filters:
|
||||
field_name_3_value:
|
||||
id: field_name_3_value
|
||||
table: node__field_name_3
|
||||
field: field_name_3_value
|
||||
value: 'field name 3: es'
|
||||
plugin_id: string
|
||||
entity_type: node
|
||||
entity_field: field_name_3
|
||||
display_plugin: embed
|
||||
display_title: Embed 5
|
||||
id: embed_5
|
||||
position: 5
|
||||
embed_6:
|
||||
display_options:
|
||||
defaults:
|
||||
filters: false
|
||||
filters:
|
||||
field_name_3_value:
|
||||
id: field_name_3_value
|
||||
table: node__field_name_3
|
||||
field: field_name_3_value
|
||||
value: 'field name 3: fr'
|
||||
plugin_id: string
|
||||
entity_type: node
|
||||
entity_field: field_name_3
|
||||
display_plugin: embed
|
||||
display_title: Embed 6
|
||||
id: embed_6
|
||||
position: 6
|
||||
+163
@@ -0,0 +1,163 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- node
|
||||
id: test_latest_revision_filter
|
||||
label: ''
|
||||
module: views
|
||||
description: ''
|
||||
tag: ''
|
||||
base_table: node_field_revision
|
||||
base_field: vid
|
||||
core: 8.x
|
||||
display:
|
||||
default:
|
||||
display_plugin: default
|
||||
id: default
|
||||
display_title: Master
|
||||
position: 0
|
||||
display_options:
|
||||
access:
|
||||
type: none
|
||||
options: { }
|
||||
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: none
|
||||
options:
|
||||
offset: 0
|
||||
style:
|
||||
type: default
|
||||
options:
|
||||
grouping: { }
|
||||
row_class: ''
|
||||
default_row_class: true
|
||||
uses_fields: false
|
||||
row:
|
||||
type: fields
|
||||
options:
|
||||
inline: { }
|
||||
separator: ''
|
||||
hide_empty: false
|
||||
default_field_elements: true
|
||||
fields:
|
||||
title:
|
||||
id: title
|
||||
table: node_field_revision
|
||||
field: title
|
||||
entity_type: node
|
||||
entity_field: title
|
||||
label: ''
|
||||
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: false
|
||||
plugin_id: field
|
||||
relationship: none
|
||||
group_type: group
|
||||
admin_label: ''
|
||||
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
|
||||
filters:
|
||||
latest_revision:
|
||||
id: latest_revision
|
||||
table: node_revision
|
||||
field: latest_revision
|
||||
relationship: none
|
||||
group_type: group
|
||||
admin_label: ''
|
||||
operator: '='
|
||||
value: ''
|
||||
group: 1
|
||||
exposed: false
|
||||
expose:
|
||||
operator_id: ''
|
||||
label: ''
|
||||
description: ''
|
||||
use_operator: false
|
||||
operator: ''
|
||||
identifier: ''
|
||||
required: false
|
||||
remember: false
|
||||
multiple: false
|
||||
remember_roles:
|
||||
authenticated: authenticated
|
||||
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: latest_revision
|
||||
sorts: { }
|
||||
header: { }
|
||||
footer: { }
|
||||
empty: { }
|
||||
relationships: { }
|
||||
arguments: { }
|
||||
display_extenders: { }
|
||||
show_admin_links: false
|
||||
cache_metadata:
|
||||
max-age: -1
|
||||
contexts:
|
||||
- 'languages:language_content'
|
||||
- 'languages:language_interface'
|
||||
- 'user.node_grants:view'
|
||||
tags: { }
|
||||
-1
@@ -59,7 +59,6 @@ display:
|
||||
type: string
|
||||
settings:
|
||||
link_to_entity: true
|
||||
plugin_id: field
|
||||
filters:
|
||||
type:
|
||||
id: type
|
||||
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies: { }
|
||||
id: test_view_sort_translation
|
||||
module: views
|
||||
description: ''
|
||||
tag: ''
|
||||
base_table: node_field_data
|
||||
base_field: id
|
||||
core: '8'
|
||||
display:
|
||||
default:
|
||||
display_options:
|
||||
fields:
|
||||
nid:
|
||||
id: nid
|
||||
field: nid
|
||||
table: node_field_data
|
||||
plugin_id: field
|
||||
entity_type: node
|
||||
entity_field: nid
|
||||
langcode:
|
||||
id: langcode
|
||||
field: langcode
|
||||
table: node_field_data
|
||||
plugin_id: field
|
||||
entity_type: node
|
||||
entity_field: langcode
|
||||
weight:
|
||||
id: weight
|
||||
table: node__weight
|
||||
field: weight
|
||||
plugin_id: numeric
|
||||
entity_type: node
|
||||
entity_field: weight
|
||||
filters:
|
||||
langcode:
|
||||
id: langcode
|
||||
table: node_field_data
|
||||
field: langcode
|
||||
relationship: none
|
||||
group_type: group
|
||||
admin_label: ''
|
||||
operator: in
|
||||
value:
|
||||
'en': 'en'
|
||||
group: 1
|
||||
exposed: false
|
||||
entity_type: node
|
||||
entity_field: langcode
|
||||
plugin_id: language
|
||||
sorts:
|
||||
weight:
|
||||
id: weight
|
||||
table: node__weight
|
||||
field: weight_value
|
||||
order: ASC
|
||||
plugin_id: standard
|
||||
entity_type: node
|
||||
entity_field: weight
|
||||
display_plugin: default
|
||||
display_title: Master
|
||||
id: default
|
||||
position: 0
|
||||
display_de:
|
||||
display_plugin: embed
|
||||
id: display_de
|
||||
display_options:
|
||||
defaults:
|
||||
filters: false
|
||||
filters:
|
||||
langcode:
|
||||
id: langcode
|
||||
table: node_field_data
|
||||
field: langcode
|
||||
relationship: none
|
||||
group_type: group
|
||||
admin_label: ''
|
||||
operator: in
|
||||
value:
|
||||
'de': 'de'
|
||||
group: 1
|
||||
exposed: false
|
||||
entity_type: node
|
||||
entity_field: langcode
|
||||
plugin_id: language
|
||||
@@ -7,8 +7,8 @@ package: Testing
|
||||
dependencies:
|
||||
- views
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
# Information added by Drupal.org packaging script on 2017-11-03
|
||||
version: '8.4.2'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1502903957
|
||||
datestamp: 1509719929
|
||||
|
||||
+1
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\views_test_data\Plugin\views\argument_validator;
|
||||
|
||||
use Drupal\views\Plugin\views\argument_validator\ArgumentValidatorPluginBase;
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* @file
|
||||
* Just a placeholder file for the test.
|
||||
*
|
||||
* @see ViewsCacheTest::testHeaderStorage
|
||||
*
|
||||
* @ignore
|
||||
*/
|
||||
@@ -1,8 +1,6 @@
|
||||
/**
|
||||
* @file
|
||||
* Just a placeholder file for the test.
|
||||
*
|
||||
* @see ViewsCacheTest::testHeaderStorage
|
||||
*
|
||||
* @ignore
|
||||
*/
|
||||
* DO NOT EDIT THIS FILE.
|
||||
* See the following change record for more information,
|
||||
* https://www.drupal.org/node/2815083
|
||||
* @preserve
|
||||
**/
|
||||
@@ -7,8 +7,8 @@ package: Testing
|
||||
dependencies:
|
||||
- views
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
# Information added by Drupal.org packaging script on 2017-11-03
|
||||
version: '8.4.2'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1502903957
|
||||
datestamp: 1509719929
|
||||
|
||||
@@ -7,8 +7,8 @@ package: Testing
|
||||
dependencies:
|
||||
- views
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
# Information added by Drupal.org packaging script on 2017-11-03
|
||||
version: '8.4.2'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1502903957
|
||||
datestamp: 1509719929
|
||||
|
||||
@@ -8,8 +8,8 @@ dependencies:
|
||||
- views
|
||||
- language
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
# Information added by Drupal.org packaging script on 2017-11-03
|
||||
version: '8.4.2'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1502903957
|
||||
datestamp: 1509719929
|
||||
|
||||
@@ -100,6 +100,15 @@ class DefaultViewsTest extends ViewTestBase {
|
||||
'field_name' => 'comment'
|
||||
];
|
||||
Comment::create($comment)->save();
|
||||
|
||||
$unpublished_comment = [
|
||||
'uid' => $user->id(),
|
||||
'status' => CommentInterface::NOT_PUBLISHED,
|
||||
'entity_id' => $node->id(),
|
||||
'entity_type' => 'node',
|
||||
'field_name' => 'comment',
|
||||
];
|
||||
Comment::create($unpublished_comment)->save();
|
||||
}
|
||||
|
||||
// Some views, such as the "Who's Online" view, only return results if at
|
||||
@@ -165,16 +174,19 @@ class DefaultViewsTest extends ViewTestBase {
|
||||
// Create additional nodes compared to the one in the setup method.
|
||||
// Create two nodes in the same month, and one in each following month.
|
||||
$node = [
|
||||
'created' => 280299600, // Sun, 19 Nov 1978 05:00:00 GMT
|
||||
// Sun, 19 Nov 1978 05:00:00 GMT.
|
||||
'created' => 280299600,
|
||||
];
|
||||
$this->drupalCreateNode($node);
|
||||
$this->drupalCreateNode($node);
|
||||
$node = [
|
||||
'created' => 282891600, // Tue, 19 Dec 1978 05:00:00 GMT
|
||||
// Tue, 19 Dec 1978 05:00:00 GMT.
|
||||
'created' => 282891600,
|
||||
];
|
||||
$this->drupalCreateNode($node);
|
||||
$node = [
|
||||
'created' => 285570000, // Fri, 19 Jan 1979 05:00:00 GMT
|
||||
// Fri, 19 Jan 1979 05:00:00 GMT.
|
||||
'created' => 285570000,
|
||||
];
|
||||
$this->drupalCreateNode($node);
|
||||
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\views\Functional\Entity;
|
||||
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\Tests\views\Functional\ViewTestBase;
|
||||
use Drupal\views\ViewExecutable;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
* Tests the 'Latest revision' filter.
|
||||
*
|
||||
* @group views
|
||||
*/
|
||||
class LatestRevisionFilterTest extends ViewTestBase {
|
||||
|
||||
/**
|
||||
* An array of node revisions.
|
||||
*
|
||||
* @var \Drupal\node\NodeInterface[]
|
||||
*/
|
||||
protected $allRevisions = [];
|
||||
|
||||
/**
|
||||
* An array of node revisions.
|
||||
*
|
||||
* @var \Drupal\node\NodeInterface[]
|
||||
*/
|
||||
protected $latestRevisions = [];
|
||||
|
||||
/**
|
||||
* Views used by this test.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $testViews = ['test_latest_revision_filter'];
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['node'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp($import_test_views = TRUE) {
|
||||
parent::setUp();
|
||||
|
||||
$this->drupalCreateContentType(['type' => 'article']);
|
||||
|
||||
// Create a node that goes through various default/pending revision stages.
|
||||
$node = Node::create([
|
||||
'title' => 'First node - v1 - default',
|
||||
'type' => 'article',
|
||||
]);
|
||||
$node->save();
|
||||
$this->allRevisions[$node->getRevisionId()] = $node;
|
||||
|
||||
$node->setTitle('First node - v2 - pending');
|
||||
$node->setNewRevision(TRUE);
|
||||
$node->isDefaultRevision(FALSE);
|
||||
$node->save();
|
||||
$this->allRevisions[$node->getRevisionId()] = $node;
|
||||
|
||||
$node->setTitle('First node - v3 - default');
|
||||
$node->setNewRevision(TRUE);
|
||||
$node->isDefaultRevision(TRUE);
|
||||
$node->save();
|
||||
$this->allRevisions[$node->getRevisionId()] = $node;
|
||||
|
||||
$node->setTitle('First node - v4 - pending');
|
||||
$node->setNewRevision(TRUE);
|
||||
$node->isDefaultRevision(TRUE);
|
||||
$node->save();
|
||||
$this->allRevisions[$node->getRevisionId()] = $node;
|
||||
$this->latestRevisions[$node->getRevisionId()] = $node;
|
||||
|
||||
// Create a node that has a default and a pending revision.
|
||||
$node = Node::create([
|
||||
'title' => 'Second node - v1 - default',
|
||||
'type' => 'article',
|
||||
]);
|
||||
$node->save();
|
||||
$this->allRevisions[$node->getRevisionId()] = $node;
|
||||
|
||||
$node->setTitle('Second node - v2 - pending');
|
||||
$node->setNewRevision(TRUE);
|
||||
$node->isDefaultRevision(FALSE);
|
||||
$node->save();
|
||||
$this->allRevisions[$node->getRevisionId()] = $node;
|
||||
$this->latestRevisions[$node->getRevisionId()] = $node;
|
||||
|
||||
// Create a node that only has a default revision.
|
||||
$node = Node::create([
|
||||
'title' => 'Third node - v1 - default',
|
||||
'type' => 'article',
|
||||
]);
|
||||
$node->save();
|
||||
$this->allRevisions[$node->getRevisionId()] = $node;
|
||||
$this->latestRevisions[$node->getRevisionId()] = $node;
|
||||
|
||||
// Create a node that only has a pending revision.
|
||||
$node = Node::create([
|
||||
'title' => 'Fourth node - v1 - pending',
|
||||
'type' => 'article',
|
||||
]);
|
||||
$node->isDefaultRevision(FALSE);
|
||||
$node->save();
|
||||
$this->allRevisions[$node->getRevisionId()] = $node;
|
||||
$this->latestRevisions[$node->getRevisionId()] = $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the 'Latest revision' filter.
|
||||
*/
|
||||
public function testLatestRevisionFilter() {
|
||||
$view = Views::getView('test_latest_revision_filter');
|
||||
|
||||
$this->executeView($view);
|
||||
|
||||
// Check that we have all the results.
|
||||
$this->assertCount(count($this->latestRevisions), $view->result);
|
||||
|
||||
$expected = $not_expected = [];
|
||||
foreach ($this->allRevisions as $revision_id => $revision) {
|
||||
if (isset($this->latestRevisions[$revision_id])) {
|
||||
$expected[] = [
|
||||
'vid' => $revision_id,
|
||||
'title' => $revision->label(),
|
||||
];
|
||||
}
|
||||
else {
|
||||
$not_expected[] = $revision_id;
|
||||
}
|
||||
}
|
||||
$this->assertIdenticalResultset($view, $expected, ['vid' => 'vid', 'title' => 'title'], 'The test view only shows the latest revisions.');
|
||||
$this->assertNotInResultSet($view, $not_expected, 'Non-latest revisions are not shown by the view.');
|
||||
$view->destroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that a list of revision IDs are not in the result.
|
||||
*
|
||||
* @param \Drupal\views\ViewExecutable $view
|
||||
* An executed View.
|
||||
* @param array $not_expected_revision_ids
|
||||
* An array of revision IDs which should not be part of the result set.
|
||||
* @param string $message
|
||||
* (optional) A custom message to display with the assertion.
|
||||
*/
|
||||
protected function assertNotInResultSet(ViewExecutable $view, array $not_expected_revision_ids, $message = '') {
|
||||
$found_revision_ids = array_filter($view->result, function ($row) use ($not_expected_revision_ids) {
|
||||
return in_array($row->vid, $not_expected_revision_ids);
|
||||
});
|
||||
$this->assertFalse($found_revision_ids, $message);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,7 +7,7 @@ use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Component\Utility\UrlHelper;
|
||||
use Drupal\Core\Render\RenderContext;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\system\Tests\Cache\AssertPageCacheContextsAndTagsTrait;
|
||||
use Drupal\Tests\system\Functional\Cache\AssertPageCacheContextsAndTagsTrait;
|
||||
use Drupal\Tests\views\Functional\ViewTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ use Drupal\views\Views;
|
||||
use Drupal\views_test_data\Plugin\views\argument_default\ArgumentDefaultTest as ArgumentDefaultTestPlugin;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
|
||||
/**
|
||||
* Tests pluggable argument_default for views.
|
||||
*
|
||||
@@ -131,7 +130,7 @@ class ArgumentDefaultTest extends ViewTestBase {
|
||||
/**
|
||||
* @todo Test php default argument.
|
||||
*/
|
||||
//function testArgumentDefaultPhp() {}
|
||||
// function testArgumentDefaultPhp() {}
|
||||
|
||||
/**
|
||||
* Test node default argument.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace Drupal\Tests\views\Functional\Plugin;
|
||||
|
||||
use Drupal\system\Tests\Cache\AssertPageCacheContextsAndTagsTrait;
|
||||
use Drupal\Tests\system\Functional\Cache\AssertPageCacheContextsAndTagsTrait;
|
||||
use Drupal\Tests\views\Functional\ViewTestBase;
|
||||
use Drupal\views\Plugin\views\display\DisplayPluginBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
+1
-1
@@ -3,9 +3,9 @@
|
||||
namespace Drupal\Tests\views\Functional\Plugin;
|
||||
|
||||
use Drupal\Core\Plugin\Context\ContextDefinitionInterface;
|
||||
use Drupal\Tests\system\Functional\Cache\AssertPageCacheContextsAndTagsTrait;
|
||||
use Drupal\Tests\views\Functional\ViewTestBase;
|
||||
use Drupal\views\Tests\ViewTestData;
|
||||
use Drupal\system\Tests\Cache\AssertPageCacheContextsAndTagsTrait;
|
||||
|
||||
/**
|
||||
* A test for contextual filters exposed as block context.
|
||||
|
||||
@@ -249,6 +249,12 @@ class DisplayEntityReferenceTest extends ViewTestBase {
|
||||
$this->executeView($view);
|
||||
|
||||
$this->assertEqual(count($view->result), 2, 'Search returned two rows');
|
||||
|
||||
// Test that the render() return empty array for empty result.
|
||||
$view = Views::getView('test_display_entity_reference');
|
||||
$view->setDisplay('entity_reference_1');
|
||||
$render = $view->display_handler->render();
|
||||
$this->assertSame([], $render, 'Render returned empty array');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace Drupal\Tests\views\Functional\Plugin;
|
||||
|
||||
use Drupal\system\Tests\Cache\AssertPageCacheContextsAndTagsTrait;
|
||||
use Drupal\Tests\system\Functional\Cache\AssertPageCacheContextsAndTagsTrait;
|
||||
use Drupal\Tests\views\Functional\ViewTestBase;
|
||||
use Drupal\views\Views;
|
||||
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\views\Functional\Plugin;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
|
||||
use Drupal\taxonomy\Entity\Term;
|
||||
use Drupal\taxonomy\Entity\Vocabulary;
|
||||
use Drupal\Tests\views\Functional\ViewTestBase;
|
||||
use Drupal\views\Tests\ViewTestData;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
* Tests exposed forms functionality.
|
||||
*
|
||||
* @group views
|
||||
*/
|
||||
class ExposedFormCheckboxesTest extends ViewTestBase {
|
||||
|
||||
use EntityReferenceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $testViews = ['test_exposed_form_checkboxes'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['node', 'views_ui', 'taxonomy'];
|
||||
|
||||
/**
|
||||
* Test terms.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $terms = [];
|
||||
|
||||
/**
|
||||
* Vocabulary for testing checkbox options.
|
||||
*
|
||||
* @var \Drupal\taxonomy\Entity\Vocabulary
|
||||
*/
|
||||
public $vocabulary;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp($import_test_views = TRUE) {
|
||||
parent::setUp(FALSE);
|
||||
|
||||
// Create a vocabulary and entity reference field so we can test the "is all
|
||||
// of" filter operator. Must be done ahead of the view import so the
|
||||
// vocabulary is in place to meet the view dependencies.
|
||||
$vocabulary = Vocabulary::create([
|
||||
'name' => 'test_exposed_checkboxes',
|
||||
'vid' => 'test_exposed_checkboxes',
|
||||
'nodes' => ['article' => 'article'],
|
||||
]);
|
||||
$vocabulary->save();
|
||||
$this->vocabulary = $vocabulary;
|
||||
|
||||
ViewTestData::createTestViews(self::class, ['views_test_config']);
|
||||
$this->enableViewsTestModule();
|
||||
|
||||
// Create two content types.
|
||||
$this->drupalCreateContentType(['type' => 'article']);
|
||||
$this->drupalCreateContentType(['type' => 'page']);
|
||||
|
||||
// Create some random nodes: 5 articles, one page.
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
$this->drupalCreateNode(['type' => 'article']);
|
||||
}
|
||||
$this->drupalCreateNode(['type' => 'page']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests overriding the default render option with checkboxes.
|
||||
*/
|
||||
public function testExposedFormRenderCheckboxes() {
|
||||
// Use a test theme to convert multi-select elements into checkboxes.
|
||||
\Drupal::service('theme_handler')->install(['views_test_checkboxes_theme']);
|
||||
$this->config('system.theme')
|
||||
->set('default', 'views_test_checkboxes_theme')
|
||||
->save();
|
||||
|
||||
// Only display 5 items per page so we can test that paging works.
|
||||
$view = Views::getView('test_exposed_form_checkboxes');
|
||||
$display = &$view->storage->getDisplay('default');
|
||||
$display['display_options']['pager']['options']['items_per_page'] = 5;
|
||||
|
||||
$view->save();
|
||||
$this->drupalGet('test_exposed_form_checkboxes');
|
||||
|
||||
$actual = $this->xpath('//form//input[@type="checkbox" and @name="type[article]"]');
|
||||
$this->assertEqual(count($actual), 1, 'Article option renders as a checkbox.');
|
||||
$actual = $this->xpath('//form//input[@type="checkbox" and @name="type[page]"]');
|
||||
$this->assertEqual(count($actual), 1, 'Page option renders as a checkbox');
|
||||
|
||||
// Ensure that all results are displayed.
|
||||
$rows = $this->xpath("//div[contains(@class, 'views-row')]");
|
||||
$this->assertEqual(count($rows), 5, '5 rows are displayed by default on the first page when no options are checked.');
|
||||
|
||||
$this->clickLink('Page 2');
|
||||
$rows = $this->xpath("//div[contains(@class, 'views-row')]");
|
||||
$this->assertEqual(count($rows), 1, '1 row is displayed by default on the second page when no options are checked.');
|
||||
$this->assertNoText('An illegal choice has been detected. Please contact the site administrator.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that "is all of" filters work with checkboxes.
|
||||
*/
|
||||
public function testExposedIsAllOfFilter() {
|
||||
foreach (['Term 1', 'Term 2', 'Term 3'] as $term_name) {
|
||||
// Add a few terms to the new vocabulary.
|
||||
$term = Term::create([
|
||||
'name' => $term_name,
|
||||
'vid' => $this->vocabulary->id(),
|
||||
]);
|
||||
$term->save();
|
||||
$this->terms[] = $term;
|
||||
}
|
||||
|
||||
// Create a field.
|
||||
$field_name = Unicode::strtolower($this->randomMachineName());
|
||||
$handler_settings = [
|
||||
'target_bundles' => [
|
||||
$this->vocabulary->id() => $this->vocabulary->id(),
|
||||
],
|
||||
'auto_create' => FALSE,
|
||||
];
|
||||
$this->createEntityReferenceField('node', 'article', $field_name, NULL, 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED);
|
||||
|
||||
// Add some test nodes.
|
||||
$this->createNode([
|
||||
'type' => 'article',
|
||||
$field_name => [$this->terms[0]->id(), $this->terms[1]->id()],
|
||||
]);
|
||||
$this->createNode([
|
||||
'type' => 'article',
|
||||
$field_name => [$this->terms[0]->id(), $this->terms[2]->id()],
|
||||
]);
|
||||
|
||||
// Use a test theme to convert multi-select elements into checkboxes.
|
||||
\Drupal::service('theme_handler')->install(['views_test_checkboxes_theme']);
|
||||
$this->config('system.theme')
|
||||
->set('default', 'views_test_checkboxes_theme')
|
||||
->save();
|
||||
|
||||
$this->drupalGet('test_exposed_form_checkboxes');
|
||||
|
||||
// Ensure that all results are displayed.
|
||||
$rows = $this->xpath("//div[contains(@class, 'views-row')]");
|
||||
$this->assertEqual(count($rows), 8, 'All rows are displayed by default on the first page when no options are checked.');
|
||||
$this->assertNoText('An illegal choice has been detected. Please contact the site administrator.');
|
||||
|
||||
// Select one option and ensure we still have results.
|
||||
$tid = $this->terms[0]->id();
|
||||
$this->drupalPostForm(NULL, ["tid[$tid]" => $tid], t('Apply'));
|
||||
|
||||
// Ensure only nodes tagged with $tid are displayed.
|
||||
$rows = $this->xpath("//div[contains(@class, 'views-row')]");
|
||||
$this->assertEqual(count($rows), 2, 'Correct rows are displayed when a tid is selected.');
|
||||
$this->assertNoText('An illegal choice has been detected. Please contact the site administrator.');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,7 +4,7 @@ namespace Drupal\Tests\views\Functional\Plugin;
|
||||
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\system\Tests\Cache\AssertPageCacheContextsAndTagsTrait;
|
||||
use Drupal\Tests\system\Functional\Cache\AssertPageCacheContextsAndTagsTrait;
|
||||
use Drupal\Tests\views\Functional\ViewTestBase;
|
||||
use Drupal\views\ViewExecutable;
|
||||
use Drupal\views\Views;
|
||||
@@ -191,48 +191,6 @@ class ExposedFormTest extends ViewTestBase {
|
||||
$this->helperButtonHasLabel('edit-reset', $expected_label);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests overriding the default render option with checkboxes.
|
||||
*/
|
||||
public function testExposedFormRenderCheckboxes() {
|
||||
// Make sure we have at least two options for node type.
|
||||
$this->drupalCreateContentType(['type' => 'page']);
|
||||
$this->drupalCreateNode(['type' => 'page']);
|
||||
|
||||
// Use a test theme to convert multi-select elements into checkboxes.
|
||||
\Drupal::service('theme_handler')->install(['views_test_checkboxes_theme']);
|
||||
$this->config('system.theme')
|
||||
->set('default', 'views_test_checkboxes_theme')
|
||||
->save();
|
||||
|
||||
// Set the "type" filter to multi-select.
|
||||
$view = Views::getView('test_exposed_form_buttons');
|
||||
$filter = $view->getHandler('page_1', 'filter', 'type');
|
||||
$filter['expose']['multiple'] = TRUE;
|
||||
$view->setHandler('page_1', 'filter', 'type', $filter);
|
||||
|
||||
// Only display 5 items per page so we can test that paging works.
|
||||
$display = &$view->storage->getDisplay('default');
|
||||
$display['display_options']['pager']['options']['items_per_page'] = 5;
|
||||
|
||||
$view->save();
|
||||
$this->drupalGet('test_exposed_form_buttons');
|
||||
|
||||
$actual = $this->xpath('//form//input[@type="checkbox" and @name="type[article]"]');
|
||||
$this->assertEqual(count($actual), 1, 'Article option renders as a checkbox.');
|
||||
$actual = $this->xpath('//form//input[@type="checkbox" and @name="type[page]"]');
|
||||
$this->assertEqual(count($actual), 1, 'Page option renders as a checkbox');
|
||||
|
||||
// Ensure that all results are displayed.
|
||||
$rows = $this->xpath("//div[contains(@class, 'views-row')]");
|
||||
$this->assertEqual(count($rows), 5, '5 rows are displayed by default on the first page when no options are checked.');
|
||||
|
||||
$this->clickLink('Page 2');
|
||||
$rows = $this->xpath("//div[contains(@class, 'views-row')]");
|
||||
$this->assertEqual(count($rows), 1, '1 row is displayed by default on the second page when no options are checked.');
|
||||
$this->assertNoText('An illegal choice has been detected. Please contact the site administrator.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the exposed block functionality.
|
||||
*/
|
||||
@@ -320,8 +278,7 @@ class ExposedFormTest extends ViewTestBase {
|
||||
*/
|
||||
public function testExposedSortAndItemsPerPage() {
|
||||
for ($i = 0; $i < 50; $i++) {
|
||||
$entity = EntityTest::create([
|
||||
]);
|
||||
$entity = EntityTest::create([]);
|
||||
$entity->save();
|
||||
}
|
||||
$contexts = [
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user