253 lines
9.1 KiB
PHP
253 lines
9.1 KiB
PHP
<?php
|
|
|
|
namespace App\Form;
|
|
|
|
use App\Config;
|
|
use App\Entity;
|
|
use App\Environment;
|
|
use App\Http\ServerRequest;
|
|
use App\Radio\Adapters;
|
|
use App\Radio\Configuration;
|
|
use App\Sync\Task\CheckMediaTask;
|
|
use DeepCopy;
|
|
use Doctrine\Common\Collections\Collection;
|
|
use Doctrine\ORM\EntityManagerInterface;
|
|
use InvalidArgumentException;
|
|
use Symfony\Component\Serializer\Serializer;
|
|
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
|
|
|
class StationCloneForm extends StationForm
|
|
{
|
|
public function __construct(
|
|
protected Configuration $configuration,
|
|
protected CheckMediaTask $media_sync,
|
|
Entity\Repository\StationRepository $stationRepo,
|
|
Entity\Repository\StorageLocationRepository $storageLocationRepo,
|
|
Entity\Repository\SettingsRepository $settingsRepo,
|
|
Environment $environment,
|
|
Adapters $adapters,
|
|
EntityManagerInterface $em,
|
|
Serializer $serializer,
|
|
ValidatorInterface $validator,
|
|
Config $config
|
|
) {
|
|
parent::__construct(
|
|
$stationRepo,
|
|
$storageLocationRepo,
|
|
$settingsRepo,
|
|
$environment,
|
|
$adapters,
|
|
$em,
|
|
$serializer,
|
|
$validator,
|
|
$config
|
|
);
|
|
|
|
$form_config = $config->get('forms/station_clone');
|
|
$this->configure($form_config);
|
|
}
|
|
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
public function process(ServerRequest $request, $record = null): object|bool
|
|
{
|
|
if (!$record instanceof Entity\Station) {
|
|
throw new InvalidArgumentException('Record must be a station.');
|
|
}
|
|
|
|
$this->populate(
|
|
[
|
|
'name' => $record->getName() . ' - Copy',
|
|
'description' => $record->getDescription(),
|
|
]
|
|
);
|
|
|
|
if ('POST' === $request->getMethod() && $this->isValid($request->getParsedBody())) {
|
|
$data = $this->getValues();
|
|
|
|
$copier = new DeepCopy\DeepCopy();
|
|
$copier->addFilter(
|
|
new DeepCopy\Filter\Doctrine\DoctrineProxyFilter(),
|
|
new DeepCopy\Matcher\Doctrine\DoctrineProxyMatcher()
|
|
);
|
|
$copier->addFilter(
|
|
new DeepCopy\Filter\KeepFilter(),
|
|
new DeepCopy\Matcher\PropertyMatcher(Entity\StationMedia::class, 'song')
|
|
);
|
|
$copier->addFilter(
|
|
new DeepCopy\Filter\KeepFilter(),
|
|
new DeepCopy\Matcher\PropertyMatcher(Entity\RolePermission::class, 'role')
|
|
);
|
|
$copier->addFilter(
|
|
new DeepCopy\Filter\KeepFilter(),
|
|
new DeepCopy\Matcher\PropertyMatcher(Entity\StationMediaCustomField::class, 'field')
|
|
);
|
|
$copier->addFilter(
|
|
new DeepCopy\Filter\Doctrine\DoctrineEmptyCollectionFilter(),
|
|
new DeepCopy\Matcher\PropertyMatcher(Entity\Station::class, 'history')
|
|
);
|
|
$copier->addFilter(
|
|
new DeepCopy\Filter\Doctrine\DoctrineEmptyCollectionFilter(),
|
|
new DeepCopy\Matcher\PropertyMatcher(Entity\Station::class, 'sftp_users')
|
|
);
|
|
$copier->addFilter(
|
|
new DeepCopy\Filter\Doctrine\DoctrineEmptyCollectionFilter(),
|
|
new DeepCopy\Matcher\PropertyMatcher(Entity\StationPlaylist::class, 'media_items')
|
|
);
|
|
|
|
// Unset some properties across all copied record types.
|
|
$global_unsets = [
|
|
'id',
|
|
'station_id',
|
|
'media_id',
|
|
'playlist_id',
|
|
'field_id',
|
|
];
|
|
foreach ($global_unsets as $prop) {
|
|
$copier->addFilter(
|
|
new DeepCopy\Filter\SetNullFilter(),
|
|
new DeepCopy\Matcher\PropertyNameMatcher($prop)
|
|
);
|
|
}
|
|
|
|
// Unset some values only on Station entities.
|
|
$unset_values = [
|
|
'short_name',
|
|
'radio_base_dir',
|
|
'media_storage_location',
|
|
'recordings_storage_location',
|
|
'adapter_api_key',
|
|
'nowplaying',
|
|
'nowplaying_timestamp',
|
|
'current_streamer_id',
|
|
'current_streamer',
|
|
];
|
|
|
|
foreach ($unset_values as $prop) {
|
|
$copier->addFilter(
|
|
new DeepCopy\Filter\SetNullFilter(),
|
|
new DeepCopy\Matcher\PropertyMatcher(Entity\Station::class, $prop)
|
|
);
|
|
}
|
|
|
|
if (!$data['clone_playlists']) {
|
|
$copier->addFilter(
|
|
new DeepCopy\Filter\Doctrine\DoctrineEmptyCollectionFilter(),
|
|
new DeepCopy\Matcher\PropertyMatcher(Entity\Station::class, 'playlists')
|
|
);
|
|
$copier->addFilter(
|
|
new DeepCopy\Filter\Doctrine\DoctrineEmptyCollectionFilter(),
|
|
new DeepCopy\Matcher\PropertyMatcher(Entity\StationMedia::class, 'playlists')
|
|
);
|
|
}
|
|
|
|
if (!$data['clone_streamers']) {
|
|
$copier->addFilter(
|
|
new DeepCopy\Filter\Doctrine\DoctrineEmptyCollectionFilter(),
|
|
new DeepCopy\Matcher\PropertyMatcher(Entity\Station::class, 'streamers')
|
|
);
|
|
}
|
|
|
|
if (!$data['clone_permissions']) {
|
|
$copier->addFilter(
|
|
new DeepCopy\Filter\Doctrine\DoctrineEmptyCollectionFilter(),
|
|
new DeepCopy\Matcher\PropertyMatcher(Entity\Station::class, 'permissions')
|
|
);
|
|
}
|
|
|
|
if ('none' === $data['clone_media']) {
|
|
$copier->addFilter(
|
|
new DeepCopy\Filter\Doctrine\DoctrineEmptyCollectionFilter(),
|
|
new DeepCopy\Matcher\PropertyMatcher(Entity\Station::class, 'media')
|
|
);
|
|
} else {
|
|
$copier->addFilter(
|
|
new DeepCopy\Filter\Doctrine\DoctrineEmptyCollectionFilter(),
|
|
new DeepCopy\Matcher\PropertyMatcher(Entity\Station::class, 'playlists')
|
|
);
|
|
}
|
|
|
|
// Execute the Doctrine entity copy.
|
|
$copier->addFilter(
|
|
new DeepCopy\Filter\Doctrine\DoctrineCollectionFilter(),
|
|
new DeepCopy\Matcher\PropertyTypeMatcher(Collection::class)
|
|
);
|
|
|
|
/** @var Entity\Station $new_record */
|
|
$new_record = $copier->copy($record);
|
|
|
|
$new_record->setName($data['name']);
|
|
$new_record->setDescription($data['description']);
|
|
$new_record->clearPorts();
|
|
|
|
$new_record->setIsStreamerLive(false);
|
|
$new_record->setNeedsRestart(false);
|
|
$new_record->setHasStarted(false);
|
|
|
|
if ('share' === $data['clone_media']) {
|
|
$new_record->setMediaStorageLocation($record->getMediaStorageLocation());
|
|
$new_record->setRecordingsStorageLocation($record->getRecordingsStorageLocation());
|
|
}
|
|
|
|
// Set new radio base directory
|
|
$station_base_dir = $this->environment->getStationDirectory();
|
|
$new_record->setRadioBaseDir($station_base_dir . '/' . $new_record->getShortName());
|
|
|
|
$new_record->ensureDirectoriesExist();
|
|
|
|
// Persist all newly created records (and relations).
|
|
$this->em->persist($new_record);
|
|
|
|
$this->em->persist($new_record->getMediaStorageLocation());
|
|
$this->em->persist($new_record->getRecordingsStorageLocation());
|
|
$this->em->persist($new_record->getPodcastsStorageLocation());
|
|
|
|
foreach ($new_record->getMounts() as $subrecord) {
|
|
$this->em->persist($subrecord);
|
|
}
|
|
|
|
foreach ($new_record->getPermissions() as $subrecord) {
|
|
$this->em->persist($subrecord);
|
|
}
|
|
|
|
foreach ($new_record->getPlaylists() as $subrecord) {
|
|
/** @var Entity\StationPlaylist $subrecord */
|
|
$this->em->persist($subrecord);
|
|
|
|
foreach ($subrecord->getScheduleItems() as $playlist_schedule_item) {
|
|
$this->em->persist($playlist_schedule_item);
|
|
}
|
|
}
|
|
|
|
foreach ($new_record->getRemotes() as $subrecord) {
|
|
$this->em->persist($subrecord);
|
|
}
|
|
|
|
foreach ($new_record->getStreamers() as $subrecord) {
|
|
/** @var Entity\StationStreamer $subrecord */
|
|
$this->em->persist($subrecord);
|
|
|
|
foreach ($subrecord->getScheduleItems() as $playlist_schedule_item) {
|
|
$this->em->persist($playlist_schedule_item);
|
|
}
|
|
}
|
|
|
|
$this->em->flush();
|
|
|
|
// Clear the EntityManager for later functions.
|
|
$new_record_id = $new_record->getId();
|
|
$this->em->clear();
|
|
$new_record = $this->em->find(Entity\Station::class, $new_record_id);
|
|
|
|
$this->configuration->assignRadioPorts($new_record, true);
|
|
$this->configuration->writeConfiguration($new_record);
|
|
|
|
$this->em->flush();
|
|
return $new_record;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|