<?php
/**
* @license Silk Software House Sp. Z O.O.
*/
declare(strict_types=1);
namespace App\Entity;
use App\Entity\Traits\IdTrait;
use App\Entity\Traits\TimePreUpdateTrait;
use App\Entity\Traits\TimeTrait;
use DateTime;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Exception;
/**
* Class Channel.
*
* @ORM\Table("channels")
* @ORM\Entity(repositoryClass="App\Repository\ChannelRepository")
* @ORM\HasLifecycleCallbacks()
*/
class Channel
{
use IdTrait;
use TimeTrait;
use TimePreUpdateTrait;
/**
* Recipe.
*
* @var Recipe|null
*
* @ORM\ManyToOne(targetEntity="App\Entity\Recipe", cascade={"persist"})
* @ORM\JoinColumn(name="recipe_id", nullable=true)
*/
private ?Recipe $recipe = null;
/**
* Measurement.
*
* @var Measurement|null
*
* @ORM\ManyToOne(targetEntity="App\Entity\Measurement", inversedBy="channels", cascade={"persist"})
* @ORM\JoinColumn(name="measurement_id", nullable=false)
*/
private ?Measurement $measurement = null;
/**
* Number.
*
* @var int
*
* @ORM\Column(name="channel_number", type="integer", nullable=false, options={"comment": "Channel number."})
*/
private int $number = 0;
/**
* @ORM\OneToMany(targetEntity="App\Entity\Probe", mappedBy="channel")
* @ORM\OrderBy({"time" = "ASC"})
*/
private $probes;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private ?string $name = null;
/**
* @var Collection<int, ChannelSetting>
*
* @ORM\OneToMany(targetEntity="App\Entity\ChannelSetting", mappedBy="channel")
* @ORM\OrderBy({"priority": "ASC"})
*/
private Collection $channelSettings;
/**
* Channel constructor.
*/
public function __construct()
{
$this->probes = new ArrayCollection();
$this->channelSettings = new ArrayCollection();
}
/**
* Get recipe.
*
* @return Recipe|null
*/
public function getRecipe(): ?Recipe
{
return $this->recipe;
}
/**
* Set recipe.
*
* @param Recipe|null $recipe
*
* @return Channel
*/
public function setRecipe(?Recipe $recipe): self
{
$this->recipe = $recipe;
return $this;
}
/**
* Get measurement.
*
* @return Measurement
*/
public function getMeasurement(): Measurement
{
if (!isset($this->measurement)) {
throw new \LogicException('The measurement is not set, not expected.');
}
return $this->measurement;
}
/**
* Set measurement.
*
* @param Measurement $measurement
*
* @return Channel
*/
public function setMeasurement(Measurement $measurement): self
{
$this->measurement = $measurement;
return $this;
}
/**
* Get number.
*
* @return int
*/
public function getNumber(): int
{
return $this->number ?? 1;
}
/**
* Set number.
*
* @param int $number
*
* @return Channel
*/
public function setNumber(int $number): self
{
$this->number = $number;
return $this;
}
/**
* @return Collection
*/
public function getProbes(): Collection
{
return $this->probes;
}
/**
* @param Probe $probe
*
* @return Channel
*/
public function addProbe(Probe $probe): self
{
$this->probes[] = $probe;
return $this;
}
/**
* Sort probes.
*
* @return Channel
* @throws Exception
*/
public function sortProbes(): self
{
$iterator = $this->probes->getIterator();
$iterator->uasort(function ($first, $second) {
return $first->getTime() > $second->getTime() ? 1 : -1;
});
$this->probes = new ArrayCollection(iterator_to_array($iterator));
return $this;
}
/**
* Filter probes older than.
*
* @param DateTime|null $startingTimePoint
*
* @return Channel
*/
public function filterProbesOlderThan(DateTime $startingTimePoint = null): self
{
if (!$startingTimePoint) {
return $this;
}
foreach ($this->probes as $probe) {
if ($probe->getTime() < $startingTimePoint) {
$this->probes->removeElement($probe);
continue;
}
return $this;
}
return $this;
}
/**
* Update visibilities.
*
* @param array $hidden
*
* @return Channel
*/
public function updateVisibilities(array $hidden): self
{
/** @var Probe $probe */
foreach ($this->probes as $probe) {
$probe->setIsActive(!in_array($probe->getTime()->format('YmdHis'), $hidden));
}
return $this;
}
/**
* @return string|null
*/
public function getName(): ?string
{
return $this->name;
}
/**
* @param string|null $name
*
* @return $this
*/
public function setName(?string $name): self
{
$this->name = $name;
return $this;
}
/**
* To string.
*
* @return string
*/
public function __toString(): string
{
return $this->getNameWithFallback();
}
/**
* Get an extended name.
*
* @return string
*/
public function getNameWithFallback(): string
{
return $this->name ?? '{{Channel}} ' . $this->number;
}
/**
* With measurement.
*
* This method is heavy.
*
* @param bool $withMeasurement
*
* @return string
*/
public function getFullName(bool $withMeasurement = true): string
{
$serial = $this->getSerialNumberString();
return $serial.': '.($this->getNameWithFallback()).($withMeasurement ? (' '.($this->measurement->getNameWithRelativeNumberPerDevice())):'');
}
/**
* Get a sequence name.
*
* @param bool $withMeasurement
*
* @return string
*/
public function getSequenceName(bool $withMeasurement = true): string
{
return ($this->name ?? '{{Sequence}} '.($this->number)).': '.($this->measurement->getDevice()).($withMeasurement ? (' '.($this->measurement->getChannelDate())):'');
}
/**
* Get the sequence name short.
*
* @return string
*/
public function getSequenceShortName(): string
{
return $this->getSequenceName(false);
}
/**
* Get channel settings.
*
* @return Collection
*/
public function getChannelSettings(): Collection
{
return $this->channelSettings;
}
/**
* @return string
*/
private function getSerialNumberString(): string
{
if (!$this->measurement) {
return '';
}
return $this->measurement->getDevice()->getSerialNumber();
}
}