acquia_dam-1.0.0-rc1/src/Form/AcquiaDamConfigurationForm.php
src/Form/AcquiaDamConfigurationForm.php
<?php namespace Drupal\acquia_dam\Form; use Drupal\acquia_dam\AcquiadamAuthService; use Drupal\acquia_dam\ImageStyleHelper; use Drupal\Component\Utility\Xss; use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Form\ConfigFormBase; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Routing\TrustedRedirectResponse; use Drupal\Core\Url; use GuzzleHttp\ClientInterface; use GuzzleHttp\Exception\TransferException; use Symfony\Component\DependencyInjection\ContainerInterface; /** * Acquia DAM module configuration form. */ class AcquiaDamConfigurationForm extends ConfigFormBase { /** * Client interface. * * @var \GuzzleHttp\ClientInterface */ protected $httpClient; /** * DAM auth service. * * @var \Drupal\acquia_dam\AcquiadamAuthService */ protected $authService; /** * The field plugin manager service. * * @var \Drupal\Core\Extension\ModuleHandler */ protected $moduleHandler; /** * Image style helper service. * * @var \Drupal\acquia_dam\ImageStyleHelper */ protected $imageStyleHelper; /** * Acquia DAM logger channel. * * @var \Drupal\Core\Logger\LoggerChannelInterface */ protected $damLoggerChannel; /** * AcquiaDamConfigurationForm constructor. * * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory * Config factory service. * @param \GuzzleHttp\ClientInterface $http_client * Http client. * @param \Drupal\acquia_dam\AcquiadamAuthService $authService * Acquia DAM authentication service. * @param \Drupal\Core\Extension\ModuleHandlerInterface $moduleHandler * Module handler. * @param \Drupal\acquia_dam\ImageStyleHelper $imageStyleHelper * Image style helper service. */ public function __construct(ConfigFactoryInterface $config_factory, ClientInterface $http_client, AcquiadamAuthService $authService, ModuleHandlerInterface $moduleHandler, ImageStyleHelper $imageStyleHelper) { parent::__construct($config_factory); $this->httpClient = $http_client; $this->authService = $authService; $this->moduleHandler = $moduleHandler; $this->imageStyleHelper = $imageStyleHelper; $this->damLoggerChannel = $this->getLogger('logger.channel.acquia_dam'); } /** * {@inheritdoc} */ public static function create(ContainerInterface $container) { return new static( $container->get('config.factory'), $container->get('http_client'), $container->get('acquia_dam.authentication_service'), $container->get('module_handler'), $container->get('acquia_dam.image_style_support') ); } /** * {@inheritdoc} */ public function getFormId() { return 'acquia_dam_config'; } /** * {@inheritdoc} */ protected function getEditableConfigNames() { return [ 'acquia_dam.settings', ]; } /** * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state): array { $config = $this->config('acquia_dam.settings'); if ($config->get('domain')) { $form['site_auth'] = [ '#type' => 'fieldset', '#title' => $this->t('Site authentication'), ]; $form['site_auth']['actions']['#type'] = 'actions'; if (!$this->authService->isSiteAuthenticated()) { $form['site_auth']['desc'] = [ '#markup' => '<p>' . $this->t('Authenticate your site with an Acquia DAM user account. It is recommended to use an Acquia DAM user account that has only view and download permissions.') . '</p>', ]; $auth_link = Url::fromRoute('acquia_dam.site_auth')->setAbsolute()->toString(); $form['site_auth']['actions']['authenticate_site'] = [ '#type' => 'link', '#title' => 'Authenticate Site', '#url' => Url::fromUri($this->authService->generateAuthUrl($auth_link)), '#cache' => [ 'max-age' => 0, ], '#attributes' => [ 'class' => ['button button--primary'], ], ]; } else { $form['site_auth']['desc'] = [ '#markup' => '<p>' . $this->t('Site is authenticated with Acquia DAM.') . '</p>', ]; $form['site_auth']['actions']['authenticate_site'] = [ '#type' => 'link', '#title' => 'Disconnect Site', '#url' => Url::fromRoute('acquia_dam.disconnect_site')->setAbsolute(), '#cache' => [ 'max-age' => 0, ], '#attributes' => [ 'class' => ['button', 'button--danger'], ], ]; } } $form['configuration'] = [ '#type' => 'fieldset', '#title' => $this->t('Acquia DAM configuration details'), ]; $form['configuration']['domain'] = [ '#type' => 'textfield', '#title' => $this->t('Acquia DAM Domain'), '#default_value' => $config->get('domain'), '#description' => $this->t('example: demo.acquiadam.com'), '#required' => TRUE, ]; $form['configuration']['actions']['#type'] = 'actions'; $form['configuration']['actions']['submit'] = [ '#type' => 'submit', '#value' => $this->t('Save DAM configuration'), '#button_type' => 'primary', ]; $image_styles = []; foreach ($this->imageStyleHelper->getImageStylesBySupportStatus()['supported'] as $styles) { $image_styles[$styles->id()] = $styles->label(); } $is_media_acquiadam_installed = $this->moduleHandler->moduleExists('media_acquiadam'); $form['configuration']['auth_type'] = [ '#type' => 'radios', '#access' => !$is_media_acquiadam_installed, '#default_value' => $config->get('auth_type'), '#options' => [ 'authorization_code' => $this->t('Authorization code (standard)'), 'refresh_token' => $this->t('Refresh token (more secure)'), ], 'authorization_code' => [ '#description' => $this->t('Standard connection using long-lived access token.'), '#disabled' => $this->authService->isUsingRefreshToken(), ], 'refresh_token' => [ '#description' => $this->t('Requires support assistance to enable an integration with refresh token support. Refresh tokens improve security by using short-lived access tokens. Disabled if Media Acquia DAM module is installed.'), ], ]; $form['configuration']['client_id'] = [ '#type' => 'textfield', '#access' => !$is_media_acquiadam_installed, '#title' => $this->t('OAuth Client ID'), '#default_value' => $config->get('client_id') ?? '', '#description' => $this->t('The client ID for your OAuth integration.'), '#states' => [ 'visible' => [ ':input[name="auth_type"]' => ['value' => 'refresh_token'], ], ], ]; $form['configuration']['client_secret'] = [ '#type' => 'textfield', '#access' => !$is_media_acquiadam_installed, '#title' => $this->t('OAuth Client secret'), '#default_value' => $config->get('client_secret') ?? '', '#description' => $this->t('The client secret for your OAuth integration.'), '#states' => [ 'visible' => [ ':input[name="auth_type"]' => ['value' => 'refresh_token'], ], ], ]; $form['configuration']['image_style'] = [ '#type' => 'checkboxes', '#description' => $this->t('Select which image style should be allowed to render Acquia DAM image assets.'), '#description_display' => 'before', '#title' => $this->t('Allowed image styles'), '#options' => $image_styles, '#default_value' => $config->get('allowed_image_styles') ?? [], '#size' => 6, '#multiple' => TRUE, ]; return $form; } /** * Save allowed image styles. * * @param array $form * Form. * @param \Drupal\Core\Form\FormStateInterface $form_state * Form state. */ public function saveImageStyles(array &$form, FormStateInterface $form_state): void { $checkboxes = $form_state->getValue('image_style') ?? []; $this->config('acquia_dam.settings') ->set('allowed_image_styles', array_filter($checkboxes)) ->save(); } /** * Validate that the provided values are valid or nor. * * @param array $form * Form array. * @param \Drupal\Core\Form\FormStateInterface $form_state * Form state instance. */ public function validateForm(array &$form, FormStateInterface $form_state): void { $domain = Xss::filter($form_state->getValue('domain')); if (!$domain) { $form_state->setErrorByName( 'domain', $this->t('Provided domain is not valid.') ); return; } $domain = preg_replace('#^https?://#', '', $domain); $domain = rtrim($domain, '/'); $form_state->setValue('domain', $domain); $this->validateDomain($form_state); } /** * Validates that the provided domain is valid. * * @param \Drupal\Core\Form\FormStateInterface $form_state * Form state instance. */ private function validateDomain(FormStateInterface $form_state): void { $domain = $form_state->getValue('domain'); // Generate the ping endpoint non-SSL URL of the configured domain. $endpoints = [ 'http' => 'http://' . $domain . '/collective.ping', 'https' => 'https://' . $domain . '/collective.ping', ]; foreach ($endpoints as $protocol => $endpoint) { try { // Process the response of the HTTP request. $response = $this->httpClient->get($endpoint); $status = $response->getStatusCode(); // If ping returns a successful HTTP response, display a confirmation // message. if ($status == '200') { $this->messenger()->addStatus($this->t('Validating domain (@protocol): OK!', [ '@protocol' => $protocol, ])); } else { // If failed, display an error message. $form_state->setErrorByName('domain', $this->t('Validating domain (@protocol): @status', [ '@protocol' => $protocol, '@status' => $status, ])); } } catch (TransferException $e) { $form_state->setErrorByName( 'domain', $this->t('Unable to connect to the domain. Please verify the domain is entered correctly.') ); } } } /** * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state): void { $current_domain = $this ->config('acquia_dam.settings') ->get('domain'); $new_domain = $form_state->getValue('domain'); // Handles domain swap when the site is already authenticated. if ($new_domain !== $current_domain && $this->authService->isSiteAuthenticated()) { try { $this->authService->disconnectSiteAndUsers(); } catch (\Exception $exception) { $this->messenger()->addMessage('Something went wrong during domain change. Please contact the site administrator for more information.'); $this->damLoggerChannel->error('Error during domain change: ' . $exception->getMessage()); return; } $this->messenger()->addMessage('Previous domain has been disconnected successfully. All user registration has been cancelled.'); } $this->config('acquia_dam.settings') ->set('domain', $new_domain) ->save(); if ($this->moduleHandler->moduleExists('media_acquiadam')) { $this->configFactory->getEditable('media_acquiadam.settings') ->set('domain', $new_domain) ->save(); } $auth_type = $form_state->getValue('auth_type') ?? 'authorization_code'; $this->config('acquia_dam.settings') ->set('auth_type', $auth_type) ->set('client_id', $auth_type === 'refresh_token' ? $form_state->getValue('client_id') : '') ->set('client_secret', $auth_type === 'refresh_token' ? $form_state->getValue('client_secret') : '') ->save(); // Authenticate only if the site isn't authenticated yet. // On domain change it will be disconnected first. if (!$this->authService->isSiteAuthenticated()) { $auth_link = Url::fromRoute('acquia_dam.site_auth')->setAbsolute()->toString(); $url = Url::fromUri($this->authService->generateAuthUrl($auth_link)); $form_state->setResponse(new TrustedRedirectResponse($url->toString())); } $this->saveImageStyles($form, $form_state); parent::submitForm($form, $form_state); } }