View source
<?php
namespace Drupal\sms\Form;
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Url;
class PhoneNumberSettingsForm extends EntityForm {
const CREATE_NEW_FIELD = '!create';
protected $entityTypeManager;
protected $entityTypeBundleInfo;
protected $entityFieldManager;
protected $entity;
public function __construct(EntityTypeManagerInterface $entity_type_manager, EntityTypeBundleInfoInterface $entity_type_bundle_info, EntityFieldManagerInterface $entity_field_manager) {
$this->entityTypeManager = $entity_type_manager;
$this->entityTypeBundleInfo = $entity_type_bundle_info;
$this->entityFieldManager = $entity_field_manager;
}
public static function create(ContainerInterface $container) {
return new static($container
->get('entity_type.manager'), $container
->get('entity_type.bundle.info'), $container
->get('entity_field.manager'));
}
public function buildForm(array $form, FormStateInterface $form_state) {
$config =& $this->entity;
$form = parent::buildForm($form, $form_state);
$bundles = [];
$storage = $this->entityTypeManager
->getStorage('phone_number_settings');
foreach ($this->entityTypeManager
->getDefinitions() as $entity_type) {
if ($entity_type
->isSubclassOf(ContentEntityInterface::class)) {
foreach ($this->entityTypeBundleInfo
->getBundleInfo($entity_type
->id()) as $bundle => $bundle_info) {
if (!$storage
->load($entity_type
->id() . '.' . $bundle) || !$config
->isNew()) {
$bundles[(string) $entity_type
->getLabel()][$entity_type
->id() . '|' . $bundle] = $bundle_info['label'];
}
}
}
}
$bundle_default_value = !$config
->isNew() ? $config
->getPhoneNumberEntityTypeId() . '|' . $config
->getPhoneNumberBundle() : NULL;
$form['entity_bundle'] = [
'#type' => 'select',
'#title' => $this
->t('Bundle'),
'#options' => $bundles,
'#default_value' => $bundle_default_value,
'#required' => TRUE,
'#access' => $config
->isNew(),
'#ajax' => [
'callback' => '::updateFieldMapping',
'wrapper' => 'edit-field-mapping-wrapper',
],
];
if (!$bundles) {
$form['entity_bundle']['#empty_option'] = $this
->t('No Bundles Available');
}
$field_options = [];
$field_options['telephone'][self::CREATE_NEW_FIELD] = $this
->t('- Create a new telephone field -');
$field_options['boolean'][self::CREATE_NEW_FIELD] = $this
->t('- Create a new boolean field -');
if ($entity_bundle = $form_state
->getValue('entity_bundle', $bundle_default_value ?: NULL)) {
list($entity_type_id, $bundle) = explode('|', $entity_bundle);
if (!empty($entity_type_id) && !empty($bundle)) {
$field_definitions = $this->entityFieldManager
->getFieldDefinitions($entity_type_id, $bundle);
foreach ($field_definitions as $field_definition) {
$field_type = $field_definition
->getType();
if (isset($field_options[$field_type])) {
$field_options[$field_type][$field_definition
->getName()] = $field_definition
->getLabel();
}
}
}
}
$form['field_mapping'] = [
'#type' => 'fieldset',
'#title' => $this
->t('Field mapping'),
'#prefix' => '<div id="edit-field-mapping-wrapper">',
'#suffix' => '</div>',
'#tree' => TRUE,
];
$form['field_mapping']['phone_number'] = [
'#type' => 'select',
'#title' => $this
->t('Phone number'),
'#description' => $this
->t('Select the field storing phone numbers.'),
'#options' => $field_options['telephone'],
'#required' => TRUE,
'#empty_option' => $this
->t('- Select -'),
'#default_value' => $config
->getFieldName('phone_number'),
];
$form['field_mapping']['automated_opt_out'] = [
'#type' => 'select',
'#title' => $this
->t('Automated messages opt out'),
'#description' => $this
->t('Select the field storing preference to opt out of automated messages.'),
'#options' => $field_options['boolean'],
'#empty_option' => $this
->t('- None -'),
'#default_value' => $config
->getFieldName('automated_opt_out'),
];
$form['message'] = [
'#type' => 'fieldset',
'#title' => $this
->t('Messages'),
];
$form['message']['verification_message'] = [
'#type' => 'textarea',
'#title' => $this
->t('Verification message'),
'#description' => $this
->t('SMS message sent to verify a phone number. The message should contain the verification code and a link to the verification page.'),
'#default_value' => $config
->isNew() ? "Your verification code is '[sms-message:verification-code]'.\nGo to [sms:verification-url] to verify your phone number.\n- [site:name]" : $config
->getVerificationMessage(),
];
$tokens = [
'sms-message',
];
if ($this->moduleHandler
->moduleExists('token')) {
$form['message']['tokens']['list'] = [
'#theme' => 'token_tree_link',
'#token_types' => $tokens,
];
}
else {
foreach ($tokens as &$token) {
$token = "[{$token}:*]";
}
$form['message']['tokens']['list'] = [
'#markup' => $this
->t('Available tokens include: @token_types', [
'@token_types' => implode(' ', $tokens),
]),
];
}
$form['expiration'] = [
'#type' => 'fieldset',
'#title' => $this
->t('Verification expiration'),
];
$form['expiration']['code_lifetime'] = [
'#type' => 'number',
'#title' => $this
->t('Verification code lifetime'),
'#description' => $this
->t('How long a verification code is valid, before it expires. Existing verification codes are retroactively updated.'),
'#field_suffix' => $this
->t('seconds'),
'#required' => TRUE,
'#min' => 60,
'#default_value' => $config
->isNew() ? 3600 : $config
->getVerificationCodeLifetime(),
];
$form['expiration']['phone_number_purge'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Purge phone numbers'),
'#description' => $this
->t('Remove phone number if verification code expires.'),
'#default_value' => $config
->isNew() ?: $config
->getPurgeVerificationPhoneNumber(),
];
return $form;
}
public function updateFieldMapping($form, FormStateInterface $form_state) {
return $form['field_mapping'];
}
public function save(array $form, FormStateInterface $form_state) {
$config =& $this->entity;
list($entity_type_id, $bundle) = explode('|', $form_state
->getValue('entity_bundle'));
$config
->setPhoneNumberEntityTypeId($entity_type_id)
->setPhoneNumberBundle($bundle);
$config
->setVerificationMessage($form_state
->getValue('verification_message'))
->setVerificationCodeLifetime($form_state
->getValue('code_lifetime'))
->setPurgeVerificationPhoneNumber((bool) $form_state
->getValue('phone_number_purge'));
foreach ($form_state
->getValue('field_mapping') as $config_key => $field_name) {
if ($field_name == self::CREATE_NEW_FIELD) {
$field_config = $this
->createNewField($entity_type_id, $bundle, $config_key);
$field_name = $field_config
->getName();
}
else {
$entity_form_display = $field_storage_config = $this->entityTypeManager
->getStorage('entity_form_display')
->load($entity_type_id . '.' . $bundle . '.default');
if ($entity_form_display) {
$component = $entity_form_display
->getComponent($field_name) ?: [];
if (!$component || $component && $component['type'] == 'telephone_default') {
$component['type'] = 'sms_telephone';
$entity_form_display
->setComponent($field_name, $component)
->save();
}
}
}
$config
->setFieldName($config_key, $field_name);
}
$saved = $config
->save();
$t_args['%id'] = $config
->id();
if ($saved == SAVED_NEW) {
drupal_set_message($this
->t('Phone number settings %id created.', $t_args));
}
else {
drupal_set_message($this
->t('Phone number settings %id saved.', $t_args));
}
$form_state
->setRedirectUrl(Url::fromRoute('sms.phone_number_settings.list'));
}
public static function createNewField($entity_type_id, $bundle, $config_key) {
$entity_type_manager = \Drupal::entityTypeManager();
$definitions['field_storage']['phone_number']['type'] = 'telephone';
$definitions['field_storage']['automated_opt_out']['type'] = 'boolean';
$definitions['field']['phone_number']['label'] = t('Phone number');
$definitions['field']['automated_opt_out'] = [
'label' => t('Opt out of SMS messages.'),
'description' => t('SMS messages requested by you are exempt.'),
'settings' => [
'on_label' => t('Do not receive SMS messages from this site.'),
'off_label' => t('Receive SMS messages from this site.'),
],
];
$definitions['form_display']['phone_number']['type'] = 'sms_telephone';
$definitions['form_display']['automated_opt_out']['type'] = 'boolean_checkbox';
$i = 1;
$field_name = $config_key;
while ($entity_type_manager
->getStorage('field_storage_config')
->load($entity_type_id . '.' . $field_name)) {
$i++;
$field_name = $config_key . '_' . $i;
}
$field_storage_config = $entity_type_manager
->getStorage('field_storage_config')
->create([
'entity_type' => $entity_type_id,
'field_name' => $field_name,
] + $definitions['field_storage'][$config_key]);
$field_storage_config
->save();
$field_config = $entity_type_manager
->getStorage('field_config')
->create([
'entity_type' => $entity_type_id,
'bundle' => $bundle,
'field_name' => $field_name,
] + $definitions['field'][$config_key]);
$field_config
->save();
$entity_form_display = $field_storage_config = $entity_type_manager
->getStorage('entity_form_display')
->load($entity_type_id . '.' . $bundle . '.default');
if ($entity_form_display) {
$entity_form_display
->setComponent($field_name, $definitions['form_display'][$config_key]);
$entity_form_display
->save();
}
return $field_config;
}
}