Preview:
<?php

namespace Drupal\pos_entity_cfp\Plugin;

use Drupal\Component\Plugin\PluginBase;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormBuilderInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Url;
use Drupal\file\Entity\File;
use Drupal\pos_entity_cfp\Form\CorrectionTextForm;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Base class for Cfp correction type plugins.
 */
abstract class CfpCorrectionTypeBase extends PluginBase implements CfpCorrectionTypeInterface, ContainerFactoryPluginInterface {

  use StringTranslationTrait;

  /**
   * Form builder.
   *
   * @var \Drupal\Core\Form\FormBuilderInterface
   */
  protected $formBuilder;

  /**
   * State to handle.
   *
   * @var string
   */
  protected $correctionState;

  /**
   * Correction order.
   *
   * @var int
   */
  protected $correctionOrder;

  /**
   * Cfp to handle.
   *
   * @var \Drupal\pos_entity_cfp\Entity\Cfp
   */
  protected $cfp;

  /**
   * @var \Drupal\Core\Session\AccountProxyInterface
   */
  protected $currentUser;

  /**
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * {@inheritdoc}
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, FormBuilderInterface $form_builder, AccountProxyInterface $account_proxy, EntityTypeManagerInterface $entity_type_manager) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->correctionState = $configuration['correctionState'];
    $this->cfp = $configuration['cfp'];
    $this->formBuilder = $form_builder;
    $this->currentUser = $account_proxy;
    $this->entityTypeManager = $entity_type_manager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('form_builder'),
      $container->get('current_user'),
      $container->get('entity_type.manager')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function getCorrectionState() {
    return $this->correctionState;
  }

  /**
   * {@inheritdoc}
   */
  public function getCorrectionOrder() {
    return $this->correctionOrder;
  }

  /**
   * {@inheritdoc}
   */
  public function getCfp() {
    return $this->cfp;
  }

  /**
   * {@inheritdoc}
   */
  public function startCorrection() {
    return TRUE;
  }

  /**
   * {@inheritdoc}
   */
  public function endCorrection() {
    return TRUE;
  }

  /**
   * Get correction config form.
   *
   * @return array
   *   Config form.
   */
  public function getCorrectionConfigForm() {
    return [];
  }

  /**
   * {@inheritdoc}
   */
  public function isCorrectionActive() {
    return $this->getCfp()->getState()->getId() === $this->getCorrectionState();
  }

  /**
   * Check if multiple.
   *
   * @return bool
   *   Is multiple.
   */
  public function isMultiple() {
    $definition = $this->getPluginDefinition();
    return isset($definition['multiple']) ? $definition['multiple'] : FALSE;
  }

  /**
   * Get correction text.
   */
  abstract public function getCorrectionText();

  /**
   * Get correction question element.
   */
  public function getCorrectionQuestionElement() {
    return $this->formBuilder->getForm(CorrectionTextForm::class, $this->getCfp(), $this->getCorrectionState(), $this->getPluginId());
  }

  /**
   * Returns if user has access to start correction.
   *
   * @return bool
   *   Returns if user has access to start correction.
   */
  public function userHasAccessToStartCorrection() {
    if ($this->cfp->getState()->getId() !== $this->correctionState) {
      return FALSE;
    }
    if ($this->cfp->isInCorrection()) {
      return FALSE;
    }
    return $this->currentUser->hasPermission('start cfp correction');
  }

  /**
   * Get correction operations form.
   */
  public function getCorrectionOperationsForm() {
    $state_item = $this->getCfp()->getState();
    $current_url = Url::fromRoute('<current>');
    if ($this->getCfp()->getSubState() != 'correction_started') {
      if ($this->userHasAccessToStartCorrection()) {
        $correction_data = $this->getCfp()->getCorrectionData($state_item->getId());
        $element['start_correction'] = [
          '#type' => 'link',
          '#title' => $this->t('Start correction @order', ['@order' => number_to_roman_representation($correction_data['number_of_corrections'] + 1)]),
          '#url' => Url::fromRoute('pos_entity_cfp.confirm_start_correction_user_cfp_form', [
            'cfp' => $this->getCfp()->id(),
            'destination' => $current_url->toString(),
          ]),
          '#attributes' => [
            'class' => ['button'],
          ],
        ];
      }
    }
    else {
      $element['start_correction'] = [
        '#type' => 'markup',
        '#markup' => '<div class="correction-info-text">' . $this->t('Correction is in progress') . '</div>',
      ];
      if ($this->currentUser->hasPermission('access correction form')) {
        $plugin_definition = $this->getCfp()->getCurrentStateCorrectionPlugin()->getPluginDefinition();
        $element['help_correction'] = [
          '#type' => 'link',
          '#title' => $this->t('Help applicant with correction'),
          '#url' => Url::fromRoute($plugin_definition['correction_form_route'], [
            'cfp' => $this->getCfp()->id(),
            'destination' => $current_url->toString(),
          ]),
          '#attributes' => [
            'class' => ['button'],
          ],
        ];
        $element['close_correction'] = [
          '#type' => 'link',
          '#title' => $this->t('Close correction'),
          '#url' => Url::fromRoute('pos_entity_cfp.confirm_correction_user_cfp_form', [
            'cfp' => $this->getCfp()->id(),
            'destination' => $current_url->toString(),
          ]),
          '#attributes' => [
            'class' => ['button'],
          ],
        ];
      }
    }
    return $element ?? [];
  }

  /**
   * Correction answers.
   */
  public function getCorrectionAnswersElement() {
    $correction_data = $this->getCfp()->getCorrectionData($this->getCorrectionState());
    $element = [];
    foreach ($correction_data['info'] as $correction_order => $correction_datum) {
      if (!is_numeric($correction_order)) {
        continue;
      }
      if (isset($correction_datum['started'])) {
        $started_date = DrupalDateTime::createFromTimestamp($correction_datum['started']);
        $started_date->setTimezone(new \DateTimeZone('Europe/Budapest'));
        $element[$correction_order]['started'] = [
          '#type' => 'item',
          '#title' => $this->t('Correction started'),
          '#markup' => $started_date->format('d/m/Y - H:i'),
        ];
      }
      if (isset($correction_datum['ended'])) {
        $ended_date = DrupalDateTime::createFromTimestamp($correction_datum['ended']);
        $ended_date->setTimezone(new \DateTimeZone('Europe/Budapest'));
        $element[$correction_order]['ended'] = [
          '#type' => 'item',
          '#title' => $this->t('Correction ended'),
          '#markup' => $ended_date->format('d/m/Y - H:i'),
        ];
      }
        if (isset($correction_data['info'][$correction_order]['correction_text'])) {
          $element[$correction_order][] = [
            '#type' => 'item',
            // @codingStandardsIgnoreStart
            '#title' => $this->t(ucfirst('correction') . ' text @order', [
              '@order' => number_to_roman_representation($correction_order + 1),
            ]),
            // @codingStandardsIgnoreEnd
            'markup' => ['#markup' => check_markup($correction_data['info'][$correction_order]['correction_text'])],
          ];
        }
        elseif (isset($correction_data['info'][$correction_order]['correction_text'])) {
          $element[$correction_order][] = [
            '#type' => 'item',
            // @codingStandardsIgnoreStart
            '#title' => $this->t(ucfirst('correction') . ' text @order', [
              '@order' => number_to_roman_representation($correction_order + 1),
            ]),
            // @codingStandardsIgnoreEnd
            'markup' => ['#markup' => check_markup($correction_data['info'][$correction_order]['correction_text'])],
          ];
        }


      if (isset($correction_datum['correction_answer_text']) && !empty($correction_datum['correction_answer_text'])) {
        $element[$correction_order]['correction_text'] = [
          '#type' => 'item',
          '#title' => t('Correction answer @order', ['@order' => number_to_roman_representation($correction_order + 1)]),
          '#markup' => check_markup($correction_datum['correction_answer_text']),
        ];
      }
      if (isset($correction_datum['correction_files']) && !empty($correction_datum['correction_files'])) {
        foreach ($correction_datum['correction_files'] as $delta => $fid) {
          $file = File::load($fid);
          $element[$correction_order]['correction_files'][$delta] = [
            '#theme' => 'file_link',
            '#file' => $file,
            '#cache' => [
              'tags' => $file->getCacheTags(),
            ],
          ];
        }
      }
      if (isset($element[$correction_order])) {
        $element[$correction_order]['#type'] = 'fieldset';
        $element[$correction_order]['#title'] = $this->t('Correction @order', ['@order' => number_to_roman_representation($correction_order + 1)]);
      }

      if (isset($correction_datum['started']) && !isset($correction_datum['ended'])) {
        $started_date = DrupalDateTime::createFromTimestamp($correction_datum['started']);
        $started_date->setTimezone(new \DateTimeZone('Europe/Budapest'));
        $now = DrupalDateTime::createFromTimestamp(time());
        $now->setTimezone(new \DateTimeZone('Europe/Budapest'));
        $days_limit = $this->pluginDefinition['correction_limit_in_days'];
        if ($started_date->diff($now)->d > $days_limit) {
          $element[$correction_order]['warning'] = [
            '#type' => 'markup',
            '#markup' => '<p class="correction-warning">' . $this->t('@number_of_days days limit expired!', [
              '@number_of_days' => $days_limit,
            ]) . '</p>',
          ];
        }
      }
    }
    if (!empty($element)) {
      $element['#type'] = 'container';
    }
    return $element;
  }

}
downloadDownload PNG downloadDownload JPEG downloadDownload SVG

Tip: You can change the style, width & colours of the snippet with the inspect tool before clicking Download!

Click to optimize width for Twitter