updated core to 8.6.1 via composer
This commit is contained in:
@@ -5,4 +5,4 @@ package: Core
|
||||
version: VERSION
|
||||
core: 8.x
|
||||
dependencies:
|
||||
- node
|
||||
- drupal:node
|
||||
|
||||
@@ -27,7 +27,7 @@ define('HISTORY_READ_LIMIT', REQUEST_TIME - 30 * 24 * 60 * 60);
|
||||
function history_help($route_name, RouteMatchInterface $route_match) {
|
||||
switch ($route_name) {
|
||||
case 'help.page.history':
|
||||
$output = '<h3>' . t('About') . '</h3>';
|
||||
$output = '<h3>' . t('About') . '</h3>';
|
||||
$output .= '<p>' . t('The History module keeps track of which content a user has read. It marks content as <em>new</em> or <em>updated</em> depending on the last time the user viewed it. History records that are older than one month are removed during cron, which means that content older than one month is always considered <em>read</em>. The History module does not have a user interface but it provides a filter to <a href=":views-help">Views</a> to show new or updated content. For more information, see the <a href=":url">online documentation for the History module</a>.', [':views-help' => (\Drupal::moduleHandler()->moduleExists('views')) ? \Drupal::url('help.page', ['name' => 'views']) : '#', ':url' => 'https://www.drupal.org/documentation/modules/history']) . '</p>';
|
||||
return $output;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ function history_views_data() {
|
||||
// We're actually defining a specific instance of the table, so let's
|
||||
// alias it so that we can later add the real table for other purposes if we
|
||||
// need it.
|
||||
$data['history']['table']['group'] = t('Content');
|
||||
$data['history']['table']['group'] = t('Content');
|
||||
|
||||
// Explain how this table joins to others.
|
||||
$data['history']['table']['join'] = [
|
||||
|
||||
@@ -5,13 +5,14 @@
|
||||
* May only be loaded for authenticated users, with the History module enabled.
|
||||
*/
|
||||
|
||||
(function ($, Drupal, drupalSettings, storage) {
|
||||
(function($, Drupal, drupalSettings, storage) {
|
||||
const currentUserID = parseInt(drupalSettings.user.uid, 10);
|
||||
|
||||
// Any comment that is older than 30 days is automatically considered read,
|
||||
// so for these we don't need to perform a request at all!
|
||||
const secondsIn30Days = 2592000;
|
||||
const thirtyDaysAgo = Math.round(new Date().getTime() / 1000) - secondsIn30Days;
|
||||
const thirtyDaysAgo =
|
||||
Math.round(new Date().getTime() / 1000) - secondsIn30Days;
|
||||
|
||||
// Use the data embedded in the page, if available.
|
||||
let embeddedLastReadTimestamps = false;
|
||||
@@ -23,7 +24,6 @@
|
||||
* @namespace
|
||||
*/
|
||||
Drupal.history = {
|
||||
|
||||
/**
|
||||
* Fetch "last read" timestamps for the given nodes.
|
||||
*
|
||||
@@ -45,8 +45,11 @@
|
||||
data: { 'node_ids[]': nodeIDs },
|
||||
dataType: 'json',
|
||||
success(results) {
|
||||
Object.keys(results || {}).forEach((nodeID) => {
|
||||
storage.setItem(`Drupal.history.${currentUserID}.${nodeID}`, results[nodeID]);
|
||||
Object.keys(results || {}).forEach(nodeID => {
|
||||
storage.setItem(
|
||||
`Drupal.history.${currentUserID}.${nodeID}`,
|
||||
results[nodeID],
|
||||
);
|
||||
});
|
||||
callback();
|
||||
},
|
||||
@@ -67,7 +70,10 @@
|
||||
if (embeddedLastReadTimestamps && embeddedLastReadTimestamps[nodeID]) {
|
||||
return parseInt(embeddedLastReadTimestamps[nodeID], 10);
|
||||
}
|
||||
return parseInt(storage.getItem(`Drupal.history.${currentUserID}.${nodeID}`) || 0, 10);
|
||||
return parseInt(
|
||||
storage.getItem(`Drupal.history.${currentUserID}.${nodeID}`) || 0,
|
||||
10,
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -84,11 +90,17 @@
|
||||
success(timestamp) {
|
||||
// If the data is embedded in the page, don't store on the client
|
||||
// side.
|
||||
if (embeddedLastReadTimestamps && embeddedLastReadTimestamps[nodeID]) {
|
||||
if (
|
||||
embeddedLastReadTimestamps &&
|
||||
embeddedLastReadTimestamps[nodeID]
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
storage.setItem(`Drupal.history.${currentUserID}.${nodeID}`, timestamp);
|
||||
storage.setItem(
|
||||
`Drupal.history.${currentUserID}.${nodeID}`,
|
||||
timestamp,
|
||||
);
|
||||
},
|
||||
});
|
||||
},
|
||||
@@ -119,11 +131,16 @@
|
||||
|
||||
// Use the data embedded in the page, if available.
|
||||
if (embeddedLastReadTimestamps && embeddedLastReadTimestamps[nodeID]) {
|
||||
return contentTimestamp > parseInt(embeddedLastReadTimestamps[nodeID], 10);
|
||||
return (
|
||||
contentTimestamp > parseInt(embeddedLastReadTimestamps[nodeID], 10)
|
||||
);
|
||||
}
|
||||
|
||||
const minLastReadTimestamp = parseInt(storage.getItem(`Drupal.history.${currentUserID}.${nodeID}`) || 0, 10);
|
||||
const minLastReadTimestamp = parseInt(
|
||||
storage.getItem(`Drupal.history.${currentUserID}.${nodeID}`) || 0,
|
||||
10,
|
||||
);
|
||||
return contentTimestamp > minLastReadTimestamp;
|
||||
},
|
||||
};
|
||||
}(jQuery, Drupal, drupalSettings, window.localStorage));
|
||||
})(jQuery, Drupal, drupalSettings, window.localStorage);
|
||||
|
||||
@@ -7,13 +7,15 @@
|
||||
* @see Drupal.history
|
||||
*/
|
||||
|
||||
(function (window, Drupal, drupalSettings) {
|
||||
(function(window, Drupal, drupalSettings) {
|
||||
// When the window's "load" event is triggered, mark all enumerated nodes as
|
||||
// read. This still allows for Drupal behaviors (which are triggered on the
|
||||
// "DOMContentReady" event) to add "new" and "updated" indicators.
|
||||
window.addEventListener('load', () => {
|
||||
if (drupalSettings.history && drupalSettings.history.nodesToMarkAsRead) {
|
||||
Object.keys(drupalSettings.history.nodesToMarkAsRead).forEach(Drupal.history.markAsRead);
|
||||
Object.keys(drupalSettings.history.nodesToMarkAsRead).forEach(
|
||||
Drupal.history.markAsRead,
|
||||
);
|
||||
}
|
||||
});
|
||||
}(window, Drupal, drupalSettings));
|
||||
})(window, Drupal, drupalSettings);
|
||||
|
||||
@@ -42,6 +42,9 @@ class HistoryUserTimestamp extends Node {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function defineOptions() {
|
||||
$options = parent::defineOptions();
|
||||
|
||||
@@ -50,6 +53,9 @@ class HistoryUserTimestamp extends Node {
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
|
||||
parent::buildOptionsForm($form, $form_state);
|
||||
if (\Drupal::moduleHandler()->moduleExists('comment')) {
|
||||
@@ -61,6 +67,9 @@ class HistoryUserTimestamp extends Node {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() {
|
||||
// Only add ourselves to the query if logged in.
|
||||
if (\Drupal::currentUser()->isAnonymous()) {
|
||||
|
||||
@@ -20,7 +20,9 @@ class HistoryUserTimestamp extends FilterPluginBase {
|
||||
|
||||
use UncacheableDependencyTrait;
|
||||
|
||||
// Don't display empty space where the operator would be.
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public $no_operator = TRUE;
|
||||
|
||||
/**
|
||||
@@ -30,6 +32,9 @@ class HistoryUserTimestamp extends FilterPluginBase {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildExposeForm(&$form, FormStateInterface $form_state) {
|
||||
parent::buildExposeForm($form, $form_state);
|
||||
// @todo There are better ways of excluding required and multiple (object flags)
|
||||
@@ -38,6 +43,9 @@ class HistoryUserTimestamp extends FilterPluginBase {
|
||||
unset($form['expose']['remember']);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function valueForm(&$form, FormStateInterface $form_state) {
|
||||
// Only present a checkbox for the exposed filter itself. There's no way
|
||||
// to tell the difference between not checked and the default value, so
|
||||
@@ -57,6 +65,9 @@ class HistoryUserTimestamp extends FilterPluginBase {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() {
|
||||
// This can only work if we're authenticated in.
|
||||
if (!\Drupal::currentUser()->isAuthenticated()) {
|
||||
@@ -70,7 +81,6 @@ class HistoryUserTimestamp extends FilterPluginBase {
|
||||
|
||||
// Hey, Drupal kills old history, so nodes that haven't been updated
|
||||
// since HISTORY_READ_LIMIT are bzzzzzzzt outta here!
|
||||
|
||||
$limit = REQUEST_TIME - HISTORY_READ_LIMIT;
|
||||
|
||||
$this->ensureMyTable();
|
||||
@@ -79,9 +89,9 @@ class HistoryUserTimestamp extends FilterPluginBase {
|
||||
|
||||
$clause = '';
|
||||
$clause2 = '';
|
||||
if ($ces = $this->query->ensureTable('comment_entity_statistics', $this->relationship)) {
|
||||
$clause = ("OR $ces.last_comment_timestamp > (***CURRENT_TIME*** - $limit)");
|
||||
$clause2 = "OR $field < $ces.last_comment_timestamp";
|
||||
if ($alias = $this->query->ensureTable('comment_entity_statistics', $this->relationship)) {
|
||||
$clause = "OR $alias.last_comment_timestamp > (***CURRENT_TIME*** - $limit)";
|
||||
$clause2 = "OR $field < $alias.last_comment_timestamp";
|
||||
}
|
||||
|
||||
// NULL means a history record doesn't exist. That's clearly new content.
|
||||
@@ -90,6 +100,9 @@ class HistoryUserTimestamp extends FilterPluginBase {
|
||||
$this->query->addWhereExpression($this->options['group'], "($field IS NULL AND ($node.changed > (***CURRENT_TIME*** - $limit) $clause)) OR $field < $node.changed $clause2");
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function adminSummary() {
|
||||
if (!empty($this->options['exposed'])) {
|
||||
return $this->t('exposed');
|
||||
|
||||
@@ -6,7 +6,6 @@ use Drupal\Component\Serialization\Json;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\Tests\system\Functional\Cache\AssertPageCacheContextsAndTagsTrait;
|
||||
use GuzzleHttp\Cookie\CookieJar;
|
||||
|
||||
/**
|
||||
* Tests the History endpoints.
|
||||
@@ -38,20 +37,6 @@ class HistoryTest extends BrowserTestBase {
|
||||
*/
|
||||
protected $testNode;
|
||||
|
||||
/**
|
||||
* The cookie jar holding the testing session cookies for Guzzle requests.
|
||||
*
|
||||
* @var \GuzzleHttp\Client;
|
||||
*/
|
||||
protected $client;
|
||||
|
||||
/**
|
||||
* The Guzzle HTTP client.
|
||||
*
|
||||
* @var \GuzzleHttp\Cookie\CookieJar;
|
||||
*/
|
||||
protected $cookies;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
@@ -60,8 +45,6 @@ class HistoryTest extends BrowserTestBase {
|
||||
$this->user = $this->drupalCreateUser(['create page content', 'access content']);
|
||||
$this->drupalLogin($this->user);
|
||||
$this->testNode = $this->drupalCreateNode(['type' => 'page', 'uid' => $this->user->id()]);
|
||||
|
||||
$this->client = $this->getHttpClient();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,16 +58,14 @@ class HistoryTest extends BrowserTestBase {
|
||||
*/
|
||||
protected function getNodeReadTimestamps(array $node_ids) {
|
||||
// Perform HTTP request.
|
||||
$http_client = $this->getHttpClient();
|
||||
$url = Url::fromRoute('history.get_last_node_view')
|
||||
->setAbsolute()
|
||||
->toString();
|
||||
return $this->client->post($url, [
|
||||
'body' => http_build_query(['node_ids' => $node_ids]),
|
||||
'cookies' => $this->cookies,
|
||||
'headers' => [
|
||||
'Accept' => 'application/json',
|
||||
'Content-Type' => 'application/x-www-form-urlencoded',
|
||||
],
|
||||
|
||||
return $http_client->request('POST', $url, [
|
||||
'form_params' => ['node_ids' => $node_ids],
|
||||
'cookies' => $this->getSessionCookies(),
|
||||
'http_errors' => FALSE,
|
||||
]);
|
||||
}
|
||||
@@ -99,12 +80,11 @@ class HistoryTest extends BrowserTestBase {
|
||||
* The response body.
|
||||
*/
|
||||
protected function markNodeAsRead($node_id) {
|
||||
$http_client = $this->getHttpClient();
|
||||
$url = Url::fromRoute('history.read_node', ['node' => $node_id], ['absolute' => TRUE])->toString();
|
||||
return $this->client->post($url, [
|
||||
'cookies' => $this->cookies,
|
||||
'headers' => [
|
||||
'Accept' => 'application/json',
|
||||
],
|
||||
|
||||
return $http_client->request('POST', $url, [
|
||||
'cookies' => $this->getSessionCookies(),
|
||||
'http_errors' => FALSE,
|
||||
]);
|
||||
}
|
||||
@@ -156,19 +136,4 @@ class HistoryTest extends BrowserTestBase {
|
||||
$this->assertEquals(403, $response->getStatusCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the HTTP client and set the cookies.
|
||||
*
|
||||
* @return \GuzzleHttp\Client
|
||||
* The client with BrowserTestBase configuration.
|
||||
*/
|
||||
protected function getHttpClient() {
|
||||
// Similar code is also employed to test CSRF tokens.
|
||||
// @see \Drupal\Tests\system\Functional\CsrfRequestHeaderTest::testRouteAccess()
|
||||
$domain = parse_url($this->getUrl(), PHP_URL_HOST);
|
||||
$session_id = $this->getSession()->getCookie($this->getSessionName());
|
||||
$this->cookies = CookieJar::fromArray([$this->getSessionName() => $session_id], $domain);
|
||||
return $this->getSession()->getDriver()->getClient()->getClient();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user