Working implementation of "Apply to Folders" feature.
This commit is contained in:
parent
c01f3c580c
commit
999b389ee9
|
@ -195,7 +195,7 @@ final class BatchAction implements SingleActionInterface
|
|||
|
||||
foreach ($result->directories as $dir) {
|
||||
try {
|
||||
$this->playlistFolderRepo->setPlaylistsForFolder($station, $playlists, $dir);
|
||||
$this->playlistFolderRepo->setPlaylistsForFolder($station, $dir, $playlists);
|
||||
} catch (Exception $e) {
|
||||
$result->errors[] = $dir . ': ' . $e->getMessage();
|
||||
}
|
||||
|
|
|
@ -24,8 +24,7 @@ final class GetApplyToAction implements SingleActionInterface
|
|||
ServerRequest $request,
|
||||
Response $response,
|
||||
array $params
|
||||
): ResponseInterface
|
||||
{
|
||||
): ResponseInterface {
|
||||
/** @var string $id */
|
||||
$id = $params['id'];
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
|||
namespace App\Controller\Api\Stations\Playlists;
|
||||
|
||||
use App\Controller\SingleActionInterface;
|
||||
use App\Entity\Api\Status;
|
||||
use App\Entity\Repository\StationPlaylistFolderRepository;
|
||||
use App\Entity\Repository\StationPlaylistRepository;
|
||||
use App\Http\Response;
|
||||
|
@ -42,9 +43,22 @@ final class PutApplyToAction extends AbstractClonableAction implements SingleAct
|
|||
$record,
|
||||
$record->getName() . ' - ' . $directory
|
||||
);
|
||||
} else {
|
||||
$playlist = $record;
|
||||
}
|
||||
|
||||
$this->folderRepo->setPlaylistsForFolder();
|
||||
$this->folderRepo->addPlaylistsToFolder(
|
||||
$station,
|
||||
$directory,
|
||||
[$playlist]
|
||||
);
|
||||
}
|
||||
|
||||
return $response->withJson(
|
||||
new Status(
|
||||
true,
|
||||
__('Playlist applied to folders.')
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ use App\Entity\Enums\PlaylistSources;
|
|||
use App\Entity\Station;
|
||||
use App\Entity\StationPlaylist;
|
||||
use App\Entity\StationPlaylistFolder;
|
||||
use App\Utilities\Arrays;
|
||||
|
||||
/**
|
||||
* @extends AbstractStationBasedRepository<StationPlaylistFolder>
|
||||
|
@ -16,41 +17,105 @@ final class StationPlaylistFolderRepository extends AbstractStationBasedReposito
|
|||
{
|
||||
protected string $entityClass = StationPlaylistFolder::class;
|
||||
|
||||
/**
|
||||
* @param Station $station
|
||||
* @param StationPlaylist[] $playlists
|
||||
* @param string $path
|
||||
*/
|
||||
public function setPlaylistsForFolder(
|
||||
public function addPlaylistsToFolder(
|
||||
Station $station,
|
||||
array $playlists,
|
||||
string $path
|
||||
string $path,
|
||||
array $playlists
|
||||
): void {
|
||||
if (str_contains($path, '://')) {
|
||||
[, $path] = explode('://', $path, 2);
|
||||
$playlists = $this->getEligiblePlaylists($playlists);
|
||||
|
||||
foreach ($this->getPlaylistIdsForFolder($station, $path) as $playlistId) {
|
||||
unset($playlists[$playlistId]);
|
||||
}
|
||||
|
||||
$this->em->createQuery(
|
||||
<<<'DQL'
|
||||
DELETE FROM App\Entity\StationPlaylistFolder spf
|
||||
WHERE spf.station = :station AND spf.path = :path
|
||||
DQL
|
||||
)->setParameter('station', $station)
|
||||
->setParameter('path', $path)
|
||||
->execute();
|
||||
|
||||
foreach ($playlists as $playlistId => $playlistRecord) {
|
||||
if (PlaylistSources::Songs === $playlistRecord->getSource()) {
|
||||
/** @var StationPlaylist $playlist */
|
||||
$playlist = $this->em->getReference(StationPlaylist::class, $playlistId);
|
||||
/** @var StationPlaylist $playlist */
|
||||
$playlist = $this->em->getReference(StationPlaylist::class, $playlistId);
|
||||
|
||||
$newRecord = new StationPlaylistFolder($station, $playlist, $path);
|
||||
$this->em->persist($newRecord);
|
||||
}
|
||||
$newRecord = new StationPlaylistFolder($station, $playlist, $path);
|
||||
$this->em->persist($newRecord);
|
||||
}
|
||||
|
||||
$this->em->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Station $station
|
||||
* @param string $path
|
||||
* @param StationPlaylist[] $playlists
|
||||
*/
|
||||
public function setPlaylistsForFolder(
|
||||
Station $station,
|
||||
string $path,
|
||||
array $playlists
|
||||
): void {
|
||||
$playlists = $this->getEligiblePlaylists($playlists);
|
||||
|
||||
$toDelete = [];
|
||||
|
||||
foreach ($this->getPlaylistIdsForFolder($station, $path) as $playlistId) {
|
||||
if (isset($playlists[$playlistId])) {
|
||||
unset($playlists[$playlistId]);
|
||||
} else {
|
||||
$toDelete[] = $playlistId;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 !== count($toDelete)) {
|
||||
$this->em->createQuery(
|
||||
<<<'DQL'
|
||||
DELETE FROM App\Entity\StationPlaylistFolder spf
|
||||
WHERE spf.station = :station
|
||||
AND spf.path = :path
|
||||
AND spf.playlist_id IN (:playlistIds)
|
||||
DQL
|
||||
)->setParameter('station', $station)
|
||||
->setParameter('path', $path)
|
||||
->setParameter('playlistIds', $toDelete)
|
||||
->execute();
|
||||
}
|
||||
|
||||
foreach ($playlists as $playlistId => $playlistRecord) {
|
||||
/** @var StationPlaylist $playlist */
|
||||
$playlist = $this->em->getReference(StationPlaylist::class, $playlistId);
|
||||
|
||||
$newRecord = new StationPlaylistFolder($station, $playlist, $path);
|
||||
$this->em->persist($newRecord);
|
||||
}
|
||||
|
||||
$this->em->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<array-key, StationPlaylist> $playlists
|
||||
* @return array<int, StationPlaylist>
|
||||
*/
|
||||
protected function getEligiblePlaylists(array $playlists): array
|
||||
{
|
||||
return Arrays::keyByCallable(
|
||||
array_filter(
|
||||
$playlists,
|
||||
fn(StationPlaylist $playlist) => PlaylistSources::Songs === $playlist->getSource()
|
||||
),
|
||||
fn(StationPlaylist $playlist) => $playlist->getIdRequired()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int[]
|
||||
*/
|
||||
protected function getPlaylistIdsForFolder(
|
||||
Station $station,
|
||||
string $path
|
||||
): array {
|
||||
return $this->em->createQuery(
|
||||
<<<'DQL'
|
||||
SELECT spf.playlist_id
|
||||
FROM App\Entity\StationPlaylistFolder spf
|
||||
WHERE spf.station = :station AND spf.path = :path
|
||||
DQL
|
||||
)->setParameter('station', $station)
|
||||
->setParameter('path', $path)
|
||||
->getSingleColumnResult();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,9 @@ class StationPlaylistFolder implements
|
|||
#[ORM\JoinColumn(name: 'playlist_id', referencedColumnName: 'id', nullable: false, onDelete: 'CASCADE')]
|
||||
protected StationPlaylist $playlist;
|
||||
|
||||
#[ORM\Column(nullable: false, insertable: false, updatable: false)]
|
||||
protected int $playlist_id;
|
||||
|
||||
#[ORM\Column(length: 500)]
|
||||
protected string $path;
|
||||
|
||||
|
|
|
@ -106,4 +106,21 @@ final class Arrays
|
|||
|
||||
return $merged;
|
||||
}
|
||||
|
||||
/**
|
||||
* @template T of object
|
||||
*
|
||||
* @param array<array-key, T> $objects
|
||||
* @param callable $keyFunction
|
||||
* @return array<array-key, T>
|
||||
*/
|
||||
public static function keyByCallable(array $objects, callable $keyFunction): array
|
||||
{
|
||||
$newArray = [];
|
||||
foreach ($objects as $object) {
|
||||
$newArray[$keyFunction($object)] = $object;
|
||||
}
|
||||
|
||||
return $newArray;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue