Update to Drupal 8.0.0 beta 14. For more information, see https://drupal.org/node/2544542
This commit is contained in:
parent
3b2511d96d
commit
81ccda77eb
2155 changed files with 54307 additions and 46870 deletions
23
core/modules/system/tests/fixtures/update/block.block.secondtestfor2354889.yml
vendored
Normal file
23
core/modules/system/tests/fixtures/update/block.block.secondtestfor2354889.yml
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
uuid: C499B41D-035E-432E-9462-36410C43C49F
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- search
|
||||
theme:
|
||||
- bartik
|
||||
id: secondtestfor2354889
|
||||
theme: bartik
|
||||
region: sidebar_first
|
||||
weight: -6
|
||||
provider: null
|
||||
plugin: search_form_block
|
||||
settings:
|
||||
id: search_form_block
|
||||
label: Search
|
||||
provider: search
|
||||
label_display: visible
|
||||
cache:
|
||||
max_age: -1
|
||||
status: true
|
||||
visibility: { }
|
51
core/modules/system/tests/fixtures/update/block.block.testfor2354889.yml
vendored
Normal file
51
core/modules/system/tests/fixtures/update/block.block.testfor2354889.yml
vendored
Normal file
|
@ -0,0 +1,51 @@
|
|||
uuid: 9d204071-a923-4707-8200-c298a540fb0c
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
content:
|
||||
- 'block_content:basic:c1895145-893e-460b-a24e-78cd2cefbb1f'
|
||||
module:
|
||||
- block_content
|
||||
- node
|
||||
- user
|
||||
theme:
|
||||
- bartik
|
||||
id: testfor2354889
|
||||
theme: bartik
|
||||
region: content
|
||||
weight: -6
|
||||
provider: null
|
||||
plugin: 'block_content:c1895145-893e-460b-a24e-78cd2cefbb1f'
|
||||
settings:
|
||||
id: 'block_content:c1895145-893e-460b-a24e-78cd2cefbb1f'
|
||||
label: 'Test for 2354889'
|
||||
provider: block_content
|
||||
label_display: visible
|
||||
cache:
|
||||
max_age: -1
|
||||
status: true
|
||||
info: ''
|
||||
view_mode: full
|
||||
visibility:
|
||||
node_type:
|
||||
id: node_type
|
||||
bundles:
|
||||
page: page
|
||||
negate: false
|
||||
context_mapping:
|
||||
node: node.node
|
||||
user_role:
|
||||
id: user_role
|
||||
roles:
|
||||
authenticated: authenticated
|
||||
negate: false
|
||||
context_mapping:
|
||||
user: user.current_user
|
||||
language:
|
||||
id: language
|
||||
langcodes:
|
||||
en: en
|
||||
de: de
|
||||
negate: false
|
||||
context_mapping:
|
||||
language: language.language_interface
|
30
core/modules/system/tests/fixtures/update/block.block.thirdtestfor2354889.yml
vendored
Normal file
30
core/modules/system/tests/fixtures/update/block.block.thirdtestfor2354889.yml
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
uuid: 4558907D-2918-48FE-B56F-8A007B5FBDD5
|
||||
langcode: en
|
||||
status: true
|
||||
dependencies:
|
||||
module:
|
||||
- user
|
||||
theme:
|
||||
- bartik
|
||||
id: thirdtestfor2354889
|
||||
theme: bartik
|
||||
region: sidebar_first
|
||||
weight: -6
|
||||
provider: null
|
||||
plugin: user_login_block
|
||||
settings:
|
||||
id: user_login_block
|
||||
label: 'User login'
|
||||
provider: user
|
||||
label_display: visible
|
||||
cache:
|
||||
max_age: -1
|
||||
status: true
|
||||
visibility:
|
||||
node_type:
|
||||
id: node_type
|
||||
bundles:
|
||||
page: page
|
||||
negate: false
|
||||
context_mapping:
|
||||
baloney: baloney.spam
|
53
core/modules/system/tests/fixtures/update/drupal-8.block-context-manager-2354889.php
vendored
Normal file
53
core/modules/system/tests/fixtures/update/drupal-8.block-context-manager-2354889.php
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains database additions to drupal-8.bare.standard.php.gz for testing the
|
||||
* upgrade path of https://www.drupal.org/node/2354889.
|
||||
*/
|
||||
|
||||
use Drupal\Core\Database\Database;
|
||||
|
||||
$connection = Database::getConnection();
|
||||
|
||||
// A custom block with visibility settings.
|
||||
$block_configs[] = \Drupal\Component\Serialization\Yaml::decode(file_get_contents(__DIR__ . '/block.block.testfor2354889.yml'));
|
||||
|
||||
// A custom block without any visibility settings.
|
||||
$block_configs[] = \Drupal\Component\Serialization\Yaml::decode(file_get_contents(__DIR__ . '/block.block.secondtestfor2354889.yml'));
|
||||
|
||||
// A custom block with visibility settings that contain a non-existing context
|
||||
// mapping.
|
||||
$block_configs[] = \Drupal\Component\Serialization\Yaml::decode(file_get_contents(__DIR__ . '/block.block.thirdtestfor2354889.yml'));
|
||||
|
||||
foreach ($block_configs as $block_config) {
|
||||
$connection->insert('config')
|
||||
->fields(array(
|
||||
'collection',
|
||||
'name',
|
||||
'data',
|
||||
))
|
||||
->values(array(
|
||||
'collection' => '',
|
||||
'name' => 'block.block.' . $block_config['id'],
|
||||
'data' => serialize($block_config),
|
||||
))
|
||||
->execute();
|
||||
}
|
||||
|
||||
// Update the config entity query "index".
|
||||
$existing_blocks = $connection->select('key_value')
|
||||
->fields('key_value', ['value'])
|
||||
->condition('collection', 'config.entity.key_store.block')
|
||||
->condition('name', 'theme:bartik')
|
||||
->execute()
|
||||
->fetchField();
|
||||
$existing_blocks = unserialize($existing_blocks);
|
||||
|
||||
$connection->update('key_value')
|
||||
->fields([
|
||||
'value' => serialize(array_merge($existing_blocks, ['block.block.testfor2354889', 'block.block.secondtestfor2354889', 'block.block.thirdtestfor2354889']))
|
||||
])
|
||||
->condition('collection', 'config.entity.key_store.block')
|
||||
->condition('name', 'theme:bartik')
|
||||
->execute();
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
namespace Drupal\accept_header_routing_test\Routing;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Core\Routing\RouteFilterInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException;
|
||||
|
@ -62,7 +61,7 @@ class AcceptHeaderMatcher implements RouteFilterInterface {
|
|||
// We do not throw a
|
||||
// \Symfony\Component\Routing\Exception\ResourceNotFoundException here
|
||||
// because we don't want to return a 404 status code, but rather a 406.
|
||||
throw new NotAcceptableHttpException(SafeMarkup::format('No route found for the specified formats @formats.', array('@formats' => implode(' ', $acceptable_mime_types))));
|
||||
throw new NotAcceptableHttpException('No route found for the specified formats ' . implode(' ', $acceptable_mime_types));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -30,10 +30,3 @@ ajax_forms_test.lazy_load_form:
|
|||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
ajax_forms_test.cached_form:
|
||||
path: '/ajax_forms_test_cached_form'
|
||||
defaults:
|
||||
_title: 'AJAX forms cached form test'
|
||||
_form: '\Drupal\ajax_forms_test\Form\AjaxFormsTestCachedForm'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\ajax_forms_test\Form\AjaxFormsTestCachedForm.
|
||||
*/
|
||||
|
||||
namespace Drupal\ajax_forms_test\Form;
|
||||
|
||||
use Drupal\Core\Form\FormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Url;
|
||||
|
||||
/**
|
||||
* Provides an AJAX form that will be cached.
|
||||
*/
|
||||
class AjaxFormsTestCachedForm extends FormBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormId() {
|
||||
return 'ajax_form_cache_test_form';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state) {
|
||||
$form['test1'] = [
|
||||
'#type' => 'select',
|
||||
'#title' => $this->t('Test 1'),
|
||||
'#options' => [
|
||||
'option1' => $this->t('Option 1'),
|
||||
'option2' => $this->t('Option 2'),
|
||||
],
|
||||
'#ajax' => [
|
||||
'url' => Url::fromRoute('system.ajax'),
|
||||
],
|
||||
];
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||
}
|
||||
|
||||
}
|
|
@ -57,7 +57,7 @@ class AjaxFormsTestSimpleForm extends FormBase {
|
|||
);
|
||||
|
||||
// This is for testing invalid callbacks that should return a 500 error in
|
||||
// \Drupal\system\FormAjaxController::content().
|
||||
// \Drupal\Core\Form\FormAjaxResponseBuilderInterface::buildResponse().
|
||||
$invalid_callbacks = array(
|
||||
'null' => NULL,
|
||||
'empty' => '',
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
cache_test.url_bubbling:
|
||||
path: '/cache-test/url-bubbling'
|
||||
defaults:
|
||||
_controller: '\Drupal\cache_test\Controller\CacheTestController::urlBubbling'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\cache_test\Controller\CacheTestController.
|
||||
*/
|
||||
|
||||
namespace Drupal\cache_test\Controller;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Core\Render\HtmlResponse;
|
||||
use Drupal\Core\Url;
|
||||
|
||||
/**
|
||||
* Controller routines for cache_test routes.
|
||||
*/
|
||||
class CacheTestController {
|
||||
|
||||
/**
|
||||
* Early renders a URL to test bubbleable metadata bubbling.
|
||||
*/
|
||||
public function urlBubbling() {
|
||||
$url = Url::fromRoute('<current>')->setAbsolute();
|
||||
return [
|
||||
'#markup' => SafeMarkup::format('This URL is early-rendered: !url. Yet, its bubbleable metadata should be bubbled.', ['!url' => $url->toString()])
|
||||
];
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\condition_test\Plugin\Condition\OptionalContextCondition.
|
||||
*/
|
||||
|
||||
namespace Drupal\condition_test\Plugin\Condition;
|
||||
|
||||
use Drupal\Core\Condition\ConditionPluginBase;
|
||||
|
||||
/**
|
||||
* Provides a condition with an optional node context.
|
||||
*
|
||||
* The context type entity:node is used since that would allow to also use this
|
||||
* for web tests with the node route context.
|
||||
*
|
||||
* @Condition(
|
||||
* id = "condition_test_optional_context",
|
||||
* label = @Translation("Optional context"),
|
||||
* context = {
|
||||
* "node" = @ContextDefinition("entity:node", label = @Translation("Node"), required = FALSE),
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
class OptionalContextCondition extends ConditionPluginBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function evaluate() {
|
||||
// Grant access if no context value is given.
|
||||
return !$this->getContextValue('node');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function summary() {
|
||||
return $this->t('Context with optional context.');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\condition_test\Tests\OptionalContextConditionTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\condition_test\Tests;
|
||||
|
||||
use Drupal\Core\Plugin\Context\Context;
|
||||
use Drupal\Core\Plugin\Context\ContextDefinition;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\simpletest\KernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests a condition with optional context.
|
||||
*
|
||||
* @group condition_test
|
||||
*/
|
||||
class OptionalContextConditionTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['system', 'user', 'condition_test', 'node'];
|
||||
|
||||
/**
|
||||
* Tests with both contexts mapped to the same user.
|
||||
*/
|
||||
protected function testContextMissing() {
|
||||
/** @var \Drupal\Core\Condition\ConditionPluginBase $condition */
|
||||
$condition = \Drupal::service('plugin.manager.condition')
|
||||
->createInstance('condition_test_optional_context')
|
||||
->setContextMapping([
|
||||
'node' => 'node',
|
||||
]);
|
||||
\Drupal::service('context.handler')->applyContextMapping($condition, []);
|
||||
$this->assertTrue($condition->execute());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests with both contexts mapped to the same user.
|
||||
*/
|
||||
protected function testContextNoValue() {
|
||||
/** @var \Drupal\Core\Condition\ConditionPluginBase $condition */
|
||||
$condition = \Drupal::service('plugin.manager.condition')
|
||||
->createInstance('condition_test_optional_context')
|
||||
->setContextMapping([
|
||||
'node' => 'node',
|
||||
]);
|
||||
$definition = new ContextDefinition('entity:node');
|
||||
$contexts['node'] = (new Context($definition));
|
||||
\Drupal::service('context.handler')->applyContextMapping($condition, $contexts);
|
||||
$this->assertTrue($condition->execute());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests with both contexts mapped to the same user.
|
||||
*/
|
||||
protected function testContextAvailable() {
|
||||
/** @var \Drupal\Core\Condition\ConditionPluginBase $condition */
|
||||
$condition = \Drupal::service('plugin.manager.condition')
|
||||
->createInstance('condition_test_optional_context')
|
||||
->setContextMapping([
|
||||
'node' => 'node',
|
||||
]);
|
||||
$definition = new ContextDefinition('entity:node');
|
||||
$node = Node::create(['type' => 'example']);
|
||||
$contexts['node'] = (new Context($definition))->setContextValue($node);
|
||||
\Drupal::service('context.handler')->applyContextMapping($condition, $contexts);
|
||||
$this->assertFalse($condition->execute());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
name: Content negotiation test
|
||||
type: module
|
||||
description: 'Support testing content negotiation variations.'
|
||||
package: Core
|
||||
package: Testing
|
||||
version: VERSION
|
||||
core: 8.x
|
||||
|
|
|
@ -274,5 +274,21 @@ function database_test_schema() {
|
|||
'primary key' => array('name', 'age'),
|
||||
);
|
||||
|
||||
$schema['test_special_columns'] = array(
|
||||
'description' => 'A simple test table with special column names.',
|
||||
'fields' => array(
|
||||
'id' => array(
|
||||
'description' => 'Simple unique ID.',
|
||||
'type' => 'int',
|
||||
'not null' => TRUE,
|
||||
),
|
||||
'offset' => array(
|
||||
'description' => 'A column with preserved name.',
|
||||
'type' => 'text',
|
||||
),
|
||||
),
|
||||
'primary key' => array('id'),
|
||||
);
|
||||
|
||||
return $schema;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
name: 'Display variant tests'
|
||||
type: module
|
||||
description: 'Support module for testing display variants.'
|
||||
package: Testing
|
||||
version: VERSION
|
||||
core: 8.x
|
|
@ -0,0 +1,5 @@
|
|||
services:
|
||||
display_variant_test.page_display_variant_subscriber:
|
||||
class: Drupal\display_variant_test\EventSubscriber\TestPageDisplayVariantSubscriber
|
||||
tags:
|
||||
- { name: 'event_subscriber', priority: 1000 }
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\display_variant_test\EventSubscriber\TestPageDisplayVariantSubscriber.
|
||||
*/
|
||||
|
||||
namespace Drupal\display_variant_test\EventSubscriber;
|
||||
|
||||
use Drupal\Core\Render\PageDisplayVariantSelectionEvent;
|
||||
use Drupal\Core\Render\RenderEvents;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
/**
|
||||
* Selects the test page display variant.
|
||||
*/
|
||||
class TestPageDisplayVariantSubscriber implements EventSubscriberInterface {
|
||||
|
||||
/**
|
||||
* Selects the page display variant.
|
||||
*
|
||||
* @param \Drupal\Core\Render\PageDisplayVariantSelectionEvent $event
|
||||
* The event to process.
|
||||
*/
|
||||
public function onSelectPageDisplayVariant(PageDisplayVariantSelectionEvent $event) {
|
||||
$event->setPluginId('display_variant_test');
|
||||
$event->setPluginConfiguration(['required_configuration' => 'A very important, required value.']);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
static function getSubscribedEvents() {
|
||||
$events[RenderEvents::SELECT_PAGE_DISPLAY_VARIANT][] = array('onSelectPageDisplayVariant');
|
||||
return $events;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\display_variant_test\Plugin\DisplayVariant\TestDisplayVariant.
|
||||
*/
|
||||
|
||||
namespace Drupal\display_variant_test\Plugin\DisplayVariant;
|
||||
|
||||
use Drupal\Core\Display\VariantBase;
|
||||
use Drupal\Core\Display\PageVariantInterface;
|
||||
|
||||
/**
|
||||
* Provides a display variant that requires configuration.
|
||||
*
|
||||
* @DisplayVariant(
|
||||
* id = "display_variant_test",
|
||||
* admin_label = @Translation("Test display variant")
|
||||
* )
|
||||
*/
|
||||
class TestDisplayVariant extends VariantBase implements PageVariantInterface {
|
||||
|
||||
/**
|
||||
* The render array representing the main page content.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $mainContent = [];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setMainContent(array $main_content) {
|
||||
$this->mainContent = $main_content;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function build() {
|
||||
$config = $this->getConfiguration();
|
||||
if (empty($config['required_configuration'])) {
|
||||
throw new \Exception('Required configuration is missing!');
|
||||
}
|
||||
|
||||
$build = [];
|
||||
$build['content']['default'] = [
|
||||
'#markup' => $config['required_configuration'],
|
||||
];
|
||||
return $build;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
name: 'Early rendering controller test'
|
||||
type: module
|
||||
description: 'Support module for EarlyRenderingControllerTest.'
|
||||
package: Testing
|
||||
version: VERSION
|
||||
core: 8.x
|
|
@ -0,0 +1,111 @@
|
|||
# Controller returning a render array.
|
||||
early_rendering_controller_test.render_array:
|
||||
path: '/early-rendering-controller-test/render-array'
|
||||
defaults:
|
||||
_controller: '\Drupal\early_rendering_controller_test\EarlyRenderingTestController::renderArray'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
early_rendering_controller_test.render_array.early:
|
||||
path: '/early-rendering-controller-test/render-array/early'
|
||||
defaults:
|
||||
_controller: '\Drupal\early_rendering_controller_test\EarlyRenderingTestController::renderArrayEarly'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
# Controller returning an AjaxResponse.
|
||||
early_rendering_controller_test.ajax_response:
|
||||
path: '/early-rendering-controller-test/ajax-response'
|
||||
defaults:
|
||||
_controller: '\Drupal\early_rendering_controller_test\EarlyRenderingTestController::ajaxResponse'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
early_rendering_controller_test.ajax_response.early:
|
||||
path: '/early-rendering-controller-test/ajax-response/early'
|
||||
defaults:
|
||||
_controller: '\Drupal\early_rendering_controller_test\EarlyRenderingTestController::ajaxResponseEarly'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
# Controller returning a basic Response object.
|
||||
early_rendering_controller_test.response:
|
||||
path: '/early-rendering-controller-test/response'
|
||||
defaults:
|
||||
_controller: '\Drupal\early_rendering_controller_test\EarlyRenderingTestController::response'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
early_rendering_controller_test.response.early:
|
||||
path: '/early-rendering-controller-test/response/early'
|
||||
defaults:
|
||||
_controller: '\Drupal\early_rendering_controller_test\EarlyRenderingTestController::responseEarly'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
# Controller returning a Response object with attachments.
|
||||
early_rendering_controller_test.response-with-attachments:
|
||||
path: '/early-rendering-controller-test/response-with-attachments'
|
||||
defaults:
|
||||
_controller: '\Drupal\early_rendering_controller_test\EarlyRenderingTestController::responseWithAttachments'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
early_rendering_controller_test.response-with-attachments.early:
|
||||
path: '/early-rendering-controller-test/response-with-attachments/early'
|
||||
defaults:
|
||||
_controller: '\Drupal\early_rendering_controller_test\EarlyRenderingTestController::responseWithAttachmentsEarly'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
# Controller returning a cacheable Response object.
|
||||
early_rendering_controller_test.cacheable-response:
|
||||
path: '/early-rendering-controller-test/cacheable-response'
|
||||
defaults:
|
||||
_controller: '\Drupal\early_rendering_controller_test\EarlyRenderingTestController::cacheableResponse'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
early_rendering_controller_test.cacheable-response.early:
|
||||
path: '/early-rendering-controller-test/cacheable-response/early'
|
||||
defaults:
|
||||
_controller: '\Drupal\early_rendering_controller_test\EarlyRenderingTestController::cacheableResponseEarly'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
# Controller returning a basic domain object.
|
||||
early_rendering_controller_test.domain-object:
|
||||
path: '/early-rendering-controller-test/domain-object'
|
||||
defaults:
|
||||
_controller: '\Drupal\early_rendering_controller_test\EarlyRenderingTestController::domainObject'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
early_rendering_controller_test.domain-object.early:
|
||||
path: '/early-rendering-controller-test/domain-object/early'
|
||||
defaults:
|
||||
_controller: '\Drupal\early_rendering_controller_test\EarlyRenderingTestController::domainObjectEarly'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
# Controller returning a domain object with attachments.
|
||||
early_rendering_controller_test.domain-object-with-attachments:
|
||||
path: '/early-rendering-controller-test/domain-object-with-attachments'
|
||||
defaults:
|
||||
_controller: '\Drupal\early_rendering_controller_test\EarlyRenderingTestController::domainObjectWithAttachments'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
early_rendering_controller_test.domain-object-with-attachments.early:
|
||||
path: '/early-rendering-controller-test/domain-object-with-attachments/early'
|
||||
defaults:
|
||||
_controller: '\Drupal\early_rendering_controller_test\EarlyRenderingTestController::domainObjectWithAttachmentsEarly'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
# Controller returning a cacheable domain object.
|
||||
early_rendering_controller_test.cacheable-domain-object:
|
||||
path: '/early-rendering-controller-test/cacheable-domain-object'
|
||||
defaults:
|
||||
_controller: '\Drupal\early_rendering_controller_test\EarlyRenderingTestController::cacheableDomainObject'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
early_rendering_controller_test.cacheable-domain-object.early:
|
||||
path: '/early-rendering-controller-test/cacheable-domain-object/early'
|
||||
defaults:
|
||||
_controller: '\Drupal\early_rendering_controller_test\EarlyRenderingTestController::cacheableDomainObjectEarly'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
|
@ -0,0 +1,5 @@
|
|||
services:
|
||||
test_domain_object.view_subscriber:
|
||||
class: Drupal\early_rendering_controller_test\TestDomainObjectViewSubscriber
|
||||
tags:
|
||||
- { name: event_subscriber }
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\early_rendering_controller_test\AttachmentsTestDomainObject.
|
||||
*/
|
||||
|
||||
namespace Drupal\early_rendering_controller_test;
|
||||
|
||||
use Drupal\Core\Render\AttachmentsInterface;
|
||||
use Drupal\Core\Render\AttachmentsTrait;
|
||||
|
||||
class AttachmentsTestDomainObject extends TestDomainObject implements AttachmentsInterface {
|
||||
|
||||
use AttachmentsTrait;
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\early_rendering_controller_test\AttachmentsTestResponse.
|
||||
*/
|
||||
|
||||
namespace Drupal\early_rendering_controller_test;
|
||||
|
||||
use Drupal\Core\Render\AttachmentsInterface;
|
||||
use Drupal\Core\Render\AttachmentsTrait;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class AttachmentsTestResponse extends Response implements AttachmentsInterface {
|
||||
|
||||
use AttachmentsTrait;
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\early_rendering_controller_test\AttachmentsTestDomainObject.
|
||||
*/
|
||||
|
||||
namespace Drupal\early_rendering_controller_test;
|
||||
|
||||
use Drupal\Core\Cache\CacheableDependencyInterface;
|
||||
|
||||
class CacheableTestDomainObject extends TestDomainObject implements CacheableDependencyInterface {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheContexts() {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheTags() {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheMaxAge() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\early_rendering_controller_test\CacheableTestResponse.
|
||||
*/
|
||||
|
||||
namespace Drupal\early_rendering_controller_test;
|
||||
|
||||
use Drupal\Core\Cache\CacheableResponseInterface;
|
||||
use Drupal\Core\Cache\CacheableResponseTrait;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class CacheableTestResponse extends Response implements CacheableResponseInterface {
|
||||
|
||||
use CacheableResponseTrait;
|
||||
|
||||
}
|
|
@ -0,0 +1,150 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\early_rendering_controller_test\EarlyRenderingTestController.
|
||||
*/
|
||||
|
||||
namespace Drupal\early_rendering_controller_test;
|
||||
|
||||
use Drupal\Core\Ajax\AjaxResponse;
|
||||
use Drupal\Core\Ajax\InsertCommand;
|
||||
use Drupal\Core\Controller\ControllerBase;
|
||||
use Drupal\Core\Render\RendererInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
/**
|
||||
* Controller routines for early_rendering_test routes.
|
||||
*
|
||||
* The methods on this controller each correspond to a route for this module,
|
||||
* each of which exist solely for test cases in EarlyRenderingControllerTest;
|
||||
* see that test for documentation.
|
||||
*
|
||||
* @see core/modules/early_rendering_controller_test/early_rendering_controller_test.routing.yml
|
||||
* @see \Drupal\system\Tests\Common\EarlyRenderingControllerTest::testEarlyRendering()
|
||||
*/
|
||||
class EarlyRenderingTestController extends ControllerBase {
|
||||
|
||||
/**
|
||||
* The renderer.
|
||||
*
|
||||
* @var \Drupal\Core\Render\RendererInterface
|
||||
*/
|
||||
protected $renderer;
|
||||
|
||||
/**
|
||||
* Constructs a EarlyRenderingTestController.
|
||||
*
|
||||
* @param \Drupal\Core\Render\RendererInterface $renderer
|
||||
*/
|
||||
public function __construct(RendererInterface $renderer) {
|
||||
$this->renderer = $renderer;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('renderer')
|
||||
);
|
||||
}
|
||||
|
||||
protected function earlyRenderContent() {
|
||||
return [
|
||||
'#markup' => 'Hello world!',
|
||||
'#cache' => [
|
||||
'tags' => [
|
||||
'foo',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function renderArray() {
|
||||
return [
|
||||
'#pre_render' => [function () {
|
||||
$elements = $this->earlyRenderContent();
|
||||
return $elements;
|
||||
}],
|
||||
];
|
||||
}
|
||||
|
||||
public function renderArrayEarly() {
|
||||
$render_array = $this->earlyRenderContent();
|
||||
return [
|
||||
'#markup' => $this->renderer->render($render_array),
|
||||
];
|
||||
}
|
||||
|
||||
public function ajaxResponse() {
|
||||
$response = new AjaxResponse();
|
||||
$response->addCommand(new InsertCommand(NULL, $this->renderArray()));
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function ajaxResponseEarly() {
|
||||
$response = new AjaxResponse();
|
||||
$response->addCommand(new InsertCommand(NULL, $this->renderArrayEarly()));
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function response() {
|
||||
return new Response('Hello world!');
|
||||
}
|
||||
|
||||
public function responseEarly() {
|
||||
$render_array = $this->earlyRenderContent();
|
||||
return new Response($this->renderer->render($render_array));
|
||||
}
|
||||
|
||||
public function responseWithAttachments() {
|
||||
return new AttachmentsTestResponse('Hello world!');
|
||||
}
|
||||
|
||||
public function responseWithAttachmentsEarly() {
|
||||
$render_array = $this->earlyRenderContent();
|
||||
return new AttachmentsTestResponse($this->renderer->render($render_array));
|
||||
}
|
||||
|
||||
public function cacheableResponse() {
|
||||
return new CacheableTestResponse('Hello world!');
|
||||
}
|
||||
|
||||
public function cacheableResponseEarly() {
|
||||
$render_array = $this->earlyRenderContent();
|
||||
return new CacheableTestResponse($this->renderer->render($render_array));
|
||||
}
|
||||
|
||||
public function domainObject() {
|
||||
return new TestDomainObject();
|
||||
}
|
||||
|
||||
public function domainObjectEarly() {
|
||||
$render_array = $this->earlyRenderContent();
|
||||
$this->renderer->render($render_array);
|
||||
return new TestDomainObject();
|
||||
}
|
||||
|
||||
public function domainObjectWithAttachments() {
|
||||
return new AttachmentsTestDomainObject();
|
||||
}
|
||||
|
||||
public function domainObjectWithAttachmentsEarly() {
|
||||
$render_array = $this->earlyRenderContent();
|
||||
$this->renderer->render($render_array);
|
||||
return new AttachmentsTestDomainObject();
|
||||
}
|
||||
|
||||
public function cacheableDomainObject() {
|
||||
return new CacheableTestDomainObject();
|
||||
}
|
||||
|
||||
public function cacheableDomainObjectEarly() {
|
||||
$render_array = $this->earlyRenderContent();
|
||||
$this->renderer->render($render_array);
|
||||
return new CacheableTestDomainObject();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\early_rendering_controller_test\TestDomainObject.
|
||||
*/
|
||||
|
||||
namespace Drupal\early_rendering_controller_test;
|
||||
|
||||
class TestDomainObject { }
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\early_rendering_controller_test\TestDomainObjectViewSubscriber.
|
||||
*/
|
||||
|
||||
namespace Drupal\early_rendering_controller_test;
|
||||
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
|
||||
/**
|
||||
* View subscriber for turning TestDomainObject objects into Response objects.
|
||||
*/
|
||||
class TestDomainObjectViewSubscriber implements EventSubscriberInterface {
|
||||
|
||||
/**
|
||||
* Sets a response given a TestDomainObject instance.
|
||||
*
|
||||
* @param \Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent $event
|
||||
* The event to process.
|
||||
*/
|
||||
public function onViewTestDomainObject(GetResponseForControllerResultEvent $event) {
|
||||
$result = $event->getControllerResult();
|
||||
|
||||
if ($result instanceof TestDomainObject) {
|
||||
if ($result instanceof AttachmentsTestDomainObject) {
|
||||
$event->setResponse(new AttachmentsTestResponse('AttachmentsTestDomainObject'));
|
||||
}
|
||||
elseif ($result instanceof CacheableTestDomainObject) {
|
||||
$event->setResponse(new CacheableTestResponse('CacheableTestDomainObject'));
|
||||
}
|
||||
else {
|
||||
$event->setResponse(new Response('TestDomainObject'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
static function getSubscribedEvents() {
|
||||
$events[KernelEvents::VIEW][] = ['onViewTestDomainObject'];
|
||||
|
||||
return $events;
|
||||
}
|
||||
|
||||
}
|
|
@ -9,6 +9,7 @@ use Drupal\Core\Access\AccessResult;
|
|||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Entity\FieldableEntityInterface;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Field\BaseFieldDefinition;
|
||||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
@ -97,6 +98,23 @@ function entity_test_entity_type_alter(array &$entity_types) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_base_field_info().
|
||||
*/
|
||||
function entity_test_entity_base_field_info(EntityTypeInterface $entity_type) {
|
||||
$fields = [];
|
||||
|
||||
if ($entity_type->id() == 'entity_test_mulrev' && \Drupal::state()->get('entity_test.field_test_item')) {
|
||||
$fields['field_test_item'] = BaseFieldDefinition::create('field_test')
|
||||
->setLabel(t('Field test'))
|
||||
->setDescription(t('A field test.'))
|
||||
->setRevisionable(TRUE)
|
||||
->setTranslatable(TRUE);
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_base_field_info_alter().
|
||||
*/
|
||||
|
@ -257,6 +275,37 @@ function entity_test_entity_extra_field_info() {
|
|||
return $extra;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_form_BASE_FORM_ID_alter().
|
||||
*/
|
||||
function entity_test_form_entity_test_form_alter(&$form) {
|
||||
switch (\Drupal::state()->get('entity_test.form.validate.test')) {
|
||||
case 'form-level':
|
||||
$form['#validate'][] = 'entity_test_form_entity_test_form_validate';
|
||||
$form['#validate'][] = 'entity_test_form_entity_test_form_validate_check';
|
||||
break;
|
||||
|
||||
case 'button-level':
|
||||
$form['actions']['submit']['#validate'][] = 'entity_test_form_entity_test_form_validate';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation handler for the entity_test entity form.
|
||||
*/
|
||||
function entity_test_form_entity_test_form_validate(array &$form, FormStateInterface $form_state) {
|
||||
$form['#entity_test_form_validate'] = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation handler for the entity_test entity form.
|
||||
*/
|
||||
function entity_test_form_entity_test_form_validate_check(array &$form, FormStateInterface $form_state) {
|
||||
if (!empty($form['#entity_test_form_validate'])) {
|
||||
\Drupal::state()->set('entity_test.form.validate.result', TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_form_BASE_FORM_ID_alter().
|
||||
*/
|
||||
|
|
|
@ -76,5 +76,12 @@ entity.user_role.test_operation:
|
|||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
entity.entity_test_view_builder.canonical:
|
||||
path: '/entity_test_view_builder/{entity_test_view_builder}'
|
||||
defaults:
|
||||
_entity_view: 'entity_test_view_builder'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
route_callbacks:
|
||||
- '\Drupal\entity_test\Routing\EntityTestRoutes::routes'
|
||||
|
|
|
@ -7,11 +7,14 @@
|
|||
|
||||
namespace Drupal\entity_test\Cache;
|
||||
|
||||
use Drupal\Core\Cache\CacheableMetadata;
|
||||
use Drupal\Core\Cache\Context\CacheContextInterface;
|
||||
|
||||
/**
|
||||
* Defines the entity_test view grants cache context service.
|
||||
*
|
||||
* Cache context ID: 'entity_test_view_grants'.
|
||||
*
|
||||
* @see \Drupal\node\Cache\NodeAccessViewGrantsCacheContext
|
||||
*/
|
||||
class EntityTestViewGrantsCacheContext implements CacheContextInterface {
|
||||
|
@ -32,4 +35,11 @@ class EntityTestViewGrantsCacheContext implements CacheContextInterface {
|
|||
return '299792458';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCacheableMetadata() {
|
||||
return new CacheableMetadata();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\entity_test\Entity\EntityTestViewBuilder.
|
||||
*/
|
||||
|
||||
namespace Drupal\entity_test\Entity;
|
||||
|
||||
/**
|
||||
* Test entity class for testing a view builder.
|
||||
*
|
||||
* @ContentEntityType(
|
||||
* id = "entity_test_view_builder",
|
||||
* label = @Translation("Entity Test view builder"),
|
||||
* handlers = {
|
||||
* "access" = "Drupal\entity_test\EntityTestAccessControlHandler",
|
||||
* "view_builder" = "Drupal\entity_test\EntityTestViewBuilderOverriddenView",
|
||||
* },
|
||||
* base_table = "entity_test",
|
||||
* render_cache = FALSE,
|
||||
* entity_keys = {
|
||||
* "id" = "id",
|
||||
* "label" = "name",
|
||||
* "bundle" = "type"
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
class EntityTestViewBuilder extends EntityTest {
|
||||
|
||||
}
|
|
@ -51,35 +51,40 @@ class EntityTestForm extends ContentEntityForm {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function save(array $form, FormStateInterface $form_state) {
|
||||
$entity = $this->entity;
|
||||
try {
|
||||
$entity = $this->entity;
|
||||
|
||||
// Save as a new revision if requested to do so.
|
||||
if (!$form_state->isValueEmpty('revision')) {
|
||||
$entity->setNewRevision();
|
||||
}
|
||||
// Save as a new revision if requested to do so.
|
||||
if (!$form_state->isValueEmpty('revision')) {
|
||||
$entity->setNewRevision();
|
||||
}
|
||||
|
||||
$is_new = $entity->isNew();
|
||||
$entity->save();
|
||||
$is_new = $entity->isNew();
|
||||
$entity->save();
|
||||
|
||||
if ($is_new) {
|
||||
$message = t('%entity_type @id has been created.', array('@id' => $entity->id(), '%entity_type' => $entity->getEntityTypeId()));
|
||||
}
|
||||
else {
|
||||
$message = t('%entity_type @id has been updated.', array('@id' => $entity->id(), '%entity_type' => $entity->getEntityTypeId()));
|
||||
}
|
||||
drupal_set_message($message);
|
||||
if ($is_new) {
|
||||
$message = t('%entity_type @id has been created.', array('@id' => $entity->id(), '%entity_type' => $entity->getEntityTypeId()));
|
||||
}
|
||||
else {
|
||||
$message = t('%entity_type @id has been updated.', array('@id' => $entity->id(), '%entity_type' => $entity->getEntityTypeId()));
|
||||
}
|
||||
drupal_set_message($message);
|
||||
|
||||
if ($entity->id()) {
|
||||
$entity_type = $entity->getEntityTypeId();
|
||||
$form_state->setRedirect(
|
||||
"entity.$entity_type.edit_form",
|
||||
array($entity_type => $entity->id())
|
||||
);
|
||||
if ($entity->id()) {
|
||||
$entity_type = $entity->getEntityTypeId();
|
||||
$form_state->setRedirect(
|
||||
"entity.$entity_type.edit_form",
|
||||
array($entity_type => $entity->id())
|
||||
);
|
||||
}
|
||||
else {
|
||||
// Error on save.
|
||||
drupal_set_message(t('The entity could not be saved.'), 'error');
|
||||
$form_state->setRebuild();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Error on save.
|
||||
drupal_set_message(t('The entity could not be saved.'), 'error');
|
||||
$form_state->setRebuild();
|
||||
catch (\Exception $e) {
|
||||
\Drupal::state()->set('entity_test.form.save.exception', get_class($e) . ': ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\entity_test\EntityTestViewBuilderOverriddenView.
|
||||
*/
|
||||
|
||||
namespace Drupal\entity_test;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
|
||||
/**
|
||||
* Provides a view builder that overrides ::view() and ::viewMultiple().
|
||||
*/
|
||||
class EntityTestViewBuilderOverriddenView extends EntityTestViewBuilder {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function view(EntityInterface $entity, $view_mode = 'full', $langcode = NULL) {
|
||||
$build = [];
|
||||
$build[$entity->id()]['#markup'] = SafeMarkup::checkPlain($entity->label());
|
||||
return $build;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function viewMultiple(array $entities = [], $view_mode = 'full', $langcode = NULL) {
|
||||
$build = [];
|
||||
foreach ($entities as $key => $entity) {
|
||||
$build[$key] = $this->view($entity, $view_mode, $langcode);
|
||||
}
|
||||
return $build;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\entity_test\Plugin\Field\FieldType\FieldTestItem.
|
||||
*/
|
||||
|
||||
namespace Drupal\entity_test\Plugin\Field\FieldType;
|
||||
|
||||
use Drupal\Core\Field\FieldItemBase;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\Core\StringTranslation\TranslationWrapper;
|
||||
use Drupal\Core\TypedData\DataDefinition;
|
||||
use Drupal\Core\TypedData\DataDefinitionInterface;
|
||||
use Drupal\Core\TypedData\TypedDataInterface;
|
||||
|
||||
|
||||
/**
|
||||
* Defines the 'field_test' entity field type.
|
||||
*
|
||||
* @FieldType(
|
||||
* id = "field_test",
|
||||
* label = @Translation("Test field item"),
|
||||
* description = @Translation("A field containing a plain string value."),
|
||||
* category = @Translation("Field"),
|
||||
* )
|
||||
*/
|
||||
class FieldTestItem extends FieldItemBase {
|
||||
|
||||
/**
|
||||
* Counts how many times all items of this type are saved.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected static $counter = [];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
|
||||
// This is called very early by the user entity roles field. Prevent
|
||||
// early t() calls by using the TranslationWrapper.
|
||||
$properties['value'] = DataDefinition::create('string')
|
||||
->setLabel(new TranslationWrapper('Test value'))
|
||||
->setRequired(TRUE);
|
||||
|
||||
return $properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function schema(FieldStorageDefinitionInterface $field_definition) {
|
||||
return array(
|
||||
'columns' => array(
|
||||
'value' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct(DataDefinitionInterface $definition, $name = NULL, TypedDataInterface $parent = NULL) {
|
||||
parent::__construct($definition, $name, $parent);
|
||||
|
||||
$name = $this->getFieldDefinition()->getName();
|
||||
static::$counter[$name] = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function preSave() {
|
||||
$name = $this->getFieldDefinition()->getName();
|
||||
static::$counter[$name]++;
|
||||
|
||||
// Overwrite the field value unless it is going to be overridden, in which
|
||||
// case its final value will already be different from the current one.
|
||||
if (!$this->getEntity()->isNew() && !$this->mustResave()) {
|
||||
$this->setValue('overwritten');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function postSave($update) {
|
||||
// Determine whether the field value should be rewritten to the storage. We
|
||||
// always rewrite on create as we need to store a value including the entity
|
||||
// id.
|
||||
$resave = !$update || $this->mustResave();
|
||||
|
||||
if ($resave) {
|
||||
$entity = $this->getEntity();
|
||||
$definition = $this->getFieldDefinition();
|
||||
$name = $definition->getName();
|
||||
$value = 'field_test:' . $name . ':' . $entity->id() . ':' . static::$counter[$name];
|
||||
$this->setValue($value);
|
||||
}
|
||||
|
||||
return $resave;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the field item value should be resaved.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the item should be resaved, FALSE otherwise.
|
||||
*/
|
||||
protected function mustResave() {
|
||||
return $this->getValue()['value'] == 'resave';
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
name: 'Entity Operation Test'
|
||||
type: module
|
||||
description: 'Provides a test operation to entities.'
|
||||
package: Testing
|
||||
version: VERSION
|
||||
core: 8.x
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains hook implementations for Entity Operation Test Module.
|
||||
*/
|
||||
|
||||
use Drupal\Core\Url;
|
||||
|
||||
/**
|
||||
* Implements hook_entity_operation().
|
||||
*/
|
||||
function entity_test_operation_entity_operation(\Drupal\Core\Entity\EntityInterface $entity) {
|
||||
return [
|
||||
'test' => [
|
||||
'title' => t('Front page'),
|
||||
'url' => Url::fromRoute('<front>'),
|
||||
'weight' => 0,
|
||||
],
|
||||
];
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
name: 'Error service test'
|
||||
type: module
|
||||
description: 'Support module for causing bedlam in container rebuilds.'
|
||||
package: Testing
|
||||
version: VERSION
|
||||
core: 8.x
|
|
@ -0,0 +1,6 @@
|
|||
error_service_test.broken_class:
|
||||
path: broken-service-class
|
||||
defaults:
|
||||
_controller: \Drupal\error_service_test\Controller\LonelyMonkeyController::testBrokenClass
|
||||
requirements:
|
||||
_access: 'TRUE'
|
|
@ -0,0 +1,8 @@
|
|||
services:
|
||||
http_middleware.monkeys:
|
||||
class: Drupal\error_service_test\MonkeysInTheControlRoom
|
||||
tags:
|
||||
- { name: http_middleware, priority: 400 }
|
||||
# Set up a service with a missing class dependency.
|
||||
broken_class_with_missing_dependency:
|
||||
class: Drupal\error_service_test\LonelyMonkeyClass
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\error_service_test\Controller\LonelyMonkeyController.
|
||||
*/
|
||||
|
||||
namespace Drupal\error_service_test\Controller;
|
||||
|
||||
use Drupal\Core\Controller\ControllerBase;
|
||||
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
|
||||
use Drupal\error_service_test\LonelyMonkeyClass;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Provides a controller which calls out to a service with missing dependencies.
|
||||
*/
|
||||
class LonelyMonkeyController extends ControllerBase implements ContainerInjectionInterface {
|
||||
|
||||
public function __construct(LonelyMonkeyClass $class) {
|
||||
$this->class = $class;
|
||||
}
|
||||
|
||||
public function testBrokenClass() {
|
||||
return [
|
||||
'#markup' => $this->t('This should be broken.'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static($container->get('broken_class_with_missing_dependency'));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\error_service_test\ErrorServiceTestServiceProvider.
|
||||
*/
|
||||
|
||||
namespace Drupal\error_service_test;
|
||||
|
||||
use Drupal\Core\DependencyInjection\ContainerBuilder;
|
||||
use Drupal\Core\DependencyInjection\ServiceModifierInterface;
|
||||
|
||||
class ErrorServiceTestServiceProvider implements ServiceModifierInterface {
|
||||
|
||||
/**
|
||||
* The in-situ container builder.
|
||||
*
|
||||
* @var \Drupal\Core\DependencyInjection\ContainerBuilder
|
||||
*/
|
||||
public static $containerBuilder;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function alter(ContainerBuilder $container) {
|
||||
static::$containerBuilder = $container;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\error_service_test\LonelyMonkeyClass.
|
||||
*/
|
||||
|
||||
namespace Drupal\error_service_test;
|
||||
|
||||
use Drupal\Core\Database\Connection;
|
||||
|
||||
/**
|
||||
* A class with a single dependency.
|
||||
*/
|
||||
class LonelyMonkeyClass {
|
||||
|
||||
public function __construct(Connection $connection) {
|
||||
$this->connection = $connection;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\error_service_test\MonkeysInTheControlRoom.
|
||||
*/
|
||||
|
||||
namespace Drupal\error_service_test;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
|
||||
/**
|
||||
* A http middleware designed to cause bedlam.
|
||||
*
|
||||
* @see error_service_test.services.yml
|
||||
*/
|
||||
class MonkeysInTheControlRoom implements HttpKernelInterface {
|
||||
|
||||
/**
|
||||
* The app kernel.
|
||||
*
|
||||
* @var \Symfony\Component\HttpKernel\HttpKernelInterface
|
||||
*/
|
||||
protected $app;
|
||||
|
||||
/**
|
||||
* MonkeysInTheControlRoom constructor.
|
||||
*
|
||||
* @param \Symfony\Component\HttpKernel\HttpKernelInterface $app
|
||||
* The wrapper HTTP kernel.
|
||||
*/
|
||||
public function __construct(HttpKernelInterface $app) {
|
||||
$this->app = $app;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = TRUE) {
|
||||
if (\Drupal::state()->get('error_service_test.break_bare_html_renderer')) {
|
||||
// Let the bedlam begin.
|
||||
// 1) Force a container rebuild.
|
||||
/** @var \Drupal\Core\DrupalKernelInterface $kernel */
|
||||
$kernel = \Drupal::service('kernel');
|
||||
$kernel->rebuildContainer();
|
||||
// 2) Fetch the in-situ container builder.
|
||||
$container = ErrorServiceTestServiceProvider::$containerBuilder;
|
||||
// Ensure the compiler pass worked.
|
||||
if (!$container) {
|
||||
throw new \Exception('Oh oh, monkeys stole the ServiceProvider.');
|
||||
}
|
||||
// Stop the theme manager from being found - and triggering error
|
||||
// maintenance mode.
|
||||
$container->removeDefinition('theme.manager');
|
||||
// Mash. Mash. Mash.
|
||||
\Drupal::setContainer($container);
|
||||
throw new \Exception('Oh oh, bananas in the instruments.');
|
||||
}
|
||||
|
||||
return $this->app->handle($request, $type, $catch);
|
||||
}
|
||||
|
||||
}
|
|
@ -75,19 +75,6 @@ function _form_test_tableselect_get_data() {
|
|||
return array($header, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_form_FORM_ID_alter().
|
||||
*
|
||||
* @see form_test_state_persist()
|
||||
*/
|
||||
function form_test_form_form_test_state_persist_alter(&$form, FormStateInterface $form_state) {
|
||||
// Simulate a form alter implementation inserting form elements that enable
|
||||
// caching of the form, e.g. elements having #ajax.
|
||||
if (\Drupal::request()->get('cache')) {
|
||||
$form_state->setCached();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_form_FORM_ID_alter() for the registration form.
|
||||
*/
|
||||
|
|
|
@ -82,17 +82,33 @@ class FormTestStorageForm extends FormBase {
|
|||
'#value' => 'Save',
|
||||
);
|
||||
|
||||
if (\Drupal::request()->get('cache')) {
|
||||
// @todo Remove this in https://www.drupal.org/node/2524408, because form
|
||||
// cache immutability is no longer necessary, because we no longer cache
|
||||
// forms during safe HTTP methods. In the meantime, because
|
||||
// Drupal\system\Tests\Form still has test coverage for a poisoned form
|
||||
// cache following a GET request, trick $form_state into caching the form
|
||||
// to keep that test working until we either remove it or change it in
|
||||
// that issue.
|
||||
if ($this->getRequest()->get('immutable')) {
|
||||
$form_state->addBuildInfo('immutable', TRUE);
|
||||
if ($this->getRequest()->get('cache') && $this->getRequest()->isMethodSafe()) {
|
||||
$form_state->setRequestMethod('FAKE');
|
||||
$form_state->setCached();
|
||||
}
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validateForm(array &$form, FormStateInterface $form_state) {
|
||||
if ($this->getRequest()->get('cache')) {
|
||||
// Manually activate caching, so we can test that the storage keeps working
|
||||
// when it's enabled.
|
||||
$form_state->setCached();
|
||||
}
|
||||
|
||||
if ($this->getRequest()->get('immutable')) {
|
||||
$form_state->addBuildInfo('immutable', TRUE);
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -105,7 +121,7 @@ class FormTestStorageForm extends FormBase {
|
|||
// This presumes that another submitted form value triggers a validation error
|
||||
// elsewhere in the form. Form API should still update the cached form storage
|
||||
// though.
|
||||
if (\Drupal::request()->get('cache') && $form_state->getValue('value') == 'change_title') {
|
||||
if ($this->getRequest()->get('cache') && $form_state->getValue('value') == 'change_title') {
|
||||
$form_state->set(['thing', 'changed'], TRUE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,7 +48,6 @@ class FormTestStoragePageCacheForm extends FormBase {
|
|||
);
|
||||
|
||||
$form['#after_build'] = array(array($this, 'form_test_storage_page_cache_old_build_id'));
|
||||
$form_state->setCached();
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
@ -70,6 +69,17 @@ class FormTestStoragePageCacheForm extends FormBase {
|
|||
$form_state->setRebuild();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validateForm(array &$form, FormStateInterface $form_state) {
|
||||
// Test using form cache when re-displaying a form due to validation
|
||||
// errors.
|
||||
if ($form_state->hasAnyErrors()) {
|
||||
$form_state->setCached();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -49,10 +49,6 @@ class FormTestValidateForm extends FormBase {
|
|||
'#value' => 'Save',
|
||||
);
|
||||
|
||||
// To simplify this test, enable form caching and use form storage to
|
||||
// remember our alteration.
|
||||
$form_state->setCached();
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
|
@ -70,6 +66,10 @@ class FormTestValidateForm extends FormBase {
|
|||
|
||||
// Trigger a form validation error to see our changes.
|
||||
$form_state->setErrorByName('');
|
||||
|
||||
// To simplify this test, enable form caching and use form storage to
|
||||
// remember our alteration.
|
||||
$form_state->setCached();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,22 @@ menu_test.local_action4:
|
|||
appears_on:
|
||||
- menu_test.local_action1
|
||||
|
||||
menu_test.local_action_derivative:
|
||||
route_name: menu_test.local_action4
|
||||
weight: -20
|
||||
deriver: Drupal\menu_test\Plugin\Derivative\LocalActionTest
|
||||
class: Drupal\Core\Menu\LocalActionDefault
|
||||
appears_on:
|
||||
- menu_test.local_action1
|
||||
|
||||
menu_test.local_action6:
|
||||
route_name: menu_test.local_action4
|
||||
title: 'Dynamic local action with user input'
|
||||
weight: -15
|
||||
class: '\Drupal\menu_test\Plugin\Menu\LocalAction\TestLocalAction5'
|
||||
appears_on:
|
||||
- menu_test.local_action1
|
||||
|
||||
menu_test.hidden_menu_add:
|
||||
route_name: menu_test.hidden_menu_add
|
||||
title: 'Add menu'
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
menu_test.hidden_manage:
|
||||
title: 'List links'
|
||||
menu_test.contextual_hidden_manage:
|
||||
title: 'List links - contextual'
|
||||
group: menu_test_menu
|
||||
route_name: menu_test.hidden_manage
|
||||
route_name: menu_test.contextual_hidden_manage
|
||||
class: '\Drupal\menu_test\Plugin\Menu\ContextualLink\TestContextualLink'
|
||||
|
||||
menu_test.hidden_manage_edit:
|
||||
title: 'Edit menu'
|
||||
menu_test.contextual_hidden_manage_edit:
|
||||
title: 'Edit menu - contextual'
|
||||
group: menu_test_menu
|
||||
route_name: menu_test.hidden_manage_edit
|
||||
route_name: menu_test.contextual_hidden_manage_edit
|
||||
|
||||
menu_test.hidden_block_configure:
|
||||
title: 'Configure block'
|
||||
|
|
|
@ -79,3 +79,7 @@ menu_test.child:
|
|||
title: 'Test menu_name child'
|
||||
route_name: menu_test.menu_name_test
|
||||
parent: menu_test.parent
|
||||
|
||||
menu_test.unsafe:
|
||||
route_name: menu_test.menu_name_test
|
||||
deriver: '\Drupal\menu_test\Plugin\Derivative\MenuLinkTestWithUnsafeTitle'
|
||||
|
|
|
@ -10,6 +10,10 @@ menu_test.local_task_test_tasks_settings:
|
|||
route_name: menu_test.local_task_test_tasks_settings
|
||||
title: Settings
|
||||
base_route: menu_test.local_task_test_tasks_view
|
||||
menu_test.local_task_test_tasks_settings_dynamic:
|
||||
route_name: menu_test.local_task_test_tasks_settings_dynamic
|
||||
base_route: menu_test.local_task_test_tasks_view
|
||||
class: \Drupal\menu_test\Plugin\Menu\LocalTask\TestTaskWithUserInput
|
||||
menu_test.local_task_test_tasks_settings_sub1:
|
||||
route_name: menu_test.local_task_test_tasks_settings_sub1
|
||||
title: sub1
|
||||
|
@ -53,6 +57,11 @@ menu_test.tasks_default_tab:
|
|||
route_name: menu_test.tasks_default
|
||||
title: 'View'
|
||||
base_route: menu_test.tasks_default
|
||||
menu_test.tasks_default_derived:
|
||||
route_name: menu_test.router_test1
|
||||
title: 'Derived'
|
||||
base_route: menu_test.tasks_default
|
||||
deriver: '\Drupal\menu_test\Plugin\Derivative\LocalTaskTestWithUnsafeTitle'
|
||||
|
||||
menu_test.tasks_tasks_tab:
|
||||
route_name: menu_test.tasks_tasks
|
||||
|
@ -82,3 +91,8 @@ menu_test.router_test3:
|
|||
route_name: menu_test.router_test3
|
||||
title: 'Local task C'
|
||||
base_route: menu_test.router_test1
|
||||
|
||||
menu_test.router_test4:
|
||||
route_name: menu_test.router_test4
|
||||
base_route: menu_test.router_test1
|
||||
class: \Drupal\menu_test\Plugin\Menu\LocalTask\TestTaskWithUserInput
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
* Module that implements various hooks for menu tests.
|
||||
*/
|
||||
|
||||
use Drupal\Core\Url;
|
||||
|
||||
/**
|
||||
* Implements hook_menu_links_discovered_alter().
|
||||
*/
|
||||
|
@ -26,20 +28,14 @@ function menu_test_menu_links_discovered_alter(&$links) {
|
|||
|
||||
/**
|
||||
* Implements hook_menu_local_tasks().
|
||||
*
|
||||
* If the menu_test.settings configuration 'tasks.add' has been set, adds
|
||||
* several local tasks to menu-test/tasks.
|
||||
*/
|
||||
function menu_test_menu_local_tasks(&$data, $route_name) {
|
||||
if (!\Drupal::config('menu_test.settings')->get('tasks.add')) {
|
||||
return;
|
||||
}
|
||||
if (in_array($route_name, array('menu_test.tasks_default', 'menu_test.tasks_empty', 'menu_test.tasks_tasks'))) {
|
||||
if (in_array($route_name, array('menu_test.tasks_default'))) {
|
||||
$data['tabs'][0]['foo'] = array(
|
||||
'#theme' => 'menu_local_task',
|
||||
'#link' => array(
|
||||
'title' => 'Task 1',
|
||||
'href' => 'task/foo',
|
||||
'title' => "Task 1 <script>alert('Welcome to the jungle!')</script>",
|
||||
'url' => Url::fromRoute('menu_test.router_test1', array('bar' => '1')),
|
||||
),
|
||||
'#weight' => 10,
|
||||
);
|
||||
|
@ -47,7 +43,7 @@ function menu_test_menu_local_tasks(&$data, $route_name) {
|
|||
'#theme' => 'menu_local_task',
|
||||
'#link' => array(
|
||||
'title' => 'Task 2',
|
||||
'href' => 'task/bar',
|
||||
'url' => Url::fromRoute('menu_test.router_test2', array('bar' => '2')),
|
||||
),
|
||||
'#weight' => 20,
|
||||
);
|
||||
|
|
|
@ -67,6 +67,13 @@ menu_test.router_test3:
|
|||
requirements:
|
||||
_access: 'FALSE'
|
||||
|
||||
menu_test.router_test4:
|
||||
path: '/foo/{bar}/d'
|
||||
defaults:
|
||||
_controller: '\Drupal\menu_test\TestControllers::test2'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
menu_test.local_action1:
|
||||
path: '/menu-test-local-action'
|
||||
defaults:
|
||||
|
@ -102,6 +109,27 @@ menu_test.local_action5:
|
|||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
menu_test.contextual_test:
|
||||
path: '/menu-test-contextual/default'
|
||||
defaults:
|
||||
_controller: '\Drupal\menu_test\TestControllers::testContextual'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
menu_test.contextual_hidden_manage:
|
||||
path: '/menu-test-contextual/{bar}'
|
||||
defaults:
|
||||
_controller: '\Drupal\menu_test\TestControllers::test1'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
menu_test.contextual_hidden_manage_edit:
|
||||
path: '/menu-test-contextual/{bar}/edit'
|
||||
defaults:
|
||||
_controller: '\Drupal\menu_test\TestControllers::test2'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
menu_test.local_task_test_tasks:
|
||||
path: '/menu-local-task-test/tasks'
|
||||
defaults:
|
||||
|
@ -109,6 +137,13 @@ menu_test.local_task_test_tasks:
|
|||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
menu_test.tasks_default:
|
||||
path: '/menu-local-task-test/default'
|
||||
defaults:
|
||||
_controller: '\Drupal\menu_test\TestControllers::test1'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
menu_test.local_task_test_tasks_tasks:
|
||||
path: '/menu-local-task-test/tasks/tasks'
|
||||
defaults:
|
||||
|
@ -137,6 +172,13 @@ menu_test.local_task_test_tasks_settings:
|
|||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
menu_test.local_task_test_tasks_settings_dynamic:
|
||||
path: '/menu-local-task-test/tasks/settings-dynamic'
|
||||
defaults:
|
||||
_controller: '\Drupal\menu_test\TestControllers::test1'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
menu_test.local_task_test_tasks_settings_sub1:
|
||||
path: '/menu-local-task-test/tasks/settings/sub1'
|
||||
defaults:
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\menu_test\Plugin\Derivative\LocalActionTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\menu_test\Plugin\Derivative;
|
||||
|
||||
use Drupal\Component\Plugin\Derivative\DeriverBase;
|
||||
|
||||
/**
|
||||
* Test derivative to check local action title escaping.
|
||||
*
|
||||
* @see \Drupal\system\Tests\Menu\LocalActionTest
|
||||
*/
|
||||
class LocalActionTest extends DeriverBase {
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getDerivativeDefinitions($base_plugin_definition) {
|
||||
$this->derivatives['example'] = $base_plugin_definition + [
|
||||
'title' => "<script>alert('Welcome to the derived jungle!')</script>",
|
||||
];
|
||||
|
||||
return $this->derivatives;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\menu_test\Plugin\Derivative\LocalTaskTestWithUnsafeTitle.
|
||||
*/
|
||||
|
||||
namespace Drupal\menu_test\Plugin\Derivative;
|
||||
|
||||
use Drupal\Component\Plugin\Derivative\DeriverBase;
|
||||
|
||||
/**
|
||||
* Test derivative to check local task title escaping.
|
||||
*
|
||||
* @see \Drupal\system\Tests\Menu\LocalTasksTest
|
||||
*/
|
||||
class LocalTaskTestWithUnsafeTitle extends DeriverBase {
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getDerivativeDefinitions($base_plugin_definition) {
|
||||
$this->derivatives['unsafe'] = [
|
||||
'title' => "<script>alert('Welcome to the derived jungle!')</script>",
|
||||
'route_parameters' => ['bar' => 'unsafe'],
|
||||
] + $base_plugin_definition;
|
||||
|
||||
return $this->derivatives;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\menu_test\Plugin\Derivative\MenuLinkTestWithUnsafeTitle.
|
||||
*/
|
||||
|
||||
namespace Drupal\menu_test\Plugin\Derivative;
|
||||
|
||||
use Drupal\Component\Plugin\Derivative\DeriverBase;
|
||||
|
||||
/**
|
||||
* Test derivative with an unsafe string.
|
||||
*/
|
||||
class MenuLinkTestWithUnsafeTitle extends DeriverBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDerivativeDefinitions($base_plugin_definition) {
|
||||
$this->derivatives['unsafe'] = [
|
||||
'title' => '<script>alert("Even more wild animals")</script>',
|
||||
'menu_name' => 'tools',
|
||||
] + $base_plugin_definition;
|
||||
|
||||
return $this->derivatives;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\menu_test\Plugin\Menu\ContextualLink\TestContextualLink.
|
||||
*/
|
||||
|
||||
namespace Drupal\menu_test\Plugin\Menu\ContextualLink;
|
||||
|
||||
use Drupal\Core\Menu\ContextualLinkDefault;
|
||||
|
||||
/**
|
||||
* Defines a contextual link plugin with a dynamic title from user input.
|
||||
*/
|
||||
class TestContextualLink extends ContextualLinkDefault {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getTitle() {
|
||||
return "<script>alert('Welcome to the jungle!')</script>";
|
||||
}
|
||||
|
||||
}
|
|
@ -8,12 +8,15 @@
|
|||
namespace Drupal\menu_test\Plugin\Menu\LocalAction;
|
||||
|
||||
use Drupal\Core\Menu\LocalActionDefault;
|
||||
use Drupal\Core\StringTranslation\StringTranslationTrait;
|
||||
|
||||
/**
|
||||
* Defines a local action plugin with a dynamic title.
|
||||
*/
|
||||
class TestLocalAction4 extends LocalActionDefault {
|
||||
|
||||
use StringTranslationTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\menu_test\Plugin\Menu\LocalAction\TestLocalAction5.
|
||||
*/
|
||||
|
||||
namespace Drupal\menu_test\Plugin\Menu\LocalAction;
|
||||
|
||||
use Drupal\Core\Menu\LocalActionDefault;
|
||||
|
||||
/**
|
||||
* Defines a local action plugin with a dynamic title from user input.
|
||||
*/
|
||||
class TestLocalAction5 extends LocalActionDefault {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getTitle() {
|
||||
return "<script>alert('Welcome to the jungle!')</script>";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\menu_test\Plugin\Menu\LocalTask\TestTaskWithUserInput.
|
||||
*/
|
||||
|
||||
namespace Drupal\menu_test\Plugin\Menu\LocalTask;
|
||||
|
||||
use Drupal\Core\Menu\LocalTaskDefault;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class TestTaskWithUserInput extends LocalTaskDefault {
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getTitle(Request $request = NULL) {
|
||||
return "<script>alert('Welcome to the jungle!')</script>";
|
||||
}
|
||||
|
||||
}
|
|
@ -8,9 +8,12 @@
|
|||
namespace Drupal\menu_test\Plugin\Menu\LocalTask;
|
||||
|
||||
use Drupal\Core\Menu\LocalTaskDefault;
|
||||
use Drupal\Core\StringTranslation\StringTranslationTrait;
|
||||
|
||||
class TestTasksSettingsSub1 extends LocalTaskDefault {
|
||||
|
||||
use StringTranslationTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -61,4 +61,20 @@ class TestControllers {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints out test data with contextual links.
|
||||
*/
|
||||
public function testContextual() {
|
||||
return [
|
||||
'#markup' => 'testContextual',
|
||||
'stuff' => [
|
||||
'#type' => 'contextual_links',
|
||||
'#contextual_links' => [
|
||||
'menu_test_menu' => [
|
||||
'route_parameters' => ['bar' => 1],
|
||||
]
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
# This entity is intentionally missing an 'id' key. During installation, an
|
||||
# EntityMalformedException should be thrown about the missing key.
|
||||
name: 'This entity does not have an ID'
|
|
@ -0,0 +1,10 @@
|
|||
module_installer_config_test.type.*:
|
||||
type: config_entity
|
||||
label: 'Test entity type'
|
||||
mapping:
|
||||
id:
|
||||
type: string
|
||||
name:
|
||||
type: label
|
||||
label: 'Name'
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
name: 'Module installer config test'
|
||||
description: 'Support module for tests that require a failed module install.'
|
||||
type: module
|
||||
package: Testing
|
||||
core: 8.x
|
||||
version: VERSION
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\module_installer_config_test\Entity\TestConfigType.
|
||||
*/
|
||||
|
||||
namespace Drupal\module_installer_config_test\Entity;
|
||||
|
||||
use Drupal\Core\Config\Entity\ConfigEntityBase;
|
||||
|
||||
/**
|
||||
* Defines a configuration-based entity type used for testing.
|
||||
*
|
||||
* @ConfigEntityType(
|
||||
* id = "test_config_type",
|
||||
* label = @Translation("Test entity type"),
|
||||
* handlers = {
|
||||
* "list_builder" = "Drupal\Core\Entity\EntityListBuilder"
|
||||
* },
|
||||
* admin_permission = "administer modules",
|
||||
* config_prefix = "type",
|
||||
* entity_keys = {
|
||||
* "id" = "id",
|
||||
* "label" = "name"
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
class TestConfigType extends ConfigEntityBase {
|
||||
}
|
|
@ -69,7 +69,7 @@ class PagerTestController extends ControllerBase {
|
|||
* #pre_render callback for #type => pager that shows the pager cache context.
|
||||
*/
|
||||
public static function showPagerCacheContext(array $pager) {
|
||||
drupal_set_message(\Drupal::service('cache_contexts_manager')->convertTokensToKeys(['url.query_args.pagers:' . $pager['#element']])[0]);
|
||||
drupal_set_message(\Drupal::service('cache_contexts_manager')->convertTokensToKeys(['url.query_args.pagers:' . $pager['#element']])->getKeys()[0]);
|
||||
return $pager;
|
||||
}
|
||||
|
||||
|
|
|
@ -141,6 +141,20 @@ router_test.22:
|
|||
requirements:
|
||||
_role: 'anonymous'
|
||||
|
||||
router_test.23:
|
||||
path: '/router_test/test23'
|
||||
defaults:
|
||||
_controller: '\Drupal\router_test\TestControllers::test23'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
router_test.24:
|
||||
path: '/router_test/test24'
|
||||
defaults:
|
||||
_controller: '\Drupal\router_test\TestControllers::test24'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
router_test.hierarchy_parent:
|
||||
path: '/menu-test/parent'
|
||||
defaults:
|
||||
|
|
|
@ -12,6 +12,8 @@ use Drupal\Core\ParamConverter\ParamNotConvertedException;
|
|||
use Drupal\user\UserInterface;
|
||||
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Zend\Diactoros\Response\HtmlResponse;
|
||||
|
||||
|
||||
/**
|
||||
* Controller routines for testing the routing system.
|
||||
|
@ -74,14 +76,7 @@ class TestControllers {
|
|||
* This can be used to test if the generated backtrace is properly escaped.
|
||||
*/
|
||||
public function test10() {
|
||||
// Remove the exception logger from the event dispatcher. We are going to
|
||||
// throw an exception to check if it is properly escaped when rendered as a
|
||||
// backtrace. The exception logger does a call to error_log() which is not
|
||||
// handled by the Simpletest error handler and would cause a test failure.
|
||||
$event_dispatcher = \Drupal::service('event_dispatcher');
|
||||
$exception_logger = \Drupal::service('exception.logger');
|
||||
$event_dispatcher->removeSubscriber($exception_logger);
|
||||
|
||||
$this->removeExceptionLogger();
|
||||
$this->throwException('<script>alert(\'xss\')</script>');
|
||||
}
|
||||
|
||||
|
@ -102,6 +97,15 @@ class TestControllers {
|
|||
return new CacheableResponse('test21');
|
||||
}
|
||||
|
||||
public function test23() {
|
||||
return new HtmlResponse('test23');
|
||||
}
|
||||
|
||||
public function test24() {
|
||||
$this->removeExceptionLogger();
|
||||
throw new \Exception('Escaped content: <p> <br> <h3>');
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an exception.
|
||||
*
|
||||
|
@ -115,4 +119,14 @@ class TestControllers {
|
|||
throw new \Exception($message);
|
||||
}
|
||||
|
||||
protected function removeExceptionLogger() {
|
||||
// Remove the exception logger from the event dispatcher. We are going to
|
||||
// throw an exception to check if it is properly escaped when rendered as a
|
||||
// backtrace. The exception logger does a call to error_log() which is not
|
||||
// handled by the Simpletest error handler and would cause a test failure.
|
||||
$event_dispatcher = \Drupal::service('event_dispatcher');
|
||||
$exception_logger = \Drupal::service('exception.logger');
|
||||
$event_dispatcher->removeSubscriber($exception_logger);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,5 +26,9 @@ class ServiceProviderTestServiceProvider implements ServiceModifierInterface {
|
|||
if ($indicator = Settings::get('deployment_identifier')) {
|
||||
$container->setParameter('container_rebuild_indicator', $indicator);
|
||||
}
|
||||
|
||||
if ($parameter = Settings::get('container_rebuild_test_parameter')) {
|
||||
$container->setParameter('container_rebuild_test_parameter', $parameter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,6 +51,9 @@ class TestClass implements EventSubscriberInterface, DestructableInterface, Cont
|
|||
if ($this->container->hasParameter('container_rebuild_indicator')) {
|
||||
$event->getResponse()->headers->set('container_rebuild_indicator', $this->container->getParameter('container_rebuild_indicator'));
|
||||
}
|
||||
if ($this->container->hasParameter('container_rebuild_test_parameter')) {
|
||||
$event->getResponse()->headers->set('container_rebuild_test_parameter', $this->container->getParameter('container_rebuild_test_parameter'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -3,6 +3,8 @@ session_test.get:
|
|||
defaults:
|
||||
_title: 'Session value'
|
||||
_controller: '\Drupal\session_test\Controller\SessionTestController::get'
|
||||
options:
|
||||
no_cache: TRUE
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
session_test.get_from_session_object:
|
||||
|
@ -10,6 +12,8 @@ session_test.get_from_session_object:
|
|||
defaults:
|
||||
_title: 'Session value'
|
||||
_controller: '\Drupal\session_test\Controller\SessionTestController::getFromSessionObject'
|
||||
options:
|
||||
no_cache: TRUE
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
session_test.id:
|
||||
|
@ -17,6 +21,8 @@ session_test.id:
|
|||
defaults:
|
||||
_title: 'Session ID'
|
||||
_controller: '\Drupal\session_test\Controller\SessionTestController::getId'
|
||||
options:
|
||||
no_cache: TRUE
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
|
@ -34,6 +40,7 @@ session_test.set:
|
|||
_title: 'Set session value'
|
||||
_controller: '\Drupal\session_test\Controller\SessionTestController::set'
|
||||
options:
|
||||
no_cache: TRUE
|
||||
converters:
|
||||
test_value: '\s+'
|
||||
requirements:
|
||||
|
@ -45,6 +52,7 @@ session_test.no_set:
|
|||
_title: 'Set session value but do not save session'
|
||||
_controller: '\Drupal\session_test\Controller\SessionTestController::noSet'
|
||||
options:
|
||||
no_cache: TRUE
|
||||
converters:
|
||||
test_value: '\s+'
|
||||
requirements:
|
||||
|
@ -96,6 +104,7 @@ session_test.get_session_basic_auth:
|
|||
_title: 'Get session information using basic authentication'
|
||||
_controller: '\Drupal\session_test\Controller\SessionTestController::getSession'
|
||||
options:
|
||||
no_cache: TRUE
|
||||
_auth: ['basic_auth']
|
||||
requirements:
|
||||
_permission: 'administer site configuration'
|
||||
|
@ -105,6 +114,8 @@ session_test.get_session_no_auth:
|
|||
defaults:
|
||||
_title: 'Get session information'
|
||||
_controller: '\Drupal\session_test\Controller\SessionTestController::getSession'
|
||||
options:
|
||||
no_cache: TRUE
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
|
@ -114,6 +125,7 @@ session_test.set_session:
|
|||
_title: 'Set a session value using basic authentication'
|
||||
_controller: '\Drupal\session_test\Controller\SessionTestController::setSession'
|
||||
options:
|
||||
no_cache: TRUE
|
||||
_auth: ['basic_auth']
|
||||
converters:
|
||||
test_value: '\s+'
|
||||
|
|
|
@ -75,7 +75,7 @@ class SessionTestController extends ControllerBase {
|
|||
* A notification message with session ID.
|
||||
*/
|
||||
public function getIdFromCookie(Request $request) {
|
||||
return ['#markup' => 'session_id:' . $request->cookies->get(session_name()) . "\n"];
|
||||
return ['#markup' => 'session_id:' . $request->cookies->get(session_name()) . "\n", '#cache' => ['contexts' => ['cookies:' . session_name()]]];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
pet llamas:
|
||||
title: 'Pet llamas'
|
||||
description: 'Petting of llamas.'
|
|
@ -1,6 +1,20 @@
|
|||
<?php
|
||||
|
||||
use Drupal\Core\Extension\Extension;
|
||||
use Drupal\Core\Routing\RouteMatchInterface;
|
||||
|
||||
/**
|
||||
* Implements hook_help().
|
||||
*/
|
||||
function system_test_help($route_name, RouteMatchInterface $route_match) {
|
||||
switch ($route_name) {
|
||||
case 'help.page.system_test':
|
||||
$output = '';
|
||||
$output .= '<h3>' . t('Test Help Page') . '</h3>';
|
||||
$output .= '<p>' . t('This is a test help page for the system_test module for the purpose of testing if the "Help" link displays properly.') . '</p>';
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_modules_installed().
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
system test:
|
||||
title: 'Administer system test'
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
namespace Drupal\test_page_test\Controller;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
|
||||
/**
|
||||
* Defines a test controller for page titles.
|
||||
*/
|
||||
|
@ -49,6 +51,26 @@ class Test {
|
|||
return 'Dynamic title';
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines a controller with a cached render array.
|
||||
*
|
||||
* @param bool $mark_safe
|
||||
* Whether or not to mark the title as safe use SafeMarkup::checkPlain.
|
||||
*
|
||||
* @return array
|
||||
* A render array
|
||||
*/
|
||||
public function controllerWithCache($mark_safe = FALSE) {
|
||||
$build = [];
|
||||
$build['#title'] = '<span>Cached title</span>';
|
||||
if ($mark_safe) {
|
||||
$build['#title'] = SafeMarkup::checkPlain($build['#title']);
|
||||
}
|
||||
$build['#cache']['keys'] = ['test_controller', 'with_title', $mark_safe];
|
||||
|
||||
return $build;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a generic page render array for title tests.
|
||||
*
|
||||
|
|
|
@ -21,6 +21,21 @@ test_page_test.static_title:
|
|||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
test_page_test.cached_controller:
|
||||
path: '/test-page-cached-controller'
|
||||
defaults:
|
||||
_controller: '\Drupal\test_page_test\Controller\Test::controllerWithCache'
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
test_page_test.cached_controller.safe:
|
||||
path: '/test-page-cached-controller-safe'
|
||||
defaults:
|
||||
_controller: '\Drupal\test_page_test\Controller\Test::controllerWithCache'
|
||||
mark_safe: true
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
test_page_test.dynamic_title:
|
||||
path: '/test-page-dynamic-title'
|
||||
defaults:
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\token_test\Controller\TestController.
|
||||
*/
|
||||
|
||||
namespace Drupal\token_test\Controller;
|
||||
|
||||
|
||||
use Drupal\Core\Controller\ControllerBase;
|
||||
use Drupal\Core\Render\BubbleableMetadata;
|
||||
use Drupal\Core\Utility\Token;
|
||||
use Drupal\node\NodeInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Provides a test controller for token replacement.
|
||||
*/
|
||||
class TestController extends ControllerBase {
|
||||
|
||||
/**
|
||||
* The token replacement system.
|
||||
*
|
||||
* @var \Drupal\Core\Utility\Token
|
||||
*/
|
||||
protected $token;
|
||||
|
||||
/**
|
||||
* Constructs a new TestController instance.
|
||||
*
|
||||
* @param \Drupal\Core\Utility\Token $token
|
||||
* The token replacement system.
|
||||
*/
|
||||
public function __construct(Token $token) {
|
||||
$this->token = $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static($container->get('token'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a token replacement with a node as well as the current user.
|
||||
*
|
||||
* This controller passes an explicit bubbleable metadata object to
|
||||
* $this->token->replace(), and applies the collected metadata to the render
|
||||
* array being built.
|
||||
*
|
||||
* @param \Drupal\node\NodeInterface $node
|
||||
* The node.
|
||||
*
|
||||
* @return array
|
||||
* The render array.
|
||||
*/
|
||||
public function tokenReplace(NodeInterface $node) {
|
||||
$bubbleable_metadata = new BubbleableMetadata();
|
||||
$build['#markup'] = $this->token->replace('Tokens: [node:nid] [current-user:uid]', ['node' => $node], [], $bubbleable_metadata);
|
||||
$bubbleable_metadata->applyTo($build);
|
||||
|
||||
return $build;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a token replacement with a node as well as the current user.
|
||||
*
|
||||
* This controller is for testing the token service's fallback behavior of
|
||||
* applying collected metadata to the currently active render context when an
|
||||
* explicit bubbleable metadata object isn't passed in.
|
||||
*
|
||||
* @param \Drupal\node\NodeInterface $node
|
||||
* The node.
|
||||
*
|
||||
* @return array
|
||||
* The render array.
|
||||
*/
|
||||
public function tokenReplaceWithoutPassedBubbleableMetadata(NodeInterface $node) {
|
||||
$build['#markup'] = $this->token->replace('Tokens: [node:nid] [current-user:uid]', ['node' => $node], []);
|
||||
|
||||
return $build;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
name: Token test
|
||||
type: module
|
||||
core: 8.x
|
||||
package: Testing
|
||||
version: VERSION
|
||||
dependencies:
|
||||
- user
|
||||
- node
|
|
@ -0,0 +1,12 @@
|
|||
token_test.test:
|
||||
path: token-test/{node}
|
||||
defaults:
|
||||
_controller: Drupal\token_test\Controller\TestController::tokenReplace
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
token_test.test_without_bubbleable_metadata:
|
||||
path: token-test-without-bubleable-metadata/{node}
|
||||
defaults:
|
||||
_controller: Drupal\token_test\Controller\TestController::tokenReplaceWithoutPassedBubbleableMetadata
|
||||
requirements:
|
||||
_access: 'TRUE'
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
namespace Drupal\twig_theme_test;
|
||||
|
||||
use Drupal\Core\Template\Attribute;
|
||||
use Drupal\Core\Url;
|
||||
|
||||
/**
|
||||
|
@ -53,11 +54,14 @@ class TwigThemeTestController {
|
|||
* Renders for testing link_generator functions in a Twig template.
|
||||
*/
|
||||
public function linkGeneratorRender() {
|
||||
return array(
|
||||
return [
|
||||
'#theme' => 'twig_theme_test_link_generator',
|
||||
'#test_url' => new Url('user.register', [], ['absolute' => TRUE]),
|
||||
'#test_url_attribute' => new Url('user.register', [], ['attributes' => ['foo' => 'bar']]),
|
||||
);
|
||||
// Explicitly creating an Attribute object to avoid false positives when
|
||||
// testing Attribute object merging with the twig link() function.
|
||||
'#attributes' => new Attribute(['class' => ['llama', 'kitten', 'panda']]),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,3 +2,4 @@
|
|||
<div>link via the linkgenerator: {{ link('register', test_url, {'foo': 'bar'}) }}</div>
|
||||
<div>link via the linkgenerator: {{ link('register', test_url_attribute, {'id': 'kitten'}) }}</div>
|
||||
<div>link via the linkgenerator: {{ link('register', 'route:user.register', {'id': 'kitten'}) }}</div>
|
||||
<div>link via the linkgenerator: {{ link('register', 'route:user.register', attributes) }}</div>
|
||||
|
|
|
@ -43,7 +43,11 @@ function twig_theme_test_theme($existing, $type, $theme, $path) {
|
|||
'template' => 'twig_theme_test.url_generator',
|
||||
);
|
||||
$items['twig_theme_test_link_generator'] = array(
|
||||
'variables' => array('test_url' => NULL, 'test_url_attribute' => NULL),
|
||||
'variables' => [
|
||||
'test_url' => NULL,
|
||||
'test_url_attribute' => NULL,
|
||||
'attributes' => [],
|
||||
],
|
||||
'template' => 'twig_theme_test.link_generator',
|
||||
);
|
||||
$items['twig_theme_test_url_to_string'] = array(
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
name: 'Update order test'
|
||||
type: module
|
||||
description: 'Support module for update testing.'
|
||||
package: Testing
|
||||
version: VERSION
|
||||
core: 8.x
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Update hooks for the update_order_test module.
|
||||
*/
|
||||
|
||||
use Drupal\Core\Entity\EntityDefinitionUpdateManagerInterface;
|
||||
|
||||
/**
|
||||
* Only declare the update hooks once the test is running.
|
||||
*
|
||||
* @see \Drupal\system\Tests\Entity\Update\SqlContentEntityStorageSchemaIndexTest
|
||||
*/
|
||||
if (\Drupal::state()->get('update_order_test', FALSE)) {
|
||||
|
||||
/**
|
||||
* Runs before entity schema updates.
|
||||
*/
|
||||
function update_order_test_update_8001() {
|
||||
// Store whether the node__default_langcode index exists when this hook is
|
||||
// invoked.
|
||||
\Drupal::state()->set('update_order_test_update_8001', db_index_exists('node_field_data', 'node__default_langcode'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs before entity schema updates.
|
||||
*/
|
||||
function update_order_test_update_8002() {
|
||||
// Check and store whether the update_order_test field exists when this
|
||||
// hook is first invoked.
|
||||
\Drupal::state()->set('update_order_test_update_8002_update_order_test_before', db_field_exists('node_field_data', 'update_order_test'));
|
||||
|
||||
// Attempt to apply the update for the update_order_test field and then
|
||||
// check and store again whether it exists.
|
||||
if (\Drupal::service('entity.definition_update_manager')->applyFieldUpdate(EntityDefinitionUpdateManagerInterface::DEFINITION_CREATED, 'node', 'update_order_test')) {
|
||||
\Drupal::state()->set('update_order_test_update_8002_update_order_test_after', db_field_exists('node_field_data', 'update_order_test'));
|
||||
}
|
||||
|
||||
// Attempt to apply all node entity type updates.
|
||||
if (\Drupal::service('entity.definition_update_manager')->applyEntityUpdate(EntityDefinitionUpdateManagerInterface::DEFINITION_UPDATED, 'node')) {
|
||||
// Node updates have now run. Check and store whether the updated node
|
||||
// indices now exist.
|
||||
\Drupal::state()->set('update_order_test_update_8002_node__default_langcode', db_index_exists('node_field_data', 'node__default_langcode'));
|
||||
\Drupal::state()->set('update_order_test_update_8002_node__id__default_langcode__langcode', db_index_exists('node_field_data', 'node__id__default_langcode__langcode'));
|
||||
|
||||
// User updates have not yet run. Check and store whether the updated
|
||||
// user indices now exist.
|
||||
\Drupal::state()->set('update_order_test_update_8002_user__id__default_langcode__langcode', db_index_exists('users_field_data', 'user__id__default_langcode__langcode'));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Hooks for the update_order_test module.
|
||||
*/
|
||||
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Field\BaseFieldDefinition;
|
||||
|
||||
/**
|
||||
* Only declare the new entity base field once the test is running.
|
||||
*/
|
||||
if (\Drupal::state()->get('update_order_test', FALSE)) {
|
||||
|
||||
/**
|
||||
* Implements hook_entity_base_field_info().
|
||||
*/
|
||||
function update_order_test_entity_base_field_info(EntityTypeInterface $entity_type) {
|
||||
if ($entity_type->id() === 'node') {
|
||||
$fields['update_order_test'] = BaseFieldDefinition::create('integer')
|
||||
->setLabel(t('Update order test'));
|
||||
return $fields;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -7,9 +7,9 @@
|
|||
|
||||
namespace Drupal\url_alter_test;
|
||||
|
||||
use Drupal\Core\Cache\CacheableMetadata;
|
||||
use Drupal\Core\PathProcessor\InboundPathProcessorInterface;
|
||||
use Drupal\Core\PathProcessor\OutboundPathProcessorInterface;
|
||||
use Drupal\Core\Render\BubbleableMetadata;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Drupal\user\Entity\User;
|
||||
|
||||
|
@ -44,14 +44,14 @@ class PathProcessorTest implements InboundPathProcessorInterface, OutboundPathPr
|
|||
/**
|
||||
* Implements Drupal\Core\PathProcessor\OutboundPathProcessorInterface::processOutbound().
|
||||
*/
|
||||
public function processOutbound($path, &$options = array(), Request $request = NULL, CacheableMetadata $cacheable_metadata = NULL) {
|
||||
public function processOutbound($path, &$options = array(), Request $request = NULL, BubbleableMetadata $bubbleable_metadata = NULL) {
|
||||
// Rewrite user/uid to user/username.
|
||||
if (preg_match('!^/user/([0-9]+)(/.*)?!', $path, $matches)) {
|
||||
if ($account = User::load($matches[1])) {
|
||||
$matches += array(2 => '');
|
||||
$path = '/user/' . $account->getUsername() . $matches[2];
|
||||
if ($cacheable_metadata) {
|
||||
$cacheable_metadata->addCacheTags($account->getCacheTags());
|
||||
if ($bubbleable_metadata) {
|
||||
$bubbleable_metadata->addCacheTags($account->getCacheTags());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Tests\system\Unit\Migrate\source\d6\MenuTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\system\Unit\Migrate\source\d6;
|
||||
|
||||
use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
|
||||
|
||||
/**
|
||||
* Tests D6 menu source plugin.
|
||||
*
|
||||
* @group system
|
||||
*/
|
||||
class MenuTest extends MigrateSqlSourceTestCase {
|
||||
|
||||
// The plugin system is not working during unit testing so the source plugin
|
||||
// class needs to be manually specified.
|
||||
const PLUGIN_CLASS = 'Drupal\system\Plugin\migrate\source\d6\Menu';
|
||||
|
||||
// The fake Migration configuration entity.
|
||||
protected $migrationConfiguration = array(
|
||||
// The ID of the entity, can be any string.
|
||||
'id' => 'test',
|
||||
// Leave it empty for now.
|
||||
'idlist' => array(),
|
||||
// This needs to be the identifier of the actual key: cid for comment, nid
|
||||
// for node and so on.
|
||||
'source' => array(
|
||||
'plugin' => 'd6_menu',
|
||||
),
|
||||
);
|
||||
|
||||
// We need to set up the database contents; it's easier to do that below.
|
||||
|
||||
protected $expectedResults = array(
|
||||
array(
|
||||
'menu_name' => 'menu-name-1',
|
||||
'title' => 'menu custom value 1',
|
||||
'description' => 'menu custom description value 1',
|
||||
),
|
||||
array(
|
||||
'menu_name' => 'menu-name-2',
|
||||
'title' => 'menu custom value 2',
|
||||
'description' => 'menu custom description value 2',
|
||||
),
|
||||
);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
// This array stores the database.
|
||||
foreach ($this->expectedResults as $k => $row) {
|
||||
$this->databaseContents['menu_custom'][$k] = $row;
|
||||
}
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
}
|
|
@ -50,6 +50,13 @@ class MachineNameControllerTest extends UnitTestCase {
|
|||
array(array('text' => 'Bob', 'langcode' => 'en', 'replace' => 'Alice', 'replace_pattern' => 'Tom'), '"Bob"'),
|
||||
array(array('text' => 'Äwesome', 'langcode' => 'en', 'lowercase' => TRUE), '"awesome"'),
|
||||
array(array('text' => 'Äwesome', 'langcode' => 'de', 'lowercase' => TRUE), '"aewesome"'),
|
||||
// Tests special characters replacement in the input text.
|
||||
array(array('text' => 'B?!"@\/-ob@e', 'langcode' => 'en', 'lowercase' => TRUE, 'replace' => '_', 'replace_pattern' => '[^a-z0-9_.]+'), '"b_ob_e"'),
|
||||
// Tests @ character in the replace_pattern regex.
|
||||
array(array('text' => 'Bob@e\0', 'langcode' => 'en', 'lowercase' => TRUE, 'replace' => '_', 'replace_pattern' => '[^a-z0-9_.@]+'), '"bob@e_0"'),
|
||||
// Tests null byte in the replace_pattern regex.
|
||||
array(array('text' => 'Bob', 'langcode' => 'en', 'lowercase' => TRUE, 'replace' => 'fail()', 'replace_pattern' => ".*@e\0"), '"bob"'),
|
||||
array(array('text' => 'Bob@e', 'langcode' => 'en', 'lowercase' => TRUE, 'replace' => 'fail()', 'replace_pattern' => ".*@e\0"), '"fail()"'),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
name: 'Theme test with invalid core version'
|
||||
type: theme
|
||||
description: 'Test theme which has an invalid core version.'
|
||||
version: VERSION
|
||||
core: 7.x
|
|
@ -0,0 +1,8 @@
|
|||
name: 'Theme test with missing content region'
|
||||
type: theme
|
||||
description: 'Test theme which has a non-existent content region.'
|
||||
version: VERSION
|
||||
core: 8.x
|
||||
|
||||
regions:
|
||||
- foo: Foo
|
Reference in a new issue