crossword-8.x-1.x-dev/src/Plugin/Field/FieldFormatter/CrosswordFormatter.php

src/Plugin/Field/FieldFormatter/CrosswordFormatter.php
<?php

namespace Drupal\crossword\Plugin\Field\FieldFormatter;

use Drupal\Component\Utility\Html;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\crossword\CrosswordDataServiceInterface;
use Drupal\file\FileInterface;
use Drupal\file\Plugin\Field\FieldFormatter\FileFormatterBase;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Plugin implementation of the 'crossword' formatter.
 *
 * @FieldFormatter(
 *   id = "crossword",
 *   label = @Translation("Crossword Puzzle"),
 *   weight = "1",
 *   field_types = {
 *     "crossword"
 *   }
 * )
 */
class CrosswordFormatter extends FileFormatterBase {

  /**
   * Crossword data service.
   *
   * @var \Drupal\crossword\CrosswordDataServiceInterface
   */
  protected $crosswordDataService;

  const BUTTONS = [
    'cheat' => 'Cheat',
    'solution' => 'Solution',
    'clear' => 'Clear',
    'undo' => 'Undo',
    'redo' => 'Redo',
    'instructions' => 'Instructions',
  ];

  /**
   * Constructs a FileDownloadLink object.
   *
   * @param string $plugin_id
   *   The plugin_id for the formatter.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
   *   The definition of the field to which the formatter is associated.
   * @param array $settings
   *   The formatter settings.
   * @param string $label
   *   The formatter label display setting.
   * @param string $view_mode
   *   The view mode.
   * @param array $third_party_settings
   *   Any third party settings.
   * @param \Drupal\crossword\CrosswordDataServiceInterface $crossword_data_service
   *   Token service.
   */
  public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, CrosswordDataServiceInterface $crossword_data_service) {
    parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings);
    $this->crosswordDataService = $crossword_data_service;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $plugin_id,
      $plugin_definition,
      $configuration['field_definition'],
      $configuration['settings'],
      $configuration['label'],
      $configuration['view_mode'],
      $configuration['third_party_settings'],
      $container->get('crossword.data_service')
    );
  }

  /**
   * {@inheritdoc}
   */
  public static function defaultSettings() {
    $options['redacted'] = FALSE;
    $options['print'] = TRUE;
    $options['congrats'] = 'Well done!';
    $options['details'] = [
      'title_tag' => 'h1',
      'author_tag' => 'h2',
      'notepad_tag' => 'p',
    ];
    $options['buttons']['class'] = NULL;
    $options['buttons']['buttons'] = [];
    foreach (CrosswordFormatter::BUTTONS as $key => $label) {
      switch ($key) {
        case 'clear':
          $confirm = 'Do you really want to clear? This action cannot be undone.';
          break;

        case 'solution':
          $confirm = 'Do you really want to give up?';
          break;

        default:
          $confirm = NULL;
      }
      $options['buttons']['buttons'][$key] = [
        'show' => TRUE,
        'input_label' => $label,
        'confirm' => $confirm,
      ];
    }
    $options['clues'] = [
      'do_not_render' => FALSE,
      'show' => FALSE,
      'checked' => FALSE,
      'input_label' => 'Show Clues',
    ];
    $options['errors'] = [
      'show' => TRUE,
      'checked' => FALSE,
      'input_label' => 'Show Errors',
    ];
    $options['references'] = [
      'show' => TRUE,
      'checked' => TRUE,
      'input_label' => 'Show References',
    ];
    $options['rebus'] = [
      'show' => FALSE,
      'input_label' => 'Rebus entry active',
    ];
    return $options;
  }

  /**
   * {@inheritdoc}
   */
  public function settingsForm(array $form, FormStateInterface $form_state) {
    $form = parent::settingsForm($form, $form_state);

    $field_name = $this->fieldDefinition->getName();

    $tag_options = [
      'h1' => 'h1',
      'h2' => 'h2',
      'h3' => 'h3',
      'h4' => 'h4',
      'p' => 'p',
      'div' => 'div',
      'span' => 'span',
    ];

    $form['redacted'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Redact Solution'),
      '#default_value' => $this->getSetting('redacted'),
      '#description' => $this->t('Redact data such that the solution is not directly available to the front end.'),
    ];
    $form['redacted_warning'] = [
      '#type' => 'container',
      '#markup' => $this->t('If the solution is redacted, it is advised that you hide the Solution button, the Cheat button, and the Show Errors checkbox. These features will not work while the solution is redacted.'),
      '#attributes' => [
        'class' => ['messages messages--warning'],
      ],
      '#states' => [
        'visible' => [
          ":input[name='fields[$field_name][settings_edit_form][settings][redacted]']" => ['checked' => TRUE],
        ],
      ],
    ];
    $form['print'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Print Styles'),
      '#default_value' => $this->getSetting('print'),
      '#description' => $this->t('Include the print stylesheet from the Crossword module.'),
    ];
    $form['congrats'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Congratulatory Message'),
      '#default_value' => $this->getSetting('congrats'),
      '#description' => $this->t('Plaintext message to display when the puzzle is solved successfully.'),
    ];
    $form['details'] = [
      '#type' => 'fieldset',
      '#title' => $this->t('Crossword Details'),
      '#tree' => TRUE,
    ];
    $form['details']['title_tag'] = [
      '#type' => 'select',
      '#title' => $this->t('Title'),
      '#default_value' => $this->getSetting('details')['title_tag'],
      '#options' => $tag_options,
      '#empty_option' => $this->t("Do not render the title"),
      '#prefix' => '<p>' . $this->t('Select the html tag to use for rendering these details.') . '</p>',
    ];
    $form['details']['author_tag'] = [
      '#type' => 'select',
      '#title' => $this->t('Author'),
      '#default_value' => $this->getSetting('details')['author_tag'],
      '#options' => $tag_options,
      '#empty_option' => $this->t("Do not render the author"),
    ];
    $form['details']['notepad_tag'] = [
      '#type' => 'select',
      '#title' => $this->t('Notepad'),
      '#default_value' => $this->getSetting('details')['notepad_tag'],
      '#options' => $tag_options,
      '#empty_option' => $this->t("Do not render the notepad"),
    ];

    if (!empty($this->getSetting('buttons'))) {
      $form['buttons'] = [
        '#type' => 'fieldset',
        '#title' => $this->t('Buttons'),
        '#tree' => TRUE,
      ];
      $form['buttons']['class'] = [
        '#type' => 'textfield',
        '#title' => $this->t('CSS Classes'),
        '#default_value' => $this->getSetting('buttons')['class'],
        '#description' => $this->t('Enter space-separated CSS classes to be added to the buttons.'),
      ];
      foreach (get_class($this)::BUTTONS as $key => $label) {
        $form['buttons']['buttons'][$key] = [
          '#type' => 'fieldset',
          '#title' => $this->t($label),
          '#tree' => TRUE,
          'show' => [
            '#type' => 'checkbox',
            '#title' => $this->t('Display Button'),
            '#default_value' => $this->getSetting('buttons')['buttons'][$key]['show'],
          ],
          'input_label' => [
            '#type' => 'textfield',
            '#title' => $this->t('Button Text'),
            '#default_value' => $this->getSetting('buttons')['buttons'][$key]['input_label'],
            '#states' => [
              'visible' => [
                ":input[name='fields[$field_name][settings_edit_form][settings][buttons][buttons][$key][show]']" => ['checked' => TRUE],
              ],
            ],
          ],
          'confirm' => [
            '#type' => 'textfield',
            '#title' => $this->t('Confirmation Message'),
            '#default_value' => $this->getSetting('buttons')['buttons'][$key]['confirm'],
            '#description' => $this->t('If empty, confirmation will not be required.'),
            '#states' => [
              'visible' => [
                ":input[name='fields[$field_name][settings_edit_form][settings][buttons][buttons][$key][show]']" => ['checked' => TRUE],
              ],
            ],
          ],
        ];
      }
    }
    if (!empty($this->getSetting('clues'))) {
      $form['clues'] = [
        '#type' => 'fieldset',
        '#title' => $this->t('Show Clues checkbox'),
        '#tree' => TRUE,
        'do_not_render' => [
          '#type' => 'checkbox',
          '#title' => $this->t('Do Not Render Clues'),
          '#default_value' => $this->getSetting('clues')['do_not_render'],
          '#description' => $this->t('If checked, clues will only be visible in the Active Clues container. The clue lists will not be rendered anywhere on the page, and there will be no button to toggle the visibility of the clue lists.'),
        ],
        'show' => [
          '#type' => 'checkbox',
          '#title' => $this->t('Display Checkbox'),
          '#default_value' => $this->getSetting('clues')['show'],
          '#states' => [
            'visible' => [
              ":input[name='fields[$field_name][settings_edit_form][settings][clues][do_not_render]']" => ['checked' => FALSE],
            ],
          ],
        ],
        'checked' => [
          '#type' => 'checkbox',
          '#title' => $this->t('Check by default'),
          '#default_value' => $this->getSetting('clues')['checked'],
          '#states' => [
            'visible' => [
              ":input[name='fields[$field_name][settings_edit_form][settings][clues][show]']" => ['checked' => TRUE],
            ],
            'invisible' => [
              ":input[name='fields[$field_name][settings_edit_form][settings][clues][do_not_render]']" => ['checked' => TRUE],
            ],
          ],
        ],
        'input_label' => [
          '#type' => 'textfield',
          '#title' => $this->t('Label'),
          '#default_value' => $this->getSetting('clues')['input_label'],
          '#states' => [
            'visible' => [
              ":input[name='fields[$field_name][settings_edit_form][settings][clues][show]']" => ['checked' => TRUE],
            ],
            'invisible' => [
              ":input[name='fields[$field_name][settings_edit_form][settings][clues][do_not_render]']" => ['checked' => TRUE],
            ],
          ],
        ],
      ];
    }
    if (!empty($this->getSetting('errors'))) {
      $form['errors'] = [
        '#type' => 'fieldset',
        '#title' => $this->t('Show Errors checkbox'),
        '#tree' => TRUE,
        'show' => [
          '#type' => 'checkbox',
          '#title' => $this->t('Display Checkbox'),
          '#default_value' => $this->getSetting('errors')['show'],
        ],
        'checked' => [
          '#type' => 'checkbox',
          '#title' => $this->t('Check by default'),
          '#default_value' => $this->getSetting('errors')['checked'],
          '#states' => [
            'visible' => [
              ":input[name='fields[$field_name][settings_edit_form][settings][errors][show]']" => ['checked' => TRUE],
            ],
          ],
        ],
        'input_label' => [
          '#type' => 'textfield',
          '#title' => $this->t('Label'),
          '#default_value' => $this->getSetting('errors')['input_label'],
          '#states' => [
            'visible' => [
              ":input[name='fields[$field_name][settings_edit_form][settings][errors][show]']" => ['checked' => TRUE],
            ],
          ],
        ],
      ];
    }
    if (!empty($this->getSetting('references'))) {
      $form['references'] = [
        '#type' => 'fieldset',
        '#title' => $this->t('Show References checkbox'),
        '#tree' => TRUE,
        'show' => [
          '#type' => 'checkbox',
          '#title' => $this->t('Display Checkbox'),
          '#default_value' => $this->getSetting('references')['show'],
        ],
        'checked' => [
          '#type' => 'checkbox',
          '#title' => $this->t('Check by default'),
          '#default_value' => $this->getSetting('references')['checked'],
          '#states' => [
            'visible' => [
              ":input[name='fields[$field_name][settings_edit_form][settings][references][show]']" => ['checked' => TRUE],
            ],
          ],
        ],
        'input_label' => [
          '#type' => 'textfield',
          '#title' => $this->t('Label'),
          '#default_value' => $this->getSetting('references')['input_label'],
          '#states' => [
            'visible' => [
              ":input[name='fields[$field_name][settings_edit_form][settings][references][show]']" => ['checked' => TRUE],
            ],
          ],
        ],
      ];
    }
    if (!empty($this->getSetting('rebus'))) {
      $form['rebus'] = [
        '#type' => 'fieldset',
        '#title' => $this->t('Rebus Entry checkbox'),
        '#tree' => TRUE,
        'show' => [
          '#type' => 'checkbox',
          '#title' => $this->t('Always Display Checkbox'),
          '#default_value' => $this->getSetting('rebus')['show'],
          '#description' => $this->t('If checked, the rebus entry button will always appear with the puzzle. If un-checked, the rebus entry checkbox will only be displayed on rebus puzzles.'),
        ],
        'input_label' => [
          '#type' => 'textfield',
          '#title' => $this->t('Label'),
          '#default_value' => $this->getSetting('rebus')['input_label'],
        ],
      ];
    }

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function settingsSummary() {
    $return = [];
    if ($this->getSetting('redacted')) {
      $return[] = $this->t('Solution redacted');
    }
    else {
      $return[] = $this->t('Solution is public');
    }
    return $return;
  }

  /**
   * {@inheritdoc}
   */
  public function viewElements(FieldItemListInterface $items, $langcode) {
    $elements = [];
    foreach ($this->getEntitiesToView($items, $langcode) as $delta => $file) {

      $data = $this->crosswordDataService->getData($file, $this->getSetting('redacted'));

      $elements[$delta] = [
        '#theme' => 'crossword',
        '#pseudofield' => $this->getPluginId() == 'crossword_pseudofields',
        '#field_formatter' => $this->getPluginId(),
        '#content' => [
          'title' => $this->getTitle($data),
          'author' => $this->getAuthor($data),
          'notepad' => $this->getNotepad($data),
          'across' => $this->getClues($data, 'across'),
          'down' => $this->getClues($data, 'down'),
          'grid' => $this->getGrid($file),
          'controls' => $this->getControls($file),
          'active_clue' => [
            '#theme' => 'crossword_active_clues',
            '#congrats' => $this->getSetting('congrats'),
            '#pseudofield' => $this->getPluginId() == 'crossword_pseudofields',
            '#field_formatter' => $this->getPluginId(),
          ],
        ],
        '#attached' => [
          'library' => [
            'crossword/crossword.default',
            $this->getSetting('print') ? 'crossword/crossword.print' : '',
          ],
          'drupalSettings' => [
            'crossword' => [
              'data' => $data,
              'selector' => '.crossword',
              'congrats' => $this->getSetting('congrats') ?? NULL,
            ],
          ],
        ],
        '#attributes' => [
          'class' => [
            $this->getSetting('errors')['show'] && $this->getSetting('errors')['checked'] ? 'show-errors' : '',
            $this->getSetting('references')['show'] && $this->getSetting('references')['checked'] ? 'show-references' : '',
            $this->getSetting('clues')['show'] && !$this->getSetting('clues')['checked'] ? 'hide-clues' : '',
          ],
        ],
        '#cache' => [
          'tags' => $file->getCacheTags(),
        ],
      ];
    }
    return $elements;
  }

  /**
   * Return render array for crossword title.
   */
  protected function getTitle($data) {
    if ($this->getSetting('details')['title_tag']) {
      return [
        '#type' => 'html_tag',
        '#tag' => $this->getSetting('details')['title_tag'],
        '#value' => $data['title'],
        '#attributes' => [
          'class' => [
            'crossword-title',
          ],
        ],
      ];
    }
  }

  /**
   * Return render array for crossword author.
   */
  protected function getAuthor($data) {
    if ($this->getSetting('details')['author_tag'] && !empty($data['author'])) {
      return [
        '#type' => 'html_tag',
        '#tag' => $this->getSetting('details')['author_tag'],
        '#value' => $data['author'],
        '#attributes' => [
          'class' => [
            'crossword-author',
          ],
        ],
      ];
    }
  }

  /**
   * Return render array for crossword notes.
   */
  protected function getNotepad($data) {
    if ($this->getSetting('details')['notepad_tag'] && !empty($data['notepad'])) {
      return [
        '#type' => 'html_tag',
        '#tag' => $this->getSetting('details')['notepad_tag'],
        '#value' => nl2br($data['notepad']),
        '#attributes' => [
          'class' => [
            'crossword-notepad',
          ],
        ],
      ];
    }
  }

  /**
   * Get render array for clues.
   */
  protected function getClues($data, $direction) {
    if (isset($this->getSetting('clues')['do_not_render']) && $this->getSetting('clues')['do_not_render']) {
      return;
    }
    $render = [
      '#theme' => 'crossword_clues',
      '#pseudofield' => $this->getPluginId() == 'crossword_pseudofields',
      '#field_formatter' => $this->getPluginId(),
      '#content' => [],
      '#direction' => $direction,
      // It's ok to translate $direction because it only takes two values.
      '#direction_label' => $this->t(ucfirst($direction), [], ['context' => 'crossword']),
      '#attributes' => [
        'class' => [$direction],
      ],
    ];
    if (!empty($data['puzzle']['clues'][$direction])) {
      foreach ($data['puzzle']['clues'][$direction] as $index => $clue) {
        $render['#content'][] = [
          '#theme' => 'crossword_clue',
          '#pseudofield' => $this->getPluginId() == 'crossword_pseudofields',
          '#text' => [
            '#markup' => $clue['text'],
          ],
          '#numeral' => $clue['numeral'],
          '#direction' => $direction,
          '#direction_label' => $this->t(ucfirst($direction), [], ['context' => 'crossword']),
          '#attributes' => [
            "data-clue-index-$direction" => (string) $index,
            "data-clue-numeral-$direction" => $clue['numeral'],
          ],
        ];
      }
    }
    return $render;
  }

  /**
   * Return render array for crossword grid.
   */
  protected function getGrid(FileInterface $file, $show_fill = FALSE) {
    $data = $this->crosswordDataService->getData($file, $this->getSetting('redacted'));
    $render = [
      '#theme' => 'crossword_grid',
      '#pseudofield' => $this->getPluginId() == 'crossword_pseudofields',
      '#field_formatter' => $this->getPluginId(),
      '#content' => [],
      '#attributes' => [
        'class' => [
          'crossword-grid',
          'crossword-columns-' . $this->crosswordDataService->getDimensionAcross($file),
          'crossword-rows-' . $this->crosswordDataService->getDimensionDown($file),
        ],
      ],
    ];
    if (!empty($data['puzzle']['grid'])) {
      foreach ($data['puzzle']['grid'] as $row_index => $grid_row) {
        $render_row = [
          '#theme' => 'crossword_grid_row',
          '#pseudofield' => $this->getPluginId() == 'crossword_pseudofields',
          '#field_formatter' => $this->getPluginId(),
          '#content' => [],
        ];
        foreach ($grid_row as $col_index => $square) {
          if ($square['fill'] === NULL) {
            $render_row['#content'][] = [
              '#theme' => 'crossword_square',
              '#image' => $this->getEmbeddedImage($square),
              '#pseudofield' => $this->getPluginId() == 'crossword_pseudofields',
              '#field_formatter' => $this->getPluginId(),
              '#attributes' => [
                'data-col' => (string) $col_index,
                'data-row' => (string) $row_index,
                'class' => [
                  'black',
                ],
              ],
            ];
          }
          else {
            $render_row['#content'][] = [
              '#theme' => 'crossword_square',
              '#pseudofield' => $this->getPluginId() == 'crossword_pseudofields',
              '#field_formatter' => $this->getPluginId(),
              '#fill' => $show_fill ? strtoupper($square['fill']) : NULL,
              '#numeral' => isset($square['numeral']) ? $square['numeral'] : NULL,
              '#attributes' => [
                'data-col' => (string) $col_index,
                'data-row' => (string) $row_index,
                'data-clue-index-across' => isset($square['across']['index']) ? (string) $square['across']['index'] : NULL,
                'data-clue-index-down' => isset($square['down']['index']) ? (string) $square['down']['index'] : NULL,
                'data-numeral' => isset($square['numeral']) ? $square['numeral'] : NULL,
                'data-fill' => $square['fill'],
                'data-circle' => $square['circle'],
                'data-rebus' => $square['rebus'],
                'data-hint' => isset($square['hint']),
              ],
            ];
          }
        }
        $render['#content'][] = $render_row;
      }
    }
    return $render;
  }

  /**
   * Return render array of crossword controls.
   *
   * If the solution is redacted the following controls are not rendered:
   * errors, cheat, solution.
   */
  protected function getControls(FileInterface $file) {
    $controls = [
      '#theme' => 'crossword_controls',
      '#pseudofield' => $this->getPluginId() == 'crossword_pseudofields',
      '#field_formatter' => $this->getPluginId(),
      '#content' => [
        'clues' => $this->getShowCluesCheckbox(),
        'errors' => $this->getShowErrorsCheckbox(),
        'references' => $this->getShowReferencesCheckbox(),
        'rebus' => $this->getRebusEntryCheckbox($file),
        'cheat' => $this->getButton('cheat'),
        'solution' => $this->getButton('solution'),
        'clear' => $this->getButton('clear'),
        'undo' => $this->getButton('undo'),
        'redo' => $this->getButton('redo'),
        'instructions' => $this->getButton('instructions'),
        'instructions_details' => $this->getInstructionsDetails($file),
      ],
    ];
    return $controls;
  }

  /**
   * Return render array for clues checkbox.
   */
  protected function getShowCluesCheckbox() {
    if (isset($this->getSetting('clues')['do_not_render']) && $this->getSetting('clues')['do_not_render']) {
      return;
    }
    if ($this->getSetting('clues')['show']) {
      return [
        '#type' => 'checkbox',
        '#title' => $this->getSetting('clues')['input_label'],
        '#title_display' => 'after',
        '#label_for' => 'show-clues',
        '#attributes' => [
          'class' => [
            'show-clues',
            'crossword-input',
          ],
          'checked' => $this->getSetting('clues')['checked'] ? "checked" : NULL,
          'name' => 'show-clues',
          'id' => 'show-clues',
        ],
      ];
    }
  }

  /**
   * Return render array for show errors checkbox.
   */
  protected function getShowErrorsCheckbox() {
    if ($this->getSetting('errors')['show']) {
      return [
        '#type' => 'checkbox',
        '#title' => $this->getSetting('errors')['input_label'],
        '#title_display' => 'after',
        '#label_for' => 'show-errors',
        '#attributes' => [
          'class' => [
            'show-errors',
            'crossword-input',
          ],
          'checked' => $this->getSetting('errors')['checked'] ? "checked" : NULL,
          'name' => 'show-errors',
          'id' => 'show-errors',
        ],
      ];
    }
  }

  /**
   * Return render array for show references checkbox.
   */
  protected function getShowReferencesCheckbox() {
    if ($this->getSetting('references')['show']) {
      return [
        '#type' => 'checkbox',
        '#title' => $this->getSetting('references')['input_label'],
        '#title_display' => 'after',
        '#label_for' => 'show-references',
        '#attributes' => [
          'class' => [
            'show-references',
            'crossword-input',
          ],
          'checked' => $this->getSetting('references')['checked'] ? "checked" : NULL,
          'name' => 'show-references',
          'id' => 'show-references',
        ],
      ];
    }
  }

  /**
   * Return render array for rebus entry checkbox.
   */
  protected function getRebusEntryCheckbox($file) {
    if ($this->getSetting('rebus')['show'] || $this->crosswordDataService->isRebus($file)) {
      return [
        '#type' => 'checkbox',
        '#title' => $this->getSetting('rebus')['input_label'],
        '#title_display' => 'after',
        '#label_for' => 'rebus-entry',
        '#attributes' => [
          'class' => [
            'rebus-entry',
            'crossword-input',
          ],
          'checked' => NULL,
          'name' => 'rebus-entry',
          'id' => 'rebus-entry',
        ],
      ];
    }
  }

  /**
   * Return render array of various buttons.
   */
  protected function getButton($name) {
    if (isset($this->getSetting('buttons')['buttons'][$name]['show']) && $this->getSetting('buttons')['buttons'][$name]['show']) {
      $class = ["button-$name"];
      if (isset($this->getSetting('buttons')['class'])) {
        $custom_classes = explode(" ", $this->getSetting('buttons')['class']);
        foreach ($custom_classes as $custom_class) {
          $class[] = Html::getClass($custom_class);
        }
      }
      return [
        '#type' => 'html_tag',
        '#tag' => 'button',
        '#value' => $this->getSetting('buttons')['buttons'][$name]['input_label'],
        '#attributes' => [
          'class' => $class,
          'data-confirm' => $this->getSetting('buttons')['buttons'][$name]['confirm'] ?? NULL,
          'title' => $this->getSetting('buttons')['buttons'][$name]['input_label'],
        ],
      ];
    }
  }

  /**
   * Return render array of instructions text, not just the button.
   */
  protected function getInstructionsDetails($file){
    if (isset($this->getSetting('buttons')['buttons']['instructions']['show']) && $this->getSetting('buttons')['buttons']['instructions']['show']) {
      return [
        '#theme' => 'crossword_instructions',
        '#field_formatter' => $this->getPluginId(),
        '#rebus' => $this->getSetting('rebus')['show'] || $this->crosswordDataService->isRebus($file),
        '#cheat' => isset($this->getSetting('buttons')['buttons']['cheat']['show']) && $this->getSetting('buttons')['buttons']['cheat']['show'],
        '#errors' => $this->getSetting('errors')['show'],
        '#attached' => [
          'library' => ['crossword/crossword.instructions'],
        ],
      ];
    }
  }

  /**
   * Return render array for embedded base64 image.
   */
  protected function getEmbeddedImage($square) {
    if (isset($square['image'])) {
      return [
        '#type' => 'html_tag',
        '#tag' => 'img',
        '#attributes' => [
          'src' => "data:image/{$square['image']['format']};base64,{$square['image']['data']}",
          'class' => [
            'crossword-embedded-image',
            'width-' . $square['image']['width'],
            'height-' . $square['image']['height'],
          ],
          'alt' => '',
          'role' => 'presentation',
        ],
      ];
    }
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc