src/Cms/CoreBundle/Entity/OneRosterSync.php line 31

Open in your IDE?
  1. <?php
  2. namespace Cms\CoreBundle\Entity;
  3. use App\Entity\Shared\FlagsInterface;
  4. use App\Entity\Shared\FlagsTrait;
  5. use App\Model\Async\StringSemaphoreInterface;
  6. use App\Model\Async\StringSemaphoreTrait;
  7. use App\Model\Schedule\ScheduleInterface;
  8. use App\Model\Schedule\ScheduleTrait;
  9. use Cms\CoreBundle\Entity\OneRoster\OneRosterOrg;
  10. use Cms\CoreBundle\Service\OneRoster\AbstractOneRosterApi;
  11. use Cms\TenantBundle\Entity\TenantedEntity;
  12. use Doctrine\Common\Collections\ArrayCollection;
  13. use Doctrine\Common\Collections\Collection;
  14. use Doctrine\Common\Collections\Criteria;
  15. use Doctrine\ORM\Mapping as ORM;
  16. use Reinder83\BinaryFlags\Bits;
  17. /**
  18.  * Class OneRosterSync
  19.  * @package Cms\CoreBundle\Entity
  20.  *
  21.  * @ORM\Entity(
  22.  *     repositoryClass = "Cms\CoreBundle\Doctrine\OneRosterSyncRepository"
  23.  * )
  24.  * @ORM\Table(
  25.  *      name = "cms__one_roster__sync",
  26.  * )
  27.  */
  28. class OneRosterSync extends TenantedEntity implements FlagsInterfaceStringSemaphoreInterfaceScheduleInterface
  29. {
  30.     const STRATEGIES = [
  31.         'notifications__staff' => self::STRATEGIES__NOTIFICATIONS__STAFF,
  32.         'notifications__family' => self::STRATEGIES__NOTIFICATIONS__FAMILY,
  33.         'notifications__students' => self::STRATEGIES__NOTIFICATIONS__STUDENTS,
  34.         'notifications__community' => self::STRATEGIES__NOTIFICATIONS__COMMUNITY,
  35.         'sso' => self::STRATEGIES__SSO,
  36.         'directories' => self::STRATEGIES__DIRECTORIES,
  37.         'schools' => self::STRATEGIES__SCHOOLS,
  38.     ];
  39.     const STRATEGIES__NOTIFICATIONS = [
  40.         'notifications__staff' => self::STRATEGIES__NOTIFICATIONS__STAFF,
  41.         'notifications__family' => self::STRATEGIES__NOTIFICATIONS__FAMILY,
  42.         'notifications__students' => self::STRATEGIES__NOTIFICATIONS__STUDENTS,
  43.         'notifications__community' => self::STRATEGIES__NOTIFICATIONS__COMMUNITY,
  44.     ];
  45.     const STRATEGIES__NOTIFICATIONS__STAFF Bits::BIT_1;
  46.     const STRATEGIES__NOTIFICATIONS__FAMILY Bits::BIT_2;
  47.     const STRATEGIES__NOTIFICATIONS__STUDENTS Bits::BIT_3;
  48.     const STRATEGIES__NOTIFICATIONS__COMMUNITY Bits::BIT_4;
  49.     const STRATEGIES__SSO Bits::BIT_17;
  50.     const STRATEGIES__DIRECTORIES Bits::BIT_18;
  51.     const STRATEGIES__SCHOOLS Bits::BIT_19;
  52.     // NOTE: order of arrays for each strategy matters!
  53.     const ONEROSTER_TYPES_MAPPINGS = [
  54.         self::STRATEGIES__NOTIFICATIONS__STAFF => AbstractOneRosterEntity::ONEROSTER_TYPES,
  55.         self::STRATEGIES__NOTIFICATIONS__FAMILY => AbstractOneRosterEntity::ONEROSTER_TYPES,
  56.         self::STRATEGIES__NOTIFICATIONS__STUDENTS => AbstractOneRosterEntity::ONEROSTER_TYPES,
  57.         self::STRATEGIES__NOTIFICATIONS__COMMUNITY => AbstractOneRosterEntity::ONEROSTER_TYPES,
  58.         self::STRATEGIES__SSO => AbstractOneRosterEntity::ONEROSTER_TYPES,
  59.         self::STRATEGIES__DIRECTORIES => AbstractOneRosterEntity::ONEROSTER_TYPES,
  60.         self::STRATEGIES__SCHOOLS => [
  61.             OneRosterOrg::ONEROSTER_TYPE => OneRosterOrg::class,
  62.         ],
  63.     ];
  64.     const FLAGS = [
  65.         'single_school' => self::FLAGS__SINGLE_SCHOOL,
  66.         'skip_twilio_lookups' => self::FLAGS__SKIP_TWILIO_LOOKUPS,
  67.         'ignore_enabled_user_property' => self::FLAGS__IGNORE_ENABLED_USER_PROPERTY,
  68.         'powerschool__skip_emergency_contacts' => self::FLAGS__POWERSCHOOL__SKIP_EMERGENCY_CONTACTS,
  69.     ];
  70.     const FLAGS__SINGLE_SCHOOL Bits::BIT_1;
  71.     const FLAGS__SKIP_TWILIO_LOOKUPS Bits::BIT_2;
  72.     const FLAGS__IGNORE_ENABLED_USER_PROPERTY Bits::BIT_3;
  73.     const FLAGS__POWERSCHOOL__SKIP_EMERGENCY_CONTACTS Bits::BIT_17;
  74.     use FlagsTrait;
  75.     use StringSemaphoreTrait;
  76.     use ScheduleTrait;
  77.     /**
  78.      * @var int
  79.      *
  80.      * @ORM\Column(
  81.      *     type = "integer",
  82.      *     nullable = false,
  83.      *     options = {
  84.      *         "unsigned" = true,
  85.      *         "default" = 0,
  86.      *     },
  87.      * )
  88.      */
  89.     protected int $strategies 0;
  90.     /**
  91.      * @var string|null
  92.      *
  93.      * @ORM\Column(
  94.      *     type = "string",
  95.      *     nullable = false,
  96.      * )
  97.      */
  98.     protected ?string $vendor null;
  99.     /**
  100.      * @var string|null
  101.      *
  102.      * @ORM\Column(
  103.      *     type = "string",
  104.      *     nullable = false,
  105.      * )
  106.      */
  107.     protected ?string $apiClientId null;
  108.     /**
  109.      * @var string|null
  110.      *
  111.      * @ORM\Column(
  112.      *     type = "string",
  113.      *     nullable = false,
  114.      * )
  115.      */
  116.     protected ?string $apiClientSecret null;
  117.     /**
  118.      * @var string|null
  119.      *
  120.      * @ORM\Column(
  121.      *     type = "string",
  122.      *     nullable = true,
  123.      * )
  124.      */
  125.     protected ?string $apiAppName null;
  126.     /**
  127.      * @var array
  128.      *
  129.      * @ORM\Column(
  130.      *     type = "json",
  131.      *     nullable = true,
  132.      * )
  133.      */
  134.     protected array $apiToken = [];
  135.     /**
  136.      * @var string|null
  137.      *
  138.      * @ORM\Column(
  139.      *     type = "string",
  140.      *     nullable = true,
  141.      * )
  142.      */
  143.     protected ?string $districtId null;
  144.     /**
  145.      * @var string|null
  146.      *
  147.      * @ORM\Column(
  148.      *     type = "string",
  149.      *     nullable = true,
  150.      * )
  151.      */
  152.     protected ?string $baseUri null;
  153.     /**
  154.      * @var Collection|OneRosterJob[]
  155.      *
  156.      * @ORM\OneToMany(
  157.      *     targetEntity = "Cms\CoreBundle\Entity\OneRosterJob",
  158.      *     mappedBy = "sync",
  159.      * )
  160.      * @ORM\OrderBy({
  161.      *     "createdAt" = "DESC",
  162.      * })
  163.      */
  164.     protected Collection $jobs;
  165.     /**
  166.      * @ORM\Column(
  167.      *     type = "boolean",
  168.      *     nullable = false,
  169.      *     options = {
  170.      *          "default" = true,
  171.      *      },
  172.      *     )
  173.      */
  174.     protected bool $active true;
  175.     /**
  176.      * @return int
  177.      */
  178.     public function getStrategies(): int
  179.     {
  180.         return $this->strategies;
  181.     }
  182.     /**
  183.      * @return array
  184.      */
  185.     public function getStrategiesAsArray(): array
  186.     {
  187.         if ($this->strategies === 0) {
  188.             return [];
  189.         }
  190.         $result = [];
  191.         foreach (self::STRATEGIES as $name => $mask) {
  192.             if ($this->hasStrategy($mask)) {
  193.                 $result[$name] = $mask;
  194.             }
  195.         }
  196.         return $result;
  197.     }
  198.     /**
  199.      * @param int $strategies
  200.      * @return $this
  201.      */
  202.     public function setStrategies(int $strategies): self
  203.     {
  204.         $this->strategies $strategies;
  205.         return $this;
  206.     }
  207.     /**
  208.      * @param int $strategy
  209.      * @return bool
  210.      */
  211.     public function hasStrategy(int $strategy): bool
  212.     {
  213.         return (($this->strategies $strategy) > 0);
  214.     }
  215.     /**
  216.      * @param int $strategy
  217.      * @param bool|null $toggle
  218.      * @return $this
  219.      */
  220.     public function toggleStrategy(int $strategy, ?bool $toggle null): self
  221.     {
  222.         if ($toggle === null) {
  223.             return ($this->hasStrategy($strategy)) ? $this->unmarkStrategy($strategy) : $this->markStrategy($strategy);
  224.         }
  225.         return ($toggle) ? $this->markStrategy($strategy) : $this->unmarkStrategy($strategy);
  226.     }
  227.     /**
  228.      * @param int $strategy
  229.      * @return $this
  230.      */
  231.     public function markStrategy(int $strategy): self
  232.     {
  233.         $this->strategies |= $strategy;
  234.         return $this;
  235.     }
  236.     /**
  237.      * @param int $strategy
  238.      * @return $this
  239.      */
  240.     public function unmarkStrategy(int $strategy): self
  241.     {
  242.         $this->strategies &= ~$strategy;
  243.         return $this;
  244.     }
  245.     /**
  246.      * @param Criteria|null $criteria
  247.      * @return Collection|OneRosterJob[]
  248.      */
  249.     public function getJobs(?Criteria $criteria null): Collection
  250.     {
  251.         if ( ! $this->jobs instanceof Collection) {
  252.             $this->jobs = new ArrayCollection();
  253.         }
  254.         if ( ! empty($criteria)) {
  255.             return $this->jobs->matching($criteria);
  256.         }
  257.         return $this->jobs;
  258.     }
  259.     /**
  260.      * @return OneRosterJob|null
  261.      */
  262.     public function getLastJob(): ?OneRosterJob
  263.     {
  264.         if ($this->jobs->count() > 0) {
  265.             $jobs $this->getJobs(new Criteria(null, ['createdAt' => 'DESC'], null1));
  266.             return $jobs->first();
  267.         }
  268.         return null;
  269.     }
  270.     /**
  271.      * @param int $limit
  272.      * @return Collection
  273.      */
  274.     public function getLastJobs(int $limit 10): Collection
  275.     {
  276.         return $this->getJobs(new Criteria(null, ['createdAt' => 'DESC'], null$limit));
  277.     }
  278.     /**
  279.      * @return string|null
  280.      */
  281.     public function getVendor(): ?string
  282.     {
  283.         return $this->vendor;
  284.     }
  285.     /**
  286.      * @param string $vendor
  287.      * @return $this
  288.      */
  289.     public function setVendor(string $vendor): self
  290.     {
  291.         if ( ! in_array($vendorAbstractOneRosterApi::VENDORS)) {
  292.             throw new \Exception(sprintf(
  293.                 'Vendor "%s" is not valid.',
  294.                 $vendor
  295.             ));
  296.         }
  297.         $this->vendor $vendor;
  298.         return $this;
  299.     }
  300.     /**
  301.      * @return string|null
  302.      */
  303.     public function getApiClientId(): ?string
  304.     {
  305.         return $this->apiClientId;
  306.     }
  307.     /**
  308.      * @param string $apiClientId
  309.      * @return $this
  310.      */
  311.     public function setApiClientId(string $apiClientId): self
  312.     {
  313.         $this->apiClientId $apiClientId;
  314.         return $this;
  315.     }
  316.     /**
  317.      * @return string|null
  318.      */
  319.     public function getApiClientSecret(): ?string
  320.     {
  321.         return $this->apiClientSecret;
  322.     }
  323.     /**
  324.      * @param string $apiClientSecret
  325.      * @return $this
  326.      */
  327.     public function setApiClientSecret(string $apiClientSecret): self
  328.     {
  329.         $this->apiClientSecret $apiClientSecret;
  330.         return $this;
  331.     }
  332.     /**
  333.      * @return string|null
  334.      */
  335.     public function getApiAppName(): ?string
  336.     {
  337.         return $this->apiAppName;
  338.     }
  339.     /**
  340.      * @param string|null $apiAppName
  341.      * @return $this
  342.      */
  343.     public function setApiAppName(?string $apiAppName): self
  344.     {
  345.         $this->apiAppName $apiAppName ?: null;
  346.         return $this;
  347.     }
  348.     /**
  349.      * @return array
  350.      */
  351.     public function getApiToken(): array
  352.     {
  353.         return $this->apiToken;
  354.     }
  355.     /**
  356.      * @return string|null
  357.      */
  358.     public function getApiTokenScope(): ?string
  359.     {
  360.         $token $this->getApiToken();
  361.         if ($token && array_key_exists('scope'$token) && ! empty($token['scope'])) {
  362.             return $token['scope'];
  363.         }
  364.         return null;
  365.     }
  366.     /**
  367.      * @return int|null
  368.      */
  369.     public function getApiTokenExpiresIn(): ?int
  370.     {
  371.         $token $this->getApiToken();
  372.         if ($token && array_key_exists('expires_in'$token) && ! empty($token['expires_in'])) {
  373.             return $token['expires_in'];
  374.         }
  375.         return null;
  376.     }
  377.     /**
  378.      * @return string|null
  379.      */
  380.     public function getApiTokenTokenType(): ?string
  381.     {
  382.         $token $this->getApiToken();
  383.         if ($token && array_key_exists('token_type'$token) && ! empty($token['token_type'])) {
  384.             return $token['token_type'];
  385.         }
  386.         return null;
  387.     }
  388.     /**
  389.      * @return string|null
  390.      */
  391.     public function getApiTokenAccessToken(): ?string
  392.     {
  393.         $token $this->getApiToken();
  394.         if ($token && array_key_exists('access_token'$token) && ! empty($token['access_token'])) {
  395.             return $token['access_token'];
  396.         }
  397.         return null;
  398.     }
  399.     /**
  400.      * @param array $apiToken
  401.      * @return $this
  402.      */
  403.     public function setApiToken(array $apiToken): self
  404.     {
  405.         $this->apiToken $apiToken;
  406.         return $this;
  407.     }
  408.     /**
  409.      * @return string|null
  410.      */
  411.     public function getDistrictId(): ?string
  412.     {
  413.         return $this->districtId;
  414.     }
  415.     /**
  416.      * @param string|null $districtId
  417.      * @return $this
  418.      */
  419.     public function setDistrictId(?string $districtId): self
  420.     {
  421.         if ($districtId === '') {
  422.             $districtId null;
  423.         }
  424.         $this->districtId $districtId;
  425.         return $this;
  426.     }
  427.     /**
  428.      * @return string|null
  429.      */
  430.     public function getBaseUri(): ?string
  431.     {
  432.         return $this->baseUri;
  433.     }
  434.     /**
  435.      * @param string|null $baseUri
  436.      * @return $this
  437.      */
  438.     public function setBaseUri(?string $baseUri): self
  439.     {
  440.         $this->baseUri $baseUri;
  441.         return $this;
  442.     }
  443.     /**
  444.      * @return bool
  445.      */
  446.     public function isOptimized(): bool
  447.     {
  448.         return $this->getVendor() && in_array(
  449.             $this->getVendor(),
  450.             [
  451.                 AbstractOneRosterApi::VENDORS__SCHOOLNOW,
  452.                 AbstractOneRosterApi::VENDORS__SCHOOLNOW_DEV,
  453.                 AbstractOneRosterApi::VENDORS__SCHOOLNOW_TEST,
  454.                 AbstractOneRosterApi::VENDORS__SCHOOLNOW_NGROK,
  455.             ],
  456.             true,
  457.         );
  458.     }
  459.     public function isActive(): bool
  460.     {
  461.         return $this->active;
  462.     }
  463.     public function setActive(bool $active): self
  464.     {
  465.         $this->active $active;
  466.         return $this;
  467.     }
  468. }