Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
project
drupal
Commits
d64047e3
Commit
d64047e3
authored
Mar 11, 2015
by
Nathaniel Catchpole
Browse files
Issue
#2448843
by dawehner: [regression] Themes unable to implement hook_element_info_alter()
parent
95fe74d5
Changes
6
Hide whitespace changes
Inline
Side-by-side
core/core.services.yml
View file @
d64047e3
...
...
@@ -979,7 +979,7 @@ services:
parent
:
default_plugin_manager
plugin.manager.element_info
:
class
:
Drupal\Core\Render\ElementInfoManager
p
arent
:
default_plugin_
manager
ar
gum
ent
s
:
[
'
@container.namespaces'
,
'
@cache.discovery'
,
'
@cache_tags.invalidator'
,
'
@module_handler'
,
'
@theme.
manager
'
]
stream_wrapper_manager
:
class
:
Drupal\Core\StreamWrapper\StreamWrapperManager
calls
:
...
...
core/lib/Drupal/Core/Render/ElementInfoManager.php
View file @
d64047e3
...
...
@@ -9,9 +9,11 @@
use
Drupal\Core\Cache\Cache
;
use
Drupal\Core\Cache\CacheBackendInterface
;
use
Drupal\Core\Cache\CacheTagsInvalidatorInterface
;
use
Drupal\Core\Extension\ModuleHandlerInterface
;
use
Drupal\Core\Plugin\DefaultPluginManager
;
use
Drupal\Core\Render\Element\FormElementInterface
;
use
Drupal\Core\Theme\ThemeManagerInterface
;
/**
* Provides a plugin manager for element plugins.
...
...
@@ -33,6 +35,20 @@ class ElementInfoManager extends DefaultPluginManager implements ElementInfoMana
*/
protected
$elementInfo
;
/**
* The theme manager.
*
* @var \Drupal\Core\Theme\ThemeManagerInterface
*/
protected
$themeManager
;
/**
* The cache tag invalidator.
*
* @var \Drupal\Core\Cache\CacheTagsInvalidatorInterface
*/
protected
$cacheTagInvalidator
;
/**
* Constructs a ElementInfoManager object.
*
...
...
@@ -41,11 +57,17 @@ class ElementInfoManager extends DefaultPluginManager implements ElementInfoMana
* keyed by the corresponding namespace to look for plugin implementations.
* @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
* Cache backend instance to use.
* @param \Drupal\Core\Cache\CacheTagsInvalidatorInterface $cache_tag_invalidator
* The cache tag invalidator.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler to invoke the alter hook with.
* @param \Drupal\Core\Theme\ThemeManagerInterface $theme_manager
* The theme manager.
*/
public
function
__construct
(
\
Traversable
$namespaces
,
CacheBackendInterface
$cache_backend
,
ModuleHandlerInterface
$module_handl
er
)
{
public
function
__construct
(
\
Traversable
$namespaces
,
CacheBackendInterface
$cache_backend
,
CacheTagsInvalidatorInterface
$cache_tag_invalidator
,
ModuleHandlerInterface
$module_handler
,
ThemeManagerInterface
$theme_manag
er
)
{
$this
->
setCacheBackend
(
$cache_backend
,
'element_info'
);
$this
->
themeManager
=
$theme_manager
;
$this
->
cacheTagInvalidator
=
$cache_tag_invalidator
;
parent
::
__construct
(
'Element'
,
$namespaces
,
$module_handler
,
'Drupal\Core\Render\Element\ElementInterface'
,
'Drupal\Core\Render\Annotation\RenderElement'
);
}
...
...
@@ -54,20 +76,27 @@ public function __construct(\Traversable $namespaces, CacheBackendInterface $cac
* {@inheritdoc}
*/
public
function
getInfo
(
$type
)
{
if
(
!
isset
(
$this
->
elementInfo
))
{
$this
->
elementInfo
=
$this
->
buildInfo
();
$theme_name
=
$this
->
themeManager
->
getActiveTheme
()
->
getName
();
if
(
!
isset
(
$this
->
elementInfo
[
$theme_name
]))
{
$this
->
elementInfo
[
$theme_name
]
=
$this
->
buildInfo
(
$theme_name
);
}
$info
=
isset
(
$this
->
elementInfo
[
$type
])
?
$this
->
elementInfo
[
$type
]
:
array
();
$info
=
isset
(
$this
->
elementInfo
[
$
theme_name
][
$
type
])
?
$this
->
elementInfo
[
$
theme_name
][
$
type
]
:
array
();
$info
[
'#defaults_loaded'
]
=
TRUE
;
return
$info
;
}
/**
* Builds up all element information.
*
* @param string $theme_name
* The theme name.
*
* @return array
*/
protected
function
buildInfo
()
{
protected
function
buildInfo
(
$theme_name
)
{
// Get cached definitions.
if
(
$cache
=
$this
->
cacheBackend
->
get
(
'element_info_build'
))
{
$cid
=
$this
->
getCid
(
$theme_name
);
if
(
$cache
=
$this
->
cacheBackend
->
get
(
$cid
))
{
return
$cache
->
data
;
}
...
...
@@ -94,8 +123,9 @@ protected function buildInfo() {
}
// Allow modules to alter the element type defaults.
$this
->
moduleHandler
->
alter
(
'element_info'
,
$info
);
$this
->
themeManager
->
alter
(
'element_info'
,
$info
);
$this
->
cacheBackend
->
set
(
'element_info_build'
,
$info
,
Cache
::
PERMANENT
);
$this
->
cacheBackend
->
set
(
$cid
,
$info
,
Cache
::
PERMANENT
,
[
'element_info_build'
]
);
return
$info
;
}
...
...
@@ -114,10 +144,21 @@ public function createInstance($plugin_id, array $configuration = array()) {
*/
public
function
clearCachedDefinitions
()
{
$this
->
elementInfo
=
NULL
;
$this
->
cache
Backend
->
delete
(
'element_info_build'
);
$this
->
cache
TagInvalidator
->
invalidateTags
([
'element_info_build'
]
);
parent
::
clearCachedDefinitions
();
}
/**
* Returns the CID used to cache the element info.
*
* @param string $theme_name
* The theme name.
*
* @return string
*/
protected
function
getCid
(
$theme_name
)
{
return
'element_info_build:'
.
$theme_name
;
}
}
core/lib/Drupal/Core/Theme/ActiveTheme.php
View file @
d64047e3
...
...
@@ -87,6 +87,16 @@ class ActiveTheme {
* The properties of the object, keyed by the names.
*/
public
function
__construct
(
array
$values
)
{
$values
+=
[
'path'
=>
''
,
'engine'
=>
'twig'
,
'owner'
=>
'twig'
,
'stylesheets_remove'
=>
[],
'stylesheets_override'
=>
[],
'libraries'
=>
[],
'extension'
=>
'html.twig'
,
'base_themes'
=>
[],
];
$this
->
name
=
$values
[
'name'
];
$this
->
path
=
$values
[
'path'
];
$this
->
engine
=
$values
[
'engine'
];
...
...
core/modules/system/src/Tests/Render/ElementInfoIntegrationTest.php
0 → 100644
View file @
d64047e3
<?php
/**
* @file
* Contains \Drupal\system\Tests\Render\ElementInfoIntegrationTest.
*/
namespace
Drupal\system\Tests\Render
;
use
Drupal\simpletest\KernelTestBase
;
/**
* Tests the element info.
*
* @group Render
*/
class
ElementInfoIntegrationTest
extends
KernelTestBase
{
/**
* {@inheritdoc}
*/
protected
function
setUp
()
{
parent
::
setUp
();
$this
->
container
->
get
(
'theme_handler'
)
->
install
([
'test_theme'
,
'classy'
]);
}
/**
* Ensures that the element info can be altered by themes.
*/
public
function
testElementInfoByTheme
()
{
/** @var \Drupal\Core\Theme\ThemeInitializationInterface $theme_initializer */
$theme_initializer
=
$this
->
container
->
get
(
'theme.initialization'
);
/** @var \Drupal\Core\Theme\ThemeManagerInterface $theme_manager */
$theme_manager
=
$this
->
container
->
get
(
'theme.manager'
);
/** @var \Drupal\Core\Render\ElementInfoManagerInterface $element_info */
$element_info
=
$this
->
container
->
get
(
'plugin.manager.element_info'
);
$theme_manager
->
setActiveTheme
(
$theme_initializer
->
getActiveThemeByName
(
'classy'
));
$this
->
assertEqual
(
60
,
$element_info
->
getInfo
(
'textfield'
)[
'#size'
]);
$theme_manager
->
setActiveTheme
(
$theme_initializer
->
getActiveThemeByName
(
'test_theme'
));
$this
->
assertEqual
(
40
,
$element_info
->
getInfo
(
'textfield'
)[
'#size'
]);
}
}
core/modules/system/tests/themes/test_theme/test_theme.theme
View file @
d64047e3
...
...
@@ -19,6 +19,16 @@ function test_theme_theme_test__suggestion($variables) {
return
'Theme hook implementor=test_theme_theme_test__suggestion(). Foo='
.
$variables
[
'foo'
];
}
/**
* Implements hook_element_info_alter().
*/
function
test_theme_element_info_alter
(
&
$info
)
{
// Decrease the default size of textfields.
if
(
isset
(
$info
[
'textfield'
][
'#size'
]))
{
$info
[
'textfield'
][
'#size'
]
=
40
;
}
}
/**
* Tests a theme implementing an alter hook.
*
...
...
core/tests/Drupal/Tests/Core/Render/ElementInfoManagerTest.php
View file @
d64047e3
...
...
@@ -8,6 +8,7 @@
namespace
Drupal\Tests\Core\Render
;
use
Drupal\Core\Render\ElementInfoManager
;
use
Drupal\Core\Theme\ActiveTheme
;
use
Drupal\Tests\UnitTestCase
;
/**
...
...
@@ -37,6 +38,20 @@ class ElementInfoManagerTest extends UnitTestCase {
*/
protected
$moduleHandler
;
/**
* The mocked theme manager.
*
* @var \Drupal\Core\Theme\ThemeManagerInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected
$themeManager
;
/**
* The cache tags invalidator.
*
* @var \Drupal\Core\Cache\CacheTagsInvalidatorInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected
$cacheTagsInvalidator
;
/**
* {@inheritdoc}
*
...
...
@@ -44,9 +59,11 @@ class ElementInfoManagerTest extends UnitTestCase {
*/
protected
function
setUp
()
{
$this
->
cache
=
$this
->
getMock
(
'Drupal\Core\Cache\CacheBackendInterface'
);
$this
->
cacheTagsInvalidator
=
$this
->
getMock
(
'Drupal\Core\Cache\CacheTagsInvalidatorInterface'
);
$this
->
moduleHandler
=
$this
->
getMock
(
'Drupal\Core\Extension\ModuleHandlerInterface'
);
$this
->
themeManager
=
$this
->
getMock
(
'Drupal\Core\Theme\ThemeManagerInterface'
);
$this
->
elementInfo
=
new
ElementInfoManager
(
new
\
ArrayObject
(),
$this
->
cache
,
$this
->
moduleHandl
er
);
$this
->
elementInfo
=
new
ElementInfoManager
(
new
\
ArrayObject
(),
$this
->
cache
,
$this
->
cacheTagsInvalidator
,
$this
->
moduleHandler
,
$this
->
themeManag
er
);
}
/**
...
...
@@ -68,10 +85,19 @@ public function testGetInfo($type, $expected_info, $element_info, callable $alte
->
will
(
$this
->
returnCallback
(
$alter_callback
?:
function
(
$info
)
{
return
$info
;
}));
$this
->
themeManager
->
expects
(
$this
->
once
())
->
method
(
'getActiveTheme'
)
->
willReturn
(
new
ActiveTheme
([
'name'
=>
'test'
]));
$this
->
themeManager
->
expects
(
$this
->
once
())
->
method
(
'alter'
)
->
with
(
'element_info'
,
$this
->
anything
())
->
will
(
$this
->
returnCallback
(
$alter_callback
?:
function
(
$info
)
{
return
$info
;
}));
$this
->
cache
->
expects
(
$this
->
at
(
0
))
->
method
(
'get'
)
->
with
(
'element_info_build'
)
->
with
(
'element_info_build
:test
'
)
->
will
(
$this
->
returnValue
(
FALSE
));
$this
->
cache
->
expects
(
$this
->
at
(
1
))
->
method
(
'get'
)
...
...
@@ -82,7 +108,7 @@ public function testGetInfo($type, $expected_info, $element_info, callable $alte
->
with
(
'element_info'
);
$this
->
cache
->
expects
(
$this
->
at
(
3
))
->
method
(
'set'
)
->
with
(
'element_info_build'
);
->
with
(
'element_info_build
:test
'
);
$this
->
assertEquals
(
$expected_info
,
$this
->
elementInfo
->
getInfo
(
$type
));
}
...
...
@@ -167,9 +193,14 @@ public function testGetInfoElementPlugin($plugin_class, $expected_info) {
));
$element_info
=
$this
->
getMockBuilder
(
'Drupal\Core\Render\ElementInfoManager'
)
->
setConstructorArgs
(
array
(
new
\
ArrayObject
(),
$this
->
cache
,
$this
->
moduleHandl
er
))
->
setConstructorArgs
(
array
(
new
\
ArrayObject
(),
$this
->
cache
,
$this
->
cacheTagsInvalidator
,
$this
->
moduleHandler
,
$this
->
themeManag
er
))
->
setMethods
(
array
(
'getDefinitions'
,
'createInstance'
))
->
getMock
();
$this
->
themeManager
->
expects
(
$this
->
any
())
->
method
(
'getActiveTheme'
)
->
willReturn
(
new
ActiveTheme
([
'name'
=>
'test'
]));
$element_info
->
expects
(
$this
->
once
())
->
method
(
'createInstance'
)
->
with
(
'page'
)
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment