<?php declare(strict_types=1);
namespace Sq\Entity\Schema\ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping AS ORM;
use Sq\Entity\Collection\ImprovedArrayCollection;
use Sq\Entity\Enum;
use Sq\Service\Repository\ORM\WorkspaceRepository;
#[ORM\Entity(repositoryClass: WorkspaceRepository::class)]
#[ORM\Table(name: 'workspaces')]
class Workspace implements BelongsToOrganizationInterface
{
/**
*
* @var int|null
*/
#[ORM\Id]
#[ORM\GeneratedValue(strategy: 'AUTO')]
#[ORM\Column(name: 'ws_id', type: 'integer', nullable: false, options: ['unsigned' => true])]
private $id;
/**
*
* @var Organization
*/
#[ORM\ManyToOne(targetEntity: Organization::class, inversedBy: 'workspaces')]
#[ORM\JoinColumn(name: 'ws_o_id', referencedColumnName: 'o_id', nullable: false)]
private $organization;
/**
* @var WorkspaceSettings
*/
#[ORM\OneToOne(targetEntity: WorkspaceSettings::class, mappedBy: 'workspace', cascade: ['persist', 'remove'])]
private $settings;
/**
* @var Collection
*/
#[ORM\ManyToMany(targetEntity: User::class, mappedBy: 'workspaces')]
private $users;
/**
* @var string
*/
#[ORM\Column(name: 'ws_name', type: 'string', nullable: false)]
private $name;
/**
* @var string
*/
#[ORM\Column(name: 'ws_timezone', type: 'string', length: 42, nullable: false, options: ['default' => 'UTC'])]
private $timezone;
/**
* @var bool
*/
#[ORM\Column(name: 'ws_deleted', type: 'boolean', nullable: false, options: ['default' => false])]
private $deleted = false;
/**
* @var Collection
*/
#[ORM\OneToMany(targetEntity: SocialProfile::class, mappedBy: 'workspace')]
private $socialProfiles;
/**
* @var Collection
*/
#[ORM\OneToMany(targetEntity: PostCategory::class, mappedBy: 'workspace', cascade: ['persist', 'remove'], orphanRemoval: true)]
private Collection $postCategories;
#[ORM\OneToMany(targetEntity: QueueSchedule::class, mappedBy: 'workspace', cascade: ['persist', 'remove'])]
private Collection $timeslots;
/**
* @var Collection<Bitly>
*/
#[ORM\OneToMany(targetEntity: Bitly::class, mappedBy: 'workspace')]
private Collection $bitlyAccounts;
#[ORM\OneToMany(targetEntity: Snippet::class, mappedBy: 'workspace', cascade: ['persist', 'remove'])]
private Collection $snippets;
#[ORM\OneToMany(targetEntity: ImportSource::class, mappedBy: 'workspace', cascade: ['persist', 'remove'])]
private Collection $importSources;
#[ORM\OneToMany(targetEntity: ImportFolder::class, mappedBy: 'workspace', cascade: ['persist', 'remove'])]
private Collection $importFolders;
#[ORM\OneToOne(targetEntity: LegacyAlphaMap::class, mappedBy: 'workspace')]
private $legacyAlphaMap;
public function __construct(
Organization $organization,
string $name,
\DateTimeZone $timezone,
?Collection $initialCategories = null,
) {
$this->organization = $organization;
$this->name = trim($name);
$this->timezone = $timezone->getName();
$this->settings = new WorkspaceSettings($this);
$this->users = new ArrayCollection;
$this->socialProfiles = new ArrayCollection;
$this->postCategories = new ArrayCollection;
$this->bitlyAccounts = new ArrayCollection;
$this->snippets = new ArrayCollection;
$this->importSources = new ArrayCollection;
$this->importFolders = new ArrayCollection;
if ($initialCategories === null)
{
$initialCategory = new PostCategory(
name: 'General',
colourHex: Enum\CategoryColor::LIGHT_GREY,
workspace: $this,
isOnboardingContent: true
);
$this->addCategory($initialCategory);
}
else
{
foreach ($initialCategories as $category)
{
$this->addCategory($category);
}
}
$organization->addWorkspace($this);
}
public function getId(): ?int
{
return $this->id;
}
public function getWorkspace(): Workspace
{
return $this;
}
public function getOrganization(): Organization
{
return $this->organization;
}
public function setOrganization(Organization $organization): self
{
$this->organization = $organization;
return $this;
}
public function isLegacyWithoutOrganization(): bool
{
return false;
}
/**
* @return Collection|User[]
*/
public function getUsers(): Collection
{
return $this->users;
}
public function getName(): string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = trim($name);
return $this;
}
public function getTimezone(): \DateTimeZone
{
return new \DateTimeZone($this->timezone);
}
public function setTimezone(\DateTimeZone $timezone): self
{
$this->timezone = $timezone->getName();
return $this;
}
public function isDeleted(): bool
{
return $this->deleted;
}
public function setDeleted(bool $deleted): self
{
$this->deleted = $deleted;
return $this;
}
public function getSettings(): WorkspaceSettings
{
return $this->settings;
}
/**
* @return Collection<SocialProfile>
*/
public function getSocialProfiles(bool $includeDeleted = false): Collection
{
$socialProfiles = $this->socialProfiles->filter(
fn (SocialProfile $profile): bool => !$profile->isLegacyOnly()
);
if ($includeDeleted)
{
return $socialProfiles;
}
return $socialProfiles->filter(function (SocialProfile $profile): bool
{
return !$profile->isDeleted();
});
}
public function addCategory(PostCategory $category): self
{
if (!$this->postCategories->contains($category))
{
$this->postCategories->add($category);
}
return $this;
}
public function removeCategory(PostCategory $category): self
{
if ($this->postCategories->contains($category))
{
$this->postCategories->removeElement($category);
}
return $this;
}
/**
* @return Collection|PostCategory[]
*/
public function getCategories(bool $includeArchived = false): Collection
{
if ($includeArchived)
{
return $this->postCategories;
}
return $this->postCategories->filter(function (PostCategory $category): bool
{
return !$category->isArchived();
});
}
/**
* NOTE: This will return timeslots that are attached to archived categories.
*
* @return Collection|QueueSchedule[]
*/
public function getTimeslots(): Collection
{
return $this->timeslots;
}
/**
* @return Collection|Snippet[]
*/
public function getSnippets(): Collection
{
return $this->snippets;
}
/**
* @return Collection|ImportSource[]
*/
public function getImportSources(): Collection
{
return $this->importSources
->filter(fn (ImportSource $importSource): bool => $importSource->getAutoImport() === null);
}
/**
* @return Collection|ImportFolder[]
*/
public function getImportFolders(): Collection
{
return $this->importFolders;
}
/**
* NOTE: This will return Auto Imports that are attached to archived categories.
*
* @return Collection|AutoImport[]
*/
public function getAutoImports(): Collection
{
return $this->importSources
->map(fn (ImportSource $importSource): ?AutoImport => $importSource->getAutoImport())
->filter(fn (?AutoImport $autoImport): bool => $autoImport !== null);
}
public function addSocialProfile(SocialNetwork $socialProfile)
{
if (!$this->socialProfiles->contains($socialProfile))
{
$this->socialProfiles->add($socialProfile);
}
}
public function removeSocialProfile(SocialNetwork $socialProfile)
{
if ($this->socialProfiles->contains($socialProfile))
{
$this->socialProfiles->removeElement($socialProfile);
}
}
public function getMobileApps(bool $onlyConnected = true): Collection
{
$apps = new ImprovedArrayCollection();
foreach ($this->users as $user)
{
foreach ($user->getMobileApps($onlyConnected) as $app)
{
$apps->add($app);
}
}
return $apps;
}
public function getAndroidApps(bool $onlyConnected = true): Collection
{
$apps = new ImprovedArrayCollection();
foreach ($this->users as $user)
{
foreach ($user->getAndroidApps($onlyConnected) as $app)
{
$apps->add($app);
}
}
return $apps;
}
public function getIosApps(bool $onlyConnected = true): Collection
{
$apps = new ImprovedArrayCollection();
foreach ($this->users as $user)
{
foreach ($user->getIosApps($onlyConnected) as $app)
{
$apps->add($app);
}
}
return $apps;
}
}