competition-8.x-1.x-dev/src/Plugin/Validation/Constraint/CompetitionEntryConstraintValidator.php

src/Plugin/Validation/Constraint/CompetitionEntryConstraintValidator.php
<?php

namespace Drupal\competition\Plugin\Validation\Constraint;

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Session\AccountProxy;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\EntityRepositoryInterface;
use Drupal\Core\StringTranslation\TranslationManager;
use Drupal\Core\Config\ConfigFactory;
use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\competition\CompetitionInterface;
use Drupal\competition\CompetitionManager;

/**
 * Validates the CompetitionEntry constraint.
 */
class CompetitionEntryConstraintValidator extends ConstraintValidator implements ContainerInjectionInterface {
  /**
   * Validator 2.5 and upwards compatible execution context.
   *
   * @var \Symfony\Component\Validator\Context\ExecutionContextInterface
   */
  protected $context;

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * The entity repository.
   *
   * @var \Drupal\Core\Entity\EntityRepositoryInterface
   */
  protected $entityRepository;

  /**
   * The translation manager.
   *
   * @var \Drupal\Core\StringTranslation\TranslationManager
   */
  protected $translationManager;

  /**
   * The configuration factory.
   *
   * @var \Drupal\Core\Config\ConfigFactory
   */
  protected $configFactory;

  /**
   * The competition manager.
   *
   * @var \Drupal\competition\CompetitionManager
   */
  protected $competitionManager;

  /**
   * The current user.
   *
   * @var \Drupal\Core\Session\AccountProxy
   */
  protected $currentUser;

  /**
   * Constructs a new CompetitionEntryConstraintValidator.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   */
  public function __construct(EntityTypeManagerInterface $entity_type_manager, EntityRepositoryInterface $entity_repository, TranslationManager $translation_manager, ConfigFactory $config_factory, CompetitionManager $competition_manager, AccountProxy $current_user) {
    $this->entityTypeManager = $entity_type_manager;
    $this->entityRepository = $entity_repository;
    $this->translationManager = $translation_manager;
    $this->configFactory = $config_factory;
    $this->competitionManager = $competition_manager;
    $this->currentUser = $current_user;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('entity_type.manager'),
      $container->get('entity.repository'),
      $container->get('string_translation'),
      $container->get('config.factory'),
      $container->get('competition.manager'),
      $container->get('current_user')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function validate($entry, Constraint $constraint) {
    // Get the competition the entry belongs to, its entry limits and global
    // interval settings.
    $competition = $this->entityRepository
      ->loadEntityByConfigTarget(
        $entry->getEntityType()->getBundleEntityType(),
        $entry->bundle()
      );

    $limits = $competition
      ->getEntryLimits();

    $intervals = $this->configFactory
      ->get('competition.settings')
      ->get('intervals');

    $intervals_keyed = array_flip($intervals);

    // Validate competition.type.*.status.
    if ($competition->getStatus() != CompetitionInterface::STATUS_OPEN) {
      if (!$this->currentUser->hasPermission('administer competition entries')) {
        $this->context
          ->buildViolation($constraint->messageCompetitionClosed)
          ->setParameter('%cycle%', $competition->getCycleLabel())
          ->setParameter('%label%', $competition->label())
          ->atPath('type')
          ->addViolation();
      }
    }

    // Validate competition.type.*.entry_limit.require_user.
    if ($entry->getOwner()->isAnonymous() && !empty($limits->require_user)) {
      $this->context
        ->buildViolation($constraint->messageLimitRequireUser)
        ->atPath('uid')
        ->addViolation();
    }

    // Do no further validation for existing entries.
    if (!$entry->isNew()) {
      return;
    }

    // Pre-validation complete, now fetch any existing entries based on
    // current stub. Do not filter to entries within interval limit, so we can
    // split those out manually below for further validations.
    $results = $this->competitionManager
      ->getCompetitionEntries($entry);

    if (!empty($results)) {
      // Validate competition.type.*.entry_limit.count, unless unlimited entries
      // are accepted.
      // Note: entry_limit.count == 0 represents "unlimited".
      if ($limits->count > 0) {
        // Filter for entries submitted within most recent interval.
        $results_interval = [];

        switch ($limits->interval) {
          case 0:
            // Interval of 0 means within the cycle - results were already
            // filtered by cycle.
            $results_interval = $results;
            break;

          case $intervals_keyed['calendar day']:
            // Within current calendar day.
            $now = new DrupalDateTime();
            $date = $now->format('Y-m-d');
            $date_start = new DrupalDateTime($date . ' 00:00:00');
            $time_start = intval($date_start->format('U'));
            $date_end = new DrupalDateTime($date . ' 23:59:59');
            $time_end = intval($date_end->format('U'));

            foreach ($results as $id => $result) {
              if ($result->getCreatedTime() >= $time_start && $result->getCreatedTime() <= $time_end) {
                $results_interval[] = $id;
              }
            }
            break;

          default:
            // Within last $interval.
            foreach ($results as $id => $result) {
              if ($result->getCreatedTime() >= (REQUEST_TIME - $limits->interval)) {
                $results_interval[] = $id;
              }
            }
            break;
        }

        if (count($results_interval) >= $limits->count) {
          // User has already met their entry quota for the competition's
          // entry interval.
          $interval_label = ' in the last ' . $intervals[$limits->interval];
          switch ($limits->interval) {
            case 0:
              $interval_label = '';
              break;

            case $intervals_keyed['calendar day']:
              $interval_label = ' today';
              break;
          }

          $this->context
            ->buildViolation($constraint->messageLimitReached)
            ->setParameter('%cycle%', $competition->getCycleLabel())
            ->setParameter('%label%', $competition->label())
            ->setParameter('@count@', $limits->count . ' ' . $this->translationManager->formatPlural($limits->count, 'time', 'times'))
            ->setParameter('@interval@', $interval_label)
            ->atPath('cycle')
            ->addViolation();
        }
      }
    }
    else {
      // Validate competition.type.*.entry_limit.field_reentry.
      // If no entries were found when validating the single reentry field, user
      // is attempting to reenter when they've never actually entered before.
      // Note: the reentry field condition is incorporated into the query -.
      // @see CompetitionManager::getCompetitionEntries()
      if ($entry->isReentry) {
        $this->context
          ->buildViolation($constraint->messageReentryInvalidField)
          ->setParameter('%cycle%', $competition->getCycleLabel())
          ->setParameter('%label%', $competition->label())
          ->setParameter('@field@', $entry->{$limits->field_reentry}->getFieldDefinition()->getLabel())
          ->setParameter('%value%', $entry->{$limits->field_reentry}->getString())
          ->setCause('field_reentry')
          ->atPath('cycle')
          ->addViolation();
      }
    }

  }

}

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

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