Update to drupal 8.0.0-rc1. For more information, see https://www.drupal.org/node/2582663

This commit is contained in:
Greg Anderson 2015-10-08 11:40:12 -07:00
parent eb34d130a8
commit f32e58e4b1
8476 changed files with 211648 additions and 170042 deletions

View file

@ -1,3 +1,5 @@
name: Accept header based routing test
core: 8.x
type: module
package: Testing
version: VERSION

View file

@ -40,6 +40,11 @@ class BatchTestMultiStepForm extends FormBase {
'#value' => 'Submit',
);
// This is a POST form with multiple steps that does not transition from one
// step to the next via POST requests, but via GET requests, because it uses
// Batch API to advance through the steps.
$form['#cache']['max-age'] = 0;
return $form;
}

View file

@ -22,7 +22,7 @@ class CacheTestController {
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()])
'#markup' => 'This URL is early-rendered: ' . $url->toString() . '. Yet, its bubbleable metadata should be bubbled.',
];
}

View file

@ -19,7 +19,8 @@ class CommonTestController {
/**
* Returns links to the current page, with and without query strings.
*
* Using #type 'link' causes these links to be rendered with _l().
* Using #type 'link' causes these links to be rendered with the link
* generator.
*/
public function typeLinkActiveClass() {
return array(

View file

@ -72,7 +72,7 @@ class ConditionTestDualUserTest extends KernelTestBase {
'user2' => 'anonymous',
]);
$definition = new ContextDefinition('entity:user');
$contexts['anonymous'] = (new Context($definition))->setContextValue($this->anonymous);
$contexts['anonymous'] = new Context($definition, $this->anonymous);
\Drupal::service('context.handler')->applyContextMapping($condition, $contexts);
$this->assertTrue($condition->execute());
}
@ -89,8 +89,8 @@ class ConditionTestDualUserTest extends KernelTestBase {
'user2' => 'authenticated',
]);
$definition = new ContextDefinition('entity:user');
$contexts['anonymous'] = (new Context($definition))->setContextValue($this->anonymous);
$contexts['authenticated'] = (new Context($definition))->setContextValue($this->authenticated);
$contexts['anonymous'] = new Context($definition, $this->anonymous);
$contexts['authenticated'] = new Context($definition, $this->authenticated);
\Drupal::service('context.handler')->applyContextMapping($condition, $contexts);
$this->assertFalse($condition->execute());
}

View file

@ -10,6 +10,7 @@ namespace Drupal\condition_test\Tests;
use Drupal\Core\Plugin\Context\Context;
use Drupal\Core\Plugin\Context\ContextDefinition;
use Drupal\node\Entity\Node;
use Drupal\node\Entity\NodeType;
use Drupal\simpletest\KernelTestBase;
/**
@ -58,6 +59,7 @@ class OptionalContextConditionTest extends KernelTestBase {
* Tests with both contexts mapped to the same user.
*/
protected function testContextAvailable() {
NodeType::create(['type' => 'example', 'name' => 'Example'])->save();
/** @var \Drupal\Core\Condition\ConditionPluginBase $condition */
$condition = \Drupal::service('plugin.manager.condition')
->createInstance('condition_test_optional_context')
@ -66,7 +68,7 @@ class OptionalContextConditionTest extends KernelTestBase {
]);
$definition = new ContextDefinition('entity:node');
$node = Node::create(['type' => 'example']);
$contexts['node'] = (new Context($definition))->setContextValue($node);
$contexts['node'] = new Context($definition, $node);
\Drupal::service('context.handler')->applyContextMapping($condition, $contexts);
$this->assertFalse($condition->execute());
}

View file

@ -290,5 +290,7 @@ function database_test_schema() {
'primary key' => array('id'),
);
$schema['TEST_UPPERCASE'] = $schema['test'];
return $schema;
}

View file

@ -7,6 +7,8 @@
namespace Drupal\display_variant_test\EventSubscriber;
use Drupal\Core\Plugin\Context\Context;
use Drupal\Core\Plugin\Context\ContextDefinition;
use Drupal\Core\Render\PageDisplayVariantSelectionEvent;
use Drupal\Core\Render\RenderEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
@ -25,6 +27,10 @@ class TestPageDisplayVariantSubscriber implements EventSubscriberInterface {
public function onSelectPageDisplayVariant(PageDisplayVariantSelectionEvent $event) {
$event->setPluginId('display_variant_test');
$event->setPluginConfiguration(['required_configuration' => 'A very important, required value.']);
$event->addCacheTags(['custom_cache_tag']);
$context = new Context(new ContextDefinition('string', NULL, TRUE), 'Explicitly passed in context.');
$event->setContexts(['context' => $context]);
}
/**

View file

@ -7,8 +7,10 @@
namespace Drupal\display_variant_test\Plugin\DisplayVariant;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Display\VariantBase;
use Drupal\Core\Display\PageVariantInterface;
use Drupal\Core\Display\ContextAwareVariantInterface;
/**
* Provides a display variant that requires configuration.
@ -18,7 +20,7 @@ use Drupal\Core\Display\PageVariantInterface;
* admin_label = @Translation("Test display variant")
* )
*/
class TestDisplayVariant extends VariantBase implements PageVariantInterface {
class TestDisplayVariant extends VariantBase implements PageVariantInterface, ContextAwareVariantInterface {
/**
* The render array representing the main page content.
@ -27,6 +29,45 @@ class TestDisplayVariant extends VariantBase implements PageVariantInterface {
*/
protected $mainContent = [];
/**
* The page title: a string (plain title) or a render array (formatted title).
*
* @var string|array
*/
protected $title = '';
/**
* An array of collected contexts.
*
* This is only used on runtime, and is not stored.
*
* @var \Drupal\Component\Plugin\Context\ContextInterface[]
*/
protected $contexts = [];
/**
* Gets the contexts.
*
* @return \Drupal\Component\Plugin\Context\ContextInterface[]
* An array of set contexts, keyed by context name.
*/
public function getContexts() {
return $this->contexts;
}
/**
* Sets the contexts.
*
* @param \Drupal\Component\Plugin\Context\ContextInterface[] $contexts
* An array of contexts, keyed by context name.
*
* @return $this
*/
public function setContexts(array $contexts) {
$this->contexts = $contexts;
return $this;
}
/**
* {@inheritdoc}
*/
@ -35,6 +76,14 @@ class TestDisplayVariant extends VariantBase implements PageVariantInterface {
return $this;
}
/**
* {@inheritdoc}
*/
public function setTitle($title) {
$this->title = $title;
return $this;
}
/**
* {@inheritdoc}
*/
@ -44,10 +93,18 @@ class TestDisplayVariant extends VariantBase implements PageVariantInterface {
throw new \Exception('Required configuration is missing!');
}
$contexts = $this->getContexts();
if (!isset($contexts['context'])) {
throw new \Exception('Required context is missing!');
}
$build = [];
$build['content']['default'] = [
'#markup' => $config['required_configuration'],
'#markup' => $config['required_configuration'] . ' ' . $contexts['context']->getContextValue(),
];
CacheableMetadata::createFromObject($this)->applyTo($build);
return $build;
}

View file

@ -0,0 +1,125 @@
langcode: en
status: true
dependencies:
module:
- entity_reference_test
- node
- user
id: test_entity_reference
label: 'Entity reference'
module: entity_reference_test
description: ''
tag: ''
base_table: node_field_data
base_field: nid
core: '8'
display:
default:
display_plugin: default
id: default
display_title: Master
position: null
display_options:
access:
type: perm
cache:
type: tag
query:
type: views_query
exposed_form:
type: basic
pager:
type: full
style:
type: default
row:
type: fields
fields:
title:
id: title
table: node_field_data
field: title
relationship: none
group_type: group
admin_label: ''
label: ''
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: false
ellipsis: false
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: false
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
plugin_id: field
entity_type: node
entity_field: title
filters:
status:
value: true
table: node_field_data
field: status
id: status
expose:
operator: ''
group: 1
plugin_id: boolean
entity_type: node
entity_field: status
sorts:
created:
id: created
table: node_field_data
field: created
order: DESC
plugin_id: date
entity_type: node
entity_field: created
entity_reference_1:
display_plugin: entity_reference
id: entity_reference_1
display_title: EntityReference
position: null
display_options:
style:
type: entity_reference
options:
grouping: { }
search_fields:
title: title
pager:
type: none
options:
offset: 0

View file

@ -0,0 +1,120 @@
langcode: en
status: true
dependencies:
module:
- entity_reference_test
- entity_test
id: test_entity_reference_entity_test
label: 'Entity reference'
module: views
description: ''
tag: ''
base_table: entity_test
base_field: id
core: 8.x
display:
default:
display_plugin: default
id: default
display_title: Master
position: 0
display_options:
access:
type: none
cache:
type: tag
query:
type: views_query
exposed_form:
type: basic
pager:
type: full
style:
type: default
row:
type: fields
fields:
name:
table: entity_test
field: name
id: name
entity_type: null
entity_field: name
plugin_id: field
relationship: none
group_type: group
admin_label: ''
label: ''
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
click_sort_column: value
type: string
settings: { }
group_column: value
group_columns: { }
group_rows: true
delta_limit: 0
delta_offset: 0
delta_reversed: false
delta_first_last: false
multi_type: separator
separator: ', '
field_api_classes: false
filters: { }
sorts: { }
header: { }
footer: { }
empty: { }
relationships: { }
arguments: { }
display_extenders: { }
entity_reference_1:
display_plugin: entity_reference
id: entity_reference_1
display_title: EntityReference
position: null
display_options:
display_extenders: { }
style:
type: entity_reference
options:
search_fields:
name: name

View file

@ -0,0 +1,11 @@
name: "Entity Reference Test"
type: module
description: "Support module for the Entity Reference tests."
core: 8.x
package: Testing
version: VERSION
dependencies:
- node
- user
- views
- entity_test

View file

@ -0,0 +1,42 @@
<?php
/**
* @file
* Helper module for the Entity Reference tests.
*/
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
/**
* Implements hook_entity_base_field_info().
*/
function entity_reference_test_entity_base_field_info(EntityTypeInterface $entity_type) {
$fields = array();
if ($entity_type->id() === 'entity_test') {
$fields['user_role'] = BaseFieldDefinition::create('entity_reference')
->setLabel(t('User role'))
->setDescription(t('The role of the associated user.'))
->setSetting('target_type', 'user_role')
->setSetting('handler', 'default');
}
return $fields;
}
/**
* Implements hook_entity_base_field_info_alter().
*/
function entity_reference_test_entity_base_field_info_alter(&$fields, EntityTypeInterface $entity_type) {
if ($entity_type->id() === 'entity_test') {
// Allow user_id field to use configurable widget.
$fields['user_id']
->setSetting('handler', 'default')
->setDisplayOptions('form', array(
'type' => 'entity_reference_autocomplete',
'weight' => 0,
))
->setDisplayConfigurable('form', TRUE);
}
}

View file

@ -0,0 +1,8 @@
name: 'Entity reference test views'
type: module
description: 'Provides default views for views entity reference tests.'
package: Testing
version: VERSION
core: 8.x
dependencies:
- views

View file

@ -0,0 +1,120 @@
langcode: en
status: true
dependencies:
module:
- entity_test
id: test_entity_reference_entity_test_mul_view
label: test_entity_reference_entity_test_mul_view
module: views
description: ''
tag: ''
base_table: entity_test_mul_property_data
base_field: id
core: 8.x
display:
default:
display_plugin: default
id: default
display_title: Master
position: 0
display_options:
access:
type: none
options: { }
cache:
type: tag
options: { }
query:
type: views_query
options:
disable_sql_rewrite: false
distinct: false
replica: false
query_comment: ''
query_tags: { }
exposed_form:
type: basic
options:
submit_button: Apply
reset_button: false
reset_button_label: Reset
exposed_sorts_label: 'Sort by'
expose_sort_order: true
sort_asc_label: Asc
sort_desc_label: Desc
pager:
type: full
options:
items_per_page: 10
offset: 0
id: 0
total_pages: null
expose:
items_per_page: false
items_per_page_label: 'Items per page'
items_per_page_options: '5, 10, 25, 50'
items_per_page_options_all: false
items_per_page_options_all_label: '- All -'
offset: false
offset_label: Offset
tags:
previous: ' Previous'
next: 'Next '
first: '« First'
last: 'Last »'
quantity: 9
style:
type: default
options:
grouping: { }
row_class: ''
default_row_class: true
uses_fields: false
row:
type: fields
options:
inline: { }
separator: ''
hide_empty: false
default_field_elements: true
fields:
id:
id: id
table: entity_test_mul_property_data
field: id
entity_type: entity_test_mul
entity_field: id
plugin_id: field
id_1:
id: id_1
table: entity_test
field: id
entity_type: entity_test
entity_field: id
plugin_id: field
relationship: field_data_test
filters: { }
sorts:
id:
id: id
table: entity_test_mul_property_data
field: id
entity_type: entity_test_mul
entity_field: id
plugin_id: standard
header: { }
footer: { }
empty: { }
relationships:
field_data_test:
id: field_data_test
table: entity_test_mul__field_data_test
field: field_data_test
plugin_id: standard
arguments: { }
display_extenders: { }
cache_metadata:
contexts:
- languages
- 'languages:language_interface'
max-age: 0

View file

@ -0,0 +1,121 @@
langcode: en
status: true
dependencies:
module:
- entity_test
id: test_entity_reference_entity_test_view
label: test_entity_reference_entity_test_view
module: views
description: ''
tag: ''
base_table: entity_test
base_field: id
core: 8.x
display:
default:
display_plugin: default
id: default
display_title: Master
position: 0
display_options:
access:
type: none
options: { }
cache:
type: tag
options: { }
query:
type: views_query
options:
disable_sql_rewrite: false
distinct: false
replica: false
query_comment: ''
query_tags: { }
exposed_form:
type: basic
options:
submit_button: Apply
reset_button: false
reset_button_label: Reset
exposed_sorts_label: 'Sort by'
expose_sort_order: true
sort_asc_label: Asc
sort_desc_label: Desc
pager:
type: full
options:
items_per_page: 10
offset: 0
id: 0
total_pages: null
expose:
items_per_page: false
items_per_page_label: 'Items per page'
items_per_page_options: '5, 10, 25, 50'
items_per_page_options_all: false
items_per_page_options_all_label: '- All -'
offset: false
offset_label: Offset
tags:
previous: ' Previous'
next: 'Next '
first: '« First'
last: 'Last »'
quantity: 9
style:
type: default
options:
grouping: { }
row_class: ''
default_row_class: true
uses_fields: false
row:
type: fields
options:
inline: { }
separator: ''
hide_empty: false
default_field_elements: true
fields:
id:
id: id
table: entity_test
field: id
entity_type: entity_test
entity_field: id
plugin_id: field
id_1:
id: id_1
table: entity_test_mul
field: id
entity_type: entity_test_mul
entity_field: id
plugin_id: field
relationship: field_test_data
filters: { }
sorts:
id:
id: id
table: entity_test
field: id
entity_type: entity_test
entity_field: id
plugin_id: standard
header: { }
footer: { }
empty: { }
relationships:
field_test_data:
id: field_test_data
table: entity_test__field_test_data
field: field_test_data
plugin_id: standard
arguments: { }
display_extenders: { }
cache_metadata:
contexts:
- entity_test_view_grants
- languages
- 'languages:language_interface'
max-age: 0

View file

@ -0,0 +1,130 @@
langcode: en
status: true
dependencies:
module:
- entity_test
id: test_entity_reference_reverse_entity_test_mul_view
label: test_entity_reference_reverse_entity_test_mul_view
module: views
description: ''
tag: ''
base_table: entity_test
base_field: id
core: 8.x
display:
default:
display_plugin: default
id: default
display_title: Master
position: 0
display_options:
access:
type: none
options: { }
cache:
type: tag
options: { }
query:
type: views_query
options:
disable_sql_rewrite: false
distinct: false
replica: false
query_comment: ''
query_tags: { }
exposed_form:
type: basic
options:
submit_button: Apply
reset_button: false
reset_button_label: Reset
exposed_sorts_label: 'Sort by'
expose_sort_order: true
sort_asc_label: Asc
sort_desc_label: Desc
pager:
type: full
options:
items_per_page: 10
offset: 0
id: 0
total_pages: null
expose:
items_per_page: false
items_per_page_label: 'Items per page'
items_per_page_options: '5, 10, 25, 50'
items_per_page_options_all: false
items_per_page_options_all_label: '- All -'
offset: false
offset_label: Offset
tags:
previous: ' Previous'
next: 'Next '
first: '« First'
last: 'Last »'
quantity: 9
style:
type: default
options:
grouping: { }
row_class: ''
default_row_class: true
uses_fields: false
row:
type: fields
options:
inline: { }
separator: ''
hide_empty: false
default_field_elements: true
fields:
id:
id: id
table: entity_test
field: id
entity_type: entity_test
entity_field: id
plugin_id: field
id_1:
id: id_1
table: entity_test_mul_property_data
field: id
entity_type: entity_test_mul
entity_field: id
plugin_id: field
relationship: reverse__entity_test_mul__field_data_test
filters: { }
sorts:
id:
id: id
table: entity_test
field: id
entity_type: entity_test
entity_field: id
plugin_id: standard
id_1:
id: id_1
table: entity_test_mul_property_data
field: id
entity_type: entity_test_mul
entity_field: id
plugin_id: standard
relationship: reverse__entity_test_mul__field_data_test
header: { }
footer: { }
empty: { }
relationships:
reverse__entity_test_mul__field_data_test:
id: reverse__entity_test_mul__field_data_test
table: entity_test
field: reverse__entity_test_mul__field_data_test
entity_type: entity_test
plugin_id: entity_reverse
arguments: { }
display_extenders: { }
cache_metadata:
contexts:
- entity_test_view_grants
- languages
- 'languages:language_interface'
max-age: 0

View file

@ -0,0 +1,129 @@
langcode: en
status: true
dependencies:
module:
- entity_test
id: test_entity_reference_reverse_entity_test_view
label: test_entity_reference_reverse_entity_test_view
module: views
description: ''
tag: ''
base_table: entity_test_mul_property_data
base_field: id
core: 8.x
display:
default:
display_plugin: default
id: default
display_title: Master
position: 0
display_options:
access:
type: none
options: { }
cache:
type: tag
options: { }
query:
type: views_query
options:
disable_sql_rewrite: false
distinct: false
replica: false
query_comment: ''
query_tags: { }
exposed_form:
type: basic
options:
submit_button: Apply
reset_button: false
reset_button_label: Reset
exposed_sorts_label: 'Sort by'
expose_sort_order: true
sort_asc_label: Asc
sort_desc_label: Desc
pager:
type: full
options:
items_per_page: 10
offset: 0
id: 0
total_pages: null
expose:
items_per_page: false
items_per_page_label: 'Items per page'
items_per_page_options: '5, 10, 25, 50'
items_per_page_options_all: false
items_per_page_options_all_label: '- All -'
offset: false
offset_label: Offset
tags:
previous: ' Previous'
next: 'Next '
first: '« First'
last: 'Last »'
quantity: 9
style:
type: default
options:
grouping: { }
row_class: ''
default_row_class: true
uses_fields: false
row:
type: fields
options:
inline: { }
separator: ''
hide_empty: false
default_field_elements: true
fields:
id:
id: id
table: entity_test_mul_property_data
field: id
entity_type: entity_test_mul
entity_field: id
plugin_id: field
id_1:
id: id_1
table: entity_test
field: id
entity_type: entity_test
entity_field: id
plugin_id: field
relationship: reverse__entity_test__field_test_data
filters: { }
sorts:
id:
id: id
table: entity_test_mul_property_data
field: id
entity_type: entity_test_mul
entity_field: id
plugin_id: standard
id_1:
id: id_1
table: entity_test
field: id
entity_type: entity_test
entity_field: id
plugin_id: standard
relationship: reverse__entity_test__field_test_data
header: { }
footer: { }
empty: { }
relationships:
reverse__entity_test__field_test_data:
id: reverse__entity_test__field_test_data
table: entity_test_mul_property_data
field: reverse__entity_test__field_test_data
entity_type: entity_test_mul
plugin_id: entity_reverse
arguments: { }
display_extenders: { }
cache_metadata:
contexts:
- languages
- 'languages:language_interface'
max-age: 0

View file

@ -7,4 +7,3 @@ core: 8.x
dependencies:
- field
- text
- entity_reference

View file

@ -170,26 +170,6 @@ function entity_test_create_bundle($bundle, $text = NULL, $entity_type = 'entity
\Drupal::entityManager()->onBundleCreate($bundle, $entity_type);
}
/**
* Renames a bundle for entity_test entities.
*
* @param string $bundle_old
* The machine-readable name of the bundle to rename.
* @param string $bundle_new
* The new machine-readable name of the bundle.
* @param string $entity_type
* (optional) The entity type for which the bundle is renamed. Defaults to
* 'entity_test'.
*/
function entity_test_rename_bundle($bundle_old, $bundle_new, $entity_type = 'entity_test') {
$bundles = \Drupal::state()->get($entity_type . '.bundles') ?: array($entity_type => array('label' => 'Entity Test Bundle'));
$bundles[$bundle_new] = $bundles[$bundle_old];
unset($bundles[$bundle_old]);
\Drupal::state()->set($entity_type . '.bundles', $bundles);
\Drupal::entityManager()->onBundleRename($bundle_old, $bundle_new, $entity_type);
}
/**
* Deletes a bundle for entity_test entities.
*
@ -641,7 +621,11 @@ function entity_test_entity_prepare_view($entity_type, array $entities, array $d
/**
* Implements hook_entity_access().
*/
function entity_test_entity_access(EntityInterface $entity, $operation, AccountInterface $account, $langcode) {
function entity_test_entity_access(EntityInterface $entity, $operation, AccountInterface $account) {
// Only apply to the 'entity_test' entities.
if ($entity->getEntityType()->getProvider() != 'entity_test') {
return AccessResult::neutral();
}
\Drupal::state()->set('entity_test_entity_access', TRUE);
// Attempt to allow access to entities with the title forbid_access,
@ -660,7 +644,7 @@ function entity_test_entity_access(EntityInterface $entity, $operation, AccountI
/**
* Implements hook_ENTITY_TYPE_access() for 'entity_test'.
*/
function entity_test_entity_test_access(EntityInterface $entity, $operation, AccountInterface $account, $langcode) {
function entity_test_entity_test_access(EntityInterface $entity, $operation, AccountInterface $account) {
\Drupal::state()->set('entity_test_entity_test_access', TRUE);
// No opinion.

View file

@ -46,12 +46,4 @@ class EntityTestConstraints extends EntityTest implements EntityChangedInterface
return $fields;
}
/**
* {@inheritdoc}
*/
public function getChangedTime() {
return $this->get('changed')->value;
}
}

View file

@ -72,12 +72,4 @@ class EntityTestMulChanged extends EntityTestMul implements EntityChangedInterfa
sleep(1);
parent::save();
}
/**
* {@inheritdoc}
*/
public function getChangedTime() {
return $this->get('changed')->value;
}
}

View file

@ -23,4 +23,11 @@ namespace Drupal\entity_test\Entity;
*/
class EntityTestNoLabel extends EntityTest {
/**
* @{inheritdoc}
*/
public function label() {
return $this->getName();
}
}

View file

@ -29,7 +29,9 @@ class EntityTestAccessControlHandler extends EntityAccessControlHandler {
/**
* {@inheritdoc}
*/
protected function checkAccess(EntityInterface $entity, $operation, $langcode, AccountInterface $account) {
protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
/** @var \Drupal\entity_test\Entity\EntityTest $entity */
// Always forbid access to entities with the label 'forbid_access', used for
// \Drupal\system\Tests\Entity\EntityAccessHControlandlerTest::testDefaultEntityAccess().
if ($entity->label() == 'forbid_access') {
@ -37,7 +39,7 @@ class EntityTestAccessControlHandler extends EntityAccessControlHandler {
}
if ($operation === 'view') {
if ($langcode != LanguageInterface::LANGCODE_DEFAULT) {
if (!$entity->isDefaultTranslation()) {
return AccessResult::allowedIfHasPermission($account, 'view test entity translations');
}
return AccessResult::allowedIfHasPermission($account, 'view test entity');

View file

@ -20,8 +20,8 @@ class EntityTestViewBuilder extends EntityViewBuilder {
/**
* {@inheritdoc}
*/
protected function getBuildDefaults(EntityInterface $entity, $view_mode, $langcode) {
$build = parent::getBuildDefaults($entity, $view_mode, $langcode);
protected function getBuildDefaults(EntityInterface $entity, $view_mode) {
$build = parent::getBuildDefaults($entity, $view_mode);
unset($build['#theme']);
return $build;
}
@ -29,8 +29,8 @@ class EntityTestViewBuilder extends EntityViewBuilder {
/**
* {@inheritdoc}
*/
public function buildComponents(array &$build, array $entities, array $displays, $view_mode, $langcode = NULL) {
parent::buildComponents($build, $entities, $displays, $view_mode, $langcode);
public function buildComponents(array &$build, array $entities, array $displays, $view_mode) {
parent::buildComponents($build, $entities, $displays, $view_mode);
foreach ($entities as $id => $entity) {
$build[$id]['label'] = array(

View file

@ -9,7 +9,7 @@ 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\StringTranslation\TranslatableMarkup;
use Drupal\Core\TypedData\DataDefinition;
use Drupal\Core\TypedData\DataDefinitionInterface;
use Drupal\Core\TypedData\TypedDataInterface;
@ -39,9 +39,9 @@ class FieldTestItem extends FieldItemBase {
*/
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.
// early t() calls by using the TranslatableMarkup.
$properties['value'] = DataDefinition::create('string')
->setLabel(new TranslationWrapper('Test value'))
->setLabel(new TranslatableMarkup('Test value'))
->setRequired(TRUE);
return $properties;

View file

@ -100,6 +100,14 @@ form_test.validate_required_no_title:
requirements:
_access: 'TRUE'
form_test.validate_without_csrf_token:
path: '/form-test/validate-no-token'
defaults:
_form: '\Drupal\form_test\Form\FormTestValidateNoToken'
_title: 'Form validation on forms with a disabled CSRF token'
requirements:
_access: 'TRUE'
form_test.validate_with_error_suppresion:
path: '/form-test/limit-validation-errors'
defaults:
@ -394,6 +402,14 @@ form_test.button_class:
requirements:
_access: 'TRUE'
form_test.details_form:
path: '/form_test/details-form'
defaults:
_form: '\Drupal\form_test\Form\FormTestDetailsForm'
_title: 'Form details form test'
requirements:
_access: 'TRUE'
form_test.description_display:
path: '/form_test/form-descriptions'
defaults:
@ -457,3 +473,10 @@ form_test.form_storage_page_cache:
_title: 'Form storage with page cache test'
requirements:
_access: 'TRUE'
form_test.get_form:
path: '/form-test/get-form'
defaults:
_form: '\Drupal\form_test\Form\FormTestGetForm'
requirements:
_access: 'TRUE'

View file

@ -36,8 +36,8 @@ class FormTestCheckboxesRadiosForm extends FormBase {
0 => 'Zero',
'foo' => 'Foo',
1 => 'One',
'bar' => 'Bar',
'>' => 'Special Char',
'bar' => $this->t('<em>Bar - checkboxes</em>'),
'>' => "<em>Special Char</em><script>alert('checkboxes');</script>",
),
);
if ($customize) {
@ -60,8 +60,8 @@ class FormTestCheckboxesRadiosForm extends FormBase {
0 => 'Zero',
'foo' => 'Foo',
1 => 'One',
'bar' => 'Bar',
'>' => 'Special Char',
'bar' => '<em>Bar - radios</em>',
'>' => "<em>Special Char</em><script>alert('radios');</script>",
),
);
if ($customize) {

View file

@ -0,0 +1,51 @@
<?php
/**
* @file
* Contains \Drupal\form_test\Form\FormTestGroupContainerForm.
*/
namespace Drupal\form_test\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
/**
* Builds a simple form to test the #group property on #type 'container'.
*/
class FormTestDetailsForm extends FormBase {
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'form_test_details_form';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$form['meta'] = [
'#type' => 'details',
'#title' => 'Details element',
'#open' => TRUE,
];
$form['submit'] = ['#type' => 'submit', '#value' => 'Submit'];
return $form;
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
$form_state->setErrorByName('meta', 'I am an error on the details element.');
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
}
}

View file

@ -0,0 +1,44 @@
<?php
/**
* @file
* Contains \Drupal\form_test\Form\FormTestGetForm.
*/
namespace Drupal\form_test\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
/**
* Form to test whether GET forms have a CSRF token.
*/
class FormTestGetForm extends FormBase {
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'form_test_get_form';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$form['#method'] = 'get';
$form['submit'] = [
'#type' => 'submit',
'#value' => 'Save',
];
return $form;
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
drupal_set_message('The form_test_get_form form has been submitted successfully.');
}
}

View file

@ -29,7 +29,7 @@ class FormTestSelectForm extends FormBase {
public function buildForm(array $form, FormStateInterface $form_state) {
$base = array(
'#type' => 'select',
'#options' => array('one' => 'one', 'two' => 'two', 'three' => 'three'),
'#options' => array('one' => 'one', 'two' => 'two', 'three' => 'three', 'four' => '<strong>four</strong>'),
);
$form['select'] = $base + array(

View file

@ -0,0 +1,52 @@
<?php
/**
* @file
* Contains \Drupal\form_test\Form\FormTestTableForm.
*/
namespace Drupal\form_test\Form;
use Drupal\Core\Form\FormStateInterface;
class FormTestTableForm extends FormTestTableSelectFormBase {
/**
* {@inheritdoc}
*/
public function getFormId() {
return '_form_test_table_form';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$form['table'] = [
'#type' => 'table',
'#tableselect' => TRUE,
'#empty' => $this->t('Empty text.'),
];
$form['table']['row'] = [
'data' => [
'#title' => '<em>kitten</em>',
'#markup' => '<p>some text</p>',
],
];
$form['table']['another_row'] = [
'data' => [
'#title' => $this->t('my favourite fruit is <strong>@fruit</strong>', ['@fruit' => 'bananas']),
'#markup' => '<p>some more text</p>',
],
];
return $form;
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
}
}

View file

@ -0,0 +1,44 @@
<?php
/**
* @file
* Contains \Drupal\form_test\Form\FormTestValidateNoToken.
*/
namespace Drupal\form_test\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
/**
* Form to test the validation of forms with a disabled CSRF token.
*/
class FormTestValidateNoToken extends FormBase {
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'form_test_validate_no_token';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$form['#token'] = FALSE;
$form['submit'] = [
'#type' => 'submit',
'#value' => 'Save',
];
return $form;
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
drupal_set_message('The form_test_validate_no_token form has been submitted successfully.');
}
}

View file

@ -33,12 +33,12 @@ class FormTestVerticalTabsForm extends FormBase {
for ($i = 1; $i <= $tab_count; $i++) {
$form['tab' . $i] = array(
'#type' => 'fieldset',
'#title' => t('Tab !num', array('!num' => $i)),
'#title' => t('Tab @num', array('@num' => $i)),
'#group' => 'vertical_tabs',
'#access' => \Drupal::currentUser()->hasPermission('access vertical_tab_test tabs'),
);
$form['tab' . $i]['field' . $i] = array(
'#title' => t('Field !num', array('!num' => $i)),
'#title' => t('Field @num', array('@num' => $i)),
'#type' => 'textfield',
);

View file

@ -4,9 +4,3 @@ httpkernel_test.empty:
_controller: '\Drupal\httpkernel_test\Controller\TestController::get'
requirements:
_access: 'TRUE'
httpkernel_test.teapot:
path: '/httpkernel-test/teapot'
defaults:
_controller: '\Drupal\httpkernel_test\Controller\TestController::teapot'
requirements:
_access: 'TRUE'

View file

@ -21,21 +21,4 @@ class TestController {
return new Response();
}
/**
* Test special header and status code rendering.
*
* @return array
* A render array using features of the 'http_header' directive.
*/
public function teapot() {
$render = [];
$render['#attached']['http_header'][] = ['X-Test-Teapot-Replace', 'This value gets replaced'];
$render['#attached']['http_header'][] = ['X-Test-Teapot-Replace', 'Teapot replaced', TRUE];
$render['#attached']['http_header'][] = ['X-Test-Teapot-No-Replace', 'This value is not replaced'];
$render['#attached']['http_header'][] = ['X-Test-Teapot-No-Replace', 'This one is added', FALSE];
$render['#attached']['http_header'][] = ['X-Test-Teapot', 'Teapot Mode Active'];
$render['#attached']['http_header'][] = ['Status', "418 I'm a teapot."];
return $render;
}
}

View file

@ -138,7 +138,7 @@ class TestToolkit extends ImageToolkitBase {
*/
public function parseFile() {
$this->logCall('parseFile', func_get_args());
$data = @getimagesize($this->getImage()->getSource());
$data = @getimagesize($this->getSource());
if ($data && in_array($data[2], static::supportedTypes())) {
$this->setType($data[2]);
$this->width = $data[0];

View file

@ -0,0 +1,6 @@
name: 'Link generation test support'
type: module
description: 'Test hooks fired in link generation.'
package: Testing
version: VERSION
core: 8.x

View file

@ -0,0 +1,21 @@
<?php
/**
* @file
* Helper module for the link generation tests.
*/
/**
* Implements hook_link_alter().
*/
function link_generation_test_link_alter(&$variables) {
if (\Drupal::state()->get('link_generation_test_link_alter', FALSE)) {
// Add a text to the end of links.
if (\Drupal::state()->get('link_generation_test_link_alter_safe', FALSE)) {
$variables['text'] = t('@text <strong>Test!</strong>', ['@text' => $variables['text']]);
}
else {
$variables['text'] .= ' <strong>Test!</strong>';
}
}
}

View file

@ -83,3 +83,8 @@ menu_test.child:
menu_test.unsafe:
route_name: menu_test.menu_name_test
deriver: '\Drupal\menu_test\Plugin\Derivative\MenuLinkTestWithUnsafeTitle'
menu_test.access_check:
title: 'Test custom route access check'
route_name: menu_test.router_test_session
menu_name: account

View file

@ -5,6 +5,7 @@
* Module that implements various hooks for menu tests.
*/
use Drupal\Core\Cache\RefinableCacheableDependencyInterface;
use Drupal\Core\Url;
/**
@ -29,7 +30,7 @@ function menu_test_menu_links_discovered_alter(&$links) {
/**
* Implements hook_menu_local_tasks_alter().
*/
function menu_test_menu_local_tasks_alter(&$data, $route_name) {
function menu_test_menu_local_tasks_alter(&$data, $route_name, RefinableCacheableDependencyInterface &$cacheability) {
if (in_array($route_name, array('menu_test.tasks_default'))) {
$data['tabs'][0]['foo'] = array(
'#theme' => 'menu_local_task',
@ -48,32 +49,7 @@ function menu_test_menu_local_tasks_alter(&$data, $route_name) {
'#weight' => 20,
);
}
}
/**
* Page callback: Tests the theme negotiation functionality.
*
* @param bool $inherited
* (optional) TRUE when the requested page is intended to inherit
* the theme of its parent.
*
* @return string
* A string describing the requested custom theme and actual theme being used
* for the current page request.
*
* @see menu_test_menu().
*
* @deprecated Use \Drupal\menu_test\Controller\MenuTestController::themePage()
*/
function menu_test_theme_page_callback($inherited = FALSE) {
$theme_key = \Drupal::theme()->getActiveTheme()->getName();
// Now we check what the theme negotiator service returns.
$active_theme = \Drupal::service('theme.negotiator')->determineActiveTheme(\Drupal::routeMatch());
$output = "Active theme: $active_theme. Actual theme: $theme_key.";
if ($inherited) {
$output .= ' Theme negotiation inheritance is being tested.';
}
return ['#markup' => $output];
$cacheability->addCacheTags(['kittens:dwarf-cat']);
}
/**

View file

@ -74,6 +74,15 @@ menu_test.router_test4:
requirements:
_access: 'TRUE'
menu_test.router_test_session:
path: '/menu_test_access_check_session'
defaults:
_controller: '\Drupal\menu_test\TestControllers::testSession'
options:
no_cache: TRUE
requirements:
_menu_test_session_access: 'TRUE'
menu_test.local_action1:
path: '/menu-test-local-action'
defaults:

View file

@ -3,3 +3,8 @@ services:
class: Drupal\menu_test\Theme\TestThemeNegotiator
tags:
- { name: theme_negotiator }
access_check.menu_test_session:
class: Drupal\menu_test\Access\AccessCheck
tags:
- { name: access_check, applies_to: _menu_test_session_access }

View file

@ -0,0 +1,33 @@
<?php
/**
* @file
* Contains \Drupal\menu_test\Access\AccessCheck.
*/
namespace Drupal\menu_test\Access;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Routing\Access\AccessInterface;
/**
* Checks access based on the 'menu_test' key in session.
*/
class AccessCheck implements AccessInterface {
/**
* Check to see if user accessed this page.
*
* @return \Drupal\Core\Access\AccessResultInterface
* The access result.
*/
public function access() {
if (!isset($_SESSION['menu_test'])) {
$result = AccessResult::allowed();
}
else {
$result = AccessResult::allowedIf($_SESSION['menu_test'] < 2);
}
return $result->setCacheMaxAge(0);
}
}

View file

@ -7,10 +7,64 @@
namespace Drupal\menu_test\Controller;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Theme\ThemeManagerInterface;
use Drupal\Core\Theme\ThemeNegotiatorInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Controller routines for menu_test routes.
*/
class MenuTestController {
class MenuTestController extends ControllerBase {
/**
* The theme manager.
*
* @var \Drupal\Core\Theme\ThemeManagerInterface
*/
protected $themeManager;
/**
* The theme negotiator.
*
* @var \Drupal\Core\Theme\ThemeNegotiatorInterface
*/
protected $themeNegotiator;
/**
* The active route match.
*
* @var \Drupal\Core\Routing\RouteMatchInterface
*/
protected $routeMatch;
/**
* Constructs the MenuTestController object.
*
* @param \Drupal\menu_test\Controller\ThemeManagerInterface $theme_manager
* The theme manager.
* @param \Drupal\menu_test\Controller\ThemeNegotiatorInterface $theme_negotiator
* The theme negotiator.
* @param \Drupal\menu_test\Controller\RouteMatchInterface $route_match
* The current route match.
*/
public function __construct(ThemeManagerInterface $theme_manager, ThemeNegotiatorInterface $theme_negotiator, RouteMatchInterface $route_match) {
$this->themeManager = $theme_manager;
$this->themeNegotiator = $theme_negotiator;
$this->routeMatch = $route_match;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('theme.manager'),
$container->get('theme.negotiator'),
$container->get('current_route_match')
);
}
/**
* Some known placeholder content which can be used for testing.
@ -40,10 +94,27 @@ class MenuTestController {
}
/**
* @todo Remove menu_test_theme_page_callback().
* Page callback: Tests the theme negotiation functionality.
*
* @param bool $inherited
* TRUE when the requested page is intended to inherit
* the theme of its parent.
*
* @return string
* A string describing the requested custom theme and actual
* theme being used
* for the current page request.
*/
public function themePage($inherited) {
return menu_test_theme_page_callback($inherited);
$theme_key = $this->themeManager->getActiveTheme()->getName();
// Now we check what the theme negotiator service returns.
$active_theme = $this->themeNegotiator
->determineActiveTheme($this->routeMatch);
$output = "Active theme: $active_theme. Actual theme: $theme_key.";
if ($inherited) {
$output .= ' Theme negotiation inheritance is being tested.';
}
return ['#markup' => $output];
}
/**

View file

@ -21,4 +21,11 @@ class TestTasksSettingsSub1 extends LocalTaskDefault {
return $this->t('Dynamic title for @class', array('@class' => 'TestTasksSettingsSub1'));
}
/**
* {@inheritdoc}
*/
function getCacheTags() {
return ['kittens:ragdoll'];
}
}

View file

@ -36,6 +36,17 @@ class TestControllers {
return ['#markup' => 'test2'];
}
/**
* Prints out test data.
*/
public function testSession() {
if (!isset($_SESSION['menu_test'])) {
$_SESSION['menu_test'] = 0;
}
$_SESSION['menu_test']++;
return ['#markup' => SafeMarkup::format('Session menu_test is @count', ['@count' => $_SESSION['menu_test']])];
}
/**
* Prints out test data.
*/

View file

@ -1,7 +1,7 @@
<?php
/**
* Implements hook_altered_test_hook()
* Implements hook_altered_test_hook().
*
* @see module_test_module_implements_alter()
*/

View file

@ -47,7 +47,7 @@ function module_test_system_info_alter(&$info, Extension $file, $type) {
}
}
if ($file->getName() == 'seven' && $type == 'theme') {
$info['regions']['test_region'] = t('Test region');
$info['regions']['test_region'] = 'Test region';
}
}

View file

@ -0,0 +1,7 @@
<?php
/**
* Test post update function.
*/
function module_test_post_update_test() {
}

View file

@ -25,6 +25,8 @@ class TestControllers {
}
public function testEntityLanguage(NodeInterface $node) {
return ['#markup' => $node->label()];
$build = ['#markup' => $node->label()];
\Drupal::service('renderer')->addCacheableDependency($build, $node);
return $build;
}
}

View file

@ -78,7 +78,7 @@ class MockBlockManager extends PluginManagerBase {
'label' => t('User name'),
'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockUserNameBlock',
'context' => array(
'user' => new ContextDefinition('entity:user', t('User')),
'user' => $this->createContextDefinition('entity:user', t('User')),
),
));
@ -87,7 +87,7 @@ class MockBlockManager extends PluginManagerBase {
'label' => t('User name optional'),
'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockUserNameBlock',
'context' => array(
'user' => new ContextDefinition('entity:user', t('User'), FALSE),
'user' => $this->createContextDefinition('entity:user', t('User'), FALSE),
),
));
@ -102,8 +102,8 @@ class MockBlockManager extends PluginManagerBase {
'label' => t('Complex context'),
'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockComplexContextBlock',
'context' => array(
'user' => new ContextDefinition('entity:user', t('User')),
'node' => new ContextDefinition('entity:node', t('Node')),
'user' => $this->createContextDefinition('entity:user', t('User')),
'node' => $this->createContextDefinition('entity:node', t('Node')),
),
));
@ -118,4 +118,24 @@ class MockBlockManager extends PluginManagerBase {
// specified), so we provide it the discovery object.
$this->factory = new ReflectionFactory($this->discovery);
}
/**
* Creates a new context definition with a label that is cast to string.
*
* @param string $data_type
* The required data type.
* @param mixed string|null $label
* The label of this context definition for the UI.
* @param bool $required
* Whether the context definition is required.
*
* @return \Drupal\Core\Plugin\Context\ContextDefinition
*/
protected function createContextDefinition($data_type, $label, $required = TRUE) {
// We cast the label to string for testing purposes only, as it may be
// a TranslatableMarkup and we will do assertEqual() checks on arrays that
// include ContextDefinition objects, and var_export() has problems
// printing TranslatableMarkup objects.
return new ContextDefinition($data_type, (string) $label, $required);
}
}

View file

@ -0,0 +1,8 @@
name: 'Rendering #attached test'
type: module
description: 'Support module for HtmlResponseAttachmentsTest.'
package: Testing
version: VERSION
core: 8.x
dependencies:
- block

View file

@ -0,0 +1,27 @@
render_attached.teapot:
path: '/render_attached_test/teapot'
defaults:
_controller: '\Drupal\render_attached_test\Controller\RenderAttachedTestController::teapotHeaderStatus'
requirements:
_access: 'TRUE'
render_attached.header:
path: '/render_attached_test/header'
defaults:
_controller: '\Drupal\render_attached_test\Controller\RenderAttachedTestController::header'
requirements:
_access: 'TRUE'
render_attached.head:
path: '/render_attached_test/head'
defaults:
_controller: '\Drupal\render_attached_test\Controller\RenderAttachedTestController::head'
requirements:
_access: 'TRUE'
render_attached.feed_single:
path: '/render_attached_test/feed'
defaults:
_controller: '\Drupal\render_attached_test\Controller\RenderAttachedTestController::feed'
requirements:
_access: 'TRUE'

View file

@ -0,0 +1,77 @@
<?php
/**
* @file
* Contains \Drupal\render_attached_test\Controller\TestController.
*/
namespace Drupal\render_attached_test\Controller;
/**
* Controller for various permutations of #attached in the render array.
*/
class RenderAttachedTestController {
/**
* Test special header and status code rendering.
*
* @return array
* A render array using features of the 'http_header' directive.
*/
public function teapotHeaderStatus() {
$render = [];
$render['#attached']['http_header'][] = ['Status', "418 I'm a teapot."];
return $render;
}
/**
* Test attached HTML head rendering.
*
* @return array
* A render array using the 'http_head' directive.
*/
public function header() {
$render = [];
$render['#attached']['http_header'][] = ['X-Test-Teapot-Replace', 'This value gets replaced'];
$render['#attached']['http_header'][] = ['X-Test-Teapot-Replace', 'Teapot replaced', TRUE];
$render['#attached']['http_header'][] = ['X-Test-Teapot-No-Replace', 'This value is not replaced'];
$render['#attached']['http_header'][] = ['X-Test-Teapot-No-Replace', 'This one is added', FALSE];
$render['#attached']['http_header'][] = ['X-Test-Teapot', 'Teapot Mode Active'];
return $render;
}
/**
* Test attached HTML head rendering.
*
* @return array
* A render array using the 'html_head' directive.
*/
public function head() {
$head = [
[
'#tag' => 'meta',
'#attributes' => [
'test-attribute' => 'testvalue',
],
],
'test_head_attribute',
];
$render = [];
$render['#attached']['html_head'][] = $head;
return $render;
}
/**
* Test attached feed rendering.
*
* @return array
* A render array using the 'feed' directive.
*/
public function feed() {
$render = [];
$render['#attached']['feed'][] = ['test://url', 'Your RSS feed.'];
return $render;
}
}

View file

@ -0,0 +1,50 @@
<?php
/**
* @file
* Contains \Drupal\render_attached_test\Plugin\Block\DrupalProcessAttachedBlock.
*/
namespace Drupal\render_attached_test\Plugin\Block;
use Drupal\render_attached_test\Controller\RenderAttachedTestController;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Render\BubbleableMetadata;
/**
* A block we can use to test caching of #attached headers.
*
* @Block(
* id = "attached_rendering_block",
* admin_label = @Translation("AttachedRenderingBlock")
* )
*
* @see \Drupal\system\Tests\Render\HtmlResponseAttachmentsTest
*/
class AttachedRenderingBlock extends BlockBase {
/**
* {@inheritdoc}
*/
public function build() {
// Grab test attachment fixtures from
// Drupal\render_attached_test\Controller\RenderAttachedTestController.
$controller = new RenderAttachedTestController();
$attached = BubbleableMetadata::mergeAttachments($controller->feed(), $controller->head());
$attached = BubbleableMetadata::mergeAttachments($attached, $controller->header());
$attached = BubbleableMetadata::mergeAttachments($attached, $controller->teapotHeaderStatus());
// Return some arbitrary markup so the block doesn't disappear.
$attached['#markup'] = 'Markup from attached_rendering_block.';
return $attached;
}
/**
* {@inheritdoc}
*/
public function getCacheMaxAge() {
return Cache::PERMANENT;
}
}

View file

@ -7,9 +7,9 @@
namespace Drupal\system_test\Controller;
use Drupal\Core\Cache\CacheableJsonResponse;
use Drupal\Core\Cache\CacheableResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
/**
* Defines a controller to respond the page cache accept header test.
@ -26,10 +26,10 @@ class PageCacheAcceptHeaderController {
*/
public function content(Request $request) {
if ($request->getRequestFormat() === 'json') {
return new JsonResponse(array('content' => 'oh hai this is json'));
return new CacheableJsonResponse(['content' => 'oh hai this is json']);
}
else {
return new Response("<p>oh hai this is html.</p>");
return new CacheableResponse("<p>oh hai this is html.</p>");
}
}
}

View file

@ -8,9 +8,10 @@
namespace Drupal\system_test\Controller;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Cache\CacheableResponse;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Render\SafeString;
use Drupal\Core\Render\Markup;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Url;
use Symfony\Component\HttpFoundation\RedirectResponse;
@ -114,18 +115,18 @@ class SystemTestController extends ControllerBase {
drupal_set_message('Duplicated message', 'status', TRUE);
drupal_set_message('Duplicated message', 'status', TRUE);
// Add a SafeString message.
drupal_set_message(SafeString::create('SafeString with <em>markup!</em>'));
// Test duplicate SafeString messages.
drupal_set_message(SafeString::create('SafeString with <em>markup!</em>'));
// Ensure that multiple SafeString messages work.
drupal_set_message(SafeString::create('SafeString2 with <em>markup!</em>'));
// Add a Markup message.
drupal_set_message(Markup::create('Markup with <em>markup!</em>'));
// Test duplicate Markup messages.
drupal_set_message(Markup::create('Markup with <em>markup!</em>'));
// Ensure that multiple Markup messages work.
drupal_set_message(Markup::create('Markup2 with <em>markup!</em>'));
// Test mixing of types.
drupal_set_message(SafeString::create('Non duplicate SafeString / string.'));
drupal_set_message('Non duplicate SafeString / string.');
drupal_set_message(SafeString::create('Duplicate SafeString / string.'), 'status', TRUE);
drupal_set_message('Duplicate SafeString / string.', 'status', TRUE);
drupal_set_message(Markup::create('Non duplicate Markup / string.'));
drupal_set_message('Non duplicate Markup / string.');
drupal_set_message(Markup::create('Duplicate Markup / string.'), 'status', TRUE);
drupal_set_message('Duplicate Markup / string.', 'status', TRUE);
// Test auto-escape of non safe strings.
drupal_set_message('<em>This<span>markup will be</span> escaped</em>.');
@ -259,13 +260,28 @@ class SystemTestController extends ControllerBase {
*/
public function setHeader(Request $request) {
$query = $request->query->all();
$response = new Response();
$response = new CacheableResponse();
$response->headers->set($query['name'], $query['value']);
$response->getCacheableMetadata()->addCacheContexts(['url.query_args:name', 'url.query_args:value']);
$response->setContent($this->t('The following header was set: %name: %value', array('%name' => $query['name'], '%value' => $query['value'])));
return $response;
}
/**
* A simple page callback that uses a plain Symfony response object.
*/
public function respondWithReponse(Request $request) {
return new Response('test');
}
/**
* A simple page callback that uses a CacheableResponse object.
*/
public function respondWithCacheableReponse(Request $request) {
return new CacheableResponse('test');
}
/**
* A simple page callback which adds a register shutdown function.
*/

View file

@ -129,3 +129,17 @@ system_test.permission_dependent_route_access:
_controller: '\Drupal\system_test\Controller\SystemTestController::mainContentFallback'
requirements:
_permission: 'pet llamas'
system_test.respond_response:
path: '/system-test/respond-reponse'
defaults:
_controller: '\Drupal\system_test\Controller\SystemTestController::respondWithReponse'
requirements:
_access: 'TRUE'
system_test.respond_cacheable_response:
path: '/system-test/respond-cacheable-reponse'
defaults:
_controller: '\Drupal\system_test\Controller\SystemTestController::respondWithCacheableReponse'
requirements:
_access: 'TRUE'

View file

@ -13,10 +13,18 @@ namespace Drupal\test_page_test\Controller;
class TestPageTestController {
/**
* @todo Remove test_page_test_page().
* Returns a test page and sets the title.
*/
public function testPage() {
return test_page_test_page();
return [
'#title' => t('Test page'),
'#markup' => t('Test page text.'),
'#attached' => [
'drupalSettings' => [
'test-setting' => 'azAZ09();.,\\\/-_{}',
],
],
];
}
}

View file

@ -1,15 +0,0 @@
<?php
/**
* Page callback: Returns a test page and sets the title.
*
* @deprecated Use \Drupal\test_page_test\Controller\TestPageTestController::testPage()
*/
function test_page_test_page() {
$attached['drupalSettings']['test-setting'] = 'azAZ09();.,\\\/-_{}';
return array(
'#title' => t('Test page'),
'#markup' => t('Test page text.'),
'#attached' => $attached,
);
}

View file

@ -81,6 +81,12 @@ function theme_test_page_bottom(array &$page_bottom) {
$page_bottom['theme_test_page_bottom'] = array('#markup' => 'theme test page bottom markup');
}
/**
* Implements template_preprocess_HOOK() for theme_test_function_suggestions theme functions.
*/
function template_preprocess_theme_test_function_suggestions(&$variables) {
}
/**
* Theme function for testing _theme('theme_test_foo').
*/

View file

@ -0,0 +1,26 @@
<?php
/**
* @file
* Contains \Drupal\twig_theme_test\ExampleRenderable.
*/
namespace Drupal\twig_theme_test;
use Drupal\Core\Render\RenderableInterface;
/**
* Provides an example implementation of the RenderableInterface.
*/
class ExampleRenderable implements RenderableInterface {
/**
* {@inheritdoc}
*/
public function toRenderable() {
return [
'#markup' => 'Example markup',
];
}
}

View file

@ -99,4 +99,14 @@ class TwigThemeTestController {
return array('#theme' => 'twig_registry_loader_test');
}
/**
* Controller for testing a renderable inside a template.
*/
public function renderable() {
return [
'#theme' => 'twig_theme_test_renderable',
'#renderable' => new ExampleRenderable()
];
}
}

View file

@ -0,0 +1 @@
<div>{{ renderable }}</div>

View file

@ -47,11 +47,6 @@
Escaped: {{ string }}
{% endtrans %}
</div>
<div>
{% trans %}
Pass-through: {{ string|passthrough }}
{% endtrans %}
</div>
<div>
{% trans %}
Placeholder: {{ string|placeholder }}
@ -63,7 +58,7 @@
{% set count = token|length %}
<div>
{% trans %}
This {{ token.name }} has a length of: {{ count }}. It contains: {{ token.numbers|placeholder }} and {{ token.bad_text }}. Lets pass the bad text through: {{ token.bad_text|passthrough }}.
This {{ token.name }} has a length of: {{ count }}. It contains: {{ token.numbers|placeholder }} and {{ token.bad_text }}.
{% endtrans %}
</div>

View file

@ -62,6 +62,12 @@ function twig_theme_test_theme($existing, $type, $theme, $path) {
'variables' => array(),
'template' => 'twig_theme_test.attach_library',
);
$items['twig_theme_test_renderable'] = array(
'variables' => array(
'renderable' => NULL,
),
'template' => 'twig_theme_test.renderable',
);
return $items;
}

View file

@ -62,3 +62,10 @@ twig_theme_test_registry_loader:
no_cache: TRUE
requirements:
_access: 'TRUE'
twig_theme_test_renderable:
path: '/twig-theme-test/renderable'
defaults:
_controller: '\Drupal\twig_theme_test\TwigThemeTestController::renderable'
requirements:
_access: 'TRUE'

View file

@ -1,6 +0,0 @@
name: 'Update order test'
type: module
description: 'Support module for update testing.'
package: Testing
version: VERSION
core: 8.x

View file

@ -1,53 +0,0 @@
<?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'));
}
}
}

View file

@ -1,27 +0,0 @@
<?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;
}
}
}

View file

@ -0,0 +1,6 @@
name: 'Update test failing'
type: module
description: 'Support module for update testing when an update hook is failing.'
package: Testing
version: VERSION
core: 8.x

View file

@ -0,0 +1,22 @@
<?php
/**
* @file
* Contains a failing update hook for testing the update system.
*/
use Drupal\Core\Utility\UpdateException;
/**
* This update will fail.
*/
function update_test_failing_update_8001() {
throw new UpdateException('This update hook is failing.');
}
/**
* A further update.
*/
function update_test_failing_update_8002() {
// This hook won't ever run.
}

View file

@ -0,0 +1,10 @@
<?php
/**
* First update, should not be run since this module's update hooks fail.
*/
function update_test_failing_post_update_first() {
$execution = \Drupal::state()->get('post_update_test_execution', []);
$execution[] = __FUNCTION__;
\Drupal::state()->set('post_update_test_execution', $execution);
}

View file

@ -0,0 +1,5 @@
core: 8.x
name: Update test after
type: module
package: Testing
version: VERSION

View file

@ -0,0 +1,7 @@
<?php
/**
* Normal update_N() function.
*/
function update_test_postupdate_update_8001() {
}

View file

@ -0,0 +1,45 @@
<?php
/**
* First update.
*/
function update_test_postupdate_post_update_first() {
$execution = \Drupal::state()->get('post_update_test_execution', []);
$execution[] = __FUNCTION__;
\Drupal::state()->set('post_update_test_execution', $execution);
return 'First update';
}
/**
* Second update.
*/
function update_test_postupdate_post_update_second() {
$execution = \Drupal::state()->get('post_update_test_execution', []);
$execution[] = __FUNCTION__;
\Drupal::state()->set('post_update_test_execution', $execution);
return 'Second update';
}
/**
* Test1 update.
*/
function update_test_postupdate_post_update_test1() {
$execution = \Drupal::state()->get('post_update_test_execution', []);
$execution[] = __FUNCTION__;
\Drupal::state()->set('post_update_test_execution', $execution);
return 'Test1 update';
}
/**
* Test0 update.
*/
function update_test_postupdate_post_update_test0() {
$execution = \Drupal::state()->get('post_update_test_execution', []);
$execution[] = __FUNCTION__;
\Drupal::state()->set('post_update_test_execution', $execution);
return 'Test0 update';
}

View file

@ -27,9 +27,7 @@ class PathProcessor implements InboundPathProcessorInterface {
}
// Rewrite community/ to forum/.
if ($path == '/community' || strpos($path, '/community/') === 0) {
$path = '/forum' . substr($path, 9);
}
$path = preg_replace('@^/community(.*)@', '/forum$1', $path);
if ($path == '/url-alter-test/bar') {
$path = '/url-alter-test/foo';

View file

@ -31,9 +31,7 @@ class PathProcessorTest implements InboundPathProcessorInterface, OutboundPathPr
}
// Rewrite community/ to forum/.
if ($path == '/community' || strpos($path, '/community/') === 0) {
$path = '/forum' . substr($path, 10);
}
$path = preg_replace('@^/community(.*)@', '/forum$1', $path);
if ($path == '/url-alter-test/bar') {
$path = '/url-alter-test/foo';
@ -57,10 +55,7 @@ class PathProcessorTest implements InboundPathProcessorInterface, OutboundPathPr
}
// Rewrite forum/ to community/.
if ($path == '/forum' || strpos($path, '/forum/') === 0) {
$path = '/community' . substr($path, 5);
}
return $path;
return preg_replace('@^/forum(.*)@', '/community$1', $path);
}
}