From c23001e7b16b21f199df0ef6a4f40e3d55fde532 Mon Sep 17 00:00:00 2001 From: "Timothy J. Warren" Date: Thu, 6 Jan 2022 12:50:26 -0500 Subject: [PATCH 1/3] Make Kitsu auth token error easier to recover from --- src/AnimeClient/API/Kitsu/Model.php | 10 ++++++++-- .../API/Kitsu/Transformer/AnimeTransformer.php | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/AnimeClient/API/Kitsu/Model.php b/src/AnimeClient/API/Kitsu/Model.php index ca7befa8..c46f925c 100644 --- a/src/AnimeClient/API/Kitsu/Model.php +++ b/src/AnimeClient/API/Kitsu/Model.php @@ -44,6 +44,7 @@ use Aviat\Ion\{ use Generator; use function Amp\Promise\wait; use function Aviat\AnimeClient\getApiClient; +use const Aviat\AnimeClient\SESSION_SEGMENT; /** * Kitsu API Model @@ -707,9 +708,14 @@ final class Model { $rawData = Json::decode($json); $data = $rawData['data']['findProfileBySlug']['library']['all'] ?? []; - $page = $data['pageInfo']; + $page = $data['pageInfo'] ?? []; if (empty($data)) { + // Clear session, in case the error is an invalid token. + $segment = $this->container->get('session') + ->getSegment(SESSION_SEGMENT); + $segment->clear(); + // @TODO Proper Error logging dump($rawData); die(); @@ -719,7 +725,7 @@ final class Model { yield $emit($data['nodes']); - if ($page['hasNextPage'] === FALSE) + if ($page['hasNextPage'] !== TRUE) { break; } diff --git a/src/AnimeClient/API/Kitsu/Transformer/AnimeTransformer.php b/src/AnimeClient/API/Kitsu/Transformer/AnimeTransformer.php index 76dddc97..e653126c 100644 --- a/src/AnimeClient/API/Kitsu/Transformer/AnimeTransformer.php +++ b/src/AnimeClient/API/Kitsu/Transformer/AnimeTransformer.php @@ -136,7 +136,7 @@ final class AnimeTransformer extends AbstractTransformer { 'show_type' => $base['subtype'], 'status' => Kitsu::getAiringStatus($base['startDate'], $base['endDate']), 'streaming_links' => Kitsu::parseStreamingLinks($base['streamingLinks']['nodes'] ?? []), - 'synopsis' => $base['description']['en'], + 'synopsis' => $base['description']['en'] ?? '', 'title' => $title, 'titles' => $titles, 'titles_more' => $titles_more, From 7415c3bbd68ea0d965c49e3c3f53cd2d9423fdba Mon Sep 17 00:00:00 2001 From: "Timothy J. Warren" Date: Thu, 6 Jan 2022 12:56:46 -0500 Subject: [PATCH 2/3] Update Anilist GraphQL schema --- src/AnimeClient/API/Anilist/schema.graphql | 235 ++++++++++++++++++--- 1 file changed, 208 insertions(+), 27 deletions(-) diff --git a/src/AnimeClient/API/Anilist/schema.graphql b/src/AnimeClient/API/Anilist/schema.graphql index a153ba61..40adeb9c 100644 --- a/src/AnimeClient/API/Anilist/schema.graphql +++ b/src/AnimeClient/API/Anilist/schema.graphql @@ -12,7 +12,7 @@ union ActivityUnion = ListActivity | MessageActivity | TextActivity union LikeableUnion = ActivityReply | ListActivity | MessageActivity | TextActivity | Thread | ThreadComment "Notification union type" -union NotificationUnion = ActivityLikeNotification | ActivityMentionNotification | ActivityMessageNotification | ActivityReplyLikeNotification | ActivityReplyNotification | ActivityReplySubscribedNotification | AiringNotification | FollowingNotification | RelatedMediaAdditionNotification | ThreadCommentLikeNotification | ThreadCommentMentionNotification | ThreadCommentReplyNotification | ThreadCommentSubscribedNotification | ThreadLikeNotification +union NotificationUnion = ActivityLikeNotification | ActivityMentionNotification | ActivityMessageNotification | ActivityReplyLikeNotification | ActivityReplyNotification | ActivityReplySubscribedNotification | AiringNotification | FollowingNotification | MediaDataChangeNotification | MediaDeletionNotification | MediaMergeNotification | RelatedMediaAdditionNotification | ThreadCommentLikeNotification | ThreadCommentMentionNotification | ThreadCommentReplyNotification | ThreadCommentSubscribedNotification | ThreadLikeNotification "Notification for when a activity is liked" type ActivityLikeNotification { @@ -227,6 +227,8 @@ type AniChartUser { type Character { "The character's age. Note this is a string, not an int, it may contain further text and additional ages." age: String + "The characters blood type" + bloodType: String "The character's birth date" dateOfBirth: FuzzyDate "A general description of the character" @@ -262,7 +264,7 @@ type Character { name: CharacterName "The url for the character page on the AniList website" siteUrl: String - updatedAt: Int @deprecated(reason : "No data available") + updatedAt: Int @deprecated(reason: "No data available") } type CharacterConnection { @@ -314,15 +316,21 @@ type CharacterName { middle: String "The character's full name in their native language" native: String + "The currently authenticated users preferred name language. Default romaji for non-authenticated" + userPreferred: String } "A submission for a character that features in an anime or manga" type CharacterSubmission { + "Data Mod assigned to handle the submission" + assignee: User "Character that the submission is referencing" character: Character createdAt: Int "The id of the submission" id: Int! + "Whether the submission is locked" + locked: Boolean "Inner details of submission status" notes: String source: String @@ -543,6 +551,7 @@ type InternalPage { sort: [AiringSort] ): [AiringSchedule] characterSubmissions( + assigneeId: Int, characterId: Int, "The order the results will be returned in" sort: [SubmissionSort], @@ -654,6 +663,8 @@ type InternalPage { id_not_in: [Int], "Filter by if the media's intended for 18+ adult audiences" isAdult: Boolean, + "If the media is officially licensed or a self-published doujin release" + isLicensed: Boolean, "Filter media by sites with a online streaming or reading license" licensedBy: String, "Filter media by sites with a online streaming or reading license" @@ -772,6 +783,7 @@ type InternalPage { userName: String ): [MediaList] mediaSubmissions( + assigneeId: Int, mediaId: Int, "The order the results will be returned in" sort: [SubmissionSort], @@ -864,7 +876,7 @@ type InternalPage { "Filter by user who created the recommendation" userId: Int ): [Recommendation] - reports: [Report] + reports(reportedId: Int, reporterId: Int): [Report] reviews( "Filter by Review id" id: Int, @@ -906,6 +918,7 @@ type InternalPage { sort: [StaffSort] ): [Staff] staffSubmissions( + assigneeId: Int, "The order the results will be returned in" sort: [SubmissionSort], staffId: Int, @@ -958,9 +971,15 @@ type InternalPage { "Filter by the user id of the thread's creator" userId: Int ): [Thread] + userBlockSearch( + "Filter by search query" + search: String + ): [User] users( "Filter by the user id" id: Int, + "Filter to moderators only if true" + isModerator: Boolean, "Filter by the name of the user" name: String, "Filter by search query" @@ -1073,6 +1092,8 @@ type Media { isAdult: Boolean "If the media is marked as favourite by the current authenticated user" isFavourite: Boolean! + "If the media is blocked from being added to favourites" + isFavouriteBlocked: Boolean! "If the media is officially licensed or a self-published doujin release" isLicensed: Boolean "Locked media may not be added to lists our favorited. This may be due to the entry pending for deletion or other reasons." @@ -1120,7 +1141,7 @@ type Media { siteUrl: String "Source type the media was adapted from." source( - "Provide 2 to use new version 2 of sources enum" + "Provide 2 or 3 to use new version 2 or 3 of sources enum" version: Int ): MediaSource "The staff who produced the media" @@ -1205,6 +1226,40 @@ type MediaCoverImage { medium: String } +"Notification for when a media entry's data was changed in a significant way impacting users' list tracking" +type MediaDataChangeNotification { + "The reason for the media data change" + context: String + "The time the notification was created at" + createdAt: Int + "The id of the Notification" + id: Int! + "The media that received data changes" + media: Media + "The id of the media that received data changes" + mediaId: Int! + "The reason for the media data change" + reason: String + "The type of notification" + type: NotificationType +} + +"Notification for when a media tracked in a user's list is deleted from the site" +type MediaDeletionNotification { + "The reason for the media deletion" + context: String + "The time the notification was created at" + createdAt: Int + "The title of the deleted media" + deletedMediaTitle: String + "The id of the Notification" + id: Int! + "The reason for the media deletion" + reason: String + "The type of notification" + type: NotificationType +} + "Media connection edge" type MediaEdge { "Media specific character name" @@ -1298,13 +1353,13 @@ type MediaList { "List of anime or manga" type MediaListCollection { "A map of media list entry arrays grouped by custom lists" - customLists(asArray: Boolean): [[MediaList]] @deprecated(reason : "Not GraphQL spec compliant, use lists field instead.") + customLists(asArray: Boolean): [[MediaList]] @deprecated(reason: "Not GraphQL spec compliant, use lists field instead.") "If there is another chunk" hasNextChunk: Boolean "Grouped media list entries" lists: [MediaListGroup] "A map of media list entry arrays grouped by status" - statusLists(asArray: Boolean): [[MediaList]] @deprecated(reason : "Not GraphQL spec compliant, use lists field instead.") + statusLists(asArray: Boolean): [[MediaList]] @deprecated(reason: "Not GraphQL spec compliant, use lists field instead.") "The owner of the list" user: User } @@ -1330,10 +1385,10 @@ type MediaListOptions { "The score format the user is using for media lists" scoreFormat: ScoreFormat "The list theme options for both lists" - sharedTheme: Json @deprecated(reason : "No longer used") + sharedTheme: Json @deprecated(reason: "No longer used") "If the shared theme should be used instead of the individual list themes" - sharedThemeEnabled: Boolean @deprecated(reason : "No longer used") - useLegacyLists: Boolean @deprecated(reason : "No longer used") + sharedThemeEnabled: Boolean @deprecated(reason: "No longer used") + useLegacyLists: Boolean @deprecated(reason: "No longer used") } "A user's list options for anime or manga lists" @@ -1349,7 +1404,27 @@ type MediaListTypeOptions { "If the completed sections of the list should be separated by format" splitCompletedSectionByFormat: Boolean "The list theme options" - theme: Json @deprecated(reason : "This field has not yet been fully implemented and may change without warning") + theme: Json @deprecated(reason: "This field has not yet been fully implemented and may change without warning") +} + +"Notification for when a media entry is merged into another for a user who had it on their list" +type MediaMergeNotification { + "The reason for the media data change" + context: String + "The time the notification was created at" + createdAt: Int + "The title of the deleted media" + deletedMediaTitles: [String] + "The id of the Notification" + id: Int! + "The media that was merged into" + media: Media + "The id of the media that was merged into" + mediaId: Int! + "The reason for the media merge" + reason: String + "The type of notification" + type: NotificationType } "The ranking of a media in a particular time span and format compared to other media" @@ -1374,7 +1449,7 @@ type MediaRank { "A media's statistics" type MediaStats { - airingProgression: [AiringProgression] @deprecated(reason : "Replaced by MediaTrends") + airingProgression: [AiringProgression] @deprecated(reason: "Replaced by MediaTrends") scoreDistribution: [ScoreDistribution] statusDistribution: [StatusDistribution] } @@ -1393,12 +1468,16 @@ type MediaStreamingEpisode { "Media submission" type MediaSubmission { + "Data Mod assigned to handle the submission" + assignee: User changes: [String] characters: [MediaSubmissionComparison] createdAt: Int externalLinks: [MediaExternalLink] "The id of the submission" id: Int! + "Whether the submission is locked" + locked: Boolean media: Media notes: String relations: [MediaEdge] @@ -1458,6 +1537,8 @@ type MediaTag { name: String! "The relevance ranking of the tag out of the 100 for this media" rank: Int + "The user who submitted the tag" + userId: Int } "The official titles of the media in various languages" @@ -1738,6 +1819,8 @@ type Mutation { comment: String, "The comment id, required for updating" id: Int, + "If the comment tree should be locked. (Mod Only)" + locked: Boolean, "The id of thread comment to reply to" parentCommentId: Int, "The id of thread the comment belongs to" @@ -1872,6 +1955,8 @@ type Mutation { rowOrder: String, "The user's list scoring system" scoreFormat: ScoreFormat, + "The language the user wants to see staff and character names in" + staffNameLanguage: UserStaffNameLanguage, "Timezone offset format: -?HH:MM" timezone: String, "User's title language" @@ -2094,6 +2179,8 @@ type Page { id_not_in: [Int], "Filter by if the media's intended for 18+ adult audiences" isAdult: Boolean, + "If the media is officially licensed or a self-published doujin release" + isLicensed: Boolean, "Filter media by sites with a online streaming or reading license" licensedBy: String, "Filter media by sites with a online streaming or reading license" @@ -2368,6 +2455,8 @@ type Page { users( "Filter by the user id" id: Int, + "Filter to moderators only if true" + isModerator: Boolean, "Filter by the name of the user" name: String, "Filter by search query" @@ -2618,6 +2707,8 @@ type Query { id_not_in: [Int], "Filter by if the media's intended for 18+ adult audiences" isAdult: Boolean, + "If the media is officially licensed or a self-published doujin release" + isLicensed: Boolean, "Filter media by sites with a online streaming or reading license" licensedBy: String, "Filter media by sites with a online streaming or reading license" @@ -2958,6 +3049,8 @@ type Query { User( "Filter by the user id" id: Int, + "Filter to moderators only if true" + isModerator: Boolean, "Filter by the name of the user" name: String, "Filter by search query" @@ -3014,6 +3107,7 @@ type RelatedMediaAdditionNotification { } type Report { + cleared: Boolean "When the entry data was created" createdAt: Int id: Int! @@ -3179,6 +3273,8 @@ type SiteTrendEdge { type Staff { "The person's age in years" age: Int + "The persons blood type" + bloodType: String "Media the actor voiced characters in. (Same data as characters with media as node instead of characters)" characterMedia( onList: Boolean, @@ -3218,7 +3314,7 @@ type Staff { "If the staff member is blocked from being added to favourites" isFavouriteBlocked: Boolean! "The primary language the staff member dub's in" - language: StaffLanguage @deprecated(reason : "Replaced with languageV2") + language: StaffLanguage @deprecated(reason: "Replaced with languageV2") "The primary language of the staff member. Current values: Japanese, English, Korean, Italian, Spanish, Portuguese, French, German, Hebrew, Hungarian, Chinese, Arabic, Filipino, Catalan" languageV2: String "Notes for site moderators" @@ -3247,7 +3343,7 @@ type Staff { submissionStatus: Int "Submitter for the submission" submitter: User - updatedAt: Int @deprecated(reason : "No data available") + updatedAt: Int @deprecated(reason: "No data available") "[startYear, endYear] (If the 2nd value is not present staff is still active)" yearsActive: [Int] } @@ -3291,6 +3387,8 @@ type StaffName { middle: String "The person's full name in their native language" native: String + "The currently authenticated users preferred name language. Default romaji for non-authenticated" + userPreferred: String } "Voice actor role for a character" @@ -3314,9 +3412,13 @@ type StaffStats { "A submission for a staff that features in an anime or manga" type StaffSubmission { + "Data Mod assigned to handle the submission" + assignee: User createdAt: Int "The id of the submission" id: Int! + "Whether the submission is locked" + locked: Boolean "Inner details of submission status" notes: String source: String @@ -3511,6 +3613,8 @@ type ThreadComment { id: Int! "If the currently authenticated user liked the comment" isLiked: Boolean + "If the comment tree is locked and may not receive replies or edits" + isLocked: Boolean "The amount of likes the comment has" likeCount: Int! "The users who liked the comment" @@ -3651,6 +3755,8 @@ type User { "The user's banner images" bannerImage: String bans: Json + "When the user's account was created. (Does not exist for accounts created before 2020)" + createdAt: Int "Custom donation badge text" donatorBadge: String "The donation tier of the user" @@ -3670,18 +3776,22 @@ type User { isFollowing: Boolean "The user's media list options" mediaListOptions: MediaListOptions + "The user's moderator roles if they are a site moderator" + moderatorRoles: [ModRole] "If the user is a moderator or data moderator" - moderatorStatus: String + moderatorStatus: String @deprecated(reason: "Deprecated. Replaced with moderatorRoles field.") "The name of the user" name: String! "The user's general options" options: UserOptions + "The user's previously used names." + previousNames: [UserPreviousName] "The url for the user page on the AniList website" siteUrl: String "The users anime & manga list statistics" statistics: UserStatisticTypes "The user's statistics" - stats: UserStats @deprecated(reason : "Deprecated. Replaced with statistics field.") + stats: UserStats @deprecated(reason: "Deprecated. Replaced with statistics field.") "The number of unread notifications the user has" unreadNotificationCount: Int "When the user's data was last updated" @@ -3747,7 +3857,9 @@ type UserModData { alts: [User] bans: Json counts: Json + email: String ip: Json + privacy: Int } "A user's general options" @@ -3762,12 +3874,24 @@ type UserOptions { notificationOptions: [NotificationOption] "Profile highlight color (blue, purple, pink, orange, red, green, gray)" profileColor: String + "The language the user wants to see staff and character names in" + staffNameLanguage: UserStaffNameLanguage "The user's timezone offset (Auth user only)" timezone: String "The language the user wants to see media titles in" titleLanguage: UserTitleLanguage } +"A user's previous name" +type UserPreviousName { + "When the user first changed from this name." + createdAt: Int + "A previous name of the user." + name: String + "When the user most recently changed from this name." + updatedAt: Int +} + type UserReleaseYearStatistic { chaptersRead: Int! count: Int! @@ -4127,24 +4251,36 @@ enum MediaSort { "Source type the media was adapted from" enum MediaSource { - "Version 2 only. Japanese Anime" + "Version 2+ only. Japanese Anime" ANIME - "Version 2 only. Self-published works" + "Version 3 only. Comics excluding manga" + COMIC + "Version 2+ only. Self-published works" DOUJINSHI + "Version 3 only. Games excluding video games" + GAME "Written work published in volumes" LIGHT_NOVEL + "Version 3 only. Live action media such as movies or TV show" + LIVE_ACTION "Asian comic book" MANGA - "Version 2 only. Written works not published in volumes" + "Version 3 only. Multimedia project" + MULTIMEDIA_PROJECT + "Version 2+ only. Written works not published in volumes" NOVEL "An original production not based of another work" ORIGINAL "Other" OTHER + "Version 3 only. Picture book" + PICTURE_BOOK "Video game" VIDEO_GAME "Video game driven primary by text and narrative" VISUAL_NOVEL + "Version 3 only. Written works published online" + WEB_NOVEL } "The current releasing status of the media" @@ -4198,6 +4334,36 @@ enum ModActionType { RESET } +"Mod role enums" +enum ModRole { + "An AniList administrator" + ADMIN + "An anime data moderator" + ANIME_DATA + "A community moderator" + COMMUNITY + "An AniList developer" + DEVELOPER + "A discord community moderator" + DISCORD_COMMUNITY + "A lead anime data moderator" + LEAD_ANIME_DATA + "A lead community moderator" + LEAD_COMMUNITY + "A head developer of AniList" + LEAD_DEVELOPER + "A lead manga data moderator" + LEAD_MANGA_DATA + "A lead social media moderator" + LEAD_SOCIAL_MEDIA + "A manga data moderator" + MANGA_DATA + "A retired moderator" + RETIRED + "A social media moderator" + SOCIAL_MEDIA +} + "Notification type enum" enum NotificationType { "A user has liked your activity" @@ -4216,6 +4382,12 @@ enum NotificationType { AIRING "A user has followed you" FOLLOWING + "An anime or manga has had a data change that affects how a user may track it in their lists" + MEDIA_DATA_CHANGE + "An anime or manga on the user's list has been deleted from the site" + MEDIA_DELETION + "Anime or manga entries on the user's list have been merged into a single entry" + MEDIA_MERGE "A new anime or manga has been added to the site where its related media is on the user's list" RELATED_MEDIA_ADDITION "A user has liked your forum comment" @@ -4399,6 +4571,16 @@ enum UserSort { WATCHED_TIME_DESC } +"The language the user wants to see staff and character names in" +enum UserStaffNameLanguage { + "The staff or character's name in their native language" + NATIVE + "The romanization of the staff or character's native name" + ROMAJI + "The romanization of the staff or character's native name, with western name ordering" + ROMAJI_WESTERN +} + "User statistics sort enum" enum UserStatisticsSort { COUNT @@ -4427,6 +4609,14 @@ enum UserTitleLanguage { ROMAJI_STYLISED } +"ISO 3166-1 alpha-2 country code" +scalar CountryCode + +"8 digit long date integer (YYYYMMDD). Unknown dates represented by 0. E.g. 2016: 20160000, May 1976: 19760500" +scalar FuzzyDateInt + +scalar Json + input AiringScheduleInput { airingAt: Int episode: Int @@ -4521,12 +4711,3 @@ input StaffNameInput { "The person's full name in their native language" native: String } - - -scalar Json - -"ISO 3166-1 alpha-2 country code" -scalar CountryCode - -"8 digit long date integer (YYYYMMDD). Unknown dates represented by 0. E.g. 2016: 20160000, May 1976: 19760500" -scalar FuzzyDateInt \ No newline at end of file From 73a69e42d38eed75f3ac4f0b37710dc2fd257819 Mon Sep 17 00:00:00 2001 From: "Timothy J. Warren" Date: Fri, 7 Jan 2022 12:33:01 -0500 Subject: [PATCH 3/3] Code style fixes --- console | 4 ++-- index.php | 2 +- src/AnimeClient/API/APIRequestBuilder.php | 2 +- src/AnimeClient/API/AbstractListItem.php | 2 +- src/AnimeClient/API/Anilist/Model.php | 10 ++++----- .../API/Anilist/RequestBuilder.php | 22 +++++++------------ .../Transformer/AnimeListTransformer.php | 3 ++- .../Transformer/MangaListTransformer.php | 3 ++- .../API/Anilist/Types/MediaListEntry.php | 6 ++--- src/AnimeClient/API/CacheTrait.php | 1 - src/AnimeClient/API/Kitsu/Auth.php | 9 ++++---- src/AnimeClient/API/Kitsu/ListItem.php | 7 ------ src/AnimeClient/API/Kitsu/MutationTrait.php | 1 - src/AnimeClient/API/Kitsu/RequestBuilder.php | 17 ++++++-------- .../API/Kitsu/RequestBuilderTrait.php | 2 +- src/AnimeClient/Command/CachePrime.php | 1 - src/AnimeClient/Command/SyncLists.php | 2 +- src/AnimeClient/Controller.php | 4 ++-- src/AnimeClient/Controller/Anime.php | 10 ++++----- .../Controller/AnimeCollection.php | 2 -- src/AnimeClient/Controller/History.php | 4 ---- src/AnimeClient/Controller/Images.php | 4 +--- src/AnimeClient/Controller/Manga.php | 4 ++-- src/AnimeClient/Controller/People.php | 2 -- src/AnimeClient/Dispatcher.php | 16 ++++++-------- src/AnimeClient/Model/Anime.php | 13 ++--------- src/AnimeClient/Model/AnimeCollection.php | 2 +- src/AnimeClient/Util.php | 2 -- src/Ion/Config.php | 18 +++++++-------- src/Ion/ConfigInterface.php | 16 +++++++------- src/Ion/Enum.php | 2 +- src/Ion/Friend.php | 8 +++---- src/Ion/View/HttpView.php | 4 ++-- src/Ion/ViewInterface.php | 4 ++-- tests/Ion/ConfigTest.php | 8 +------ 35 files changed, 83 insertions(+), 134 deletions(-) diff --git a/console b/console index 7c4260cb..5019c37a 100755 --- a/console +++ b/console @@ -9,8 +9,8 @@ use ConsoleKit\Console; $GLOBALS['_SERVER']['HTTP_HOST'] = 'localhost'; -define('APP_DIR', __DIR__ . '/app'); -define('TEMPLATE_DIR', APP_DIR . '/templates'); +const APP_DIR = __DIR__ . '/app'; +const TEMPLATE_DIR = APP_DIR . '/templates'; // ----------------------------------------------------------------------------- // Start console script diff --git a/index.php b/index.php index e5b904c1..9d643332 100644 --- a/index.php +++ b/index.php @@ -25,7 +25,7 @@ setlocale(LC_CTYPE, 'en_US'); // Load composer autoloader require_once __DIR__ . '/vendor/autoload.php'; -Debugger::$strictMode = E_ALL & ~E_DEPRECATED & ~E_USER_DEPRECATED; // all errors except deprecated notices +Debugger::$strictMode = E_ALL & ~E_DEPRECATED; // all errors except deprecated notices Debugger::$showBar = false; Debugger::enable(Debugger::DEVELOPMENT, __DIR__ . '/app/logs'); diff --git a/src/AnimeClient/API/APIRequestBuilder.php b/src/AnimeClient/API/APIRequestBuilder.php index 2e98620d..b1da1595 100644 --- a/src/AnimeClient/API/APIRequestBuilder.php +++ b/src/AnimeClient/API/APIRequestBuilder.php @@ -154,7 +154,7 @@ abstract class APIRequestBuilder { * Set a request header * * @param string $name - * @param string $value + * @param string|null $value * @return self */ public function setHeader(string $name, string $value = NULL): self diff --git a/src/AnimeClient/API/AbstractListItem.php b/src/AnimeClient/API/AbstractListItem.php index 6669ebc2..0986f85a 100644 --- a/src/AnimeClient/API/AbstractListItem.php +++ b/src/AnimeClient/API/AbstractListItem.php @@ -70,7 +70,7 @@ abstract class AbstractListItem { * Delete a list item * * @param string $id - The id of the list item to delete - * @return Request + * @return Request|null */ abstract public function delete(string $id):?Request; } \ No newline at end of file diff --git a/src/AnimeClient/API/Anilist/Model.php b/src/AnimeClient/API/Anilist/Model.php index 00e3e71a..825c8a05 100644 --- a/src/AnimeClient/API/Anilist/Model.php +++ b/src/AnimeClient/API/Anilist/Model.php @@ -207,7 +207,7 @@ final class Model * * @param FormItem $data * @param string $type - Them media type (anime/manga) - * @return Request + * @return Request|null */ public function incrementListItem(FormItem $data, string $type): ?Request { @@ -225,7 +225,7 @@ final class Model * * @param FormItem $data * @param string $type - Them media type (anime/manga) - * @return Request + * @return Request|null */ public function updateListItem(FormItem $data, string $type): ?Request { @@ -244,7 +244,7 @@ final class Model * * @param string $malId - The id of the list item to remove * @param string $type - Them media type (anime/manga) - * @return Request + * @return Request|null */ public function deleteListItem(string $malId, string $type): ?Request { @@ -262,7 +262,7 @@ final class Model * * @param string $malId * @param string $type - The media type (anime/manga) - * @return string + * @return string|null */ public function getListIdFromMalId(string $malId, string $type): ?string { @@ -306,7 +306,7 @@ final class Model * * @param string $malId * @param string $type - * @return string + * @return string|null */ private function getMediaIdFromMalId(string $malId, string $type = 'ANIME'): ?string { diff --git a/src/AnimeClient/API/Anilist/RequestBuilder.php b/src/AnimeClient/API/Anilist/RequestBuilder.php index 6c30d6ab..20f0622d 100644 --- a/src/AnimeClient/API/Anilist/RequestBuilder.php +++ b/src/AnimeClient/API/Anilist/RequestBuilder.php @@ -257,24 +257,18 @@ final class RequestBuilder extends APIRequestBuilder { $validResponseCodes = [200, 201]; $logger = $this->container->getLogger('anilist-request'); - if ($logger !== NULL) - { - $logger->debug('Anilist response', [ - 'status' => $response->getStatus(), - 'reason' => $response->getReason(), - 'body' => $response->getBody(), - 'headers' => $response->getHeaders(), - //'requestHeaders' => $request->getHeaders(), - ]); - } + $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)) { - if ($logger !== NULL) - { - $logger->warning('Non 200 response for POST api call', (array)$response->getBody()); - } + $logger?->warning('Non 200 response for POST api call', (array)$response->getBody()); } $rawBody = wait($response->getBody()->buffer()); diff --git a/src/AnimeClient/API/Anilist/Transformer/AnimeListTransformer.php b/src/AnimeClient/API/Anilist/Transformer/AnimeListTransformer.php index ffb82c13..386e6a78 100644 --- a/src/AnimeClient/API/Anilist/Transformer/AnimeListTransformer.php +++ b/src/AnimeClient/API/Anilist/Transformer/AnimeListTransformer.php @@ -24,6 +24,7 @@ use Aviat\AnimeClient\Types\{AnimeListItem, FormItem}; use Aviat\Ion\Transformer\AbstractTransformer; use DateTime; +use DateTimeInterface; class AnimeListTransformer extends AbstractTransformer { @@ -57,7 +58,7 @@ class AnimeListTransformer extends AbstractTransformer { : AnimeWatchingStatus::ANILIST_TO_KITSU[$item['status']], 'updatedAt' => (new DateTime()) ->setTimestamp($item['updatedAt']) - ->format(DateTime::W3C) + ->format(DateTimeInterface::W3C) ], ]); } diff --git a/src/AnimeClient/API/Anilist/Transformer/MangaListTransformer.php b/src/AnimeClient/API/Anilist/Transformer/MangaListTransformer.php index e1e47a79..6f91a2e9 100644 --- a/src/AnimeClient/API/Anilist/Transformer/MangaListTransformer.php +++ b/src/AnimeClient/API/Anilist/Transformer/MangaListTransformer.php @@ -25,6 +25,7 @@ use Aviat\AnimeClient\Types\FormItem; use Aviat\Ion\Transformer\AbstractTransformer; use DateTime; +use DateTimeInterface; class MangaListTransformer extends AbstractTransformer { @@ -58,7 +59,7 @@ class MangaListTransformer extends AbstractTransformer { : MangaReadingStatus::ANILIST_TO_KITSU[$item['status']], 'updatedAt' => (new DateTime()) ->setTimestamp($item['updatedAt']) - ->format(DateTime::W3C), + ->format(DateTimeInterface::W3C), ] ]); } diff --git a/src/AnimeClient/API/Anilist/Types/MediaListEntry.php b/src/AnimeClient/API/Anilist/Types/MediaListEntry.php index 0e1edb8d..b846b017 100644 --- a/src/AnimeClient/API/Anilist/Types/MediaListEntry.php +++ b/src/AnimeClient/API/Anilist/Types/MediaListEntry.php @@ -19,10 +19,8 @@ namespace Aviat\AnimeClient\API\Anilist\Types; use Aviat\AnimeClient\Types\AbstractType; class MediaListEntry extends AbstractType { - /** - * @var int|string - */ - public $id; + + public int|string $id; public ?string $notes; diff --git a/src/AnimeClient/API/CacheTrait.php b/src/AnimeClient/API/CacheTrait.php index 22ecc210..15ee6358 100644 --- a/src/AnimeClient/API/CacheTrait.php +++ b/src/AnimeClient/API/CacheTrait.php @@ -17,7 +17,6 @@ namespace Aviat\AnimeClient\API; use Psr\SimpleCache\CacheInterface; -use Psr\SimpleCache\InvalidArgumentException; /** * Helper methods for dealing with the Cache diff --git a/src/AnimeClient/API/Kitsu/Auth.php b/src/AnimeClient/API/Kitsu/Auth.php index 045433d7..b39145f6 100644 --- a/src/AnimeClient/API/Kitsu/Auth.php +++ b/src/AnimeClient/API/Kitsu/Auth.php @@ -23,7 +23,6 @@ use const Aviat\AnimeClient\SESSION_SEGMENT; use Aviat\AnimeClient\Kitsu as K; use Aviat\AnimeClient\API\CacheTrait; use Aviat\Ion\Di\{ContainerAware, ContainerInterface}; -use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException}; use Aviat\Ion\Event; /** @@ -129,11 +128,11 @@ final class Auth { { if (PHP_SAPI === 'cli') { - return $this->segment->get('auth_token', NULL) - ?? $this->cache->get(K::AUTH_TOKEN_CACHE_KEY, NULL); + return $this->segment->get('auth_token') + ?? $this->cache->get(K::AUTH_TOKEN_CACHE_KEY); } - return $this->segment->get('auth_token', NULL); + return $this->segment->get('auth_token'); } /** @@ -146,7 +145,7 @@ final class Auth { if (PHP_SAPI === 'cli') { return $this->segment->get('refresh_token') - ?? $this->cache->get(K::AUTH_TOKEN_REFRESH_CACHE_KEY, NULL); + ?? $this->cache->get(K::AUTH_TOKEN_REFRESH_CACHE_KEY); } return $this->segment->get('refresh_token'); diff --git a/src/AnimeClient/API/Kitsu/ListItem.php b/src/AnimeClient/API/Kitsu/ListItem.php index 64837edb..1caab456 100644 --- a/src/AnimeClient/API/Kitsu/ListItem.php +++ b/src/AnimeClient/API/Kitsu/ListItem.php @@ -16,17 +16,10 @@ namespace Aviat\AnimeClient\API\Kitsu; -use Aviat\Ion\Di\Exception\ContainerException; -use Aviat\Ion\Di\Exception\NotFoundException; - -use function Amp\Promise\wait; -use function Aviat\AnimeClient\getResponse; - use Amp\Http\Client\Request; use Aviat\AnimeClient\API\AbstractListItem; use Aviat\AnimeClient\Types\FormItemData; use Aviat\Ion\Di\ContainerAware; -use Aviat\Ion\Json; use Throwable; diff --git a/src/AnimeClient/API/Kitsu/MutationTrait.php b/src/AnimeClient/API/Kitsu/MutationTrait.php index 0fbc30b4..664e4567 100644 --- a/src/AnimeClient/API/Kitsu/MutationTrait.php +++ b/src/AnimeClient/API/Kitsu/MutationTrait.php @@ -18,7 +18,6 @@ namespace Aviat\AnimeClient\API\Kitsu; use Amp\Http\Client\Request; use Aviat\AnimeClient\Types\FormItem; -use Aviat\Banker\Exception\InvalidArgumentException; /** * Kitsu API calls that mutate data, C/U/D parts of CRUD diff --git a/src/AnimeClient/API/Kitsu/RequestBuilder.php b/src/AnimeClient/API/Kitsu/RequestBuilder.php index 4e234207..b461b099 100644 --- a/src/AnimeClient/API/Kitsu/RequestBuilder.php +++ b/src/AnimeClient/API/Kitsu/RequestBuilder.php @@ -192,16 +192,13 @@ final class RequestBuilder extends APIRequestBuilder { $request = $this->setUpRequest($type, $url, $options); $response = getResponse($request); - if ($logger !== NULL) - { - $logger->debug('Kitsu API Response', [ - 'status' => $response->getStatus(), - 'reason' => $response->getReason(), - 'body' => $response->getBody(), - 'headers' => $response->getHeaders(), - 'requestHeaders' => $request->getHeaders(), - ]); - } + $logger?->debug('Kitsu API Response', [ + 'status' => $response->getStatus(), + 'reason' => $response->getReason(), + 'body' => $response->getBody(), + 'headers' => $response->getHeaders(), + 'requestHeaders' => $request->getHeaders(), + ]); return $response; } diff --git a/src/AnimeClient/API/Kitsu/RequestBuilderTrait.php b/src/AnimeClient/API/Kitsu/RequestBuilderTrait.php index 369454e0..46fd53ea 100644 --- a/src/AnimeClient/API/Kitsu/RequestBuilderTrait.php +++ b/src/AnimeClient/API/Kitsu/RequestBuilderTrait.php @@ -27,7 +27,7 @@ trait RequestBuilderTrait { * Set the request builder object * * @param RequestBuilder $requestBuilder - * @return $this + * @return RequestBuilderTrait|ListItem|Model */ public function setRequestBuilder(RequestBuilder $requestBuilder): self { diff --git a/src/AnimeClient/Command/CachePrime.php b/src/AnimeClient/Command/CachePrime.php index 8b7d3687..d6074d3d 100644 --- a/src/AnimeClient/Command/CachePrime.php +++ b/src/AnimeClient/Command/CachePrime.php @@ -16,7 +16,6 @@ namespace Aviat\AnimeClient\Command; -use Aviat\AnimeClient\Kitsu; use Aviat\Ion\Di\Exception\ContainerException; use Aviat\Ion\Di\Exception\NotFoundException; use function Aviat\AnimeClient\clearCache; diff --git a/src/AnimeClient/Command/SyncLists.php b/src/AnimeClient/Command/SyncLists.php index 2b581127..3e9d15b6 100644 --- a/src/AnimeClient/Command/SyncLists.php +++ b/src/AnimeClient/Command/SyncLists.php @@ -203,7 +203,7 @@ final class SyncLists extends BaseCommand { * * @param string $type * @param array $data - * @return array|array[] + * @return array */ protected function compare(string $type, array $data): array { diff --git a/src/AnimeClient/Controller.php b/src/AnimeClient/Controller.php index 71fc97ad..7b0cfeec 100644 --- a/src/AnimeClient/Controller.php +++ b/src/AnimeClient/Controller.php @@ -375,10 +375,10 @@ class Controller { * @param array $data * @param HtmlView|NULL $view * @param int $code - * @throws InvalidArgumentException * @return void + *@throws InvalidArgumentException */ - protected function outputHTML(string $template, array $data = [], $view = NULL, int $code = 200): void + protected function outputHTML(string $template, array $data = [], HtmlView $view = NULL, int $code = 200): void { if (NULL === $view) { diff --git a/src/AnimeClient/Controller/Anime.php b/src/AnimeClient/Controller/Anime.php index 45cf24bc..a7340a34 100644 --- a/src/AnimeClient/Controller/Anime.php +++ b/src/AnimeClient/Controller/Anime.php @@ -66,15 +66,13 @@ final class Anime extends BaseController { /** * Show a portion, or all of the anime list * - * @param string|int $status - The section of the list + * @param int|string $status - The section of the list * @param string|null $view - List or cover view - * @throws ContainerException - * @throws NotFoundException + * @return void * @throws InvalidArgumentException * @throws Throwable - * @return void */ - public function index($status = KitsuWatchingStatus::WATCHING, ?string $view = NULL): void + public function index(int|string $status = KitsuWatchingStatus::WATCHING, ?string $view = NULL): void { if ( ! in_array($status, [ 'all', @@ -178,7 +176,7 @@ final class Anime extends BaseController { * @param string $id * @param string $status */ - public function edit(string $id, $status = 'all'): void + public function edit(string $id, string $status = 'all'): void { $this->checkAuth(); diff --git a/src/AnimeClient/Controller/AnimeCollection.php b/src/AnimeClient/Controller/AnimeCollection.php index 984392ea..10daf158 100644 --- a/src/AnimeClient/Controller/AnimeCollection.php +++ b/src/AnimeClient/Controller/AnimeCollection.php @@ -239,8 +239,6 @@ final class AnimeCollection extends BaseController { * Update a collection item * * @param array $data - * @throws ContainerException - * @throws NotFoundException */ protected function update(array $data): void { diff --git a/src/AnimeClient/Controller/History.php b/src/AnimeClient/Controller/History.php index 429119a9..58b59c71 100644 --- a/src/AnimeClient/Controller/History.php +++ b/src/AnimeClient/Controller/History.php @@ -78,8 +78,6 @@ final class History extends BaseController { 'url_type' => 'anime', ]); - // $this->outputJSON($this->animeModel->getHistory()); - // return; $this->outputHTML('history', [ 'title' => $this->formatTitle( $this->config->get('whose_list') . "'s Anime List", @@ -98,8 +96,6 @@ final class History extends BaseController { 'url_type' => 'manga', ]); - // $this->outputJSON($this->mangaModel->getHistory()); - // return; $this->outputHTML('history', [ 'title' => $this->formatTitle( $this->config->get('whose_list') . "'s Manga List", diff --git a/src/AnimeClient/Controller/Images.php b/src/AnimeClient/Controller/Images.php index e94aa8ca..8a64fec6 100644 --- a/src/AnimeClient/Controller/Images.php +++ b/src/AnimeClient/Controller/Images.php @@ -16,8 +16,6 @@ namespace Aviat\AnimeClient\Controller; -use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException}; - use function Amp\Promise\wait; use function Aviat\AnimeClient\getResponse; use function Aviat\AnimeClient\createPlaceholderImage; @@ -39,7 +37,7 @@ final class Images extends BaseController { * @return void * @throws Throwable */ - public function cache(string $type, string $file, $display = TRUE): void + public function cache(string $type, string $file, bool $display = TRUE): void { $currentUrl = (string)$this->request->getUri(); diff --git a/src/AnimeClient/Controller/Manga.php b/src/AnimeClient/Controller/Manga.php index f52d629e..56a37864 100644 --- a/src/AnimeClient/Controller/Manga.php +++ b/src/AnimeClient/Controller/Manga.php @@ -64,10 +64,10 @@ final class Manga extends Controller { * * @param string $status * @param string $view - * @throws InvalidArgumentException * @return void + *@throws InvalidArgumentException */ - public function index($status = 'all', $view = ''): void + public function index(string $status = 'all', string $view = ''): void { if ( ! in_array($status, [ 'all', diff --git a/src/AnimeClient/Controller/People.php b/src/AnimeClient/Controller/People.php index e1e9e9dc..f86347c2 100644 --- a/src/AnimeClient/Controller/People.php +++ b/src/AnimeClient/Controller/People.php @@ -52,8 +52,6 @@ final class People extends BaseController { * * @param string $slug * @return void - * @throws ContainerException - * @throws NotFoundException */ public function index(string $slug): void { diff --git a/src/AnimeClient/Dispatcher.php b/src/AnimeClient/Dispatcher.php index 08cc5cb2..0c445526 100644 --- a/src/AnimeClient/Dispatcher.php +++ b/src/AnimeClient/Dispatcher.php @@ -16,6 +16,8 @@ namespace Aviat\AnimeClient; +use Aviat\AnimeClient\Enum\EventType; +use Aviat\Ion\Event; use Aviat\Ion\Json; use Aura\Router\{ Map, @@ -27,7 +29,6 @@ use Aviat\AnimeClient\API\FailedResponseException; use Aviat\Ion\Di\ContainerInterface; use Aviat\Ion\Friend; use Aviat\Ion\Type\StringType; -use JetBrains\PhpStorm\ArrayShape; use LogicException; use ReflectionException; @@ -117,7 +118,7 @@ final class Dispatcher extends RoutingBase { * @return void * @throws ReflectionException */ - public function __invoke($route = NULL): void + public function __invoke(object $route = NULL): void { $logger = $this->container->getLogger(); @@ -136,7 +137,7 @@ final class Dispatcher extends RoutingBase { { // If not route was matched, return an appropriate http // error message - $errorRoute = (array)$this->getErrorParams(); + $errorRoute = $this->getErrorParams(); $controllerName = DEFAULT_CONTROLLER; $actionMethod = $errorRoute['action_method']; $params = $errorRoute['params']; @@ -278,17 +279,14 @@ final class Dispatcher extends RoutingBase { */ protected function call(string $controllerName, string $method, array $params): void { - $logger = $this->container->getLogger('default'); + $logger = $this->container->getLogger(); try { $controller = new $controllerName($this->container); // Run the appropriate controller method - if ($logger !== NULL) - { - $logger->debug('Dispatcher - controller arguments', $params); - } + $logger?->debug('Dispatcher - controller arguments', $params); $params = array_values($params); $controller->$method(...$params); @@ -360,7 +358,7 @@ final class Dispatcher extends RoutingBase { } /** - * Select controller based on the current url, and apply its relevent routes + * Select controller based on the current url, and apply its relevant routes * * @return array */ diff --git a/src/AnimeClient/Model/Anime.php b/src/AnimeClient/Model/Anime.php index 7736977a..86efcc1c 100644 --- a/src/AnimeClient/Model/Anime.php +++ b/src/AnimeClient/Model/Anime.php @@ -16,17 +16,8 @@ namespace Aviat\AnimeClient\Model; -use Aviat\AnimeClient\API\ParallelAPIRequest; use Aviat\AnimeClient\API\Mapping\AnimeWatchingStatus; -use Aviat\AnimeClient\Types\{ - Anime as AnimeType, - FormItem, - AnimeListItem -}; -use Aviat\Ion\Json; - -use Throwable; -use function is_array; +use Aviat\AnimeClient\Types\Anime as AnimeType; /** * Model for handling requests dealing with the anime list @@ -64,7 +55,7 @@ class Anime extends API { { $data = $this->kitsuModel->getFullOrganizedAnimeList(); - foreach($data as $section => &$list) + foreach($data as &$list) { $this->sortByName($list, 'anime'); } diff --git a/src/AnimeClient/Model/AnimeCollection.php b/src/AnimeClient/Model/AnimeCollection.php index 6802d0d8..c6fdba03 100644 --- a/src/AnimeClient/Model/AnimeCollection.php +++ b/src/AnimeClient/Model/AnimeCollection.php @@ -578,7 +578,7 @@ final class AnimeCollection extends Collection { * @param string $animeId The current anime * @return void */ - private function updateGenres($animeId): void + private function updateGenres(string $animeId): void { if ($this->db === NULL) { diff --git a/src/AnimeClient/Util.php b/src/AnimeClient/Util.php index fcb77751..13348caf 100644 --- a/src/AnimeClient/Util.php +++ b/src/AnimeClient/Util.php @@ -46,8 +46,6 @@ class Util { * Set up the Util class * * @param ContainerInterface $container - * @throws ContainerException - * @throws NotFoundException */ public function __construct(ContainerInterface $container) { diff --git a/src/Ion/Config.php b/src/Ion/Config.php index 8d0cdc60..ac7b3b4a 100644 --- a/src/Ion/Config.php +++ b/src/Ion/Config.php @@ -45,10 +45,10 @@ class Config implements ConfigInterface { /** * Does the config item exist? * - * @param string|int|array $key + * @param array|int|string $key * @return bool */ - public function has($key): bool + public function has(array|int|string $key): bool { return $this->map->hasKey($key); } @@ -60,7 +60,7 @@ class Config implements ConfigInterface { * @return mixed * @throws ConfigException */ - public function get($key = NULL) + public function get(array|string $key = NULL): mixed { if (\is_array($key)) { @@ -73,10 +73,10 @@ class Config implements ConfigInterface { /** * Remove a config value * - * @param string|array $key + * @param array|string $key * @return void */ - public function delete($key): void + public function delete(array|string $key): void { if (\is_array($key)) { @@ -92,12 +92,12 @@ class Config implements ConfigInterface { /** * Set a config value * - * @param integer|string|array $key - * @param mixed $value - * @throws InvalidArgumentException + * @param array|integer|string $key + * @param mixed $value * @return ConfigInterface + *@throws InvalidArgumentException */ - public function set($key, $value): ConfigInterface + public function set(array|int|string $key, mixed $value): ConfigInterface { if (\is_array($key)) { diff --git a/src/Ion/ConfigInterface.php b/src/Ion/ConfigInterface.php index b469cc31..01f8598f 100644 --- a/src/Ion/ConfigInterface.php +++ b/src/Ion/ConfigInterface.php @@ -23,10 +23,10 @@ interface ConfigInterface { /** * Does the config item exist? * - * @param string|int|array $key + * @param array|int|string $key * @return bool */ - public function has($key): bool; + public function has(array|int|string $key): bool; /** * Get a config value @@ -34,23 +34,23 @@ interface ConfigInterface { * @param array|string|null $key * @return mixed */ - public function get($key = NULL); + public function get(array|string $key = NULL): mixed; /** * Set a config value * - * @param integer|string|array $key + * @param array|integer|string $key * @param mixed $value - * @throws \InvalidArgumentException * @return ConfigInterface + * @throws \InvalidArgumentException */ - public function set($key, $value): self; + public function set(array|int|string $key, mixed $value): self; /** * Remove a config value * - * @param string|array $key + * @param array|string $key * @return void */ - public function delete($key): void; + public function delete(array|string $key): void; } \ No newline at end of file diff --git a/src/Ion/Enum.php b/src/Ion/Enum.php index 098907e8..3a9b77c9 100644 --- a/src/Ion/Enum.php +++ b/src/Ion/Enum.php @@ -51,7 +51,7 @@ abstract class Enum { * @return boolean * @throws ReflectionException */ - public static function isValid($key): bool + public static function isValid(mixed $key): bool { $values = array_values(static::getConstList()); return in_array($key, $values, TRUE); diff --git a/src/Ion/Friend.php b/src/Ion/Friend.php index 89b15a56..36391799 100644 --- a/src/Ion/Friend.php +++ b/src/Ion/Friend.php @@ -31,7 +31,7 @@ class Friend { * Object to create a friend of * @var mixed */ - private $_friend_; + private mixed $_friend_; /** * Reflection class of the object @@ -46,7 +46,7 @@ class Friend { * @throws InvalidArgumentException * @throws \ReflectionException */ - public function __construct($obj) + public function __construct(mixed $obj) { if ( ! \is_object($obj)) { @@ -63,7 +63,7 @@ class Friend { * @param string $key * @return mixed */ - public function __get(string $key) + public function __get(string $key): mixed { if ($this->__isset($key)) { @@ -96,7 +96,7 @@ class Friend { * @param mixed $value * @return void */ - public function __set(string $key, $value) + public function __set(string $key, mixed $value) { if ($this->__isset($key)) { diff --git a/src/Ion/View/HttpView.php b/src/Ion/View/HttpView.php index c0b65913..4f279282 100644 --- a/src/Ion/View/HttpView.php +++ b/src/Ion/View/HttpView.php @@ -93,7 +93,7 @@ class HttpView implements HttpViewInterface{ * @param string|string[] $value * @return HttpView */ - public function addHeader(string $name, $value): self + public function addHeader(string $name, array|string $value): self { $this->response = $this->response->withHeader($name, $value); return $this; @@ -105,7 +105,7 @@ class HttpView implements HttpViewInterface{ * @param mixed $string * @return HttpViewInterface */ - public function setOutput($string): HttpViewInterface + public function setOutput(mixed $string): HttpViewInterface { $this->response->getBody()->write($string); diff --git a/src/Ion/ViewInterface.php b/src/Ion/ViewInterface.php index 01762360..63ae966c 100644 --- a/src/Ion/ViewInterface.php +++ b/src/Ion/ViewInterface.php @@ -37,7 +37,7 @@ interface ViewInterface { * @param mixed $string * @return ViewInterface */ - public function setOutput($string): self; + public function setOutput(mixed $string): self; /** * Append additional output. @@ -54,7 +54,7 @@ interface ViewInterface { * @param string|string[] $value * @return ViewInterface */ - public function addHeader(string $name, $value): self; + public function addHeader(string $name, array|string $value): self; /** * Get the current output as a string. Does not diff --git a/tests/Ion/ConfigTest.php b/tests/Ion/ConfigTest.php index 58466998..40854d8d 100644 --- a/tests/Ion/ConfigTest.php +++ b/tests/Ion/ConfigTest.php @@ -20,7 +20,7 @@ use Aviat\Ion\Config; class ConfigTest extends IonTestCase { - protected $config; + protected Config $config; public function setUp(): void { @@ -66,12 +66,6 @@ class ConfigTest extends IonTestCase { $this->assertEquals('great', $this->config->get(['apple', 'sauce', 'is']), "Array argument get for config failed."); } - public function testConfigBadSet(): void - { - $this->expectException('InvalidArgumentException'); - $this->config->set(NULL, FALSE); - } - public function dataConfigDelete(): array { return [