digital_signage_framework-2.3.x-dev/src/Plugin/DigitalSignageScheduleGenerator/Base.php

src/Plugin/DigitalSignageScheduleGenerator/Base.php
<?php

namespace Drupal\digital_signage_framework\Plugin\DigitalSignageScheduleGenerator;

use Drupal\digital_signage_framework\ContentSettingInterface;
use Drupal\digital_signage_framework\DefaultDuration;
use Drupal\digital_signage_framework\DefaultWeight;
use Drupal\digital_signage_framework\ScheduleGeneratorPluginBase;
use Drupal\digital_signage_framework\SequenceItem;
use Drupal\digital_signage_framework\WeightInterface;

/**
 * Plugin implementation of the digital_signage_schedule_generator.
 *
 * @DigitalSignageScheduleGenerator(
 *   id = "default",
 *   label = @Translation("Default Schedule Generator"),
 *   description = @Translation("Default Schedule Generator provided by the core digital signage framework.")
 * )
 */
class Base extends ScheduleGeneratorPluginBase {

  /**
   * {@inheritdoc}
   */
  public function generate($device, $contentSettings): array {
    $sequenceItems = [];
    $criticalSequenceItems = [];
    /** @var \Drupal\digital_signage_framework\ContentSettingInterface[] $nonCriticalEntities */
    $nonCriticalEntities = [];
    $nonChosenEntities = [];

    // @todo use dependency injection
    $duration = new DefaultDuration($this->settings);
    $weight = new DefaultWeight($this->settings);
    $weightSum = 0;

    foreach ($contentSettings as $contentSetting) {
      if ($contentSetting->isEnabled()) {
        if ($contentSetting->isCritical()) {
          $criticalSequenceItems[] = SequenceItem::create($contentSetting, $duration->getDurationByComplexity($contentSetting->getType()));
        }
        else {
          $nonCriticalEntities[] = $contentSetting;
          $nonChosenEntities[] = $contentSetting;
          $weightSum += $weight->getWeightByPriority($contentSetting->getPriority());
        }
      }
    }

    $weightMap = $this->getWeightMap($nonCriticalEntities, $weight);

    /** @var \Drupal\digital_signage_framework\ContentSettingInterface|null $contentEntityTmp */
    $contentEntityTmp = NULL;
    for ($i = 0; $i < $weightSum; $i++) {
      $contentEntity = $this->getNonCriticalEntity($weightMap, $weightSum);
      if ($contentEntityTmp !== NULL && $contentEntityTmp->getReverseEntityId() === $contentEntity->getReverseEntityId()) {
        continue;
      }
      /* @noinspection SlowArrayOperationsInLoopInspection */
      $sequenceItems = array_merge($sequenceItems, $criticalSequenceItems);
      $contentEntityTmp = $contentEntity;
      $sequenceItems[] = SequenceItem::create($contentEntity, $duration->getDurationByComplexity($contentEntity->getType()));

      // Remove from non chosen entity array.
      $key = array_search($contentEntity, $nonChosenEntities, TRUE);
      unset($nonChosenEntities[$key]);
    }

    usort($nonChosenEntities, [$this, 'sortItemsByPriority']);
    foreach ($nonChosenEntities as $nonChosenEntity) {
      /* @noinspection SlowArrayOperationsInLoopInspection */
      $sequenceItems = array_merge($sequenceItems, $criticalSequenceItems);
      $sequenceItems[] = SequenceItem::create($nonChosenEntity, $duration->getDurationByComplexity($nonChosenEntity->getType()));
    }
    return $sequenceItems;
  }

  /**
   * Sort by priority function for entities.
   *
   * @param \Drupal\digital_signage_framework\ContentSettingInterface $contentSetting
   *   The settings.
   * @param \Drupal\digital_signage_framework\ContentSettingInterface $otherContentSetting
   *   The other settings.
   *
   * @return int
   *   0, if both settings are equal, 1 if settings come after other settings,
   *   -1 otherwise.
   */
  private function sortItemsByPriority(ContentSettingInterface $contentSetting, ContentSettingInterface $otherContentSetting): int {
    if ($contentSetting->getPriority() === $otherContentSetting->getPriority()) {
      return 0;
    }
    return ($contentSetting->getPriority() < $otherContentSetting->getPriority()) ? -1 : 1;
  }

  /**
   * Returns a sequence item based on the given weight.
   *
   * @param \Drupal\digital_signage_framework\ContentSettingInterface[] $weightMap
   *   List of entities order by weight.
   * @param int $weightSum
   *   Max weight.
   *
   * @return \Drupal\digital_signage_framework\ContentSettingInterface
   *   One of the entities.
   */
  private function getNonCriticalEntity(array $weightMap, int $weightSum): ContentSettingInterface {
    $randomNumber = rand(1, $weightSum);
    foreach ($weightMap as $key => $value) {
      if ($randomNumber <= $key) {
        return $value;
      }
    }

    return end($weightMap);
  }

  /**
   * Returns a weighted array for entities.
   *
   * @param \Drupal\digital_signage_framework\ContentSettingInterface[] $nonCriticalEntities
   *   List of entities.
   * @param \Drupal\digital_signage_framework\WeightInterface $weight
   *   The weight service.
   *
   * @return \Drupal\digital_signage_framework\ContentSettingInterface[]
   *   Ordered list of entities.
   */
  private function getWeightMap(array $nonCriticalEntities, WeightInterface $weight): array {
    $weightMap = [];
    $calculatedSum = 0;
    foreach ($nonCriticalEntities as $contentEntity) {
      $relativeWeight = $weight->getWeightByPriority($contentEntity->getPriority());
      $calculatedSum += $relativeWeight;
      $weightMap[$calculatedSum] = $contentEntity;
    }

    return $weightMap;
  }

}

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

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