You are here

public function FillPdfSettingsForm::buildForm in FillPDF 8.4

Same name and namespace in other branches
  1. 5.0.x src/Form/FillPdfSettingsForm.php \Drupal\fillpdf\Form\FillPdfSettingsForm::buildForm()

Form constructor.

Parameters

array $form: An associative array containing the structure of the form.

\Drupal\Core\Form\FormStateInterface $form_state: The current state of the form.

Return value

array The form structure.

Overrides ConfigFormBase::buildForm

File

src/Form/FillPdfSettingsForm.php, line 130

Class

FillPdfSettingsForm
Configure FillPDF settings form.

Namespace

Drupal\fillpdf\Form

Code

public function buildForm(array $form, FormStateInterface $form_state) {
  $form = parent::buildForm($form, $form_state);
  $config = $this
    ->config('fillpdf.settings');

  // Get available scheme options.
  $scheme_options = $this->adminFormHelper
    ->schemeOptions([
    'public' => $this
      ->t('@scheme (discouraged)'),
    'private' => $this
      ->t('@scheme (recommended)'),
  ]);
  $form['allowed_schemes'] = [
    '#type' => 'checkboxes',
    '#title' => $this
      ->t('Allowed file storages'),
    '#default_value' => array_intersect(array_keys($scheme_options), $config
      ->get('allowed_schemes')),
    '#options' => $scheme_options,
    '#description' => $this
      ->t("You may choose one or more file storages to be available for storing generated PDF files with actual entity data; note that %public does not provide any access control.<br />If you don't choose any file storage, generated PDFs may only be sent to the browser instead of being stored.", [
      '%public' => $this
        ->t('Public files'),
    ]),
  ];
  $form['advanced_storage'] = [
    '#type' => 'details',
    '#title' => $this
      ->t('Advanced storage settings'),
  ];
  $file_default_scheme = $this
    ->config('system.file')
    ->get('default_scheme');
  $template_scheme_options = $this->adminFormHelper
    ->schemeOptions([
    $file_default_scheme => $this
      ->t('@scheme (site default)'),
  ]);
  $template_scheme = $config
    ->get('template_scheme');

  // Set an error if the previously configured scheme doesn't exist anymore.
  if ($template_scheme && !array_key_exists($template_scheme, $template_scheme_options)) {
    $this
      ->messenger()
      ->addError($this
      ->t('Your previously used file storage %previous_scheme is no longer available on this Drupal site, see the %system_settings. Please reset your default to an existing file storage.', [
      '%previous_scheme' => $template_scheme . '://',
      '%system_settings' => Link::createFromRoute($this
        ->t('File system settings'), 'system.file_system_settings')
        ->toString(),
    ]));

    // @todo: It would be helpful if we could use EntityQuery instead, see
    // https://www.drupal.org/project/fillpdf/issues/3043508.
    $map = $this->adminFormHelper
      ->getFormsByTemplateScheme($template_scheme);
    if ($count = count($map)) {
      $forms = FillPdfForm::loadMultiple(array_keys($map));
      $items = [];
      foreach ($map as $form_id => $file_uri) {
        $fillpdf_form = $forms[$form_id];
        $admin_title = current($fillpdf_form
          ->get('admin_title')
          ->getValue());

        // @todo: We can simpify this once an admin_title is #required,
        // see https://www.drupal.org/project/fillpdf/issues/3040776.
        $link = Link::fromTextAndUrl($admin_title ?: "FillPDF form {$fillpdf_form->id()}", $fillpdf_form
          ->toUrl());
        $items[$form_id] = new FormattableMarkup("@fillpdf_form: {$file_uri}", [
          '@fillpdf_form' => $link
            ->toString(),
        ]);
      }
      $error_message = [
        '#prefix' => $this
          ->t('Nevertheless, the following FillPDF forms will not work until their respective PDF templates have been moved to an existing file scheme:'),
        [
          '#theme' => 'item_list',
          '#items' => $items,
        ],
      ];
      $this
        ->messenger()
        ->addError(\Drupal::service('renderer')
        ->renderPlain($error_message));
    }
    $this
      ->logger('fillpdf')
      ->critical('File storage %previous_scheme is no longer available.' . $count ? " {$count} FillPDF forms are defunct." : '', [
      '%previous_scheme' => $template_scheme . '://',
    ]);
  }
  $form['advanced_storage']['template_scheme'] = [
    '#type' => 'radios',
    '#title' => $this
      ->t('Template storage'),
    '#default_value' => array_key_exists($template_scheme, $template_scheme_options) ? $template_scheme : $file_default_scheme,
    '#options' => $template_scheme_options,
    '#description' => $this
      ->t('This setting is used as the storage for uploaded templates; note that the use of %public is more efficient, but does not provide any access control.<br />Changing this setting will require you to migrate associated files and data yourself and is not recommended after you have uploaded a template.', [
      '%public' => t('Public files'),
    ]),
  ];
  $form['backend'] = [
    '#type' => 'radios',
    '#title' => $this
      ->t('PDF-filling service'),
    '#description' => $this
      ->t('This module requires the use of one of several external PDF manipulation tools. Choose the service you would like to use.'),
    '#default_value' => $config
      ->get('backend') ?: 'fillpdf_service',
    '#options' => [],
  ];
  foreach ($this->definitions as $id => $definition) {

    // Add a radio option for every backend plugin.
    $label = $definition['label'];
    $description = $definition['description'];
    $form['backend']['#options'][$id] = "<strong>{$label}</strong>" . ($description ? ": {$description}" : '');
  }
  $form['fillpdf_service'] = [
    '#type' => 'details',
    '#title' => $this
      ->t('Configure %label', [
      '%label' => $this->definitions['fillpdf_service']['label'],
    ]),
    '#open' => TRUE,
    '#states' => [
      'visible' => [
        ':input[name="backend"]' => [
          'value' => 'fillpdf_service',
        ],
      ],
    ],
  ];
  $form['fillpdf_service']['remote_endpoint'] = [
    '#type' => 'textfield',
    '#title' => $this
      ->t('Server endpoint'),
    '#default_value' => $config
      ->get('remote_endpoint'),
    '#description' => $this
      ->t('The endpoint for the FillPDF Service instance. This does not usually need to be changed, but you may want to if you have, for example, a <a href="https://fillpdf.io/hosting">private server</a>. Do not include the protocol, as this is determined by the <em>Use HTTPS?</em> setting below.'),
  ];
  $form['fillpdf_service']['fillpdf_service_api_key'] = [
    '#type' => 'textfield',
    '#title' => $this
      ->t('API Key'),
    '#default_value' => $config
      ->get('fillpdf_service_api_key'),
    '#description' => $this
      ->t('You need to sign up for an API key at <a href="@link">FillPDF Service</a>', [
      '@link' => Url::fromUri('https://fillpdf.io')
        ->toString(),
    ]),
  ];
  $form['fillpdf_service']['remote_protocol'] = [
    '#type' => 'radios',
    '#title' => $this
      ->t('Use HTTPS?'),
    '#description' => $this
      ->t('It is recommended to select <em>Use HTTPS</em> for this option. Doing so will help prevent
      sensitive information in your PDFs from being intercepted in transit between your server and the remote service. <strong>FillPDF Service will only work with HTTPS.</strong>'),
    '#default_value' => $config
      ->get('remote_protocol'),
    '#options' => [
      'https' => $this
        ->t('Use HTTPS'),
      'http' => $this
        ->t('Do not use HTTPS'),
    ],
  ];
  $form['local_service'] = [
    '#type' => 'details',
    '#title' => $this
      ->t('Configure %label', [
      '%label' => $this->definitions['local_service']['label'],
    ]),
    '#open' => TRUE,
    '#states' => [
      'visible' => [
        ':input[name="backend"]' => [
          'value' => 'local_service',
        ],
      ],
    ],
  ];
  $form['local_service_endpoint'] = [
    '#type' => 'textfield',
    '#title' => $this
      ->t('Configure FillPdf LocalServer endpoint (address)'),
    '#default_value' => $config
      ->get('local_service_endpoint'),
    '#description' => $this
      ->t("Enter the network address of your FillPDF LocalServer installation. If you are running the Docker container on port 8085 locally, then the address is <em>http://127.0.0.1:8085</em>."),
    '#group' => 'local_service',
  ];
  $form['pdftk'] = [
    '#type' => 'details',
    '#title' => $this
      ->t('Configure %label', [
      '%label' => $this->definitions['pdftk']['label'],
    ]),
    '#open' => TRUE,
    '#states' => [
      'visible' => [
        ':input[name="backend"]' => [
          'value' => 'pdftk',
        ],
      ],
    ],
  ];
  $form['pdftk_path'] = [
    '#type' => 'textfield',
    '#title' => $this
      ->t('Configure path to pdftk'),
    '#description' => $this
      ->t("If FillPDF is not detecting your pdftk installation, you can specify the full path to the program here. Include the program name as well. On many systems, <em>/usr/bin/pdftk</em> is a valid value. You can almost always leave this field blank. If you should set it, you'll probably know."),
    '#default_value' => $config
      ->get('pdftk_path') ?: 'pdftk',
    '#group' => 'pdftk',
  ];
  $form['shell_locale'] = [
    '#title' => $this
      ->t('Server locale'),
    '#group' => 'pdftk',
  ];
  if ($this->shellManager
    ->isWindows()) {
    $form['shell_locale'] += [
      '#type' => 'textfield',
      '#description' => $this
        ->t("The locale to be used to prepare the command passed to executables. The default, <kbd>'@default'</kbd>, should work in most cases. If that is not available on the server, @op.", [
        '@default' => '',
        '@op' => $this
          ->t('enter another locale'),
      ]),
      '#default_value' => $config
        ->get('shell_locale') ?: '',
    ];
  }
  else {
    $locales = $this->shellManager
      ->getInstalledLocales();

    // Locale names are unfortunately not standardized. 'locale -a' will give
    // 'en_US.UTF-8' on Mac OS systems, 'en_US.utf8' on most/all Unix systems.
    $default = isset($locales['en_US.UTF-8']) ? 'en_US.UTF-8' : 'en_US.utf8';
    $form['shell_locale'] += [
      '#type' => 'select',
      '#description' => $this
        ->t("The locale to be used to prepare the command passed to executables. The default, <kbd>'@default'</kbd>, should work in most cases. If that is not available on the server, @op.", [
        '@default' => $default,
        '@op' => $this
          ->t('choose another locale'),
      ]),
      '#options' => $locales,
      '#default_value' => $config
        ->get('shell_locale') ?: 'en_US.utf8',
    ];

    // @todo: We're working around Core issue #2190333, resp. #2854166.
    // Remove once one of these landed. See:
    // https://www.drupal.org/project/drupal/issues/2854166.
    $form['shell_locale']['#process'][] = [
      'Drupal\\Core\\Render\\Element\\Select',
      'processGroup',
    ];
    $form['shell_locale']['#pre_render'][] = [
      'Drupal\\Core\\Render\\Element\\Select',
      'preRenderGroup',
    ];
  }
  return $form;
}