src/Products/NotificationsBundle/Entity/Profile.php line 63

Open in your IDE?
  1. <?php
  2. namespace Products\NotificationsBundle\Entity;
  3. use App\Entity\OAuth2\App\AbstractAppToken;
  4. use App\Entity\Shared\AliasableInterface;
  5. use App\Entity\Shared\AliasableTrait;
  6. use App\Entity\Shared\DiscardableInterface;
  7. use App\Entity\Shared\DiscardableTrait;
  8. use App\Entity\Shared\FlagsInterface;
  9. use App\Entity\Shared\FlagsTrait;
  10. use App\Util\Locales;
  11. use Cms\CoreBundle\Entity\OneRoster\OneRosterUser;
  12. use Cms\CoreBundle\Model\Interfaces\OneRosterable\OneRosterableInterface;
  13. use Cms\CoreBundle\Model\Interfaces\OneRosterable\OneRosterableTrait;
  14. use Cms\TenantBundle\Entity\TenantedEntity;
  15. use Doctrine\Common\Collections\ArrayCollection;
  16. use Doctrine\Common\Collections\Collection;
  17. use Doctrine\Common\Collections\Criteria;
  18. use Doctrine\ORM\Mapping as ORM;
  19. use League\OAuth2\Server\Entities\UserEntityInterface;
  20. use Products\NotificationsBundle\Entity\Recipients\AppRecipient;
  21. use Products\NotificationsBundle\Entity\Recipients\EmailRecipient;
  22. use Products\NotificationsBundle\Entity\Recipients\PhoneRecipient;
  23. use Products\NotificationsBundle\Util\ReachabilityTrait;
  24. use Reinder83\BinaryFlags\Bits;
  25. use Serializable;
  26. use Symfony\Component\Security\Core\User\EquatableInterface;
  27. use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
  28. use Symfony\Component\Security\Core\User\UserInterface;
  29. /**
  30.  * Class Profile
  31.  * @package Products\NotificationsBundle\Entity
  32.  *
  33.  * @ORM\Entity(
  34.  *     repositoryClass = "Products\NotificationsBundle\Doctrine\Repository\ProfileRepository",
  35.  * )
  36.  * @ORM\Table(
  37.  *     name = "notis__profile",
  38.  *     indexes = {
  39.  *         @ORM\Index(
  40.  *             name = "idx__onerosterId",
  41.  *             columns = {
  42.  *                 "onerosterId",
  43.  *             },
  44.  *         ),
  45.  *         @ORM\Index(
  46.  *             name = "idx__discarded",
  47.  *             columns = {
  48.  *                 "discarded",
  49.  *             },
  50.  *         ),
  51.  *         @ORM\Index(
  52.  *             name = "idx__discardedAt",
  53.  *             columns = {
  54.  *                 "discardedAt",
  55.  *             },
  56.  *         ),
  57.  *     },
  58.  * )
  59.  */
  60. class Profile extends TenantedEntity implements
  61.     UserInterface,
  62.     Serializable,
  63.     EquatableInterface,
  64.     OneRosterableInterface,
  65.     DiscardableInterface,
  66.     UserEntityInterface,
  67.     PasswordAuthenticatedUserInterface,
  68.     FlagsInterface,
  69.     AliasableInterface
  70. {
  71.     use ReachabilityTrait;
  72.     use OneRosterableTrait;
  73.     use DiscardableTrait;
  74.     use FlagsTrait;
  75.     use AliasableTrait;
  76.     public const METADATA__LANGUAGE '_language';
  77.     const FLAGS = [
  78.         'fixed' => self::FLAGS__FIXED,
  79.     ];
  80.     const FLAGS__FIXED Bits::BIT_1;
  81.     /**
  82.      * @var Collection|ProfileContact[]
  83.      *
  84.      * @ORM\OneToMany(
  85.      *     targetEntity = "Products\NotificationsBundle\Entity\ProfileContact",
  86.      *     mappedBy = "profile",
  87.      * )
  88.      */
  89.     protected Collection $contacts;
  90.     /**
  91.      * @var Collection|Checkup[]
  92.      *
  93.      * @ORM\OneToMany(
  94.      *     targetEntity = "Products\NotificationsBundle\Entity\Checkup",
  95.      *     mappedBy = "profile",
  96.      * )
  97.      * @ORM\OrderBy({
  98.      *     "createdAt" = "DESC",
  99.      * })
  100.      */
  101.     protected Collection $checkups;
  102.     /**
  103.      * @var Collection|AbstractAppToken[]
  104.      *
  105.      * @ORM\OneToMany(
  106.      *     targetEntity = AbstractAppToken::class,
  107.      *     mappedBy = "profile",
  108.      * )
  109.      * @ORM\OrderBy({
  110.      *     "createdAt" = "DESC",
  111.      * })
  112.      */
  113.     protected Collection $tokens;
  114.     /**
  115.      * @var string|null
  116.      *
  117.      * @ORM\Column(
  118.      *     type = "string",
  119.      *     nullable = true,
  120.      * )
  121.      */
  122.     protected ?string $firstName null;
  123.     /**
  124.      * @var string|null
  125.      *
  126.      * @ORM\Column(
  127.      *     type = "string",
  128.      *     nullable = true,
  129.      * )
  130.      */
  131.     protected ?string $lastName null;
  132.     /**
  133.      * This is always the language that comes over from the SIS, if any.
  134.      * This value should never be set by controllers for the portals, etc.
  135.      * Should only really ever be set in the syncing code.
  136.      *
  137.      * @var string|null
  138.      *
  139.      * @ORM\Column(
  140.      *     type = "string",
  141.      *     nullable = true,
  142.      *     length = 2,
  143.      * )
  144.      */
  145.     protected ?string $language null;
  146.     /**
  147.      * This is an optional language value to track any language setting the person has selected within our system.
  148.      * Things like portal controllers and such should modify this value.
  149.      *
  150.      * @var string|null
  151.      *
  152.      * @ORM\Column(
  153.      *     type = "string",
  154.      *     nullable = true,
  155.      *     length = 2,
  156.      * )
  157.      */
  158.     protected ?string $languageOverride null;
  159.     /**
  160.      * @var string|null
  161.      *
  162.      * @ORM\Column(
  163.      *     type = "string",
  164.      *     nullable = false,
  165.      * )
  166.      */
  167.     protected ?string $role null;
  168.     /**
  169.      * @var integer|null
  170.      *
  171.      * @ORM\Column(
  172.      *     type = "integer",
  173.      *     nullable = true,
  174.      * )
  175.      */
  176.     protected ?int $code null;
  177.     /**
  178.      * @var Collection|ProfileRelationship[]|null
  179.      *
  180.      * @ORM\OneToMany(
  181.      *     targetEntity = "Products\NotificationsBundle\Entity\ProfileRelationship",
  182.      *     mappedBy = "profile",
  183.      * )
  184.      */
  185.     protected Collection $relationships;
  186.     /**
  187.      * @var array|null
  188.      *
  189.      * @ORM\Column(
  190.      *     type = "json",
  191.      *     nullable = true,
  192.      * )
  193.      */
  194.     protected ?array $metadata = [];
  195.     /**
  196.      * @var Collection|AutomationRecord[]|
  197.      *
  198.      * @ORM\OneToMany(
  199.      *     targetEntity = "Products\NotificationsBundle\Entity\AutomationRecord",
  200.      *     mappedBy = "profile",
  201.      * )
  202.      */
  203.     protected Collection $automationRecords;
  204.     /**
  205.      *
  206.      */
  207.     public function __construct()
  208.     {
  209.         $this->contacts = new ArrayCollection();
  210.         $this->relationships = new ArrayCollection();
  211.         $this->tokens = new ArrayCollection();
  212.         $this->automationRecords = new ArrayCollection();
  213.     }
  214.     /**
  215.      * @return array
  216.      */
  217.     public function getMetadata(): array
  218.     {
  219.         return $this->metadata ?? [];
  220.     }
  221.     /**
  222.      * @param array|null $metadata
  223.      * @return $this
  224.      */
  225.     public function setMetadata(?array $metadata): self
  226.     {
  227.         $this->metadata $metadata ?: null;
  228.         return $this;
  229.     }
  230.     /**
  231.      * @param string $key
  232.      * @param mixed $value
  233.      * @return $this
  234.      */
  235.     public function setMetadataEntry(string $key$value): self
  236.     {
  237.         $metadata $this->getMetadata() ?: [];
  238.         $metadata[$key] = $value;
  239.         $this->setMetadata($metadata);
  240.         return $this;
  241.     }
  242.     /**
  243.      * @param Criteria|bool|null $criteria
  244.      * @return iterable|Collection|array|ProfileContact[]
  245.      */
  246.     public function getContacts($criteria null): iterable
  247.     {
  248.         if ( ! $this->contacts instanceof Collection) {
  249.             $this->contacts = new ArrayCollection();
  250.         }
  251.         $criteria = ($criteria === true) ? new Criteria() : ($criteria ?: null);
  252.         if ( ! empty($criteria)) {
  253.             return $this->contacts->matching($criteria);
  254.         }
  255.         return $this->contacts;
  256.     }
  257.     /**
  258.      * @param Criteria|bool|null $criteria
  259.      * @return iterable|Collection|array|ProfileContact[]
  260.      */
  261.     public function getEmailContacts($criteria null): iterable
  262.     {
  263.         return $this->getContacts($criteria)->filter(function (ProfileContact $contact) {
  264.             return $contact->getRecipient() instanceof EmailRecipient;
  265.         });
  266.     }
  267.     /**
  268.      * @param Criteria|bool|null $criteria
  269.      * @return iterable|Collection|array|ProfileContact[]
  270.      */
  271.     public function getPhoneContacts($criteria null): iterable
  272.     {
  273.         return $this->getContacts($criteria)->filter(function (ProfileContact $contact) {
  274.             return $contact->getRecipient() instanceof PhoneRecipient;
  275.         });
  276.     }
  277.     /**
  278.      * @param PhoneRecipient $phoneRecipient
  279.      * @return ProfileContact|null
  280.      */
  281.     public function getPhoneContactByPhoneRecipient(PhoneRecipient $phoneRecipient): ?ProfileContact
  282.     {
  283.         $expressionBuilder Criteria::expr();
  284.         $criteria = new Criteria();
  285.         $criteria->andWhere($expressionBuilder->eq('recipient'$phoneRecipient));
  286.         return $this->getContacts($criteria)->first();
  287.     }
  288.     /**
  289.      * @param Criteria|bool|null $criteria
  290.      * @return iterable|Collection|array|ProfileContact[]
  291.      */
  292.     public function getAppContacts($criteria null): iterable
  293.     {
  294.         return $this->getContacts($criteria)->filter(function (ProfileContact $contact) {
  295.             return $contact->getRecipient() instanceof AppRecipient;
  296.         });
  297.     }
  298.     /**
  299.      * @param Criteria|bool|null $criteria
  300.      * @return iterable|Collection|array|AbstractRecipient[]
  301.      */
  302.     public function getRecipients($criteria null): iterable
  303.     {
  304.         return $this->getContacts($criteria)->map(function (ProfileContact $contact) {
  305.             return $contact->getRecipient();
  306.         });
  307.     }
  308.     /**
  309.      * @param Criteria|bool|null $criteria
  310.      * @return array|AbstractRecipient[]
  311.      */
  312.     public function getRecipientsAsArray($criteria null): array
  313.     {
  314.         return $this->getRecipients($criteria)->toArray();
  315.     }
  316.     /**
  317.      * @param Criteria|bool|null $criteria
  318.      * @return iterable|Collection|array|EmailRecipient[]
  319.      */
  320.     public function getEmailRecipients($criteria null): iterable
  321.     {
  322.         return $this->getRecipients($criteria)->filter(function (AbstractRecipient $recipient) {
  323.             return $recipient instanceof EmailRecipient;
  324.         });
  325.     }
  326.     /**
  327.      * @param Criteria|bool|null $criteria
  328.      * @return array|EmailRecipient[]
  329.      */
  330.     public function getEmailRecipientsAsArray($criteria null): array
  331.     {
  332.         return $this->getEmailRecipients($criteria)->toArray();
  333.     }
  334.     /**
  335.      * @param Criteria|bool|null $criteria
  336.      * @return iterable|Collection|array|PhoneRecipient[]
  337.      */
  338.     public function getPhoneRecipients($criteria null): iterable
  339.     {
  340.         return $this->getRecipients($criteria)->filter(function (AbstractRecipient $recipient) {
  341.             return $recipient instanceof PhoneRecipient;
  342.         });
  343.     }
  344.     /**
  345.      * @param Criteria|bool|null $criteria
  346.      * @return array|PhoneRecipient[]
  347.      */
  348.     public function getPhoneRecipientsAsArray($criteria null): array
  349.     {
  350.         return $this->getPhoneRecipients($criteria)->toArray();
  351.     }
  352.     /**
  353.      * @param Criteria|bool|null $criteria
  354.      * @return iterable|Collection|array|AppRecipient[]
  355.      */
  356.     public function getAppRecipients($criteria null): iterable
  357.     {
  358.         return $this->getRecipients($criteria)->filter(function (AbstractRecipient $recipient) {
  359.             return $recipient instanceof AppRecipient;
  360.         });
  361.     }
  362.     /**
  363.      * @param Criteria|bool|null $criteria
  364.      * @return array|AppRecipient[]
  365.      */
  366.     public function getAppRecipientsAsArray($criteria null): array
  367.     {
  368.         return $this->getAppRecipients($criteria)->toArray();
  369.     }
  370.     /**
  371.      * {@inheritDoc}
  372.      */
  373.     public function getRoles(): array
  374.     {
  375.         return [
  376.             'DUMMY_ROLE',
  377.         ];
  378.     }
  379.     /**
  380.      * {@inheritDoc}
  381.      */
  382.     public function getPassword(): ?string
  383.     {
  384.         return $this->getCode();
  385.     }
  386.     /**
  387.      * {@inheritDoc}
  388.      */
  389.     public function getSalt(): ?string
  390.     {
  391.         // TODO: this function is not needed once we are on Symfony6
  392.         return null;
  393.     }
  394.     /**
  395.      * {@inheritDoc}
  396.      */
  397.     public function getUserIdentifier(): string
  398.     {
  399.         return $this->getUid()->toString();
  400.     }
  401.     /**
  402.      * {@inheritDoc}
  403.      */
  404.     public function getUsername(): string
  405.     {
  406.         // TODO: remove this function once we are on Symfony6
  407.         return $this->getUserIdentifier();
  408.     }
  409.     /**
  410.      * {@inheritDoc}
  411.      */
  412.     public function eraseCredentials()
  413.     {
  414.         // NOOP
  415.     }
  416.     /**
  417.      * {@inheritDoc}
  418.      */
  419.     public function serialize(): string
  420.     {
  421.         return serialize([
  422.             $this->getId(),
  423.         ]);
  424.     }
  425.     /**
  426.      * {@inheritDoc}
  427.      */
  428.     public function unserialize($data): void
  429.     {
  430.         [$this->id] = unserialize($data, ['allowed_classes' => false]);
  431.     }
  432.     /**
  433.      * {@inheritDoc}
  434.      * @param Profile $user
  435.      */
  436.     public function isEqualTo(UserInterface $user): bool
  437.     {
  438.         return $this->getId() === $user->getId();
  439.     }
  440.     /**
  441.      * @return string|null
  442.      */
  443.     public function getFirstName(): ?string
  444.     {
  445.         return $this->firstName;
  446.     }
  447.     /**
  448.      * @param string|null $firstName
  449.      * @return $this
  450.      */
  451.     public function setFirstName(?string $firstName): self
  452.     {
  453.         $this->firstName $firstName ?: null;
  454.         return $this;
  455.     }
  456.     /**
  457.      * @return string|null
  458.      */
  459.     public function getLastName(): ?string
  460.     {
  461.         return $this->lastName;
  462.     }
  463.     /**
  464.      * @param string|null $lastName
  465.      * @return $this
  466.      */
  467.     public function setLastName(?string $lastName): self
  468.     {
  469.         $this->lastName $lastName ?: null;
  470.         return $this;
  471.     }
  472.     /**
  473.      * @return string|null
  474.      */
  475.     public function getFullName(): ?string
  476.     {
  477.         return trim(sprintf(
  478.             '%s %s',
  479.             $this->getFirstName() ?: '—',
  480.             $this->getLastName()
  481.         )) ?? null;
  482.     }
  483.     /**
  484.      * @return string|null
  485.      */
  486.     public function getCensoredName(): ?string
  487.     {
  488.         return trim(sprintf(
  489.             '%s %s',
  490.             mb_strtoupper(mb_substr($this->getFirstName(), 01)),
  491.             $this->getLastName()
  492.         )) ?? null;
  493.     }
  494.     /**
  495.      * @return string|null
  496.      */
  497.     public function getSortName(): ?string
  498.     {
  499.         return trim(sprintf(
  500.                 '%s, %s',
  501.                 $this->getLastName(),
  502.                 $this->getFirstName()
  503.             ), ", \t\n\r\0\x0B") ?? null;
  504.     }
  505.     /**
  506.      * @return string|null
  507.      */
  508.     public function getLanguage(): ?string
  509.     {
  510.         return $this->language;
  511.     }
  512.     /**
  513.      * @param string|null $language
  514.      * @return $this
  515.      */
  516.     public function setLanguage(?string $language): self
  517.     {
  518.         if ($language && ! Locales::isLanguage($language)) {
  519.             throw new \RuntimeException(
  520.                 sprintf(
  521.                     'Language code "%s" is not supported, must be one of: %s.',
  522.                     $language,
  523.                     implode(', 'Locales::ISO6391),
  524.                 ),
  525.             );
  526.         }
  527.         $this->language $language;
  528.         return $this->setMetadataEntry(self::METADATA__LANGUAGE$this->getEffectiveLanguage());
  529.     }
  530.     /**
  531.      * @return string|null
  532.      */
  533.     public function getLanguageOverride(): ?string
  534.     {
  535.         return $this->languageOverride;
  536.     }
  537.     /**
  538.      * @param string|null $languageOverride
  539.      * @return $this
  540.      */
  541.     public function setLanguageOverride(?string $languageOverride): self
  542.     {
  543.         if ( ! Locales::isLanguage($languageOverride)) {
  544.             throw new \RuntimeException(
  545.                 sprintf(
  546.                     'Language override code "%s" is not supported, must be one of: %s.',
  547.                     $languageOverride,
  548.                     implode(', 'Locales::ISO6391),
  549.                 ),
  550.             );
  551.         }
  552.         $this->languageOverride $languageOverride;
  553.         return $this->setMetadataEntry(self::METADATA__LANGUAGE$this->getEffectiveLanguage());
  554.     }
  555.     /**
  556.      * This is the method that should generally be used when trying to determine a user's language preferences.
  557.      * If a user has set something within our system, that preference will be returned.
  558.      * If not, it will attempt to see if any language preference has come over from the SIS.
  559.      * If none of those are set, then it will return English as that is the default.
  560.      *
  561.      * @return string
  562.      */
  563.     public function getEffectiveLanguage(): string
  564.     {
  565.         return $this->getLanguageOverride() ?? $this->getLanguage() ?? Locales::ISO6391__ENGLISH;
  566.     }
  567.     /**
  568.      * @return string
  569.      */
  570.     public function getLocale(): string
  571.     {
  572.         return Locales::localeForLanguage(
  573.             $this->getEffectiveLanguage(),
  574.         );
  575.     }
  576.     /**
  577.      * @return string|null
  578.      */
  579.     public function getRole(): ?string
  580.     {
  581.         return $this->role;
  582.     }
  583.     /**
  584.      * @param string $role
  585.      * @return $this
  586.      */
  587.     public function setRole(string $role): self
  588.     {
  589.         $this->role $role;
  590.         return $this;
  591.     }
  592.     /**
  593.      * @return int|null
  594.      */
  595.     public function getRoleType(): ?int
  596.     {
  597.         return ($this->getRole()) ? OneRosterUser::ROLES_MAPPING[$this->getRole()] : null;
  598.     }
  599.     /**
  600.      * @return string|null
  601.      */
  602.     public function getRoleTypeName(): ?string
  603.     {
  604.         return ($this->getRoleType()) ? OneRosterUser::TYPES_LOOKUP[$this->getRoleType()] : null;
  605.     }
  606.     /**
  607.      * @param int $type
  608.      * @return bool
  609.      */
  610.     public function isRoleType(int $type): bool
  611.     {
  612.         return ($this->getRoleType() === $type);
  613.     }
  614.     /**
  615.      * TODO: rename and fix code...
  616.      *
  617.      * @return bool
  618.      */
  619.     public function isRoleStaff(): bool
  620.     {
  621.         return $this->isRoleType(OneRosterUser::TYPES__STAFF);
  622.     }
  623.     /**
  624.      * TODO: rename and fix code...
  625.      *
  626.      * @return bool
  627.      */
  628.     public function isRoleStudent(): bool
  629.     {
  630.         return $this->isRoleType(OneRosterUser::TYPES__STUDENT);
  631.     }
  632.     /**
  633.      * TODO: rename and fix code...
  634.      *
  635.      * @return bool
  636.      */
  637.     public function isRoleFamily(): bool
  638.     {
  639.         return $this->isRoleType(OneRosterUser::TYPES__FAMILY);
  640.     }
  641.     /**
  642.      * @param Criteria|null $criteria
  643.      * @return Collection|ProfileRelationship[]
  644.      */
  645.     public function getRelationships(?Criteria $criteria null): Collection
  646.     {
  647.         if ( ! $this->relationships instanceof Collection) {
  648.             $this->relationships = new ArrayCollection();
  649.         }
  650.         if ( ! empty($criteria)) {
  651.             return $this->relationships->matching($criteria);
  652.         }
  653.         return $this->relationships;
  654.     }
  655.     /**
  656.      * @param Criteria|null $criteria
  657.      * @return Collection|Student[]
  658.      */
  659.     public function getStudents(?Criteria $criteria null): Collection
  660.     {
  661.         return $this->getRelationships($criteria)->map(function (ProfileRelationship $relationship) {
  662.             return $relationship->getStudent();
  663.         });
  664.     }
  665.     /**
  666.      * @return int|null
  667.      */
  668.     public function getCode(): ?int
  669.     {
  670.         return $this->code;
  671.     }
  672.     /**
  673.      * @param int|null $code
  674.      * @return $this
  675.      */
  676.     public function setCode(?int $code): self
  677.     {
  678.         $this->code $code ?: null;
  679.         return $this;
  680.     }
  681.     /**
  682.      * @param Criteria|bool|null $criteria
  683.      * @return ArrayCollection|Checkup[]
  684.      */
  685.     public function getCheckups($criteria null): iterable
  686.     {
  687.         if ( ! $this->checkups instanceof Collection) {
  688.             $this->checkups = new ArrayCollection();
  689.         }
  690.         $criteria = ($criteria === true) ? new Criteria() : ($criteria ?: null);
  691.         if ( ! empty($criteria)) {
  692.             return $this->checkups->matching($criteria);
  693.         }
  694.         return $this->checkups;
  695.     }
  696.     /**
  697.      * @return Checkup|null
  698.      */
  699.     public function getUnhandledCheckup(): ?Checkup
  700.     {
  701.         $results $this->getCheckups(
  702.             (new Criteria())
  703.                 ->andWhere(Criteria::expr()->eq('ok'false))
  704.                 ->andWhere(Criteria::expr()->isNull('fixedAt'))
  705.                 ->orderBy([
  706.                     'createdAt' => 'DESC',
  707.                 ])
  708.         );
  709.         return ($results->count()) ? $results->get(0) : null;
  710.     }
  711.     /**
  712.      * {@inheritDoc}
  713.      */
  714.     public function getIdentifier(): string
  715.     {
  716.         return $this->getUidString();
  717.     }
  718.     /**
  719.      * @param Criteria|bool|null $criteria
  720.      * @return ArrayCollection|AbstractAppToken[]
  721.      */
  722.     public function getTokens($criteria null): iterable
  723.     {
  724.         if ( ! $this->tokens instanceof Collection) {
  725.             $this->tokens = new ArrayCollection();
  726.         }
  727.         $criteria = ($criteria === true) ? new Criteria() : ($criteria ?: null);
  728.         if ( ! empty($criteria)) {
  729.             return $this->tokens->matching($criteria);
  730.         }
  731.         return $this->tokens;
  732.     }
  733.     /**
  734.      * @return string|null
  735.      */
  736.     public function getMetadataDistrict(): ?string
  737.     {
  738.         $metadata $this->getMetadata();
  739.         return ($metadata && isset($metadata['_district'])) ? $metadata['_district'] : null;
  740.     }
  741.     /**
  742.      * @return array
  743.      */
  744.     public function getMetadataSchools(): array
  745.     {
  746.         $metadata $this->getMetadata();
  747.         return ($metadata && isset($metadata['_schools'])) ? $metadata['_schools'] : [];
  748.     }
  749.     /**
  750.      * @return Collection|AutomationRecord[]
  751.      */
  752.     public function getAutomationRecords(): Collection
  753.     {
  754.         return $this->automationRecords;
  755.     }
  756.     /**
  757.      * @param Collection|AutomationRecord[] $automationRecords
  758.      * @return self
  759.      */
  760.     public function setAutomationRecords(Collection $automationRecords): self
  761.     {
  762.         $this->automationRecords $automationRecords;
  763.         return $this;
  764.     }
  765.     /**
  766.      * @return array
  767.      */
  768.     public function jsonSerialize(): array
  769.     {
  770.         return [
  771.             'metadata' => $this->getMetadata(),
  772.         ];
  773.     }
  774. }