Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
project
drupal
Commits
bba539c6
Commit
bba539c6
authored
Apr 26, 2013
by
catch
Browse files
#1869562
by fago, berdir, dawehner: Avoid instantiating EntityNG field value objects by default.
parent
288f240c
Changes
45
Hide whitespace changes
Inline
Side-by-side
core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php
View file @
bba539c6
...
...
@@ -89,7 +89,7 @@ public function get($property_name, $langcode = NULL) {
* EntityInterface::set() implements support for fieldable entities, but
* configuration entities are not fieldable.
*/
public
function
set
(
$property_name
,
$value
,
$langcode
=
NULL
)
{
public
function
set
(
$property_name
,
$value
,
$langcode
=
NULL
,
$notify
=
TRUE
)
{
// @todo: Add support for translatable properties being not fields.
$this
->
{
$property_name
}
=
$value
;
}
...
...
core/lib/Drupal/Core/Config/Schema/Element.php
View file @
bba539c6
...
...
@@ -7,12 +7,12 @@
namespace
Drupal\Core\Config\Schema
;
use
Drupal\Core\TypedData\
ContextAware
TypedData
;
use
Drupal\Core\TypedData\TypedData
;
/**
* Defines a generic configuration element.
*/
abstract
class
Element
extends
ContextAware
TypedData
{
abstract
class
Element
extends
TypedData
{
/**
* The configuration value.
...
...
core/lib/Drupal/Core/Config/Schema/Mapping.php
View file @
bba539c6
...
...
@@ -9,6 +9,7 @@
use
Drupal\Component\Utility\NestedArray
;
use
Drupal\Core\TypedData\ComplexDataInterface
;
use
Drupal\Core\TypedData\TypedDataInterface
;
use
\
InvalidArgumentException
;
/**
...
...
@@ -51,7 +52,11 @@ public function get($property_name) {
/**
* Implements Drupal\Core\TypedData\ComplexDataInterface::set().
*/
public
function
set
(
$property_name
,
$value
)
{
public
function
set
(
$property_name
,
$value
,
$notify
=
TRUE
)
{
// Notify the parent of any changes to be made.
if
(
$notify
&&
isset
(
$this
->
parent
))
{
$this
->
parent
->
onChange
(
$this
->
name
);
}
// Set the data into the configuration array but behave according to the
// interface specification when we've got a null value.
if
(
isset
(
$value
))
{
...
...
@@ -122,4 +127,14 @@ public function isEmpty() {
return
empty
(
$this
->
value
);
}
/**
* Implements \Drupal\Core\TypedData\ComplexDataInterface::onChange().
*/
public
function
onChange
(
$property_name
)
{
// Notify the parent of changes.
if
(
isset
(
$this
->
parent
))
{
$this
->
parent
->
onChange
(
$this
->
name
);
}
}
}
core/lib/Drupal/Core/Config/Schema/Sequence.php
View file @
bba539c6
...
...
@@ -40,4 +40,13 @@ public function getItemDefinition() {
return
$this
->
definition
[
'sequence'
][
0
];
}
/**
* Implements \Drupal\Core\TypedData\ListInterface::onChange().
*/
public
function
onChange
(
$delta
)
{
// Notify the parent of changes.
if
(
isset
(
$this
->
parent
))
{
$this
->
parent
->
onChange
(
$this
->
name
);
}
}
}
core/lib/Drupal/Core/Entity/DatabaseStorageControllerNG.php
View file @
bba539c6
...
...
@@ -109,7 +109,7 @@ public function create(array $values) {
// Assign a new UUID if there is none yet.
if
(
$this
->
uuidKey
&&
!
isset
(
$entity
->
{
$this
->
uuidKey
}
->
value
))
{
$uuid
=
new
Uuid
();
$entity
->
{
$this
->
uuidKey
}
->
value
=
$uuid
->
generate
();
$entity
->
{
$this
->
uuidKey
}
=
$uuid
->
generate
();
}
// Modules might need to add or change the data initially held by the new
...
...
core/lib/Drupal/Core/Entity/Entity.php
View file @
bba539c6
...
...
@@ -9,7 +9,7 @@
use
Drupal\Component\Uuid\Uuid
;
use
Drupal\Core\Language\Language
;
use
Drupal\Core\TypedData\
ContextAware
Interface
;
use
Drupal\Core\TypedData\
TypedData
Interface
;
use
IteratorAggregate
;
/**
...
...
@@ -191,7 +191,7 @@ public function get($property_name, $langcode = NULL) {
/**
* Implements \Drupal\Core\TypedData\ComplexDataInterface::set().
*/
public
function
set
(
$property_name
,
$value
)
{
public
function
set
(
$property_name
,
$value
,
$notify
=
TRUE
)
{
// @todo: Replace by EntityNG implementation once all entity types have been
// converted to use the entity field API.
$this
->
{
$property_name
}
=
$value
;
...
...
@@ -251,6 +251,7 @@ public function isEmpty() {
public
function
getIterator
()
{
// @todo: Replace by EntityNG implementation once all entity types have been
// converted to use the entity field API.
return
new
\
ArrayIterator
(
array
());
}
/**
...
...
@@ -406,37 +407,103 @@ public function getNGEntity() {
}
/**
* Implements \Drupal\Core\TypedData\ContextAwareInterface::getName().
* Implements \Drupal\Core\TypedData\TypedDataInterface::getType().
*/
public
function
getType
()
{
// @todo: Incorporate the entity type here by making entities proper
// typed data. See http://drupal.org/node/1868004.
return
'entity'
;
}
/**
* Implements \Drupal\Core\TypedData\TypedDataInterface::getDefinition().
*/
public
function
getDefinition
()
{
return
array
(
'type'
=>
$this
->
getType
()
);
}
/**
* Implements \Drupal\Core\TypedData\TypedDataInterface::getValue().
*/
public
function
getValue
()
{
// @todo: Implement by making entities proper typed data. See
// http://drupal.org/node/1868004.
}
/**
* Implements \Drupal\Core\TypedData\TypedDataInterface::setValue().
*/
public
function
setValue
(
$value
,
$notify
=
TRUE
)
{
// @todo: Implement by making entities proper typed data. See
// http://drupal.org/node/1868004.
}
/**
* Implements \Drupal\Core\TypedData\TypedDataInterface::getString().
*/
public
function
getString
()
{
// @todo: Implement by making entities proper typed data. See
// http://drupal.org/node/1868004.
}
/**
* Implements \Drupal\Core\TypedData\TypedDataInterface::getConstraints().
*/
public
function
getConstraints
()
{
// @todo: Implement by making entities proper typed data. See
// http://drupal.org/node/1868004.
return
array
();
}
/**
* Implements \Drupal\Core\TypedData\TypedDataInterface::validate().
*/
public
function
validate
()
{
// @todo: Implement by making entities proper typed data. See
// http://drupal.org/node/1868004.
}
/**
* Implements \Drupal\Core\TypedData\ComplexDataInterface::onChange().
*/
public
function
onChange
(
$property_name
)
{
// Nothing to do.
}
/**
* Implements \Drupal\Core\TypedData\TypedDataInterface::getName().
*/
public
function
getName
()
{
return
NULL
;
}
/**
* Implements \Drupal\Core\TypedData\
ContextAware
Interface::getRoot().
* Implements \Drupal\Core\TypedData\
TypedData
Interface::getRoot().
*/
public
function
getRoot
()
{
return
$this
;
}
/**
* Implements \Drupal\Core\TypedData\
ContextAware
Interface::getPropertyPath().
* Implements \Drupal\Core\TypedData\
TypedData
Interface::getPropertyPath().
*/
public
function
getPropertyPath
()
{
return
''
;
}
/**
* Implements \Drupal\Core\TypedData\
ContextAware
Interface::getParent().
* Implements \Drupal\Core\TypedData\
TypedData
Interface::getParent().
*/
public
function
getParent
()
{
return
NULL
;
}
/**
* Implements \Drupal\Core\TypedData\
ContextAware
Interface::setContext().
* Implements \Drupal\Core\TypedData\
TypedData
Interface::setContext().
*/
public
function
setContext
(
$name
=
NULL
,
ContextAware
Interface
$parent
=
NULL
)
{
public
function
setContext
(
$name
=
NULL
,
TypedData
Interface
$parent
=
NULL
)
{
// As entities are always the root of the tree of typed data, we do not need
// to set any parent or name.
}
...
...
core/lib/Drupal/Core/Entity/EntityBCDecorator.php
View file @
bba539c6
...
...
@@ -9,7 +9,7 @@
use
IteratorAggregate
;
use
Drupal\Core\Entity\EntityInterface
;
use
Drupal\Core\TypedData\
ContextAware
Interface
;
use
Drupal\Core\TypedData\
TypedData
Interface
;
/**
* Provides backwards compatible (BC) access to entity fields.
...
...
@@ -229,7 +229,7 @@ public function get($property_name) {
/**
* Forwards the call to the decorated entity.
*/
public
function
set
(
$property_name
,
$value
)
{
public
function
set
(
$property_name
,
$value
,
$notify
=
TRUE
)
{
// Ensure this works with not yet defined fields.
if
(
!
isset
(
$this
->
definitions
[
$property_name
]))
{
return
$this
->
__set
(
$property_name
,
$value
);
...
...
@@ -419,6 +419,55 @@ public function getTranslation($langcode, $strict = TRUE) {
return
$this
->
decorated
->
getTranslation
(
$langcode
,
$strict
);
}
/**
* Forwards the call to the decorated entity.
*/
public
function
getType
()
{
return
$this
->
decorated
->
getType
();
}
/**
* Forwards the call to the decorated entity.
*/
public
function
getDefinition
()
{
return
$this
->
decorated
->
getDefinition
();
}
/**
* Forwards the call to the decorated entity.
*/
public
function
getValue
()
{
return
$this
->
decorated
->
getValue
();
}
/**
* Forwards the call to the decorated entity.
*/
public
function
setValue
(
$value
,
$notify
=
TRUE
)
{
return
$this
->
decorated
->
setValue
(
$value
,
$notify
);
}
/**
* Forwards the call to the decorated entity.
*/
public
function
getString
()
{
return
$this
->
decorated
->
getString
();
}
/**
* Forwards the call to the decorated entity.
*/
public
function
getConstraints
()
{
return
$this
->
decorated
->
getConstraints
();
}
/**
* Forwards the call to the decorated entity.
*/
public
function
validate
()
{
return
$this
->
decorated
->
validate
();
}
/**
* Forwards the call to the decorated entity.
*/
...
...
@@ -450,7 +499,7 @@ public function getParent() {
/**
* Forwards the call to the decorated entity.
*/
public
function
setContext
(
$name
=
NULL
,
ContextAware
Interface
$parent
=
NULL
)
{
public
function
setContext
(
$name
=
NULL
,
TypedData
Interface
$parent
=
NULL
)
{
$this
->
decorated
->
setContext
(
$name
,
$parent
);
}
...
...
@@ -461,11 +510,17 @@ public function getExportProperties() {
$this
->
decorated
->
getExportProperties
();
}
/**
* Forwards the call to the decorated entity.
*/
public
function
onChange
(
$property_name
)
{
$this
->
decorated
->
onChange
(
$property_name
);
}
/**
* Forwards the call to the decorated entity.
*/
public
function
isTranslatable
()
{
return
$this
->
decorated
->
isTranslatable
();
}
}
core/lib/Drupal/Core/Entity/EntityInterface.php
View file @
bba539c6
...
...
@@ -8,7 +8,6 @@
namespace
Drupal\Core\Entity
;
use
Drupal\Core\TypedData\AccessibleInterface
;
use
Drupal\Core\TypedData\ContextAwareInterface
;
use
Drupal\Core\TypedData\ComplexDataInterface
;
use
Drupal\Core\TypedData\TranslatableInterface
;
...
...
@@ -28,7 +27,7 @@
* @see \Drupal\Core\TypedData\TypedDataManager
* @see \Drupal\Core\Field\FieldInterface
*/
interface
EntityInterface
extends
ContextAwareInterface
,
ComplexDataInterface
,
AccessibleInterface
,
TranslatableInterface
{
interface
EntityInterface
extends
ComplexDataInterface
,
AccessibleInterface
,
TranslatableInterface
{
/**
* Returns the entity identifier (the entity's machine name or numeric ID).
...
...
core/lib/Drupal/Core/Entity/EntityNG.php
View file @
bba539c6
...
...
@@ -8,7 +8,6 @@
namespace
Drupal\Core\Entity
;
use
Drupal\Core\Language\Language
;
use
Drupal\Core\TypedData\ContextAwareInterface
;
use
Drupal\Core\TypedData\TypedDataInterface
;
use
Drupal\Component\Uuid\Uuid
;
use
ArrayIterator
;
...
...
@@ -170,6 +169,7 @@ protected function getTranslatedField($property_name, $langcode) {
if
(
isset
(
$this
->
values
[
$property_name
][
$langcode
]))
{
$value
=
$this
->
values
[
$property_name
][
$langcode
];
}
// @todo: Make entities implement the TypedDataInterface.
$this
->
fields
[
$property_name
][
$langcode
]
=
typed_data
()
->
getPropertyInstance
(
$this
,
$property_name
,
$value
);
}
}
...
...
@@ -179,8 +179,8 @@ protected function getTranslatedField($property_name, $langcode) {
/**
* Implements \Drupal\Core\TypedData\ComplexDataInterface::set().
*/
public
function
set
(
$property_name
,
$value
)
{
$this
->
get
(
$property_name
)
->
setValue
(
$value
);
public
function
set
(
$property_name
,
$value
,
$notify
=
TRUE
)
{
$this
->
get
(
$property_name
)
->
setValue
(
$value
,
FALSE
);
}
/**
...
...
@@ -318,9 +318,7 @@ public function getTranslation($langcode, $strict = TRUE) {
);
$translation
=
typed_data
()
->
create
(
$translation_definition
,
$fields
);
$translation
->
setStrictMode
(
$strict
);
if
(
$translation
instanceof
ContextAwareInterface
)
{
$translation
->
setContext
(
'@'
.
$langcode
,
$this
);
}
$translation
->
setContext
(
'@'
.
$langcode
,
$this
);
return
$translation
;
}
...
...
@@ -435,7 +433,7 @@ public function &__get($name) {
*/
public
function
__set
(
$name
,
$value
)
{
// Support setting values via property objects.
if
(
$value
instanceof
TypedDataInterface
)
{
if
(
$value
instanceof
TypedDataInterface
&&
!
$value
instanceof
EntityInterface
)
{
$value
=
$value
->
getValue
();
}
// If this is an entity field, handle it accordingly. We first check whether
...
...
@@ -508,9 +506,7 @@ public function __clone() {
foreach
(
$this
->
fields
as
$name
=>
$properties
)
{
foreach
(
$properties
as
$langcode
=>
$property
)
{
$this
->
fields
[
$name
][
$langcode
]
=
clone
$property
;
if
(
$property
instanceof
ContextAwareInterface
)
{
$this
->
fields
[
$name
][
$langcode
]
->
setContext
(
$name
,
$this
);
}
$this
->
fields
[
$name
][
$langcode
]
->
setContext
(
$name
,
$this
);
}
}
}
...
...
core/lib/Drupal/Core/Entity/Field/FieldInterface.php
View file @
bba539c6
...
...
@@ -8,9 +8,7 @@
namespace
Drupal\Core\Entity\Field
;
use
Drupal\Core\TypedData\AccessibleInterface
;
use
Drupal\Core\TypedData\ContextAwareInterface
;
use
Drupal\Core\TypedData\ListInterface
;
use
Drupal\Core\TypedData\TypedDataInterface
;
/**
* Interface for fields, being lists of field items.
...
...
@@ -27,7 +25,7 @@
* When implementing this interface which extends Traversable, make sure to list
* IteratorAggregate or Iterator before this interface in the implements clause.
*/
interface
FieldInterface
extends
ListInterface
,
AccessibleInterface
,
ContextAwareInterface
,
TypedDataInterface
{
interface
FieldInterface
extends
ListInterface
,
AccessibleInterface
{
/**
* Gets a property object from the first field item.
...
...
core/lib/Drupal/Core/Entity/Field/FieldItemBase.php
View file @
bba539c6
...
...
@@ -7,13 +7,10 @@
namespace
Drupal\Core\Entity\Field
;
use
Drupal\Core\
TypedData\ContextAwareTypedData
;
use
Drupal\Core\TypedData\
ContextAwareInterface
;
use
Drupal\Core\
Entity\EntityInterface
;
use
Drupal\Core\TypedData\
Type\Map
;
use
Drupal\Core\TypedData\TypedDataInterface
;
use
Drupal\user
;
use
ArrayIterator
;
use
IteratorAggregate
;
use
InvalidArgumentException
;
/**
* An entity field item.
...
...
@@ -23,61 +20,20 @@
*
* @see \Drupal\Core\Entity\Field\FieldItemInterface
*/
abstract
class
FieldItemBase
extends
ContextAwareTypedData
implements
IteratorAggregate
,
FieldItemInterface
{
abstract
class
FieldItemBase
extends
Map
implements
FieldItemInterface
{
/**
* The array of properties, each implementing the TypedDataInterface.
*
* Field objects are instantiated during object construction and cannot be
* replaced by others, so computed properties can safely store references on
* other properties.
*
* @var array
*/
protected
$properties
=
array
();
/**
* Holds any non-property values that get set on the object.
*
* @todo: Remove or refactor once EntityNG conversion is complete.
*
* @var array
*/
protected
$extraValues
=
array
();
/**
* Overrides ContextAwareTypedData::__construct().
* Overrides \Drupal\Core\TypedData\TypedData::__construct().
*/
public
function
__construct
(
array
$definition
,
$name
=
NULL
,
ContextAware
Interface
$parent
=
NULL
)
{
public
function
__construct
(
array
$definition
,
$name
=
NULL
,
TypedData
Interface
$parent
=
NULL
)
{
parent
::
__construct
(
$definition
,
$name
,
$parent
);
// Initialize all property objects, but postpone the creating of computed
// properties to a second step. That way computed properties can safely get
// references on non-computed properties during construction.
$step2
=
array
();
// Initialize computed properties by default, such that they get cloned
// with the whole item.
foreach
(
$this
->
getPropertyDefinitions
()
as
$name
=>
$definition
)
{
if
(
empty
(
$definition
[
'computed'
]))
{
if
(
!
empty
(
$definition
[
'computed'
]))
{
$this
->
properties
[
$name
]
=
typed_data
()
->
getPropertyInstance
(
$this
,
$name
);
}
else
{
$step2
[]
=
$name
;
}
}
foreach
(
$step2
as
$name
)
{
$this
->
properties
[
$name
]
=
typed_data
()
->
getPropertyInstance
(
$this
,
$name
);
}
}
/**
* Overrides \Drupal\Core\TypedData\TypedData::getValue().
*/
public
function
getValue
()
{
$values
=
array
();
foreach
(
$this
->
getProperties
()
as
$name
=>
$property
)
{
$values
[
$name
]
=
$property
->
getValue
();
}
return
$values
+
$this
->
extraValues
;
}
/**
...
...
@@ -86,66 +42,59 @@ public function getValue() {
* @param array|null $values
* An array of property values.
*/
public
function
setValue
(
$values
)
{
public
function
setValue
(
$values
,
$notify
=
TRUE
)
{
// Treat the values as property value of the first property, if no array is
// given.
if
(
!
is_array
(
$values
))
{
$keys
=
array_keys
(
$this
->
p
ropert
ies
);
if
(
isset
(
$values
)
&&
!
is_array
(
$values
))
{
$keys
=
array_keys
(
$this
->
getP
ropert
yDefinitions
()
);
$values
=
array
(
$keys
[
0
]
=>
$values
);
}
// Notify the parent of any changes to be made.
if
(
$notify
&&
isset
(
$this
->
parent
))
{
$this
->
parent
->
onChange
(
$this
->
name
);
}
$this
->
values
=
$values
;
// Update any existing property objects.
foreach
(
$this
->
properties
as
$name
=>
$property
)
{
$value
=
NULL
;
if
(
isset
(
$values
[
$name
]))
{
$property
->
setValue
(
$values
[
$name
]);
}
else
{
$property
->
setValue
(
NULL
);
$value
=
$values
[
$name
];
}
unset
(
$values
[
$name
]);
$property
->
setValue
(
$value
,
FALSE
);
unset
(
$this
->
values
[
$name
]);
}
// @todo: Throw an exception for invalid values once conversion is
// totally completed.
$this
->
extraValues
=
$values
;
}
/**
*
Override
s \Drupal\Core\
TypedData\TypedData::getString
().
*
Implement
s \Drupal\Core\
Entity\Field\FieldItemInterface::__get
().
*/
public
function
getString
()
{
$strings
=
array
();
foreach
(
$this
->
getProperties
()
as
$property
)
{
$strings
[]
=
$property
->
getString
();
public
function
__get
(
$name
)
{
// There is either a property object or a plain value - possibly for a
// not-defined property. If we have a plain value, directly return it.
if
(
isset
(
$this
->
values
[
$name
]))
{
return
$this
->
values
[
$name
];
}
return
implode
(
', '
,
array_filter
(
$strings
));
}
/**
* Implements \Drupal\Core\TypedData\ComplexDataInterface::get().
*/
public
function
get
(
$property_name
)
{
if
(
!
isset
(
$this
->
properties
[
$property_name
]))
{
throw
new
InvalidArgumentException
(
'Field '
.
check_plain
(
$property_name
)
.
' is unknown.'
);
elseif
(
isset
(
$this
->
properties
[
$name
]))
{
return
$this
->
properties
[
$name
]
->
getValue
();
}
return
$this
->
properties
[
$property_name
];
}
/**
*
Implement
s \Drupal\Core\TypedData\
ComplexDataInterface
::set().
*
Override
s \Drupal\Core\TypedData\
Type\Map
::set().
*/
public
function
set
(
$property_name
,
$value
)
{
$this
->
get
(
$property_name
)
->
setValue
(
$value
);
}
/**
* Implements \Drupal\Core\Entity\Field\FieldItemInterface::__get().
*/
public
function
__get
(
$name
)
{
if
(
isset
(
$this
->
properties
[
$name
]))
{
return
$this
->
properties
[
$name
]
->
getValue
();
public
function
set
(
$property_name
,
$value
,
$notify
=
TRUE
)
{
// Notify the parent of any changes to be made.
if
(
$notify
&&
isset
(
$this
->
parent
))
{
$this
->
parent
->
onChange
(
$this
->
name
);
}
// For defined properties there is either a property object or a plain
// value that needs to be updated.
if
(
isset
(
$this
->
properties
[
$property_name
]))
{
$this
->
properties
[
$property_name
]
->
setValue
(
$value
,
FALSE
);
}
//
The property is unknown, so try to get it from the extra values
.
else
if
(
isset
(
$this
->
extraValues
[
$name
]))
{
return
$this
->
extraV
alues
[
$
name
]
;
//
Allow setting plain values for not-defined properties also
.
else
{
$this
->
v
alues
[
$
property_name
]
=
$value
;
}
}
...
...
@@ -153,105 +102,38 @@ public function __get($name) {
* Implements \Drupal\Core\Entity\Field\FieldItemInterface::__set().
*/
public
function
__set
(
$name
,
$value
)
{
// Support setting values via property objects.
if
(
$value
instanceof
TypedDataInterface
)
{
// Support setting values via property objects, but take care in as the
// value of the 'entity' property is typed data also.
if
(
$value
instanceof
TypedDataInterface
&&
!
(
$value
instanceof
EntityInterface
))
{
$value
=
$value
->
getValue
();
}