View source
<?php
namespace Drupal\ccl\Form;
use Drupal\ccl\CclService;
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Entity\EntityMalformedException;
use Drupal\Core\Entity\EntityStorageException;
use Drupal\Core\Entity\EntityTypeManager;
use Drupal\Core\Extension\ModuleHandler;
use Drupal\Core\Form\FormStateInterface;
use Exception;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher as EventDispatcher;
class CustomContextualLinkForm extends EntityForm {
protected $moduleHandler;
protected $cclService;
protected $entityTypeManager;
protected $eventDispatcher;
public function __construct(ModuleHandler $module_handler, CclService $ccl_service, EntityTypeManager $entity_type_manager, EventDispatcher $event_dispatcher) {
$this->moduleHandler = $module_handler;
$this->cclService = $ccl_service;
$this->entityTypeManager = $entity_type_manager;
$this->eventDispatcher = $event_dispatcher;
}
public static function create(ContainerInterface $container) {
return new static($container
->get('module_handler'), $container
->get('ccl.service'), $container
->get('entity_type.manager'), $container
->get('event_dispatcher'));
}
public function form(array $form, FormStateInterface $form_state) {
$form = parent::form($form, $form_state);
$form['#attached']['library'][] = 'ccl/ccl';
$form['#attributes']['class'][] = 'ccl-form';
$custom_contextual_link = $this->entity;
$form['label'] = [
'#type' => 'textfield',
'#title' => $this
->t('Label'),
'#maxlength' => 255,
'#default_value' => $custom_contextual_link
->label(),
'#description' => $this
->t("Label for the Custom Contextual Link. This for internal identification."),
'#required' => TRUE,
];
$form['id'] = [
'#type' => 'machine_name',
'#default_value' => $custom_contextual_link
->id(),
'#machine_name' => [
'exists' => '\\Drupal\\ccl\\Entity\\CustomContextualLink::load',
],
'#disabled' => !$custom_contextual_link
->isNew(),
];
$form['title'] = [
'#type' => 'textfield',
'#title' => $this
->t('Link Title'),
'#description' => $this
->t('The title of this link as it will be displayed in the contextual widget.'),
'#default_value' => $custom_contextual_link
->get('title'),
'#required' => TRUE,
];
$form['link'] = [
'#type' => 'textfield',
'#title' => $this
->t('URL'),
'#default_value' => $custom_contextual_link
->get('link'),
'#description' => $this
->t('The URL of this link.'),
'#required' => TRUE,
];
$form['advanced'] = [
'#type' => 'details',
'#title' => $this
->t('Advanced Options'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#tree' => TRUE,
];
$form['advanced']['css'] = [
'#type' => 'textfield',
'#title' => $this
->t('CSS Class'),
'#default_value' => $custom_contextual_link
->getAdvancedOption('css'),
'#description' => $this
->t('Add class name(s) to the link. Multiple classes should be seperated by a space. Example: "%example".', [
'%example' => "colorbox-load extra-class",
]),
];
$form['advanced']['anchor'] = [
'#type' => 'textfield',
'#title' => $this
->t('Anchor'),
'#default_value' => $custom_contextual_link
->getAdvancedOption('anchor'),
'#description' => $this
->t('Append an anchor string to the end of the link. Do not use the "#" at the beginning of the string.'),
];
$form['advanced']['query'] = [
'#type' => 'textfield',
'#title' => $this
->t('Query String'),
'#default_value' => $custom_contextual_link
->getAdvancedOption('query'),
'#description' => $this
->t('Append a query string to the end of the link. Do not use the "?" at the beginning of the query. Tokens can be used for this field as well.<br />Example: "%example".', [
'%example' => "width=500&height=500&iframe=true&user=[current-user:uid]",
]),
];
$form['advanced']['target'] = [
'#type' => 'select',
'#title' => $this
->t('Link Target'),
'#options' => [
'default' => $this
->t('Default (no target attribute)'),
'_top' => $this
->t('Open link in window root'),
'_blank' => $this
->t('Open link in new window'),
],
'#default_value' => $custom_contextual_link
->getAdvancedOption('target'),
'#description' => $this
->t('Set a target attribute for the link.'),
];
$form['token_group'] = [
'#type' => 'details',
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#title' => $this
->t('Tokens'),
'#description' => $this
->t("Token replacements will be performed for the link title and for the URL. Note that 'Node' tokens will not be replaced for links that are added to blocks.<br>Because contextual links are heavily cached, dynamic tokens like 'Current date' might not work as expected."),
];
if ($this->moduleHandler
->moduleExists('token')) {
$form['token_group']['tokens'] = [
'#theme' => 'token_tree_link',
'#token_types' => [
'node',
],
'#global_types' => TRUE,
'#click_insert' => TRUE,
'#dialog' => TRUE,
];
}
else {
$form['token_group']['token_tree'] = [
'#markup' => '<p>' . $this
->t('Enable the <a href=":drupal-token">Token module</a> to view the available token browser.', [
':drupal-token' => 'http://drupal.org/project/token',
]) . '</p>',
];
}
$form['options_group'] = [
'#type' => 'fieldset',
'#tree' => FALSE,
'#title' => $this
->t('Options'),
];
$form['options_group']['type'] = [
'#type' => 'radios',
'#title' => $this
->t('Link Type'),
'#description' => $this
->t('Select if this link should be displayed for a node or for a block.'),
'#options' => [
'node' => $this
->t('Node'),
],
'#default_value' => $custom_contextual_link
->get('type'),
'#required' => TRUE,
];
$form['options_group']['options'] = [
'#type' => 'container',
'#tree' => TRUE,
];
$form['options_group']['options']['node_option'] = [
'#type' => 'radios',
'#title' => $this
->t('Show link for'),
'#description' => $this
->t('Select if this link should be displayed for all nodes, all nodes of a content type or a specific node.'),
'#options' => [
'node' => $this
->t('Single node'),
'ct' => $this
->t('Content type'),
'global' => $this
->t('All nodes'),
],
'#default_value' => $custom_contextual_link
->getLinkOption('node_option'),
'#states' => [
'visible' => [
':input[name="type"]' => [
'value' => 'node',
],
],
],
];
$types = node_type_get_names();
$form['options_group']['options']['node_type'] = [
'#type' => 'select',
'#title' => $this
->t('Content Type'),
'#description' => $this
->t('The content type this link will be displayed for.'),
'#options' => $types,
'#default_value' => $custom_contextual_link
->getLinkOption('node_type'),
'#states' => [
'visible' => [
':input[name="options[node_option]"]' => [
'value' => 'ct',
],
':input[name="type"]' => [
'value' => 'node',
],
],
],
];
$defaultNid = $custom_contextual_link
->getLinkOption('node_id');
$defaultNode = NULL;
try {
$nodeStorage = $this->entityTypeManager
->getStorage('node');
$defaultNode = $defaultNid ? $nodeStorage
->load($defaultNid) : NULL;
} catch (Exception $exception) {
$this
->logger('ccl')
->error($exception
->getMessage());
}
$form['options_group']['options']['node_id'] = [
'#type' => 'entity_autocomplete',
'#target_type' => 'node',
'#title' => $this
->t('Node ID'),
'#description' => $this
->t('Enter the title of the node or the id of the node this link should be added to.'),
'#default_value' => $defaultNode,
'#states' => [
'visible' => [
':input[name="options[node_option]"]' => [
'value' => 'node',
],
':input[name="type"]' => [
'value' => 'node',
],
],
],
];
return $form;
}
public function validateForm(array &$form, FormStateInterface $form_state) {
parent::validateForm($form, $form_state);
$url = $form_state
->getValue('link');
if (strpos($url, '/') !== 0 && strpos($url, 'http') !== 0) {
$form_state
->setErrorByName('link', $this
->t("Internal links need to start with a '/' and external links with 'http'"));
}
}
public function save(array $form, FormStateInterface $form_state) {
$custom_contextual_link = $this->entity;
try {
$custom_contextual_link
->clearOptions();
$status = $custom_contextual_link
->save();
switch ($status) {
case SAVED_NEW:
$this
->messenger()
->addMessage($this
->t('Created the %label Custom Contextual Link.', [
'%label' => $custom_contextual_link
->label(),
]));
break;
default:
$this
->messenger()
->addMessage($this
->t('Saved the %label Custom Contextual Link.', [
'%label' => $custom_contextual_link
->label(),
]));
}
$this->eventDispatcher
->dispatch('ccl_update_cache');
try {
$form_state
->setRedirectUrl($custom_contextual_link
->toUrl('collection'));
} catch (EntityMalformedException $exception) {
$this
->logger('ccl')
->error($exception
->getMessage());
}
} catch (EntityStorageException $exception) {
$this
->logger('ccl')
->error($exception
->getMessage());
$this
->messenger()
->addError($this
->t('There was an error saving the link. Please consult the error log for more details.'));
}
}
}