RealisticDummyContentFieldModifier.php in Realistic Dummy Content 3.x
Same filename and directory in other branches
File
api/src/includes/RealisticDummyContentFieldModifier.phpView source
<?php
namespace Drupal\realistic_dummy_content_api\includes;
use Drupal\realistic_dummy_content_api\Framework\Framework;
/**
* Field modifier class.
*
* All manipulation of generated content to make it more realistic
* passes through modifiers (direct or indirect subclasses of
* RealisticDummyContentEntityBase).
*
* This class (RealisticDummyContentFieldModifier) allows active modules to put
* files in a specific directory hierarchy resembling
* realistic_dummy_content/fields/[entity_type]/[bundle]/[field_name], and for
* these files to define data which will replace the values of the corresponding
* property or field in any given entity.
*
* The difference between a field and a property is that a field is managed by
* Drupal's Field system, whereas a property is not. Example of fields include
* field_image, which define images in articles (in a standard installation);
* examples of properties include the user entity's picture property, and the
* title of nodes.
*
* Drupal stores field values differently depending on the type of field, and
* third-party modules can define their own schemes for storing values; an
* extensible system has been defined to allow any module (including this one)
* to define field formats and interpret data from files. To do so, modules must
* implement hook_realistic_dummy_content_field_manipular_alter(). Please see
* the example in this module's .module file, with more documentation in
* realistic_dummy_content_api.api.php. (Realistic Dummy Content API defines
* specific manipulators for the fields image, text_with_summary,
* taxonomy_term_reference...).
*/
class RealisticDummyContentFieldModifier extends RealisticDummyContentEntityBase {
/**
* Get properties for the entity, for example user's picture or node's name.
*
* @return array
* An array of RealisticDummyContentAttribute objects, keyed by attribute
* name, e.g. title => [RealisticDummyContentAttribute], field_image =>
* [RealisticDummyContentAttribute]
*/
public function getProperties() {
$modifiable_properties = [];
$fields = $this
->getFields();
foreach (Framework::instance()
->entityProperties($this
->getEntity()) as $property => $info) {
if (!in_array($property, array_keys($fields)) && $this
->filter($property)) {
$this
->addModifier($modifiable_properties, 'property', $property);
}
}
return $modifiable_properties;
}
/**
* Get fields for the entity, for example body or field_image.
*
* @return array
* An array of RealisticDummyContentAttribute objects, keyed by attribute
* name, e.g. title => [RealisticDummyContentAttribute], field_image =>
* [RealisticDummyContentAttribute]
*/
public function getFields() {
$modifiable_fields = [];
$type = $this
->getType();
$bundle = $this
->getBundle();
// Get _all_ defined fields. This should return an associative array.
$fields = Framework::instance()
->fieldInfoFields();
foreach ($fields as $field => $info) {
if (isset($info['bundles'][$type]) && is_array($info['bundles'][$type]) && in_array($bundle, $info['bundles'][$type]) && $this
->filter($field)) {
$this
->addModifier($modifiable_fields, 'field', $field);
}
}
return $modifiable_fields;
}
/**
* Adds a modifier to a list of attribute modifiers.
*
* To abstract away the difference between fields and properties, we
* call them all attributes. Modifiers will modify attributes depending on
* what they are. For example, a user picture is modified differently than
* an image in an article. This is managed through an extensible class
* hierarchy. Modules, including this one, can implement
* hook_realistic_dummy_content_attribute_manipular_alter() to determine
* which class should modify which attribute (field or property).
*
* By default, we will consider that properties are text properties and that
* fields' [value] property should be modified. This is not the case, however
* for user pictures (which should load a file), body fields (which contain
* a text format), and others. These are all defined in subclasses and can
* be extended by module developers.
*
* @param array $modifiers
* Existing array of subclasses of RealisticDummyContentAttribute, to which
* new modifiers will be added.
* @param string $type
* Either 'property' or 'field'.
* @param string $name
* Name of the property or field, for example 'body', 'picture', 'title',
* 'field_image'.
*/
public function addModifier(array &$modifiers, $type, $name) {
$class = '';
switch ($type) {
case 'property':
$original_class = '\\Drupal\\realistic_dummy_content_api\\includes\\RealisticDummyContentTextProperty';
$attribute_type = $name;
break;
case 'field':
$original_class = '\\Drupal\\realistic_dummy_content_api\\includes\\RealisticDummyContentValueField';
$field_info = Framework::instance()
->fieldInfoField($name);
$attribute_type = $field_info['type'];
break;
default:
return;
}
$class = $original_class;
$info = [
'type' => $type,
'machine_name' => $attribute_type,
'entity' => $this
->getEntity(),
'field_name' => $name,
];
Framework::instance()
->alter('realistic_dummy_content_attribute_manipulator', $class, $info);
// PHPStan complains that "Negated boolean expression is always false.",
// however it is technically possible for an alter hook to set the class
// to NULL or something.
// @phpstan-ignore-next-line
if (!$class) {
// third-parties might want to signal that certain fields cannot be
// modified (they can be too complex for the default modifier and do not
// yet have a custom modifier).
return;
}
elseif (class_exists($class)) {
$modifier = new $class($this, $name);
}
else {
// @phpstan-ignore-next-line
\Drupal::logger('realistic_dummy_content_api')
->notice('Class does not exist: @c. This is probably because a third-party module has implemented realistic_dummy_content_api_realistic_dummy_content_attribute_manipular_alter() with a class that cannot be implemented. @original will used instead.', [
'@c' => $class,
'@original' => $original_class,
]);
$modifier = new $original_class($this, $name);
}
if (isset($modifier)) {
// It's OK to index by name because attributes and fields can never have
// the same names.
$modifiers[$name] = $modifier;
}
}
/**
* {@inheritdoc}
*/
public function modify() {
$attributes = $this
->getAttributes();
foreach ($attributes as $attribute) {
$attribute
->change();
}
}
/**
* Returns all fields and properties.
*
* We implement fields and properties as subclasses of the same parent class,
* which defines a common interface for dealing with them.
*
* @return array
* An array of RealisticDummyContentAttribute objects, keyed by attribute
* name, e.g. title => [RealisticDummyContentAttribute], field_image =>
* [RealisticDummyContentAttribute]
*/
public function getAttributes() {
return array_merge($this
->getFields(), $this
->getProperties());
}
/**
* Generate a random number, or during tests, give the first available number.
*/
public function rand($start, $end) {
$return = realistic_dummy_content_api_rand($start, $end, $this
->getHash());
return $return;
}
/**
* Get the uid property of this entity, or 0.
*
* @return int
* The uid of the associated entity.
*/
public function getUid() {
$entity = $this
->getEntity();
if (isset($entity->uid)) {
return $entity->uid;
}
else {
return 0;
}
}
}
Classes
Name | Description |
---|---|
RealisticDummyContentFieldModifier | Field modifier class. |