mirror of
https://github.com/AzuraCast/AzuraCast.git
synced 2024-06-13 20:56:36 +00:00
Move entity OpenAPI annotations to attributes.
This commit is contained in:
parent
c943fc91ec
commit
a2eb5d0471
|
@ -10,8 +10,8 @@ use OpenApi\Annotations as OA;
|
|||
use Stringable;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
/** @OA\Schema(type="object") */
|
||||
#[
|
||||
OA\Schema(type: 'object'),
|
||||
ORM\Entity,
|
||||
ORM\Table(name: 'custom_field'),
|
||||
Attributes\Auditable
|
||||
|
@ -21,17 +21,27 @@ class CustomField implements Stringable, IdentifiableEntityInterface
|
|||
use Traits\HasAutoIncrementId;
|
||||
use Traits\TruncateStrings;
|
||||
|
||||
/** @OA\Property() */
|
||||
#[ORM\Column(length: 255)]
|
||||
#[Assert\NotBlank]
|
||||
#[
|
||||
OA\Property,
|
||||
ORM\Column(length: 255),
|
||||
Assert\NotBlank
|
||||
]
|
||||
protected string $name;
|
||||
|
||||
/** @OA\Property(description="The programmatic name for the field. Can be auto-generated from the full name.") */
|
||||
#[ORM\Column(length: 100, nullable: false)]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "The programmatic name for the field. Can be auto-generated from the full name."
|
||||
),
|
||||
ORM\Column(length: 100, nullable: false)
|
||||
]
|
||||
protected string $short_name;
|
||||
|
||||
/** @OA\Property(description="An ID3v2 field to automatically assign to this value, if it exists in the media file.") */
|
||||
#[ORM\Column(length: 100, nullable: true)]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "An ID3v2 field to automatically assign to this value, if it exists in the media file."
|
||||
),
|
||||
ORM\Column(length: 100, nullable: true)
|
||||
]
|
||||
protected ?string $auto_assign = null;
|
||||
|
||||
public function getName(): string
|
||||
|
|
|
@ -10,8 +10,8 @@ use Doctrine\Common\Collections\Collection;
|
|||
use Doctrine\ORM\Mapping as ORM;
|
||||
use OpenApi\Annotations as OA;
|
||||
|
||||
/** @OA\Schema(type="object") */
|
||||
#[
|
||||
OA\Schema(type: "object"),
|
||||
ORM\Entity,
|
||||
ORM\Table(name: 'relays'),
|
||||
ORM\HasLifecycleCallbacks
|
||||
|
@ -21,27 +21,37 @@ class Relay implements IdentifiableEntityInterface
|
|||
use Traits\HasAutoIncrementId;
|
||||
use Traits\TruncateStrings;
|
||||
|
||||
/** @OA\Property(example="https://custom-url.example.com") */
|
||||
#[ORM\Column(length: 255)]
|
||||
#[
|
||||
OA\Property(example: "https://custom-url.example.com"),
|
||||
ORM\Column(length: 255)
|
||||
]
|
||||
protected string $base_url;
|
||||
|
||||
/** @OA\Property(example="Relay") */
|
||||
#[ORM\Column(length: 100, nullable: true)]
|
||||
#[
|
||||
OA\Property(example: "Relay"),
|
||||
ORM\Column(length: 100, nullable: true)
|
||||
]
|
||||
protected ?string $name = 'Relay';
|
||||
|
||||
/** @OA\Property(example=true) */
|
||||
#[ORM\Column]
|
||||
#[
|
||||
OA\Property(example: true),
|
||||
ORM\Column
|
||||
]
|
||||
protected bool $is_visible_on_public_pages = true;
|
||||
|
||||
#[ORM\Column(type: 'array', nullable: true)]
|
||||
protected mixed $nowplaying;
|
||||
|
||||
/** @OA\Property(example=1609480800) */
|
||||
#[ORM\Column]
|
||||
#[
|
||||
OA\Property(example: 1609480800),
|
||||
ORM\Column
|
||||
]
|
||||
protected int $created_at;
|
||||
|
||||
/** @OA\Property(example=1609480800) */
|
||||
#[ORM\Column]
|
||||
#[
|
||||
OA\Property(example: 1609480800),
|
||||
ORM\Column
|
||||
]
|
||||
protected int $updated_at;
|
||||
|
||||
#[ORM\OneToMany(mappedBy: 'relay', targetEntity: StationRemote::class)]
|
||||
|
|
|
@ -13,8 +13,8 @@ use OpenApi\Annotations as OA;
|
|||
use Stringable;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
/** @OA\Schema(type="object") */
|
||||
#[
|
||||
OA\Schema(type: "object"),
|
||||
ORM\Entity,
|
||||
ORM\Table(name: 'role'),
|
||||
Attributes\Auditable
|
||||
|
@ -24,16 +24,20 @@ class Role implements JsonSerializable, Stringable, IdentifiableEntityInterface
|
|||
use Traits\HasAutoIncrementId;
|
||||
use Traits\TruncateStrings;
|
||||
|
||||
/** @OA\Property(example="Super Administrator") */
|
||||
#[ORM\Column(length: 100)]
|
||||
#[Assert\NotBlank]
|
||||
#[
|
||||
OA\Property(example: "Super Administrator"),
|
||||
ORM\Column(length: 100),
|
||||
Assert\NotBlank
|
||||
]
|
||||
protected string $name;
|
||||
|
||||
#[ORM\ManyToMany(targetEntity: User::class, mappedBy: 'roles')]
|
||||
protected Collection $users;
|
||||
|
||||
/** @OA\Property(type="array", @OA\Items) */
|
||||
#[ORM\OneToMany(mappedBy: 'role', targetEntity: RolePermission::class)]
|
||||
#[
|
||||
OA\Property(type: "array", items: new OA\Items()),
|
||||
ORM\OneToMany(mappedBy: 'role', targetEntity: RolePermission::class)
|
||||
]
|
||||
protected Collection $permissions;
|
||||
|
||||
public function __construct()
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -13,33 +13,44 @@ use Symfony\Component\Validator\Constraints as Assert;
|
|||
|
||||
use const PASSWORD_ARGON2ID;
|
||||
|
||||
/** @OA\Schema(type="object") */
|
||||
#[ORM\Entity, ORM\Table(name: 'sftp_user')]
|
||||
#[ORM\UniqueConstraint(name: 'username_idx', columns: ['username'])]
|
||||
#[UniqueEntity(fields: ['username'])]
|
||||
#[Auditable]
|
||||
#[
|
||||
OA\Schema(type: "object"),
|
||||
ORM\Entity,
|
||||
ORM\Table(name: 'sftp_user'),
|
||||
ORM\UniqueConstraint(name: 'username_idx', columns: ['username']),
|
||||
UniqueEntity(fields: ['username']),
|
||||
Auditable
|
||||
]
|
||||
class SftpUser implements IdentifiableEntityInterface
|
||||
{
|
||||
use Traits\HasAutoIncrementId;
|
||||
|
||||
#[ORM\ManyToOne(inversedBy: 'sftp_users')]
|
||||
#[ORM\JoinColumn(name: 'station_id', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')]
|
||||
#[
|
||||
ORM\ManyToOne(inversedBy: 'sftp_users'),
|
||||
ORM\JoinColumn(name: 'station_id', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')
|
||||
]
|
||||
protected Station $station;
|
||||
|
||||
/** @OA\Property() */
|
||||
#[ORM\Column(length: 32)]
|
||||
#[Assert\Length(min: 1, max: 32)]
|
||||
#[Assert\NotBlank]
|
||||
#[Assert\Regex(pattern: '/^[a-zA-Z0-9-_.~]+$/')]
|
||||
#[
|
||||
OA\Property,
|
||||
ORM\Column(length: 32),
|
||||
Assert\Length(min: 1, max: 32),
|
||||
Assert\NotBlank,
|
||||
Assert\Regex(pattern: '/^[a-zA-Z0-9-_.~]+$/')
|
||||
]
|
||||
protected string $username;
|
||||
|
||||
/** @OA\Property() */
|
||||
#[ORM\Column(length: 255)]
|
||||
#[Assert\NotBlank]
|
||||
#[
|
||||
OA\Property,
|
||||
ORM\Column(length: 255),
|
||||
Assert\NotBlank
|
||||
]
|
||||
protected string $password;
|
||||
|
||||
/** @OA\Property() */
|
||||
#[ORM\Column(name: 'public_keys', type: 'text', nullable: true)]
|
||||
#[
|
||||
OA\Property,
|
||||
ORM\Column(name: 'public_keys', type: 'text', nullable: true)
|
||||
]
|
||||
protected ?string $publicKeys = null;
|
||||
|
||||
public function __construct(Station $station)
|
||||
|
|
|
@ -8,9 +8,12 @@ use App\Entity\Interfaces\IdentifiableEntityInterface;
|
|||
use App\Entity\Interfaces\SongInterface;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
#[ORM\Entity, ORM\Table(name: 'song_history')]
|
||||
#[ORM\Index(columns: ['timestamp_start'], name: 'idx_timestamp_start')]
|
||||
#[ORM\Index(columns: ['timestamp_end'], name: 'idx_timestamp_end')]
|
||||
#[
|
||||
ORM\Entity,
|
||||
ORM\Table(name: 'song_history'),
|
||||
ORM\Index(columns: ['timestamp_start'], name: 'idx_timestamp_start'),
|
||||
ORM\Index(columns: ['timestamp_end'], name: 'idx_timestamp_end')
|
||||
]
|
||||
class SongHistory implements SongInterface, IdentifiableEntityInterface
|
||||
{
|
||||
use Traits\HasAutoIncrementId;
|
||||
|
|
|
@ -26,8 +26,8 @@ use Stringable;
|
|||
use Symfony\Component\Serializer\Annotation as Serializer;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
/** @OA\Schema(type="object", schema="Station") */
|
||||
#[
|
||||
OA\Schema(type: "object", schema: "Station"),
|
||||
ORM\Entity,
|
||||
ORM\Table(name: 'station'),
|
||||
ORM\Index(columns: ['short_name'], name: 'idx_short_name'),
|
||||
|
@ -44,275 +44,308 @@ class Station implements Stringable, IdentifiableEntityInterface
|
|||
// Taxonomical groups for permission-based serialization.
|
||||
public const GROUP_AUTOMATION = 'automation';
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* description="The full display name of the station.",
|
||||
* example="AzuraTest Radio"
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column(length: 100, nullable: false)]
|
||||
#[Assert\NotBlank]
|
||||
#[Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])]
|
||||
#[
|
||||
OA\Property(description: "The full display name of the station.", example: "AzuraTest Radio"),
|
||||
ORM\Column(length: 100, nullable: false),
|
||||
Assert\NotBlank,
|
||||
Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])
|
||||
]
|
||||
protected string $name = '';
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* description="The URL-friendly name for the station, typically auto-generated from the full station name.",
|
||||
* example="azuratest_radio"
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column(length: 100, nullable: false)]
|
||||
#[Assert\NotBlank]
|
||||
#[Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "The URL-friendly name for the station, typically auto-generated from the full station name.",
|
||||
example: "azuratest_radio"
|
||||
),
|
||||
ORM\Column(length: 100, nullable: false),
|
||||
Assert\NotBlank,
|
||||
Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])
|
||||
]
|
||||
protected string $short_name = '';
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* description="If set to 'false', prevents the station from broadcasting but leaves it in the database.",
|
||||
* example=true
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column]
|
||||
#[Serializer\Groups([EntityGroupsInterface::GROUP_ADMIN, EntityGroupsInterface::GROUP_ALL])]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "If set to 'false', prevents the station from broadcasting but leaves it in the database.",
|
||||
example: true
|
||||
),
|
||||
ORM\Column,
|
||||
Serializer\Groups([EntityGroupsInterface::GROUP_ADMIN, EntityGroupsInterface::GROUP_ALL])
|
||||
]
|
||||
protected bool $is_enabled = true;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* description="The frontend adapter (icecast,shoutcast,remote,etc)",
|
||||
* example="icecast"
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column(length: 100, nullable: true)]
|
||||
#[Assert\Choice(choices: [Adapters::FRONTEND_ICECAST, Adapters::FRONTEND_REMOTE, Adapters::FRONTEND_SHOUTCAST])]
|
||||
#[Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "The frontend adapter (icecast,shoutcast,remote,etc)",
|
||||
example: "icecast"
|
||||
),
|
||||
ORM\Column(length: 100, nullable: true),
|
||||
Assert\Choice(choices: [Adapters::FRONTEND_ICECAST, Adapters::FRONTEND_REMOTE, Adapters::FRONTEND_SHOUTCAST]),
|
||||
Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])
|
||||
]
|
||||
protected ?string $frontend_type = Adapters::FRONTEND_ICECAST;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* type="array",
|
||||
* description="An array containing station-specific frontend configuration",
|
||||
* @OA\Items()
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column(type: 'json', nullable: true)]
|
||||
#[Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])]
|
||||
#[
|
||||
OA\Property(
|
||||
type: "array",
|
||||
description: "An array containing station-specific frontend configuration",
|
||||
items: new OA\Items()
|
||||
),
|
||||
ORM\Column(type: 'json', nullable: true),
|
||||
Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])
|
||||
]
|
||||
protected ?array $frontend_config = null;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* description="The backend adapter (liquidsoap,etc)",
|
||||
* example="liquidsoap"
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column(length: 100, nullable: true)]
|
||||
#[Assert\Choice(choices: [Adapters::BACKEND_LIQUIDSOAP, Adapters::BACKEND_NONE])]
|
||||
#[Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "The backend adapter (liquidsoap,etc)",
|
||||
example: "liquidsoap"
|
||||
),
|
||||
ORM\Column(length: 100, nullable: true),
|
||||
Assert\Choice(choices: [Adapters::BACKEND_LIQUIDSOAP, Adapters::BACKEND_NONE]),
|
||||
Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])
|
||||
]
|
||||
protected ?string $backend_type = Adapters::BACKEND_LIQUIDSOAP;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* type="array",
|
||||
* description="An array containing station-specific backend configuration",
|
||||
* @OA\Items()
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column(type: 'json', nullable: true)]
|
||||
#[Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])]
|
||||
#[
|
||||
OA\Property(
|
||||
type: "array",
|
||||
description: "An array containing station-specific backend configuration",
|
||||
items: new OA\Items()
|
||||
),
|
||||
ORM\Column(type: 'json', nullable: true),
|
||||
Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])
|
||||
]
|
||||
protected ?array $backend_config = null;
|
||||
|
||||
#[ORM\Column(length: 150, nullable: true)]
|
||||
#[Attributes\AuditIgnore]
|
||||
#[
|
||||
ORM\Column(length: 150, nullable: true),
|
||||
Attributes\AuditIgnore
|
||||
]
|
||||
protected ?string $adapter_api_key = null;
|
||||
|
||||
/** @OA\Property(example="A sample radio station.") */
|
||||
#[ORM\Column(type: 'text', nullable: true)]
|
||||
#[Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])]
|
||||
#[
|
||||
OA\Property(example: "A sample radio station."),
|
||||
ORM\Column(type: 'text', nullable: true),
|
||||
Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])
|
||||
]
|
||||
protected ?string $description = null;
|
||||
|
||||
/** @OA\Property(example="https://demo.azuracast.com/") */
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
#[Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])]
|
||||
#[
|
||||
OA\Property(example: "https://demo.azuracast.com/"),
|
||||
ORM\Column(length: 255, nullable: true),
|
||||
Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])
|
||||
]
|
||||
protected ?string $url = null;
|
||||
|
||||
/** @OA\Property(example="Various") */
|
||||
#[ORM\Column(length: 150, nullable: true)]
|
||||
#[Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])]
|
||||
#[
|
||||
OA\Property(example: "Various"),
|
||||
ORM\Column(length: 150, nullable: true),
|
||||
Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])
|
||||
]
|
||||
protected ?string $genre = null;
|
||||
|
||||
/** @OA\Property(example="/var/azuracast/stations/azuratest_radio") */
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
#[Serializer\Groups([EntityGroupsInterface::GROUP_ADMIN, EntityGroupsInterface::GROUP_ALL])]
|
||||
#[
|
||||
OA\Property(example: "/var/azuracast/stations/azuratest_radio"),
|
||||
ORM\Column(length: 255, nullable: true),
|
||||
Serializer\Groups([EntityGroupsInterface::GROUP_ADMIN, EntityGroupsInterface::GROUP_ALL])
|
||||
]
|
||||
protected ?string $radio_base_dir = null;
|
||||
|
||||
#[ORM\Column(type: 'array', nullable: true)]
|
||||
#[Attributes\AuditIgnore]
|
||||
#[
|
||||
ORM\Column(type: 'array', nullable: true),
|
||||
Attributes\AuditIgnore
|
||||
]
|
||||
protected mixed $nowplaying;
|
||||
|
||||
#[ORM\Column(nullable: true)]
|
||||
#[Attributes\AuditIgnore]
|
||||
#[
|
||||
ORM\Column(nullable: true),
|
||||
Attributes\AuditIgnore
|
||||
]
|
||||
protected ?int $nowplaying_timestamp = null;
|
||||
|
||||
/** @OA\Property(type="array", @OA\Items()) */
|
||||
#[ORM\Column(type: 'json', nullable: true)]
|
||||
#[Serializer\Groups([self::GROUP_AUTOMATION, EntityGroupsInterface::GROUP_ALL])]
|
||||
#[
|
||||
OA\Property(type: "array", items: new OA\Items()),
|
||||
ORM\Column(type: 'json', nullable: true),
|
||||
Serializer\Groups([self::GROUP_AUTOMATION, EntityGroupsInterface::GROUP_ALL])
|
||||
]
|
||||
protected ?array $automation_settings = null;
|
||||
|
||||
#[ORM\Column(nullable: true)]
|
||||
#[Attributes\AuditIgnore]
|
||||
#[Serializer\Groups([self::GROUP_AUTOMATION, EntityGroupsInterface::GROUP_ALL])]
|
||||
#[
|
||||
ORM\Column(nullable: true),
|
||||
Attributes\AuditIgnore,
|
||||
Serializer\Groups([self::GROUP_AUTOMATION, EntityGroupsInterface::GROUP_ALL])
|
||||
]
|
||||
protected ?int $automation_timestamp = 0;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* description="Whether listeners can request songs to play on this station.",
|
||||
* example=true
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column]
|
||||
#[Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "Whether listeners can request songs to play on this station.",
|
||||
example: true
|
||||
),
|
||||
ORM\Column,
|
||||
Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])
|
||||
]
|
||||
protected bool $enable_requests = false;
|
||||
|
||||
/** @OA\Property(example=5) */
|
||||
#[ORM\Column(nullable: true)]
|
||||
#[Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])]
|
||||
#[
|
||||
OA\Property(example: 5),
|
||||
ORM\Column(nullable: true),
|
||||
Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])
|
||||
]
|
||||
protected ?int $request_delay = 5;
|
||||
|
||||
/** @OA\Property(example=15) */
|
||||
#[ORM\Column(nullable: true)]
|
||||
#[Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])]
|
||||
#[
|
||||
OA\Property(example: 15),
|
||||
ORM\Column(nullable: true),
|
||||
Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])
|
||||
]
|
||||
protected ?int $request_threshold = 15;
|
||||
|
||||
/** @OA\Property(example=0) */
|
||||
#[ORM\Column(nullable: true, options: ['default' => 0])]
|
||||
#[Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])]
|
||||
#[
|
||||
OA\Property(example: 0),
|
||||
ORM\Column(nullable: true, options: ['default' => 0]),
|
||||
Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])
|
||||
]
|
||||
protected ?int $disconnect_deactivate_streamer = 0;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* description="Whether streamers are allowed to broadcast to this station at all.",
|
||||
* example=false
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column]
|
||||
#[Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "Whether streamers are allowed to broadcast to this station at all.",
|
||||
example: false
|
||||
),
|
||||
ORM\Column,
|
||||
Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])
|
||||
]
|
||||
protected bool $enable_streamers = false;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* description="Whether a streamer is currently active on the station.",
|
||||
* example=false
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column]
|
||||
#[Attributes\AuditIgnore]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "Whether a streamer is currently active on the station.",
|
||||
example: false
|
||||
),
|
||||
ORM\Column,
|
||||
Attributes\AuditIgnore
|
||||
]
|
||||
protected bool $is_streamer_live = false;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* description="Whether this station is visible as a public page and in a now-playing API response.",
|
||||
* example=true
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column]
|
||||
#[Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "Whether this station is visible as a public page and in a now-playing API response.",
|
||||
example: true
|
||||
),
|
||||
ORM\Column,
|
||||
Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])
|
||||
]
|
||||
protected bool $enable_public_page = true;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* description="Whether this station has a public 'on-demand' streaming and download page.",
|
||||
* example=true
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column]
|
||||
#[Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "Whether this station has a public 'on-demand' streaming and download page.",
|
||||
example: true
|
||||
),
|
||||
ORM\Column,
|
||||
Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])
|
||||
]
|
||||
protected bool $enable_on_demand = false;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* description="Whether the 'on-demand' page offers download capability.",
|
||||
* example=true
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column]
|
||||
#[Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "Whether the 'on-demand' page offers download capability.",
|
||||
example: true
|
||||
),
|
||||
ORM\Column,
|
||||
Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])
|
||||
]
|
||||
protected bool $enable_on_demand_download = true;
|
||||
|
||||
#[ORM\Column]
|
||||
#[Attributes\AuditIgnore]
|
||||
#[
|
||||
ORM\Column,
|
||||
Attributes\AuditIgnore
|
||||
]
|
||||
protected bool $needs_restart = false;
|
||||
|
||||
#[ORM\Column]
|
||||
#[Attributes\AuditIgnore]
|
||||
#[
|
||||
ORM\Column,
|
||||
Attributes\AuditIgnore
|
||||
]
|
||||
protected bool $has_started = false;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* description="The number of 'last played' history items to show for a station in API responses.",
|
||||
* example=5
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column(type: 'smallint')]
|
||||
#[Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "The number of 'last played' history items to show for a station in API responses.",
|
||||
example: 5
|
||||
),
|
||||
ORM\Column(type: 'smallint'),
|
||||
Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])
|
||||
]
|
||||
protected int $api_history_items = 5;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* description="The time zone that station operations should take place in.",
|
||||
* example="UTC"
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column(length: 100, nullable: true)]
|
||||
#[Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "The time zone that station operations should take place in.",
|
||||
example: "UTC"
|
||||
),
|
||||
ORM\Column(length: 100, nullable: true),
|
||||
Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])
|
||||
]
|
||||
protected ?string $timezone = 'UTC';
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* description="The station-specific default album artwork URL.",
|
||||
* example="https://example.com/image.jpg"
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
#[Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "The station-specific default album artwork URL.",
|
||||
example: "https://example.com/image.jpg"
|
||||
),
|
||||
ORM\Column(length: 255, nullable: true),
|
||||
Serializer\Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])
|
||||
]
|
||||
protected ?string $default_album_art_url = null;
|
||||
|
||||
#[ORM\OneToMany(mappedBy: 'station', targetEntity: SongHistory::class)]
|
||||
#[ORM\OrderBy(['timestamp_start' => 'desc'])]
|
||||
#[
|
||||
ORM\OneToMany(mappedBy: 'station', targetEntity: SongHistory::class),
|
||||
ORM\OrderBy(['timestamp_start' => 'desc'])
|
||||
]
|
||||
protected Collection $history;
|
||||
|
||||
#[ORM\ManyToOne]
|
||||
#[ORM\JoinColumn(
|
||||
name: 'media_storage_location_id',
|
||||
referencedColumnName: 'id',
|
||||
nullable: true,
|
||||
onDelete: 'SET NULL'
|
||||
)]
|
||||
#[DeepNormalize(true)]
|
||||
#[Serializer\MaxDepth(1)]
|
||||
#[Serializer\Groups([EntityGroupsInterface::GROUP_ADMIN, EntityGroupsInterface::GROUP_ALL])]
|
||||
#[
|
||||
ORM\ManyToOne,
|
||||
ORM\JoinColumn(
|
||||
name: 'media_storage_location_id',
|
||||
referencedColumnName: 'id',
|
||||
nullable: true,
|
||||
onDelete: 'SET NULL'
|
||||
),
|
||||
DeepNormalize(true),
|
||||
Serializer\MaxDepth(1),
|
||||
Serializer\Groups([EntityGroupsInterface::GROUP_ADMIN, EntityGroupsInterface::GROUP_ALL])
|
||||
]
|
||||
protected ?StorageLocation $media_storage_location = null;
|
||||
|
||||
#[ORM\ManyToOne]
|
||||
#[ORM\JoinColumn(
|
||||
name: 'recordings_storage_location_id',
|
||||
referencedColumnName: 'id',
|
||||
nullable: true,
|
||||
onDelete: 'SET NULL'
|
||||
)]
|
||||
#[DeepNormalize(true)]
|
||||
#[Serializer\MaxDepth(1)]
|
||||
#[Serializer\Groups([EntityGroupsInterface::GROUP_ADMIN, EntityGroupsInterface::GROUP_ALL])]
|
||||
#[
|
||||
ORM\ManyToOne,
|
||||
ORM\JoinColumn(
|
||||
name: 'recordings_storage_location_id',
|
||||
referencedColumnName: 'id',
|
||||
nullable: true,
|
||||
onDelete: 'SET NULL'
|
||||
),
|
||||
DeepNormalize(true),
|
||||
Serializer\MaxDepth(1),
|
||||
Serializer\Groups([EntityGroupsInterface::GROUP_ADMIN, EntityGroupsInterface::GROUP_ALL])
|
||||
]
|
||||
protected ?StorageLocation $recordings_storage_location = null;
|
||||
|
||||
#[ORM\ManyToOne]
|
||||
#[ORM\JoinColumn(
|
||||
name: 'podcasts_storage_location_id',
|
||||
referencedColumnName: 'id',
|
||||
nullable: true,
|
||||
onDelete: 'SET NULL'
|
||||
)]
|
||||
#[DeepNormalize(true)]
|
||||
#[Serializer\MaxDepth(1)]
|
||||
#[Serializer\Groups([EntityGroupsInterface::GROUP_ADMIN, EntityGroupsInterface::GROUP_ALL])]
|
||||
#[
|
||||
ORM\ManyToOne,
|
||||
ORM\JoinColumn(
|
||||
name: 'podcasts_storage_location_id',
|
||||
referencedColumnName: 'id',
|
||||
nullable: true,
|
||||
onDelete: 'SET NULL'
|
||||
),
|
||||
DeepNormalize(true),
|
||||
Serializer\MaxDepth(1),
|
||||
Serializer\Groups([EntityGroupsInterface::GROUP_ADMIN, EntityGroupsInterface::GROUP_ALL])
|
||||
]
|
||||
protected ?StorageLocation $podcasts_storage_location = null;
|
||||
|
||||
#[ORM\OneToMany(mappedBy: 'station', targetEntity: StationStreamer::class)]
|
||||
|
@ -321,15 +354,19 @@ class Station implements Stringable, IdentifiableEntityInterface
|
|||
#[ORM\Column(nullable: true)]
|
||||
protected ?int $current_streamer_id = null;
|
||||
|
||||
#[ORM\ManyToOne]
|
||||
#[ORM\JoinColumn(name: 'current_streamer_id', referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')]
|
||||
#[
|
||||
ORM\ManyToOne,
|
||||
ORM\JoinColumn(name: 'current_streamer_id', referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL')
|
||||
]
|
||||
protected ?StationStreamer $current_streamer = null;
|
||||
|
||||
#[ORM\OneToMany(mappedBy: 'station', targetEntity: RolePermission::class)]
|
||||
protected Collection $permissions;
|
||||
|
||||
#[ORM\OneToMany(mappedBy: 'station', targetEntity: StationPlaylist::class)]
|
||||
#[ORM\OrderBy(['type' => 'ASC', 'weight' => 'DESC'])]
|
||||
#[
|
||||
ORM\OneToMany(mappedBy: 'station', targetEntity: StationPlaylist::class),
|
||||
ORM\OrderBy(['type' => 'ASC', 'weight' => 'DESC'])
|
||||
]
|
||||
protected Collection $playlists;
|
||||
|
||||
#[ORM\OneToMany(mappedBy: 'station', targetEntity: StationMount::class)]
|
||||
|
|
|
@ -20,8 +20,8 @@ use OpenApi\Annotations as OA;
|
|||
use RuntimeException;
|
||||
use Symfony\Component\Serializer\Annotation as Serializer;
|
||||
|
||||
/** @OA\Schema(type="object") */
|
||||
#[
|
||||
OA\Schema(type: "object"),
|
||||
ORM\Entity,
|
||||
ORM\Table(name: 'station_media'),
|
||||
ORM\Index(columns: ['title', 'artist', 'album'], name: 'search_idx'),
|
||||
|
@ -38,161 +38,165 @@ class StationMedia implements SongInterface, ProcessableMediaInterface, PathAwar
|
|||
public const DIR_ALBUM_ART = '.albumart';
|
||||
public const DIR_WAVEFORMS = '.waveforms';
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* description="A unique identifier associated with this record.",
|
||||
* example="69b536afc7ebbf16457b8645"
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column(length: 25, nullable: true)]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "A unique identifier associated with this record.",
|
||||
example: "69b536afc7ebbf16457b8645"
|
||||
),
|
||||
ORM\Column(length: 25, nullable: true)
|
||||
]
|
||||
protected ?string $unique_id = null;
|
||||
|
||||
#[ORM\Column(nullable: false)]
|
||||
protected int $storage_location_id;
|
||||
|
||||
#[ORM\ManyToOne(inversedBy: 'media')]
|
||||
#[ORM\JoinColumn(name: 'storage_location_id', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')]
|
||||
#[
|
||||
ORM\ManyToOne(inversedBy: 'media'),
|
||||
ORM\JoinColumn(name: 'storage_location_id', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')
|
||||
]
|
||||
protected StorageLocation $storage_location;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* description="The name of the media file's album.",
|
||||
* example="Test Album"
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column(length: 200, nullable: true)]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "The name of the media file's album.",
|
||||
example: "Test Album"
|
||||
),
|
||||
ORM\Column(length: 200, nullable: true)
|
||||
]
|
||||
protected ?string $album = null;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* description="The genre of the media file.",
|
||||
* example="Rock"
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column(length: 30, nullable: true)]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "The genre of the media file.",
|
||||
example: "Rock"
|
||||
),
|
||||
ORM\Column(length: 30, nullable: true)
|
||||
]
|
||||
protected ?string $genre = null;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* description="Full lyrics of the track, if available.",
|
||||
* example="...Never gonna give you up..."
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column(type: 'text', nullable: true)]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "Full lyrics of the track, if available.",
|
||||
example: "...Never gonna give you up..."
|
||||
),
|
||||
ORM\Column(type: 'text', nullable: true)
|
||||
]
|
||||
protected ?string $lyrics = null;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* description="The track ISRC (International Standard Recording Code), used for licensing purposes.",
|
||||
* example="GBARL0600786"
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column(length: 15, nullable: true)]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "The track ISRC (International Standard Recording Code), used for licensing purposes.",
|
||||
example: "GBARL0600786"
|
||||
),
|
||||
ORM\Column(length: 15, nullable: true)
|
||||
]
|
||||
protected ?string $isrc = null;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* description="The song duration in seconds.",
|
||||
* example=240.00
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column(type: 'decimal', precision: 7, scale: 2, nullable: true)]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "The song duration in seconds.",
|
||||
example: 240.00
|
||||
),
|
||||
ORM\Column(type: 'decimal', precision: 7, scale: 2, nullable: true)
|
||||
]
|
||||
protected ?float $length = 0.00;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* description="The formatted song duration (in mm:ss format)",
|
||||
* example="4:00"
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column(length: 10, nullable: true)]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "The formatted song duration (in mm:ss format)",
|
||||
example: "4:00"
|
||||
),
|
||||
ORM\Column(length: 10, nullable: true)
|
||||
]
|
||||
protected ?string $length_text = '0:00';
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* description="The relative path of the media file.",
|
||||
* example="test.mp3"
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column(length: 500)]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "The relative path of the media file.",
|
||||
example: "test.mp3"
|
||||
),
|
||||
ORM\Column(length: 500)
|
||||
]
|
||||
protected string $path;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* description="The UNIX timestamp when the database was last modified.",
|
||||
* example=1609480800
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column(nullable: true)]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "The UNIX timestamp when the database was last modified.",
|
||||
example: 1609480800
|
||||
),
|
||||
ORM\Column(nullable: true)
|
||||
]
|
||||
protected ?int $mtime = 0;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* description="The amount of amplification (in dB) to be applied to the radio source (liq_amplify)",
|
||||
* example=-14.00
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column(type: 'decimal', precision: 6, scale: 1, nullable: true)]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "The amount of amplification (in dB) to be applied to the radio source (liq_amplify)",
|
||||
example: -14.00
|
||||
),
|
||||
ORM\Column(type: 'decimal', precision: 6, scale: 1, nullable: true)
|
||||
]
|
||||
protected ?float $amplify = null;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* description="The length of time (in seconds) before the next song starts in the fade (liq_start_next)",
|
||||
* example=2.00
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column(type: 'decimal', precision: 6, scale: 1, nullable: true)]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "The length of time (in seconds) before the next song starts in the fade (liq_start_next)",
|
||||
example: 2.00
|
||||
),
|
||||
ORM\Column(type: 'decimal', precision: 6, scale: 1, nullable: true)
|
||||
]
|
||||
protected ?float $fade_overlap = null;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* description="The length of time (in seconds) to fade in the next track (liq_fade_in)",
|
||||
* example=3.00
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column(type: 'decimal', precision: 6, scale: 1, nullable: true)]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "The length of time (in seconds) to fade in the next track (liq_fade_in)",
|
||||
example: 3.00
|
||||
),
|
||||
ORM\Column(type: 'decimal', precision: 6, scale: 1, nullable: true)
|
||||
]
|
||||
protected ?float $fade_in = null;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* description="The length of time (in seconds) to fade out the previous track (liq_fade_out)",
|
||||
* example=3.00
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column(type: 'decimal', precision: 6, scale: 1, nullable: true)]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "The length of time (in seconds) to fade out the previous track (liq_fade_out)",
|
||||
example: 3.00
|
||||
),
|
||||
ORM\Column(type: 'decimal', precision: 6, scale: 1, nullable: true)
|
||||
]
|
||||
protected ?float $fade_out = null;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* description="The length of time (in seconds) from the start of the track to start playing (liq_cue_in)",
|
||||
* example=30.00
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column(type: 'decimal', precision: 6, scale: 1, nullable: true)]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "The length of time (in seconds) from the start of the track to start playing (liq_cue_in)",
|
||||
example: 30.00
|
||||
),
|
||||
ORM\Column(type: 'decimal', precision: 6, scale: 1, nullable: true)
|
||||
]
|
||||
protected ?float $cue_in = null;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* description="The length of time (in seconds) from the CUE-IN of the track to stop playing (liq_cue_out)",
|
||||
* example=30.00
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column(type: 'decimal', precision: 6, scale: 1, nullable: true)]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "The length of time (in seconds) from the CUE-IN of the track to stop playing (liq_cue_out)",
|
||||
example: 30.00
|
||||
),
|
||||
ORM\Column(type: 'decimal', precision: 6, scale: 1, nullable: true)
|
||||
]
|
||||
protected ?float $cue_out = null;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* description="The latest time (UNIX timestamp) when album art was updated.",
|
||||
* example=1609480800
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "The latest time (UNIX timestamp) when album art was updated.",
|
||||
example: 1609480800
|
||||
),
|
||||
ORM\Column
|
||||
]
|
||||
protected int $art_updated_at = 0;
|
||||
|
||||
/** @OA\Property(type="array", @OA\Items()) */
|
||||
#[ORM\OneToMany(mappedBy: 'media', targetEntity: StationPlaylistMedia::class)]
|
||||
#[DeepNormalize(true)]
|
||||
#[Serializer\MaxDepth(1)]
|
||||
#[
|
||||
OA\Property(type: "array", items: new OA\Items()),
|
||||
ORM\OneToMany(mappedBy: 'media', targetEntity: StationPlaylistMedia::class),
|
||||
DeepNormalize(true),
|
||||
Serializer\MaxDepth(1)
|
||||
]
|
||||
protected Collection $playlists;
|
||||
|
||||
#[ORM\OneToMany(mappedBy: 'media', targetEntity: StationMediaCustomField::class)]
|
||||
|
|
|
@ -13,8 +13,8 @@ use Psr\Http\Message\UriInterface;
|
|||
use Stringable;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
/** @OA\Schema(type="object") */
|
||||
#[
|
||||
OA\Schema(type: "object"),
|
||||
ORM\Entity,
|
||||
ORM\Table(name: 'station_mounts'),
|
||||
Attributes\Auditable
|
||||
|
@ -32,88 +32,118 @@ class StationMount implements
|
|||
#[ORM\Column(nullable: false)]
|
||||
protected int $station_id;
|
||||
|
||||
#[ORM\ManyToOne(inversedBy: 'mounts')]
|
||||
#[ORM\JoinColumn(name: 'station_id', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')]
|
||||
#[
|
||||
ORM\ManyToOne(inversedBy: 'mounts'),
|
||||
ORM\JoinColumn(name: 'station_id', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')
|
||||
]
|
||||
protected Station $station;
|
||||
|
||||
/** @OA\Property(example="/radio.mp3") */
|
||||
#[ORM\Column(length: 100)]
|
||||
#[Assert\NotBlank]
|
||||
#[
|
||||
OA\Property(example: "/radio.mp3"),
|
||||
ORM\Column(length: 100),
|
||||
Assert\NotBlank
|
||||
]
|
||||
protected string $name = '';
|
||||
|
||||
/** @OA\Property(example="128kbps MP3") */
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
#[
|
||||
OA\Property(example: "128kbps MP3"),
|
||||
ORM\Column(length: 255, nullable: true)
|
||||
]
|
||||
protected ?string $display_name = null;
|
||||
|
||||
/** @OA\Property(example=true) */
|
||||
#[ORM\Column]
|
||||
#[
|
||||
OA\Property(example: true),
|
||||
ORM\Column
|
||||
]
|
||||
protected bool $is_visible_on_public_pages = true;
|
||||
|
||||
/** @OA\Property(example=false) */
|
||||
#[ORM\Column]
|
||||
#[
|
||||
OA\Property(example: false),
|
||||
ORM\Column
|
||||
]
|
||||
protected bool $is_default = false;
|
||||
|
||||
/** @OA\Property(example=false) */
|
||||
#[ORM\Column]
|
||||
#[
|
||||
OA\Property(example: false),
|
||||
ORM\Column
|
||||
]
|
||||
protected bool $is_public = false;
|
||||
|
||||
/** @OA\Property(example="/error.mp3") */
|
||||
#[ORM\Column(length: 100, nullable: true)]
|
||||
#[
|
||||
OA\Property(example: "/error.mp3"),
|
||||
ORM\Column(length: 100, nullable: true)
|
||||
]
|
||||
protected ?string $fallback_mount = null;
|
||||
|
||||
/** @OA\Property(example="https://radio.example.com:8000/radio.mp3") */
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
#[
|
||||
OA\Property(example: "https://radio.example.com:8000/radio.mp3"),
|
||||
ORM\Column(length: 255, nullable: true)
|
||||
]
|
||||
protected ?string $relay_url = null;
|
||||
|
||||
/** @OA\Property(example="") */
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
#[
|
||||
OA\Property(example: ""),
|
||||
ORM\Column(length: 255, nullable: true)
|
||||
]
|
||||
protected ?string $authhash = null;
|
||||
|
||||
/** @OA\Property(example=43200) */
|
||||
#[ORM\Column(type: 'integer', nullable: false)]
|
||||
#[
|
||||
OA\Property(example: 43200),
|
||||
ORM\Column(type: 'integer', nullable: false)
|
||||
]
|
||||
protected int $max_listener_duration = 0;
|
||||
|
||||
/** @OA\Property(example=true) */
|
||||
#[ORM\Column]
|
||||
#[
|
||||
OA\Property(example: true),
|
||||
ORM\Column
|
||||
]
|
||||
protected bool $enable_autodj = true;
|
||||
|
||||
/** @OA\Property(example="mp3") */
|
||||
#[ORM\Column(length: 10, nullable: true)]
|
||||
#[
|
||||
OA\Property(example: "mp3"),
|
||||
ORM\Column(length: 10, nullable: true)
|
||||
]
|
||||
protected ?string $autodj_format = 'mp3';
|
||||
|
||||
/** @OA\Property(example=128) */
|
||||
#[ORM\Column(type: 'smallint', nullable: true)]
|
||||
#[
|
||||
OA\Property(example: 128),
|
||||
ORM\Column(type: 'smallint', nullable: true)
|
||||
]
|
||||
protected ?int $autodj_bitrate = 128;
|
||||
|
||||
/** @OA\Property(example="https://custom-listen-url.example.com/stream.mp3") */
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
#[
|
||||
OA\Property(example: "https://custom-listen-url.example.com/stream.mp3"),
|
||||
ORM\Column(length: 255, nullable: true)
|
||||
]
|
||||
protected ?string $custom_listen_url = null;
|
||||
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
protected ?string $intro_path = null;
|
||||
|
||||
/** @OA\Property(type="array", @OA\Items()) */
|
||||
#[ORM\Column(type: 'text', nullable: true)]
|
||||
#[
|
||||
OA\Property(type: "array", items: new OA\Items()),
|
||||
ORM\Column(type: 'text', nullable: true)
|
||||
]
|
||||
protected ?string $frontend_config = null;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* description="The most recent number of unique listeners.",
|
||||
* example=10
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column]
|
||||
#[Attributes\AuditIgnore]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "The most recent number of unique listeners.",
|
||||
example: 10
|
||||
),
|
||||
ORM\Column,
|
||||
Attributes\AuditIgnore
|
||||
]
|
||||
protected int $listeners_unique = 0;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* description="The most recent number of total (non-unique) listeners.",
|
||||
* example=12
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column]
|
||||
#[Attributes\AuditIgnore]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "The most recent number of total (non-unique) listeners.",
|
||||
example: 12
|
||||
),
|
||||
ORM\Column,
|
||||
Attributes\AuditIgnore
|
||||
]
|
||||
protected int $listeners_total = 0;
|
||||
|
||||
public function __construct(Station $station)
|
||||
|
|
|
@ -13,8 +13,8 @@ use Stringable;
|
|||
use Symfony\Component\Serializer\Annotation as Serializer;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
/** @OA\Schema(type="object") */
|
||||
#[
|
||||
OA\Schema(type: "object"),
|
||||
ORM\Entity,
|
||||
ORM\Table(name: 'station_playlists'),
|
||||
ORM\HasLifecycleCallbacks,
|
||||
|
@ -55,132 +55,169 @@ class StationPlaylist implements
|
|||
#[ORM\Column(nullable: false)]
|
||||
protected int $station_id;
|
||||
|
||||
#[ORM\ManyToOne(inversedBy: 'playlists')]
|
||||
#[ORM\JoinColumn(name: 'station_id', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')]
|
||||
#[
|
||||
ORM\ManyToOne(inversedBy: 'playlists'),
|
||||
ORM\JoinColumn(name: 'station_id', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')
|
||||
]
|
||||
protected Station $station;
|
||||
|
||||
/** @OA\Property(example="Test Playlist") */
|
||||
#[ORM\Column(length: 200)]
|
||||
#[Assert\NotBlank]
|
||||
#[
|
||||
OA\Property(example: "Test Playlist"),
|
||||
ORM\Column(length: 200),
|
||||
Assert\NotBlank
|
||||
]
|
||||
protected string $name;
|
||||
|
||||
/** @OA\Property(example="default") */
|
||||
#[ORM\Column(length: 50)]
|
||||
#[Assert\Choice(choices: [
|
||||
self::TYPE_DEFAULT,
|
||||
self::TYPE_ONCE_PER_X_SONGS,
|
||||
self::TYPE_ONCE_PER_X_MINUTES,
|
||||
self::TYPE_ONCE_PER_HOUR,
|
||||
self::TYPE_ADVANCED,
|
||||
])]
|
||||
#[
|
||||
OA\Property(example: "default"),
|
||||
ORM\Column(length: 50),
|
||||
Assert\Choice(choices: [
|
||||
self::TYPE_DEFAULT,
|
||||
self::TYPE_ONCE_PER_X_SONGS,
|
||||
self::TYPE_ONCE_PER_X_MINUTES,
|
||||
self::TYPE_ONCE_PER_HOUR,
|
||||
self::TYPE_ADVANCED,
|
||||
])
|
||||
]
|
||||
protected string $type = self::TYPE_DEFAULT;
|
||||
|
||||
/** @OA\Property(example="songs") */
|
||||
#[ORM\Column(length: 50)]
|
||||
#[Assert\Choice(choices: [self::SOURCE_SONGS, self::SOURCE_REMOTE_URL])]
|
||||
#[
|
||||
OA\Property(example: "songs"),
|
||||
ORM\Column(length: 50),
|
||||
Assert\Choice(choices: [self::SOURCE_SONGS, self::SOURCE_REMOTE_URL])
|
||||
]
|
||||
protected string $source = self::SOURCE_SONGS;
|
||||
|
||||
/** @OA\Property(example="shuffle") */
|
||||
#[ORM\Column(name: 'playback_order', length: 50)]
|
||||
#[Assert\Choice(choices: [self::ORDER_RANDOM, self::ORDER_SHUFFLE, self::ORDER_SEQUENTIAL])]
|
||||
#[
|
||||
OA\Property(example: "shuffle"),
|
||||
ORM\Column(name: 'playback_order', length: 50),
|
||||
Assert\Choice(choices: [self::ORDER_RANDOM, self::ORDER_SHUFFLE, self::ORDER_SEQUENTIAL])
|
||||
]
|
||||
protected string $order = self::ORDER_SHUFFLE;
|
||||
|
||||
/** @OA\Property(example="https://remote-url.example.com/stream.mp3") */
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
#[
|
||||
OA\Property(example: "https://remote-url.example.com/stream.mp3"),
|
||||
ORM\Column(length: 255, nullable: true)
|
||||
]
|
||||
protected ?string $remote_url = null;
|
||||
|
||||
/** @OA\Property(example="stream") */
|
||||
#[ORM\Column(length: 25, nullable: true)]
|
||||
#[Assert\Choice(choices: [self::REMOTE_TYPE_STREAM, self::REMOTE_TYPE_PLAYLIST])]
|
||||
#[
|
||||
OA\Property(example: "stream"),
|
||||
ORM\Column(length: 25, nullable: true),
|
||||
Assert\Choice(choices: [self::REMOTE_TYPE_STREAM, self::REMOTE_TYPE_PLAYLIST])
|
||||
]
|
||||
protected ?string $remote_type = self::REMOTE_TYPE_STREAM;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* description="The total time (in seconds) that Liquidsoap should buffer remote URL streams.",
|
||||
* example=0
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column(name: 'remote_timeout', type: 'smallint')]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "The total time (in seconds) that Liquidsoap should buffer remote URL streams.",
|
||||
example: 0
|
||||
),
|
||||
ORM\Column(name: 'remote_timeout', type: 'smallint')
|
||||
]
|
||||
protected int $remote_buffer = 0;
|
||||
|
||||
/** @OA\Property(example=true) */
|
||||
#[ORM\Column]
|
||||
#[
|
||||
OA\Property(example: true),
|
||||
ORM\Column
|
||||
]
|
||||
protected bool $is_enabled = true;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* description="If yes, do not send jingle metadata to AutoDJ or trigger web hooks.",
|
||||
* example=false
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "If yes, do not send jingle metadata to AutoDJ or trigger web hooks.",
|
||||
example: false
|
||||
),
|
||||
ORM\Column
|
||||
]
|
||||
protected bool $is_jingle = false;
|
||||
|
||||
/** @OA\Property(example=5) */
|
||||
#[ORM\Column(type: 'smallint')]
|
||||
#[
|
||||
OA\Property(example: 5),
|
||||
ORM\Column(type: 'smallint')
|
||||
]
|
||||
protected int $play_per_songs = 0;
|
||||
|
||||
/** @OA\Property(example=120) */
|
||||
#[ORM\Column(type: 'smallint')]
|
||||
#[
|
||||
OA\Property(example: 120),
|
||||
ORM\Column(type: 'smallint')
|
||||
]
|
||||
protected int $play_per_minutes = 0;
|
||||
|
||||
/** @OA\Property(example=15) */
|
||||
#[ORM\Column(type: 'smallint')]
|
||||
#[
|
||||
OA\Property(example: 15),
|
||||
ORM\Column(type: 'smallint')
|
||||
]
|
||||
protected int $play_per_hour_minute = 0;
|
||||
|
||||
/** @OA\Property(example=3) */
|
||||
#[ORM\Column(type: 'smallint')]
|
||||
#[
|
||||
OA\Property(example: 3),
|
||||
ORM\Column(type: 'smallint')
|
||||
]
|
||||
protected int $weight = self::DEFAULT_WEIGHT;
|
||||
|
||||
/** @OA\Property(example=true) */
|
||||
#[ORM\Column]
|
||||
#[
|
||||
OA\Property(example: true),
|
||||
ORM\Column
|
||||
]
|
||||
protected bool $include_in_requests = true;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* description="Whether this playlist's media is included in 'on demand' download/streaming if enabled.",
|
||||
* example=true
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "Whether this playlist's media is included in 'on demand' download/streaming if enabled.",
|
||||
example: true
|
||||
),
|
||||
ORM\Column
|
||||
]
|
||||
protected bool $include_in_on_demand = false;
|
||||
|
||||
/** @OA\Property(example=false) */
|
||||
#[ORM\Column]
|
||||
#[
|
||||
OA\Property(example: false),
|
||||
ORM\Column
|
||||
]
|
||||
protected bool $include_in_automation = false;
|
||||
|
||||
/** @OA\Property(example="interrupt,loop_once,single_track,merge") */
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
#[
|
||||
OA\Property(example: "interrupt,loop_once,single_track,merge"),
|
||||
ORM\Column(length: 255, nullable: true)
|
||||
]
|
||||
protected ?string $backend_options = '';
|
||||
|
||||
/** @OA\Property(example=true) */
|
||||
#[ORM\Column]
|
||||
#[
|
||||
OA\Property(example: true),
|
||||
ORM\Column
|
||||
]
|
||||
protected bool $avoid_duplicates = true;
|
||||
|
||||
#[ORM\Column]
|
||||
#[Attributes\AuditIgnore]
|
||||
#[
|
||||
ORM\Column,
|
||||
Attributes\AuditIgnore
|
||||
]
|
||||
protected int $played_at = 0;
|
||||
|
||||
#[ORM\Column]
|
||||
#[Attributes\AuditIgnore]
|
||||
#[
|
||||
ORM\Column,
|
||||
Attributes\AuditIgnore
|
||||
]
|
||||
protected int $queue_reset_at = 0;
|
||||
|
||||
#[ORM\OneToMany(mappedBy: 'playlist', targetEntity: StationPlaylistMedia::class, fetch: 'EXTRA_LAZY')]
|
||||
#[ORM\OrderBy(['weight' => 'ASC'])]
|
||||
#[
|
||||
ORM\OneToMany(mappedBy: 'playlist', targetEntity: StationPlaylistMedia::class, fetch: 'EXTRA_LAZY'),
|
||||
ORM\OrderBy(['weight' => 'ASC'])
|
||||
]
|
||||
protected Collection $media_items;
|
||||
|
||||
#[ORM\OneToMany(mappedBy: 'playlist', targetEntity: StationPlaylistFolder::class, fetch: 'EXTRA_LAZY')]
|
||||
#[
|
||||
ORM\OneToMany(mappedBy: 'playlist', targetEntity: StationPlaylistFolder::class, fetch: 'EXTRA_LAZY')
|
||||
]
|
||||
protected Collection $folders;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* type="array",
|
||||
* @OA\Items()
|
||||
* )
|
||||
*/
|
||||
#[ORM\OneToMany(mappedBy: 'playlist', targetEntity: StationSchedule::class, fetch: 'EXTRA_LAZY')]
|
||||
#[DeepNormalize(true)]
|
||||
#[Serializer\MaxDepth(1)]
|
||||
#[
|
||||
OA\Property(type: "array", items: new OA\Items()),
|
||||
ORM\OneToMany(mappedBy: 'playlist', targetEntity: StationSchedule::class, fetch: 'EXTRA_LAZY'),
|
||||
DeepNormalize(true),
|
||||
Serializer\MaxDepth(1)
|
||||
]
|
||||
protected Collection $schedule_items;
|
||||
|
||||
public function __construct(Station $station)
|
||||
|
|
|
@ -12,8 +12,8 @@ use Doctrine\ORM\Mapping as ORM;
|
|||
use InvalidArgumentException;
|
||||
use OpenApi\Annotations as OA;
|
||||
|
||||
/** @OA\Schema(type="object") */
|
||||
#[
|
||||
OA\Schema(type: "object"),
|
||||
ORM\Entity,
|
||||
ORM\Table(name: 'station_schedules'),
|
||||
Attributes\Auditable
|
||||
|
@ -22,20 +22,28 @@ class StationSchedule implements IdentifiableEntityInterface
|
|||
{
|
||||
use Traits\HasAutoIncrementId;
|
||||
|
||||
#[ORM\ManyToOne(inversedBy: 'schedule_items')]
|
||||
#[ORM\JoinColumn(name: 'playlist_id', referencedColumnName: 'id', nullable: true, onDelete: 'CASCADE')]
|
||||
#[
|
||||
ORM\ManyToOne(inversedBy: 'schedule_items'),
|
||||
ORM\JoinColumn(name: 'playlist_id', referencedColumnName: 'id', nullable: true, onDelete: 'CASCADE')
|
||||
]
|
||||
protected ?StationPlaylist $playlist = null;
|
||||
|
||||
#[ORM\ManyToOne(inversedBy: 'schedule_items')]
|
||||
#[ORM\JoinColumn(name: 'streamer_id', referencedColumnName: 'id', nullable: true, onDelete: 'CASCADE')]
|
||||
#[
|
||||
ORM\ManyToOne(inversedBy: 'schedule_items'),
|
||||
ORM\JoinColumn(name: 'streamer_id', referencedColumnName: 'id', nullable: true, onDelete: 'CASCADE')
|
||||
]
|
||||
protected ?StationStreamer $streamer = null;
|
||||
|
||||
/** @OA\Property(example=900) */
|
||||
#[ORM\Column(type: 'smallint')]
|
||||
#[
|
||||
OA\Property(example: 900),
|
||||
ORM\Column(type: 'smallint')
|
||||
]
|
||||
protected int $start_time = 0;
|
||||
|
||||
/** @OA\Property(example=2200) */
|
||||
#[ORM\Column(type: 'smallint')]
|
||||
#[
|
||||
OA\Property(example: 2200),
|
||||
ORM\Column(type: 'smallint')
|
||||
]
|
||||
protected int $end_time = 0;
|
||||
|
||||
#[ORM\Column(length: 10, nullable: true)]
|
||||
|
@ -44,17 +52,19 @@ class StationSchedule implements IdentifiableEntityInterface
|
|||
#[ORM\Column(length: 10, nullable: true)]
|
||||
protected ?string $end_date = null;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* description="Array of ISO-8601 days (1 for Monday, 7 for Sunday)",
|
||||
* example="0,1,2,3"
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column(length: 50, nullable: true)]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "Array of ISO-8601 days (1 for Monday, 7 for Sunday)",
|
||||
example: "0,1,2,3"
|
||||
),
|
||||
ORM\Column(length: 50, nullable: true)
|
||||
]
|
||||
protected ?string $days = null;
|
||||
|
||||
/** @OA\Property(example=false) */
|
||||
#[ORM\Column]
|
||||
#[
|
||||
OA\Property(example: false),
|
||||
ORM\Column
|
||||
]
|
||||
protected bool $loop_once = false;
|
||||
|
||||
public function __construct(StationPlaylist|StationStreamer $relation)
|
||||
|
|
|
@ -16,12 +16,11 @@ use Symfony\Component\Validator\Constraints as Assert;
|
|||
|
||||
use const PASSWORD_ARGON2ID;
|
||||
|
||||
/**
|
||||
* Station streamers (DJ accounts) allowed to broadcast to a station.
|
||||
*
|
||||
* @OA\Schema(type="object")
|
||||
*/
|
||||
#[
|
||||
OA\Schema(
|
||||
description: 'Station streamers (DJ accounts) allowed to broadcast to a station.',
|
||||
type: "object"
|
||||
),
|
||||
ORM\Entity,
|
||||
ORM\Table(name: 'station_streamers'),
|
||||
ORM\UniqueConstraint(name: 'username_unique_idx', columns: ['station_id', 'streamer_username']),
|
||||
|
@ -40,51 +39,64 @@ class StationStreamer implements
|
|||
#[ORM\Column(nullable: false)]
|
||||
protected int $station_id;
|
||||
|
||||
#[ORM\ManyToOne(inversedBy: 'streamers')]
|
||||
#[ORM\JoinColumn(name: 'station_id', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')]
|
||||
#[
|
||||
ORM\ManyToOne(inversedBy: 'streamers'),
|
||||
ORM\JoinColumn(name: 'station_id', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')
|
||||
]
|
||||
protected Station $station;
|
||||
|
||||
/** @OA\Property(example="dj_test") */
|
||||
#[ORM\Column(length: 50)]
|
||||
#[Assert\NotBlank]
|
||||
#[
|
||||
OA\Property(example: "dj_test"),
|
||||
ORM\Column(length: 50),
|
||||
Assert\NotBlank
|
||||
]
|
||||
protected string $streamer_username;
|
||||
|
||||
/** @OA\Property(example="") */
|
||||
#[ORM\Column(length: 255)]
|
||||
#[Assert\NotBlank]
|
||||
#[Attributes\AuditIgnore]
|
||||
#[
|
||||
OA\Property(example: ""),
|
||||
ORM\Column(length: 255),
|
||||
Assert\NotBlank,
|
||||
Attributes\AuditIgnore
|
||||
]
|
||||
protected string $streamer_password;
|
||||
|
||||
/** @OA\Property(example="Test DJ") */
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
#[
|
||||
OA\Property(example: "Test DJ"),
|
||||
ORM\Column(length: 255, nullable: true)
|
||||
]
|
||||
protected ?string $display_name = null;
|
||||
|
||||
/** @OA\Property(example="This is a test DJ account.") */
|
||||
#[ORM\Column(type: 'text', nullable: true)]
|
||||
#[
|
||||
OA\Property(example: "This is a test DJ account."),
|
||||
ORM\Column(type: 'text', nullable: true)
|
||||
]
|
||||
protected ?string $comments = null;
|
||||
|
||||
/** @OA\Property(example=true) */
|
||||
#[ORM\Column]
|
||||
#[
|
||||
OA\Property(example: true),
|
||||
ORM\Column
|
||||
]
|
||||
protected bool $is_active = true;
|
||||
|
||||
/** @OA\Property(example=false) */
|
||||
#[ORM\Column]
|
||||
#[
|
||||
OA\Property(example: false),
|
||||
ORM\Column
|
||||
]
|
||||
protected bool $enforce_schedule = false;
|
||||
|
||||
/** @OA\Property(example=1609480800) */
|
||||
#[ORM\Column(nullable: true)]
|
||||
#[Attributes\AuditIgnore]
|
||||
#[
|
||||
OA\Property(example: 1609480800),
|
||||
ORM\Column(nullable: true),
|
||||
Attributes\AuditIgnore
|
||||
]
|
||||
protected ?int $reactivate_at = null;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* type="array",
|
||||
* @OA\Items()
|
||||
* )
|
||||
*/
|
||||
#[ORM\OneToMany(mappedBy: 'streamer', targetEntity: StationSchedule::class)]
|
||||
#[DeepNormalize(true)]
|
||||
#[Serializer\MaxDepth(1)]
|
||||
#[
|
||||
OA\Property(type: "array", items: new OA\Items()),
|
||||
ORM\OneToMany(mappedBy: 'streamer', targetEntity: StationSchedule::class),
|
||||
DeepNormalize(true),
|
||||
Serializer\MaxDepth(1)
|
||||
]
|
||||
protected Collection $schedule_items;
|
||||
|
||||
public function __construct(Station $station)
|
||||
|
|
|
@ -10,12 +10,11 @@ use Carbon\CarbonImmutable;
|
|||
use Doctrine\ORM\Mapping as ORM;
|
||||
use OpenApi\Annotations as OA;
|
||||
|
||||
/**
|
||||
* Each individual broadcast associated with a streamer.
|
||||
*
|
||||
* @OA\Schema(type="object")
|
||||
*/
|
||||
#[
|
||||
OA\Schema(
|
||||
description: 'Each individual broadcast associated with a streamer.',
|
||||
type: "object"
|
||||
),
|
||||
ORM\Entity,
|
||||
ORM\Table(name: 'station_streamer_broadcasts')
|
||||
]
|
||||
|
@ -26,12 +25,16 @@ class StationStreamerBroadcast implements IdentifiableEntityInterface
|
|||
|
||||
public const PATH_PREFIX = 'stream';
|
||||
|
||||
#[ORM\ManyToOne(inversedBy: 'streamer_broadcasts')]
|
||||
#[ORM\JoinColumn(name: 'station_id', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')]
|
||||
#[
|
||||
ORM\ManyToOne(inversedBy: 'streamer_broadcasts'),
|
||||
ORM\JoinColumn(name: 'station_id', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')
|
||||
]
|
||||
protected Station $station;
|
||||
|
||||
#[ORM\ManyToOne(inversedBy: 'broadcasts')]
|
||||
#[ORM\JoinColumn(name: 'streamer_id', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')]
|
||||
#[
|
||||
ORM\ManyToOne(inversedBy: 'broadcasts'),
|
||||
ORM\JoinColumn(name: 'streamer_id', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')
|
||||
]
|
||||
protected StationStreamer $streamer;
|
||||
|
||||
#[ORM\Column(name: 'timestamp_start')]
|
||||
|
|
|
@ -9,10 +9,8 @@ use OpenApi\Annotations as OA;
|
|||
use Stringable;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
/**
|
||||
* @OA\Schema(type="object")
|
||||
*/
|
||||
#[
|
||||
OA\Schema(type: "object"),
|
||||
ORM\Entity,
|
||||
ORM\Table(name: 'station_webhooks', options: ['charset' => 'utf8mb4', 'collate' => 'utf8mb4_unicode_ci']),
|
||||
Attributes\Auditable
|
||||
|
@ -39,62 +37,66 @@ class StationWebhook implements
|
|||
#[ORM\Column(nullable: false)]
|
||||
protected int $station_id;
|
||||
|
||||
#[ORM\ManyToOne(inversedBy: 'webhooks')]
|
||||
#[ORM\JoinColumn(name: 'station_id', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')]
|
||||
#[
|
||||
ORM\ManyToOne(inversedBy: 'webhooks'),
|
||||
ORM\JoinColumn(name: 'station_id', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')
|
||||
]
|
||||
protected Station $station;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* description="The nickname of the webhook connector.",
|
||||
* example="Twitter Post"
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column(length: 100, nullable: true)]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "The nickname of the webhook connector.",
|
||||
example: "Twitter Post"
|
||||
),
|
||||
ORM\Column(length: 100, nullable: true)
|
||||
]
|
||||
protected ?string $name = null;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* description="The type of webhook connector to use.",
|
||||
* example="twitter"
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column(length: 100)]
|
||||
#[Assert\NotBlank]
|
||||
#[
|
||||
OA\Property(
|
||||
description: "The type of webhook connector to use.",
|
||||
example: "twitter"
|
||||
),
|
||||
ORM\Column(length: 100),
|
||||
Assert\NotBlank
|
||||
]
|
||||
protected string $type;
|
||||
|
||||
/** @OA\Property(example=true) */
|
||||
#[ORM\Column]
|
||||
#[
|
||||
OA\Property(example: true),
|
||||
ORM\Column
|
||||
]
|
||||
protected bool $is_enabled = true;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* type="array",
|
||||
* description="List of events that should trigger the webhook notification.",
|
||||
* @OA\Items()
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column(type: 'json', nullable: true)]
|
||||
#[
|
||||
OA\Property(
|
||||
type: "array",
|
||||
description: "List of events that should trigger the webhook notification.",
|
||||
items: new OA\Items()
|
||||
),
|
||||
ORM\Column(type: 'json', nullable: true)
|
||||
]
|
||||
protected ?array $triggers = null;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* type="array",
|
||||
* description="Detailed webhook configuration (if applicable)",
|
||||
* @OA\Items()
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column(type: 'json', nullable: true)]
|
||||
#[
|
||||
OA\Property(
|
||||
type: "array",
|
||||
description: "Detailed webhook configuration (if applicable)",
|
||||
items: new OA\Items()
|
||||
),
|
||||
ORM\Column(type: 'json', nullable: true)
|
||||
]
|
||||
protected ?array $config = null;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* type="array",
|
||||
* description="Internal details used by the webhook to preserve state.",
|
||||
* @OA\Items()
|
||||
* )
|
||||
*/
|
||||
#[ORM\Column(type: 'json', nullable: true)]
|
||||
#[Attributes\AuditIgnore]
|
||||
#[
|
||||
OA\Property(
|
||||
type: "array",
|
||||
description: "Internal details used by the webhook to preserve state.",
|
||||
items: new OA\Items()
|
||||
),
|
||||
ORM\Column(type: 'json', nullable: true),
|
||||
Attributes\AuditIgnore
|
||||
]
|
||||
protected ?array $metadata = null;
|
||||
|
||||
public function __construct(Station $station, string $type)
|
||||
|
|
|
@ -22,8 +22,8 @@ use Symfony\Component\Validator\Constraints as Assert;
|
|||
|
||||
use const PASSWORD_BCRYPT;
|
||||
|
||||
/** @OA\Schema(type="object") */
|
||||
#[
|
||||
OA\Schema(type: "object"),
|
||||
ORM\Entity,
|
||||
ORM\Table(name: 'users'),
|
||||
ORM\HasLifecycleCallbacks,
|
||||
|
@ -36,73 +36,90 @@ class User implements Stringable, IdentifiableEntityInterface
|
|||
use Traits\HasAutoIncrementId;
|
||||
use Traits\TruncateStrings;
|
||||
|
||||
/** @OA\Property(example="demo@azuracast.com") */
|
||||
#[ORM\Column(length: 100, nullable: false)]
|
||||
#[Assert\NotBlank]
|
||||
#[Assert\Email]
|
||||
#[Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])]
|
||||
#[
|
||||
OA\Property(example: "demo@azuracast.com"),
|
||||
ORM\Column(length: 100, nullable: false),
|
||||
Assert\NotBlank,
|
||||
Assert\Email,
|
||||
Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])
|
||||
]
|
||||
protected string $email;
|
||||
|
||||
#[ORM\Column(length: 255, nullable: false)]
|
||||
#[Attributes\AuditIgnore]
|
||||
#[
|
||||
ORM\Column(length: 255, nullable: false),
|
||||
Attributes\AuditIgnore
|
||||
]
|
||||
protected string $auth_password = '';
|
||||
|
||||
/** @OA\Property(example="") */
|
||||
#[Groups([EntityGroupsInterface::GROUP_ADMIN, EntityGroupsInterface::GROUP_ALL])]
|
||||
#[
|
||||
OA\Property(example: ""),
|
||||
Groups([EntityGroupsInterface::GROUP_ADMIN, EntityGroupsInterface::GROUP_ALL])
|
||||
]
|
||||
protected ?string $new_password = null;
|
||||
|
||||
/** @OA\Property(example="Demo Account") */
|
||||
#[ORM\Column(length: 100, nullable: true)]
|
||||
#[Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])]
|
||||
#[
|
||||
OA\Property(example: "Demo Account"),
|
||||
ORM\Column(length: 100, nullable: true),
|
||||
Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])
|
||||
]
|
||||
protected ?string $name = null;
|
||||
|
||||
/** @OA\Property(example="en_US") */
|
||||
#[ORM\Column(length: 25, nullable: true)]
|
||||
#[Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])]
|
||||
#[
|
||||
OA\Property(example: "en_US"),
|
||||
ORM\Column(length: 25, nullable: true),
|
||||
Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])
|
||||
]
|
||||
protected ?string $locale = null;
|
||||
|
||||
/** @OA\Property(example="dark") */
|
||||
#[ORM\Column(length: 25, nullable: true)]
|
||||
#[Attributes\AuditIgnore]
|
||||
#[Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])]
|
||||
#[
|
||||
OA\Property(example: "dark"),
|
||||
ORM\Column(length: 25, nullable: true),
|
||||
Attributes\AuditIgnore,
|
||||
Groups([EntityGroupsInterface::GROUP_GENERAL, EntityGroupsInterface::GROUP_ALL])
|
||||
]
|
||||
protected ?string $theme = null;
|
||||
|
||||
/** @OA\Property(example="A1B2C3D4") */
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
#[Attributes\AuditIgnore]
|
||||
#[Groups([EntityGroupsInterface::GROUP_ADMIN, EntityGroupsInterface::GROUP_ALL])]
|
||||
#[
|
||||
OA\Property(example: "A1B2C3D4"),
|
||||
ORM\Column(length: 255, nullable: true),
|
||||
Attributes\AuditIgnore,
|
||||
Groups([EntityGroupsInterface::GROUP_ADMIN, EntityGroupsInterface::GROUP_ALL])
|
||||
]
|
||||
protected ?string $two_factor_secret = null;
|
||||
|
||||
/** @OA\Property(example=1609480800) */
|
||||
#[ORM\Column]
|
||||
#[Attributes\AuditIgnore]
|
||||
#[Groups([EntityGroupsInterface::GROUP_ADMIN, EntityGroupsInterface::GROUP_ALL])]
|
||||
#[
|
||||
OA\Property(example: 1609480800),
|
||||
ORM\Column,
|
||||
Attributes\AuditIgnore,
|
||||
Groups([EntityGroupsInterface::GROUP_ADMIN, EntityGroupsInterface::GROUP_ALL])
|
||||
]
|
||||
protected int $created_at;
|
||||
|
||||
/** @OA\Property(example=1609480800) */
|
||||
#[ORM\Column]
|
||||
#[Attributes\AuditIgnore]
|
||||
#[Groups([EntityGroupsInterface::GROUP_ADMIN, EntityGroupsInterface::GROUP_ALL])]
|
||||
#[
|
||||
OA\Property(example: 1609480800),
|
||||
ORM\Column,
|
||||
Attributes\AuditIgnore,
|
||||
Groups([EntityGroupsInterface::GROUP_ADMIN, EntityGroupsInterface::GROUP_ALL])
|
||||
]
|
||||
protected int $updated_at;
|
||||
|
||||
/**
|
||||
* @OA\Property(
|
||||
* type="array",
|
||||
* @OA\Items()
|
||||
* )
|
||||
*/
|
||||
#[ORM\ManyToMany(targetEntity: Role::class, inversedBy: 'users', fetch: 'EAGER')]
|
||||
#[ORM\JoinTable(name: 'user_has_role')]
|
||||
#[ORM\JoinColumn(name: 'user_id', referencedColumnName: 'id', onDelete: 'CASCADE')]
|
||||
#[ORM\InverseJoinColumn(name: 'role_id', referencedColumnName: 'id', onDelete: 'CASCADE')]
|
||||
#[Groups([EntityGroupsInterface::GROUP_ADMIN, EntityGroupsInterface::GROUP_ALL])]
|
||||
#[DeepNormalize(true)]
|
||||
#[Serializer\MaxDepth(1)]
|
||||
#[
|
||||
OA\Property(type: "array", items: new OA\Items()),
|
||||
ORM\ManyToMany(targetEntity: Role::class, inversedBy: 'users', fetch: 'EAGER'),
|
||||
ORM\JoinTable(name: 'user_has_role'),
|
||||
ORM\JoinColumn(name: 'user_id', referencedColumnName: 'id', onDelete: 'CASCADE'),
|
||||
ORM\InverseJoinColumn(name: 'role_id', referencedColumnName: 'id', onDelete: 'CASCADE'),
|
||||
Groups([EntityGroupsInterface::GROUP_ADMIN, EntityGroupsInterface::GROUP_ALL]),
|
||||
DeepNormalize(true),
|
||||
Serializer\MaxDepth(1)
|
||||
]
|
||||
protected Collection $roles;
|
||||
|
||||
#[ORM\OneToMany(mappedBy: 'user', targetEntity: ApiKey::class)]
|
||||
#[Groups([EntityGroupsInterface::GROUP_ADMIN, EntityGroupsInterface::GROUP_ALL])]
|
||||
#[DeepNormalize(true)]
|
||||
#[
|
||||
ORM\OneToMany(mappedBy: 'user', targetEntity: ApiKey::class),
|
||||
Groups([EntityGroupsInterface::GROUP_ADMIN, EntityGroupsInterface::GROUP_ALL]),
|
||||
DeepNormalize(true)
|
||||
]
|
||||
protected Collection $api_keys;
|
||||
|
||||
public function __construct()
|
||||
|
|
Loading…
Reference in New Issue
Block a user