diff --git a/index.php b/index.php index ca9a24a5..0aa93974 100644 --- a/index.php +++ b/index.php @@ -60,7 +60,7 @@ $checkedConfig = ConfigType::check($configArray); // First look in app config, then PHP config, and at last // resort, just set to UTC. $timezone = ini_get('date.timezone'); -if (array_key_exists('timezone', $checkedConfig) && ! empty($checkedConfig['timezone'])) +if (is_array($checkedConfig) && array_key_exists('timezone', $checkedConfig) && ! empty($checkedConfig['timezone'])) { date_default_timezone_set($checkedConfig['timezone']); } diff --git a/phpstan.neon b/phpstan.neon index 2fa40512..5a474a6a 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -12,6 +12,7 @@ parameters: - '#Function imagepalletetotruecolor not found#' - '#Call to an undefined method Aura\\\Html\\\HelperLocator::[a-zA-Z0-9_]+\(\)#' - '#Call to an undefined method Query\\QueryBuilderInterface::[a-zA-Z0-9_]+\(\)#' + - '#Unable to resolve the template type TValue#' excludes_analyse: - tests/mocks.php - vendor diff --git a/src/AnimeClient/API/APIRequestBuilder.php b/src/AnimeClient/API/APIRequestBuilder.php index 8b832090..631b43a6 100644 --- a/src/AnimeClient/API/APIRequestBuilder.php +++ b/src/AnimeClient/API/APIRequestBuilder.php @@ -193,12 +193,11 @@ abstract class APIRequestBuilder { * Set the request body * * @param mixed $body - * @throws \TypeError * @return self */ - public function setJsonBody($body): self + public function setJsonBody(mixed $body): self { - $requestBody = ( ! is_scalar($body)) + $requestBody = ( ! is_string($body)) ? Json::encode($body) : $body; diff --git a/src/AnimeClient/API/Anilist/ListItem.php b/src/AnimeClient/API/Anilist/ListItem.php index 3910d145..b4b17d74 100644 --- a/src/AnimeClient/API/Anilist/ListItem.php +++ b/src/AnimeClient/API/Anilist/ListItem.php @@ -38,7 +38,7 @@ final class ListItem extends AbstractListItem { public function create(array $data): Request { $checkedData = Types\MediaListEntry::check($data); - return $this->requestBuilder->mutateRequest('CreateMediaListEntry', $checkedData); + return $this->requestBuilder->mutateRequest('CreateMediaListEntry', $checkedData ?? []); } /** @@ -50,7 +50,7 @@ final class ListItem extends AbstractListItem { public function createFull(array $data): Request { $checkedData = Types\MediaListEntry::check($data); - return $this->requestBuilder->mutateRequest('CreateFullMediaListEntry', $checkedData); + return $this->requestBuilder->mutateRequest('CreateFullMediaListEntry', $checkedData ?? []); } /** @@ -90,7 +90,7 @@ final class ListItem extends AbstractListItem { 'progress' => $data->progress, ]); - return $this->requestBuilder->mutateRequest('IncrementMediaListEntry', $checkedData); + return $this->requestBuilder->mutateRequest('IncrementMediaListEntry', $checkedData ?? []); } /** @@ -120,6 +120,6 @@ final class ListItem extends AbstractListItem { 'notes' => $notes, ]); - return $this->requestBuilder->mutateRequest('UpdateMediaListEntry', $updateData); + return $this->requestBuilder->mutateRequest('UpdateMediaListEntry', $updateData ?? []); } } \ No newline at end of file diff --git a/src/AnimeClient/API/Anilist/Model.php b/src/AnimeClient/API/Anilist/Model.php index 22f5df16..00e3e71a 100644 --- a/src/AnimeClient/API/Anilist/Model.php +++ b/src/AnimeClient/API/Anilist/Model.php @@ -190,6 +190,10 @@ final class Model public function getListItem(string $malId, string $type): array { $id = $this->getListIdFromMalId($malId, $type); + if ($id === NULL) + { + return []; + } $data = $this->listItem->get($id)['data']; diff --git a/src/AnimeClient/API/Anilist/RequestBuilder.php b/src/AnimeClient/API/Anilist/RequestBuilder.php index a7f4c1e8..6c30d6ab 100644 --- a/src/AnimeClient/API/Anilist/RequestBuilder.php +++ b/src/AnimeClient/API/Anilist/RequestBuilder.php @@ -205,13 +205,16 @@ final class RequestBuilder extends APIRequestBuilder { $request = $this->setUpRequest($url, $options); $response = getResponse($request); - $logger->debug('Anilist response', [ - 'status' => $response->getStatus(), - 'reason' => $response->getReason(), - 'body' => $response->getBody(), - 'headers' => $response->getHeaders(), - 'requestHeaders' => $request->getHeaders(), - ]); + if ($logger !== NULL) + { + $logger->debug('Anilist response', [ + 'status' => $response->getStatus(), + 'reason' => $response->getReason(), + 'body' => $response->getBody(), + 'headers' => $response->getHeaders(), + 'requestHeaders' => $request->getHeaders(), + ]); + } return $response; } @@ -227,13 +230,16 @@ final class RequestBuilder extends APIRequestBuilder { $response = getResponse($request); - $logger->debug('Anilist response', [ - 'status' => $response->getStatus(), - 'reason' => $response->getReason(), - 'body' => $response->getBody(), - 'headers' => $response->getHeaders(), - 'requestHeaders' => $request->getHeaders(), - ]); + if ($logger !== NULL) + { + $logger->debug('Anilist response', [ + 'status' => $response->getStatus(), + 'reason' => $response->getReason(), + 'body' => $response->getBody(), + 'headers' => $response->getHeaders(), + 'requestHeaders' => $request->getHeaders(), + ]); + } return $response; } @@ -251,17 +257,24 @@ final class RequestBuilder extends APIRequestBuilder { $validResponseCodes = [200, 201]; $logger = $this->container->getLogger('anilist-request'); - $logger->debug('Anilist response', [ - 'status' => $response->getStatus(), - 'reason' => $response->getReason(), - 'body' => $response->getBody(), - 'headers' => $response->getHeaders(), - //'requestHeaders' => $request->getHeaders(), - ]); + if ($logger !== NULL) + { + $logger->debug('Anilist response', [ + 'status' => $response->getStatus(), + 'reason' => $response->getReason(), + 'body' => $response->getBody(), + 'headers' => $response->getHeaders(), + //'requestHeaders' => $request->getHeaders(), + ]); + } + if ( ! \in_array($response->getStatus(), $validResponseCodes, TRUE)) { - $logger->warning('Non 200 response for POST api call', (array)$response->getBody()); + if ($logger !== NULL) + { + $logger->warning('Non 200 response for POST api call', (array)$response->getBody()); + } } $rawBody = wait($response->getBody()->buffer()); diff --git a/src/AnimeClient/API/CacheTrait.php b/src/AnimeClient/API/CacheTrait.php index a7c0d111..c8726a78 100644 --- a/src/AnimeClient/API/CacheTrait.php +++ b/src/AnimeClient/API/CacheTrait.php @@ -62,10 +62,11 @@ trait CacheTrait { */ public function getCached(string $key, callable $primer, ?array $primeArgs = []): mixed { - $value = $this->cache->get($key, NULL); + $value = $this->cache->get($key); if ($value === NULL) { + $primeArgs ??= []; $value = $primer(...$primeArgs); if ($value === NULL) { diff --git a/src/AnimeClient/API/Kitsu/ListItem.php b/src/AnimeClient/API/Kitsu/ListItem.php index 40d7cfa4..64837edb 100644 --- a/src/AnimeClient/API/Kitsu/ListItem.php +++ b/src/AnimeClient/API/Kitsu/ListItem.php @@ -166,11 +166,6 @@ final class ListItem extends AbstractListItem { return $this->requestBuilder->mutateRequest('UpdateLibraryItem', $updateData); } - /** - * @return bool|string - * @throws ContainerException - * @throws NotFoundException - */ private function getAuthHeader(): ?string { $auth = $this->getContainer()->get('auth'); diff --git a/src/AnimeClient/API/Kitsu/Model.php b/src/AnimeClient/API/Kitsu/Model.php index c91e7633..60123ab5 100644 --- a/src/AnimeClient/API/Kitsu/Model.php +++ b/src/AnimeClient/API/Kitsu/Model.php @@ -89,9 +89,9 @@ final class Model { * * @param string $username * @param string $password - * @return bool|array + * @return array|false */ - public function authenticate(string $username, string $password) + public function authenticate(string $username, string $password): array|false { // K::AUTH_URL $response = $this->requestBuilder->getResponse('POST', K::AUTH_URL, [ @@ -131,9 +131,9 @@ final class Model { * Extend the current session with a refresh token * * @param string $token - * @return bool|array + * @return array|false */ - public function reAuthenticate(string $token) + public function reAuthenticate(string $token): array|false { $response = $this->requestBuilder->getResponse('POST', K::AUTH_URL, [ 'headers' => [ @@ -617,6 +617,7 @@ final class Model { } /** + * * Get the data to sync Kitsu anime/manga list with another API * * @param string $type @@ -708,11 +709,9 @@ final class Model { $page = $data['pageInfo']; if (empty($data)) { + // @TODO Proper Error logging dump($rawData); die(); - - // @TODO Error logging - break; } $cursor = $page['endCursor']; @@ -812,7 +811,7 @@ final class Model { }); } - private function getPages(callable $method, mixed ...$args): ?Generator + private function getPages(callable $method, mixed ...$args): Generator { $items = $method(...$args); diff --git a/src/AnimeClient/API/Kitsu/RequestBuilder.php b/src/AnimeClient/API/Kitsu/RequestBuilder.php index 999b0794..4e234207 100644 --- a/src/AnimeClient/API/Kitsu/RequestBuilder.php +++ b/src/AnimeClient/API/Kitsu/RequestBuilder.php @@ -144,7 +144,10 @@ final class RequestBuilder extends APIRequestBuilder { if ( ! \in_array($response->getStatus(), $validResponseCodes, TRUE)) { $logger = $this->container->getLogger('kitsu-graphql'); - $logger->warning('Non 200 response for GraphQL call', (array)$response->getBody()); + if ($logger !== NULL) + { + $logger->warning('Non 200 response for GraphQL call', (array)$response->getBody()); + } } return Json::decode(wait($response->getBody()->buffer())); @@ -166,7 +169,10 @@ final class RequestBuilder extends APIRequestBuilder { if ( ! \in_array($response->getStatus(), $validResponseCodes, TRUE)) { $logger = $this->container->getLogger('kitsu-graphql'); - $logger->warning('Non 200 response for GraphQL call', (array)$response->getBody()); + if ($logger !== NULL) + { + $logger->warning('Non 200 response for GraphQL call', (array)$response->getBody()); + } } return Json::decode(wait($response->getBody()->buffer())); @@ -186,13 +192,16 @@ final class RequestBuilder extends APIRequestBuilder { $request = $this->setUpRequest($type, $url, $options); $response = getResponse($request); - $logger->debug('Kitsu API Response', [ - 'status' => $response->getStatus(), - 'reason' => $response->getReason(), - 'body' => $response->getBody(), - 'headers' => $response->getHeaders(), - 'requestHeaders' => $request->getHeaders(), - ]); + if ($logger !== NULL) + { + $logger->debug('Kitsu API Response', [ + 'status' => $response->getStatus(), + 'reason' => $response->getReason(), + 'body' => $response->getBody(), + 'headers' => $response->getHeaders(), + 'requestHeaders' => $request->getHeaders(), + ]); + } return $response; } @@ -289,7 +298,10 @@ final class RequestBuilder extends APIRequestBuilder { // Any other type of failed request if ($statusCode > 299 || $statusCode < 200) { - $logger->warning('Non 2xx response for api call', (array)$response); + if ($logger !== NULL) + { + $logger->warning('Non 2xx response for api call', (array)$response); + } } try diff --git a/src/AnimeClient/API/Kitsu/Transformer/AnimeTransformer.php b/src/AnimeClient/API/Kitsu/Transformer/AnimeTransformer.php index 53c62e27..1a2caf00 100644 --- a/src/AnimeClient/API/Kitsu/Transformer/AnimeTransformer.php +++ b/src/AnimeClient/API/Kitsu/Transformer/AnimeTransformer.php @@ -43,7 +43,7 @@ final class AnimeTransformer extends AbstractTransformer { sort($genres); - $title = $base['titles']['canonical']; + $title = $base['titles']['canonical'] ?? ''; $titles = Kitsu::getTitles($base['titles']); $titles_more = Kitsu::filterLocalizedTitles($base['titles']); diff --git a/src/AnimeClient/Command/SyncLists.php b/src/AnimeClient/Command/SyncLists.php index 427ec829..cb062b02 100644 --- a/src/AnimeClient/Command/SyncLists.php +++ b/src/AnimeClient/Command/SyncLists.php @@ -727,7 +727,7 @@ final class SyncLists extends BaseCommand { $this->echoWarning("Skipped creating Kitsu {$type} due to missing id ¯\_(ツ)_/¯"); continue; } - $requester->addRequest($this->kitsuModel->createListItem($item)); + $requester->addRequest($maybeRequest); } } @@ -785,9 +785,11 @@ final class SyncLists extends BaseCommand { { if ($action === SyncAction::UPDATE) { - $requester->addRequest( - $this->anilistModel->updateListItem(FormItem::from($item), $type) - ); + $maybeRequest = $this->anilistModel->updateListItem(FormItem::from($item), $type); + if ($maybeRequest !== NULL) + { + $requester->addRequest($maybeRequest); + } } else if ($action === SyncAction::CREATE) { diff --git a/src/AnimeClient/Controller/Anime.php b/src/AnimeClient/Controller/Anime.php index e011e426..d5503e24 100644 --- a/src/AnimeClient/Controller/Anime.php +++ b/src/AnimeClient/Controller/Anime.php @@ -329,7 +329,7 @@ final class Anime extends BaseController { 'title' => $this->formatTitle( $this->config->get('whose_list') . "'s Anime List", 'Anime', - $data->title + $data->title ?? '' ), 'data' => $data, ]); @@ -367,7 +367,7 @@ final class Anime extends BaseController { 'title' => $this->formatTitle( $this->config->get('whose_list') . "'s Anime List", 'Anime', - $data->title + $data->title ?? '' ), 'data' => $data, ]); diff --git a/src/AnimeClient/Controller/AnimeCollection.php b/src/AnimeClient/Controller/AnimeCollection.php index 97de11d4..95040b4a 100644 --- a/src/AnimeClient/Controller/AnimeCollection.php +++ b/src/AnimeClient/Controller/AnimeCollection.php @@ -139,7 +139,7 @@ final class AnimeCollection extends BaseController { $action ), 'media_items' => $this->animeCollectionModel->getMediaTypeList(), - 'item' => ($action === 'Edit') ? $this->animeCollectionModel->get($id) : [] + 'item' => ($action === 'Edit' && $id !== NULL) ? $this->animeCollectionModel->get($id) : [] ]); } diff --git a/src/AnimeClient/Controller/Images.php b/src/AnimeClient/Controller/Images.php index 1f526d7a..e94aa8ca 100644 --- a/src/AnimeClient/Controller/Images.php +++ b/src/AnimeClient/Controller/Images.php @@ -166,7 +166,7 @@ final class Images extends BaseController { { $contentType = ($ext === 'webp') ? 'image/webp' - : $response->getHeader('content-type')[0]; + : $response->getHeader('content-type')[0] ?? 'image/jpeg'; $outputFile = (str_contains($file, '-original')) ? "{$filePrefix}-original.{$ext}"