src/Pumukit/SchemaBundle/Document/MultimediaObject.php line 32

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace Pumukit\SchemaBundle\Document;
  4. use ApiPlatform\Core\Annotation\ApiResource;
  5. use Doctrine\Common\Collections\ArrayCollection;
  6. use Doctrine\ODM\MongoDB\DocumentNotFoundException;
  7. use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
  8. use Gedmo\Mapping\Annotation as Gedmo;
  9. use Pumukit\SchemaBundle\Document\MediaType\Document;
  10. use Pumukit\SchemaBundle\Document\MediaType\External;
  11. use Pumukit\SchemaBundle\Document\MediaType\Image;
  12. use Pumukit\SchemaBundle\Document\MediaType\MediaInterface;
  13. use Pumukit\SchemaBundle\Document\MediaType\Metadata\VideoAudio;
  14. use Pumukit\SchemaBundle\Document\MediaType\Track;
  15. use Pumukit\SchemaBundle\Document\ValueObject\Immutable;
  16. /**
  17.  * @MongoDB\Document(repositoryClass="Pumukit\SchemaBundle\Repository\MultimediaObjectRepository")
  18.  *
  19.  * @MongoDB\Index(name="text_index", keys={"textindex.text"="text", "secondarytextindex.text"="text"}, options={"language_override"="indexlanguage", "default_language"="none", "weights"={"textindex.text"=10, "secondarytextindex.text"=1}})
  20.  *
  21.  * @MongoDB\HasLifecycleCallbacks
  22.  *
  23.  * @ApiResource(
  24.  *       collectionOperations={"get"={"method"="GET", "access_control"="is_granted('ROLE_ACCESS_API')"}},
  25.  *       itemOperations={"get"={"method"="GET", "access_control"="is_granted('ROLE_ACCESS_API')"}}
  26.  *   )
  27.  */
  28. class MultimediaObject
  29. {
  30.     use Traits\Keywords;
  31.     use Traits\Properties;
  32.     use Traits\HeadAndTail;
  33.     use Traits\Link {
  34.         Traits\Link::__construct as private __LinkConstruct;
  35.     }
  36.     use Traits\Pic {
  37.         Traits\Pic::__construct as private __PicConstruct;
  38.     }
  39.     use Traits\Material {
  40.         Traits\Material::__construct as private __MaterialConstruct;
  41.     }
  42.     public const STATUS_PUBLISHED 0;
  43.     public const STATUS_BLOCKED 1;
  44.     public const STATUS_HIDDEN 2;
  45.     public const STATUS_NEW = -1;
  46.     public const STATUS_PROTOTYPE = -2;
  47.     public const TYPE_UNKNOWN 0;
  48.     public const TYPE_VIDEO 1;
  49.     public const TYPE_AUDIO 2;
  50.     public const TYPE_EXTERNAL 3;
  51.     public const TYPE_LIVE 4;
  52.     public const TYPE_IMAGE 5;
  53.     public const TYPE_DOCUMENT 6;
  54.     public static $statusTexts = [
  55.         self::STATUS_PUBLISHED => 'Published',
  56.         self::STATUS_BLOCKED => 'Blocked',
  57.         self::STATUS_HIDDEN => 'Hidden',
  58.         self::STATUS_NEW => 'New',
  59.         self::STATUS_PROTOTYPE => 'Prototype',
  60.     ];
  61.     public static $typeTexts = [
  62.         self::TYPE_UNKNOWN => '',
  63.         self::TYPE_VIDEO => 'Video',
  64.         self::TYPE_AUDIO => 'Audio',
  65.         self::TYPE_EXTERNAL => 'External',
  66.         self::TYPE_LIVE => 'Live',
  67.         self::TYPE_IMAGE => 'Image',
  68.         self::TYPE_DOCUMENT => 'Document',
  69.     ];
  70.     /**
  71.      * @MongoDB\Id
  72.      */
  73.     private $id;
  74.     /**
  75.      * @MongoDB\Field(type="int")
  76.      *
  77.      * @MongoDB\UniqueIndex()
  78.      */
  79.     private $numerical_id;
  80.     /**
  81.      * @MongoDB\EmbedOne(name="immutable", targetDocument="Pumukit\SchemaBundle\Document\ValueObject\Immutable")
  82.      */
  83.     private $immutable;
  84.     /**
  85.      * @MongoDB\Field(type="int")
  86.      *
  87.      * @MongoDB\Index
  88.      */
  89.     private $type self::TYPE_UNKNOWN;
  90.     /**
  91.      * @MongoDB\Field(type="string")
  92.      *
  93.      * @MongoDB\Index
  94.      */
  95.     private $secret;
  96.     /**
  97.      * @MongoDB\ReferenceOne(targetDocument=Series::class, storeAs="id", inversedBy="multimedia_object", cascade={"persist"})
  98.      *
  99.      * @Gedmo\SortableGroup
  100.      *
  101.      * @MongoDB\Index
  102.      */
  103.     private $series;
  104.     /**
  105.      * NOTE: This field is for MongoDB Search Index purposes. Do not use this field and do not create setter and/or getter.
  106.      *
  107.      * @MongoDB\Field(type="raw")
  108.      */
  109.     private $seriesTitle = ['en' => ''];
  110.     /**
  111.      * @MongoDB\EmbedOne(targetDocument=EmbeddedBroadcast::class)
  112.      */
  113.     private $embeddedBroadcast;
  114.     /**
  115.      * @MongoDB\EmbedOne(targetDocument=EmbeddedEvent::class)
  116.      */
  117.     private $embeddedEvent;
  118.     /**
  119.      * @MongoDB\EmbedMany(targetDocument=EmbeddedSegment::class)
  120.      */
  121.     private $embeddedSegments;
  122.     /**
  123.      * @MongoDB\EmbedOne(targetDocument=EmbeddedSocial::class)
  124.      */
  125.     private $embeddedSocial;
  126.     /**
  127.      * @MongoDB\EmbedMany(targetDocument=EmbeddedTag::class)
  128.      */
  129.     private $tags;
  130.     /**
  131.      * @MongoDB\EmbedMany(targetDocument=Track::class)
  132.      */
  133.     private $tracks;
  134.     /**
  135.      * @MongoDB\EmbedMany(targetDocument=Document::class)
  136.      */
  137.     private $documents;
  138.     /**
  139.      * @MongoDB\EmbedMany(targetDocument=External::class)
  140.      */
  141.     private $external;
  142.     /**
  143.      * @MongoDB\EmbedMany(targetDocument=Image::class)
  144.      */
  145.     private $images;
  146.     /**
  147.      * @MongoDB\ReferenceMany(targetDocument=Group::class, storeAs="id", sort={"key":1}, strategy="setArray", cascade={"persist","remove"})
  148.      */
  149.     private $groups;
  150.     /**
  151.      * @MongoDB\Field(type="int")
  152.      *
  153.      * @Gedmo\SortablePosition
  154.      */
  155.     private $rank;
  156.     /**
  157.      * @MongoDB\Field(type="int")
  158.      */
  159.     private $status self::STATUS_NEW;
  160.     /**
  161.      * @MongoDB\Field(type="date")
  162.      *
  163.      * @MongoDB\Index
  164.      */
  165.     private $record_date;
  166.     /**
  167.      * @MongoDB\Field(type="date")
  168.      *
  169.      * @MongoDB\Index
  170.      */
  171.     private $public_date;
  172.     /**
  173.      * @MongoDB\Field(type="raw")
  174.      */
  175.     private $title = ['en' => ''];
  176.     /**
  177.      * @MongoDB\Field(type="raw")
  178.      */
  179.     private $subtitle = ['en' => ''];
  180.     /**
  181.      * @MongoDB\Field(type="raw")
  182.      */
  183.     private $description = ['en' => ''];
  184.     /**
  185.      * @MongoDB\Field(type="string")
  186.      */
  187.     private $comments;
  188.     /**
  189.      * @MongoDB\Field(type="raw")
  190.      */
  191.     private $line2 = ['en' => ''];
  192.     /**
  193.      * @MongoDB\Field(type="string")
  194.      */
  195.     private $copyright;
  196.     /**
  197.      * @MongoDB\Field(type="string")
  198.      */
  199.     private $license;
  200.     /**
  201.      * @MongoDB\Field(type="int")
  202.      */
  203.     private $duration 0;
  204.     /**
  205.      * @MongoDB\Field(type="int", strategy="increment")
  206.      */
  207.     private $numview 0;
  208.     /**
  209.      * @MongoDB\EmbedMany(targetDocument=EmbeddedRole::class)
  210.      */
  211.     private $people;
  212.     /**
  213.      * @MongoDB\Field(type="bool")
  214.      */
  215.     private $head false;
  216.     /**
  217.      * @MongoDB\Field(type="bool")
  218.      */
  219.     private $tail false;
  220.     /**
  221.      * @MongoDB\Field(type="raw")
  222.      */
  223.     private $textindex = [];
  224.     /**
  225.      * @MongoDB\Field(type="raw")
  226.      */
  227.     private $secondarytextindex = [];
  228.     /**
  229.      * @MongoDB\Field(type="date")
  230.      */
  231.     private $updatedAt;
  232.     /**
  233.      * Used locale to override Translation listener`s locale this is not a mapped field of entity metadata, just a simple property.
  234.      */
  235.     private $locale 'en';
  236.     public function __construct()
  237.     {
  238.         $this->secret base_convert(sha1(uniqid((string) random_int(0mt_getrandmax()), true)), 1636);
  239.         $this->tracks = new ArrayCollection();
  240.         $this->documents = new ArrayCollection();
  241.         $this->images = new ArrayCollection();
  242.         $this->external = new ArrayCollection();
  243.         $this->tags = new ArrayCollection();
  244.         $this->people = new ArrayCollection();
  245.         $this->groups = new ArrayCollection();
  246.         $this->__LinkConstruct();
  247.         $this->__PicConstruct();
  248.         $this->__MaterialConstruct();
  249.         $now = new \DateTime('now');
  250.         $this->setPublicDate($now);
  251.         $this->setRecordDate($now);
  252.         $this->setPropertyAsDateTime('created'$now);
  253.         $this->setUpdateAt();
  254.     }
  255.     public function __toString(): string
  256.     {
  257.         return $this->getTitle();
  258.     }
  259.     public function isCollection(): bool
  260.     {
  261.         return false;
  262.     }
  263.     public function getId()
  264.     {
  265.         return $this->id;
  266.     }
  267.     public function getNumericalID(): int
  268.     {
  269.         return $this->numerical_id;
  270.     }
  271.     public function setNumericalID(int $numericalID): void
  272.     {
  273.         $this->numerical_id $numericalID;
  274.     }
  275.     public function getImmutable(): ?Immutable
  276.     {
  277.         return $this->immutable;
  278.     }
  279.     public function setImmutable(Immutable $immutable): void
  280.     {
  281.         $this->immutable $immutable;
  282.     }
  283.     public function getSecret(): string
  284.     {
  285.         return $this->secret;
  286.     }
  287.     public function resetSecret(): string
  288.     {
  289.         $this->secret base_convert(sha1(uniqid((string) random_int(0mt_getrandmax()), true)), 1636);
  290.         return $this->secret;
  291.     }
  292.     public function setLocale(string $locale): void
  293.     {
  294.         $this->locale $locale;
  295.     }
  296.     public function getLocale(): string
  297.     {
  298.         return $this->locale;
  299.     }
  300.     public function setRank(int $rank): void
  301.     {
  302.         $this->rank $rank;
  303.     }
  304.     public function getRank(): int
  305.     {
  306.         return $this->rank;
  307.     }
  308.     public function isLive(): bool
  309.     {
  310.         return self::TYPE_LIVE === $this->type;
  311.     }
  312.     public function setType($type): void
  313.     {
  314.         $this->type $type;
  315.     }
  316.     public function getType(): int
  317.     {
  318.         return $this->type;
  319.     }
  320.     public function setVideoType(): void
  321.     {
  322.         $this->type self::TYPE_VIDEO;
  323.     }
  324.     public function isVideoAudioType(): bool
  325.     {
  326.         return $this->isVideoType() || $this->isAudioType();
  327.     }
  328.     public function isVideoType(): bool
  329.     {
  330.         return self::TYPE_VIDEO === $this->getType();
  331.     }
  332.     public function isAudioType(): bool
  333.     {
  334.         return self::TYPE_AUDIO === $this->getType();
  335.     }
  336.     public function setAudioType(): void
  337.     {
  338.         $this->type self::TYPE_AUDIO;
  339.     }
  340.     public function setLiveType(): void
  341.     {
  342.         $this->type self::TYPE_LIVE;
  343.     }
  344.     public function isLiveType(): bool
  345.     {
  346.         return self::TYPE_LIVE === $this->getType();
  347.     }
  348.     public function setImageType(): void
  349.     {
  350.         $this->type self::TYPE_IMAGE;
  351.     }
  352.     public function isImageType(): bool
  353.     {
  354.         return self::TYPE_IMAGE === $this->getType();
  355.     }
  356.     public function setDocumentType(): void
  357.     {
  358.         $this->type self::TYPE_DOCUMENT;
  359.     }
  360.     public function isDocumentType(): bool
  361.     {
  362.         return self::TYPE_DOCUMENT === $this->getType();
  363.     }
  364.     public function setExternalType(): void
  365.     {
  366.         $this->type self::TYPE_EXTERNAL;
  367.     }
  368.     public function isExternalType(): bool
  369.     {
  370.         return self::TYPE_EXTERNAL === $this->getType();
  371.     }
  372.     public function getStringType($type): string
  373.     {
  374.         return self::$typeTexts[$type];
  375.     }
  376.     public function setStatus($status): void
  377.     {
  378.         $this->status $status;
  379.     }
  380.     public function getStatus(): int
  381.     {
  382.         return $this->status;
  383.     }
  384.     public function getStringStatus($status): string
  385.     {
  386.         return self::$statusTexts[$status];
  387.     }
  388.     public function isPublished(): bool
  389.     {
  390.         return self::STATUS_PUBLISHED === $this->getStatus();
  391.     }
  392.     public function isBlocked(): bool
  393.     {
  394.         return self::STATUS_BLOCKED === $this->getStatus();
  395.     }
  396.     public function isHidden(): bool
  397.     {
  398.         return self::STATUS_HIDDEN === $this->getStatus();
  399.     }
  400.     public function isPrototype(): bool
  401.     {
  402.         return self::STATUS_PROTOTYPE === $this->getStatus();
  403.     }
  404.     public function setRecordDate($recordDate): void
  405.     {
  406.         $this->record_date $recordDate;
  407.     }
  408.     public function getRecordDate()
  409.     {
  410.         return $this->record_date;
  411.     }
  412.     public function setPublicDate($publicDate): void
  413.     {
  414.         $this->public_date $publicDate;
  415.     }
  416.     public function getPublicDate()
  417.     {
  418.         return $this->public_date;
  419.     }
  420.     public function setTitle($title$locale null): void
  421.     {
  422.         if (null === $locale) {
  423.             $locale $this->locale;
  424.         }
  425.         $this->title[$locale] = $title;
  426.     }
  427.     public function getTitle($locale null): string
  428.     {
  429.         if (null === $locale) {
  430.             $locale $this->locale;
  431.         }
  432.         return $this->title[$locale] ?? '';
  433.     }
  434.     public function setI18nTitle(array $title): void
  435.     {
  436.         $this->title $title;
  437.     }
  438.     public function getI18nTitle(): array
  439.     {
  440.         return $this->title;
  441.     }
  442.     public function setSubtitle($subtitle$locale null): void
  443.     {
  444.         if (null === $locale) {
  445.             $locale $this->locale;
  446.         }
  447.         $this->subtitle[$locale] = $subtitle;
  448.     }
  449.     public function getSubtitle($locale null): string
  450.     {
  451.         if (null === $locale) {
  452.             $locale $this->locale;
  453.         }
  454.         return $this->subtitle[$locale] ?? '';
  455.     }
  456.     public function setI18nSubtitle(array $subtitle): void
  457.     {
  458.         $this->subtitle $subtitle;
  459.     }
  460.     public function getI18nSubtitle(): array
  461.     {
  462.         return $this->subtitle;
  463.     }
  464.     public function setDescription($description$locale null): void
  465.     {
  466.         if (null === $locale) {
  467.             $locale $this->locale;
  468.         }
  469.         $this->description[$locale] = $description;
  470.     }
  471.     public function getDescription($locale null): string
  472.     {
  473.         if (null === $locale) {
  474.             $locale $this->locale;
  475.         }
  476.         return $this->description[$locale] ?? '';
  477.     }
  478.     public function setI18nDescription(array $description): void
  479.     {
  480.         $this->description $description;
  481.     }
  482.     public function getI18nDescription(): array
  483.     {
  484.         return $this->description;
  485.     }
  486.     public function setComments($comments): void
  487.     {
  488.         $this->comments $comments;
  489.     }
  490.     public function getComments()
  491.     {
  492.         return $this->comments;
  493.     }
  494.     public function setLine2($line2$locale null): void
  495.     {
  496.         if (null === $locale) {
  497.             $locale $this->locale;
  498.         }
  499.         $this->line2[$locale] = $line2;
  500.     }
  501.     public function getLine2($locale null): string
  502.     {
  503.         if (null === $locale) {
  504.             $locale $this->locale;
  505.         }
  506.         return $this->line2[$locale] ?? '';
  507.     }
  508.     public function setI18nLine2(array $line2): void
  509.     {
  510.         $this->line2 $line2;
  511.     }
  512.     public function getI18nLine2(): array
  513.     {
  514.         return $this->line2;
  515.     }
  516.     public function setCopyright($copyright): void
  517.     {
  518.         $this->copyright $copyright;
  519.     }
  520.     public function getCopyright()
  521.     {
  522.         return $this->copyright;
  523.     }
  524.     public function setLicense($license)
  525.     {
  526.         $this->license $license;
  527.     }
  528.     public function getLicense()
  529.     {
  530.         return $this->license;
  531.     }
  532.     public function setDuration($duration): void
  533.     {
  534.         $this->duration $duration;
  535.     }
  536.     public function getDuration(): int
  537.     {
  538.         return $this->duration;
  539.     }
  540.     public function getDurationString(): string
  541.     {
  542.         if ($this->duration 0) {
  543.             $min floor($this->duration 60);
  544.             $seg $this->duration 60;
  545.             if ($seg 10) {
  546.                 $seg '0'.$seg;
  547.             }
  548.             if (=== $min) {
  549.                 $aux $seg."''";
  550.             } else {
  551.                 $aux $min."' ".$seg."''";
  552.             }
  553.             return $aux;
  554.         }
  555.         return "0''";
  556.     }
  557.     public function setNumview($numview): void
  558.     {
  559.         $this->numview $numview;
  560.     }
  561.     public function incNumview(): void
  562.     {
  563.         ++$this->numview;
  564.     }
  565.     public function getNumview(): int
  566.     {
  567.         return $this->numview;
  568.     }
  569.     public function setSeries(Series $series): void
  570.     {
  571.         $this->series $series;
  572.         // NOTE: This field is for MongoDB Search Index purposes.
  573.         //       Do not use this field and do not create setter and/or getter.
  574.         if (!$series->isHide()) {
  575.             $this->seriesTitle $series->getI18nTitle();
  576.         } else {
  577.             $this->seriesTitle = [];
  578.         }
  579.     }
  580.     public function getSeries()
  581.     {
  582.         // WORKAROUND: get the object series is it's hidden and the MongoDB filter is enabled.
  583.         try {
  584.             $this->series->isHide();
  585.         } catch (DocumentNotFoundException $e) {
  586.         }
  587.         return $this->series;
  588.     }
  589.     public function getSeriesTitle($locale null): string
  590.     {
  591.         if (null === $locale) {
  592.             $locale $this->locale;
  593.         }
  594.         return $this->seriesTitle[$locale] ?? '';
  595.     }
  596.     public function setEmbeddedBroadcast(EmbeddedBroadcast $embeddedBroadcast): void
  597.     {
  598.         $this->embeddedBroadcast $embeddedBroadcast;
  599.     }
  600.     public function getEmbeddedEvent()
  601.     {
  602.         return $this->embeddedEvent;
  603.     }
  604.     public function setEmbeddedEvent(EmbeddedEvent $embeddedEvent): void
  605.     {
  606.         $this->embeddedEvent $embeddedEvent;
  607.     }
  608.     public function getEmbeddedSegments()
  609.     {
  610.         return $this->embeddedSegments;
  611.     }
  612.     public function setEmbeddedSegments($embeddedSegments): void
  613.     {
  614.         $this->embeddedSegments $embeddedSegments;
  615.     }
  616.     public function addEmbeddedSegment(EmbeddedSegment $embeddedSegment): void
  617.     {
  618.         $this->embeddedSegments[] = $embeddedSegment;
  619.     }
  620.     public function removeEmbeddedSegment(EmbeddedSegment $embeddedSegment): bool
  621.     {
  622.         foreach ($this->embeddedSegments as $segment) {
  623.             if ($segment->getId() === $embeddedSegment->getId()) {
  624.                 $removed $this->embeddedSegments->removeElement($embeddedSegment);
  625.                 $this->embeddedSegments = new ArrayCollection(array_values($this->embeddedSegments->toArray()));
  626.                 return $removed;
  627.             }
  628.         }
  629.         return false;
  630.     }
  631.     public function getEmbeddedBroadcastNotNull(): EmbeddedBroadcast
  632.     {
  633.         if ($this->embeddedBroadcast) {
  634.             return $this->embeddedBroadcast;
  635.         }
  636.         return new EmbeddedBroadcast();
  637.     }
  638.     public function getEmbeddedBroadcast()
  639.     {
  640.         return $this->embeddedBroadcast;
  641.     }
  642.     public function isPublicEmbeddedBroadcast(): bool
  643.     {
  644.         return !$this->embeddedBroadcast || EmbeddedBroadcast::TYPE_PUBLIC === $this->embeddedBroadcast->getType();
  645.     }
  646.     public function setEmbeddedSocial(EmbeddedSocial $embeddedSocial): void
  647.     {
  648.         $this->embeddedSocial $embeddedSocial;
  649.     }
  650.     public function getEmbeddedSocial()
  651.     {
  652.         return $this->embeddedSocial;
  653.     }
  654.     public function getTags()
  655.     {
  656.         return $this->tags;
  657.     }
  658.     public function setTags($tags): void
  659.     {
  660.         $this->tags $tags;
  661.     }
  662.     public function addTag($tag): bool
  663.     {
  664.         if (!$this->containsTag($tag)) {
  665.             $embedTag EmbeddedTag::getEmbeddedTag($this->tags$tag);
  666.             $this->tags[] = $embedTag;
  667.             return true;
  668.         }
  669.         return false;
  670.     }
  671.     public function removeTag(TagInterface $tagToRemove): bool
  672.     {
  673.         foreach ($this->tags as $tag) {
  674.             if ($tag->getCod() === $tagToRemove->getCod()) {
  675.                 return $this->tags->removeElement($tag);
  676.             }
  677.         }
  678.         return false;
  679.     }
  680.     public function containsTag(TagInterface $tagToCheck): bool
  681.     {
  682.         foreach ($this->tags as $tag) {
  683.             if ($tag->getCod() === $tagToCheck->getCod()) {
  684.                 return true;
  685.             }
  686.         }
  687.         return false;
  688.     }
  689.     public function containsTagWithCod($tagCod): bool
  690.     {
  691.         foreach ($this->tags as $tag) {
  692.             if ($tag->getCod() === $tagCod) {
  693.                 return true;
  694.             }
  695.         }
  696.         return false;
  697.     }
  698.     public function containsAllTags(array $tags): bool
  699.     {
  700.         foreach ($tags as $tag) {
  701.             if (!$this->containsTag($tag)) {
  702.                 return false;
  703.             }
  704.         }
  705.         return true;
  706.     }
  707.     public function containsAllTagsWithCodes(array $tagCodes): bool
  708.     {
  709.         foreach ($tagCodes as $tagCode) {
  710.             if (!$this->containsTagWithCod($tagCode)) {
  711.                 return false;
  712.             }
  713.         }
  714.         return true;
  715.     }
  716.     public function containsAnyTag(array $tags): bool
  717.     {
  718.         foreach ($tags as $tag) {
  719.             if ($this->containsTag($tag)) {
  720.                 return true;
  721.             }
  722.         }
  723.         return false;
  724.     }
  725.     public function containsAnyTagWithCodes(array $tagCodes): bool
  726.     {
  727.         foreach ($tagCodes as $tagCode) {
  728.             if ($this->containsTagWithCod($tagCode)) {
  729.                 return true;
  730.             }
  731.         }
  732.         return false;
  733.     }
  734.     public function addTrack(Track $track): void
  735.     {
  736.         $this->tracks->add($track);
  737.         if ($track->metadata() instanceof VideoAudio && $track->metadata()->duration() > $this->getDuration()) {
  738.             $this->setDuration($track->metadata()->duration());
  739.         }
  740.     }
  741.     public function addDocument(Document $document): void
  742.     {
  743.         $this->documents->add($document);
  744.     }
  745.     public function addExternal(External $external): void
  746.     {
  747.         $this->external->add($external);
  748.     }
  749.     public function addImage(Image $image): void
  750.     {
  751.         $this->images->add($image);
  752.     }
  753.     public function removeTrack(Track $track): void
  754.     {
  755.         $this->tracks->removeElement($track);
  756.         $this->updateDuration();
  757.     }
  758.     public function removeDocument(Document $document): void
  759.     {
  760.         $this->removeMediaById($document->id());
  761.     }
  762.     public function removeImage(Image $image): void
  763.     {
  764.         $this->removeMediaById($image->id());
  765.     }
  766.     public function removeTrackById($trackId): void
  767.     {
  768.         $this->tracks $this->tracks->filter(function (Track $track) use ($trackId) {
  769.             return $track->id() !== $trackId;
  770.         });
  771.         $this->updateDuration();
  772.     }
  773.     public function removeMediaById(string $id)
  774.     {
  775.         $this->tracks $this->tracks->filter(function (Track $media) use ($id) {
  776.             return $media->id() !== $id;
  777.         });
  778.         $this->images $this->images->filter(function (Image $media) use ($id) {
  779.             return $media->id() !== $id;
  780.         });
  781.         $this->documents $this->documents->filter(function (Document $media) use ($id) {
  782.             return $media->id() !== $id;
  783.         });
  784.     }
  785.     public function removeAllMedias(): void
  786.     {
  787.         $this->tracks = new ArrayCollection();
  788.         $this->documents = new ArrayCollection();
  789.         $this->external = new ArrayCollection();
  790.         $this->images = new ArrayCollection();
  791.     }
  792.     public function upTrackById($trackId): void
  793.     {
  794.         $this->reorderTrackById($trackId);
  795.     }
  796.     public function downTrackById($trackId): void
  797.     {
  798.         $this->reorderTrackById($trackIdfalse);
  799.     }
  800.     public function containsTrack(Track $track): bool
  801.     {
  802.         return $this->tracks->contains($track);
  803.     }
  804.     public function getMedias(): array
  805.     {
  806.         return array_merge($this->tracks->toArray(), $this->documents->toArray(), $this->external->toArray(), $this->images->toArray());
  807.     }
  808.     public function getMediasWithoutExternal(): array
  809.     {
  810.         return array_merge($this->tracks->toArray(), $this->documents->toArray(), $this->images->toArray());
  811.     }
  812.     /**
  813.      * Deprecated Use method tracks instead getTracks.
  814.      */
  815.     public function getTracks()
  816.     {
  817.         return $this->tracks();
  818.     }
  819.     public function tracks()
  820.     {
  821.         return $this->tracks;
  822.     }
  823.     public function documents()
  824.     {
  825.         return $this->documents;
  826.     }
  827.     public function external()
  828.     {
  829.         return $this->external;
  830.     }
  831.     public function images()
  832.     {
  833.         return $this->images;
  834.     }
  835.     /**
  836.      * Deprecated use getMediaById instead.
  837.      *
  838.      * @param mixed $mediaId
  839.      */
  840.     public function getTrackById($mediaId)
  841.     {
  842.         return $this->getMediaById($mediaId);
  843.     }
  844.     public function getMediaById(?string $mediaId)
  845.     {
  846.         foreach ($this->getMedias() as $media) {
  847.             if ($media->id() === $mediaId) {
  848.                 return $media;
  849.             }
  850.         }
  851.         return null;
  852.     }
  853.     public function getTracksWithTag($tag): array
  854.     {
  855.         $r = [];
  856.         foreach ($this->getMedias() as $track) {
  857.             if ($track->tags()->contains($tag)) {
  858.                 $r[] = $track;
  859.             }
  860.         }
  861.         return $r;
  862.     }
  863.     public function getTrackWithTag($tag)
  864.     {
  865.         foreach ($this->getMedias() as $track) {
  866.             if ($track->tags()->contains($tag)) {
  867.                 return $track;
  868.             }
  869.         }
  870.         return null;
  871.     }
  872.     public function getTracksWithAllTags(array $tags): array
  873.     {
  874.         $r = [];
  875.         foreach ($this->getMedias() as $track) {
  876.             if ($track->tags()->containsAllTags($tags)) {
  877.                 $r[] = $track;
  878.             }
  879.         }
  880.         return $r;
  881.     }
  882.     public function getTrackWithAllTags(array $tags)
  883.     {
  884.         foreach ($this->getMedias() as $track) {
  885.             if ($track->tags()->containsAllTags($tags)) {
  886.                 return $track;
  887.             }
  888.         }
  889.         return null;
  890.     }
  891.     public function getTracksWithAnyTag(array $tags): array
  892.     {
  893.         $r = [];
  894.         foreach ($this->getMedias() as $track) {
  895.             if ($track->tags()->containsAnyTag($tags)) {
  896.                 $r[] = $track;
  897.             }
  898.         }
  899.         return $r;
  900.     }
  901.     public function getTrackWithAnyTag(array $tags)
  902.     {
  903.         foreach ($this->getMedias() as $track) {
  904.             if ($track->tags()->containsAnyTag($tags)) {
  905.                 return $track;
  906.             }
  907.         }
  908.         return null;
  909.     }
  910.     public function getRealDuration(): int
  911.     {
  912.         $master $this->getMaster();
  913.         if (!$master instanceof Track) {
  914.             return 0;
  915.         }
  916.         try {
  917.             $trackDuration $master->metadata()->duration();
  918.         } catch (\Exception $exception) {
  919.             return 0;
  920.         }
  921.         if ($this->getDuration() < $master->metadata()->duration()) {
  922.             return $master->metadata()->duration();
  923.         }
  924.         return $this->getDuration();
  925.     }
  926.     public function getMaster($any true): ?MediaInterface
  927.     {
  928.         $master $this->getTrackWithTag('master');
  929.         if ($master) {
  930.             return $master;
  931.         }
  932.         $isAudio $this->isOnlyAudio();
  933.         foreach ($this->getMedias() as $track) {
  934.             if (($isAudio && $track->metadata()->isOnlyAudio()) || (!$isAudio && !$track->metadata()->isOnlyAudio())) {
  935.                 return $track;
  936.             }
  937.         }
  938.         return null;
  939.     }
  940.     public function getDisplayTrack()
  941.     {
  942.         return $this->isOnlyAudio() ? $this->getFilteredTrackWithTags(['display']) : $this->getFilteredTrackWithTags(['display'], [], ['audio']);
  943.     }
  944.     public function getFilteredTracksWithTags(array $any_tags = [], array $all_tags = [], array $not_any_tags = [], array $not_all_tags = [], $all true): array
  945.     {
  946.         $r = [];
  947.         foreach ($this->tracks as $track) {
  948.             if ($all && $track->isHide()) {
  949.                 continue;
  950.             }
  951.             if ($any_tags && !$track->tags()->containsAnyTag($any_tags)) {
  952.                 continue;
  953.             }
  954.             if ($all_tags && !$track->tags()->containsAllTags($all_tags)) {
  955.                 continue;
  956.             }
  957.             if ($not_any_tags && $track->tags()->containsAnyTag($not_any_tags)) {
  958.                 continue;
  959.             }
  960.             if ($not_all_tags && $track->tags()->containsAllTags($not_all_tags)) {
  961.                 continue;
  962.             }
  963.             $r[] = $track;
  964.         }
  965.         return $r;
  966.     }
  967.     public function getFilteredTrackWithTags(array $any_tags = [], array $all_tags = [], array $not_any_tags = [], array $not_all_tags = [], $all true)
  968.     {
  969.         foreach ($this->getMedias() as $track) {
  970.             if ($all && $track->isHide()) {
  971.                 continue;
  972.             }
  973.             if ($any_tags && !$track->tags()->containsAnyTag($any_tags)) {
  974.                 continue;
  975.             }
  976.             if ($all_tags && !$track->tags()->containsAllTags($all_tags)) {
  977.                 continue;
  978.             }
  979.             if ($not_any_tags && $track->tags()->containsAnyTag($not_any_tags)) {
  980.                 continue;
  981.             }
  982.             if ($not_all_tags && $track->tags()->containsAllTags($not_all_tags)) {
  983.                 continue;
  984.             }
  985.             return $track;
  986.         }
  987.         return null;
  988.     }
  989.     public function getPeople(): array
  990.     {
  991.         $aux = [];
  992.         foreach ($this->people as $role) {
  993.             foreach ($role->getPeople() as $person) {
  994.                 if (!in_array($person$auxtrue)) {
  995.                     $aux[] = $person;
  996.                 }
  997.             }
  998.         }
  999.         return $aux;
  1000.     }
  1001.     public function getAllEmbeddedPeopleByPerson(PersonInterface $person): array
  1002.     {
  1003.         $aux = [];
  1004.         foreach ($this->people as $role) {
  1005.             foreach ($role->getPeople() as $embeddedPerson) {
  1006.                 if ($embeddedPerson->getId() === $person->getId()) {
  1007.                     $aux[] = $embeddedPerson;
  1008.                 }
  1009.             }
  1010.         }
  1011.         return $aux;
  1012.     }
  1013.     public function getAllEmbeddedRolesByPerson(PersonInterface $person): array
  1014.     {
  1015.         $aux = [];
  1016.         foreach ($this->people as $embeddedRole) {
  1017.             foreach ($embeddedRole->getPeople() as $embeddedPerson) {
  1018.                 if ($embeddedPerson->getId() === $person->getId()) {
  1019.                     $aux[] = $embeddedRole;
  1020.                     break;
  1021.                 }
  1022.             }
  1023.         }
  1024.         return $aux;
  1025.     }
  1026.     public function containsPerson(PersonInterface $person): bool
  1027.     {
  1028.         foreach ($this->getPeople() as $embeddedPerson) {
  1029.             if ($person->getId() === $embeddedPerson->getId()) {
  1030.                 return true;
  1031.             }
  1032.         }
  1033.         return false;
  1034.     }
  1035.     public function containsPersonWithRole(PersonInterface $personRoleInterface $role): bool
  1036.     {
  1037.         foreach ($this->getPeopleByRole($roletrue) as $embeddedPerson) {
  1038.             if ($person->getId() === $embeddedPerson->getId()) {
  1039.                 return true;
  1040.             }
  1041.         }
  1042.         return false;
  1043.     }
  1044.     public function containsPersonWithAllRoles(PersonInterface $person, array $roles): bool
  1045.     {
  1046.         foreach ($roles as $role) {
  1047.             if (!$this->containsPersonWithRole($person$role)) {
  1048.                 return false;
  1049.             }
  1050.         }
  1051.         return true;
  1052.     }
  1053.     public function containsPersonWithAnyRole(PersonInterface $person, array $roles): bool
  1054.     {
  1055.         foreach ($roles as $role) {
  1056.             if ($this->containsPersonWithRole($person$role)) {
  1057.                 return true;
  1058.             }
  1059.         }
  1060.         return false;
  1061.     }
  1062.     public function getPeopleByRole(?RoleInterface $role null$always false): array
  1063.     {
  1064.         return $this->getPeopleByRoleCod($role $role->getCod() : null$always);
  1065.     }
  1066.     public function getPeopleByRoleCod($roleCod null$always false): array
  1067.     {
  1068.         $aux = [];
  1069.         if (null !== $roleCod) {
  1070.             foreach ($this->people as $embeddedRole) {
  1071.                 if ($roleCod === $embeddedRole->getCod()) {
  1072.                     if ($always || $embeddedRole->getDisplay()) {
  1073.                         foreach ($embeddedRole->getPeople() as $embeddedPerson) {
  1074.                             $aux[] = $embeddedPerson;
  1075.                         }
  1076.                     }
  1077.                     break;
  1078.                 }
  1079.             }
  1080.         } else {
  1081.             foreach ($this->people as $embeddedRole) {
  1082.                 if ($always || $embeddedRole->getDisplay()) {
  1083.                     foreach ($embeddedRole->getPeople() as $embeddedPerson) {
  1084.                         if (!in_array($embeddedPerson$auxtrue)) {
  1085.                             $aux[] = $embeddedPerson;
  1086.                         }
  1087.                     }
  1088.                 }
  1089.             }
  1090.         }
  1091.         return $aux;
  1092.     }
  1093.     public function addPersonWithRole(PersonInterface $personRoleInterface $role): void
  1094.     {
  1095.         if (!$this->containsPersonWithRole($person$role)) {
  1096.             if ($embeddedRole $this->getEmbeddedRole($role)) {
  1097.                 $embeddedRole->addPerson($person);
  1098.             } else {
  1099.                 $embeddedRole $this->createEmbeddedRole($role);
  1100.                 $embeddedRole->addPerson($person);
  1101.                 $this->people[] = $embeddedRole;
  1102.             }
  1103.         }
  1104.     }
  1105.     public function removePersonWithRole(PersonInterface $personRoleInterface $role): bool
  1106.     {
  1107.         if (!$this->containsPersonWithRole($person$role)) {
  1108.             return false;
  1109.         }
  1110.         $embeddedRole $this->getEmbeddedRole($role);
  1111.         $hasRemoved $embeddedRole->removePerson($person);
  1112.         if (=== (is_countable($embeddedRole->getPeople()) ? count($embeddedRole->getPeople()) : 0)) {
  1113.             $this->people->removeElement($embeddedRole);
  1114.         }
  1115.         return $hasRemoved;
  1116.     }
  1117.     public function getPersonWithRole($person$role): ?PersonInterface
  1118.     {
  1119.         if ($this->containsPersonWithRole($person$role)) {
  1120.             return $this->getEmbeddedRole($role)->getEmbeddedPerson($person);
  1121.         }
  1122.         return null;
  1123.     }
  1124.     public function upPersonWithRole($person$role): void
  1125.     {
  1126.         $this->reorderPersonWithRole($person$role);
  1127.     }
  1128.     public function downPersonWithRole($person$role): void
  1129.     {
  1130.         $this->reorderPersonWithRole($person$rolefalse);
  1131.     }
  1132.     public function reorderPersonWithRole(PersonInterface $person$role$up true): void
  1133.     {
  1134.         $people array_values($this->getPeopleByRole($roletrue));
  1135.         $this->getEmbeddedRole($role)->getPeople()->clear();
  1136.         $out = [];
  1137.         foreach ($people as $key => $embeddedPerson) {
  1138.             if ($person->getId() === $embeddedPerson->getId()) {
  1139.                 $out[($key 10) + ($up ? -11 11)] = $embeddedPerson;
  1140.             } else {
  1141.                 $out[$key 10] = $embeddedPerson;
  1142.             }
  1143.         }
  1144.         ksort($out);
  1145.         foreach ($out as $embeddedPerson) {
  1146.             $this->getEmbeddedRole($role)->addPerson($embeddedPerson);
  1147.         }
  1148.     }
  1149.     public function getEmbeddedRole(RoleInterface $role): ?RoleInterface
  1150.     {
  1151.         foreach ($this->people as $embeddedRole) {
  1152.             if ($role->getCod() === $embeddedRole->getCod()) {
  1153.                 return $embeddedRole;
  1154.             }
  1155.         }
  1156.         return null;
  1157.     }
  1158.     public function createEmbeddedRole(RoleInterface $role): RoleInterface
  1159.     {
  1160.         if ($role instanceof EmbeddedRole) {
  1161.             return $role;
  1162.         }
  1163.         return new EmbeddedRole($role);
  1164.     }
  1165.     public function getRoles()
  1166.     {
  1167.         return $this->people;
  1168.     }
  1169.     public function containsGroup(Group $group): bool
  1170.     {
  1171.         return $this->groups->contains($group);
  1172.     }
  1173.     public function addGroup(Group $group): void
  1174.     {
  1175.         $this->groups->add($group);
  1176.     }
  1177.     public function removeGroup(Group $group): void
  1178.     {
  1179.         $this->groups->removeElement($group);
  1180.     }
  1181.     public function getGroups()
  1182.     {
  1183.         return $this->groups;
  1184.     }
  1185.     public function isOnlyAudio(): bool
  1186.     {
  1187.         return self::TYPE_AUDIO === $this->type;
  1188.     }
  1189.     public function getDurationInMinutesAndSeconds(): array
  1190.     {
  1191.         $minutes floor($this->getDuration() / 60);
  1192.         $seconds $this->getDuration() % 60;
  1193.         return [
  1194.             'minutes' => $minutes,
  1195.             'seconds' => $seconds,
  1196.         ];
  1197.     }
  1198.     public function setDurationInMinutesAndSeconds($durationInMinutesAndSeconds): void
  1199.     {
  1200.         if ((!empty($durationInMinutesAndSeconds['minutes'])) && (!empty($durationInMinutesAndSeconds['seconds']))) {
  1201.             $this->duration = ($durationInMinutesAndSeconds['minutes'] * 60) + $durationInMinutesAndSeconds['seconds'];
  1202.         }
  1203.     }
  1204.     public function isMultistream(): bool
  1205.     {
  1206.         $presenterTracks $this->getFilteredTracksWithTags(['presenter/delivery']);
  1207.         $presentationTracks $this->getFilteredTracksWithTags(['presentation/delivery']);
  1208.         return $presenterTracks && $presentationTracks;
  1209.     }
  1210.     public function setTextIndex($textindex): void
  1211.     {
  1212.         $this->textindex $textindex;
  1213.     }
  1214.     public function getTextIndex(): array
  1215.     {
  1216.         return $this->textindex;
  1217.     }
  1218.     public function setSecondaryTextIndex($secondarytextindex): void
  1219.     {
  1220.         $this->secondarytextindex $secondarytextindex;
  1221.     }
  1222.     public function getSecondaryTextIndex(): array
  1223.     {
  1224.         return $this->secondarytextindex;
  1225.     }
  1226.     public function setHead(bool $isHead): void
  1227.     {
  1228.         $this->head $isHead;
  1229.     }
  1230.     public function isHead(): bool
  1231.     {
  1232.         return $this->head;
  1233.     }
  1234.     public function setTail(bool $isTail): void
  1235.     {
  1236.         $this->tail $isTail;
  1237.     }
  1238.     public function isTail(): bool
  1239.     {
  1240.         return $this->tail;
  1241.     }
  1242.     /**
  1243.      * @MongoDB\PreUpdate
  1244.      *
  1245.      * @MongoDB\PrePersist
  1246.      */
  1247.     public function setUpdateAt(): void
  1248.     {
  1249.         $this->updatedAt = new \DateTime();
  1250.     }
  1251.     public function isUpdatedAt(): \DateTime
  1252.     {
  1253.         return $this->updatedAt;
  1254.     }
  1255.     /**
  1256.      * Reorder track by id.
  1257.      *
  1258.      * @param string $trackId
  1259.      * @param bool   $up
  1260.      */
  1261.     private function reorderTrackById($trackId$up true)
  1262.     {
  1263.         $snapshot array_values($this->tracks->toArray());
  1264.         $this->tracks->clear();
  1265.         $out = [];
  1266.         foreach ($snapshot as $key => $track) {
  1267.             if ($track->id() === $trackId) {
  1268.                 $out[($key 10) + ($up ? -11 11)] = $track;
  1269.             } else {
  1270.                 $out[$key 10] = $track;
  1271.             }
  1272.         }
  1273.         ksort($out);
  1274.         foreach ($out as $track) {
  1275.             $this->tracks->add($track);
  1276.         }
  1277.     }
  1278.     private function updateDuration(): void
  1279.     {
  1280.         if (=== count($this->tracks)) {
  1281.             $this->setDuration(0);
  1282.             return;
  1283.         }
  1284.         $trackMinDuration $this->tracks->first()->metadata()->duration();
  1285.         foreach ($this->tracks as $mmTrack) {
  1286.             if ($mmTrack->metadata()->duration() < $trackMinDuration) {
  1287.                 $trackMinDuration $mmTrack->metadata()->duration();
  1288.             }
  1289.         }
  1290.         $minDuration $this->getDuration();
  1291.         if ($minDuration $trackMinDuration) {
  1292.             $this->setDuration($trackMinDuration);
  1293.         }
  1294.     }
  1295. }