Last active
February 8, 2021 06:19
-
-
Save artyuum/0bb26a93798ff99dfcbe1211e14dd916 to your computer and use it in GitHub Desktop.
A simple helper to ease with the creation of custom fields on Drupal without having to use YAML files as they are less convenient.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace Drupal\artyuum\Helper; | |
| use Drupal; | |
| use Drupal\Core\Entity\EntityStorageException; | |
| use Drupal\field\Entity\FieldConfig; | |
| use Drupal\field\Entity\FieldStorageConfig; | |
| /** | |
| * This helper is used to ease with the creation of custom fields in PHP without having to use YAML files as they are less convenient. | |
| */ | |
| class FieldCreationHelper | |
| { | |
| /** | |
| * @var string Should contain the entity type (e.g "node", "user", etc). | |
| */ | |
| private $entityType; | |
| /** | |
| * @var string Should contain the field machine name (e.g. "my_field_name"). | |
| */ | |
| private $fieldName; | |
| /** | |
| * @var string Should contain the field type (e.g. "string", "integer", etc.). | |
| */ | |
| private $fieldType; | |
| /** | |
| * @var string Should contain the field label (e.g. "Something"). | |
| */ | |
| private $fieldLabel; | |
| /** | |
| * @var string Should contain the field form type (e.g. "text_textfield", "number", etc.). | |
| */ | |
| private $fieldFormType; | |
| /** | |
| * @var array Should contain the node type that will have this field (e.g ['page', 'article']). | |
| */ | |
| private $bundles; | |
| /** | |
| * @var int Should contain the field's weight (NOTE: seems like this is not working) | |
| */ | |
| private $weight = 20; | |
| /** | |
| * @var string Should contain the region form (e.g. "content", "hidden", etc.) | |
| */ | |
| private $regionForm = 'content'; | |
| /** | |
| * @var int Should contain the limit of selected option. (-1 for unlimuted) | |
| */ | |
| private $cardinality = 1; | |
| /** | |
| * @var array Should contain the storage settings which is usually used to set the allowed values for a field or the target type (when making a relation to an entity) | |
| */ | |
| private $storageSettings = []; | |
| /** | |
| * @var array Should contain the field settings which is usually used to set the entity machine name (when making a relation to an entity) | |
| */ | |
| private $fieldSettings = []; | |
| /** | |
| * @var bool should contain whether this field is required or not | |
| */ | |
| private $required = true; | |
| public function __construct(string $entityType, string $fieldName, string $fieldType, string $fieldLabel, string $fieldFormType, array $bundles) | |
| { | |
| $this->entityType = $entityType; | |
| $this->fieldName = $fieldName; | |
| $this->fieldType = $fieldType; | |
| $this->fieldLabel = $fieldLabel; | |
| $this->fieldFormType = $fieldFormType; | |
| $this->bundles = $bundles; | |
| } | |
| public function getEntityType(): string | |
| { | |
| return $this->entityType; | |
| } | |
| public function setEntityType(string $entityType): self | |
| { | |
| $this->entityType = $entityType; | |
| return $this; | |
| } | |
| public function getFieldName(): string | |
| { | |
| if ($this->fieldName === 'body') { | |
| return $this->fieldName; | |
| } | |
| return 'field_' . $this->fieldName; | |
| } | |
| public function setFieldName(string $fieldName): self | |
| { | |
| $this->fieldName = $fieldName; | |
| return $this; | |
| } | |
| public function getFieldType(): string | |
| { | |
| return $this->fieldType; | |
| } | |
| public function setFieldType(string $fieldType): self | |
| { | |
| $this->fieldType = $fieldType; | |
| return $this; | |
| } | |
| public function getFieldLabel(): string | |
| { | |
| return $this->fieldLabel; | |
| } | |
| public function setFieldLabel(string $fieldLabel): self | |
| { | |
| $this->fieldLabel = $fieldLabel; | |
| return $this; | |
| } | |
| public function getFieldFormType(): string | |
| { | |
| return $this->fieldFormType; | |
| } | |
| public function setFieldFormType(string $fieldFormType): self | |
| { | |
| $this->fieldFormType = $fieldFormType; | |
| return $this; | |
| } | |
| public function getBundles(): array | |
| { | |
| return $this->bundles; | |
| } | |
| public function setBundles(array $bundles): self | |
| { | |
| $this->bundles = $bundles; | |
| return $this; | |
| } | |
| public function getWeight(): int | |
| { | |
| return $this->weight; | |
| } | |
| public function setWeight(int $weight): self | |
| { | |
| $this->weight = $weight; | |
| return $this; | |
| } | |
| public function getRegionForm(): string | |
| { | |
| return $this->regionForm; | |
| } | |
| public function setRegionForm(string $regionForm): self | |
| { | |
| $this->regionForm = $regionForm; | |
| return $this; | |
| } | |
| public function getCardinality(): int | |
| { | |
| return $this->cardinality; | |
| } | |
| public function setCardinality(int $cardinality): self | |
| { | |
| $this->cardinality = $cardinality; | |
| return $this; | |
| } | |
| public function getStorageSettings(): array | |
| { | |
| return $this->storageSettings; | |
| } | |
| public function setStorageSettings(array $storageSettings): self | |
| { | |
| $this->storageSettings = $storageSettings; | |
| return $this; | |
| } | |
| public function getFieldSettings(): array | |
| { | |
| return $this->fieldSettings; | |
| } | |
| public function setFieldSettings(array $fieldSettings): self | |
| { | |
| $this->fieldSettings = $fieldSettings; | |
| return $this; | |
| } | |
| public function getRequired(): bool | |
| { | |
| return $this->required; | |
| } | |
| public function setRequired(bool $required): self | |
| { | |
| $this->required = $required; | |
| return $this; | |
| } | |
| /** | |
| * Creates a new field. | |
| * | |
| * @throws EntityStorageException | |
| */ | |
| public function create(): void | |
| { | |
| $fieldStorage = FieldStorageConfig::loadByName($this->getEntityType(), $this->getFieldName()); | |
| // creates the field only if it doesn't already exist | |
| if (!$fieldStorage) { | |
| FieldStorageConfig::create([ | |
| 'field_name' => $this->getFieldName(), | |
| 'entity_type' => $this->getEntityType(), | |
| 'type' => $this->getFieldType(), | |
| 'weight' => $this->getWeight(), | |
| 'cardinality' => $this->getCardinality(), | |
| 'settings' => $this->getStorageSettings(), | |
| ])->save(); | |
| $fieldStorage = FieldStorageConfig::loadByName($this->getEntityType(), $this->getFieldName()); | |
| } | |
| // loops through all bundles and assigns the field | |
| foreach ($this->getBundles() as $bundle) { | |
| $field = FieldConfig::loadByName($this->getEntityType(), $bundle, $this->getFieldName()); | |
| if (!$field) { | |
| FieldConfig::create([ | |
| 'field_storage' => $fieldStorage, | |
| 'bundle' => $bundle, | |
| 'label' => $this->getFieldLabel(), | |
| 'settings' => $this->getFieldSettings(), | |
| 'required' => $this->getRequired(), | |
| ])->save(); | |
| /** @var Drupal\Core\Entity\EntityDisplayRepository $displayRepository */ | |
| $displayRepository = Drupal::service('entity_display.repository'); | |
| $displayRepository->getFormDisplay($this->getEntityType(), $bundle) | |
| ->setComponent($this->getFieldName(), [ | |
| 'region' => $this->getRegionForm(), | |
| 'type' => $this->getFieldFormType(), | |
| ])->save(); | |
| $displayRepository->getViewDisplay($this->getEntityType(), $bundle) | |
| ->setComponent($this->getFieldName(), [ | |
| 'label' => 'hidden', | |
| 'type' => 'text_default', | |
| ])->save(); | |
| } | |
| } | |
| } | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Usage
All field's name will be prefixed with "field_" (unless the field name is "body"). So for the code above, the field will be created as "field_youtube_video_ids".
Fields are created as required by default. You can change that by calling the following
setRequired()method before callingcreate(), like this: