View source
<?php
namespace Drupal\cer\Form;
use Drupal\Core\Entity\EntityFieldManager;
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\EntityWithPluginCollectionInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\cer\Entity\CorrespondingReferenceInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
class CorrespondingReferenceForm extends EntityForm {
protected $entityTypeManager;
protected $fieldManager;
public function __construct(EntityTypeManagerInterface $entity_type_manager, EntityFieldManager $field_manager) {
$this->entityTypeManager = $entity_type_manager;
$this->fieldManager = $field_manager;
}
public static function create(ContainerInterface $container) {
$entity_type_manager = $container
->get('entity_type.manager');
$field_manager = $container
->get('entity_field.manager');
return new static($entity_type_manager, $field_manager);
}
public function form(array $form, FormStateInterface $form_state) {
$form = parent::form($form, $form_state);
$correspondingReference = $this->entity;
$form['label'] = [
'#type' => 'textfield',
'#title' => $this
->t('Label'),
'#maxlength' => 255,
'#default_value' => $correspondingReference
->label(),
'#description' => $this
->t("Label for the corresponding reference."),
'#required' => TRUE,
];
$form['id'] = [
'#type' => 'machine_name',
'#default_value' => $correspondingReference
->id(),
'#machine_name' => [
'exists' => [
$this,
'exists',
],
],
'#disabled' => !$correspondingReference
->isNew(),
];
$form['first_field'] = [
'#type' => 'select',
'#title' => $this
->t('First field'),
'#description' => $this
->t('Select the first field.'),
'#options' => $this
->getFieldOptions(),
'#default_value' => $correspondingReference
->getFirstField(),
'#required' => TRUE,
];
$form['second_field'] = [
'#type' => 'select',
'#title' => $this
->t('Second field'),
'#description' => $this
->t('Select the corresponding field. It may be the same field.'),
'#options' => $this
->getFieldOptions(),
'#default_value' => $correspondingReference
->getSecondField(),
'#required' => TRUE,
];
$form['bundles'] = [
'#type' => 'select',
'#title' => $this
->t('Bundles'),
'#description' => $this
->t('Select the bundles which should correspond to one another when they have one of the corresponding fields.'),
'#options' => $this
->getBundleOptions(),
'#multiple' => TRUE,
'#default_value' => $this
->getBundleValuesForForm($correspondingReference
->getBundles()),
];
$form['enabled'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Enabled'),
'#description' => $this
->t('When enabled, corresponding references will be automatically created upon saving an entity.'),
'#default_value' => $correspondingReference
->isEnabled(),
];
return $form;
}
public function save(array $form, FormStateInterface $form_state) {
$correspondingReference = $this->entity;
$status = $correspondingReference
->save();
if ($status) {
$this
->messenger()
->addStatus($this
->t('Saved the %label corresponding reference.', [
'%label' => $correspondingReference
->label(),
]));
}
else {
$this
->messenger()
->addStatus($this
->t('The %label corresponding reference was not saved.', [
'%label' => $correspondingReference
->label(),
]));
}
$form_state
->setRedirect('entity.corresponding_reference.collection');
}
public function exists($id) {
$entity = $this->entityTypeManager
->getStorage('corresponding_reference')
->getQuery()
->condition('id', $id)
->execute();
return (bool) $entity;
}
protected function getReferenceFieldMap() {
$map = $this->fieldManager
->getFieldMapByFieldType('entity_reference');
return $map;
}
protected function getFieldOptions() {
$options = [];
foreach ($this
->getReferenceFieldMap() as $entityType => $entityTypeFields) {
foreach ($entityTypeFields as $fieldName => $field) {
if (!preg_match('/^field_.*$/', $fieldName)) {
continue;
}
$options[$fieldName] = $fieldName;
}
}
return $options;
}
protected function getBundleOptions() {
$correspondingReference = $this->entity;
$correspondingFields = $correspondingReference
->getCorrespondingFields();
$options = [];
foreach ($this
->getReferenceFieldMap() as $entityType => $entityTypeFields) {
$includeType = FALSE;
foreach ($entityTypeFields as $fieldName => $field) {
if (!empty($correspondingFields) && !in_array($fieldName, $correspondingFields)) {
continue;
}
if (!preg_match('/^field_.*$/', $fieldName)) {
continue;
}
$includeType = TRUE;
foreach ($field['bundles'] as $bundle) {
$options["{$entityType}:{$bundle}"] = "{$entityType}: {$bundle}";
}
}
if ($includeType) {
$options["{$entityType}:*"] = "{$entityType}: *";
}
}
ksort($options);
return $options;
}
protected function getBundleValuesForForm(array $values = NULL) {
$formValues = [];
if (!is_null($values)) {
foreach ($values as $entityType => $bundles) {
foreach ($bundles as $bundle) {
$formValues[] = "{$entityType}:{$bundle}";
}
}
}
return $formValues;
}
protected function getBundleValuesForEntity(array $values = NULL) {
$entityValues = [];
if (!is_null($values)) {
foreach ($values as $value) {
list($entityType, $bundle) = explode(':', $value);
$entityValues[$entityType][] = $bundle;
}
}
return $entityValues;
}
protected function copyFormValuesToEntity(EntityInterface $entity, array $form, FormStateInterface $form_state) {
$values = $form_state
->getValues();
if ($this->entity instanceof EntityWithPluginCollectionInterface) {
$values = array_diff_key($values, $this->entity
->getPluginCollections());
}
$entity
->set('id', $values['id']);
$entity
->set('label', $values['label']);
$entity
->set('first_field', $values['first_field']);
$entity
->set('second_field', $values['second_field']);
$entity
->set('bundles', $this
->getBundleValuesForEntity($values['bundles']));
$entity
->set('enabled', $values['enabled']);
}
}