Skip to content
Commits on Source (45)
......@@ -90,6 +90,19 @@ INSTALLATION
mv drupal-x.y.z/* drupal-x.y.z/.htaccess drupal-x.y.z/.csslintrc drupal-x.y.z/.editorconfig drupal-x.y.z/.eslintignore drupal-x.y.z/.eslintrc drupal-x.y.z/.gitattributes /path/to/your/installation
You can also download the latest version of Drupal using Git on the command
line and set up a repository by following the instructions at
https://www.drupal.org/project/drupal/git-instructions for "Setting up
repository for the first time".
Once you have downloaded Drupal successfully, you may install Composer
globally using the instructions at
https://getcomposer.org/doc/00-intro.md#globally
With Composer installed, run the following command from the Drupal web root:
composer install
2. Create the Drupal database.
Because Drupal stores all site information in a database, the Drupal
......
......@@ -23,9 +23,10 @@ Drupal 8
(Release Manager)
- Alex Pott 'alexpott' https://www.drupal.org/u/alexpott
(Framework Manager)
Provisional membership:
- Scott Reeves 'Cottser' https://www.drupal.org/u/cottser
(Framework Manager - Frontend)
Provisional membership: None at this time.
Drupal 7
- Fabian Franz 'Fabianx' https://www.drupal.org/u/fabianx
......@@ -472,11 +473,13 @@ Views module
- Tim Plunkett 'tim.plunkett' https://www.drupal.org/u/tim.plunkett
- Damian Lee 'damiankloip' https://www.drupal.org/u/damiankloip
- Jess Myrbo 'xjm' https://www.drupal.org/u/xjm
- Len Swaneveld 'Lendude' https://www.drupal.org/u/lendude
Views UI module
- Daniel Wehner 'dawehner' https://www.drupal.org/u/dawehner
- Tim Plunkett 'tim.plunkett' https://www.drupal.org/u/tim.plunkett
- Damian Lee 'damiankloip' https://www.drupal.org/u/damiankloip
- Len Swaneveld 'Lendude' https://www.drupal.org/u/lendude
Theme maintainers
......
......@@ -2047,7 +2047,7 @@ function hook_mail_alter(&$message) {
* An array of parameters supplied by the caller of
* MailManagerInterface->mail().
*
* @see \Drupal\Core\Mail\MailManagerInterface->mail()
* @see \Drupal\Core\Mail\MailManagerInterface::mail()
*/
function hook_mail($key, &$message, $params) {
$account = $params['account'];
......
......@@ -1220,7 +1220,9 @@ function file_directory_os_temp() {
foreach ($directories as $directory) {
if (is_dir($directory) && is_writable($directory)) {
return $directory;
// Both sys_get_temp_dir() and ini_get('upload_tmp_dir') can return paths
// with a trailing directory separator.
return rtrim($directory, DIRECTORY_SEPARATOR);
}
}
return FALSE;
......
......@@ -596,7 +596,7 @@ function update_already_performed($module, $number) {
* An array of return values obtained by merging the results of the
* hook_update_dependencies() implementations in all installed modules.
*
* @see \Drupal::moduleHandler()->invokeAll()
* @see \Drupal\Core\Extension\ModuleHandlerInterface::invokeAll()
* @see hook_update_dependencies()
*/
function update_retrieve_dependencies() {
......
......@@ -81,7 +81,7 @@ class Drupal {
/**
* The current system version.
*/
const VERSION = '8.1.9-dev';
const VERSION = '8.1.11-dev';
/**
* Core API compatibility.
......
......@@ -23,7 +23,7 @@ class Schema extends DatabaseSchema {
* This is collected by DatabaseConnection_pgsql->queryTableInformation(),
* by introspecting the database.
*
* @see DatabaseConnection_pgsql->queryTableInformation()
* @see \Drupal\Core\Database\Driver\pgsql\Schema::queryTableInformation()
* @var array
*/
protected $tableInformation = array();
......
......@@ -297,7 +297,7 @@ protected static function matchEntityByTitle(SelectionInterface $handler, $input
$multiples[] = $name . ' (' . $id . ')';
}
$params['@id'] = $id;
$form_state->setError($element, t('Multiple entities match this reference; "%multiple". Specify the one you want by appending the id in parentheses, like "@value (@id)".', array('%multiple' => implode('", "', $multiples))));
$form_state->setError($element, t('Multiple entities match this reference; "%multiple". Specify the one you want by appending the id in parentheses, like "@value (@id)".', array('%multiple' => implode('", "', $multiples)) + $params));
}
else {
// Take the one and only matching entity.
......
......@@ -1543,6 +1543,7 @@ protected function readFieldItemsToPurge(FieldDefinitionInterface $field_definit
$item_query = $this->database->select($table_name, 't', array('fetch' => \PDO::FETCH_ASSOC))
->fields('t')
->condition('entity_id', $row['entity_id'])
->condition('deleted', 1)
->orderBy('delta');
foreach ($item_query->execute() as $item_row) {
......@@ -1581,10 +1582,12 @@ protected function purgeFieldItems(ContentEntityInterface $entity, FieldDefiniti
$revision_id = $this->entityType->isRevisionable() ? $entity->getRevisionId() : $entity->id();
$this->database->delete($table_name)
->condition('revision_id', $revision_id)
->condition('deleted', 1)
->execute();
if ($this->entityType->isRevisionable()) {
$this->database->delete($revision_name)
->condition('revision_id', $revision_id)
->condition('deleted', 1)
->execute();
}
}
......@@ -1684,6 +1687,12 @@ public function countFieldData($storage_definition, $as_bool = FALSE) {
* Whether the field has been already deleted.
*/
protected function storageDefinitionIsDeleted(FieldStorageDefinitionInterface $storage_definition) {
// Configurable fields are marked for deletion.
if ($storage_definition instanceOf FieldStorageConfigInterface) {
return $storage_definition->isDeleted();
}
// For non configurable fields check whether they are still in the last
// installed schema repository.
return !array_key_exists($storage_definition->getName(), $this->entityManager->getLastInstalledFieldStorageDefinitions($this->entityTypeId));
}
......
......@@ -1845,7 +1845,8 @@ function hook_entity_operation_alter(array &$operations, \Drupal\Core\Entity\Ent
*
* @param string $operation
* The operation to be performed. See
* \Drupal\Core\Access\AccessibleInterface::access() for possible values.
* \Drupal\Core\Entity\EntityAccessControlHandlerInterface::fieldAccess()
* for possible values.
* @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
* The field definition.
* @param \Drupal\Core\Session\AccountInterface $account
......@@ -1856,6 +1857,8 @@ function hook_entity_operation_alter(array &$operations, \Drupal\Core\Entity\Ent
*
* @return \Drupal\Core\Access\AccessResultInterface
* The access result.
*
* @see \Drupal\Core\Entity\EntityAccessControlHandlerInterface::fieldAccess()
*/
function hook_entity_field_access($operation, \Drupal\Core\Field\FieldDefinitionInterface $field_definition, \Drupal\Core\Session\AccountInterface $account, \Drupal\Core\Field\FieldItemListInterface $items = NULL) {
if ($field_definition->getName() == 'field_of_interest' && $operation == 'edit') {
......
......@@ -188,13 +188,16 @@ public function onException(GetResponseForExceptionEvent $event) {
if (!method_exists($this, $method)) {
if ($exception instanceof HttpExceptionInterface) {
$this->onFormatUnknown($event);
$response = $event->getResponse();
$response->headers->set('Content-Type', 'text/plain');
}
else {
$this->onHtml($event);
}
return;
}
$this->$method($event);
else {
$this->$method($event);
}
}
/**
......
......@@ -157,12 +157,6 @@ function hook_archiver_info_alter(&$info) {
* will always be passed the full path to the root of the site that should
* be used to restrict where file transfer operations can occur (the $jail)
* and an array of settings values returned by the settings form.
* - 'file': Required. The include file containing the FileTransfer class.
* This should be a separate .inc file, not just the .module file, so that
* the minimum possible code is loaded when authorize.php is running.
* - 'file path': Optional. The directory (relative to the Drupal root)
* where the include file lives. If not defined, defaults to the base
* directory of the module implementing the hook.
* - 'weight': Optional. Integer weight used for sorting connection types on
* the authorize.php form.
*
......
......@@ -172,7 +172,7 @@ function getProjectName(Extension $file) {
* @return
* Array of .info.yml file data we need for the update manager.
*
* @see \Drupal\Core\Utility\ProjectInfo->processInfoList()
* @see \Drupal\Core\Utility\ProjectInfo::processInfoList()
*/
function filterProjectInfo($info, $additional_whitelist = array()) {
$whitelist = array(
......
......@@ -108,10 +108,10 @@ public function getDefaultOperations(EntityInterface $entity) {
* {@inheritdoc}
*/
public function render() {
$build['action_header']['#markup'] = '<h3>' . t('Available actions:') . '</h3>';
$build['action_header']['#markup'] = '<h3>' . $this->t('Available actions:') . '</h3>';
$build['action_table'] = parent::render();
if (!$this->hasConfigurableActions) {
unset($build['action_table']['#header']['operations']);
unset($build['action_table']['table']['#header']['operations']);
}
$build['action_admin_manage_form'] = \Drupal::formBuilder()->getForm('Drupal\action\Form\ActionAdminManageForm');
return $build;
......
<?php
namespace Drupal\action\Tests;
use Drupal\simpletest\WebTestBase;
/**
* Test behaviors when visiting the action listing page.
*
* @group action
*/
class ActionListTest extends WebTestBase {
/**
* Modules to install.
*
* @var array
*/
public static $modules = array('action');
/**
* Tests the behavior when there are no actions to list in the admin page.
*/
public function testEmptyActionList() {
// Create a user with permission to view the actions administration pages.
$this->drupalLogin($this->drupalCreateUser(['administer actions']));
// Ensure the empty text appears on the action list page.
/** @var $storage \Drupal\Core\Entity\EntityStorageInterface */
$storage = $this->container->get('entity.manager')->getStorage('action');
$actions = $storage->loadMultiple();
$storage->delete($actions);
$this->drupalGet('/admin/config/system/actions');
$this->assertRaw('There is no Action yet.');
}
}
......@@ -104,9 +104,15 @@ public function getTheme() {
*/
public function postSave(EntityStorageInterface $storage, $update = TRUE) {
parent::postSave($storage, $update);
static::invalidateBlockPluginCache();
}
// Invalidate the block cache to update custom block-based derivatives.
\Drupal::service('plugin.manager.block')->clearCachedDefinitions();
/**
* {@inheritdoc}
*/
public static function postDelete(EntityStorageInterface $storage, array $entities) {
parent::postDelete($storage, $entities);
static::invalidateBlockPluginCache();
}
/**
......@@ -237,4 +243,12 @@ public function setRevisionLog($revision_log) {
return $this;
}
/**
* Invalidates the block plugin cache after changes and deletions.
*/
protected static function invalidateBlockPluginCache() {
// Invalidate the block cache to update custom block-based derivatives.
\Drupal::service('plugin.manager.block')->clearCachedDefinitions();
}
}
......@@ -44,6 +44,8 @@ public static function create(ContainerInterface $container, $base_plugin_id) {
*/
public function getDerivativeDefinitions($base_plugin_definition) {
$block_contents = $this->blockContentStorage->loadMultiple();
// Reset the discovered definitions.
$this->derivatives = [];
/** @var $block_content \Drupal\block_content\Entity\BlockContent */
foreach ($block_contents as $block_content) {
$this->derivatives[$block_content->uuid()] = $base_plugin_definition;
......
<?php
namespace Drupal\Tests\block_content\Kernel;
use Drupal\block_content\Entity\BlockContent;
use Drupal\block_content\Entity\BlockContentType;
use Drupal\Component\Plugin\PluginBase;
use Drupal\KernelTests\KernelTestBase;
/**
* Tests that deleting a block clears the cached definitions.
*
* @group block_content
*/
class BlockContentDeletionTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['block', 'block_content', 'system', 'user'];
/**
* {@inheritdoc}
*/
public function setUp() {
parent::setUp();
$this->installSchema('system', ['sequence']);
$this->installEntitySchema('user');
$this->installEntitySchema('block_content');
}
/**
* Tests deleting a block_content updates the discovered block plugin.
*/
public function testDeletingBlockContentShouldClearPluginCache() {
// Create a block content type.
$block_content_type = BlockContentType::create([
'id' => 'spiffy',
'label' => 'Mucho spiffy',
'description' => "Provides a block type that increases your site's spiffiness by upto 11%",
]);
$block_content_type->save();
// And a block content entity.
$block_content = BlockContent::create([
'info' => 'Spiffy prototype',
'type' => 'spiffy',
]);
$block_content->save();
// Make sure the block content provides a derivative block plugin in the
// block repository.
/** @var \Drupal\Core\Block\BlockManagerInterface $block_manager */
$block_manager = $this->container->get('plugin.manager.block');
$plugin_id = 'block_content' . PluginBase::DERIVATIVE_SEPARATOR . $block_content->uuid();
$this->assertTrue($block_manager->hasDefinition($plugin_id));
// Now delete the block content entity.
$block_content->delete();
// The plugin should no longer exist.
$this->assertFalse($block_manager->hasDefinition($plugin_id));
}
}
......@@ -2,7 +2,9 @@
namespace Drupal\comment;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Field\FieldItemList;
use Drupal\Core\Session\AccountInterface;
/**
* Defines a item list class for comment fields.
......@@ -37,4 +39,28 @@ public function offsetExists($offset) {
return parent::offsetExists($offset);
}
/**
* {@inheritdoc}
*/
public function access($operation = 'view', AccountInterface $account = NULL, $return_as_object = FALSE) {
if ($operation === 'edit') {
// Only users with administer comments permission can edit the comment
// status field.
$result = AccessResult::allowedIfHasPermission($account ?: \Drupal::currentUser(), 'administer comments');
return $return_as_object ? $result : $result->isAllowed();
}
if ($operation === 'view') {
// Only users with either post comments or access comments permisison can
// view the field value. The formatter,
// Drupal\comment\Plugin\Field\FieldFormatter\CommentDefaultFormatter,
// takes care of showing the thread and form based on individual
// permissions, so if a user only has ‘post comments’ access, only the
// form will be shown and not the comments.
$result = AccessResult::allowedIfHasPermission($account ?: \Drupal::currentUser(), 'access comments')
->orIf(AccessResult::allowedIfHasPermission($account ?: \Drupal::currentUser(), 'post comments'));
return $return_as_object ? $result : $result->isAllowed();
}
return parent::access($operation, $account, $return_as_object);
}
}
......@@ -384,6 +384,7 @@ function testCommentFunctionality() {
'administer entity_test fields',
'view test entity',
'administer entity_test content',
'administer comments',
));
$this->drupalLogin($limited_user);
$this->drupalGet('entity_test/structure/entity_test/fields/entity_test.entity_test.comment');
......