src/Products/NotificationsBundle/Entity/Lists/ConditionList.php line 21

Open in your IDE?
  1. <?php
  2. namespace Products\NotificationsBundle\Entity\Lists;
  3. use App\Model\Query\ConditionQuery\Condition\ContainsCondition;
  4. use App\Model\Query\ConditionQuery\Condition\OverlapsCondition;
  5. use App\Model\Query\ConditionQuery\ConditionGroup;
  6. use App\Model\Query\ConditionQuery\ConditionGroupInterface;
  7. use App\Model\Query\ConditionQuery\ConditionQuery;
  8. use App\Model\Query\ConditionQuery\ConditionQueryListInterface;
  9. use Cms\CoreBundle\Entity\OneRoster\OneRosterUser;
  10. use Doctrine\ORM\Mapping as ORM;
  11. use Products\NotificationsBundle\Entity\AbstractList;
  12. use Products\NotificationsBundle\Util\ListBuilder\AbstractListBuilder;
  13. /**
  14.  * @ORM\Entity(
  15.  *     repositoryClass = "Products\NotificationsBundle\Doctrine\Repository\Lists\ConditionListRepository",
  16.  * )
  17.  */
  18. class ConditionList extends AbstractList implements ConditionQueryListInterface
  19. {
  20.     public const DISCR 'condition';
  21.     /**
  22.      * @var ConditionQuery
  23.      *
  24.      * @ORM\Column(
  25.      *     type = "condition_query",
  26.      *     nullable = false,
  27.      * )
  28.      */
  29.     protected ConditionQuery $conditionQuery;
  30.     /**
  31.      * @param ConditionQuery|null $conditionQuery
  32.      */
  33.     public function __construct(?ConditionQuery $conditionQuery null)
  34.     {
  35.         $this->conditionQuery $conditionQuery ?? new ConditionQuery();
  36.     }
  37.     /**
  38.      * @return ConditionQuery
  39.      */
  40.     public function getRunnableConditionQuery(): ConditionQuery
  41.     {
  42.         if ( ! $this->getTypes()) {
  43.             return $this->decorateSchool($this->getConditionQuery());
  44.         }
  45.         if ( ! $this->getConditionQuery()->getConditions()) {
  46.             return $this->decorateSchool($this->getConditionQuery());
  47.         }
  48.         return ($this->decorateSchool(new ConditionQuery(
  49.             $this->getConditionQuery()->getEntity(),
  50.             [
  51.                 new OverlapsCondition(
  52.                     sprintf(
  53.                         '%s.metadata/_role_type',
  54.                         ConditionQuery::ENTITY_ALIAS_MAP[ConditionQuery::PROFILE_ENTITY],
  55.                     ),
  56.                     $this->getTypeNames()
  57.                 ),
  58.                 new ConditionGroup(
  59.                     $this->getConditionQuery()->getConditions(),
  60.                     $this->getConditionQuery()->getMode(),
  61.                 ),
  62.             ],
  63.             ConditionGroupInterface::MODES__AND
  64.         )))
  65.             ->setEntityOverride($this->getConditionQuery()->hasEntityOverride())
  66.             ->setConditionConfig($this->getConditionQuery()->getConditionConfig())
  67.             ->setConditionContext($this);
  68.     }
  69.     /**
  70.      * {@inheritDoc}
  71.      */
  72.     public function getConditionQuery(): ConditionQuery
  73.     {
  74.         return $this->conditionQuery;
  75.     }
  76.     /**
  77.      * @param ConditionQuery $conditionQuery
  78.      * @return ConditionList
  79.      */
  80.     public function setConditionQuery(ConditionQuery $conditionQuery): self
  81.     {
  82.         $this->conditionQuery $conditionQuery->setEntityOverride(
  83.             $this->getConditionQuery()->hasEntityOverride(),
  84.         );
  85.         return $this;
  86.     }
  87.     /**
  88.      * @return bool
  89.      */
  90.     public function isEntityOverridable(): bool
  91.     {
  92.         return $this->getTypes() === OneRosterUser::TYPES__FAMILY;
  93.     }
  94.     /**
  95.      * {@inheritDoc}
  96.      */
  97.     public static function factory(?string $variant null): AbstractList
  98.     {
  99.         if ( ! $variant) {
  100.             throw new \RuntimeException();
  101.         }
  102.         $list = new self();
  103.         switch (true) {
  104.             case $variant === 'family':
  105.                 $list
  106.                     ->setTypes(OneRosterUser::TYPES__FAMILY)
  107.                     ->setConditionQuery(
  108.                         new ConditionQuery(ConditionQuery::PROFILE_ENTITY),
  109.                     );
  110.                 break;
  111.             case $variant === 'staff':
  112.                 $list
  113.                     ->setTypes(OneRosterUser::TYPES__STAFF)
  114.                     ->setConditionQuery(
  115.                         new ConditionQuery(ConditionQuery::PROFILE_ENTITY),
  116.                     );
  117.                 break;
  118.             case $variant === 'community':
  119.                 $list
  120.                     ->setTypes(OneRosterUser::TYPES__COMMUNITY)
  121.                     ->setConditionQuery(
  122.                         new ConditionQuery(ConditionQuery::PROFILE_ENTITY),
  123.                     );
  124.                 break;
  125.             case $variant === 'student':
  126.                 $list
  127.                     ->setTypes(OneRosterUser::TYPES__STUDENT)
  128.                     ->setConditionQuery(
  129.                         new ConditionQuery(ConditionQuery::PROFILE_ENTITY),
  130.                     );
  131.                 break;
  132.             default:
  133.                 throw new \RuntimeException();
  134.         }
  135.         return $list;
  136.     }
  137.     /**
  138.      * @return string
  139.      */
  140.     public function getEntity(): string
  141.     {
  142.         return $this->getConditionQuery()->getEntity(true);
  143.     }
  144.     /**
  145.      * @return string
  146.      */
  147.     public function getEntityClass(): string
  148.     {
  149.         return $this->getConditionQuery()->getEntityClass();
  150.     }
  151.     /**
  152.      * @return array<string>
  153.      */
  154.     public function getFilterableEntities(): array
  155.     {
  156.         return array_values(array_filter([
  157.             AbstractListBuilder::ENTITIES__PROFILES,
  158.             $this->isEntityOverridable() ? AbstractListBuilder::ENTITIES__PROFILE_RELATIONSHIPS null,
  159.             $this->isEntityOverridable() ? AbstractListBuilder::ENTITIES__STUDENTS null,
  160.         ]));
  161.     }
  162.     /**
  163.      * @param ConditionQuery $conditionQuery
  164.      * @return ConditionQuery
  165.      */
  166.     private function decorateSchool(ConditionQuery $conditionQuery): ConditionQuery
  167.     {
  168.         if ( ! $this->getSchool()) {
  169.             return $conditionQuery;
  170.         }
  171.         // if the school is a district level, we don't need to modify the query in any way
  172.         // the district school should cover the entire database
  173.         // we only care about filtering the list further if we have a non-district school
  174.         if ($this->getSchool()->isTypeDistrict()) {
  175.             return $conditionQuery;
  176.         }
  177.         // determine the entity we want to enforce the school checking on
  178.         // if we are building a staff or community list, we want to check against the profiles directly
  179.         // if we are doing a parent list, we really want to cross-check against the students
  180.         // NOTE: this assumes only a single type is allowed (as is currently coded 2024-05-20)
  181.         // if the system ever allows for mixed types when making a list, this logic will need changed...
  182.         $entity $conditionQuery->getEntity();
  183.         if ($this->hasType(OneRosterUser::TYPES__FAMILY)) {
  184.             $entity ConditionQuery::STUDENT_ENTITY;
  185.         }
  186.         return new ConditionQuery(
  187.             $conditionQuery->getEntity(),
  188.             [
  189.                 new ContainsCondition(
  190.                     ConditionQuery::ENTITY_ALIAS_MAP[$entity] . '.metadata/_orgs',
  191.                     $this->getSchool()->getOneRosterOrg()
  192.                 ),
  193.                 new ConditionGroup(
  194.                     $this->getConditionQuery()->getConditions(),
  195.                     $this->getConditionQuery()->getMode(),
  196.                 ),
  197.             ],
  198.             ConditionGroupInterface::MODES__AND
  199.         );
  200.     }
  201. }