access_policy-1.0.x-dev/src/Plugin/access_policy/AccessRule/WeekdayRange.php

src/Plugin/access_policy/AccessRule/WeekdayRange.php
<?php

namespace Drupal\access_policy\Plugin\access_policy\AccessRule;

use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Core\Datetime\TimeZoneFormHelper;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Week day range access rule.
 *
 * @AccessRule(
 *   id = "weekday_range",
 * )
 */
class WeekdayRange extends AccessRuleBase {

  use StringTranslationTrait;

  /**
   * The config object.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected $configFactory;

  /**
   * Constructs a new WeekdayRange access rule.
   *
   * @param array $configuration
   *   A configuration array containing information about the plugin instance.
   * @param string $plugin_id
   *   The plugin_id for the plugin instance.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   The config object.
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, ConfigFactoryInterface $config_factory) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->configFactory = $config_factory;
  }

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

  /**
   * {@inheritdoc}
   */
  public function defaultSettings() {
    return [
      'weekday' => [],
      'start_time' => '',
      'end_time' => '',
      'all_day' => FALSE,
      'timezone_select' => 'default',
    ] + parent::defaultSettings();
  }

  /**
   * {@inheritdoc}
   */
  public function isApplicable(EntityInterface $entity) {
    return TRUE;
  }

  /**
   * {@inheritdoc}
   */
  public function accessRuleForm(array $form, FormStateInterface $form_state) {
    $form['weekday'] = [
      '#title' => $this->t('Weekday'),
      '#type' => 'checkboxes',
      '#options' => $this->getWeekdays(),
      '#description' => $this->t('Choose the days of the week you want to grant access to this content.'),
      '#default_value' => $this->settings['weekday'],
      '#required' => TRUE,
    ];
    $form['time_range'] = [
      '#type' => 'container',
      '#states' => [
        'visible' => [':input[name="all_day"]' => ['checked' => FALSE]],
      ],
    ];
    $form['time_range']['start_time'] = [
      '#type' => 'datetime',
      '#title' => $this->t('Start time'),
      '#date_date_element' => 'none',
      '#default_value' => $this->getDateTimeObj($this->settings['start_time']),
    ];
    $form['time_range']['end_time'] = [
      '#type' => 'datetime',
      '#title' => $this->t('End time'),
      '#date_date_element' => 'none',
      '#default_value' => $this->getDateTimeObj($this->settings['end_time']),
    ];
    $form['all_day'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('All day'),
      '#default_value' => $this->settings['all_day'],
    ];
    $form['timezone_select'] = [
      '#type' => 'select',
      '#title' => $this->t('Time zone'),
      '#default_value' => $this->settings['timezone_select'],
      '#options' => [
        // Default will do either site or current user.
        'default' => $this->t('Default'),
        'other' => $this->t('Other'),
      ],
    ];

    $system_date_config = $this->configFactory->get('system.date');
    $form['timezone'] = [
      '#type' => 'select',
      '#title' => $this->t('Select time zone'),
      '#default_value' => $this->settings['timezone'] ?? $system_date_config->get('timezone.default'),
      '#options' => TimeZoneFormHelper::getOptionsListByRegion(NULL),
      '#description' => $this->t('Select the desired time zone.'),
      '#states' => [
        'visible' => [':input[name="timezone_select"]' => ['value' => 'other']],
      ],
    ];

    return $form;
  }

  /**
   * Get the date time object.
   *
   * This is necessary in order to properly render the value in the form.
   *
   * @param string $time
   *   The current saved time in a specific format (e.g 9:00:00 AM).
   *
   * @return \Drupal\Core\Datetime\DrupalDateTime|string
   *   The drupal date time object.
   */
  protected function getDateTimeObj($time) {
    if (empty($time)) {
      return '';
    }
    return DrupalDateTime::createFromFormat('H:i:s', $time);
  }

  /**
   * Get the days of the week.
   *
   * @return array
   *   Array of the days of the week.
   */
  protected function getWeekdays() {
    return [
      'sun' => $this->t('Sunday'),
      'mon' => $this->t('Monday'),
      'tue' => $this->t('Tuesday'),
      'wed' => $this->t('Wednesday'),
      'thu' => $this->t('Thursday'),
      'fri' => $this->t('Friday'),
      'sat' => $this->t('Saturday'),
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function accessRuleFormSubmit(array &$form, FormStateInterface $form_state) {
    parent::accessRuleFormSubmit($form, $form_state);
    $values = $form_state->getValues();
    $this->settings['weekday'] = array_filter($values['weekday']);
    $this->settings['all_day'] = boolval($values['all_day']);

    if (!$values['all_day']) {
      $this->settings['start_time'] = $values['start_time'] ? $values['start_time']->format('H:i:s') : '';
      $this->settings['end_time'] = $values['end_time'] ? $values['end_time']->format('H:i:s') : '';
    }
    else {
      unset($this->settings['start_time']);
      unset($this->settings['end_time']);
    }

    $this->settings['timezone_select'] = $values['timezone_select'];
    if ($this->settings['timezone_select'] == 'other') {
      $this->settings['timezone'] = $values['timezone'];
    }
    else {
      unset($this->settings['timezone']);
    }
  }

  /**
   * {@inheritdoc}
   */
  public function accessRuleFormValidate(array &$form, FormStateInterface $form_state) {
    $all_day = $form_state->getValue('all_day');
    if (empty($all_day)) {
      if (empty($form_state->getValue('start_time'))) {
        $form_state->setErrorByName('start_time', "Start time is required.");
      }
      if (empty($form_state->getValue('end_time'))) {
        $form_state->setErrorByName('end_time', "End time is required.");
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public function validate(EntityInterface $entity, AccountInterface $account) {
    // Get the current day.
    $date = $this->getValue();
    $day = strtolower($date->format('D'));

    // If the day is not supported then return false.
    if (!in_array($day, $this->settings['weekday'])) {
      return FALSE;
    }

    if (!$this->settings['all_day']) {
      $timestamp = $date->getTimestamp();
      if ($timestamp < $this->getTimestampFromTime($this->settings['start_time']) || $timestamp > $this->getTimestampFromTime($this->settings['end_time'])) {
        return FALSE;
      }
    }

    return TRUE;
  }

  /**
   * {@inheritdoc}
   */
  public function getValue() {
    if (!$this->value) {
      $time_zone = $this->settings['timezone'] ?? NULL;
      $this->value = new DrupalDateTime('now', $time_zone);
    }

    return $this->value;
  }

  /**
   * Get the DrupalDateTime object for a specific daily time.
   *
   * This is the date in the format ready to be validated against.
   *
   * @param string $time
   *   The current time (e.g 9:00:00).
   *
   * @return int
   *   The DrupalDateTime object.
   */
  protected function getTimestampFromTime($time) {
    $time_zone = $this->settings['timezone'] ?? NULL;
    $datetime = new DrupalDateTime($time, $time_zone);
    return $datetime->getTimestamp();
  }

}

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

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