More type fixes!
This commit is contained in:
parent
c2f352c115
commit
bbf8d56b46
|
@ -12,7 +12,7 @@ $environment = App\AppFactory::buildEnvironment();
|
||||||
|
|
||||||
$console = new Symfony\Component\Console\Application(
|
$console = new Symfony\Component\Console\Application(
|
||||||
'AzuraCast installer',
|
'AzuraCast installer',
|
||||||
App\Version::FALLBACK_VERSION
|
App\Version::STABLE_VERSION
|
||||||
);
|
);
|
||||||
|
|
||||||
$installCommand = new App\Installer\Command\InstallCommand();
|
$installCommand = new App\Installer\Command\InstallCommand();
|
||||||
|
|
|
@ -330,6 +330,10 @@ return [
|
||||||
// Register plugin-provided message queue receivers
|
// Register plugin-provided message queue receivers
|
||||||
$receivers = $plugins->registerMessageQueueReceivers($receivers);
|
$receivers = $plugins->registerMessageQueueReceivers($receivers);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var class-string $messageClass
|
||||||
|
* @var class-string $handlerClass
|
||||||
|
*/
|
||||||
foreach ($receivers as $messageClass => $handlerClass) {
|
foreach ($receivers as $messageClass => $handlerClass) {
|
||||||
$handlers[$messageClass][] = static function ($message) use ($handlerClass, $di) {
|
$handlers[$messageClass][] = static function ($message) use ($handlerClass, $di) {
|
||||||
$obj = $di->get($handlerClass);
|
$obj = $di->get($handlerClass);
|
||||||
|
|
25
src/Acl.php
25
src/Acl.php
|
@ -19,12 +19,30 @@ use Psr\EventDispatcher\EventDispatcherInterface;
|
||||||
use function in_array;
|
use function in_array;
|
||||||
use function is_array;
|
use function is_array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @phpstan-type PermissionsArray array{
|
||||||
|
* global: array<string, string>,
|
||||||
|
* station: array<string, string>
|
||||||
|
* }
|
||||||
|
*/
|
||||||
final class Acl
|
final class Acl
|
||||||
{
|
{
|
||||||
use RequestAwareTrait;
|
use RequestAwareTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var PermissionsArray
|
||||||
|
*/
|
||||||
private array $permissions;
|
private array $permissions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var null|array<
|
||||||
|
* int,
|
||||||
|
* array{
|
||||||
|
* stations?: array<int, array<string>>,
|
||||||
|
* global?: array<string>
|
||||||
|
* }
|
||||||
|
* >
|
||||||
|
*/
|
||||||
private ?array $actions;
|
private ?array $actions;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
|
@ -41,12 +59,12 @@ final class Acl
|
||||||
{
|
{
|
||||||
$sql = $this->em->createQuery(
|
$sql = $this->em->createQuery(
|
||||||
<<<'DQL'
|
<<<'DQL'
|
||||||
SELECT rp FROM App\Entity\RolePermission rp
|
SELECT rp.station_id, rp.role_id, rp.action_name FROM App\Entity\RolePermission rp
|
||||||
DQL
|
DQL
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->actions = [];
|
$this->actions = [];
|
||||||
foreach ($sql->getArrayResult() as $row) {
|
foreach ($sql->toIterable() as $row) {
|
||||||
if ($row['station_id']) {
|
if ($row['station_id']) {
|
||||||
$this->actions[$row['role_id']]['stations'][$row['station_id']][] = $row['action_name'];
|
$this->actions[$row['role_id']]['stations'][$row['station_id']][] = $row['action_name'];
|
||||||
} else {
|
} else {
|
||||||
|
@ -69,12 +87,11 @@ final class Acl
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return mixed[]
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function listPermissions(): array
|
public function listPermissions(): array
|
||||||
{
|
{
|
||||||
if (!isset($this->permissions)) {
|
if (!isset($this->permissions)) {
|
||||||
/** @var array<string,array<string, string>> $permissions */
|
|
||||||
$permissions = [
|
$permissions = [
|
||||||
'global' => [],
|
'global' => [],
|
||||||
'station' => [],
|
'station' => [],
|
||||||
|
|
|
@ -8,6 +8,7 @@ use App\Container\EnvironmentAwareTrait;
|
||||||
use App\Entity\Repository\UserRepository;
|
use App\Entity\Repository\UserRepository;
|
||||||
use App\Entity\User;
|
use App\Entity\User;
|
||||||
use App\Exception\NotLoggedInException;
|
use App\Exception\NotLoggedInException;
|
||||||
|
use App\Utilities\Types;
|
||||||
use Mezzio\Session\SessionInterface;
|
use Mezzio\Session\SessionInterface;
|
||||||
|
|
||||||
final class Auth
|
final class Auth
|
||||||
|
@ -83,7 +84,7 @@ final class Auth
|
||||||
if (!$this->session->has(self::SESSION_MASQUERADE_USER_ID_KEY)) {
|
if (!$this->session->has(self::SESSION_MASQUERADE_USER_ID_KEY)) {
|
||||||
$this->masqueraded_user = false;
|
$this->masqueraded_user = false;
|
||||||
} else {
|
} else {
|
||||||
$maskUserId = (int)$this->session->get(self::SESSION_MASQUERADE_USER_ID_KEY);
|
$maskUserId = Types::int($this->session->get(self::SESSION_MASQUERADE_USER_ID_KEY));
|
||||||
if (0 !== $maskUserId) {
|
if (0 !== $maskUserId) {
|
||||||
$user = $this->userRepo->getRepository()->find($maskUserId);
|
$user = $this->userRepo->getRepository()->find($maskUserId);
|
||||||
} else {
|
} else {
|
||||||
|
@ -125,7 +126,7 @@ final class Auth
|
||||||
*/
|
*/
|
||||||
public function isLoginComplete(): bool
|
public function isLoginComplete(): bool
|
||||||
{
|
{
|
||||||
return $this->session->get(self::SESSION_IS_LOGIN_COMPLETE_KEY, false) ?? false;
|
return Types::bool($this->session->get(self::SESSION_IS_LOGIN_COMPLETE_KEY, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -136,7 +137,7 @@ final class Auth
|
||||||
public function getUser(): ?User
|
public function getUser(): ?User
|
||||||
{
|
{
|
||||||
if (null === $this->user) {
|
if (null === $this->user) {
|
||||||
$userId = (int)$this->session->get(self::SESSION_USER_ID_KEY);
|
$userId = Types::int($this->session->get(self::SESSION_USER_ID_KEY));
|
||||||
|
|
||||||
if (0 === $userId) {
|
if (0 === $userId) {
|
||||||
$this->user = false;
|
$this->user = false;
|
||||||
|
|
|
@ -6,6 +6,7 @@ namespace App\Cache;
|
||||||
|
|
||||||
use App\Entity\Api\NowPlaying\NowPlaying;
|
use App\Entity\Api\NowPlaying\NowPlaying;
|
||||||
use App\Entity\Station;
|
use App\Entity\Station;
|
||||||
|
use App\Utilities\Types;
|
||||||
use Psr\Cache\CacheItemInterface;
|
use Psr\Cache\CacheItemInterface;
|
||||||
use Psr\Cache\CacheItemPoolInterface;
|
use Psr\Cache\CacheItemPoolInterface;
|
||||||
|
|
||||||
|
@ -41,9 +42,13 @@ final class NowPlayingCache
|
||||||
|
|
||||||
$stationCacheItem = $this->getStationCache($station);
|
$stationCacheItem = $this->getStationCache($station);
|
||||||
|
|
||||||
return ($stationCacheItem->isHit())
|
if (!$stationCacheItem->isHit()) {
|
||||||
? $stationCacheItem->get()
|
return null;
|
||||||
: null;
|
}
|
||||||
|
|
||||||
|
$np = $stationCacheItem->get();
|
||||||
|
assert($np instanceof NowPlaying);
|
||||||
|
return $np;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -78,11 +83,18 @@ final class NowPlayingCache
|
||||||
return $np;
|
return $np;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<int, array{
|
||||||
|
* short_name: string,
|
||||||
|
* is_public: bool,
|
||||||
|
* updated_at: int
|
||||||
|
* }>
|
||||||
|
*/
|
||||||
public function getLookup(): array
|
public function getLookup(): array
|
||||||
{
|
{
|
||||||
$lookupCacheItem = $this->getLookupCache();
|
$lookupCacheItem = $this->getLookupCache();
|
||||||
return $lookupCacheItem->isHit()
|
return $lookupCacheItem->isHit()
|
||||||
? (array)$lookupCacheItem->get()
|
? Types::array($lookupCacheItem->get())
|
||||||
: [];
|
: [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +126,7 @@ final class NowPlayingCache
|
||||||
$lookupCacheItem = $this->getLookupCache();
|
$lookupCacheItem = $this->getLookupCache();
|
||||||
|
|
||||||
$lookupCache = $lookupCacheItem->isHit()
|
$lookupCache = $lookupCacheItem->isHit()
|
||||||
? (array)$lookupCacheItem->get()
|
? Types::array($lookupCacheItem->get())
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
$lookupCache[$station->getIdRequired()] = [
|
$lookupCache[$station->getIdRequired()] = [
|
||||||
|
@ -131,12 +143,9 @@ final class NowPlayingCache
|
||||||
private function getStationCache(string $identifier): CacheItemInterface
|
private function getStationCache(string $identifier): CacheItemInterface
|
||||||
{
|
{
|
||||||
if (is_numeric($identifier)) {
|
if (is_numeric($identifier)) {
|
||||||
$lookupCacheItem = $this->getLookupCache();
|
$lookupCache = $this->getLookup();
|
||||||
$lookupCache = $lookupCacheItem->isHit()
|
|
||||||
? (array)$lookupCacheItem->get()
|
|
||||||
: [];
|
|
||||||
|
|
||||||
$identifier = (int)$identifier;
|
$identifier = Types::int($identifier);
|
||||||
if (isset($lookupCache[$identifier])) {
|
if (isset($lookupCache[$identifier])) {
|
||||||
$identifier = $lookupCache[$identifier]['short_name'];
|
$identifier = $lookupCache[$identifier]['short_name'];
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ final class GenerateApiDocsCommand extends CommandAbstract
|
||||||
define('AZURACAST_API_NAME', 'AzuraCast Public Demo Server');
|
define('AZURACAST_API_NAME', 'AzuraCast Public Demo Server');
|
||||||
define(
|
define(
|
||||||
'AZURACAST_VERSION',
|
'AZURACAST_VERSION',
|
||||||
$useCurrentVersion ? $this->version->getVersion() : Version::FALLBACK_VERSION
|
$useCurrentVersion ? $this->version->getVersion() : Version::STABLE_VERSION
|
||||||
);
|
);
|
||||||
|
|
||||||
$finder = Util::finder(
|
$finder = Util::finder(
|
||||||
|
|
|
@ -206,7 +206,8 @@ final class CloneAction extends StationsController implements SingleActionInterf
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Collection<int, mixed> $collection
|
* @template T of mixed
|
||||||
|
* @param Collection<int, T> $collection
|
||||||
*/
|
*/
|
||||||
private function cloneCollection(
|
private function cloneCollection(
|
||||||
Collection $collection,
|
Collection $collection,
|
||||||
|
|
|
@ -86,6 +86,7 @@ final class DownloadAction implements SingleActionInterface
|
||||||
|
|
||||||
$csv->insertOne($headerRow);
|
$csv->insertOne($headerRow);
|
||||||
|
|
||||||
|
/** @var array $row */
|
||||||
foreach ($query->getArrayResult() as $row) {
|
foreach ($query->getArrayResult() as $row) {
|
||||||
$customFieldsById = [];
|
$customFieldsById = [];
|
||||||
foreach ($row['custom_fields'] ?? [] as $rowCustomField) {
|
foreach ($row['custom_fields'] ?? [] as $rowCustomField) {
|
||||||
|
|
|
@ -28,6 +28,7 @@ use App\Radio\Backend\Liquidsoap;
|
||||||
use App\Radio\Enums\BackendAdapters;
|
use App\Radio\Enums\BackendAdapters;
|
||||||
use App\Radio\Enums\LiquidsoapQueues;
|
use App\Radio\Enums\LiquidsoapQueues;
|
||||||
use App\Utilities\File;
|
use App\Utilities\File;
|
||||||
|
use App\Utilities\Types;
|
||||||
use Exception;
|
use Exception;
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
use League\Flysystem\StorageAttributes;
|
use League\Flysystem\StorageAttributes;
|
||||||
|
@ -411,8 +412,12 @@ final class BatchAction implements SingleActionInterface
|
||||||
ExtendedFilesystemInterface $fs,
|
ExtendedFilesystemInterface $fs,
|
||||||
bool $recursive = false
|
bool $recursive = false
|
||||||
): BatchResult {
|
): BatchResult {
|
||||||
$files = array_values((array)$request->getParam('files', []));
|
$files = array_values(
|
||||||
$directories = array_values((array)$request->getParam('dirs', []));
|
Types::array($request->getParam('files', []))
|
||||||
|
);
|
||||||
|
$directories = array_values(
|
||||||
|
Types::array($request->getParam('dirs', []))
|
||||||
|
);
|
||||||
|
|
||||||
if ($recursive) {
|
if ($recursive) {
|
||||||
foreach ($directories as $dir) {
|
foreach ($directories as $dir) {
|
||||||
|
|
|
@ -9,6 +9,7 @@ use App\Entity\Api\Error;
|
||||||
use App\Flysystem\StationFilesystems;
|
use App\Flysystem\StationFilesystems;
|
||||||
use App\Http\Response;
|
use App\Http\Response;
|
||||||
use App\Http\ServerRequest;
|
use App\Http\ServerRequest;
|
||||||
|
use App\Utilities\Types;
|
||||||
use Psr\Http\Message\ResponseInterface;
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
|
||||||
final class DownloadAction implements SingleActionInterface
|
final class DownloadAction implements SingleActionInterface
|
||||||
|
@ -29,7 +30,7 @@ final class DownloadAction implements SingleActionInterface
|
||||||
|
|
||||||
$fsMedia = $this->stationFilesystems->getMediaFilesystem($station);
|
$fsMedia = $this->stationFilesystems->getMediaFilesystem($station);
|
||||||
|
|
||||||
$path = $request->getParam('file');
|
$path = Types::string($request->getParam('file'));
|
||||||
|
|
||||||
if (!$fsMedia->fileExists($path)) {
|
if (!$fsMedia->fileExists($path)) {
|
||||||
return $response->withStatus(404)
|
return $response->withStatus(404)
|
||||||
|
|
|
@ -20,6 +20,7 @@ use App\Http\Response;
|
||||||
use App\Http\ServerRequest;
|
use App\Http\ServerRequest;
|
||||||
use App\Media\MediaProcessor;
|
use App\Media\MediaProcessor;
|
||||||
use App\Service\Flow;
|
use App\Service\Flow;
|
||||||
|
use App\Utilities\Types;
|
||||||
use Psr\Http\Message\ResponseInterface;
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
|
||||||
final class FlowUploadAction implements SingleActionInterface
|
final class FlowUploadAction implements SingleActionInterface
|
||||||
|
@ -51,7 +52,7 @@ final class FlowUploadAction implements SingleActionInterface
|
||||||
return $flowResponse;
|
return $flowResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
$currentDir = $request->getParam('currentDirectory', '');
|
$currentDir = Types::string($request->getParam('currentDirectory'));
|
||||||
|
|
||||||
$destPath = $flowResponse->getClientFilename();
|
$destPath = $flowResponse->getClientFilename();
|
||||||
if (!empty($currentDir)) {
|
if (!empty($currentDir)) {
|
||||||
|
|
|
@ -52,10 +52,10 @@ final class ListAction implements SingleActionInterface
|
||||||
|
|
||||||
$fs = $this->stationFilesystems->getMediaFilesystem($station);
|
$fs = $this->stationFilesystems->getMediaFilesystem($station);
|
||||||
|
|
||||||
$currentDir = $request->getParam('currentDirectory', '');
|
$currentDir = Types::string($request->getParam('currentDirectory'));
|
||||||
|
|
||||||
$searchPhraseFull = trim($request->getParam('searchPhrase', ''));
|
$searchPhraseFull = Types::stringOrNull($request->getParam('searchPhrase'), true);
|
||||||
$isSearch = !empty($searchPhraseFull);
|
$isSearch = null !== $searchPhraseFull;
|
||||||
|
|
||||||
[$searchPhrase, $playlist, $special] = $this->parseSearchQuery(
|
[$searchPhrase, $playlist, $special] = $this->parseSearchQuery(
|
||||||
$station,
|
$station,
|
||||||
|
@ -74,7 +74,7 @@ final class ListAction implements SingleActionInterface
|
||||||
|
|
||||||
$cacheKey = implode('.', $cacheKeyParts);
|
$cacheKey = implode('.', $cacheKeyParts);
|
||||||
|
|
||||||
$flushCache = (bool)$request->getParam('flushCache', false);
|
$flushCache = Types::bool($request->getParam('flushCache'));
|
||||||
|
|
||||||
if (!$flushCache && $this->cache->has($cacheKey)) {
|
if (!$flushCache && $this->cache->has($cacheKey)) {
|
||||||
/** @var array<int, FileList> $result */
|
/** @var array<int, FileList> $result */
|
||||||
|
|
|
@ -61,7 +61,7 @@ trait CanSortResults
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array{string, string}
|
* @return array{string|null, Criteria::ASC|Criteria::DESC}
|
||||||
*/
|
*/
|
||||||
protected function getSortFromRequest(
|
protected function getSortFromRequest(
|
||||||
ServerRequest $request,
|
ServerRequest $request,
|
||||||
|
@ -69,7 +69,7 @@ trait CanSortResults
|
||||||
): array {
|
): array {
|
||||||
$sortOrder = Types::stringOrNull($request->getParam('sortOrder'), true) ?? $defaultSortOrder;
|
$sortOrder = Types::stringOrNull($request->getParam('sortOrder'), true) ?? $defaultSortOrder;
|
||||||
return [
|
return [
|
||||||
$request->getParam('sort'),
|
Types::stringOrNull($request->getParam('sort'), true),
|
||||||
(Criteria::DESC === strtoupper($sortOrder))
|
(Criteria::DESC === strtoupper($sortOrder))
|
||||||
? Criteria::DESC
|
? Criteria::DESC
|
||||||
: Criteria::ASC,
|
: Criteria::ASC,
|
||||||
|
|
|
@ -41,10 +41,9 @@ trait HasMediaSearch
|
||||||
FROM App\Entity\StationPlaylist sp
|
FROM App\Entity\StationPlaylist sp
|
||||||
WHERE sp.station = :station
|
WHERE sp.station = :station
|
||||||
DQL
|
DQL
|
||||||
)->setParameter('station', $station)
|
)->setParameter('station', $station);
|
||||||
->getArrayResult();
|
|
||||||
|
|
||||||
foreach ($playlistNameLookupRaw as $playlistRow) {
|
foreach ($playlistNameLookupRaw->toIterable() as $playlistRow) {
|
||||||
$shortName = StationPlaylist::generateShortName($playlistRow['name']);
|
$shortName = StationPlaylist::generateShortName($playlistRow['name']);
|
||||||
if ($shortName === $playlistId) {
|
if ($shortName === $playlistId) {
|
||||||
$playlistId = $playlistRow['id'];
|
$playlistId = $playlistRow['id'];
|
||||||
|
|
|
@ -8,8 +8,10 @@ use JsonSerializable;
|
||||||
|
|
||||||
final class BatchResult implements JsonSerializable
|
final class BatchResult implements JsonSerializable
|
||||||
{
|
{
|
||||||
|
/** @var string[] */
|
||||||
public array $files = [];
|
public array $files = [];
|
||||||
|
|
||||||
|
/** @var string[] */
|
||||||
public array $directories = [];
|
public array $directories = [];
|
||||||
|
|
||||||
public array $errors = [];
|
public array $errors = [];
|
||||||
|
|
|
@ -4,23 +4,33 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\Event;
|
namespace App\Event;
|
||||||
|
|
||||||
|
use App\Acl;
|
||||||
use Symfony\Contracts\EventDispatcher\Event;
|
use Symfony\Contracts\EventDispatcher\Event;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @phpstan-import-type PermissionsArray from Acl
|
||||||
|
*/
|
||||||
final class BuildPermissions extends Event
|
final class BuildPermissions extends Event
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @param PermissionsArray $permissions
|
||||||
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private array $permissions
|
private array $permissions
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return mixed[]
|
* @return PermissionsArray
|
||||||
*/
|
*/
|
||||||
public function getPermissions(): array
|
public function getPermissions(): array
|
||||||
{
|
{
|
||||||
return $this->permissions;
|
return $this->permissions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param PermissionsArray $permissions
|
||||||
|
*/
|
||||||
public function setPermissions(array $permissions): void
|
public function setPermissions(array $permissions): void
|
||||||
{
|
{
|
||||||
$this->permissions = $permissions;
|
$this->permissions = $permissions;
|
||||||
|
|
|
@ -56,7 +56,7 @@ final class RemoteAlbumArt
|
||||||
[
|
[
|
||||||
RequestOptions::TIMEOUT => 10,
|
RequestOptions::TIMEOUT => 10,
|
||||||
RequestOptions::HEADERS => [
|
RequestOptions::HEADERS => [
|
||||||
'User-Agent' => 'AzuraCast ' . Version::FALLBACK_VERSION,
|
'User-Agent' => 'AzuraCast ' . Version::STABLE_VERSION,
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
|
@ -43,7 +43,7 @@ final class AzuraCastCentral
|
||||||
if ($commitHash) {
|
if ($commitHash) {
|
||||||
$requestBody['version'] = $commitHash;
|
$requestBody['version'] = $commitHash;
|
||||||
} else {
|
} else {
|
||||||
$requestBody['release'] = Version::FALLBACK_VERSION;
|
$requestBody['release'] = Version::STABLE_VERSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->logger->debug(
|
$this->logger->debug(
|
||||||
|
|
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||||
namespace App\Service\Dropbox;
|
namespace App\Service\Dropbox;
|
||||||
|
|
||||||
use App\Entity\StorageLocation;
|
use App\Entity\StorageLocation;
|
||||||
|
use App\Utilities\Types;
|
||||||
use GuzzleHttp\Exception\ClientException;
|
use GuzzleHttp\Exception\ClientException;
|
||||||
use Psr\Cache\CacheItemPoolInterface;
|
use Psr\Cache\CacheItemPoolInterface;
|
||||||
use Spatie\Dropbox\RefreshableTokenProvider;
|
use Spatie\Dropbox\RefreshableTokenProvider;
|
||||||
|
@ -80,7 +81,7 @@ final class OAuthAdapter implements RefreshableTokenProvider
|
||||||
$this->psr6Cache->save($cacheItem);
|
$this->psr6Cache->save($cacheItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $cacheItem->get();
|
return Types::string($cacheItem->get());
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getOauthProvider(): OAuthProvider
|
private function getOauthProvider(): OAuthProvider
|
||||||
|
|
|
@ -81,7 +81,7 @@ final class LastFm
|
||||||
[
|
[
|
||||||
RequestOptions::HTTP_ERRORS => true,
|
RequestOptions::HTTP_ERRORS => true,
|
||||||
RequestOptions::HEADERS => [
|
RequestOptions::HEADERS => [
|
||||||
'User-Agent' => 'AzuraCast ' . Version::FALLBACK_VERSION,
|
'User-Agent' => 'AzuraCast ' . Version::STABLE_VERSION,
|
||||||
'Accept' => 'application/json',
|
'Accept' => 'application/json',
|
||||||
],
|
],
|
||||||
RequestOptions::QUERY => $query,
|
RequestOptions::QUERY => $query,
|
||||||
|
|
|
@ -65,7 +65,7 @@ final class MusicBrainz
|
||||||
RequestOptions::TIMEOUT => 7,
|
RequestOptions::TIMEOUT => 7,
|
||||||
RequestOptions::HTTP_ERRORS => true,
|
RequestOptions::HTTP_ERRORS => true,
|
||||||
RequestOptions::HEADERS => [
|
RequestOptions::HEADERS => [
|
||||||
'User-Agent' => 'AzuraCast ' . Version::FALLBACK_VERSION,
|
'User-Agent' => 'AzuraCast ' . Version::STABLE_VERSION,
|
||||||
'Accept' => 'application/json',
|
'Accept' => 'application/json',
|
||||||
],
|
],
|
||||||
RequestOptions::QUERY => $query,
|
RequestOptions::QUERY => $query,
|
||||||
|
@ -157,7 +157,7 @@ final class MusicBrainz
|
||||||
[
|
[
|
||||||
RequestOptions::ALLOW_REDIRECTS => true,
|
RequestOptions::ALLOW_REDIRECTS => true,
|
||||||
RequestOptions::HEADERS => [
|
RequestOptions::HEADERS => [
|
||||||
'User-Agent' => 'AzuraCast ' . Version::FALLBACK_VERSION,
|
'User-Agent' => 'AzuraCast ' . Version::STABLE_VERSION,
|
||||||
'Accept' => 'application/json',
|
'Accept' => 'application/json',
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
|
|
|
@ -6,6 +6,7 @@ namespace App\Session;
|
||||||
|
|
||||||
use App\Environment;
|
use App\Environment;
|
||||||
use App\Exception;
|
use App\Exception;
|
||||||
|
use App\Utilities\Types;
|
||||||
use Mezzio\Session\SessionInterface;
|
use Mezzio\Session\SessionInterface;
|
||||||
|
|
||||||
final class Csrf
|
final class Csrf
|
||||||
|
@ -32,9 +33,9 @@ final class Csrf
|
||||||
{
|
{
|
||||||
$sessionKey = $this->getSessionIdentifier($namespace);
|
$sessionKey = $this->getSessionIdentifier($namespace);
|
||||||
if ($this->session->has($sessionKey)) {
|
if ($this->session->has($sessionKey)) {
|
||||||
$csrf = $this->session->get($sessionKey);
|
$csrf = Types::stringOrNull($this->session->get($sessionKey), true);
|
||||||
if (!empty($csrf)) {
|
if (null !== $csrf) {
|
||||||
return (string)$csrf;
|
return $csrf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,9 +72,8 @@ final class Csrf
|
||||||
throw new Exception\CsrfValidationException('No CSRF token supplied for this namespace.');
|
throw new Exception\CsrfValidationException('No CSRF token supplied for this namespace.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$sessionKey = $this->session->get($sessionIdentifier);
|
$sessionKey = Types::string($this->session->get($sessionIdentifier));
|
||||||
|
if (0 !== strcmp($key, $sessionKey)) {
|
||||||
if (0 !== strcmp($key, (string)$sessionKey)) {
|
|
||||||
throw new Exception\CsrfValidationException('Invalid CSRF token supplied.');
|
throw new Exception\CsrfValidationException('Invalid CSRF token supplied.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,11 +14,19 @@ use Throwable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* App Core Framework Version
|
* App Core Framework Version
|
||||||
|
*
|
||||||
|
* @phpstan-type VersionDetails array{
|
||||||
|
* commit: string|null,
|
||||||
|
* commit_short: string,
|
||||||
|
* commit_timestamp: int,
|
||||||
|
* commit_date: string,
|
||||||
|
* branch: string|null,
|
||||||
|
* }
|
||||||
*/
|
*/
|
||||||
final class Version
|
final class Version
|
||||||
{
|
{
|
||||||
/** @var string Version that is displayed if no Git repository information is present. */
|
/** @var string The current latest stable version. */
|
||||||
public const FALLBACK_VERSION = '0.19.4';
|
public const STABLE_VERSION = '0.19.4';
|
||||||
|
|
||||||
private string $repoDir;
|
private string $repoDir;
|
||||||
|
|
||||||
|
@ -41,19 +49,10 @@ final class Version
|
||||||
: ReleaseChannel::RollingRelease;
|
: ReleaseChannel::RollingRelease;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string The current tagged version.
|
|
||||||
*/
|
|
||||||
public function getVersion(): string
|
|
||||||
{
|
|
||||||
$details = $this->getDetails();
|
|
||||||
return $details['tag'] ?? self::FALLBACK_VERSION;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load cache or generate new repository details from the underlying Git repository.
|
* Load cache or generate new repository details from the underlying Git repository.
|
||||||
*
|
*
|
||||||
* @return string[]
|
* @return VersionDetails
|
||||||
*/
|
*/
|
||||||
public function getDetails(): array
|
public function getDetails(): array
|
||||||
{
|
{
|
||||||
|
@ -63,12 +62,16 @@ final class Version
|
||||||
$details = $this->cache->get('app_version_details');
|
$details = $this->cache->get('app_version_details');
|
||||||
|
|
||||||
if (empty($details)) {
|
if (empty($details)) {
|
||||||
$details = $this->getRawDetails();
|
$rawDetails = $this->getRawDetails();
|
||||||
|
|
||||||
$details['commit_short'] = substr($details['commit'] ?? '', 0, 7);
|
$details = [
|
||||||
|
'commit' => $rawDetails['commit'],
|
||||||
|
'commit_short' => substr($rawDetails['commit'] ?? '', 0, 7),
|
||||||
|
'branch' => $rawDetails['branch'],
|
||||||
|
];
|
||||||
|
|
||||||
if (!empty($details['commit_date_raw'])) {
|
if (!empty($rawDetails['commit_date_raw'])) {
|
||||||
$commitDate = new DateTime($details['commit_date_raw']);
|
$commitDate = new DateTime($rawDetails['commit_date_raw']);
|
||||||
$commitDate->setTimezone(new DateTimeZone('UTC'));
|
$commitDate->setTimezone(new DateTimeZone('UTC'));
|
||||||
|
|
||||||
$details['commit_timestamp'] = $commitDate->getTimestamp();
|
$details['commit_timestamp'] = $commitDate->getTimestamp();
|
||||||
|
@ -78,8 +81,6 @@ final class Version
|
||||||
$details['commit_date'] = 'N/A';
|
$details['commit_date'] = 'N/A';
|
||||||
}
|
}
|
||||||
|
|
||||||
$details['tag'] = self::FALLBACK_VERSION;
|
|
||||||
|
|
||||||
$ttl = $this->environment->isProduction() ? 86400 : 600;
|
$ttl = $this->environment->isProduction() ? 86400 : 600;
|
||||||
|
|
||||||
$this->cache->set('app_version_details', $details, $ttl);
|
$this->cache->set('app_version_details', $details, $ttl);
|
||||||
|
@ -92,7 +93,11 @@ final class Version
|
||||||
/**
|
/**
|
||||||
* Generate new repository details from the underlying Git repository.
|
* Generate new repository details from the underlying Git repository.
|
||||||
*
|
*
|
||||||
* @return mixed[]
|
* @return array{
|
||||||
|
* commit: string|null,
|
||||||
|
* commit_date_raw: string|null,
|
||||||
|
* branch: string|null
|
||||||
|
* }
|
||||||
*/
|
*/
|
||||||
private function getRawDetails(): array
|
private function getRawDetails(): array
|
||||||
{
|
{
|
||||||
|
@ -120,7 +125,11 @@ final class Version
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return [];
|
return [
|
||||||
|
'commit' => null,
|
||||||
|
'commit_date_raw' => null,
|
||||||
|
'branch' => null,
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -145,8 +154,9 @@ final class Version
|
||||||
public function getVersionText(): string
|
public function getVersionText(): string
|
||||||
{
|
{
|
||||||
$details = $this->getDetails();
|
$details = $this->getDetails();
|
||||||
|
$releaseChannel = $this->getReleaseChannelEnum();
|
||||||
|
|
||||||
if (isset($details['tag'])) {
|
if (ReleaseChannel::RollingRelease === $releaseChannel) {
|
||||||
$commitLink = 'https://github.com/AzuraCast/AzuraCast/commit/' . $details['commit'];
|
$commitLink = 'https://github.com/AzuraCast/AzuraCast/commit/' . $details['commit'];
|
||||||
$commitText = sprintf(
|
$commitText = sprintf(
|
||||||
'#<a href="%s" target="_blank">%s</a> (%s)',
|
'#<a href="%s" target="_blank">%s</a> (%s)',
|
||||||
|
@ -155,14 +165,10 @@ final class Version
|
||||||
$details['commit_date']
|
$details['commit_date']
|
||||||
);
|
);
|
||||||
|
|
||||||
$releaseChannel = $this->getReleaseChannelEnum();
|
return 'Rolling Release ' . $commitText;
|
||||||
if (ReleaseChannel::RollingRelease === $releaseChannel) {
|
|
||||||
return 'Rolling Release ' . $commitText;
|
|
||||||
}
|
|
||||||
return 'v' . $details['tag'] . ' Stable';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'v' . self::FALLBACK_VERSION . ' Release Build';
|
return 'v' . self::STABLE_VERSION . ' Stable';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -171,15 +177,20 @@ final class Version
|
||||||
public function getCommitHash(): ?string
|
public function getCommitHash(): ?string
|
||||||
{
|
{
|
||||||
$details = $this->getDetails();
|
$details = $this->getDetails();
|
||||||
return $details['commit'] ?? null;
|
return $details['commit'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string|null The shortened Git hash corresponding to the current commit.
|
* @return string The shortened Git hash corresponding to the current commit.
|
||||||
*/
|
*/
|
||||||
public function getCommitShort(): ?string
|
public function getCommitShort(): string
|
||||||
{
|
{
|
||||||
$details = $this->getDetails();
|
$details = $this->getDetails();
|
||||||
return $details['commit_short'] ?? null;
|
return $details['commit_short'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getVersion(): string
|
||||||
|
{
|
||||||
|
return self::STABLE_VERSION;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,9 @@ namespace App\Webhook\Connector;
|
||||||
use App\Container\LoggerAwareTrait;
|
use App\Container\LoggerAwareTrait;
|
||||||
use App\Entity\Api\NowPlaying\NowPlaying;
|
use App\Entity\Api\NowPlaying\NowPlaying;
|
||||||
use App\Entity\StationWebhook;
|
use App\Entity\StationWebhook;
|
||||||
use App\Utilities;
|
use App\Utilities\Arrays;
|
||||||
|
use App\Utilities\Types;
|
||||||
|
use App\Utilities\Urls;
|
||||||
use GuzzleHttp\Client;
|
use GuzzleHttp\Client;
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
use Psr\Http\Message\ResponseInterface;
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
@ -87,7 +89,7 @@ abstract class AbstractConnector implements ConnectorInterface
|
||||||
*/
|
*/
|
||||||
public function replaceVariables(array $rawVars, NowPlaying $np): array
|
public function replaceVariables(array $rawVars, NowPlaying $np): array
|
||||||
{
|
{
|
||||||
$values = Utilities\Arrays::flattenArray($np);
|
$values = Arrays::flattenArray($np);
|
||||||
$vars = [];
|
$vars = [];
|
||||||
|
|
||||||
foreach ($rawVars as $varKey => $varValue) {
|
foreach ($rawVars as $varKey => $varValue) {
|
||||||
|
@ -96,7 +98,7 @@ abstract class AbstractConnector implements ConnectorInterface
|
||||||
"/\{\{(\s*)([a-zA-Z\d\-_.]+)(\s*)}}/",
|
"/\{\{(\s*)([a-zA-Z\d\-_.]+)(\s*)}}/",
|
||||||
static function (array $matches) use ($values): string {
|
static function (array $matches) use ($values): string {
|
||||||
$innerValue = strtolower(trim($matches[2]));
|
$innerValue = strtolower(trim($matches[2]));
|
||||||
return $values[$innerValue] ?? '';
|
return Types::string($values[$innerValue] ?? '');
|
||||||
},
|
},
|
||||||
$varValue
|
$varValue
|
||||||
);
|
);
|
||||||
|
@ -110,9 +112,9 @@ abstract class AbstractConnector implements ConnectorInterface
|
||||||
*/
|
*/
|
||||||
protected function getValidUrl(mixed $urlString = null): ?string
|
protected function getValidUrl(mixed $urlString = null): ?string
|
||||||
{
|
{
|
||||||
$urlString = Utilities\Types::stringOrNull($urlString, true);
|
$urlString = Types::stringOrNull($urlString, true);
|
||||||
|
|
||||||
$uri = Utilities\Urls::tryParseUserUrl(
|
$uri = Urls::tryParseUserUrl(
|
||||||
$urlString,
|
$urlString,
|
||||||
'Webhook'
|
'Webhook'
|
||||||
);
|
);
|
||||||
|
|
|
@ -18,7 +18,7 @@ final class Mastodon extends AbstractSocialConnector
|
||||||
protected function getRateLimitTime(StationWebhook $webhook): ?int
|
protected function getRateLimitTime(StationWebhook $webhook): ?int
|
||||||
{
|
{
|
||||||
$config = $webhook->getConfig();
|
$config = $webhook->getConfig();
|
||||||
$rateLimitSeconds = (int)($config['rate_limit'] ?? 0);
|
$rateLimitSeconds = Types::int($config['rate_limit'] ?? null);
|
||||||
|
|
||||||
return max(10, $rateLimitSeconds);
|
return max(10, $rateLimitSeconds);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ ini_set('display_errors', 1);
|
||||||
|
|
||||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||||
|
|
||||||
const AZURACAST_VERSION = App\Version::FALLBACK_VERSION;
|
const AZURACAST_VERSION = App\Version::STABLE_VERSION;
|
||||||
const AZURACAST_API_URL = 'https://localhost/api';
|
const AZURACAST_API_URL = 'https://localhost/api';
|
||||||
const AZURACAST_API_NAME = 'Testing API';
|
const AZURACAST_API_NAME = 'Testing API';
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue