Configure all mutual toOne relationships explicitly.
This commit is contained in:
parent
24c56345df
commit
2f14540477
|
@ -15,7 +15,7 @@ use RuntimeException;
|
|||
#[
|
||||
ORM\Entity(readOnly: true),
|
||||
ORM\Table(name: 'analytics'),
|
||||
ORM\Index(columns: ['type', 'moment'], name: 'search_idx'),
|
||||
ORM\Index(name: 'search_idx', columns: ['type', 'moment']),
|
||||
ORM\UniqueConstraint(name: 'stats_unique_idx', columns: ['station_id', 'type', 'moment'])
|
||||
]
|
||||
class Analytics implements IdentifiableEntityInterface
|
||||
|
|
|
@ -11,7 +11,7 @@ use Doctrine\ORM\Mapping as ORM;
|
|||
#[
|
||||
ORM\Entity(readOnly: true),
|
||||
ORM\Table(name: 'audit_log'),
|
||||
ORM\Index(columns: ['class', 'user', 'identifier'], name: 'idx_search')
|
||||
ORM\Index(name: 'idx_search', columns: ['class', 'user', 'identifier'])
|
||||
]
|
||||
class AuditLog implements IdentifiableEntityInterface
|
||||
{
|
||||
|
|
|
@ -6,6 +6,8 @@ namespace App\Entity;
|
|||
|
||||
use App\Entity\Interfaces\IdentifiableEntityInterface;
|
||||
use App\Utilities\File;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use OpenApi\Attributes as OA;
|
||||
use Stringable;
|
||||
|
@ -45,6 +47,15 @@ class CustomField implements Stringable, IdentifiableEntityInterface
|
|||
]
|
||||
protected ?string $auto_assign = null;
|
||||
|
||||
/** @var Collection<int, StationMediaCustomField> */
|
||||
#[ORM\OneToMany(targetEntity: StationMediaCustomField::class, mappedBy: 'field')]
|
||||
protected Collection $media_fields;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->media_fields = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
|
|
|
@ -10,10 +10,10 @@ use NowPlaying\Result\Client;
|
|||
#[
|
||||
ORM\Entity,
|
||||
ORM\Table(name: 'listener'),
|
||||
ORM\Index(columns: ['timestamp_end', 'timestamp_start'], name: 'idx_timestamps'),
|
||||
ORM\Index(columns: ['location_country'], name: 'idx_statistics_country'),
|
||||
ORM\Index(columns: ['device_os_family'], name: 'idx_statistics_os'),
|
||||
ORM\Index(columns: ['device_browser_family'], name: 'idx_statistics_browser')
|
||||
ORM\Index(name: 'idx_timestamps', columns: ['timestamp_end', 'timestamp_start']),
|
||||
ORM\Index(name: 'idx_statistics_country', columns: ['location_country']),
|
||||
ORM\Index(name: 'idx_statistics_os', columns: ['device_os_family']),
|
||||
ORM\Index(name: 'idx_statistics_browser', columns: ['device_browser_family'])
|
||||
]
|
||||
class Listener implements
|
||||
Interfaces\IdentifiableEntityInterface,
|
||||
|
|
|
@ -71,11 +71,11 @@ class Podcast implements Interfaces\IdentifiableEntityInterface
|
|||
protected bool $playlist_auto_publish = true;
|
||||
|
||||
/** @var Collection<int, PodcastCategory> */
|
||||
#[ORM\OneToMany(mappedBy: 'podcast', targetEntity: PodcastCategory::class)]
|
||||
#[ORM\OneToMany(targetEntity: PodcastCategory::class, mappedBy: 'podcast')]
|
||||
protected Collection $categories;
|
||||
|
||||
/** @var Collection<int, PodcastEpisode> */
|
||||
#[ORM\OneToMany(mappedBy: 'podcast', targetEntity: PodcastEpisode::class, fetch: 'EXTRA_LAZY')]
|
||||
#[ORM\OneToMany(targetEntity: PodcastEpisode::class, mappedBy: 'podcast', fetch: 'EXTRA_LAZY')]
|
||||
protected Collection $episodes;
|
||||
|
||||
public function __construct(StorageLocation $storageLocation)
|
||||
|
|
|
@ -25,7 +25,7 @@ class PodcastEpisode implements IdentifiableEntityInterface
|
|||
#[ORM\JoinColumn(name: 'podcast_id', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')]
|
||||
protected Podcast $podcast;
|
||||
|
||||
#[ORM\OneToOne(inversedBy: 'podcast_episode')]
|
||||
#[ORM\ManyToOne(inversedBy: 'podcast_episodes')]
|
||||
#[ORM\JoinColumn(name: 'playlist_media_id', referencedColumnName: 'id', nullable: true, onDelete: 'CASCADE')]
|
||||
protected ?StationMedia $playlist_media = null;
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ class Relay implements IdentifiableEntityInterface
|
|||
protected int $updated_at;
|
||||
|
||||
/** @var Collection<int, StationRemote> */
|
||||
#[ORM\OneToMany(mappedBy: 'relay', targetEntity: StationRemote::class)]
|
||||
#[ORM\OneToMany(targetEntity: StationRemote::class, mappedBy: 'relay')]
|
||||
protected Collection $remotes;
|
||||
|
||||
public function __construct(string $baseUrl)
|
||||
|
|
|
@ -38,7 +38,7 @@ class Role implements JsonSerializable, Stringable, IdentifiableEntityInterface
|
|||
/** @var Collection<int, RolePermission> */
|
||||
#[
|
||||
OA\Property(type: "array", items: new OA\Items()),
|
||||
ORM\OneToMany(mappedBy: 'role', targetEntity: RolePermission::class)
|
||||
ORM\OneToMany(targetEntity: RolePermission::class, mappedBy: 'role')
|
||||
]
|
||||
protected Collection $permissions;
|
||||
|
||||
|
|
|
@ -10,9 +10,9 @@ use Doctrine\ORM\Mapping as ORM;
|
|||
#[
|
||||
ORM\Entity,
|
||||
ORM\Table(name: 'song_history'),
|
||||
ORM\Index(columns: ['is_visible'], name: 'idx_is_visible'),
|
||||
ORM\Index(columns: ['timestamp_start'], name: 'idx_timestamp_start'),
|
||||
ORM\Index(columns: ['timestamp_end'], name: 'idx_timestamp_end')
|
||||
ORM\Index(name: 'idx_is_visible', columns: ['is_visible']),
|
||||
ORM\Index(name: 'idx_timestamp_start', columns: ['timestamp_start']),
|
||||
ORM\Index(name: 'idx_timestamp_end', columns: ['timestamp_end'])
|
||||
]
|
||||
class SongHistory implements
|
||||
Interfaces\SongInterface,
|
||||
|
|
|
@ -33,7 +33,7 @@ use Symfony\Component\Validator\Constraints as Assert;
|
|||
OA\Schema(schema: "Station", type: "object"),
|
||||
ORM\Entity,
|
||||
ORM\Table(name: 'station'),
|
||||
ORM\Index(columns: ['short_name'], name: 'idx_short_name'),
|
||||
ORM\Index(name: 'idx_short_name', columns: ['short_name']),
|
||||
ORM\HasLifecycleCallbacks,
|
||||
Attributes\Auditable,
|
||||
AppAssert\StationPortChecker,
|
||||
|
@ -285,7 +285,7 @@ class Station implements Stringable, IdentifiableEntityInterface
|
|||
|
||||
/** @var Collection<int, SongHistory> */
|
||||
#[
|
||||
ORM\OneToMany(mappedBy: 'station', targetEntity: SongHistory::class),
|
||||
ORM\OneToMany(targetEntity: SongHistory::class, mappedBy: 'station'),
|
||||
ORM\OrderBy(['timestamp_start' => 'desc'])
|
||||
]
|
||||
protected Collection $history;
|
||||
|
@ -333,7 +333,7 @@ class Station implements Stringable, IdentifiableEntityInterface
|
|||
protected ?StorageLocation $podcasts_storage_location = null;
|
||||
|
||||
/** @var Collection<int, StationStreamer> */
|
||||
#[ORM\OneToMany(mappedBy: 'station', targetEntity: StationStreamer::class)]
|
||||
#[ORM\OneToMany(targetEntity: StationStreamer::class, mappedBy: 'station')]
|
||||
protected Collection $streamers;
|
||||
|
||||
#[
|
||||
|
@ -353,41 +353,49 @@ class Station implements Stringable, IdentifiableEntityInterface
|
|||
protected ?string $fallback_path = null;
|
||||
|
||||
/** @var Collection<int, RolePermission> */
|
||||
#[ORM\OneToMany(mappedBy: 'station', targetEntity: RolePermission::class)]
|
||||
#[ORM\OneToMany(targetEntity: RolePermission::class, mappedBy: 'station')]
|
||||
protected Collection $permissions;
|
||||
|
||||
/** @var Collection<int, StationPlaylist> */
|
||||
#[
|
||||
ORM\OneToMany(mappedBy: 'station', targetEntity: StationPlaylist::class),
|
||||
ORM\OneToMany(targetEntity: StationPlaylist::class, mappedBy: 'station'),
|
||||
ORM\OrderBy(['type' => 'ASC', 'weight' => 'DESC'])
|
||||
]
|
||||
protected Collection $playlists;
|
||||
|
||||
/** @var Collection<int, StationMount> */
|
||||
#[ORM\OneToMany(mappedBy: 'station', targetEntity: StationMount::class)]
|
||||
#[ORM\OneToMany(targetEntity: StationMount::class, mappedBy: 'station')]
|
||||
protected Collection $mounts;
|
||||
|
||||
/** @var Collection<int, StationRemote> */
|
||||
#[ORM\OneToMany(mappedBy: 'station', targetEntity: StationRemote::class)]
|
||||
#[ORM\OneToMany(targetEntity: StationRemote::class, mappedBy: 'station')]
|
||||
protected Collection $remotes;
|
||||
|
||||
/** @var Collection<int, StationHlsStream> */
|
||||
#[ORM\OneToMany(mappedBy: 'station', targetEntity: StationHlsStream::class)]
|
||||
#[ORM\OneToMany(targetEntity: StationHlsStream::class, mappedBy: 'station')]
|
||||
protected Collection $hls_streams;
|
||||
|
||||
/** @var Collection<int, StationWebhook> */
|
||||
#[ORM\OneToMany(
|
||||
mappedBy: 'station',
|
||||
targetEntity: StationWebhook::class,
|
||||
mappedBy: 'station',
|
||||
cascade: ['persist'],
|
||||
fetch: 'EXTRA_LAZY'
|
||||
)]
|
||||
protected Collection $webhooks;
|
||||
|
||||
/** @var Collection<int, StationStreamerBroadcast> */
|
||||
#[ORM\OneToMany(targetEntity: StationStreamerBroadcast::class, mappedBy: 'station')]
|
||||
protected Collection $streamer_broadcasts;
|
||||
|
||||
/** @var Collection<int, SftpUser> */
|
||||
#[ORM\OneToMany(mappedBy: 'station', targetEntity: SftpUser::class)]
|
||||
#[ORM\OneToMany(targetEntity: SftpUser::class, mappedBy: 'station')]
|
||||
protected Collection $sftp_users;
|
||||
|
||||
/** @var Collection<int, StationRequest> */
|
||||
#[ORM\OneToMany(targetEntity: StationRequest::class, mappedBy: 'station')]
|
||||
protected Collection $requests;
|
||||
|
||||
#[
|
||||
ORM\ManyToOne,
|
||||
ORM\JoinColumn(name: 'current_song_id', referencedColumnName: 'id', nullable: true, onDelete: 'SET NULL'),
|
||||
|
@ -408,7 +416,9 @@ class Station implements Stringable, IdentifiableEntityInterface
|
|||
$this->hls_streams = new ArrayCollection();
|
||||
$this->webhooks = new ArrayCollection();
|
||||
$this->streamers = new ArrayCollection();
|
||||
$this->streamer_broadcasts = new ArrayCollection();
|
||||
$this->sftp_users = new ArrayCollection();
|
||||
$this->requests = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function getName(): ?string
|
||||
|
|
|
@ -23,7 +23,7 @@ use Symfony\Component\Serializer\Annotation as Serializer;
|
|||
OA\Schema(type: "object"),
|
||||
ORM\Entity,
|
||||
ORM\Table(name: 'station_media'),
|
||||
ORM\Index(columns: ['title', 'artist', 'album'], name: 'search_idx'),
|
||||
ORM\Index(name: 'search_idx', columns: ['title', 'artist', 'album']),
|
||||
ORM\UniqueConstraint(name: 'path_unique_idx', columns: ['path', 'storage_location_id'])
|
||||
]
|
||||
class StationMedia implements
|
||||
|
@ -193,22 +193,27 @@ class StationMedia implements
|
|||
/** @var Collection<int, StationPlaylistMedia> */
|
||||
#[
|
||||
OA\Property(type: "array", items: new OA\Items()),
|
||||
ORM\OneToMany(mappedBy: 'media', targetEntity: StationPlaylistMedia::class),
|
||||
ORM\OneToMany(targetEntity: StationPlaylistMedia::class, mappedBy: 'media'),
|
||||
DeepNormalize(true),
|
||||
Serializer\MaxDepth(1)
|
||||
]
|
||||
protected Collection $playlists;
|
||||
|
||||
/** @var Collection<int, StationMediaCustomField> */
|
||||
#[ORM\OneToMany(mappedBy: 'media', targetEntity: StationMediaCustomField::class)]
|
||||
#[ORM\OneToMany(targetEntity: StationMediaCustomField::class, mappedBy: 'media')]
|
||||
protected Collection $custom_fields;
|
||||
|
||||
/** @var Collection<int, PodcastEpisode> */
|
||||
#[ORM\OneToMany(targetEntity: PodcastEpisode::class, mappedBy: 'playlist_media')]
|
||||
protected Collection $podcast_episodes;
|
||||
|
||||
public function __construct(StorageLocation $storageLocation, string $path)
|
||||
{
|
||||
$this->storage_location = $storageLocation;
|
||||
|
||||
$this->playlists = new ArrayCollection();
|
||||
$this->custom_fields = new ArrayCollection();
|
||||
$this->podcast_episodes = new ArrayCollection();
|
||||
|
||||
$this->setPath($path);
|
||||
$this->generateUniqueId();
|
||||
|
@ -445,6 +450,14 @@ class StationMedia implements
|
|||
$this->custom_fields = $customFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection<int, PodcastEpisode>
|
||||
*/
|
||||
public function getPodcastEpisodes(): Collection
|
||||
{
|
||||
return $this->podcast_episodes;
|
||||
}
|
||||
|
||||
public static function needsReprocessing(int $fileModifiedTime = 0, int $dbModifiedTime = 0): bool
|
||||
{
|
||||
return $fileModifiedTime > $dbModifiedTime;
|
||||
|
|
|
@ -16,7 +16,7 @@ class StationMediaCustomField implements IdentifiableEntityInterface
|
|||
use Traits\HasAutoIncrementId;
|
||||
use Traits\TruncateStrings;
|
||||
|
||||
#[ORM\ManyToOne(inversedBy: 'metadata')]
|
||||
#[ORM\ManyToOne(inversedBy: 'custom_fields')]
|
||||
#[ORM\JoinColumn(name: 'media_id', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')]
|
||||
protected StationMedia $media;
|
||||
|
||||
|
|
|
@ -175,26 +175,35 @@ class StationPlaylist implements
|
|||
|
||||
/** @var Collection<int, StationPlaylistMedia> */
|
||||
#[
|
||||
ORM\OneToMany(mappedBy: 'playlist', targetEntity: StationPlaylistMedia::class, fetch: 'EXTRA_LAZY'),
|
||||
ORM\OneToMany(targetEntity: StationPlaylistMedia::class, mappedBy: 'playlist', fetch: 'EXTRA_LAZY'),
|
||||
ORM\OrderBy(['weight' => 'ASC'])
|
||||
]
|
||||
protected Collection $media_items;
|
||||
|
||||
/** @var Collection<int, StationPlaylistFolder> */
|
||||
#[
|
||||
ORM\OneToMany(mappedBy: 'playlist', targetEntity: StationPlaylistFolder::class, fetch: 'EXTRA_LAZY')
|
||||
ORM\OneToMany(targetEntity: StationPlaylistFolder::class, mappedBy: 'playlist', fetch: 'EXTRA_LAZY')
|
||||
]
|
||||
protected Collection $folders;
|
||||
|
||||
/** @var Collection<int, StationSchedule> */
|
||||
#[
|
||||
OA\Property(type: "array", items: new OA\Items()),
|
||||
ORM\OneToMany(mappedBy: 'playlist', targetEntity: StationSchedule::class, fetch: 'EXTRA_LAZY'),
|
||||
ORM\OneToMany(targetEntity: StationSchedule::class, mappedBy: 'playlist', fetch: 'EXTRA_LAZY'),
|
||||
DeepNormalize(true),
|
||||
Serializer\MaxDepth(1)
|
||||
]
|
||||
protected Collection $schedule_items;
|
||||
|
||||
/** @var Collection<int, Podcast> */
|
||||
#[
|
||||
OA\Property(type: "array", items: new OA\Items()),
|
||||
ORM\OneToMany(targetEntity: Podcast::class, mappedBy: 'playlist', fetch: 'EXTRA_LAZY'),
|
||||
DeepNormalize(true),
|
||||
Serializer\MaxDepth(1)
|
||||
]
|
||||
protected Collection $podcasts;
|
||||
|
||||
public function __construct(Station $station)
|
||||
{
|
||||
$this->station = $station;
|
||||
|
@ -207,6 +216,7 @@ class StationPlaylist implements
|
|||
$this->media_items = new ArrayCollection();
|
||||
$this->folders = new ArrayCollection();
|
||||
$this->schedule_items = new ArrayCollection();
|
||||
$this->podcasts = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function getStation(): Station
|
||||
|
@ -414,6 +424,14 @@ class StationPlaylist implements
|
|||
return $this->schedule_items;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection<int, Podcast>
|
||||
*/
|
||||
public function getPodcasts(): Collection
|
||||
{
|
||||
return $this->podcasts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether a playlist is enabled and has content which can be scheduled by an AutoDJ scheduler.
|
||||
*
|
||||
|
|
|
@ -9,10 +9,10 @@ use Doctrine\ORM\Mapping as ORM;
|
|||
#[
|
||||
ORM\Entity,
|
||||
ORM\Table(name: 'station_queue'),
|
||||
ORM\Index(columns: ['is_played'], name: 'idx_is_played'),
|
||||
ORM\Index(columns: ['timestamp_played'], name: 'idx_timestamp_played'),
|
||||
ORM\Index(columns: ['sent_to_autodj'], name: 'idx_sent_to_autodj'),
|
||||
ORM\Index(columns: ['timestamp_cued'], name: 'idx_timestamp_cued')
|
||||
ORM\Index(name: 'idx_is_played', columns: ['is_played']),
|
||||
ORM\Index(name: 'idx_timestamp_played', columns: ['timestamp_played']),
|
||||
ORM\Index(name: 'idx_sent_to_autodj', columns: ['sent_to_autodj']),
|
||||
ORM\Index(name: 'idx_timestamp_cued', columns: ['timestamp_cued'])
|
||||
]
|
||||
class StationQueue implements
|
||||
Interfaces\SongInterface,
|
||||
|
|
|
@ -19,7 +19,7 @@ class StationRequest implements
|
|||
{
|
||||
use Traits\HasAutoIncrementId;
|
||||
|
||||
#[ORM\ManyToOne(inversedBy: 'media')]
|
||||
#[ORM\ManyToOne(inversedBy: 'requests')]
|
||||
#[ORM\JoinColumn(name: 'station_id', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')]
|
||||
protected Station $station;
|
||||
|
||||
|
|
|
@ -101,16 +101,25 @@ class StationStreamer implements
|
|||
/** @var Collection<int, StationSchedule> */
|
||||
#[
|
||||
OA\Property(type: "array", items: new OA\Items()),
|
||||
ORM\OneToMany(mappedBy: 'streamer', targetEntity: StationSchedule::class),
|
||||
ORM\OneToMany(targetEntity: StationSchedule::class, mappedBy: 'streamer'),
|
||||
DeepNormalize(true),
|
||||
Serializer\MaxDepth(1)
|
||||
]
|
||||
protected Collection $schedule_items;
|
||||
|
||||
/** @var Collection<int, StationStreamerBroadcast> */
|
||||
#[
|
||||
ORM\OneToMany(targetEntity: StationStreamerBroadcast::class, mappedBy: 'streamer'),
|
||||
DeepNormalize(true)
|
||||
]
|
||||
protected Collection $broadcasts;
|
||||
|
||||
public function __construct(Station $station)
|
||||
{
|
||||
$this->station = $station;
|
||||
|
||||
$this->schedule_items = new ArrayCollection();
|
||||
$this->broadcasts = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function getStation(): Station
|
||||
|
|
|
@ -98,9 +98,13 @@ class StorageLocation implements Stringable, IdentifiableEntityInterface
|
|||
protected string|int|null $storageUsed = null;
|
||||
|
||||
/** @var Collection<int, StationMedia> */
|
||||
#[ORM\OneToMany(mappedBy: 'storage_location', targetEntity: StationMedia::class)]
|
||||
#[ORM\OneToMany(targetEntity: StationMedia::class, mappedBy: 'storage_location')]
|
||||
protected Collection $media;
|
||||
|
||||
/** @var Collection<int, UnprocessableMedia> */
|
||||
#[ORM\OneToMany(targetEntity: UnprocessableMedia::class, mappedBy: 'storage_location')]
|
||||
protected Collection $unprocessable_media;
|
||||
|
||||
public function __construct(
|
||||
StorageLocationTypes $type,
|
||||
StorageLocationAdapters $adapter
|
||||
|
@ -109,6 +113,7 @@ class StorageLocation implements Stringable, IdentifiableEntityInterface
|
|||
$this->adapter = $adapter;
|
||||
|
||||
$this->media = new ArrayCollection();
|
||||
$this->unprocessable_media = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function getType(): StorageLocationTypes
|
||||
|
|
|
@ -20,7 +20,7 @@ class UnprocessableMedia implements ProcessableMediaInterface, PathAwareInterfac
|
|||
|
||||
public const REPROCESS_THRESHOLD_MINIMUM = 604800; // One week
|
||||
|
||||
#[ORM\ManyToOne(inversedBy: 'media')]
|
||||
#[ORM\ManyToOne(inversedBy: 'unprocessable_media')]
|
||||
#[ORM\JoinColumn(name: 'storage_location_id', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')]
|
||||
protected StorageLocation $storage_location;
|
||||
|
||||
|
|
|
@ -119,7 +119,7 @@ class User implements Stringable, IdentifiableEntityInterface
|
|||
|
||||
/** @var Collection<int, ApiKey> */
|
||||
#[
|
||||
ORM\OneToMany(mappedBy: 'user', targetEntity: ApiKey::class),
|
||||
ORM\OneToMany(targetEntity: ApiKey::class, mappedBy: 'user'),
|
||||
Groups([EntityGroupsInterface::GROUP_ADMIN, EntityGroupsInterface::GROUP_ALL]),
|
||||
DeepNormalize(true)
|
||||
]
|
||||
|
@ -127,12 +127,20 @@ class User implements Stringable, IdentifiableEntityInterface
|
|||
|
||||
/** @var Collection<int, UserPasskey> */
|
||||
#[
|
||||
ORM\OneToMany(mappedBy: 'user', targetEntity: UserPasskey::class),
|
||||
ORM\OneToMany(targetEntity: UserPasskey::class, mappedBy: 'user'),
|
||||
Groups([EntityGroupsInterface::GROUP_ADMIN, EntityGroupsInterface::GROUP_ALL]),
|
||||
DeepNormalize(true)
|
||||
]
|
||||
protected Collection $passkeys;
|
||||
|
||||
/** @var Collection<int, UserLoginToken> */
|
||||
#[
|
||||
ORM\OneToMany(targetEntity: UserLoginToken::class, mappedBy: 'user'),
|
||||
Groups([EntityGroupsInterface::GROUP_ADMIN, EntityGroupsInterface::GROUP_ALL]),
|
||||
DeepNormalize(true)
|
||||
]
|
||||
protected Collection $login_tokens;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->created_at = time();
|
||||
|
@ -140,6 +148,7 @@ class User implements Stringable, IdentifiableEntityInterface
|
|||
|
||||
$this->roles = new ArrayCollection();
|
||||
$this->api_keys = new ArrayCollection();
|
||||
$this->login_tokens = new ArrayCollection();
|
||||
}
|
||||
|
||||
#[ORM\PreUpdate]
|
||||
|
|
|
@ -15,7 +15,7 @@ class UserLoginToken
|
|||
{
|
||||
use Traits\HasSplitTokenFields;
|
||||
|
||||
#[ORM\ManyToOne(fetch: 'EAGER', inversedBy: 'api_keys')]
|
||||
#[ORM\ManyToOne(fetch: 'EAGER', inversedBy: 'login_tokens')]
|
||||
#[ORM\JoinColumn(name: 'user_id', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')]
|
||||
protected User $user;
|
||||
|
||||
|
|
Loading…
Reference in New Issue