View source
<?php
namespace Drupal\akamai\Form;
use Drupal\akamai\AkamaiClientManager;
use Drupal\akamai\KeyProviderInterface;
use Drupal\Core\Config\ConfigFactory;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Link;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Security\TrustedCallbackInterface;
use Drupal\Core\Url;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\akamai\Helper\Edgescape;
class ConfigForm extends ConfigFormBase implements TrustedCallbackInterface {
protected $availableVersions = [];
protected $messenger;
public function __construct(ConfigFactory $configFactory, RequestStack $request_stack, AkamaiClientManager $manager, MessengerInterface $messenger, ModuleHandlerInterface $module_handler, KeyProviderInterface $key_provider) {
$this->requestStack = $request_stack;
$this->keyProvider = $key_provider;
$this->messenger = $messenger;
$this->moduleHandler = $module_handler;
foreach ($manager
->getAvailableVersions() as $id => $definition) {
$this->availableVersions[$id] = $manager
->createInstance($id);
}
parent::__construct($configFactory);
}
public static function create(ContainerInterface $container) {
return new static($container
->get('config.factory'), $container
->get('request_stack'), $container
->get('akamai.client.manager'), $container
->get('messenger'), $container
->get('module_handler'), $container
->get('akamai.key_provider'));
}
public static function trustedCallbacks() {
return [
'implodeElement',
];
}
protected function getEditableConfigNames() {
return [
'akamai.settings',
];
}
public function getFormId() {
return 'akamai_config_form';
}
public function httpsWarning() {
$this->messenger
->addWarning($this
->t('If you submit this form via HTTP, your API credentials will be sent in clear text and may be intercepted. For information on setting up HTTPs, see <a href="https://www.drupal.org/https-information">Enabling HTTPs</a>.'));
}
public function buildForm(array $form, FormStateInterface $form_state) {
if ($this
->isHttps() === FALSE) {
$this
->httpsWarning();
}
$config = $this
->config('akamai.settings');
$luna_url = 'https://developer.akamai.com/introduction/Prov_Creds.html';
$luna_uri = Url::fromUri($luna_url);
$form['akamai_credentials_fieldset'] = [
'#type' => 'fieldset',
'#title' => $this
->t('Akamai CCU Credentials'),
'#description' => $this
->t('API Credentials for Akamai. Someone with Luna access will need to set this up. See @link for more.', [
'@link' => Link::fromTextAndUrl($luna_url, $luna_uri)
->toString(),
]),
];
$options = [
'file' => $this
->t('.edgerc file'),
];
if ($this->moduleHandler
->moduleExists('key')) {
$options['key'] = $this
->t('Key module');
}
$form['akamai_credentials_fieldset']['storage_method'] = [
'#type' => 'radios',
'#title' => $this
->t('Credential storage method'),
'#default_value' => $config
->get('storage_method') ?: 'file',
'#options' => $options,
'#required' => TRUE,
'#description' => $this
->t('Credentials may be stored in an .edgerc file or using the Key module (if installed). See the README file for more information.'),
];
$key_field_states = [
'required' => [
':input[name="storage_method"]' => [
'value' => 'key',
],
],
'visible' => [
':input[name="storage_method"]' => [
'value' => 'key',
],
],
'optional' => [
':input[name="storage_method"]' => [
'value' => 'file',
],
],
'invisible' => [
':input[name="storage_method"]' => [
'value' => 'file',
],
],
];
$file_field_states = [
'required' => [
':input[name="storage_method"]' => [
'value' => 'file',
],
],
'visible' => [
':input[name="storage_method"]' => [
'value' => 'file',
],
],
'optional' => [
':input[name="storage_method"]' => [
'value' => 'key',
],
],
'invisible' => [
':input[name="storage_method"]' => [
'value' => 'key',
],
],
];
$form['akamai_credentials_fieldset']['rest_api_url'] = [
'#type' => 'url',
'#title' => $this
->t('REST API URL'),
'#description' => $this
->t('The URL of the Akamai CCU API host. It should be in the format *.purge.akamaiapis.net/'),
'#default_value' => $config
->get('rest_api_url'),
'#states' => $key_field_states,
];
$keys = [];
if ($this->keyProvider
->hasKeyRepository()) {
foreach ($this->keyProvider
->getKeys() as $key) {
$keys[$key
->id()] = $key
->label();
}
}
asort($keys);
$form['akamai_credentials_fieldset']['access_token'] = [
'#type' => 'select',
'#title' => $this
->t('Access Token'),
'#description' => $this
->t('Access token.'),
'#options' => $keys,
'#default_value' => $config
->get('access_token'),
'#states' => $key_field_states,
];
$form['akamai_credentials_fieldset']['client_token'] = [
'#type' => 'select',
'#title' => $this
->t('Client Token'),
'#description' => $this
->t('Client token.'),
'#options' => $keys,
'#default_value' => $config
->get('client_token'),
'#states' => $key_field_states,
];
$form['akamai_credentials_fieldset']['client_secret'] = [
'#type' => 'select',
'#title' => $this
->t('Client Secret'),
'#description' => $this
->t('Client secret.'),
'#options' => $keys,
'#default_value' => $config
->get('client_secret'),
'#states' => $key_field_states,
];
$form['akamai_credentials_fieldset']['edgerc_path'] = [
'#type' => 'textfield',
'#title' => $this
->t('Path to .edgerc file'),
'#default_value' => $config
->get('edgerc_path') ?: '',
'#states' => $file_field_states,
];
$form['akamai_credentials_fieldset']['edgerc_section'] = [
'#type' => 'textfield',
'#title' => $this
->t('Section of .edgerc file to use for the CCU API'),
'#default_value' => $config
->get('edgerc_section') ?: 'default',
'#states' => $file_field_states,
];
$form['ccu_version'] = [
'#type' => 'radios',
'#title' => $this
->t('CCU Version'),
'#default_value' => $config
->get('version') ?: 'v3',
'#options' => array_map(function ($version) {
return $version
->getPluginDefinition()['title'];
}, $this->availableVersions),
'#required' => TRUE,
'#description' => $this
->t('Select which Akamai client version to use.'),
];
foreach ($this->availableVersions as $id => $version) {
$definition = $version
->getPluginDefinition();
$form['akamai_version_settings']['#options'][$id] = $definition['title'];
$form['akamai_version_settings'][$id] = [
'#type' => 'details',
'#title' => $this
->t('@version settings', [
'@version' => $definition['title'],
]),
'#open' => TRUE,
'#tree' => TRUE,
'#states' => [
'visible' => [
':radio[name="ccu_version"]' => [
'value' => $id,
],
],
],
];
$form['akamai_version_settings'][$id] += $version
->buildConfigurationForm([], $form_state);
}
global $base_url;
$basepath = $config
->get('basepath') ?: $base_url;
$form['basepath'] = [
'#type' => 'textfield',
'#title' => $this
->t('Base Path'),
'#default_value' => $basepath,
'#description' => $this
->t('The URL of the base path (fully qualified domain name) of the site. This will be used as a prefix for all cache clears (Akamai indexes on the full URI). e.g. "http://www.example.com"'),
'#required' => TRUE,
];
$form['timeout'] = [
'#type' => 'textfield',
'#title' => $this
->t('Timeout Length'),
'#description' => $this
->t("The timeout in seconds used when sending the cache clear request to Akamai's servers. Most users will not need to change this value."),
'#size' => 5,
'#maxlength' => 3,
'#default_value' => $config
->get('timeout'),
'#required' => TRUE,
];
$form['domain'] = [
'#type' => 'select',
'#title' => $this
->t('Domain'),
'#default_value' => $this
->getMappingKey($config
->get('domain')),
'#options' => [
'production' => $this
->t('Production'),
'staging' => $this
->t('Staging'),
],
'#description' => $this
->t('The Akamai domain to use for cache clearing.'),
'#required' => TRUE,
];
$form['edge_cache_tag_header_fieldset'] = [
'#type' => 'fieldset',
'#title' => $this
->t('Edge-Cache-Tag Header Settings'),
];
$form['edge_cache_tag_header_fieldset']['edge_cache_tag_header'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Enable Edge-Cache-Tag Header'),
'#default_value' => $config
->get('edge_cache_tag_header'),
'#description' => $this
->t('Sends Edge-Cache-Tag header in responses for Akamai'),
];
$form['edge_cache_tag_header_fieldset']['edge_cache_tag_header_blacklist'] = [
'#type' => 'textarea',
'#title' => $this
->t('Cache Tag Blacklist'),
'#default_value' => $config
->get('edge_cache_tag_header_blacklist'),
'#description' => $this
->t('List of tag prefixes to blacklist from the Edge-Cache-Tag header. One per line.'),
'#pre_render' => [
[
$this,
'implodeElement',
],
],
];
$form['edgescape_fieldset'] = [
'#type' => 'fieldset',
'#title' => $this
->t('Edgescape Settings'),
];
$form['edgescape_fieldset'][Edgescape::EDGESCAPE_SUPPORT] = [
'#type' => 'checkbox',
'#title' => $this
->t('Enable Edgescape Support'),
'#default_value' => $config
->get(Edgescape::EDGESCAPE_SUPPORT),
'#description' => $this
->t('Enable support for Akamai Edgescape processing and Drupal token'),
];
$form['devel_fieldset'] = [
'#type' => 'fieldset',
'#title' => $this
->t('Development Options'),
];
$form['devel_fieldset']['disabled'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Disable all calls to Akamai'),
'#default_value' => $config
->get('disabled'),
'#description' => $this
->t('Killswitch - disable Akamai cache clearing entirely.'),
];
$form['devel_fieldset']['log_requests'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Log requests'),
'#default_value' => $config
->get('log_requests'),
'#description' => $this
->t('Log all requests and responses.'),
];
return parent::buildForm($form, $form_state);
}
public function validateForm(array &$form, FormStateInterface $form_state) {
parent::validateForm($form, $form_state);
$int_fields = [
'timeout',
];
foreach ($int_fields as $field) {
if (!ctype_digit($form_state
->getValue($field))) {
$form_state
->setErrorByName($field, $this
->t('Please enter only integer values in this field.'));
}
}
foreach ($this->availableVersions as $version) {
$version
->validateConfigurationForm($form, $form_state);
}
}
public function submitform(array &$form, FormStateInterface $form_state) {
$values = $form_state
->getValues();
$blacklist = trim($values['edge_cache_tag_header_blacklist']);
$blacklist = !empty($blacklist) ? array_map('trim', explode(PHP_EOL, $blacklist)) : [];
$this
->config('akamai.settings')
->set('version', $values['ccu_version'])
->set('rest_api_url', $values['rest_api_url'])
->set('storage_method', $values['storage_method'])
->set('client_token', $values['client_token'])
->set('client_secret', $values['client_secret'])
->set('access_token', $values['access_token'])
->set('edgerc_path', $values['edgerc_path'])
->set('edgerc_section', $values['edgerc_section'])
->set('basepath', $values['basepath'])
->set('timeout', $values['timeout'])
->set('domain', $this
->saveDomain($values['domain']))
->set('log_requests', $values['log_requests'])
->set('edge_cache_tag_header', $values['edge_cache_tag_header'])
->set('edge_cache_tag_header_blacklist', $blacklist)
->set(Edgescape::EDGESCAPE_SUPPORT, $values[Edgescape::EDGESCAPE_SUPPORT])
->set('disabled', $values['disabled'])
->save();
foreach ($this->availableVersions as $version) {
$version
->submitConfigurationForm($form, $form_state);
}
parent::submitForm($form, $form_state);
$this->messenger
->addMessage($this
->t('Settings saved.'));
}
protected function getMappingKey(array $array) {
return key(array_filter($array));
}
protected function saveDomain($value) {
$domain = [
'production' => FALSE,
'staging' => FALSE,
];
$domain[$value] = TRUE;
return $domain;
}
protected function isHttps() {
$request = $this->requestStack
->getCurrentRequest();
return $request
->getScheme() === 'https';
}
public function implodeElement(array $element) {
$element['#value'] = !empty($element['#value']) ? implode(PHP_EOL, $element['#value']) : '';
return $element;
}
}