From bbf8d56b460d5cca9318bdefc463a44631024eef Mon Sep 17 00:00:00 2001 From: Buster Neece Date: Sun, 14 Jan 2024 13:20:01 -0600 Subject: [PATCH] More type fixes! --- bin/installer | 2 +- config/services.php | 4 + src/Acl.php | 25 ++++++- src/Auth.php | 7 +- src/Cache/NowPlayingCache.php | 29 +++++--- .../Command/GenerateApiDocsCommand.php | 2 +- .../Api/Admin/Stations/CloneAction.php | 3 +- .../Api/Stations/BulkMedia/DownloadAction.php | 1 + .../Api/Stations/Files/BatchAction.php | 9 ++- .../Api/Stations/Files/DownloadAction.php | 3 +- .../Api/Stations/Files/FlowUploadAction.php | 3 +- .../Api/Stations/Files/ListAction.php | 8 +- src/Controller/Api/Traits/CanSortResults.php | 4 +- src/Controller/Api/Traits/HasMediaSearch.php | 5 +- src/Entity/Api/BatchResult.php | 2 + src/Event/BuildPermissions.php | 12 ++- src/Media/RemoteAlbumArt.php | 2 +- src/Service/AzuraCastCentral.php | 2 +- src/Service/Dropbox/OAuthAdapter.php | 3 +- src/Service/LastFm.php | 2 +- src/Service/MusicBrainz.php | 4 +- src/Session/Csrf.php | 12 +-- src/Version.php | 73 +++++++++++-------- src/Webhook/Connector/AbstractConnector.php | 12 +-- src/Webhook/Connector/Mastodon.php | 2 +- util/phpstan.php | 2 +- 26 files changed, 149 insertions(+), 84 deletions(-) diff --git a/bin/installer b/bin/installer index 9664a5778..f4ac2e8ef 100755 --- a/bin/installer +++ b/bin/installer @@ -12,7 +12,7 @@ $environment = App\AppFactory::buildEnvironment(); $console = new Symfony\Component\Console\Application( 'AzuraCast installer', - App\Version::FALLBACK_VERSION + App\Version::STABLE_VERSION ); $installCommand = new App\Installer\Command\InstallCommand(); diff --git a/config/services.php b/config/services.php index b4454042c..b7a92b3e5 100644 --- a/config/services.php +++ b/config/services.php @@ -330,6 +330,10 @@ return [ // Register plugin-provided message queue receivers $receivers = $plugins->registerMessageQueueReceivers($receivers); + /** + * @var class-string $messageClass + * @var class-string $handlerClass + */ foreach ($receivers as $messageClass => $handlerClass) { $handlers[$messageClass][] = static function ($message) use ($handlerClass, $di) { $obj = $di->get($handlerClass); diff --git a/src/Acl.php b/src/Acl.php index 8cf819f0d..646043566 100644 --- a/src/Acl.php +++ b/src/Acl.php @@ -19,12 +19,30 @@ use Psr\EventDispatcher\EventDispatcherInterface; use function in_array; use function is_array; +/** + * @phpstan-type PermissionsArray array{ + * global: array, + * station: array + * } + */ final class Acl { use RequestAwareTrait; + /** + * @var PermissionsArray + */ private array $permissions; + /** + * @var null|array< + * int, + * array{ + * stations?: array>, + * global?: array + * } + * > + */ private ?array $actions; public function __construct( @@ -41,12 +59,12 @@ final class Acl { $sql = $this->em->createQuery( <<<'DQL' - SELECT rp FROM App\Entity\RolePermission rp + SELECT rp.station_id, rp.role_id, rp.action_name FROM App\Entity\RolePermission rp DQL ); $this->actions = []; - foreach ($sql->getArrayResult() as $row) { + foreach ($sql->toIterable() as $row) { if ($row['station_id']) { $this->actions[$row['role_id']]['stations'][$row['station_id']][] = $row['action_name']; } else { @@ -69,12 +87,11 @@ final class Acl } /** - * @return mixed[] + * @return array */ public function listPermissions(): array { if (!isset($this->permissions)) { - /** @var array> $permissions */ $permissions = [ 'global' => [], 'station' => [], diff --git a/src/Auth.php b/src/Auth.php index a2102b173..bb9f59032 100644 --- a/src/Auth.php +++ b/src/Auth.php @@ -8,6 +8,7 @@ use App\Container\EnvironmentAwareTrait; use App\Entity\Repository\UserRepository; use App\Entity\User; use App\Exception\NotLoggedInException; +use App\Utilities\Types; use Mezzio\Session\SessionInterface; final class Auth @@ -83,7 +84,7 @@ final class Auth if (!$this->session->has(self::SESSION_MASQUERADE_USER_ID_KEY)) { $this->masqueraded_user = false; } 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) { $user = $this->userRepo->getRepository()->find($maskUserId); } else { @@ -125,7 +126,7 @@ final class Auth */ 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 { 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) { $this->user = false; diff --git a/src/Cache/NowPlayingCache.php b/src/Cache/NowPlayingCache.php index b71e6d0e1..953dc4880 100644 --- a/src/Cache/NowPlayingCache.php +++ b/src/Cache/NowPlayingCache.php @@ -6,6 +6,7 @@ namespace App\Cache; use App\Entity\Api\NowPlaying\NowPlaying; use App\Entity\Station; +use App\Utilities\Types; use Psr\Cache\CacheItemInterface; use Psr\Cache\CacheItemPoolInterface; @@ -41,9 +42,13 @@ final class NowPlayingCache $stationCacheItem = $this->getStationCache($station); - return ($stationCacheItem->isHit()) - ? $stationCacheItem->get() - : null; + if (!$stationCacheItem->isHit()) { + return null; + } + + $np = $stationCacheItem->get(); + assert($np instanceof NowPlaying); + return $np; } /** @@ -78,11 +83,18 @@ final class NowPlayingCache return $np; } + /** + * @return array + */ public function getLookup(): array { $lookupCacheItem = $this->getLookupCache(); return $lookupCacheItem->isHit() - ? (array)$lookupCacheItem->get() + ? Types::array($lookupCacheItem->get()) : []; } @@ -114,7 +126,7 @@ final class NowPlayingCache $lookupCacheItem = $this->getLookupCache(); $lookupCache = $lookupCacheItem->isHit() - ? (array)$lookupCacheItem->get() + ? Types::array($lookupCacheItem->get()) : []; $lookupCache[$station->getIdRequired()] = [ @@ -131,12 +143,9 @@ final class NowPlayingCache private function getStationCache(string $identifier): CacheItemInterface { if (is_numeric($identifier)) { - $lookupCacheItem = $this->getLookupCache(); - $lookupCache = $lookupCacheItem->isHit() - ? (array)$lookupCacheItem->get() - : []; + $lookupCache = $this->getLookup(); - $identifier = (int)$identifier; + $identifier = Types::int($identifier); if (isset($lookupCache[$identifier])) { $identifier = $lookupCache[$identifier]['short_name']; } diff --git a/src/Console/Command/GenerateApiDocsCommand.php b/src/Console/Command/GenerateApiDocsCommand.php index b25299ac6..9c353dea9 100644 --- a/src/Console/Command/GenerateApiDocsCommand.php +++ b/src/Console/Command/GenerateApiDocsCommand.php @@ -51,7 +51,7 @@ final class GenerateApiDocsCommand extends CommandAbstract define('AZURACAST_API_NAME', 'AzuraCast Public Demo Server'); define( 'AZURACAST_VERSION', - $useCurrentVersion ? $this->version->getVersion() : Version::FALLBACK_VERSION + $useCurrentVersion ? $this->version->getVersion() : Version::STABLE_VERSION ); $finder = Util::finder( diff --git a/src/Controller/Api/Admin/Stations/CloneAction.php b/src/Controller/Api/Admin/Stations/CloneAction.php index cd6737149..c85f963aa 100644 --- a/src/Controller/Api/Admin/Stations/CloneAction.php +++ b/src/Controller/Api/Admin/Stations/CloneAction.php @@ -206,7 +206,8 @@ final class CloneAction extends StationsController implements SingleActionInterf } /** - * @param Collection $collection + * @template T of mixed + * @param Collection $collection */ private function cloneCollection( Collection $collection, diff --git a/src/Controller/Api/Stations/BulkMedia/DownloadAction.php b/src/Controller/Api/Stations/BulkMedia/DownloadAction.php index df7731dfa..ec4362f86 100644 --- a/src/Controller/Api/Stations/BulkMedia/DownloadAction.php +++ b/src/Controller/Api/Stations/BulkMedia/DownloadAction.php @@ -86,6 +86,7 @@ final class DownloadAction implements SingleActionInterface $csv->insertOne($headerRow); + /** @var array $row */ foreach ($query->getArrayResult() as $row) { $customFieldsById = []; foreach ($row['custom_fields'] ?? [] as $rowCustomField) { diff --git a/src/Controller/Api/Stations/Files/BatchAction.php b/src/Controller/Api/Stations/Files/BatchAction.php index 6fd7959cc..c95fe0029 100644 --- a/src/Controller/Api/Stations/Files/BatchAction.php +++ b/src/Controller/Api/Stations/Files/BatchAction.php @@ -28,6 +28,7 @@ use App\Radio\Backend\Liquidsoap; use App\Radio\Enums\BackendAdapters; use App\Radio\Enums\LiquidsoapQueues; use App\Utilities\File; +use App\Utilities\Types; use Exception; use InvalidArgumentException; use League\Flysystem\StorageAttributes; @@ -411,8 +412,12 @@ final class BatchAction implements SingleActionInterface ExtendedFilesystemInterface $fs, bool $recursive = false ): BatchResult { - $files = array_values((array)$request->getParam('files', [])); - $directories = array_values((array)$request->getParam('dirs', [])); + $files = array_values( + Types::array($request->getParam('files', [])) + ); + $directories = array_values( + Types::array($request->getParam('dirs', [])) + ); if ($recursive) { foreach ($directories as $dir) { diff --git a/src/Controller/Api/Stations/Files/DownloadAction.php b/src/Controller/Api/Stations/Files/DownloadAction.php index caf4f6cb1..7a88e7422 100644 --- a/src/Controller/Api/Stations/Files/DownloadAction.php +++ b/src/Controller/Api/Stations/Files/DownloadAction.php @@ -9,6 +9,7 @@ use App\Entity\Api\Error; use App\Flysystem\StationFilesystems; use App\Http\Response; use App\Http\ServerRequest; +use App\Utilities\Types; use Psr\Http\Message\ResponseInterface; final class DownloadAction implements SingleActionInterface @@ -29,7 +30,7 @@ final class DownloadAction implements SingleActionInterface $fsMedia = $this->stationFilesystems->getMediaFilesystem($station); - $path = $request->getParam('file'); + $path = Types::string($request->getParam('file')); if (!$fsMedia->fileExists($path)) { return $response->withStatus(404) diff --git a/src/Controller/Api/Stations/Files/FlowUploadAction.php b/src/Controller/Api/Stations/Files/FlowUploadAction.php index 76f58395a..aa26932d4 100644 --- a/src/Controller/Api/Stations/Files/FlowUploadAction.php +++ b/src/Controller/Api/Stations/Files/FlowUploadAction.php @@ -20,6 +20,7 @@ use App\Http\Response; use App\Http\ServerRequest; use App\Media\MediaProcessor; use App\Service\Flow; +use App\Utilities\Types; use Psr\Http\Message\ResponseInterface; final class FlowUploadAction implements SingleActionInterface @@ -51,7 +52,7 @@ final class FlowUploadAction implements SingleActionInterface return $flowResponse; } - $currentDir = $request->getParam('currentDirectory', ''); + $currentDir = Types::string($request->getParam('currentDirectory')); $destPath = $flowResponse->getClientFilename(); if (!empty($currentDir)) { diff --git a/src/Controller/Api/Stations/Files/ListAction.php b/src/Controller/Api/Stations/Files/ListAction.php index 0a116a21b..3408450c9 100644 --- a/src/Controller/Api/Stations/Files/ListAction.php +++ b/src/Controller/Api/Stations/Files/ListAction.php @@ -52,10 +52,10 @@ final class ListAction implements SingleActionInterface $fs = $this->stationFilesystems->getMediaFilesystem($station); - $currentDir = $request->getParam('currentDirectory', ''); + $currentDir = Types::string($request->getParam('currentDirectory')); - $searchPhraseFull = trim($request->getParam('searchPhrase', '')); - $isSearch = !empty($searchPhraseFull); + $searchPhraseFull = Types::stringOrNull($request->getParam('searchPhrase'), true); + $isSearch = null !== $searchPhraseFull; [$searchPhrase, $playlist, $special] = $this->parseSearchQuery( $station, @@ -74,7 +74,7 @@ final class ListAction implements SingleActionInterface $cacheKey = implode('.', $cacheKeyParts); - $flushCache = (bool)$request->getParam('flushCache', false); + $flushCache = Types::bool($request->getParam('flushCache')); if (!$flushCache && $this->cache->has($cacheKey)) { /** @var array $result */ diff --git a/src/Controller/Api/Traits/CanSortResults.php b/src/Controller/Api/Traits/CanSortResults.php index a9bcc2b47..5275b3165 100644 --- a/src/Controller/Api/Traits/CanSortResults.php +++ b/src/Controller/Api/Traits/CanSortResults.php @@ -61,7 +61,7 @@ trait CanSortResults } /** - * @return array{string, string} + * @return array{string|null, Criteria::ASC|Criteria::DESC} */ protected function getSortFromRequest( ServerRequest $request, @@ -69,7 +69,7 @@ trait CanSortResults ): array { $sortOrder = Types::stringOrNull($request->getParam('sortOrder'), true) ?? $defaultSortOrder; return [ - $request->getParam('sort'), + Types::stringOrNull($request->getParam('sort'), true), (Criteria::DESC === strtoupper($sortOrder)) ? Criteria::DESC : Criteria::ASC, diff --git a/src/Controller/Api/Traits/HasMediaSearch.php b/src/Controller/Api/Traits/HasMediaSearch.php index 02fa42a68..f5d38e373 100644 --- a/src/Controller/Api/Traits/HasMediaSearch.php +++ b/src/Controller/Api/Traits/HasMediaSearch.php @@ -41,10 +41,9 @@ trait HasMediaSearch FROM App\Entity\StationPlaylist sp WHERE sp.station = :station DQL - )->setParameter('station', $station) - ->getArrayResult(); + )->setParameter('station', $station); - foreach ($playlistNameLookupRaw as $playlistRow) { + foreach ($playlistNameLookupRaw->toIterable() as $playlistRow) { $shortName = StationPlaylist::generateShortName($playlistRow['name']); if ($shortName === $playlistId) { $playlistId = $playlistRow['id']; diff --git a/src/Entity/Api/BatchResult.php b/src/Entity/Api/BatchResult.php index 81fa02edf..876ea2611 100644 --- a/src/Entity/Api/BatchResult.php +++ b/src/Entity/Api/BatchResult.php @@ -8,8 +8,10 @@ use JsonSerializable; final class BatchResult implements JsonSerializable { + /** @var string[] */ public array $files = []; + /** @var string[] */ public array $directories = []; public array $errors = []; diff --git a/src/Event/BuildPermissions.php b/src/Event/BuildPermissions.php index c7fc4482e..e5a6e4f87 100644 --- a/src/Event/BuildPermissions.php +++ b/src/Event/BuildPermissions.php @@ -4,23 +4,33 @@ declare(strict_types=1); namespace App\Event; +use App\Acl; use Symfony\Contracts\EventDispatcher\Event; +/** + * @phpstan-import-type PermissionsArray from Acl + */ final class BuildPermissions extends Event { + /** + * @param PermissionsArray $permissions + */ public function __construct( private array $permissions ) { } /** - * @return mixed[] + * @return PermissionsArray */ public function getPermissions(): array { return $this->permissions; } + /** + * @param PermissionsArray $permissions + */ public function setPermissions(array $permissions): void { $this->permissions = $permissions; diff --git a/src/Media/RemoteAlbumArt.php b/src/Media/RemoteAlbumArt.php index 47b6f6925..f1e2be46c 100644 --- a/src/Media/RemoteAlbumArt.php +++ b/src/Media/RemoteAlbumArt.php @@ -56,7 +56,7 @@ final class RemoteAlbumArt [ RequestOptions::TIMEOUT => 10, RequestOptions::HEADERS => [ - 'User-Agent' => 'AzuraCast ' . Version::FALLBACK_VERSION, + 'User-Agent' => 'AzuraCast ' . Version::STABLE_VERSION, ], ] ); diff --git a/src/Service/AzuraCastCentral.php b/src/Service/AzuraCastCentral.php index 21dfdccf4..12a2228de 100644 --- a/src/Service/AzuraCastCentral.php +++ b/src/Service/AzuraCastCentral.php @@ -43,7 +43,7 @@ final class AzuraCastCentral if ($commitHash) { $requestBody['version'] = $commitHash; } else { - $requestBody['release'] = Version::FALLBACK_VERSION; + $requestBody['release'] = Version::STABLE_VERSION; } $this->logger->debug( diff --git a/src/Service/Dropbox/OAuthAdapter.php b/src/Service/Dropbox/OAuthAdapter.php index 1fe630736..7e229a4ad 100644 --- a/src/Service/Dropbox/OAuthAdapter.php +++ b/src/Service/Dropbox/OAuthAdapter.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace App\Service\Dropbox; use App\Entity\StorageLocation; +use App\Utilities\Types; use GuzzleHttp\Exception\ClientException; use Psr\Cache\CacheItemPoolInterface; use Spatie\Dropbox\RefreshableTokenProvider; @@ -80,7 +81,7 @@ final class OAuthAdapter implements RefreshableTokenProvider $this->psr6Cache->save($cacheItem); } - return $cacheItem->get(); + return Types::string($cacheItem->get()); } private function getOauthProvider(): OAuthProvider diff --git a/src/Service/LastFm.php b/src/Service/LastFm.php index 7b7d3cd77..10fe97527 100644 --- a/src/Service/LastFm.php +++ b/src/Service/LastFm.php @@ -81,7 +81,7 @@ final class LastFm [ RequestOptions::HTTP_ERRORS => true, RequestOptions::HEADERS => [ - 'User-Agent' => 'AzuraCast ' . Version::FALLBACK_VERSION, + 'User-Agent' => 'AzuraCast ' . Version::STABLE_VERSION, 'Accept' => 'application/json', ], RequestOptions::QUERY => $query, diff --git a/src/Service/MusicBrainz.php b/src/Service/MusicBrainz.php index 2330cccf9..240a1ad3b 100644 --- a/src/Service/MusicBrainz.php +++ b/src/Service/MusicBrainz.php @@ -65,7 +65,7 @@ final class MusicBrainz RequestOptions::TIMEOUT => 7, RequestOptions::HTTP_ERRORS => true, RequestOptions::HEADERS => [ - 'User-Agent' => 'AzuraCast ' . Version::FALLBACK_VERSION, + 'User-Agent' => 'AzuraCast ' . Version::STABLE_VERSION, 'Accept' => 'application/json', ], RequestOptions::QUERY => $query, @@ -157,7 +157,7 @@ final class MusicBrainz [ RequestOptions::ALLOW_REDIRECTS => true, RequestOptions::HEADERS => [ - 'User-Agent' => 'AzuraCast ' . Version::FALLBACK_VERSION, + 'User-Agent' => 'AzuraCast ' . Version::STABLE_VERSION, 'Accept' => 'application/json', ], ] diff --git a/src/Session/Csrf.php b/src/Session/Csrf.php index 217b50630..900e48913 100644 --- a/src/Session/Csrf.php +++ b/src/Session/Csrf.php @@ -6,6 +6,7 @@ namespace App\Session; use App\Environment; use App\Exception; +use App\Utilities\Types; use Mezzio\Session\SessionInterface; final class Csrf @@ -32,9 +33,9 @@ final class Csrf { $sessionKey = $this->getSessionIdentifier($namespace); if ($this->session->has($sessionKey)) { - $csrf = $this->session->get($sessionKey); - if (!empty($csrf)) { - return (string)$csrf; + $csrf = Types::stringOrNull($this->session->get($sessionKey), true); + if (null !== $csrf) { + return $csrf; } } @@ -71,9 +72,8 @@ final class Csrf throw new Exception\CsrfValidationException('No CSRF token supplied for this namespace.'); } - $sessionKey = $this->session->get($sessionIdentifier); - - if (0 !== strcmp($key, (string)$sessionKey)) { + $sessionKey = Types::string($this->session->get($sessionIdentifier)); + if (0 !== strcmp($key, $sessionKey)) { throw new Exception\CsrfValidationException('Invalid CSRF token supplied.'); } } diff --git a/src/Version.php b/src/Version.php index 0a200ce1b..bcef40618 100644 --- a/src/Version.php +++ b/src/Version.php @@ -14,11 +14,19 @@ use Throwable; /** * 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 { - /** @var string Version that is displayed if no Git repository information is present. */ - public const FALLBACK_VERSION = '0.19.4'; + /** @var string The current latest stable version. */ + public const STABLE_VERSION = '0.19.4'; private string $repoDir; @@ -41,19 +49,10 @@ final class Version : 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. * - * @return string[] + * @return VersionDetails */ public function getDetails(): array { @@ -63,12 +62,16 @@ final class Version $details = $this->cache->get('app_version_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'])) { - $commitDate = new DateTime($details['commit_date_raw']); + if (!empty($rawDetails['commit_date_raw'])) { + $commitDate = new DateTime($rawDetails['commit_date_raw']); $commitDate->setTimezone(new DateTimeZone('UTC')); $details['commit_timestamp'] = $commitDate->getTimestamp(); @@ -78,8 +81,6 @@ final class Version $details['commit_date'] = 'N/A'; } - $details['tag'] = self::FALLBACK_VERSION; - $ttl = $this->environment->isProduction() ? 86400 : 600; $this->cache->set('app_version_details', $details, $ttl); @@ -92,7 +93,11 @@ final class Version /** * 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 { @@ -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 { $details = $this->getDetails(); + $releaseChannel = $this->getReleaseChannelEnum(); - if (isset($details['tag'])) { + if (ReleaseChannel::RollingRelease === $releaseChannel) { $commitLink = 'https://github.com/AzuraCast/AzuraCast/commit/' . $details['commit']; $commitText = sprintf( '#%s (%s)', @@ -155,14 +165,10 @@ final class Version $details['commit_date'] ); - $releaseChannel = $this->getReleaseChannelEnum(); - if (ReleaseChannel::RollingRelease === $releaseChannel) { - return 'Rolling Release ' . $commitText; - } - return 'v' . $details['tag'] . ' Stable'; + return 'Rolling Release ' . $commitText; } - return 'v' . self::FALLBACK_VERSION . ' Release Build'; + return 'v' . self::STABLE_VERSION . ' Stable'; } /** @@ -171,15 +177,20 @@ final class Version public function getCommitHash(): ?string { $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(); - return $details['commit_short'] ?? null; + return $details['commit_short']; + } + + public function getVersion(): string + { + return self::STABLE_VERSION; } } diff --git a/src/Webhook/Connector/AbstractConnector.php b/src/Webhook/Connector/AbstractConnector.php index 05ab55758..dfcfc2db6 100644 --- a/src/Webhook/Connector/AbstractConnector.php +++ b/src/Webhook/Connector/AbstractConnector.php @@ -7,7 +7,9 @@ namespace App\Webhook\Connector; use App\Container\LoggerAwareTrait; use App\Entity\Api\NowPlaying\NowPlaying; use App\Entity\StationWebhook; -use App\Utilities; +use App\Utilities\Arrays; +use App\Utilities\Types; +use App\Utilities\Urls; use GuzzleHttp\Client; use InvalidArgumentException; use Psr\Http\Message\ResponseInterface; @@ -87,7 +89,7 @@ abstract class AbstractConnector implements ConnectorInterface */ public function replaceVariables(array $rawVars, NowPlaying $np): array { - $values = Utilities\Arrays::flattenArray($np); + $values = Arrays::flattenArray($np); $vars = []; foreach ($rawVars as $varKey => $varValue) { @@ -96,7 +98,7 @@ abstract class AbstractConnector implements ConnectorInterface "/\{\{(\s*)([a-zA-Z\d\-_.]+)(\s*)}}/", static function (array $matches) use ($values): string { $innerValue = strtolower(trim($matches[2])); - return $values[$innerValue] ?? ''; + return Types::string($values[$innerValue] ?? ''); }, $varValue ); @@ -110,9 +112,9 @@ abstract class AbstractConnector implements ConnectorInterface */ 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, 'Webhook' ); diff --git a/src/Webhook/Connector/Mastodon.php b/src/Webhook/Connector/Mastodon.php index de2437a87..cc7b42527 100644 --- a/src/Webhook/Connector/Mastodon.php +++ b/src/Webhook/Connector/Mastodon.php @@ -18,7 +18,7 @@ final class Mastodon extends AbstractSocialConnector protected function getRateLimitTime(StationWebhook $webhook): ?int { $config = $webhook->getConfig(); - $rateLimitSeconds = (int)($config['rate_limit'] ?? 0); + $rateLimitSeconds = Types::int($config['rate_limit'] ?? null); return max(10, $rateLimitSeconds); } diff --git a/util/phpstan.php b/util/phpstan.php index c50fdd51f..5ac271b18 100644 --- a/util/phpstan.php +++ b/util/phpstan.php @@ -8,7 +8,7 @@ ini_set('display_errors', 1); 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_NAME = 'Testing API';