You are here

public function XBBCodeTagForm::buildForm in Extensible BBCode 8.2

Parameters

$name: If passed, load this tag for editing. Otherwise, list all tags and show a collapsed tag creation form.

Overrides FormInterface::buildForm

File

src/Form/XBBCodeTagForm.php, line 35
Contains \Drupal\xbbcode\Form\XBBCodeTagForm.

Class

XBBCodeTagForm
List custom tags and edit or delete them.

Namespace

Drupal\xbbcode\Form

Code

public function buildForm(array $form, FormStateInterface $form_state, $name = NULL) {
  module_load_include('inc', 'xbbcode', 'xbbcode.crud');

  // Determine whether the user has loaded an existing tag for editing (via edit link).
  $editing_tag = !empty($name);

  // If the form was submitted, then a new tag is being added.
  $adding_tag = $form_state
    ->getValue('op') == $this
    ->t('Save');
  $access_php = Drupal::moduleHandler()
    ->moduleExists('php') && Drupal::currentUser()
    ->hasPermission('use PHP for settings');
  $use_php = FALSE;

  // The upshot is that if a tag is being edited or added, the otherwise optional fields become required.
  // If editing a tag, load this tag and populate the form with its values.
  if ($editing_tag) {
    $tag = xbbcode_custom_tag_load($name);
    if (!$tag) {
      throw new NotFoundHttpException();
    }
    $use_php = $tag->options['php'];
    $form['edit'] = [
      '#type' => 'fieldset',
      '#title' => $this
        ->t('Editing Tag %name', [
        '%name' => $name,
      ]),
      '#collapsible' => FALSE,
    ];
  }
  else {
    $tags = array_keys(xbbcode_custom_tag_load());

    // If any tags already exist, build a list for deletion and editing.
    if (!empty($tags)) {
      foreach ($tags as $tag) {
        if (!empty($tag)) {
          $options[$tag] = '[' . $tag . '] ' . Drupal::l($this
            ->t('Edit'), new Url('xbbcode.tag_edit', [
            'name' => $tag,
          ]));
        }
      }
      $form['existing'] = [
        '#type' => 'checkboxes',
        '#title' => $this
          ->t('Existing tags'),
        '#description' => $this
          ->t('Check these tags and click "Delete" to delete them.'),
        '#options' => $options,
      ];
    }
    else {

      // If no tags exist, then a new tag must be added now.
      $adding_tag = TRUE;
    }
    $form['edit'] = [
      '#type' => 'fieldset',
      '#title' => $this
        ->t('Create new tag'),
      '#collapsible' => TRUE,
      '#collapsed' => count($tags),
    ];

    // Create an empty tag.
    $tag = (object) [
      'name' => '',
      'description' => '',
      'markup' => '',
      'sample' => '',
    ];
  }

  // Regardless of whether a new tag or an existing tag is being edited,
  // show the edit form now. The fields are required only if a new tag is being
  // saved (during the submission phase), or if an existing tag is being edited.
  $form['edit']['name'] = [
    '#type' => 'textfield',
    '#title' => $this
      ->t('Tag name'),
    '#default_value' => $tag->name,
    '#field_prefix' => '[',
    '#field_suffix' => ']',
    '#required' => $editing_tag || $adding_tag,
    '#maxlength' => 32,
    '#size' => 16,
    '#description' => $this
      ->t('The name of this tag. The name will be used in the text as [name]...[/name]. Must be alphanumeric and will automatically be converted to lowercase.'),
  ];
  $form['edit']['description'] = [
    '#type' => 'textarea',
    '#title' => $this
      ->t('Description'),
    '#default_value' => $tag->description,
    '#required' => $editing_tag || $adding_tag,
    '#description' => $this
      ->t('This will be shown on help pages'),
  ];
  $form['edit']['sample'] = [
    '#type' => 'textfield',
    '#title' => $this
      ->t('Sample tag'),
    '#required' => $editing_tag || $adding_tag,
    '#description' => $this
      ->t('Enter an example of how this tag would be used. It will be shown on the help pages.'),
    '#default_value' => $tag->sample,
  ];
  $form['edit']['options'] = [
    '#type' => 'checkboxes',
    '#title' => $this
      ->t('Tag options'),
    '#options' => [
      'selfclosing' => $this
        ->t('The tag is self-closing and requires no closing tag, like <code>[hr]</code>).'),
    ],
  ];
  $form['edit']['php'] = [
    '#type' => 'checkbox',
    '#title' => $this
      ->t('Evaluate as PHP code.'),
    '#return_value' => TRUE,
    '#description' => $this
      ->t('This option requires the PHP module to be enabled, and the appropriate permission.'),
    '#default_value' => $use_php,
  ];
  foreach ($form['edit']['options']['#options'] as $key => $value) {
    if (!empty($tag->options[$key])) {
      $form['edit']['options']['#default_value'][] = $key;
    }
  }
  $form['edit']['markup'] = [
    '#type' => 'textarea',
    '#attributes' => [
      'style' => 'font-family:monospace',
    ],
    '#title' => $this
      ->t('Rendering code'),
    '#default_value' => $tag->markup,
    '#required' => $editing_tag || $adding_tag,
    '#description' => $this
      ->t('The text that [tag]content[/tag] should be replaced with, or PHP code that prints/returns the text.'),
  ];
  if (!$access_php) {
    $form['edit']['php']['#disabled'] = TRUE;
    $form['edit']['php']['#value'] = $form['edit']['php']['#default_value'];

    // Imitate the behavior of filter.module on forbidden formats.
    if ($use_php) {
      $form['edit']['markup']['#disabled'] = TRUE;
      $form['edit']['markup']['#resizable'] = FALSE;
      $form['edit']['markup']['#value'] = $form['edit']['markup']['#default_value'];
      $form['edit']['markup']['#pre_render'] = [
        'filter_form_access_denied',
      ];
    }
  }
  $form['edit']['help'] = [
    '#type' => 'markup',
    '#title' => $this
      ->t('Coding help'),
    '#markup' => $this
      ->t('<p>The above field should be filled either with HTML or PHP code depending on whether you enabled the PHP code option. PHP code must be placed in &lt;?php ?&gt; enclosures, or it will be
      printed literally.</p>
      <p>If your tag uses static HTML, then the tag\'s content and attributes will be inserted into your code by replacing placeholders. In PHP code, they will be available in the <code>$tag</code> object.</p>
      <dl>
        <dt><code>{content}</code> or <code>$tag->content</code></dt>
        <dd>The text between opening and closing tags, if the tag is not self-closing. Example: <code>[url=http://www.drupal.org]<strong>Drupal</strong>[/url]</code></dd>
        <dt><code>{option}</code> or <code>$tag->option</code></dt>
        <dd>The single tag attribute, if one is entered. Example: <code>[url=<strong>http://www.drupal.org</strong>]Drupal[/url]</code>.</dd>
        <dt>any other <code>{attribute}</code> or <code>$tag->attr(\'attribute\')</code></dt>
        <dd>The tag attribute of the same name, if it is entered. E.g: <strong>{by}</strong> or <strong><code>$tag->attr(\'by\')</code></strong> for <code>[quote&nbsp;by=<strong>Author</strong>&nbsp;date=2008]Text[/quote]</code>. If the attribute is not entered, the placeholder will be replaced with an empty string, and the <code>attr()</code> return value will be <code>NULL</code>.</dd>
      </dl>'),
  ];
  $form['edit']['submit'] = [
    '#type' => 'submit',
    '#value' => $this
      ->t('Save'),
    '#submit' => [
      '::_submitFormSave',
    ],
  ];
  if (!empty($name) || count($tags)) {
    $delete = [
      '#type' => 'submit',
      '#value' => $this
        ->t('Delete'),
      '#submit' => [
        '::_submitFormDelete',
      ],
    ];
    if (!empty($name)) {
      $form['edit']['delete'] = $delete;
    }
    else {
      $form['delete'] = $delete;
    }
  }
  return $form;
}