diff --git a/changelog.md b/changelog.md index edfc2443..19a3d456 100755 --- a/changelog.md +++ b/changelog.md @@ -59,46 +59,46 @@ $genres = $jikan->getMangaGenres( - Parser bug fixes - Improved image quality parsing for some requests - `\Jikan\Helper\Parser::parseImageQuality($imageUrl)` now removes `v` from the end of images, which resulted in a smaller thumbnail + `\Jikan\Helper\Parser::parseImageQuality($imageUrl)` now removes `v` from the end of images, which resulted in a smaller thumbnail ### 2.9.0 - Nov 11, 19 - **[Anime Episode Details]** - - Added feature request [jikan#229](https://github.com/jikan-me/jikan/issues/229) + - Added feature request [jikan#229](https://github.com/jikan-me/jikan/issues/229) - **[User Profile]** - - Added `userId` property [jikan-rest#74](https://github.com/jikan-me/jikan-rest/issues/74) - + - Added `userId` property [jikan-rest#74](https://github.com/jikan-me/jikan-rest/issues/74) + ### 2.8.6 - Aug 18, 19 - Bug fixes - **[Search]** - - Throws `BadResponseException` if search query is < 3 + - Throws `BadResponseException` if search query is < 3 ### 2.8.0 - Apr 30, 19 - **[User List : Anime|Manga]** - - Throw `BadResponseException` instead of `ParserException` when the request fails [#217](/../../issues/217) - - Add list filtering & sorting [jikan-rest#49](https://github.com/jikan-me/jikan-rest/issues/49) - - Replace `StudioMeta`, `LicensorMeta` & `MagazineMeta` with `MalUrl` intead - - This will further provide properties like `type`, `url` + - Throw `BadResponseException` instead of `ParserException` when the request fails [#217](/../../issues/217) + - Add list filtering & sorting [jikan-rest#49](https://github.com/jikan-me/jikan-rest/issues/49) + - Replace `StudioMeta`, `LicensorMeta` & `MagazineMeta` with `MalUrl` intead + - This will further provide properties like `type`, `url` - **[Search : Anime|Manga]** - - Add result ordering & sorting [jikan-rest#48](https://github.com/jikan-me/jikan-rest/issues/48) - + - Add result ordering & sorting [jikan-rest#48](https://github.com/jikan-me/jikan-rest/issues/48) + ### 2.7.0 - Apr 14, 19 -- **[Anime|Manga]** - - `EpisodeListItem` `aired` property to return `DateTimeImmutable` instead of `DateRange` - - [Bug Fix] Stats Score refactoring; returns `AnimeStatsScore`/`MangaStatsScore` object instead of array now - [#216](/../../issues/216) - - Fix `AnimeListItem`/`MangaListItem` parsing date formats incorrectly +- **[Anime|Manga]** + - `EpisodeListItem` `aired` property to return `DateTimeImmutable` instead of `DateRange` + - [Bug Fix] Stats Score refactoring; returns `AnimeStatsScore`/`MangaStatsScore` object instead of array now - [#216](/../../issues/216) + - Fix `AnimeListItem`/`MangaListItem` parsing date formats incorrectly - **[Helper]** fix `parseDateMDY` returning incorrect date - **[Jikan.php]** - - fix `PersonSearch`incorrect Request class hinting - - add `UserMangaList` + - fix `PersonSearch`incorrect Request class hinting + - add `UserMangaList` - **[MalClient.php]** - - `getAnimeEpisodes` with no episodes return empty episodes array now instead of BadResponseException (404) - - `getPersonSearch` with no results returns empty array now instead of BadResponseException (404) - - `getCharacterSearch` with no results returns empty array now instead of BadResponseException (404) - - `getCharacter` returns BadResponseException (404) now if invalid ID is provided - - Fix guzzle dep injection being overriden in some cases + - `getAnimeEpisodes` with no episodes return empty episodes array now instead of BadResponseException (404) + - `getPersonSearch` with no results returns empty array now instead of BadResponseException (404) + - `getCharacterSearch` with no results returns empty array now instead of BadResponseException (404) + - `getCharacter` returns BadResponseException (404) now if invalid ID is provided + - Fix guzzle dep injection being overriden in some cases - **[User]** - - Fix `UserProfileParser`'s `getUsername()` returning the URL instead of the username + - Fix `UserProfileParser`'s `getUsername()` returning the URL instead of the username - Added default values to some models - Other minor code and bug fixes @@ -144,24 +144,24 @@ $genres = $jikan->getMangaGenres( ### 2.0.0-rc.1 - Aug 5, 18 - Complete refactor using better dependencies - - Parser is more robust and stable - - Library now implements PSR2 + - Parser is more robust and stable + - Library now implements PSR2 - Clean data values - Added **Season List** - Added **Top** - - Characters - - People + - Characters + - People - Added **Genre** - - Anime listing by genre - - Manga listing by genre + - Anime listing by genre + - Manga listing by genre - Added **Producers** - - Anime listing by producer + - Anime listing by producer - Added **Magazine** - - Manga listing by magazine + - Manga listing by magazine - Added **User** - - Profile - - History - - Friends + - Profile + - History + - Friends - Complete syntax revamp - And a whole lot more! @@ -184,14 +184,14 @@ $genres = $jikan->getMangaGenres( - Only supported for `ANIME` and `MANGA` type searches ### 1.15.9 stable - May 14, 18 -- **[Search]** +- **[Search]** - Bug fix for `genre`, `genreInclude`, `startDate` & `endDate` - **[SearchConfig]** `Jikan\Helpers\SearchConfig` - `setGenre` now no longer takes an array for multiple genres, but rather Variadic arguments. - e.g `setGenre(1, 18)` + e.g `setGenre(1, 18)` ### 1.15.8 stable - May 12, 18 -- **[Search]** +- **[Search]** - Bug fix for [#139](/../../issues/139) - 1.15.6 - Bug fix for [#138](/../../issues/138) - 1.15.7 - HTML special character decode for some titles @@ -240,7 +240,7 @@ $genres = $jikan->getMangaGenres( ### 1.9.0 stable - March 3, 18 - **[Anime|Manga]** - - Add extended data "forum topics" parsing [#19](/../../issues/19) - 1.8.0 + - Add extended data "forum topics" parsing [#19](/../../issues/19) - 1.8.0 - Add extended data "more_info" parsing [#17](/../../issues/17) ### 1.7.2 stable - February 25, 18 @@ -260,7 +260,7 @@ $genres = $jikan->getMangaGenres( ### 1.6.2 stable - January 26, 18 - **[Anime|Manga]** - Add stats parsing - 1.6.0 -- **[Core]** +- **[Core]** - Fixed an impactful bug which had the parser requesting the page *twice* in some extend cases (was i drunk coding this part?!) - 1.6.1 - Was doubling chances of rate limiting - Slowing down the script 2x @@ -318,7 +318,7 @@ $genres = $jikan->getMangaGenres( - Fixed parsing bug for anime and manga that only have one `aired` and `published` date. ### 1.2.0 stable - December 2, 17 -- **[Anime|Manga]** +- **[Anime|Manga]** - Convert Dates to ISO Format - Enhancement [#72](/../../issues/72) - `aired` will now be an array returning ISO 8601 - You can find the string version of the date, like before, in a new field; `aired_string` @@ -327,7 +327,7 @@ $genres = $jikan->getMangaGenres( - Remmoved extra forward slash in the related item URL - Added boolean field `airing` & `publishing` for anime & manga respectively - **[Manga]** Removed extra whitespace for `title_japanese` -- **[Person]** +- **[Person]** - Fixed `More` field not parsing - Issue [#61](/../../issues/61) - Changed `website` to `website_url` @@ -346,7 +346,7 @@ $genres = $jikan->getMangaGenres( - **[Character]** Added `link_canonical` ### 1.1.0 stable - November 9, 17 -- **[Character]** +- **[Character]** - Fixed name having whitespace appended to it - Fixed name not showing up for characters without kanji names - Rename name_japanese -> name_kanji (since that's what it actually is) @@ -356,18 +356,18 @@ $genres = $jikan->getMangaGenres( ### 1.0.1 stable - October 5, 17 - **[Anime]** - - Fixed [#65](/../../issues/65) + - Fixed [#65](/../../issues/65) ### 1.0.0 stable - July 11, 17 - **Added** Composer - **Refactored** entire code base to meet with proper PSR compliants -- **[Person]** - - Name Parsing [#44](/../../issues/44) - - Alternate name issue fixed [#47](/../../issues/47) -- **[Anime/Manga]** - - Adaption contains HTML tags [#45](/../../issues/45) - - Related anime/manga parse the ID now [#52](/../../issues/52) - - **[Episodes]** Romanji/Japanese titles swapped now fixed [#46](/../../issues/46) +- **[Person]** + - Name Parsing [#44](/../../issues/44) + - Alternate name issue fixed [#47](/../../issues/47) +- **[Anime/Manga]** + - Adaption contains HTML tags [#45](/../../issues/45) + - Related anime/manga parse the ID now [#52](/../../issues/52) + - **[Episodes]** Romanji/Japanese titles swapped now fixed [#46](/../../issues/46) - **Fixed** Some responses showing HTML tags - HTML special characters are now decoded to Unicode - **[Character]** Canonical Link parsing [#50](/../../issues/50) @@ -408,9 +408,9 @@ $genres = $jikan->getMangaGenres( - Check response types @ [http://jikan.me/docs#rest-manga](http://jikan.me/docs#rest-manga) - Returns empty array if there's no authors set - `authors` is renamed to `author` -- Refactors `genres` array response +- Refactors `genres` array response - Check response types @ [http://jikan.me/docs#rest-manga](http://jikan.me/docs#rest-manga) - - `genres` is renamed to `genre` + - `genres` is renamed to `genre` - `background` returns empty string if there's no background available ### 0.2.2 alpha - June 2, 17 @@ -451,11 +451,11 @@ $genres = $jikan->getMangaGenres( ### 0.1.4 alpha - May 16, 17 - Jikan library is renamed from **mal-uapi.php** to **jikan.php** - Namespace changed from **MAL** to **Jikan** - ```php - $jikan = new \Jikan\GET; - $jikan->anime(1); - $anime = $jikan->data; - ``` + ```php + $jikan = new \Jikan\GET; + $jikan->anime(1); + $anime = $jikan->data; + ``` - Main class is changed from **GET** to **Get** - Completed person fetch - Added canonical link for Characters in the return data @@ -496,10 +496,10 @@ $genres = $jikan->getMangaGenres( ### 0.1.3 alpha - May 15, 17 - Completed character fetch data - You can now fetch animeography, mangaography, voice actors and member favorites of that character - ```php - $mal = new \MAL\GET; - $character = $mal->character(1)->data; - ``` + ```php + $mal = new \MAL\GET; + $character = $mal->character(1)->data; + ``` ### 0.1.2 alpha - May 12, 17 - Added Character fetch, you can now get character data. @@ -509,23 +509,23 @@ $genres = $jikan->getMangaGenres( - Added chaining methods (return $this) - Note that this only works for similar type gets, for example Anime, Manga, Characters - So you can fetch extra stuff such as videos, episodes, reviews, etc from their own respective pages like this: - ```php - $mal = new \MAL\GET; - $anime = $mal->anime(1)->videos()->episode()->reviews(); - ``` + ```php + $mal = new \MAL\GET; + $anime = $mal->anime(1)->videos()->episode()->reviews(); + ``` - This will be slower as every method is fetching a completely new page dedicated to that data - Simply calling the anime or manga method like this, - ```php - $anime = $mal->anime(1) - ``` - will no longer return the data! The data will be saved to its array, which you'll need to use a new method to return it. - The reason for this is chained methods to fetch other related data as stated above! - ```php - $anime = $mal->anime(1)->return(); - //or - $anime = $mail->anime(1)->data; - //same stuff - ``` + ```php + $anime = $mal->anime(1) + ``` + will no longer return the data! The data will be saved to its array, which you'll need to use a new method to return it. + The reason for this is chained methods to fetch other related data as stated above! + ```php + $anime = $mal->anime(1)->return(); + //or + $anime = $mail->anime(1)->data; + //same stuff + ``` ### 0.1.1 alpha - Apr 17, 17 diff --git a/composer.json b/composer.json index e78ce409..b69de464 100755 --- a/composer.json +++ b/composer.json @@ -7,7 +7,7 @@ "authors": [ { "name": "Irfan", - "email": "irfan.dahir@gmail.com" + "email": "neko@jikan.moe" } ], "autoload": { @@ -25,19 +25,18 @@ } }, "require": { - "fabpot/goutte": "^3.2", - "php": "^7.1", - "ext-json": "*" + "php": "^8.0", + "ext-json": "*", + "fabpot/goutte": "^4.0" }, "require-dev": { - "brianium/paratest": "~4.0", + "brianium/paratest": "^6.4.1", "doctrine/collections": "^1.5", "friendsofphp/php-cs-fixer": "^2.16", "jakub-onderka/php-parallel-lint": "^1.0", "jikan-me/jikan-fixtures": "dev-master", - "php-vcr/php-vcr": "~1.4", - "php-vcr/phpunit-testlistener-vcr": "~3.2", - "phpro/grumphp": "^0.19", + "php-vcr/php-vcr": "^1.6", + "phpro/grumphp": "^1.7.0", "phpunit/phpunit": "~9.0", "squizlabs/php_codesniffer": "^3.3" }, @@ -51,7 +50,10 @@ ] }, "config": { - "sort-packages": true + "sort-packages": true, + "allow-plugins": { + "phpro/grumphp": true + } }, "repositories": { } diff --git a/phpunit.xml b/phpunit.xml index b344bddb..6a61d330 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,18 +1,19 @@ - - - - - - - ./test/JikanTest - - - ./test/JikanTest/JikanTest.php - - - - - src - - - \ No newline at end of file + + + + + src + + + + + + + + ./test/JikanTest + + + ./test/JikanTest/JikanTest.php + + + diff --git a/readme.md b/readme.md index aa3a6574..c19b0d3f 100755 --- a/readme.md +++ b/readme.md @@ -2,7 +2,7 @@ # Jikan - Unofficial MyAnimeList.net PHP API -[![build](https://travis-ci.org/jikan-me/jikan.svg?branch=master)](https://travis-ci.org/jikan-me/jikan?branch=master) [![build](https://ci.appveyor.com/api/projects/status/github/jikan-me/jikan?branch=master&svg=true)](https://ci.appveyor.com/project/irfan-dahir/jikan) [![stable](https://img.shields.io/packagist/v/jikan-me/jikan.svg?style=flat)](https://packagist.org/packages/jikan-me/jikan) [![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/jikan-me/jikan.svg)](http://isitmaintained.com/project/jikan-me/jikan "Average time to resolve an issue") [![Percentage of issues still open](http://isitmaintained.com/badge/open/jikan-me/jikan.svg)](http://isitmaintained.com/project/jikan-me/jikan "Percentage of issues still open") [![stable](https://img.shields.io/badge/PHP-^%207.1-blue.svg?style=flat)]() [![Discord Server](https://img.shields.io/discord/460491088004907029.svg?style=flat&logo=discord)](https://discord.gg/4tvCr36) +[![build](https://travis-ci.org/jikan-me/jikan.svg?branch=master)](https://travis-ci.org/jikan-me/jikan?branch=master) [![build](https://ci.appveyor.com/api/projects/status/github/jikan-me/jikan?branch=master&svg=true)](https://ci.appveyor.com/project/irfan-dahir/jikan) [![stable](https://img.shields.io/packagist/v/jikan-me/jikan.svg?style=flat)](https://packagist.org/packages/jikan-me/jikan) [![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/jikan-me/jikan.svg)](http://isitmaintained.com/project/jikan-me/jikan "Average time to resolve an issue") [![Percentage of issues still open](http://isitmaintained.com/badge/open/jikan-me/jikan.svg)](http://isitmaintained.com/project/jikan-me/jikan "Percentage of issues still open") [![stable](https://img.shields.io/badge/PHP-^%208.0-blue.svg?style=flat)]() [![Discord Server](https://img.shields.io/discord/460491088004907029.svg?style=flat&logo=discord)](https://discord.gg/4tvCr36) Jikan is a PHP API for [MyAnimeList.net](https://myanimelist.net). It scrapes the website to satisfy the need for API functionality that MyAnimeList.net lacks. @@ -21,7 +21,7 @@ The word _Jikan_ literally translates to _Time_ in Japanese (**時間**). And th | [`~1`](https://github.com/jikan-me/jikan/tree/1.16.3) | ❌ No longer maintained or supported | [![stable](https://img.shields.io/badge/PHP-^%207.0-blue.svg?style=flat)]() | `5.5.*` | -1. `composer require jikan-me/jikan` (This will install version `^2`) +1. `composer require jikan-me/jikan:dev-master` 2. [Documentation](http://docs.jikan.moe) # Jikan REST API @@ -34,7 +34,22 @@ A REST API service is available as well ## Wrappers -[View available wrappers](https://github.com/jikan-me/jikan-rest/blob/master/README.MD#wrappers) +| Language | Wrappers | +|------------|----------| +| JavaScript | [JikanJS](https://github.com/zuritor/jikanjs) by Zuritor | +| Java | [Jikan4java](https://github.com/Doomsdayrs/Jikan4java) by Doomsdayrs
[reactive-jikan](https://github.com/SandroHc/reactive-jikan) by Sandro Marques
[Jaikan](https://github.com/ShindouMihou/Jaikan) by ShindouMihou | +| Python | [JikanPy](https://github.com/abhinavk99/jikanpy) by Abhinav Kasamsetty | +| Node.js | [jikan-node](https://github.com/xy137/jikan-node) by xy137
[jikan-nodejs](https://github.com/ribeirogab/jikan-nodejs) by ribeirogab | +| TypeScript | [jikants](https://github.com/Julien-Broyard/jikants) by Julien Broyard
[jikan-client](https://github.com/javi11/jikan-client) by Javier Blanco | +| PHP | [jikan-php](https://github.com/janvernieuwe/jikan-jikanPHP) by Jan Vernieuwe | +| .NET | [Jikan.net](https://github.com/Ervie/jikan.net) by Ervie | +| Elixir | [JikanEx](https://github.com/seanbreckenridge/jikan_ex) by Sean Breckenridge | +| Go | [jikan-go](https://github.com/darenliang/jikan-go) by Daren Liang
[jikan2go](https://github.com/nokusukun/jikan2go) by nokusukun | +| Ruby | [Jikan.rb](https://github.com/Zerocchi/jikan.rb) by Zerocchi | +| Dart | [jikan-dart](https://github.com/charafau/jikan-dart) by Rafal Wachol | +| Kotlin | [JikanKt](https://github.com/GSculerlor/JikanKt) by Ganedra Afrasya | + +[Add your wrapper here](https://github.com/jikan-me/jikan/edit/master/readme.md) # Features diff --git a/src/Goutte/GoutteWrapper.php b/src/Goutte/GoutteWrapper.php index 2f830872..a0bd139b 100644 --- a/src/Goutte/GoutteWrapper.php +++ b/src/Goutte/GoutteWrapper.php @@ -4,6 +4,7 @@ use Goutte\Client; use Jikan\Exception\BadResponseException; +use Symfony\Component\DomCrawler\Crawler; /** * Class GoutteWrapper @@ -21,7 +22,7 @@ class GoutteWrapper extends Client * @param array $server * @param string|null $content * @param bool $changeHistory - * @return \Symfony\Component\DomCrawler\Crawler + * @return Crawler * @throws BadResponseException */ public function request( @@ -32,7 +33,8 @@ public function request( array $server = [], string $content = null, bool $changeHistory = true - ) { + ) : Crawler + { $response = parent::request( $method, $uri, diff --git a/src/Helper/Constants.php b/src/Helper/Constants.php index 8e082f94..1da83e31 100644 --- a/src/Helper/Constants.php +++ b/src/Helper/Constants.php @@ -37,6 +37,7 @@ class Constants public const TOP_OVA = 'ova'; public const TOP_ONA = 'ona'; public const TOP_SPECIAL = 'special'; + public const TOP_ONA = 'ona'; public const TOP_MANGA = 'manga'; public const TOP_LIGHTNOVELS = 'lightnovels'; @@ -45,6 +46,7 @@ class Constants public const TOP_DOUJINSHI = 'doujin'; public const TOP_MANHWA = 'manhwa'; public const TOP_MANHUA = 'manhua'; + public const TOP_LIGHTNOVELS = 'lightnovels'; public const TOP_BY_POPULARITY = 'bypopularity'; public const TOP_BY_FAVORITES = 'favorite'; @@ -53,6 +55,20 @@ class Constants public const TOP_REVIEW_MANGA = 'manga'; public const TOP_REVIEW_BEST_VOTED = 'bestvoted'; + // v3 status const // remove old ones + public const STATUS_ANIME_AIRING = 1; + public const STATUS_ANIME_FINISHED = 2; + public const STATUS_ANIME_NOT_YET_AIRED = 3; + public const STATUS_MANGA_PUBLISHING = 1; + public const STATUS_MANGA_FINISHED = 2; + public const STATUS_MANGA_NOT_YET_PUBLISHED = 3; + public const STATUS_MANGA_ON_HIATUS = 4; + public const STATUS_MANGA_DISCONTINUED = 5; + + public const TOP_REVIEW_ANIME = 'anime'; + public const TOP_REVIEW_MANGA = 'manga'; + public const TOP_REVIEW_BEST_VOTED = 'bestvoted'; + public const SEARCH_ANIME_TV = 1; public const SEARCH_ANIME_OVA = 2; public const SEARCH_ANIME_MOVIE = 3; diff --git a/src/Helper/JString.php b/src/Helper/JString.php index 60ade611..941b5c6d 100644 --- a/src/Helper/JString.php +++ b/src/Helper/JString.php @@ -16,7 +16,7 @@ class JString */ public static function cleanse(string $string): string { - //
to new line + // convert any html before hand to new line $string = str_replace( ["
", "
", "
", "
"], "\\n", $string ); @@ -25,10 +25,19 @@ public static function cleanse(string $string): string $string = preg_replace('~[[:cntrl:]]~', "", $string); // strip any leftover tags +// $string = htmlspecialchars_decode(strip_tags($string)); $string = strip_tags($string); - // trim + // trim Nbsp // causing serializer issues +// $string = self::UTF8NbspTrim($string); + + + + // remove any newlines at the end $string = str_replace('\\n', "\n", $string); +// $string = preg_replace('~([\n]+)~', '', $string); + + // trim $string = trim($string); return $string; @@ -36,7 +45,6 @@ public static function cleanse(string $string): string /** * @param string $string - * * @return string */ public static function UTF8NbspTrim(string $string): string diff --git a/src/Helper/MalUrlExtractor.php b/src/Helper/MalUrlExtractor.php index 32f61dab..83ed03be 100644 --- a/src/Helper/MalUrlExtractor.php +++ b/src/Helper/MalUrlExtractor.php @@ -55,7 +55,7 @@ public function getMalUrls(): array if (!$this->imageLinks) { $this->crawler->filterXPath('//a/img')->each( function (Crawler $c) { - $node = $c->parents()->first()->getNode(0); + $node = $c->ancestors()->first()->getNode(0); /** * * diff --git a/src/Helper/Media.php b/src/Helper/Media.php new file mode 100644 index 00000000..75316f6a --- /dev/null +++ b/src/Helper/Media.php @@ -0,0 +1,58 @@ +]+)/", + $url, + $matches + ); + + return $matches[1] ?? null; + } + + /** + * @param string $id + * @return string + */ + public static function generateYoutubeUrlFromId(?string $id) : ?string + { + if ($id === null) { + return null; + } + + return sprintf('https://www.youtube.com/watch?v=%s', $id); + } + + /** + * @param string $id + * @return YoutubeImageResource + */ + public static function generateYoutubeImageResource(?string $id) : YoutubeImageResource + { + return YoutubeImageResource::factory($id); + } +} diff --git a/src/Helper/Parser.php b/src/Helper/Parser.php index 53de9237..6cbf39ef 100644 --- a/src/Helper/Parser.php +++ b/src/Helper/Parser.php @@ -152,6 +152,22 @@ public static function parseDateMDYReadable(string $date): ?\DateTimeImmutable return null; } + /** + * @param string $dateTime + * @return \DateTimeImmutable|null + */ + public static function parseDateTimePST(string $dateTime) : ?\DateTimeImmutable + { + try{ + $malTimeZone = new \DateTimeZone('America/Los_Angeles'); // + $parsedDateTime = new \DateTimeImmutable($dateTime,$malTimeZone); + return $parsedDateTime->setTimezone(new \DateTimeZone('UTC')); + } + catch (\Exception $e){ + return null; + } + } + /** * @param Crawler $crawler * diff --git a/src/Model/Anime/Anime.php b/src/Model/Anime/Anime.php index 5fb5f3dc..e927ddcb 100755 --- a/src/Model/Anime/Anime.php +++ b/src/Model/Anime/Anime.php @@ -5,6 +5,8 @@ use Jikan\Model\Common\DateRange; use Jikan\Model\Common\MalUrl; use Jikan\Model\Common\Url; +use Jikan\Model\Common\YoutubeMeta; +use Jikan\Model\Resource\CommonImageResource\CommonImageResource; use Jikan\Parser\Anime\AnimeParser; /** @@ -26,14 +28,14 @@ class Anime private $url; /** - * @var string + * @var CommonImageResource */ - private $imageUrl; + private $images; /** - * @var string|null + * @var YoutubeMeta */ - private $trailerUrl; + private $trailer; /** * @var string @@ -212,11 +214,11 @@ class Anime public static function fromParser(AnimeParser $parser): Anime { $instance = new self(); - $instance->trailerUrl = $parser->getPreview(); + $instance->trailer = YoutubeMeta::factory($parser->getPreview()); $instance->title = $parser->getTitle(); $instance->url = $parser->getURL(); $instance->malId = $parser->getId(); - $instance->imageUrl = $parser->getImageURL(); + $instance->images = CommonImageResource::factory($parser->getImageURL()); $instance->synopsis = $parser->getSynopsis(); $instance->titleEnglish = $parser->getTitleEnglish(); $instance->titleSynonyms = $parser->getTitleSynonyms(); @@ -253,6 +255,38 @@ public static function fromParser(AnimeParser $parser): Anime return $instance; } + /** + * @return MalUrl[] + */ + public function getExplicitGenres(): array + { + return $this->explicitGenres; + } + + /** + * @return MalUrl[] + */ + public function getDemographics(): array + { + return $this->demographics; + } + + /** + * @return MalUrl[] + */ + public function getThemes(): array + { + return $this->themes; + } + + /** + * @return Url[] + */ + public function getExternalLinks(): array + { + return $this->externalLinks; + } + /** * @return int */ @@ -302,19 +336,19 @@ public function getTitleSynonyms(): array } /** - * @return string + * @return CommonImageResource */ - public function getImageUrl(): string + public function getImages(): CommonImageResource { - return $this->imageUrl; + return $this->images; } /** - * @return string|null + * @return YoutubeMeta */ - public function getTrailerUrl(): ?string + public function getTrailer(): YoutubeMeta { - return $this->trailerUrl; + return $this->trailer; } /** @@ -516,29 +550,4 @@ public function getEndingThemes(): array { return $this->endingThemes; } - - /** - * @return MalUrl[] - */ - public function getExplicitGenres(): array - { - return $this->explicitGenres; - } - - /** - * @return MalUrl[] - */ - public function getDemographics(): array - { - return $this->demographics; - } - - /** - * @return MalUrl[] - */ - public function getThemes(): array - { - return $this->themes; - } - } diff --git a/src/Model/Anime/AnimeRecentlyUpdatedByUser.php b/src/Model/Anime/AnimeRecentlyUpdatedByUser.php index 66a1872f..84249a5c 100644 --- a/src/Model/Anime/AnimeRecentlyUpdatedByUser.php +++ b/src/Model/Anime/AnimeRecentlyUpdatedByUser.php @@ -2,6 +2,7 @@ namespace Jikan\Model\Anime; +use Jikan\Model\Common\UserMeta; use Jikan\Parser\Anime\AnimeRecentlyUpdatedByUsersListParser; /** @@ -12,19 +13,9 @@ class AnimeRecentlyUpdatedByUser { /** - * @var string - */ - private $username; - - /** - * @var string + * @var UserMeta */ - private $url; - - /** - * @var string - */ - private $imageUrl; + private $user; /** * @var int|null @@ -61,9 +52,7 @@ public static function fromParser(AnimeRecentlyUpdatedByUsersListParser $parser) { $instance = new self(); - $instance->username = $parser->getUsername(); - $instance->url = $parser->getUrl(); - $instance->imageUrl = $parser->getImageUrl(); + $instance->user = $parser->getUserMeta(); $instance->score = $parser->getScore(); $instance->status = $parser->getStatus(); $instance->episodesSeen = $parser->getEpisodesSeen(); @@ -74,27 +63,11 @@ public static function fromParser(AnimeRecentlyUpdatedByUsersListParser $parser) } /** - * @return string - */ - public function getUsername(): string - { - return $this->username; - } - - /** - * @return string - */ - public function getUrl(): string - { - return $this->url; - } - - /** - * @return string + * @return UserMeta */ - public function getImageUrl(): string + public function getUser(): UserMeta { - return $this->imageUrl; + return $this->user; } /** diff --git a/src/Model/Anime/AnimeReview.php b/src/Model/Anime/AnimeReview.php index d29f9e49..191da679 100644 --- a/src/Model/Anime/AnimeReview.php +++ b/src/Model/Anime/AnimeReview.php @@ -2,60 +2,26 @@ namespace Jikan\Model\Anime; -use Jikan\Parser\Anime\AnimeReviewParser; +use Jikan\Model\Resource\CommonImageResource\CommonImageResource; +use Jikan\Model\Reviews\Reviewer; +use Jikan\Parser\Reviews\AnimeReviewParser; /** - * Class AnimeReview + * Class UserAnimeReview * * @package Jikan\Model */ -class AnimeReview +class AnimeReview extends \Jikan\Model\Reviews\AnimeReview { - - /** - * @var int - */ - private $malId; - - /** - * @var string - */ - private $url; - /** - * @var string + * @var Reviewer */ - private $type; + private $user; /** - * @var int - */ - private $helpfulCount; - - /** - * @var \DateTimeImmutable - */ - private $date; - - /** - * @var AnimeReviewer - */ - private $reviewer; - - /** - * @var string - */ - private $content; - - /** - * Create an instance from an AnimeReviewParser parser - * * @param AnimeReviewParser $parser - * * @return AnimeReview * @throws \Exception - * @throws \RuntimeException - * @throws \InvalidArgumentException */ public static function fromParser(AnimeReviewParser $parser): AnimeReview { @@ -63,68 +29,86 @@ public static function fromParser(AnimeReviewParser $parser): AnimeReview $instance->malId = $parser->getId(); $instance->url = $parser->getUrl(); - $instance->type = $parser->getType(); - $instance->helpfulCount= $parser->getHelpfulCount(); + $instance->type = $parser->getType() ?? 'anime'; + $instance->votes = $parser->getHelpfulCount(); $instance->date = $parser->getDate(); - $instance->reviewer = $parser->getReviewer(); - $instance->content = $parser->getContent(); + $instance->user = $parser->getReviewer(); + $instance->scores = $parser->getAnimeScores(); + $instance->review = $parser->getContent(); + $instance->episodesWatched = $parser->getEpisodesWatched(); return $instance; } /** - * @return int + * @return string */ - public function getMalId(): int + public function getEpisodesWatched(): string { - return $this->malId; + return $this->episodesWatched; } /** - * @return string + * @return AnimeReviewScores */ - public function getUrl(): string + public function getScores(): AnimeReviewScores { - return $this->url; + return $this->scores; } /** - * @return int + * @return Reviewer */ - public function getHelpfulCount(): int + public function getUser(): Reviewer { - return $this->helpfulCount; + return $this->user; } /** - * @return \DateTimeImmutable + * @return int */ - public function getDate(): \DateTimeImmutable + public function getMalId(): int { - return $this->date; + return $this->malId; } /** - * @return AnimeReviewer + * @return string */ - public function getReviewer(): AnimeReviewer + public function getUrl(): string { - return $this->reviewer; + return $this->url; } /** * @return string */ - public function getContent(): string + public function getType(): string { - return $this->content; + return $this->type; + } + + /** + * @return int + */ + public function getVotes(): int + { + return $this->votes; + } + + /** + * @return \DateTimeImmutable + */ + public function getDate(): \DateTimeImmutable + { + return $this->date; } /** * @return string */ - public function getType(): string + public function getReview(): string { - return $this->type; + return $this->review; } } diff --git a/src/Model/Anime/AnimeReviewScores.php b/src/Model/Anime/AnimeReviewScores.php index 0a9a1fd4..c1466cb8 100644 --- a/src/Model/Anime/AnimeReviewScores.php +++ b/src/Model/Anime/AnimeReviewScores.php @@ -43,12 +43,12 @@ class AnimeReviewScores private $enjoyment; /** - * @param Parser\Anime\AnimeReviewScoresParser $parser + * @param Parser\Reviews\AnimeReviewScoresParser $parser * * @return AnimeReviewScores * @throws \InvalidArgumentException */ - public static function fromParser(Parser\Anime\AnimeReviewScoresParser $parser): AnimeReviewScores + public static function fromParser(Parser\Reviews\AnimeReviewScoresParser $parser): AnimeReviewScores { $instance = new self(); diff --git a/src/Model/Anime/AnimeReviewer.php b/src/Model/Anime/AnimeReviewer.php deleted file mode 100644 index b970dfcf..00000000 --- a/src/Model/Anime/AnimeReviewer.php +++ /dev/null @@ -1,84 +0,0 @@ -url= $parser->getUrl(); - $instance->imageUrl = $parser->getImageUrl(); - $instance->username = $parser->getUsername(); - $instance->episodesSeen = $parser->getEpisodesSeen(); - $instance->scores = $parser->getAnimeScores(); - - return $instance; - } - - /** - * @return int - */ - public function getEpisodesSeen(): int - { - return $this->episodesSeen; - } - - /** - * @return AnimeReviewScores - */ - public function getScores(): AnimeReviewScores - { - return $this->scores; - } - - /** - * @return string - */ - public function getUrl(): string - { - return $this->url; - } - - /** - * @return string - */ - public function getImageUrl(): string - { - return $this->imageUrl; - } - - /** - * @return string - */ - public function getUsername(): string - { - return $this->username; - } -} diff --git a/src/Model/Anime/AnimeReviews.php b/src/Model/Anime/AnimeReviews.php new file mode 100644 index 00000000..e9f04e34 --- /dev/null +++ b/src/Model/Anime/AnimeReviews.php @@ -0,0 +1,68 @@ +results = $parser->getResults(); + $instance->hasNextPage = $parser->hasNextPage(); + + return $instance; + } + + /** + * @return static + */ + public static function mock() : self + { + return new self(); + } + + /** + * @return array + */ + public function getResults(): array + { + return $this->results; + } + + /** + * @return bool + */ + public function hasNextPage(): bool + { + return $this->hasNextPage; + } + + /** + * @return int + */ + public function getLastVisiblePage(): int + { + return $this->lastVisiblePage; + } +} diff --git a/src/Model/Anime/AnimeStatsScore.php b/src/Model/Anime/AnimeStatsScore.php index 17ec20a6..9cbbf2f0 100644 --- a/src/Model/Anime/AnimeStatsScore.php +++ b/src/Model/Anime/AnimeStatsScore.php @@ -9,6 +9,11 @@ */ class AnimeStatsScore { + /** + * @var + */ + private $score; + /** * @var int */ @@ -25,16 +30,25 @@ class AnimeStatsScore * @param float $percentage * @return AnimeStats */ - public static function setProperties(int $votes, float $percentage): AnimeStatsScore + public static function setProperties(int $score, int $votes, float $percentage): AnimeStatsScore { $instance = new self(); + $instance->score = $score; $instance->votes = $votes; $instance->percentage = $percentage; return $instance; } + /** + * @return mixed + */ + public function getScore() + { + return $this->score; + } + /** * @return int */ diff --git a/src/Model/Anime/AnimeUserUpdates.php b/src/Model/Anime/AnimeUserUpdates.php new file mode 100644 index 00000000..6665ba0a --- /dev/null +++ b/src/Model/Anime/AnimeUserUpdates.php @@ -0,0 +1,74 @@ +results = $parser->getResults(); + $instance->hasNextPage = $parser->getHasNextPage(); + $instance->lastVisiblePage = $parser->getLastPage(); + + return $instance; + } + + public static function mock() : self + { + return new self(); + } + + /** + * @return bool + */ + public function hasNextPage(): bool + { + return $this->hasNextPage; + } + + /** + * @return int + */ + public function getLastVisiblePage(): int + { + return $this->lastVisiblePage; + } + + /** + * @return array + */ + public function getResults(): array + { + return $this->results; + } +} diff --git a/src/Model/Anime/EpisodeListItem.php b/src/Model/Anime/EpisodeListItem.php index 9dcc9161..c07b472f 100644 --- a/src/Model/Anime/EpisodeListItem.php +++ b/src/Model/Anime/EpisodeListItem.php @@ -15,7 +15,12 @@ class EpisodeListItem /** * @var int */ - public $episodeId; + public $malId; + + /** + * @var string + */ + private $url; /** * @var string @@ -47,11 +52,6 @@ class EpisodeListItem */ public $recap; - /** - * @var string - */ - public $videoUrl; - /** * @var string */ @@ -66,14 +66,14 @@ class EpisodeListItem public static function fromParser(EpisodeListItemParser $parser): self { $instance = new self(); - $instance->episodeId = $parser->getEpisodeId(); + $instance->malId = $parser->getEpisodeId(); $instance->title = $parser->getTitle(); $instance->titleJapanese = $parser->getTitleJapanese(); $instance->titleRomanji = $parser->getTitleRomanji(); $instance->aired = $parser->getAired(); $instance->filler = $parser->getFiller(); $instance->recap = $parser->getRecap(); - $instance->videoUrl = $parser->getVideoUrl(); + $instance->url = $parser->getVideoUrl(); $instance->forumUrl = $parser->getForumUrl(); return $instance; @@ -82,9 +82,9 @@ public static function fromParser(EpisodeListItemParser $parser): self /** * @return int */ - public function getEpisodeId(): int + public function getMalId(): int { - return $this->episodeId; + return $this->malId; } /** @@ -138,9 +138,9 @@ public function isRecap(): bool /** * @return string */ - public function getVideoUrl(): string + public function getUrl(): string { - return $this->videoUrl; + return $this->url; } /** diff --git a/src/Model/Anime/Episodes.php b/src/Model/Anime/Episodes.php index 92f9fbc8..0e270894 100644 --- a/src/Model/Anime/Episodes.php +++ b/src/Model/Anime/Episodes.php @@ -2,6 +2,9 @@ namespace Jikan\Model\Anime; +use Jikan\Model\Common\Collection\Pagination; +use Jikan\Model\Common\Collection\Results; +use Jikan\Model\Reviews\RecentReviews; use Jikan\Parser\Anime\EpisodesParser; /** @@ -9,17 +12,18 @@ * * @package Jikan\Model */ -class Episodes +class Episodes extends Results implements Pagination { + /** - * @var int + * @var bool */ - private $episodesLastPage = 1; + private $hasNextPage = false; /** - * @var EpisodeListItem[] + * @var int */ - private $episodes = []; + private $lastVisiblePage = 1; /** * @param EpisodesParser $parser @@ -30,25 +34,42 @@ class Episodes public static function fromParser(EpisodesParser $parser): self { $instance = new self(); - $instance->episodes = $parser->getEpisodes(); - $instance->episodesLastPage = $parser->getEpisodesLastPage(); + $instance->results = $parser->getEpisodes(); + $instance->lastVisiblePage = $parser->getLastPage(); + $instance->hasNextPage = $parser->getHasNextPage(); return $instance; } /** - * @return EpisodeListItem[] + * @return static */ - public function getEpisodes(): array + public static function mock() : self { - return $this->episodes; + return new self(); + } + + /** + * @return bool + */ + public function hasNextPage(): bool + { + return $this->hasNextPage; } /** * @return int */ - public function getEpisodesLastPage(): int + public function getLastVisiblePage(): int + { + return $this->lastVisiblePage; + } + + /** + * @return array + */ + public function getResults(): array { - return $this->episodesLastPage; + return $this->results; } } diff --git a/src/Model/Anime/PromoListItem.php b/src/Model/Anime/PromoListItem.php index 140b7714..7f8d9967 100644 --- a/src/Model/Anime/PromoListItem.php +++ b/src/Model/Anime/PromoListItem.php @@ -2,6 +2,7 @@ namespace Jikan\Model\Anime; +use Jikan\Model\Common\YoutubeMeta; use Jikan\Parser\Anime\PromoListItemParser; /** @@ -17,14 +18,9 @@ class PromoListItem public $title; /** - * @var string - */ - public $imageUrl; - - /** - * @var string + * @var YoutubeMeta */ - public $videoUrl; + public $trailer; /** * @param PromoListItemParser $parser @@ -36,8 +32,7 @@ public static function fromParser(PromoListItemParser $parser): self { $instance = new self(); $instance->title = $parser->getTitle(); - $instance->videoUrl = $parser->getVideoUrl(); - $instance->imageUrl = $parser->getImageUrl(); + $instance->trailer = YoutubeMeta::factory($parser->getVideoUrl()); return $instance; } @@ -51,18 +46,10 @@ public function getTitle(): string } /** - * @return string - */ - public function getImageUrl(): string - { - return $this->imageUrl; - } - - /** - * @return string + * @return YoutubeMeta */ - public function getVideoUrl(): string + public function getTrailer(): YoutubeMeta { - return $this->videoUrl; + return $this->trailer; } } diff --git a/src/Model/Anime/StaffListItem.php b/src/Model/Anime/StaffListItem.php index 8d84b0e4..c8ad7c19 100755 --- a/src/Model/Anime/StaffListItem.php +++ b/src/Model/Anime/StaffListItem.php @@ -2,34 +2,21 @@ namespace Jikan\Model\Anime; +use Jikan\Model\Common\PersonMeta; +use Jikan\Model\Resource\PersonImageResource\PersonImageResource; use Jikan\Parser\Anime\StaffListItemParser; /** - * Class CharacterParser + * Class StaffListItem * * @package Jikan\Model */ class StaffListItem { /** - * @var int + * @var PersonMeta */ - public $malId; - - /** - * @var string - */ - public $url; - - /** - * @var string - */ - public $name; - - /** - * @var string - */ - public $imageUrl; + public $person; /** * @var string[] @@ -46,44 +33,17 @@ public static function fromParser(StaffListItemParser $parser): self { $instance = new self(); $instance->positions = $parser->getPositions(); - $instance->malId = $parser->getMalId(); - $instance->url = $parser->getUrl(); - $instance->name = $parser->getName(); - $instance->imageUrl = $parser->getImage(); + $instance->person = $parser->getPersonMeta(); return $instance; } /** - * @return int - */ - public function getMalId(): int - { - return $this->malId; - } - - /** - * @return string - */ - public function getName(): string - { - return $this->name; - } - - /** - * @return string - */ - public function getImageUrl(): string - { - return $this->imageUrl; - } - - /** - * @return string + * @return PersonMeta */ - public function getUrl(): string + public function getPerson(): PersonMeta { - return $this->url; + return $this->person; } /** diff --git a/src/Model/Anime/StreamEpisodeListItem.php b/src/Model/Anime/StreamEpisodeListItem.php index 68e8042b..8eda1071 100644 --- a/src/Model/Anime/StreamEpisodeListItem.php +++ b/src/Model/Anime/StreamEpisodeListItem.php @@ -2,6 +2,7 @@ namespace Jikan\Model\Anime; +use Jikan\Model\Resource\WrapImageResource\WrapImageResource; use Jikan\Parser\Anime\StreamEpisodeListItemParser; /** @@ -27,9 +28,9 @@ class StreamEpisodeListItem public $url; /** - * @var string + * @var WrapImageResource */ - public $imageUrl; + public $images; /** * @param StreamEpisodeListItemParser $parser @@ -43,7 +44,7 @@ public static function fromParser(StreamEpisodeListItemParser $parser): self $instance->title = $parser->getTitle(); $instance->episode = $parser->getEpisode(); $instance->url = $parser->getUrl(); - $instance->imageUrl = $parser->getImageUrl(); + $instance->images = WrapImageResource::factory($parser->getImageUrl()); return $instance; } @@ -73,10 +74,10 @@ public function getUrl(): string } /** - * @return string + * @return WrapImageResource */ - public function getImageUrl(): string + public function getImages(): WrapImageResource { - return $this->imageUrl; + return $this->images; } } diff --git a/src/Model/Character/Animeography.php b/src/Model/Character/Animeography.php index 65f4d881..e859ae39 100644 --- a/src/Model/Character/Animeography.php +++ b/src/Model/Character/Animeography.php @@ -2,6 +2,7 @@ namespace Jikan\Model\Character; +use Jikan\Model\Common\AnimeMeta; use Jikan\Model\Common\Ography; use Jikan\Parser\Character\AnimeographyParser; @@ -12,6 +13,11 @@ */ class Animeography extends Ography { + /** + * @var AnimeMeta + */ + private $anime; + /** * @param AnimeographyParser $parser * @@ -21,8 +27,26 @@ class Animeography extends Ography public static function fromParser(AnimeographyParser $parser): Animeography { $instance = new self(); - parent::setProperties($parser, $instance); + + $instance->anime = $parser->getAnimeMeta(); + $instance->role = $parser->getRole(); return $instance; } + + /** + * @return AnimeMeta + */ + public function getAnime(): AnimeMeta + { + return $this->anime; + } + + /** + * @return string + */ + public function getRole(): string + { + return $this->role; + } } diff --git a/src/Model/Character/Character.php b/src/Model/Character/Character.php index a6ec3f61..876b1444 100755 --- a/src/Model/Character/Character.php +++ b/src/Model/Character/Character.php @@ -2,6 +2,7 @@ namespace Jikan\Model\Character; +use Jikan\Model\Resource\CharacterImageResource\CharacterImageResource; use Jikan\Parser; /** @@ -37,7 +38,7 @@ class Character public $nicknames = []; /** - * @var string + * @var string|null */ public $about; @@ -47,9 +48,9 @@ class Character public $memberFavorites; /** - * @var string + * @var CharacterImageResource */ - public $imageUrl; + public $images; /** * @var Animeography[] @@ -86,7 +87,7 @@ public static function fromParser(Parser\Character\CharacterParser $parser): sel $instance->nicknames = $parser->getNameNicknames(); $instance->about = $parser->getAbout(); $instance->memberFavorites = $parser->getMemberFavorites(); - $instance->imageUrl = $parser->getImage(); + $instance->images = CharacterImageResource::factory($parser->getImage()); return $instance; } @@ -102,7 +103,7 @@ public function getMalId(): int /** * @return string */ - public function getCharacterUrl(): string + public function getUrl(): string { return $this->url; } @@ -124,7 +125,7 @@ public function getNameKanji(): ?string } /** - * @return array + * @return string[] */ public function getNicknames(): array { @@ -132,9 +133,9 @@ public function getNicknames(): array } /** - * @return string + * @return string|null */ - public function getAbout(): string + public function getAbout(): ?string { return $this->about; } @@ -148,11 +149,11 @@ public function getMemberFavorites(): int } /** - * @return string + * @return CharacterImageResource */ - public function getImageUrl(): string + public function getImages(): CharacterImageResource { - return $this->imageUrl; + return $this->images; } /** diff --git a/src/Model/Character/CharacterListItem.php b/src/Model/Character/CharacterListItem.php index d6ce0543..fbca49ae 100755 --- a/src/Model/Character/CharacterListItem.php +++ b/src/Model/Character/CharacterListItem.php @@ -2,6 +2,8 @@ namespace Jikan\Model\Character; +use Jikan\Model\Common\CharacterMeta; +use Jikan\Model\Resource\CharacterImageResource\CharacterImageResource; use Jikan\Parser\Character\CharacterListItemParser; /** @@ -12,24 +14,9 @@ class CharacterListItem { /** - * @var int + * @var CharacterMeta */ - public $malId; - - /** - * @var string - */ - public $url; - - /** - * @var string - */ - public $imageUrl; - - /** - * @var string - */ - public $name; + public $character; /** * @var string @@ -52,47 +39,12 @@ public static function fromParser(CharacterListItemParser $parser): self { $instance = new self(); $instance->voiceActors = $parser->getVoiceActors(); - $instance->malId = $parser->getMalId(); - $instance->url = $parser->getCharacterUrl(); - $instance->name = $parser->getName(); + $instance->character = $parser->getCharacterMeta(); $instance->role = $parser->getRole(); - $instance->imageUrl = $parser->getImage(); return $instance; } - /** - * @return string - */ - public function __toString() - { - return $this->name; - } - - /** - * @return int - */ - public function getMalId(): int - { - return $this->malId; - } - - /** - * @return string - */ - public function getUrl(): string - { - return $this->url; - } - - /** - * @return string - */ - public function getName(): string - { - return $this->name; - } - /** * @return string */ @@ -102,11 +54,11 @@ public function getRole(): string } /** - * @return string + * @return CharacterMeta */ - public function getImageUrl(): string + public function getCharacter(): CharacterMeta { - return $this->imageUrl; + return $this->character; } /** diff --git a/src/Model/Character/Mangaography.php b/src/Model/Character/Mangaography.php index 88b55d76..6c700981 100644 --- a/src/Model/Character/Mangaography.php +++ b/src/Model/Character/Mangaography.php @@ -2,6 +2,7 @@ namespace Jikan\Model\Character; +use Jikan\Model\Common\MangaMeta; use Jikan\Model\Common\Ography; use Jikan\Parser\Character\MangaographyParser; @@ -12,6 +13,11 @@ */ class Mangaography extends Ography { + /** + * @var MangaMeta + */ + private $manga; + /** * @param MangaographyParser $parser * @@ -21,8 +27,26 @@ class Mangaography extends Ography public static function fromParser(MangaographyParser $parser): Mangaography { $instance = new self(); - parent::setProperties($parser, $instance); + + $instance->manga = $parser->getMangaMeta(); + $instance->role = $parser->getRole(); return $instance; } + + /** + * @return MangaMeta + */ + public function getManga(): MangaMeta + { + return $this->manga; + } + + /** + * @return string + */ + public function getRole(): string + { + return $this->role; + } } diff --git a/src/Model/Character/VoiceActor.php b/src/Model/Character/VoiceActor.php index f733f862..e0e26fae 100644 --- a/src/Model/Character/VoiceActor.php +++ b/src/Model/Character/VoiceActor.php @@ -2,6 +2,7 @@ namespace Jikan\Model\Character; +use Jikan\Model\Common\PersonMeta; use Jikan\Parser\Character\VoiceActorParser; /** @@ -11,25 +12,11 @@ */ class VoiceActor { - /** - * @var int - */ - private $malId; - - /** - * @var string - */ - private $name; - - /** - * @var string - */ - private $url; /** - * @var string + * @var PersonMeta */ - private $imageUrl; + private $person; /** * @var string @@ -46,54 +33,18 @@ class VoiceActor public static function fromParser(VoiceActorParser $parser): VoiceActor { $instance = new self(); - $instance->malId = $parser->getMalId(); - $instance->url = $parser->getUrl(); - $instance->name = $parser->getName(); - $instance->imageUrl = $parser->getImage(); + $instance->person = $parser->getPersonMeta(); $instance->language = $parser->getLanguage(); - $instance->url = $parser->getUrl(); return $instance; } /** - * @return string - */ - public function __toString() - { - return $this->getName(); - } - - /** - * @return string - */ - public function getName(): string - { - return $this->name; - } - - /** - * @return int - */ - public function getMalId(): int - { - return $this->malId; - } - - /** - * @return string - */ - public function getUrl(): string - { - return $this->url; - } - - /** - * @return string + * @return PersonMeta */ - public function getImageUrl(): string + public function getPerson(): PersonMeta { - return $this->imageUrl; + return $this->person; } /** diff --git a/src/Model/Club/Club.php b/src/Model/Club/Club.php index 3d66e2bb..ecd248cc 100644 --- a/src/Model/Club/Club.php +++ b/src/Model/Club/Club.php @@ -3,6 +3,7 @@ namespace Jikan\Model\Club; use Jikan\Model\Common\MalUrl; +use Jikan\Model\Resource\ClubImageResource\ClubImageResource; use Jikan\Parser\Club\ClubParser; /** @@ -24,24 +25,19 @@ class Club private $url; /** - * @var string + * @var ClubImageResource */ - private $imageUrl; + private $images; /** * @var string */ - private $title; - - /** - * @var int - */ - private $membersCount; + private $name; /** * @var int */ - private $picturesCount; + private $members; /** * @var string @@ -56,7 +52,7 @@ class Club /** * @var string */ - private $type; + private $access; /** * @var MalUrl[] @@ -66,17 +62,17 @@ class Club /** * @var MalUrl[] */ - private $animeRelations; + private $anime; /** * @var MalUrl[] */ - private $mangaRelations; + private $manga; /** * @var MalUrl[] */ - private $characterRelations; + private $characters; /** * @param ClubParser $parser @@ -89,16 +85,16 @@ public static function fromParser(ClubParser $parser): Club $instance->malId = $parser->getMalId(); $instance->url = $parser->getUrl(); - $instance->title = $parser->getTitle(); - $instance->imageUrl = $parser->getImageUrl(); - $instance->membersCount = $parser->getMembersCount(); - $instance->picturesCount = $parser->getPicturesCount(); + $instance->name = $parser->getTitle(); + $instance->images = ClubImageResource::factory($parser->getImageUrl()); + $instance->members = $parser->getMembersCount(); +// $instance->picturesCount = $parser->getPicturesCount(); $instance->category = $parser->getCategory(); $instance->created = $parser->getCreated(); - $instance->animeRelations = $parser->getAnimeRelations(); - $instance->mangaRelations = $parser->getMangaRelations(); - $instance->characterRelations = $parser->getCharacterRelations(); - $instance->type = $parser->getType(); + $instance->anime = $parser->getAnimeRelations(); + $instance->manga = $parser->getMangaRelations(); + $instance->characters = $parser->getCharacterRelations(); + $instance->access = $parser->getType(); $instance->staff = $parser->getStaff(); return $instance; @@ -121,35 +117,27 @@ public function getUrl(): string } /** - * @return string + * @return ClubImageResource */ - public function getImageUrl(): string + public function getImages(): ClubImageResource { - return $this->imageUrl; + return $this->images; } /** * @return string */ - public function getTitle(): string - { - return $this->title; - } - - /** - * @return int - */ - public function getMembersCount(): int + public function getName(): string { - return $this->membersCount; + return $this->name; } /** * @return int */ - public function getPicturesCount(): int + public function getMembers(): int { - return $this->picturesCount; + return $this->members; } /** @@ -171,9 +159,9 @@ public function getCreated(): \DateTimeImmutable /** * @return string */ - public function getType(): string + public function getAccess(): string { - return $this->type; + return $this->access; } /** @@ -187,24 +175,24 @@ public function getStaff(): array /** * @return MalUrl[] */ - public function getAnimeRelations(): array + public function getAnime(): array { - return $this->animeRelations; + return $this->anime; } /** * @return MalUrl[] */ - public function getMangaRelations(): array + public function getManga(): array { - return $this->mangaRelations; + return $this->manga; } /** * @return MalUrl[] */ - public function getCharacterRelations(): array + public function getCharacters(): array { - return $this->characterRelations; + return $this->characters; } } diff --git a/src/Model/Club/UserList.php b/src/Model/Club/UserList.php index 52459fc3..2b4ba9ef 100644 --- a/src/Model/Club/UserList.php +++ b/src/Model/Club/UserList.php @@ -2,6 +2,8 @@ namespace Jikan\Model\Club; +use Jikan\Model\Common\Collection\Pagination; +use Jikan\Model\Common\Collection\Results; use Jikan\Parser\Club\UserListParser; /** @@ -9,23 +11,66 @@ * * @package Jikan\Model\Club */ -class UserList +class UserList extends Results implements Pagination { /** - * @var UserProfile[] + * @var bool */ - private $profiles = []; + private $hasNextPage = false; + + /** + * @var int + */ + private $lastVisiblePage = 1; /** * @param UserListParser $parser * * @return UserList + * @throws \Exception + * @throws \RuntimeException + * @throws \InvalidArgumentException */ public static function fromParser(UserListParser $parser): self { $instance = new self(); - $instance->profiles = $parser->getResults(); + + $instance->results = $parser->getResults(); + $instance->hasNextPage = $parser->hasNextPage(); + $instance->lastVisiblePage = $parser->getLastPage(); return $instance; } + + /** + * @return static + */ + public static function mock() : self + { + return new self(); + } + + /** + * @return array + */ + public function getResults(): array + { + return $this->results; + } + + /** + * @return bool + */ + public function hasNextPage(): bool + { + return $this->hasNextPage; + } + + /** + * @return int + */ + public function getLastVisiblePage(): int + { + return $this->lastVisiblePage; + } } diff --git a/src/Model/Club/UserProfile.php b/src/Model/Club/UserProfile.php index 3fc4fb9d..dfce312e 100644 --- a/src/Model/Club/UserProfile.php +++ b/src/Model/Club/UserProfile.php @@ -2,6 +2,7 @@ namespace Jikan\Model\Club; +use Jikan\Model\Resource\UserImageResource\UserImageResource; use Jikan\Parser\Club\UserProfileParser; /** @@ -22,9 +23,9 @@ class UserProfile private $url; /** - * @var string + * @var UserImageResource */ - private $imageUrl; + private $images; /** * @param UserProfileParser $parser @@ -35,7 +36,7 @@ public static function fromParser(UserProfileParser $parser): self { $instance = new self(); $instance->username = $parser->getUsername(); - $instance->imageUrl = $parser->getImage(); + $instance->images = UserImageResource::factory($parser->getImage()); $instance->url = $parser->getUrl(); return $instance; @@ -58,10 +59,10 @@ public function getUrl(): string } /** - * @return string + * @return UserImageResource */ - public function getImageUrl(): string + public function getImages(): UserImageResource { - return $this->imageUrl; + return $this->images; } } diff --git a/src/Model/Common/AnimeCard.php b/src/Model/Common/AnimeCard.php index 8bb941cd..d52c1de5 100755 --- a/src/Model/Common/AnimeCard.php +++ b/src/Model/Common/AnimeCard.php @@ -2,6 +2,7 @@ namespace Jikan\Model\Common; +use Jikan\Model\Resource\CommonImageResource\CommonImageResource; use Jikan\Parser; /** @@ -27,9 +28,9 @@ class AnimeCard protected $title; /** - * @var string + * @var CommonImageResource */ - protected $imageUrl; + protected $images; /** * @var string|null @@ -133,7 +134,7 @@ protected static function setProperties(Parser\Common\AnimeCardParser $parser, $ $instance->malId = $parser->getMalId(); $instance->url = $parser->getAnimeUrl(); $instance->title = $parser->getTitle(); - $instance->imageUrl = $parser->getAnimeImage(); + $instance->images = CommonImageResource::factory($parser->getAnimeImage()); $instance->synopsis = $parser->getDescription(); $instance->type = $parser->getType(); $instance->airingStart = $parser->getAirDates(); @@ -208,11 +209,11 @@ public function getTitle(): string } /** - * @return string + * @return CommonImageResource */ - public function getImageUrl(): string + public function getImages(): CommonImageResource { - return $this->imageUrl; + return $this->images; } /** diff --git a/src/Model/Common/AnimeMeta.php b/src/Model/Common/AnimeMeta.php index 13b1e20a..3ecf1e24 100644 --- a/src/Model/Common/AnimeMeta.php +++ b/src/Model/Common/AnimeMeta.php @@ -2,11 +2,89 @@ namespace Jikan\Model\Common; +use Jikan\Helper\Parser; +use Jikan\Model\Resource\CommonImageResource\CommonImageResource; + /** * Class AnimeMeta * * @package Jikan\Model */ -class AnimeMeta extends ItemMeta +class AnimeMeta { + /** + * @var int + */ + private $malId; + + /** + * @var string + */ + private $url; + + /** + * @var CommonImageResource + */ + private $images; + + /** + * @var string + */ + private $title; + + /** + * Genre constructor. + * + * @param string $title + * @param string $url + * @param string $imageUrl + */ + public function __construct(string $title, string $url, string $imageUrl) + { + $this->url = $url; + $this->images = CommonImageResource::factory(Parser::parseImageQuality($imageUrl)); + $this->title = $title; + + $this->malId = Parser::idFromUrl($this->url); + } + + /** + * @return string + */ + public function __toString() + { + return $this->title; + } + + /** + * @return int + */ + public function getMalId(): int + { + return $this->malId; + } + + /** + * @return string + */ + public function getUrl(): string + { + return $this->url; + } + + /** + * @return CommonImageResource + */ + public function getImages(): CommonImageResource + { + return $this->images; + } + + /** + * @return string + */ + public function getTitle(): string + { + return $this->title; + } } diff --git a/src/Model/Common/CharacterMeta.php b/src/Model/Common/CharacterMeta.php index a7652c50..50a1e9b8 100644 --- a/src/Model/Common/CharacterMeta.php +++ b/src/Model/Common/CharacterMeta.php @@ -2,11 +2,81 @@ namespace Jikan\Model\Common; +use Jikan\Helper\Parser; +use Jikan\Model\Resource\CharacterImageResource\CharacterImageResource; + /** * Class CharacterMeta * * @package Jikan\Model */ -class CharacterMeta extends ItemMeta +class CharacterMeta { + /** + * @var int + */ + private $malId; + + /** + * @var string + */ + private $url; + + /** + * @var CharacterImageResource + */ + private $images; + + /** + * @var string + */ + private $name; + + /** + * Genre constructor. + * + * @param string $title + * @param string $url + * @param string $imageUrl + */ + public function __construct(string $name, string $url, string $imageUrl) + { + $this->url = $url; + $this->images = CharacterImageResource::factory($imageUrl); + $this->name = $name; + + $this->malId = Parser::idFromUrl($this->url); + } + + /** + * @return int + */ + public function getMalId(): int + { + return $this->malId; + } + + /** + * @return string + */ + public function getUrl(): string + { + return $this->url; + } + + /** + * @return CharacterImageResource + */ + public function getImages(): CharacterImageResource + { + return $this->images; + } + + /** + * @return string + */ + public function getName(): string + { + return $this->name; + } } diff --git a/src/Model/Common/CommonMeta.php b/src/Model/Common/CommonMeta.php new file mode 100644 index 00000000..9380cb16 --- /dev/null +++ b/src/Model/Common/CommonMeta.php @@ -0,0 +1,90 @@ +url = $url; + $this->images = CommonImageResource::factory(Parser::parseImageQuality($imageUrl)); + $this->title = $title; + + $this->malId = Parser::idFromUrl($this->url); + } + + /** + * @return string + */ + public function __toString() + { + return $this->title; + } + + /** + * @return int + */ + public function getMalId(): int + { + return $this->malId; + } + + /** + * @return string + */ + public function getUrl(): string + { + return $this->url; + } + + /** + * @return CommonImageResource + */ + public function getImages(): CommonImageResource + { + return $this->images; + } + + /** + * @return string + */ + public function getTitle(): string + { + return $this->title; + } +} diff --git a/src/Model/Common/DefaultPicture.php b/src/Model/Common/DefaultPicture.php index 2907c6a6..1cc8b1f8 100644 --- a/src/Model/Common/DefaultPicture.php +++ b/src/Model/Common/DefaultPicture.php @@ -38,4 +38,4 @@ public function getImageUrl(): string return $this->imageUrl; } -} \ No newline at end of file +} diff --git a/src/Model/Common/MangaCard.php b/src/Model/Common/MangaCard.php index b47d73df..e8dc645a 100644 --- a/src/Model/Common/MangaCard.php +++ b/src/Model/Common/MangaCard.php @@ -2,6 +2,7 @@ namespace Jikan\Model\Common; +use Jikan\Model\Resource\CommonImageResource\CommonImageResource; use Jikan\Parser; /** @@ -27,9 +28,9 @@ class MangaCard protected $title; /** - * @var string + * @var CommonImageResource */ - protected $imageUrl; + protected $images; /** * @var string @@ -118,7 +119,7 @@ protected static function setProperties(Parser\Common\MangaCardParser $parser, $ $instance->malId = $parser->getMalId(); $instance->url = $parser->getMangaUrl(); $instance->title = $parser->getTitle(); - $instance->imageUrl = $parser->getMangaImage(); + $instance->images = CommonImageResource::factory($parser->getMangaImage()); $instance->synopsis = $parser->getDescription(); $instance->type = $parser->getType(); $instance->publishingStart = $parser->getPublishDates(); @@ -141,6 +142,30 @@ public function __toString() return (string)$this->url; } + /** + * @return MalUrl[] + */ + public function getExplicitGenres(): array + { + return $this->explicitGenres; + } + + /** + * @return MalUrl[] + */ + public function getThemes(): array + { + return $this->themes; + } + + /** + * @return MalUrl[] + */ + public function getDemographics(): array + { + return $this->demographics; + } + /** * @return int */ @@ -166,11 +191,11 @@ public function getTitle(): string } /** - * @return string + * @return CommonImageResource */ - public function getImageUrl(): string + public function getImages(): CommonImageResource { - return $this->imageUrl; + return $this->images; } /** diff --git a/src/Model/Common/MangaMeta.php b/src/Model/Common/MangaMeta.php index 763791af..6b404cb4 100644 --- a/src/Model/Common/MangaMeta.php +++ b/src/Model/Common/MangaMeta.php @@ -2,11 +2,89 @@ namespace Jikan\Model\Common; +use Jikan\Helper\Parser; +use Jikan\Model\Resource\CommonImageResource\CommonImageResource; + /** * Class MangaMeta * * @package Jikan\Model */ -class MangaMeta extends ItemMeta +class MangaMeta { + /** + * @var int + */ + private $malId; + + /** + * @var string + */ + private $url; + + /** + * @var CommonImageResource + */ + private $images; + + /** + * @var string + */ + private $title; + + /** + * Genre constructor. + * + * @param string $title + * @param string $url + * @param string $imageUrl + */ + public function __construct(string $title, string $url, string $imageUrl) + { + $this->url = $url; + $this->images = CommonImageResource::factory(Parser::parseImageQuality($imageUrl)); + $this->title = $title; + + $this->malId = Parser::idFromUrl($this->url); + } + + /** + * @return string + */ + public function __toString() + { + return $this->title; + } + + /** + * @return int + */ + public function getMalId(): int + { + return $this->malId; + } + + /** + * @return string + */ + public function getUrl(): string + { + return $this->url; + } + + /** + * @return CommonImageResource + */ + public function getImages(): CommonImageResource + { + return $this->images; + } + + /** + * @return string + */ + public function getTitle(): string + { + return $this->title; + } } diff --git a/src/Model/Common/Ography.php b/src/Model/Common/Ography.php index 11ac7365..17759d74 100644 --- a/src/Model/Common/Ography.php +++ b/src/Model/Common/Ography.php @@ -11,77 +11,10 @@ */ abstract class Ography { - /** - * @var int - */ - private $malId; - - /** - * @var string - */ - private $name; - - /** - * @var string - */ - private $url; - /** * @var string */ - private $imageUrl; - - /** - * @var string - */ - private $role; - - /** - * @param OgraphyParser $parser - * @param $instance - * - * @throws \InvalidArgumentException - */ - protected static function setProperties($parser, $instance): void - { - $instance->malId = $parser->getMalId(); - $instance->url = $parser->getUrl(); - $instance->name = $parser->getName(); - $instance->imageUrl = $parser->getImage(); - $instance->role = $parser->getRole(); - } - - /** - * @return int - */ - public function getMalId(): int - { - return $this->malId; - } - - /** - * @return string - */ - public function getName(): string - { - return $this->name; - } - - /** - * @return string - */ - public function getUrl(): string - { - return $this->url; - } - - /** - * @return string - */ - public function getImageUrl(): string - { - return $this->imageUrl; - } + protected $role; /** * @return string diff --git a/src/Model/Common/PersonMeta.php b/src/Model/Common/PersonMeta.php index 4d779275..65828528 100644 --- a/src/Model/Common/PersonMeta.php +++ b/src/Model/Common/PersonMeta.php @@ -2,11 +2,81 @@ namespace Jikan\Model\Common; +use Jikan\Helper\Parser; +use Jikan\Model\Resource\PersonImageResource\PersonImageResource; + /** * Class PersonMeta * * @package Jikan\Model */ -class PersonMeta extends ItemMeta +class PersonMeta { + /** + * @var int + */ + private $malId; + + /** + * @var string + */ + private $url; + + /** + * @var PersonImageResource + */ + private $images; + + /** + * @var string + */ + private $name; + + /** + * Genre constructor. + * + * @param string $title + * @param string $url + * @param string $imageUrl + */ + public function __construct(string $name, string $url, string $imageUrl) + { + $this->url = $url; + $this->images = PersonImageResource::factory(Parser::parseImageQuality($imageUrl)); + $this->name = $name; + + $this->malId = Parser::idFromUrl($this->url); + } + + /** + * @return int + */ + public function getMalId(): int + { + return $this->malId; + } + + /** + * @return string + */ + public function getUrl(): string + { + return $this->url; + } + + /** + * @return PersonImageResource + */ + public function getImages(): PersonImageResource + { + return $this->images; + } + + /** + * @return string + */ + public function getName(): string + { + return $this->name; + } } diff --git a/src/Model/Common/Recommendation.php b/src/Model/Common/Recommendation.php index 3acc1eaa..c1650fd9 100644 --- a/src/Model/Common/Recommendation.php +++ b/src/Model/Common/Recommendation.php @@ -2,7 +2,10 @@ namespace Jikan\Model\Common; +use Jikan\Helper\MalUrlExtractor; use Jikan\Helper\Parser; +use Jikan\Model\Resource\CommonImageResource\CommonImageResource; +use Jikan\Parser\Common\MalUrlParser; /** * Class Recommendation @@ -13,34 +16,19 @@ class Recommendation { /** - * @var int + * @var CommonMeta */ - private $malId; + private $entry; /** * @var string */ private $url; - /** - * @var string - */ - private $imageUrl; - - /** - * @var string - */ - private $recommendationUrl; - - /** - * @var string - */ - private $title; - /** * @var int */ - private $recommendationCount; + private $votes; /** * @param \Jikan\Parser\Common\Recommendation $parser @@ -52,22 +40,19 @@ public static function fromParser(\Jikan\Parser\Common\Recommendation $parser): { $instance = new self(); - $instance->url = $parser->getUrl(); - $instance->malId = Parser::idFromUrl($instance->url); - $instance->imageUrl = $parser->getImageUrl(); - $instance->recommendationUrl = $parser->getRecommendationurl(); - $instance->title = $parser->getTitle(); - $instance->recommendationCount = $parser->getRecommendationCount(); + $instance->entry = $parser->getEntryMeta(); + $instance->url = $parser->getRecommendationurl(); + $instance->votes = $parser->getRecommendationCount(); return $instance; } /** - * @return int + * @return CommonMeta */ - public function getMalId(): int + public function getEntry(): CommonMeta { - return $this->malId; + return $this->entry; } /** @@ -78,35 +63,11 @@ public function getUrl(): string return $this->url; } - /** - * @return string - */ - public function getImageUrl(): string - { - return $this->imageUrl; - } - - /** - * @return string - */ - public function getRecommendationUrl(): string - { - return $this->recommendationUrl; - } - - /** - * @return string - */ - public function getTitle(): string - { - return $this->title; - } - /** * @return int */ - public function getRecommendationCount(): int + public function getVotes(): int { - return $this->recommendationCount; + return $this->votes; } } diff --git a/src/Model/Common/Reviewer.php b/src/Model/Common/Reviewer.php deleted file mode 100644 index 841c09e4..00000000 --- a/src/Model/Common/Reviewer.php +++ /dev/null @@ -1,27 +0,0 @@ -url; } -} +} \ No newline at end of file diff --git a/src/Model/Common/UserMeta.php b/src/Model/Common/UserMeta.php new file mode 100644 index 00000000..d116b3af --- /dev/null +++ b/src/Model/Common/UserMeta.php @@ -0,0 +1,76 @@ +url = $url; + $this->images = UserImageResource::factory(Parser::parseImageQuality($imageUrl)); + $this->username = $username; + } + + /** + * @return string + */ + public function __toString() + { + return $this->username; + } + + /** + * @return string + */ + public function getUsername(): string + { + return $this->username; + } + + /** + * @return string + */ + public function getUrl(): string + { + return $this->url; + } + + /** + * @return UserImageResource + */ + public function getImages(): UserImageResource + { + return $this->images; + } +} diff --git a/src/Model/Common/UserMetaBasic.php b/src/Model/Common/UserMetaBasic.php new file mode 100644 index 00000000..a0b07a7b --- /dev/null +++ b/src/Model/Common/UserMetaBasic.php @@ -0,0 +1,21 @@ +username = $username; + $instance->url = $url; + + return $instance; + } +} diff --git a/src/Model/Genre/AnimeGenreList.php b/src/Model/Genre/AnimeGenreList.php index dd5c66d9..ac3f9795 100644 --- a/src/Model/Genre/AnimeGenreList.php +++ b/src/Model/Genre/AnimeGenreList.php @@ -34,6 +34,7 @@ class AnimeGenreList */ public $demographics = []; + /** * @param AnimeGenreListParser $parser * @@ -53,14 +54,6 @@ public static function fromParser(AnimeGenreListParser $parser): self return $instance; } - /** - * @return array|AnimeGenreListItem[] - */ - public function getGenres() - { - return $this->genres; - } - /** * @return array|AnimeGenreListItem[] */ @@ -85,4 +78,11 @@ public function getDemographics(): array return $this->demographics; } + /** + * @return array|AnimeGenreListItem[] + */ + public function getGenres() + { + return $this->genres; + } } diff --git a/src/Model/Genre/MangaGenreList.php b/src/Model/Genre/MangaGenreList.php index 9c839c6e..302d998f 100644 --- a/src/Model/Genre/MangaGenreList.php +++ b/src/Model/Genre/MangaGenreList.php @@ -53,6 +53,30 @@ public static function fromParser(MangaGenreListParser $parser): self return $instance; } + /** + * @return array|MangaGenreListItem[] + */ + public function getExplicitGenres(): array + { + return $this->explicitGenres; + } + + /** + * @return array|MangaGenreListItem[] + */ + public function getThemes(): array + { + return $this->themes; + } + + /** + * @return array|MangaGenreListItem[] + */ + public function getDemographics(): array + { + return $this->demographics; + } + /** * @return array|MangaGenreListItem[] */ diff --git a/src/Model/Manga/CharacterListItem.php b/src/Model/Manga/CharacterListItem.php index 9ad8afcb..9510271f 100755 --- a/src/Model/Manga/CharacterListItem.php +++ b/src/Model/Manga/CharacterListItem.php @@ -2,6 +2,8 @@ namespace Jikan\Model\Manga; +use Jikan\Model\Common\CharacterMeta; +use Jikan\Model\Resource\CharacterImageResource\CharacterImageResource; use Jikan\Parser\Character\CharacterListItemParser; /** @@ -12,24 +14,9 @@ class CharacterListItem { /** - * @var int + * @var CharacterMeta */ - private $malId; - - /** - * @var string - */ - private $url; - - /** - * @var string - */ - private $imageUrl; - - /** - * @var string - */ - private $name; + private $character; /** * @var string @@ -46,52 +33,17 @@ public static function fromParser(CharacterListItemParser $parser): self { $instance = new self(); $instance->role = $parser->getRole(); - $instance->malId = $parser->getMalId(); - $instance->url = $parser->getCharacterUrl(); - $instance->name = $parser->getName(); - $instance->imageUrl = $parser->getImage(); + $instance->character = $parser->getCharacterMeta(); return $instance; } /** - * @return string - */ - public function __toString() - { - return $this->name; - } - - /** - * @return int - */ - public function getMalId(): int - { - return $this->malId; - } - - /** - * @return string - */ - public function getUrl(): string - { - return $this->url; - } - - /** - * @return string - */ - public function getName(): string - { - return $this->name; - } - - /** - * @return string + * @return CharacterMeta */ - public function getImageUrl(): string + public function getCharacter(): CharacterMeta { - return $this->imageUrl; + return $this->character; } /** diff --git a/src/Model/Manga/Manga.php b/src/Model/Manga/Manga.php index 43cba61b..837adb19 100755 --- a/src/Model/Manga/Manga.php +++ b/src/Model/Manga/Manga.php @@ -11,6 +11,7 @@ use Jikan\Model\Common\DateRange; use Jikan\Model\Common\MalUrl; use Jikan\Model\Common\Url; +use Jikan\Model\Resource\CommonImageResource\CommonImageResource; use Jikan\Parser\Manga\MangaParser; /** @@ -57,9 +58,9 @@ class Manga private $status; /** - * @var string + * @var CommonImageResource */ - private $imageUrl; + private $images; /** * @var string|null @@ -183,7 +184,7 @@ public static function fromParser(MangaParser $parser): Manga $instance->title = $parser->getMangaTitle(); $instance->url = $parser->getMangaURL(); $instance->malId = $parser->getMangaId(); - $instance->imageUrl = $parser->getMangaImageURL(); + $instance->images = CommonImageResource::factory($parser->getMangaImageURL()); $instance->synopsis = $parser->getMangaSynopsis(); $instance->titleEnglish = $parser->getMangaTitleEnglish(); $instance->titleSynonyms = $parser->getMangaTitleSynonyms(); @@ -213,6 +214,38 @@ public static function fromParser(MangaParser $parser): Manga return $instance; } + /** + * @return MalUrl[] + */ + public function getExplicitGenres(): array + { + return $this->explicitGenres; + } + + /** + * @return MalUrl[] + */ + public function getDemographics(): array + { + return $this->demographics; + } + + /** + * @return MalUrl[] + */ + public function getThemes(): array + { + return $this->themes; + } + + /** + * @return Url[] + */ + public function getExternalLinks(): array + { + return $this->externalLinks; + } + /** * @return int */ @@ -270,13 +303,14 @@ public function getStatus(): ?string } /** - * @return string + * @return CommonImageResource */ - public function getImageUrl(): string + public function getImages(): CommonImageResource { - return $this->imageUrl; + return $this->images; } + /** * @return string|null */ diff --git a/src/Model/Manga/MangaRecentlyUpdatedByUser.php b/src/Model/Manga/MangaRecentlyUpdatedByUser.php index f3dc1282..77f2eac5 100644 --- a/src/Model/Manga/MangaRecentlyUpdatedByUser.php +++ b/src/Model/Manga/MangaRecentlyUpdatedByUser.php @@ -2,6 +2,7 @@ namespace Jikan\Model\Manga; +use Jikan\Model\Common\UserMeta; use Jikan\Parser\Manga\MangaRecentlyUpdatedByUsersListParser; /** @@ -12,19 +13,9 @@ class MangaRecentlyUpdatedByUser { /** - * @var string - */ - private $username; - - /** - * @var string + * @var UserMeta */ - private $url; - - /** - * @var string - */ - private $imageUrl; + private $user; /** * @var int|null @@ -71,9 +62,7 @@ public static function fromParser(MangaRecentlyUpdatedByUsersListParser $parser) { $instance = new self(); - $instance->username = $parser->getUsername(); - $instance->url = $parser->getUrl(); - $instance->imageUrl = $parser->getImageUrl(); + $instance->user = $parser->getUserMeta(); $instance->score = $parser->getScore(); $instance->status = $parser->getStatus(); $instance->volumesRead = $parser->getVolumesRead(); @@ -86,27 +75,11 @@ public static function fromParser(MangaRecentlyUpdatedByUsersListParser $parser) } /** - * @return string - */ - public function getUsername(): string - { - return $this->username; - } - - /** - * @return string - */ - public function getUrl(): string - { - return $this->url; - } - - /** - * @return string + * @return UserMeta */ - public function getImageUrl(): string + public function getUser(): UserMeta { - return $this->imageUrl; + return $this->user; } /** diff --git a/src/Model/Manga/MangaReview.php b/src/Model/Manga/MangaReview.php index 6803f1a4..c1a06d48 100644 --- a/src/Model/Manga/MangaReview.php +++ b/src/Model/Manga/MangaReview.php @@ -2,60 +2,28 @@ namespace Jikan\Model\Manga; -use Jikan\Parser\Manga\MangaReviewParser; +use Jikan\Model\Resource\CommonImageResource\CommonImageResource; +use Jikan\Model\Reviews\Reviewer; +use Jikan\Parser\Reviews\MangaReviewParser; /** - * Class MangaReview + * Class UserMangaReview * * @package Jikan\Model */ -class MangaReview +class MangaReview extends \Jikan\Model\Reviews\MangaReview { /** - * @var int + * @var Reviewer */ - private $malId; + private $user; - /** - * @var string - */ - private $url; - - /** - * @var string - */ - private $type; - - /** - * @var int - */ - private $helpfulCount; - - /** - * @var \DateTimeImmutable - */ - private $date; - - /** - * @var MangaReviewer - */ - private $reviewer; - - /** - * @var string - */ - private $content; /** - * Create an instance from an MangaReviewParser parser - * * @param MangaReviewParser $parser - * * @return MangaReview * @throws \Exception - * @throws \RuntimeException - * @throws \InvalidArgumentException */ public static function fromParser(MangaReviewParser $parser): MangaReview { @@ -63,68 +31,86 @@ public static function fromParser(MangaReviewParser $parser): MangaReview $instance->malId = $parser->getId(); $instance->url = $parser->getUrl(); - $instance->type = $parser->getType(); - $instance->helpfulCount= $parser->getHelpfulCount(); + $instance->type = $parser->getType() ?? 'manga'; + $instance->votes = $parser->getHelpfulCount(); $instance->date = $parser->getDate(); - $instance->reviewer = $parser->getReviewer(); - $instance->content = $parser->getContent(); + $instance->user = $parser->getReviewer(); + $instance->scores = $parser->getMangaScores(); + $instance->review = $parser->getContent(); + $instance->chaptersRead = $parser->getChaptersRead(); return $instance; } /** - * @return int + * @return string */ - public function getMalId(): int + public function getChaptersRead(): string { - return $this->malId; + return $this->chaptersRead; } /** - * @return string + * @return MangaReviewScores */ - public function getUrl(): string + public function getScores(): MangaReviewScores { - return $this->url; + return $this->scores; } /** - * @return int + * @return Reviewer */ - public function getHelpfulCount(): int + public function getUser(): Reviewer { - return $this->helpfulCount; + return $this->user; } /** - * @return \DateTimeImmutable + * @return int */ - public function getDate(): \DateTimeImmutable + public function getMalId(): int { - return $this->date; + return $this->malId; } /** - * @return MangaReviewer + * @return string */ - public function getReviewer(): MangaReviewer + public function getUrl(): string { - return $this->reviewer; + return $this->url; } /** * @return string */ - public function getContent(): string + public function getType(): string + { + return $this->type; + } + + /** + * @return int + */ + public function getVotes(): int { - return $this->content; + return $this->votes; + } + + /** + * @return \DateTimeImmutable + */ + public function getDate(): \DateTimeImmutable + { + return $this->date; } /** * @return string */ - public function getType(): string + public function getReview(): string { - return $this->type; + return $this->review; } } diff --git a/src/Model/Manga/MangaReviewer.php b/src/Model/Manga/MangaReviewer.php index a1a975bb..7e8d9cdc 100644 --- a/src/Model/Manga/MangaReviewer.php +++ b/src/Model/Manga/MangaReviewer.php @@ -3,6 +3,7 @@ namespace Jikan\Model\Manga; use Jikan\Model\Common\Reviewer; +use Jikan\Model\Resource\UserImageResource\UserImageResource; use Jikan\Parser\Manga\MangaReviewerParser; /** @@ -21,7 +22,7 @@ class MangaReviewer extends Reviewer /** * @var MangaReviewScores */ - private $scores; +// private $scores; /** * @param MangaReviewerParser $parser @@ -34,10 +35,10 @@ public static function fromParser(MangaReviewerParser $parser): MangaReviewer $instance = new self(); $instance->url= $parser->getUrl(); - $instance->imageUrl = $parser->getImageUrl(); + $instance->images = UserImageResource::factory($parser->getImageUrl()); $instance->username = $parser->getUsername(); $instance->chaptersRead = $parser->getChaptersRead(); - $instance->scores = $parser->getMangaScores(); +// $instance->scores = $parser->getMangaScores(); return $instance; } diff --git a/src/Model/Manga/MangaReviews.php b/src/Model/Manga/MangaReviews.php new file mode 100644 index 00000000..8a90f0fd --- /dev/null +++ b/src/Model/Manga/MangaReviews.php @@ -0,0 +1,68 @@ +results = $parser->getResults(); + $instance->hasNextPage = $parser->hasNextPage(); + + return $instance; + } + + /** + * @return static + */ + public static function mock() : self + { + return new self(); + } + + /** + * @return array + */ + public function getResults(): array + { + return $this->results; + } + + /** + * @return bool + */ + public function hasNextPage(): bool + { + return $this->hasNextPage; + } + + /** + * @return int + */ + public function getLastVisiblePage(): int + { + return $this->lastVisiblePage; + } +} diff --git a/src/Model/Manga/MangaStatsScore.php b/src/Model/Manga/MangaStatsScore.php index d1934593..2a10e214 100644 --- a/src/Model/Manga/MangaStatsScore.php +++ b/src/Model/Manga/MangaStatsScore.php @@ -9,6 +9,11 @@ */ class MangaStatsScore { + /** + * @var int + */ + private $score; + /** * @var int */ @@ -25,16 +30,25 @@ class MangaStatsScore * @param float $percentage * @return MangaStatsScore */ - public static function setProperties(int $votes, float $percentage): MangaStatsScore + public static function setProperties(int $score, int $votes, float $percentage): MangaStatsScore { $instance = new self(); + $instance->score = $score; $instance->votes = $votes; $instance->percentage = $percentage; return $instance; } + /** + * @return int + */ + public function getScore(): int + { + return $this->score; + } + /** * @return int */ diff --git a/src/Model/Manga/MangaUserUpdates.php b/src/Model/Manga/MangaUserUpdates.php new file mode 100644 index 00000000..96219b95 --- /dev/null +++ b/src/Model/Manga/MangaUserUpdates.php @@ -0,0 +1,74 @@ +results = $parser->getResults(); + $instance->hasNextPage = $parser->getHasNextPage(); + $instance->lastVisiblePage = $parser->getLastPage(); + + return $instance; + } + + public static function mock() : self + { + return new self(); + } + + /** + * @return bool + */ + public function hasNextPage(): bool + { + return $this->hasNextPage; + } + + /** + * @return int + */ + public function getLastVisiblePage(): int + { + return $this->lastVisiblePage; + } + + /** + * @return array + */ + public function getResults(): array + { + return $this->results; + } +} diff --git a/src/Model/News/NewsListItem.php b/src/Model/News/NewsListItem.php index 4eabe4b7..fdeece48 100644 --- a/src/Model/News/NewsListItem.php +++ b/src/Model/News/NewsListItem.php @@ -2,6 +2,7 @@ namespace Jikan\Model\News; +use Jikan\Model\Resource\WrapImageResource\WrapImageResource; use Jikan\Parser\News\NewsListItemParser; /** @@ -42,9 +43,9 @@ class NewsListItem private $forumUrl; /** - * @var string|null + * @var WrapImageResource */ - private $imageUrl; + private $images; /** * @var int @@ -71,7 +72,7 @@ public static function fromParser(NewsListItemParser $parser): self $instance->authorName = $parser->getAuthor()->getName(); $instance->authorUrl = $parser->getAuthor()->getUrl(); $instance->forumUrl = $parser->getDiscussionLink(); - $instance->imageUrl = $parser->getImage(); + $instance->images = WrapImageResource::factory($parser->getImage()); $instance->comments = $parser->getComments(); $instance->intro = $parser->getIntro(); @@ -127,11 +128,11 @@ public function getForumUrl(): string } /** - * @return string|null + * @return WrapImageResource */ - public function getImageUrl(): ?string + public function getImages(): WrapImageResource { - return $this->imageUrl; + return $this->images; } /** diff --git a/src/Model/Person/AnimeStaffPosition.php b/src/Model/Person/AnimeStaffPosition.php index 9f55e2dd..e7745553 100644 --- a/src/Model/Person/AnimeStaffPosition.php +++ b/src/Model/Person/AnimeStaffPosition.php @@ -20,7 +20,7 @@ class AnimeStaffPosition /** * @var AnimeMeta */ - private $animeMeta; + private $anime; /** * @param AnimeStaffPositionParser $parser @@ -33,7 +33,7 @@ public static function fromParser(AnimeStaffPositionParser $parser): AnimeStaffP { $instance = new self(); $instance->position = $parser->getPosition(); - $instance->animeMeta = $parser->getAnimeMeta(); + $instance->anime = $parser->getAnimeMeta(); return $instance; } diff --git a/src/Model/Person/Person.php b/src/Model/Person/Person.php index 1d93ded4..2dce52d2 100755 --- a/src/Model/Person/Person.php +++ b/src/Model/Person/Person.php @@ -2,6 +2,7 @@ namespace Jikan\Model\Person; +use Jikan\Model\Resource\PersonImageResource\PersonImageResource; use Jikan\Parser\Person\PersonParser; /** @@ -22,9 +23,9 @@ class Person public $url; /** - * @var string + * @var PersonImageResource */ - public $imageUrl; + public $images; /** * @var string|null @@ -94,7 +95,7 @@ public static function fromParser(PersonParser $parser): self $instance = new self(); $instance->malId = $parser->getPersonId(); $instance->url = $parser->getPersonURL(); - $instance->imageUrl = $parser->getPersonImageUrl(); + $instance->images = PersonImageResource::factory($parser->getPersonImageUrl()); $instance->name = $parser->getPersonName(); $instance->givenName = $parser->getPersonGivenName(); $instance->familyName = $parser->getPersonFamilyName(); @@ -127,11 +128,11 @@ public function getUrl(): string } /** - * @return string + * @return PersonImageResource */ - public function getImageUrl(): string + public function getImages(): PersonImageResource { - return $this->imageUrl; + return $this->images; } /** @@ -206,14 +207,6 @@ public function getVoiceActingRoles(): array return $this->voiceActingRoles; } - /** - * @param VoiceActingRole[] $voiceActingRoles - */ - public function setVoiceActingRoles(array $voiceActingRoles): void - { - $this->voiceActingRoles = $voiceActingRoles; - } - /** * @return AnimeStaffPosition[] */ @@ -222,14 +215,6 @@ public function getAnimeStaffPositions(): array return $this->animeStaffPositions; } - /** - * @param AnimeStaffPosition[] $animeStaffPositions - */ - public function setAnimeStaffPositions(array $animeStaffPositions): void - { - $this->animeStaffPositions = $animeStaffPositions; - } - /** * @return PublishedManga[] */ @@ -237,12 +222,4 @@ public function getPublishedManga(): array { return $this->publishedManga; } - - /** - * @param PublishedManga[] $publishedManga - */ - public function setPublishedManga(array $publishedManga): void - { - $this->publishedManga = $publishedManga; - } } diff --git a/src/Model/Person/VoiceActingRole.php b/src/Model/Person/VoiceActingRole.php index 635916ce..5686ab70 100644 --- a/src/Model/Person/VoiceActingRole.php +++ b/src/Model/Person/VoiceActingRole.php @@ -21,12 +21,12 @@ class VoiceActingRole /** * @var AnimeMeta */ - private $animeMeta; + private $anime; /** * @var CharacterMeta */ - private $characterMeta; + private $character; /** * @param VoiceActingRoleParser $parser @@ -39,8 +39,8 @@ public static function fromParser(VoiceActingRoleParser $parser): VoiceActingRol { $instance = new self(); $instance->role = $parser->getRole(); - $instance->animeMeta = $parser->getAnimeMeta(); - $instance->characterMeta = $parser->getCharacterMeta(); + $instance->anime = $parser->getAnimeMeta(); + $instance->character = $parser->getCharacterMeta(); return $instance; } diff --git a/src/Model/Recommendations/RecentRecommendations.php b/src/Model/Recommendations/RecentRecommendations.php new file mode 100644 index 00000000..96d04f36 --- /dev/null +++ b/src/Model/Recommendations/RecentRecommendations.php @@ -0,0 +1,75 @@ +results = $parser->getRecentRecommendations(); + $instance->lastVisiblePage = $parser->getLastPage(); + $instance->hasNextPage = $parser->hasNextPage(); + + return $instance; + } + + /** + * @return static + */ + public static function mock() : self + { + return new self(); + } + + /** + * @return array + */ + public function getResults(): array + { + return $this->results; + } + + /** + * @return bool + */ + public function hasNextPage(): bool + { + return $this->hasNextPage; + } + + /** + * @return int + */ + public function getLastVisiblePage(): int + { + return $this->lastVisiblePage; + } +} diff --git a/src/Model/Recommendations/RecommendationListItem.php b/src/Model/Recommendations/RecommendationListItem.php new file mode 100644 index 00000000..65e85946 --- /dev/null +++ b/src/Model/Recommendations/RecommendationListItem.php @@ -0,0 +1,98 @@ +entry = $parser->getRecommendations(); + $instance->malId = $instance->getEntry()[0]->getMalId() . '-' . $instance->getEntry()[1]->getMalId(); + $instance->content = $parser->getContent(); + $instance->user = $parser->getRecommender(); + $instance->date = $parser->getDate(); + + return $instance; + } + + /** + * @return string + */ + public function getMalId(): string + { + return $this->malId; + } + + /** + * @return CommonMeta[] + */ + public function getEntry(): array + { + return $this->entry; + } + + /** + * @return string + */ + public function getContent(): string + { + return $this->content; + } + + /** + * @return \DateTimeImmutable|null + */ + public function getDate(): ?\DateTimeImmutable + { + return $this->date; + } + + /** + * @return Recommender + */ + public function getUser(): Recommender + { + return $this->user; + } +} diff --git a/src/Model/Recommendations/UserRecommendations.php b/src/Model/Recommendations/UserRecommendations.php new file mode 100644 index 00000000..fb5cdad3 --- /dev/null +++ b/src/Model/Recommendations/UserRecommendations.php @@ -0,0 +1,73 @@ +results = $parser->getUserRecommendations(); + $instance->lastVisiblePage = $parser->getLastPage(); + $instance->hasNextPage = $parser->hasNextPage(); + + return $instance; + } + + /** + * @return static + */ + public static function mock() : self + { + return new self(); + } + + /** + * @return array + */ + public function getResults(): array + { + return $this->results; + } + + /** + * @return bool + */ + public function hasNextPage(): bool + { + return $this->hasNextPage; + } + + /** + * @return int + */ + public function getLastVisiblePage(): int + { + return $this->lastVisiblePage; + } +} diff --git a/src/Model/Resource/AnimeImageResource/AnimeImageResource.php b/src/Model/Resource/AnimeImageResource/AnimeImageResource.php new file mode 100644 index 00000000..150a9146 --- /dev/null +++ b/src/Model/Resource/AnimeImageResource/AnimeImageResource.php @@ -0,0 +1,59 @@ +jpg = Jpg::factory($imageUrl); + $instance->webp = Webp::factory($imageUrl); + + return $instance; + } + + /** + * @return string + */ + public function __toString() : string + { + return $this->getJpg()->getImageUrl(); + } + + /** + * @return Jpg + */ + public function getJpg(): Jpg + { + return $this->jpg; + } + + /** + * @return Webp + */ + public function getWebp(): Webp + { + return $this->webp; + } +} diff --git a/src/Model/Resource/AnimeImageResource/Jpg.php b/src/Model/Resource/AnimeImageResource/Jpg.php new file mode 100644 index 00000000..d01fa8d8 --- /dev/null +++ b/src/Model/Resource/AnimeImageResource/Jpg.php @@ -0,0 +1,71 @@ +imageUrl = $imageUrl; + + if ($instance->imageUrl === null) { + return $instance; + } + + $instance->smallImageUrl = str_replace('.jpg', 't.jpg', $imageUrl); + $instance->largeImageUrl = str_replace('.jpg', 'l.jpg', $imageUrl); + + return $instance; + } + + /** + * @return string|null + */ + public function getImageUrl(): ?string + { + return $this->imageUrl; + } + + /** + * @return string|null + */ + public function getSmallImageUrl(): ?string + { + return $this->smallImageUrl; + } + + /** + * @return string|null + */ + public function getLargeImageUrl(): ?string + { + return $this->largeImageUrl; + } +} diff --git a/src/Model/Resource/AnimeImageResource/Webp.php b/src/Model/Resource/AnimeImageResource/Webp.php new file mode 100644 index 00000000..b5fbfbe4 --- /dev/null +++ b/src/Model/Resource/AnimeImageResource/Webp.php @@ -0,0 +1,71 @@ +imageUrl = str_replace('.jpg', '.webp', $imageUrl); + + if ($instance->imageUrl === null) { + return $instance; + } + + $instance->smallImageUrl = str_replace('.jpg', 't.webp', $imageUrl); + $instance->largeImageUrl = str_replace('.jpg', 'l.webp', $imageUrl); + + return $instance; + } + + /** + * @return string|null + */ + public function getImageUrl(): ?string + { + return $this->imageUrl; + } + + /** + * @return string|null + */ + public function getSmallImageUrl(): ?string + { + return $this->smallImageUrl; + } + + /** + * @return string|null + */ + public function getLargeImageUrl(): ?string + { + return $this->largeImageUrl; + } +} diff --git a/src/Model/Resource/CharacterImageResource/CharacterImageResource.php b/src/Model/Resource/CharacterImageResource/CharacterImageResource.php new file mode 100644 index 00000000..83468a32 --- /dev/null +++ b/src/Model/Resource/CharacterImageResource/CharacterImageResource.php @@ -0,0 +1,60 @@ +jpg = Jpg::factory($imageUrl); + $instance->webp = Webp::factory($imageUrl); + + return $instance; + } + + /** + * @return string + */ + public function __toString() : string + { + return $this->getJpg()->getImageUrl(); + } + + /** + * @return Webp + */ + public function getWebp(): Webp + { + return $this->webp; + } + + /** + * @return Jpg + */ + public function getJpg(): Jpg + { + return $this->jpg; + } +} diff --git a/src/Model/Resource/CharacterImageResource/Jpg.php b/src/Model/Resource/CharacterImageResource/Jpg.php new file mode 100644 index 00000000..9ccf8481 --- /dev/null +++ b/src/Model/Resource/CharacterImageResource/Jpg.php @@ -0,0 +1,41 @@ +imageUrl = $imageUrl; + + if ($instance->imageUrl === null) { + return $instance; + } + + return $instance; + } + + /** + * @return string|null + */ + public function getImageUrl(): ?string + { + return $this->imageUrl; + } +} diff --git a/src/Model/Resource/CharacterImageResource/Webp.php b/src/Model/Resource/CharacterImageResource/Webp.php new file mode 100644 index 00000000..dc3777ae --- /dev/null +++ b/src/Model/Resource/CharacterImageResource/Webp.php @@ -0,0 +1,56 @@ +imageUrl = str_replace('.jpg', '.webp', $imageUrl); + + if ($instance->imageUrl === null) { + return $instance; + } + + $instance->smallImageUrl = str_replace('.jpg', 't.webp', $imageUrl); + + return $instance; + } + + /** + * @return string|null + */ + public function getImageUrl(): ?string + { + return $this->imageUrl; + } + + /** + * @return string|null + */ + public function getSmallImageUrl(): ?string + { + return $this->smallImageUrl; + } +} diff --git a/src/Model/Resource/ClubImageResource/ClubImageResource.php b/src/Model/Resource/ClubImageResource/ClubImageResource.php new file mode 100644 index 00000000..64c64a8b --- /dev/null +++ b/src/Model/Resource/ClubImageResource/ClubImageResource.php @@ -0,0 +1,45 @@ +jpg = Jpg::factory($imageUrl); + + return $instance; + } + + /** + * @return string + */ + public function __toString() : string + { + return $this->getJpg()->getImageUrl(); + } + + /** + * @return Jpg + */ + public function getJpg(): Jpg + { + return $this->jpg; + } +} diff --git a/src/Model/Resource/ClubImageResource/Jpg.php b/src/Model/Resource/ClubImageResource/Jpg.php new file mode 100644 index 00000000..9667d3af --- /dev/null +++ b/src/Model/Resource/ClubImageResource/Jpg.php @@ -0,0 +1,41 @@ +imageUrl = $imageUrl; + + if ($instance->imageUrl === null) { + return $instance; + } + + return $instance; + } + + /** + * @return string|null + */ + public function getImageUrl(): ?string + { + return $this->imageUrl; + } +} diff --git a/src/Model/Resource/CommonImageResource/CommonImageResource.php b/src/Model/Resource/CommonImageResource/CommonImageResource.php new file mode 100644 index 00000000..d7e63a18 --- /dev/null +++ b/src/Model/Resource/CommonImageResource/CommonImageResource.php @@ -0,0 +1,59 @@ +jpg = Jpg::factory($imageUrl); + $instance->webp = Webp::factory($imageUrl); + + return $instance; + } + + /** + * @return string + */ + public function __toString() : string + { + return $this->getJpg()->getImageUrl(); + } + + /** + * @return Jpg + */ + public function getJpg(): Jpg + { + return $this->jpg; + } + + /** + * @return Webp + */ + public function getWebp(): Webp + { + return $this->webp; + } +} diff --git a/src/Model/Resource/CommonImageResource/Jpg.php b/src/Model/Resource/CommonImageResource/Jpg.php new file mode 100644 index 00000000..30663aa3 --- /dev/null +++ b/src/Model/Resource/CommonImageResource/Jpg.php @@ -0,0 +1,71 @@ +imageUrl = $imageUrl; + + if ($instance->imageUrl === null) { + return $instance; + } + + $instance->smallImageUrl = str_replace('.jpg', 't.jpg', $imageUrl); + $instance->largeImageUrl = str_replace('.jpg', 'l.jpg', $imageUrl); + + return $instance; + } + + /** + * @return string|null + */ + public function getImageUrl(): ?string + { + return $this->imageUrl; + } + + /** + * @return string|null + */ + public function getSmallImageUrl(): ?string + { + return $this->smallImageUrl; + } + + /** + * @return string|null + */ + public function getLargeImageUrl(): ?string + { + return $this->largeImageUrl; + } +} diff --git a/src/Model/Resource/CommonImageResource/Webp.php b/src/Model/Resource/CommonImageResource/Webp.php new file mode 100644 index 00000000..87188109 --- /dev/null +++ b/src/Model/Resource/CommonImageResource/Webp.php @@ -0,0 +1,71 @@ +imageUrl = str_replace('.jpg', '.webp', $imageUrl); + + if ($instance->imageUrl === null) { + return $instance; + } + + $instance->smallImageUrl = str_replace('.jpg', 't.webp', $imageUrl); + $instance->largeImageUrl = str_replace('.jpg', 'l.webp', $imageUrl); + + return $instance; + } + + /** + * @return string|null + */ + public function getImageUrl(): ?string + { + return $this->imageUrl; + } + + /** + * @return string|null + */ + public function getSmallImageUrl(): ?string + { + return $this->smallImageUrl; + } + + /** + * @return string|null + */ + public function getLargeImageUrl(): ?string + { + return $this->largeImageUrl; + } +} diff --git a/src/Model/Resource/PersonImageResource/Jpg.php b/src/Model/Resource/PersonImageResource/Jpg.php new file mode 100644 index 00000000..358defcb --- /dev/null +++ b/src/Model/Resource/PersonImageResource/Jpg.php @@ -0,0 +1,49 @@ +imageUrl = $imageUrl; + + if ($instance->imageUrl === null) { + return $instance; + } + + return $instance; + } + + /** + * @return string + */ + public function __toString() : string + { + return $this->getJpg()->getImageUrl(); + } + + /** + * @return string|null + */ + public function getImageUrl(): ?string + { + return $this->imageUrl; + } +} diff --git a/src/Model/Resource/PersonImageResource/PersonImageResource.php b/src/Model/Resource/PersonImageResource/PersonImageResource.php new file mode 100644 index 00000000..37ae4236 --- /dev/null +++ b/src/Model/Resource/PersonImageResource/PersonImageResource.php @@ -0,0 +1,38 @@ +jpg = Jpg::factory($imageUrl); + + return $instance; + } + + /** + * @return Jpg + */ + public function getJpg(): Jpg + { + return $this->jpg; + } +} diff --git a/src/Model/Resource/UserImageResource/Jpg.php b/src/Model/Resource/UserImageResource/Jpg.php new file mode 100644 index 00000000..5f569e76 --- /dev/null +++ b/src/Model/Resource/UserImageResource/Jpg.php @@ -0,0 +1,45 @@ +imageUrl = $imageUrl; + + return $instance; + } + + /** + * @return string + */ + public function __toString() : string + { + return $this->getJpg()->getImageUrl(); + } + + /** + * @return string|null + */ + public function getImageUrl(): ?string + { + return $this->imageUrl; + } +} diff --git a/src/Model/Resource/UserImageResource/UserImageResource.php b/src/Model/Resource/UserImageResource/UserImageResource.php new file mode 100644 index 00000000..3118f8d7 --- /dev/null +++ b/src/Model/Resource/UserImageResource/UserImageResource.php @@ -0,0 +1,51 @@ +jpg = Jpg::factory($imageUrl); + $instance->webp = Webp::factory($imageUrl); + + return $instance; + } + + /** + * @return Jpg + */ + public function getJpg(): Jpg + { + return $this->jpg; + } + + /** + * @return Webp + */ + public function getWebp(): Webp + { + return $this->webp; + } +} diff --git a/src/Model/Resource/UserImageResource/Webp.php b/src/Model/Resource/UserImageResource/Webp.php new file mode 100644 index 00000000..b26ead3e --- /dev/null +++ b/src/Model/Resource/UserImageResource/Webp.php @@ -0,0 +1,37 @@ +imageUrl = str_replace('.jpg', '.webp', $imageUrl); + + return $instance; + } + + /** + * @return string|null + */ + public function getImageUrl(): ?string + { + return $this->imageUrl; + } +} diff --git a/src/Model/Resource/WrapImageResource/Jpg.php b/src/Model/Resource/WrapImageResource/Jpg.php new file mode 100644 index 00000000..3e8238e8 --- /dev/null +++ b/src/Model/Resource/WrapImageResource/Jpg.php @@ -0,0 +1,37 @@ +imageUrl = $imageUrl; + + return $instance; + } + + /** + * @return string|null + */ + public function getImageUrl(): ?string + { + return $this->imageUrl; + } +} diff --git a/src/Model/Resource/WrapImageResource/WrapImageResource.php b/src/Model/Resource/WrapImageResource/WrapImageResource.php new file mode 100644 index 00000000..c5e31e7d --- /dev/null +++ b/src/Model/Resource/WrapImageResource/WrapImageResource.php @@ -0,0 +1,45 @@ +jpg = Jpg::factory($imageUrl); + + return $instance; + } + + /** + * @return string + */ + public function __toString() : string + { + return $this->getJpg()->getImageUrl(); + } + + /** + * @return Jpg + */ + public function getJpg(): Jpg + { + return $this->jpg; + } +} diff --git a/src/Model/Resource/YoutubeImageResource.php b/src/Model/Resource/YoutubeImageResource.php new file mode 100644 index 00000000..c5b59ff8 --- /dev/null +++ b/src/Model/Resource/YoutubeImageResource.php @@ -0,0 +1,106 @@ +imageUrl = sprintf('https://img.youtube.com/vi/%s/default.jpg', $id); + $instance->smallImageUrl = sprintf('https://img.youtube.com/vi/%s/sddefault.jpg', $id); + $instance->mediumImageUrl = sprintf('https://img.youtube.com/vi/%s/mqdefault.jpg', $id); + $instance->largeImageUrl = sprintf('https://img.youtube.com/vi/%s/hqdefault.jpg', $id); + $instance->maximumImageUrl = sprintf('https://img.youtube.com/vi/%s/maxresdefault.jpg', $id); + } + + return $instance; + } + + /** + * @return string|null + */ + public function getImageUrl(): ?string + { + return $this->imageUrl; + } + + /** + * @param string|null $imageUrl + * @return YoutubeImageResource + */ + public function setImageUrl(?string $imageUrl): YoutubeImageResource + { + $this->imageUrl = $imageUrl; + return $this; + } + + /** + * @return string|null + */ + public function getSmallImageUrl(): ?string + { + return $this->smallImageUrl; + } + + /** + * @return string|null + */ + public function getMediumImageUrl(): ?string + { + return $this->mediumImageUrl; + } + + /** + * @return string|null + */ + public function getLargeImageUrl(): ?string + { + return $this->largeImageUrl; + } + + /** + * @return string|null + */ + public function getMaximumImageUrl(): ?string + { + return $this->maximumImageUrl; + } +} diff --git a/src/Model/Reviews/AnimeReview.php b/src/Model/Reviews/AnimeReview.php new file mode 100644 index 00000000..e4b9d2fe --- /dev/null +++ b/src/Model/Reviews/AnimeReview.php @@ -0,0 +1,88 @@ +episodesWatched; + } + + /** + * @return AnimeReviewScores + */ + public function getScores(): AnimeReviewScores + { + return $this->scores; + } + + /** + * @return int + */ + public function getMalId(): int + { + return $this->malId; + } + + /** + * @return string + */ + public function getUrl(): string + { + return $this->url; + } + + /** + * @return string + */ + public function getType(): string + { + return $this->type; + } + + /** + * @return int + */ + public function getVotes(): int + { + return $this->votes; + } + + /** + * @return \DateTimeImmutable + */ + public function getDate(): \DateTimeImmutable + { + return $this->date; + } + + /** + * @return string + */ + public function getReview(): string + { + return $this->review; + } +} diff --git a/src/Model/Reviews/MangaReview.php b/src/Model/Reviews/MangaReview.php new file mode 100644 index 00000000..51eb1e09 --- /dev/null +++ b/src/Model/Reviews/MangaReview.php @@ -0,0 +1,88 @@ +chaptersRead; + } + + /** + * @return MangaReviewScores + */ + public function getScores(): MangaReviewScores + { + return $this->scores; + } + + /** + * @return int + */ + public function getMalId(): int + { + return $this->malId; + } + + /** + * @return string + */ + public function getUrl(): string + { + return $this->url; + } + + /** + * @return string + */ + public function getType(): string + { + return $this->type; + } + + /** + * @return int + */ + public function getVotes(): int + { + return $this->votes; + } + + /** + * @return \DateTimeImmutable + */ + public function getDate(): \DateTimeImmutable + { + return $this->date; + } + + /** + * @return string + */ + public function getReview(): string + { + return $this->review; + } +} diff --git a/src/Model/Reviews/Recent/RecentAnimeReview.php b/src/Model/Reviews/Recent/RecentAnimeReview.php new file mode 100644 index 00000000..eff59c44 --- /dev/null +++ b/src/Model/Reviews/Recent/RecentAnimeReview.php @@ -0,0 +1,130 @@ +entry = $parser->getAnime(); + $instance->malId = $parser->getId(); + $instance->url = $parser->getUrl(); + $instance->type = $parser->getType(); + $instance->votes = $parser->getHelpfulCount(); + $instance->date = $parser->getDate(); + $instance->user = $parser->getReviewer(); + $instance->scores = $parser->getAnimeScores(); + $instance->review = $parser->getContent(); + $instance->episodesWatched = $parser->getEpisodesWatched(); + + return $instance; + } + + /** + * @return string + */ + public function getEpisodesWatched(): string + { + return $this->episodesWatched; + } + + /** + * @return AnimeReviewScores + */ + public function getScores(): AnimeReviewScores + { + return $this->scores; + } + + /** + * @return AnimeMeta + */ + public function getEntry(): AnimeMeta + { + return $this->entry; + } + + /** + * @return Reviewer + */ + public function getUser(): Reviewer + { + return $this->user; + } + + /** + * @return int + */ + public function getMalId(): int + { + return $this->malId; + } + + /** + * @return string + */ + public function getUrl(): string + { + return $this->url; + } + + /** + * @return string + */ + public function getType(): string + { + return $this->type; + } + + /** + * @return int + */ + public function getVotes(): int + { + return $this->votes; + } + + /** + * @return \DateTimeImmutable + */ + public function getDate(): \DateTimeImmutable + { + return $this->date; + } + + /** + * @return string + */ + public function getReview(): string + { + return $this->review; + } +} diff --git a/src/Model/Reviews/Recent/RecentMangaReview.php b/src/Model/Reviews/Recent/RecentMangaReview.php new file mode 100644 index 00000000..209a2fb1 --- /dev/null +++ b/src/Model/Reviews/Recent/RecentMangaReview.php @@ -0,0 +1,135 @@ +entry = $parser->getManga(); + $instance->malId = $parser->getId(); + $instance->url = $parser->getUrl(); + $instance->type = $parser->getType(); + $instance->votes = $parser->getHelpfulCount(); + $instance->date = $parser->getDate(); + $instance->user = $parser->getReviewer(); + $instance->scores = $parser->getMangaScores(); + $instance->review = $parser->getContent(); + $instance->chaptersRead = $parser->getChaptersRead(); + + return $instance; + } + + /** + * @return string + */ + public function getChaptersRead(): string + { + return $this->chaptersRead; + } + + /** + * @return MangaReviewScores + */ + public function getScores(): MangaReviewScores + { + return $this->scores; + } + + /** + * @return MangaMeta + */ + public function getEntry(): MangaMeta + { + return $this->entry; + } + + /** + * @return Reviewer + */ + public function getUser(): Reviewer + { + return $this->user; + } + + /** + * @return int + */ + public function getMalId(): int + { + return $this->malId; + } + + /** + * @return string + */ + public function getUrl(): string + { + return $this->url; + } + + /** + * @return string + */ + public function getType(): string + { + return $this->type; + } + + /** + * @return int + */ + public function getVotes(): int + { + return $this->votes; + } + + /** + * @return \DateTimeImmutable + */ + public function getDate(): \DateTimeImmutable + { + return $this->date; + } + + /** + * @return string + */ + public function getReview(): string + { + return $this->review; + } +} diff --git a/src/Model/Reviews/RecentReviews.php b/src/Model/Reviews/RecentReviews.php new file mode 100644 index 00000000..c9ef08cb --- /dev/null +++ b/src/Model/Reviews/RecentReviews.php @@ -0,0 +1,77 @@ +results = $parser->getRecentReviews(); + $instance->hasNextPage = $parser->hasNextPage(); + + return $instance; + } + + /** + * @return static + */ + public static function mock() : self + { + return new self(); + } + + /** + * @return array + */ + public function getResults(): array + { + return $this->results; + } + + /** + * @return bool + */ + public function hasNextPage(): bool + { + return $this->hasNextPage; + } + + /** + * @return int + */ + public function getLastVisiblePage(): int + { + return $this->lastVisiblePage; + } +} diff --git a/src/Model/Reviews/Review.php b/src/Model/Reviews/Review.php new file mode 100644 index 00000000..adead9b3 --- /dev/null +++ b/src/Model/Reviews/Review.php @@ -0,0 +1,93 @@ +malId; + } + + /** + * @return string + */ + public function getUrl(): string + { + return $this->url; + } + + /** + * @return string + */ + public function getType(): string + { + return $this->type; + } + + /** + * @return int + */ + public function getVotes(): int + { + return $this->votes; + } + + /** + * @return \DateTimeImmutable + */ + public function getDate(): \DateTimeImmutable + { + return $this->date; + } + + /** + * @return string + */ + public function getReview(): string + { + return $this->review; + } +} diff --git a/src/Model/Reviews/Reviewer.php b/src/Model/Reviews/Reviewer.php new file mode 100644 index 00000000..8131fbc2 --- /dev/null +++ b/src/Model/Reviews/Reviewer.php @@ -0,0 +1,57 @@ +url= $parser->getUrl(); + $instance->images = UserImageResource::factory($parser->getImageUrl()); + $instance->username = $parser->getUsername(); + + return $instance; + } + + /** + * @return UserImageResource + */ + public function getImages(): UserImageResource + { + return $this->images; + } + + /** + * @return string + */ + public function getUrl(): string + { + return $this->url; + } + + /** + * @return string + */ + public function getUsername(): string + { + return $this->username; + } +} diff --git a/src/Model/Search/AnimeSearchListItem.php b/src/Model/Search/AnimeSearchListItem.php index 1d85249a..bbe4a5d4 100644 --- a/src/Model/Search/AnimeSearchListItem.php +++ b/src/Model/Search/AnimeSearchListItem.php @@ -2,6 +2,7 @@ namespace Jikan\Model\Search; +use Jikan\Model\Resource\CommonImageResource\CommonImageResource; use Jikan\Parser; /** @@ -22,9 +23,9 @@ class AnimeSearchListItem private $url; /** - * @var string + * @var CommonImageResource */ - private $imageUrl; + private $images; /** * @var string @@ -90,7 +91,7 @@ public static function fromParser(Parser\Search\AnimeSearchListItemParser $parse $instance->url = $parser->getUrl(); $instance->malId = \Jikan\Helper\Parser::idFromUrl($instance->url); - $instance->imageUrl = $parser->getImageUrl(); + $instance->images = CommonImageResource::factory($parser->getImageUrl()); $instance->title = $parser->getTitle(); $instance->synopsis = $parser->getSynopsis(); $instance->type = $parser->getType(); @@ -122,11 +123,11 @@ public function getUrl(): string } /** - * @return string + * @return CommonImageResource */ - public function getImageUrl(): string + public function getImages(): CommonImageResource { - return $this->imageUrl; + return $this->images; } /** diff --git a/src/Model/Search/CharacterSearchListItem.php b/src/Model/Search/CharacterSearchListItem.php index cbe7e712..fdc8f07a 100644 --- a/src/Model/Search/CharacterSearchListItem.php +++ b/src/Model/Search/CharacterSearchListItem.php @@ -2,6 +2,7 @@ namespace Jikan\Model\Search; +use Jikan\Model\Resource\CharacterImageResource\CharacterImageResource; use Jikan\Parser; /** @@ -23,9 +24,9 @@ class CharacterSearchListItem private $url; /** - * @var string + * @var CharacterImageResource */ - private $imageUrl; + private $images; /** * @var string @@ -60,7 +61,7 @@ public static function fromParser(Parser\Search\CharacterSearchListItemParser $p $instance->url = $parser->getUrl(); $instance->malId = \Jikan\Helper\Parser::idFromUrl($instance->url); - $instance->imageUrl = $parser->getImageUrl(); + $instance->images = CharacterImageResource::factory($parser->getImageUrl()); $instance->name = $parser->getName(); $instance->alternativeNames = $parser->getAlternativeNames(); $instance->anime = $parser->getAnime(); @@ -87,11 +88,11 @@ public function getUrl(): string } /** - * @return string + * @return CharacterImageResource */ - public function getImageUrl(): string + public function getImages(): CharacterImageResource { - return $this->imageUrl; + return $this->images; } /** diff --git a/src/Model/Search/MangaSearch.php b/src/Model/Search/MangaSearch.php index a3361ed1..d4c4f676 100644 --- a/src/Model/Search/MangaSearch.php +++ b/src/Model/Search/MangaSearch.php @@ -2,6 +2,8 @@ namespace Jikan\Model\Search; +use Jikan\Model\Common\Collection\Pagination; +use Jikan\Model\Common\Collection\Results; use Jikan\Parser; /** @@ -9,19 +11,18 @@ * * @package Jikan\Model\Search\Search */ -class MangaSearch +class MangaSearch extends Results implements Pagination { /** - * @var MangaSearchListItem[] + * @var bool */ - private $results; + private $hasNextPage = false; /** * @var int */ - private $lastPage; - + private $lastVisiblePage = 1; /** * @param Parser\Search\MangaSearchParser $parser @@ -36,24 +37,38 @@ public static function fromParser(Parser\Search\MangaSearchParser $parser): self $instance = new self(); $instance->results = $parser->getResults(); - $instance->lastPage = $parser->getLastPage(); + $instance->hasNextPage = $parser->getHasNextPage(); + $instance->lastVisiblePage = $parser->getLastPage(); return $instance; } + public static function mock(): self + { + return new self(); + } + /** - * @return MangaSearchListItem[] + * @return bool */ - public function getResults(): array + public function hasNextPage(): bool { - return $this->results; + return $this->hasNextPage; } /** * @return int */ - public function getLastPage(): int + public function getLastVisiblePage(): int { - return $this->lastPage; + return $this->lastVisiblePage; + } + + /** + * @return array + */ + public function getResults(): array + { + return $this->results; } } diff --git a/src/Model/Search/MangaSearchListItem.php b/src/Model/Search/MangaSearchListItem.php index 44287a8e..923956bd 100644 --- a/src/Model/Search/MangaSearchListItem.php +++ b/src/Model/Search/MangaSearchListItem.php @@ -2,6 +2,7 @@ namespace Jikan\Model\Search; +use Jikan\Model\Resource\CommonImageResource\CommonImageResource; use Jikan\Parser; /** @@ -23,9 +24,9 @@ class MangaSearchListItem private $url; /** - * @var string + * @var CommonImageResource */ - private $imageUrl; + private $images; /** * @var string @@ -92,7 +93,7 @@ public static function fromParser(Parser\Search\MangaSearchListItemParser $parse $instance->url = $parser->getUrl(); $instance->malId = \Jikan\Helper\Parser::idFromUrl($instance->url); - $instance->imageUrl = $parser->getImageUrl(); + $instance->images = CommonImageResource::factory($parser->getImageUrl()); $instance->title = $parser->getTitle(); $instance->synopsis = $parser->getSynopsis(); $instance->type = $parser->getType(); @@ -134,13 +135,14 @@ public function getUrl(): string } /** - * @return string + * @return CommonImageResource */ - public function getImageUrl(): string + public function getImages(): CommonImageResource { - return $this->imageUrl; + return $this->images; } + /** * @return string */ diff --git a/src/Model/Search/PersonSearchListItem.php b/src/Model/Search/PersonSearchListItem.php index 6b725cba..fbb6a6b7 100644 --- a/src/Model/Search/PersonSearchListItem.php +++ b/src/Model/Search/PersonSearchListItem.php @@ -2,6 +2,7 @@ namespace Jikan\Model\Search; +use Jikan\Model\Resource\PersonImageResource\PersonImageResource; use Jikan\Parser; /** @@ -23,9 +24,9 @@ class PersonSearchListItem private $url; /** - * @var string + * @var PersonImageResource */ - private $imageUrl; + private $images; /** * @var string @@ -50,7 +51,7 @@ public static function fromParser(Parser\Search\PersonSearchListItemParser $pars $instance->url = $parser->getUrl(); $instance->malId = \Jikan\Helper\Parser::idFromUrl($instance->url); - $instance->imageUrl = $parser->getImageUrl(); + $instance->images = PersonImageResource::factory($parser->getImageUrl()); $instance->name = $parser->getName(); $instance->alternativeNames = $parser->getAlternativeNames(); @@ -71,7 +72,7 @@ public static function fromPersonParser(Parser\Person\PersonParser $parser): sel $instance->url = $parser->getPersonURL(); $instance->malId = \Jikan\Helper\Parser::idFromUrl($instance->url); - $instance->imageUrl = $parser->getPersonImageUrl(); + $instance->images = PersonImageResource::factory($parser->getImageUrl()); $instance->name = $parser->getPersonName(); $instance->alternativeNames = $parser->getPersonAlternateNames(); @@ -96,11 +97,11 @@ public function getUrl(): string } /** - * @return string + * @return PersonImageResource */ - public function getImageUrl(): string + public function getImages(): PersonImageResource { - return $this->imageUrl; + return $this->images; } /** diff --git a/src/Model/Search/UserSearchListItem.php b/src/Model/Search/UserSearchListItem.php new file mode 100644 index 00000000..938ce0c7 --- /dev/null +++ b/src/Model/Search/UserSearchListItem.php @@ -0,0 +1,99 @@ +username = $parser->getUsername(); + $instance->url = $parser->getUrl(); + $instance->images = UserImageResource::factory($parser->getImageUrl()); + $instance->lastOnline = $parser->getLastOnline(); + + return $instance; + } + + + public static function fromUserSearchParser(Parser\User\Profile\UserProfileParser $parser): self + { + $instance = new self(); + + $instance->username = $parser->getUsername(); + $instance->url = $parser->getProfileUrl(); + $instance->images = UserImageResource::factory($parser->getImageUrl()); + $instance->lastOnline = $parser->getLastOnline(); + + return $instance; + } + + /** + * @return string + */ + public function getUsername(): string + { + return $this->username; + } + + /** + * @return string + */ + public function getUrl(): string + { + return $this->url; + } + + /** + * @return UserImageResource + */ + public function getImages(): UserImageResource + { + return $this->images; + } + + /** + * @return \DateTimeImmutable + */ + public function getLastOnline(): \DateTimeImmutable + { + return $this->lastOnline; + } +} diff --git a/src/Model/SeasonList/SeasonArchive.php b/src/Model/SeasonList/SeasonArchive.php new file mode 100644 index 00000000..3e6220e6 --- /dev/null +++ b/src/Model/SeasonList/SeasonArchive.php @@ -0,0 +1,34 @@ +results = $parser->getResults(); + + return $instance; + } + + /** + * @return array + */ + public function getResults(): array + { + return $this->results; + } +} diff --git a/src/Model/Top/TopAnimeListItem.php b/src/Model/Top/TopAnimeListItem.php new file mode 100644 index 00000000..3c667487 --- /dev/null +++ b/src/Model/Top/TopAnimeListItem.php @@ -0,0 +1,192 @@ +rank = $parser->getRank(); + $instance->malId = $parser->getMalUrl()->getMalId(); + $instance->title = $parser->getMalUrl()->getTitle(); + $instance->url = $parser->getMalUrl()->getUrl(); + $instance->type = $parser->getType(); + $instance->episodes = $parser->getEpisodes(); + $instance->startDate = $parser->getStartDate(); + $instance->endDate = $parser->getEndDate(); + $instance->members = $parser->getMembers(); + $instance->score = $parser->getScore(); + $instance->images = CommonImageResource::factory($parser->getImage()); + + return $instance; + } + + /** + * @return string + */ + public function __toString(): string + { + return $this->getTitle(); + } + + /** + * @return int + */ + public function getRank(): int + { + return $this->rank; + } + + /** + * @return int + */ + public function getMalId(): int + { + return $this->malId; + } + + /** + * @return string + */ + public function getTitle(): string + { + return $this->title; + } + + /** + * @return string + */ + public function getUrl(): string + { + return $this->url; + } + + /** + * @return string + */ + public function getType(): string + { + return $this->type; + } + + /** + * @return int|null + */ + public function getEpisodes(): ?int + { + return $this->episodes; + } + + /** + * @return string|null + */ + public function getStartDate(): ?string + { + return $this->startDate; + } + + /** + * @return string|null + */ + public function getEndDate(): ?string + { + return $this->endDate; + } + + /** + * @return int + */ + public function getMembers(): int + { + return $this->members; + } + + /** + * @return float + */ + public function getScore(): float + { + return $this->score; + } + + /** + * @return CommonImageResource + */ + public function getImages(): CommonImageResource + { + return $this->images; + } +} diff --git a/src/Model/Top/TopCharacter.php b/src/Model/Top/TopCharacter.php index ef003fd7..94b1b2f7 100755 --- a/src/Model/Top/TopCharacter.php +++ b/src/Model/Top/TopCharacter.php @@ -3,6 +3,7 @@ namespace Jikan\Model\Top; use Jikan\Model\Common\MalUrl; +use Jikan\Model\Resource\CharacterImageResource\CharacterImageResource; use Jikan\Parser\Top\TopListItemParser; /** @@ -32,6 +33,11 @@ class TopCharacter */ private $url; + /** + * @var CharacterImageResource + */ + private $images; + /** * @var string|null */ @@ -52,11 +58,6 @@ class TopCharacter */ private $favorites; - /** - * @var string - */ - private $imageUrl; - /** * Create an instance from an AnimeParser parser * @@ -77,7 +78,7 @@ public static function fromParser(TopListItemParser $parser): self $instance->animeography = $parser->getAnimeography(); $instance->mangaography = $parser->getMangaography(); $instance->favorites = $parser->getFavorites(); - $instance->imageUrl = $parser->getImage(); + $instance->images = CharacterImageResource::factory($parser->getImage()); return $instance; } @@ -155,10 +156,10 @@ public function getFavorites(): int } /** - * @return string + * @return CharacterImageResource */ - public function getImageUrl(): string + public function getImages(): CharacterImageResource { - return $this->imageUrl; + return $this->images; } } diff --git a/src/Model/Top/TopMangaListItem.php b/src/Model/Top/TopMangaListItem.php new file mode 100644 index 00000000..970c98f9 --- /dev/null +++ b/src/Model/Top/TopMangaListItem.php @@ -0,0 +1,192 @@ +rank = $parser->getRank(); + $instance->malId = $parser->getMalUrl()->getMalId(); + $instance->title = $parser->getMalUrl()->getTitle(); + $instance->url = $parser->getMalUrl()->getUrl(); + $instance->type = $parser->getType(); + $instance->volumes = $parser->getVolumes(); + $instance->startDate = $parser->getStartDate(); + $instance->endDate = $parser->getEndDate(); + $instance->members = $parser->getMembers(); + $instance->score = $parser->getScore(); + $instance->images = CommonImageResource::factory($parser->getImage()); + + return $instance; + } + + /** + * @return string + */ + public function __toString(): string + { + return $this->getTitle(); + } + + /** + * @return int + */ + public function getRank(): int + { + return $this->rank; + } + + /** + * @return int + */ + public function getMalId(): int + { + return $this->malId; + } + + /** + * @return string + */ + public function getTitle(): string + { + return $this->title; + } + + /** + * @return string + */ + public function getUrl(): string + { + return $this->url; + } + + /** + * @return string + */ + public function getType(): string + { + return $this->type; + } + + /** + * @return int|null + */ + public function getVolumes(): ?int + { + return $this->volumes; + } + + /** + * @return string|null + */ + public function getStartDate(): ?string + { + return $this->startDate; + } + + /** + * @return string|null + */ + public function getEndDate(): ?string + { + return $this->endDate; + } + + /** + * @return int + */ + public function getMembers(): int + { + return $this->members; + } + + /** + * @return float + */ + public function getScore(): float + { + return $this->score; + } + + /** + * @return CommonImageResource + */ + public function getImages(): CommonImageResource + { + return $this->images; + } +} diff --git a/src/Model/Top/TopPerson.php b/src/Model/Top/TopPerson.php index 47b88274..3138f6c1 100755 --- a/src/Model/Top/TopPerson.php +++ b/src/Model/Top/TopPerson.php @@ -2,6 +2,7 @@ namespace Jikan\Model\Top; +use Jikan\Model\Resource\PersonImageResource\PersonImageResource; use Jikan\Parser\Top\TopListItemParser; /** @@ -42,9 +43,9 @@ class TopPerson private $favorites; /** - * @var string + * @var PersonImageResource */ - private $imageUrl; + private $images; /** * @var \DateTimeImmutable|null @@ -69,7 +70,7 @@ public static function fromParser(TopListItemParser $parser): self $instance->url = $parser->getMalUrl()->getUrl(); $instance->nameKanji = $parser->getKanjiName(); $instance->favorites = $parser->getPeopleFavorites(); - $instance->imageUrl = $parser->getImage(); + $instance->images = PersonImageResource::factory($parser->getImage()); $instance->birthday = $parser->getBirthday(); return $instance; @@ -132,11 +133,11 @@ public function getFavorites(): int } /** - * @return string + * @return PersonImageResource */ - public function getImageUrl(): string + public function getImages(): PersonImageResource { - return $this->imageUrl; + return $this->images; } /** diff --git a/src/Model/User/AnimeListItem.php b/src/Model/User/AnimeListItem.php index 31823e5d..114ea080 100644 --- a/src/Model/User/AnimeListItem.php +++ b/src/Model/User/AnimeListItem.php @@ -8,6 +8,7 @@ use Jikan\Model\Common\LicensorMeta; use Jikan\Model\Common\MalUrl; use Jikan\Model\Common\StudioMeta; +use Jikan\Model\Resource\CommonImageResource\CommonImageResource; /** * Class AnimeListItem @@ -37,9 +38,9 @@ class AnimeListItem private $url; /** - * @var string + * @var CommonImageResource */ - private $imageUrl; + private $images; /** * @var string @@ -180,13 +181,15 @@ public static function factory(\stdClass $item): self $instance = new self(); $instance->malId = $item->anime_id; - $instance->title = (string) $item->anime_title; - $instance->imageUrl = Parser::parseImageQuality($item->anime_image_path); + $instance->title = $item->anime_title; + $instance->images = CommonImageResource::factory( + Parser::parseImageQuality($item->anime_image_path) + ); $instance->url = Constants::BASE_URL . $item->anime_url; $instance->videoUrl = Constants::BASE_URL . $item->video_url; $instance->watchingStatus = $item->status; $instance->score = $item->score; - $instance->tags = $item->tags === "" ? null : (string) $item->tags; + $instance->tags = empty($item->tags) ? null : $item->tags; $instance->isRewatching = (bool) $item->is_rewatching; $instance->watchedEpisodes = $item->num_watched_episodes; $instance->totalEpisodes = $item->anime_num_episodes; @@ -254,67 +257,67 @@ public static function factory(\stdClass $item): self } /** - * @return bool + * @return int */ - public function isAddedToList(): bool + public function getMalId(): int { - return $this->addedToList; + return $this->malId; } /** - * @return array|MalUrl + * @return string */ - public function getGenres() + public function getTitle(): string { - return $this->genres; + return $this->title; } /** * @return array|MalUrl */ - public function getDemographics() + public function getGenres() { - return $this->demographics; + return $this->genres; } /** - * @return int + * @return array|MalUrl */ - public function getMalId(): int + public function getDemographics() { - return $this->malId; + return $this->demographics; } /** * @return string */ - public function getTitle(): string + public function getVideoUrl(): string { - return $this->title; + return $this->videoUrl; } /** * @return string */ - public function getVideoUrl(): string + public function getUrl(): string { - return $this->videoUrl; + return $this->url; } /** - * @return string + * @return CommonImageResource */ - public function getUrl(): string + public function getImages(): CommonImageResource { - return $this->url; + return $this->images; } /** - * @return string + * @return bool */ - public function getImageUrl(): string + public function isAddedToList(): bool { - return $this->imageUrl; + return $this->addedToList; } /** diff --git a/src/Model/User/BaseLastUpdate.php b/src/Model/User/BaseLastUpdate.php new file mode 100644 index 00000000..55194c40 --- /dev/null +++ b/src/Model/User/BaseLastUpdate.php @@ -0,0 +1,134 @@ +progressedSubEntries = $progressedSubEntries; + $this->total = $total; + $this->status = $status; + $this->score = $score; + $this->date = $date; + $this->url = $url; + $this->title = $title; + $this->imageUrl = $imageUrl; + } + + /** + * @return string + */ + public function getUrl(): string + { + return $this->url; + } + + /** + * @return string + */ + public function getTitle(): string + { + return $this->title; + } + + /** + * @return string + */ + public function getImageUrl(): string + { + return $this->imageUrl; + } + + /** + * @return int|null + */ + public function getProgressedSubEntries(): ?int + { + return $this->progressedSubEntries; + } + + /** + * @return int|null + */ + public function getTotal(): ?int + { + return $this->total; + } + + /** + * @return string + */ + public function getStatus(): string + { + return $this->status; + } + + /** + * @return int|null + */ + public function getScore(): ?int + { + return $this->score; + } + + /** + * @return \DateTimeImmutable + */ + public function getDate(): \DateTimeImmutable + { + return $this->date; + } +} \ No newline at end of file diff --git a/src/Model/User/FavoriteAnime.php b/src/Model/User/FavoriteAnime.php new file mode 100644 index 00000000..70eaa9d9 --- /dev/null +++ b/src/Model/User/FavoriteAnime.php @@ -0,0 +1,13 @@ +entry = new FavoriteCharacterRelatedEntry($malUrl); + } +} diff --git a/src/Model/User/FavoriteCharacterRelatedEntry.php b/src/Model/User/FavoriteCharacterRelatedEntry.php new file mode 100644 index 00000000..4c0bc850 --- /dev/null +++ b/src/Model/User/FavoriteCharacterRelatedEntry.php @@ -0,0 +1,80 @@ +malId = $malUrl->getMalId(); + $this->title = $malUrl->getTitle(); + $this->type = $malUrl->getType(); + $this->url = $malUrl->getUrl(); + } + + /** + * @return int + */ + public function getMalId(): int + { + return $this->malId; + } + + /** + * @return string + */ + public function getTitle(): string + { + return $this->title; + } + + /** + * @return string + */ + public function getType(): string + { + return $this->type; + } + + /** + * @return string + */ + public function getUrl(): string + { + return $this->url; + } +} diff --git a/src/Model/User/FavoriteListEntry.php b/src/Model/User/FavoriteListEntry.php new file mode 100644 index 00000000..e90c5e72 --- /dev/null +++ b/src/Model/User/FavoriteListEntry.php @@ -0,0 +1,55 @@ +type = trim($typeAndYearArr[0]); + $this->startYear = (int) trim($typeAndYearArr[1]); + } + + /** + * @return string + */ + public function getEntityType(): string + { + return $this->type; + } + + /** + * @return int + */ + public function getStartYear(): int + { + return $this->startYear; + } +} diff --git a/src/Model/User/FavoriteManga.php b/src/Model/User/FavoriteManga.php new file mode 100644 index 00000000..628baed4 --- /dev/null +++ b/src/Model/User/FavoriteManga.php @@ -0,0 +1,13 @@ +url = $parser->getUrl(); - $instance->username = $parser->getName(); - $instance->imageUrl = $parser->getAvatar(); + $instance->user = $parser->getUserMeta(); $instance->friendsSince = $parser->getFriendsSince(); $instance->lastOnline = $parser->getLastOnline(); @@ -56,35 +45,11 @@ public static function fromParser(FriendParser $parser): Friend } /** - * @return string - */ - public function __toString() - { - return $this->username; - } - - /** - * @return string - */ - public function getUrl(): string - { - return $this->url; - } - - /** - * @return string - */ - public function getUsername(): string - { - return $this->username; - } - - /** - * @return string + * @return UserMeta */ - public function getImageUrl(): string + public function getUser(): UserMeta { - return $this->imageUrl; + return $this->user; } /** diff --git a/src/Model/User/Friends.php b/src/Model/User/Friends.php new file mode 100644 index 00000000..3dc8b420 --- /dev/null +++ b/src/Model/User/Friends.php @@ -0,0 +1,74 @@ +results = $parser->getResults(); + $instance->hasNextPage = $parser->getHasNextPage(); + $instance->lastVisiblePage = $parser->getLastPage(); + + return $instance; + } + + /** + * @return static + */ + public static function mock() : self + { + return new self(); + } + + /** + * @return bool + */ + public function hasNextPage(): bool + { + return $this->hasNextPage; + } + + /** + * @return int + */ + public function getLastVisiblePage(): int + { + return $this->lastVisiblePage; + } + + /** + * @return array + */ + public function getResults(): array + { + return $this->results; + } +} diff --git a/src/Model/User/LastAnimeUpdate.php b/src/Model/User/LastAnimeUpdate.php new file mode 100644 index 00000000..79a74727 --- /dev/null +++ b/src/Model/User/LastAnimeUpdate.php @@ -0,0 +1,102 @@ +entry = new AnimeMeta($baseLastUpdate->getTitle(), $baseLastUpdate->getUrl(), $baseLastUpdate->getImageUrl()); + $this->score = $baseLastUpdate->getScore(); + $this->status = $baseLastUpdate->getStatus(); + $this->episodesSeen = $baseLastUpdate->getProgressedSubEntries(); + $this->episodesTotal = $baseLastUpdate->getTotal(); + $this->date = $baseLastUpdate->getDate(); + } + + /** + * @return AnimeMeta + */ + public function getEntry(): AnimeMeta + { + return $this->entry; + } + + /** + * @return int|null + */ + public function getScore(): ?int + { + return $this->score; + } + + /** + * @return string + */ + public function getStatus(): string + { + return $this->status; + } + + /** + * @return int|null + */ + public function getEpisodesSeen(): ?int + { + return $this->episodesSeen; + } + + /** + * @return int|null + */ + public function getEpisodesTotal(): ?int + { + return $this->episodesTotal; + } + + /** + * @return \DateTimeImmutable + */ + public function getDate(): \DateTimeImmutable + { + return $this->date; + } +} \ No newline at end of file diff --git a/src/Model/User/LastMangaUpdate.php b/src/Model/User/LastMangaUpdate.php new file mode 100644 index 00000000..1889fe2f --- /dev/null +++ b/src/Model/User/LastMangaUpdate.php @@ -0,0 +1,101 @@ +entry = new MangaMeta($baseLastUpdate->getTitle(), $baseLastUpdate->getUrl(), $baseLastUpdate->getImageUrl()); + $this->score = $baseLastUpdate->getScore(); + $this->status = $baseLastUpdate->getStatus(); + $this->chaptersRead = $baseLastUpdate->getProgressedSubEntries(); + $this->chaptersTotal = $baseLastUpdate->getTotal(); + $this->date = $baseLastUpdate->getDate(); + } + + /** + * @return MangaMeta + */ + public function getEntry(): MangaMeta + { + return $this->entry; + } + + /** + * @return int|null + */ + public function getScore(): ?int + { + return $this->score; + } + + /** + * @return string + */ + public function getStatus(): string + { + return $this->status; + } + + /** + * @return int|null + */ + public function getChaptersRead(): ?int + { + return $this->chaptersRead; + } + + /** + * @return int|null + */ + public function getChaptersTotal(): ?int + { + return $this->chaptersTotal; + } + + /** + * @return \DateTimeImmutable + */ + public function getDate(): \DateTimeImmutable + { + return $this->date; + } +} \ No newline at end of file diff --git a/src/Model/User/LastUpdates.php b/src/Model/User/LastUpdates.php new file mode 100644 index 00000000..dcedfa0a --- /dev/null +++ b/src/Model/User/LastUpdates.php @@ -0,0 +1,44 @@ +anime = $parser->getLastAnimeUpdates(); + $instance->manga = $parser->getLastMangaUpdates(); + return $instance; + } + + /** + * @return array + */ + public function getAnime(): array + { + return $this->anime; + } + + /** + * @return array + */ + public function getManga(): array + { + return $this->manga; + } + +} \ No newline at end of file diff --git a/src/Model/User/MangaListItem.php b/src/Model/User/MangaListItem.php index 575634fa..bbbf77cd 100644 --- a/src/Model/User/MangaListItem.php +++ b/src/Model/User/MangaListItem.php @@ -7,6 +7,7 @@ use Jikan\Helper\Parser; use Jikan\Model\Common\MagazineMeta; use Jikan\Model\Common\MalUrl; +use Jikan\Model\Resource\CommonImageResource\CommonImageResource; /** * Class MangaListItem @@ -31,9 +32,9 @@ class MangaListItem private $url; /** - * @var string + * @var CommonImageResource */ - private $imageUrl; + private $images; /** * @var string @@ -149,12 +150,14 @@ public static function factory(\stdClass $item): self $instance = new self(); $instance->malId = $item->manga_id; - $instance->title = (string) $item->manga_title; - $instance->imageUrl = Parser::parseImageQuality($item->manga_image_path); + $instance->title = $item->manga_title; + $instance->images = CommonImageResource::factory( + Parser::parseImageQuality($item->manga_image_path) + ); $instance->url = Constants::BASE_URL . $item->manga_url; $instance->readingStatus = $item->status; $instance->score = $item->score; - $instance->tags = $item->tags === "" ? null : (string) $item->tags; + $instance->tags = empty($item->tags) ? null : $item->tags; $instance->isRereading = (bool) $item->is_rereading; $instance->readChapters = $item->num_read_chapters; $instance->readVolumes = $item->num_read_volumes; @@ -204,51 +207,51 @@ public static function factory(\stdClass $item): self } /** - * @return array|MalUrl + * @return int */ - public function getGenres() + public function getMalId(): int { - return $this->genres; + return $this->malId; } /** - * @return array|MalUrl + * @return string */ - public function getDemographics() + public function getTitle(): string { - return $this->demographics; + return $this->title; } /** - * @return int + * @return string */ - public function getMalId(): int + public function getUrl(): string { - return $this->malId; + return $this->url; } /** - * @return string + * @return CommonImageResource */ - public function getTitle(): string + public function getImages(): CommonImageResource { - return $this->title; + return $this->images; } /** - * @return string + * @return array|MalUrl */ - public function getUrl(): string + public function getGenres() { - return $this->url; + return $this->genres; } /** - * @return string + * @return array|MalUrl */ - public function getImageUrl(): string + public function getDemographics() { - return $this->imageUrl; + return $this->demographics; } /** @@ -324,7 +327,7 @@ public function isRereading(): bool } /** - * @return null|string + * @return string|null */ public function getTags(): ?string { @@ -364,7 +367,7 @@ public function getReadEndDate(): ?\DateTimeImmutable } /** - * @return null|string + * @return string|null */ public function getDays(): ?string { @@ -372,7 +375,7 @@ public function getDays(): ?string } /** - * @return null|string + * @return string|null */ public function getRetail(): ?string { diff --git a/src/Model/User/Profile.php b/src/Model/User/Profile.php index 27439944..d8900730 100644 --- a/src/Model/User/Profile.php +++ b/src/Model/User/Profile.php @@ -2,6 +2,7 @@ namespace Jikan\Model\User; +use Jikan\Model\Resource\UserImageResource\UserImageResource; use Jikan\Parser\User\Profile\UserProfileParser; /** @@ -15,7 +16,7 @@ class Profile /** * @var int|null */ - private $userId; + private $malId; /** * @var string @@ -28,9 +29,9 @@ class Profile private $url; /** - * @var string|null + * @var UserImageResource */ - private $imageUrl; + private $images; /** * @var \DateTimeImmutable|null @@ -72,6 +73,11 @@ class Profile */ private $favorites; + /** + * @var LastUpdates + */ + private $lastUpdates; + /** * @var string|null */ @@ -87,10 +93,10 @@ class Profile public static function fromParser(UserProfileParser $parser): self { $instance = new self(); - $instance->userId = $parser->getUserId(); + $instance->malId = $parser->getUserId(); $instance->username = $parser->getUsername(); $instance->url = $parser->getProfileUrl(); - $instance->imageUrl = $parser->getImageUrl(); + $instance->images = UserImageResource::factory($parser->getImageUrl()); $instance->joined = $parser->getJoinDate(); $instance->lastOnline = $parser->getLastOnline(); $instance->gender = $parser->getGender(); @@ -100,6 +106,7 @@ public static function fromParser(UserProfileParser $parser): self $instance->mangaStats = $parser->getMangaStats(); $instance->about = $parser->getAbout(); $instance->favorites = $parser->getFavorites(); + $instance->lastUpdates = $parser->getUserLastUpdates(); return $instance; } @@ -107,9 +114,9 @@ public static function fromParser(UserProfileParser $parser): self /** * @return int|null */ - public function getUserId(): int + public function getMalId(): ?int { - return $this->userId; + return $this->malId; } /** @@ -201,10 +208,18 @@ public function getUrl(): string } /** - * @return null|string + * @return UserImageResource + */ + public function getImages(): UserImageResource + { + return $this->images; + } + + /** + * @return LastUpdates */ - public function getImageUrl(): ?string + public function getLastUpdates(): LastUpdates { - return $this->imageUrl; + return $this->lastUpdates; } } diff --git a/src/Model/User/Reviews/UserAnimeReview.php b/src/Model/User/Reviews/UserAnimeReview.php new file mode 100644 index 00000000..49fafc35 --- /dev/null +++ b/src/Model/User/Reviews/UserAnimeReview.php @@ -0,0 +1,118 @@ +entry = $parser->getAnime(); + $instance->malId = $parser->getId(); + $instance->url = $parser->getUrl(); + $instance->type = $parser->getType(); + $instance->votes = $parser->getHelpfulCount(); + $instance->date = $parser->getDate(); + $instance->scores = $parser->getAnimeScores(); + $instance->review = $parser->getContent(); + $instance->episodesWatched = $parser->getEpisodesWatched(); + + return $instance; + } + + /** + * @return string + */ + public function getEpisodesWatched(): string + { + return $this->episodesWatched; + } + + /** + * @return AnimeReviewScores + */ + public function getScores(): AnimeReviewScores + { + return $this->scores; + } + + /** + * @return int + */ + public function getMalId(): int + { + return $this->malId; + } + + /** + * @return string + */ + public function getUrl(): string + { + return $this->url; + } + + /** + * @return string + */ + public function getType(): string + { + return $this->type; + } + + /** + * @return int + */ + public function getVotes(): int + { + return $this->votes; + } + + /** + * @return \DateTimeImmutable + */ + public function getDate(): \DateTimeImmutable + { + return $this->date; + } + + /** + * @return string + */ + public function getReview(): string + { + return $this->review; + } + + /** + * @return AnimeMeta + */ + public function getEntry(): AnimeMeta + { + return $this->entry; + } +} diff --git a/src/Model/User/Reviews/UserMangaReview.php b/src/Model/User/Reviews/UserMangaReview.php new file mode 100644 index 00000000..9ecee36a --- /dev/null +++ b/src/Model/User/Reviews/UserMangaReview.php @@ -0,0 +1,116 @@ +entry = $parser->getManga(); + $instance->malId = $parser->getId(); + $instance->url = $parser->getUrl(); + $instance->type = $parser->getType(); + $instance->votes = $parser->getHelpfulCount(); + $instance->date = $parser->getDate(); + $instance->scores = $parser->getMangaScores(); + $instance->review = $parser->getContent(); + $instance->chaptersRead = $parser->getChaptersRead(); + + return $instance; + } + + /** + * @return string + */ + public function getChaptersRead(): string + { + return $this->chaptersRead; + } + + /** + * @return MangaReviewScores + */ + public function getScores(): MangaReviewScores + { + return $this->scores; + } + + /** + * @return int + */ + public function getMalId(): int + { + return $this->malId; + } + + /** + * @return string + */ + public function getUrl(): string + { + return $this->url; + } + + /** + * @return string + */ + public function getType(): string + { + return $this->type; + } + + /** + * @return int + */ + public function getVotes(): int + { + return $this->votes; + } + + /** + * @return \DateTimeImmutable + */ + public function getDate(): \DateTimeImmutable + { + return $this->date; + } + + /** + * @return string + */ + public function getReview(): string + { + return $this->review; + } + + /** + * @return MangaMeta + */ + public function getEntry(): MangaMeta + { + return $this->entry; + } +} diff --git a/src/Model/User/Reviews/UserReviews.php b/src/Model/User/Reviews/UserReviews.php new file mode 100644 index 00000000..68197db9 --- /dev/null +++ b/src/Model/User/Reviews/UserReviews.php @@ -0,0 +1,72 @@ +results = $parser->getReviews(); + $instance->lastVisiblePage = $parser->getLastVisiblePage(); + $instance->hasNextPage = $parser->hasNextPage(); + + return $instance; + } + + /** + * @return static + */ + public static function mock() : self + { + return new self(); + } + + /** + * @return array + */ + public function getResults(): array + { + return $this->results; + } + + /** + * @return bool + */ + public function hasNextPage(): bool + { + return $this->hasNextPage; + } + + /** + * @return int + */ + public function getLastVisiblePage(): int + { + return $this->lastVisiblePage; + } +} diff --git a/src/Model/Watch/EpisodeListItem.php b/src/Model/Watch/EpisodeListItem.php new file mode 100644 index 00000000..e2891ba4 --- /dev/null +++ b/src/Model/Watch/EpisodeListItem.php @@ -0,0 +1,71 @@ +entry = $parser->getAnimeMeta(); + $instance->episodes = $parser->getEpisodes(); + $instance->regionLocked = $parser->getRegionLocked(); + + return $instance; + } + + /** + * @return AnimeMeta + */ + public function getEntry(): AnimeMeta + { + return $this->entry; + } + + /** + * @return RecentEpisodeListItem + */ + public function getEpisodes(): RecentEpisodeListItem + { + return $this->episodes; + } + + /** + * @return bool + */ + public function isRegionLocked(): bool + { + return $this->regionLocked; + } +} diff --git a/src/Model/Watch/PromotionalVideoListItem.php b/src/Model/Watch/PromotionalVideoListItem.php new file mode 100644 index 00000000..e5773914 --- /dev/null +++ b/src/Model/Watch/PromotionalVideoListItem.php @@ -0,0 +1,76 @@ +entry = new AnimeMeta( + $parser->getTitle(), + $parser->getUrl(), + $parser->getImages() + ); + $instance->title = $parser->getPromoTitle(); + $instance->trailer = $parser->getPromoMedia(); + + return $instance; + } + + /** + * @return string + */ + public function getTitle(): string + { + return $this->title; + } + + /** + * @return AnimeMeta + */ + public function getEntry(): AnimeMeta + { + return $this->entry; + } + + /** + * @return YoutubeMeta + */ + public function getTrailer(): YoutubeMeta + { + return $this->trailer; + } +} diff --git a/src/Model/Watch/RecentEpisodeListItem.php b/src/Model/Watch/RecentEpisodeListItem.php new file mode 100644 index 00000000..efc76216 --- /dev/null +++ b/src/Model/Watch/RecentEpisodeListItem.php @@ -0,0 +1,85 @@ +malId = $malId; + $instance->url = $url; + $instance->title = $title; + $instance->premium = $premium; + + return $instance; + } + + /** + * @return int + */ + public function getMalId(): int + { + return $this->malId; + } + + /** + * @return string + */ + public function getUrl(): string + { + return $this->url; + } + + /** + * @return string + */ + public function getTitle(): string + { + return $this->title; + } + + /** + * @return bool + */ + public function isPremium(): bool + { + return $this->premium; + } +} diff --git a/src/MyAnimeList/MalClient.php b/src/MyAnimeList/MalClient.php index 4347ca6b..77079046 100644 --- a/src/MyAnimeList/MalClient.php +++ b/src/MyAnimeList/MalClient.php @@ -1,23 +1,24 @@ ghoutte = new GoutteWrapper(); - if ($guzzle !== null) { - $this->ghoutte->setClient($guzzle); - } + $this->httpClient = $httpClient ?? HttpClient::create(); + $this->ghoutte = new GoutteWrapper($this->httpClient); } /** @@ -136,6 +140,10 @@ public function getManga(Request\Manga\MangaRequest $request): Model\Manga\Manga */ public function getCharacter(Request\Character\CharacterRequest $request): Model\Character\Character { + if ($request->getId() === 0) { + throw new BadResponseException(sprintf('404 on %s', $request->getPath()), 404); + } + $crawler = $this->ghoutte->request('GET', $request->getPath()); // MAL returns `Invalid ID provided.` instead of 404 on invalid characters @@ -162,6 +170,10 @@ public function getCharacter(Request\Character\CharacterRequest $request): Model */ public function getPerson(Request\Person\PersonRequest $request): Model\Person\Person { + if ($request->getId() === 0) { + throw new BadResponseException(sprintf('404 on %s', $request->getPath()), 404); + } + $crawler = $this->ghoutte->request('GET', $request->getPath()); try { $parser = new Parser\Person\PersonParser($crawler); @@ -191,12 +203,12 @@ public function getUserProfile(Request\User\UserProfileRequest $request): Model\ } /** - * @param Request\User\UserFriendsRequest $request - * @return array + * @param Request\User\UserFriendsRequest $request + * @return Model\User\Friends * @throws BadResponseException * @throws ParserException */ - public function getUserFriends(Request\User\UserFriendsRequest $request): array + public function getUserFriends(Request\User\UserFriendsRequest $request): Model\User\Friends { $crawler = $this->ghoutte->request('GET', $request->getPath()); try { @@ -411,11 +423,11 @@ public function getPersonPictures(Request\Person\PersonPicturesRequest $request) /** * @param Request\RequestInterface $request * - * @return Model\News\NewsListItem[] + * @return Model\News\NewsList * @throws BadResponseException * @throws ParserException */ - public function getNewsList(Request\RequestInterface $request): array + public function getNewsList(Request\RequestInterface $request): Model\News\NewsList { $crawler = $this->ghoutte->request('GET', $request->getPath()); try { @@ -437,6 +449,30 @@ public function getNewsList(Request\RequestInterface $request): array public function getAnimeSearch(Request\Search\AnimeSearchRequest $request): Model\Search\AnimeSearch { $crawler = $this->ghoutte->request('GET', $request->getPath()); + +// if ($this->ghoutte->getInternalResponse()->getStatusCode()) { +// return Model\Search\AnimeSearch::mock(); +// } + + try { + $parser = new Parser\Search\AnimeSearchParser($crawler); + + return $parser->getModel(); + } catch (\Exception $e) { + throw ParserException::fromRequest($request, $e); + } + } + + /** + * @param Request\Search\AnimeSearchRequest $request + * + * @return Model\Search\AnimeSearch + * @throws BadResponseException + * @throws ParserException + */ + public function getAnimeSearchAlt(Request\Search\AnimeSearchRequest $request): Model\Search\AnimeSearchAlt + { + $crawler = $this->ghoutte->request('GET', $request->getPath()); try { $parser = new Parser\Search\AnimeSearchParser($crawler); @@ -474,7 +510,14 @@ public function getMangaSearch(Request\Search\MangaSearchRequest $request): Mode */ public function getCharacterSearch(Request\Search\CharacterSearchRequest $request): Model\Search\CharacterSearch { - $crawler = $this->ghoutte->request('GET', $request->getPath()); + try { + $crawler = $this->ghoutte->request('GET', $request->getPath()); + } catch (BadResponseException $e) { + if ($e->getCode() === 404) { + return Model\Search\CharacterSearch::mock(); + } + } + try { $parser = new Parser\Search\CharacterSearchParser($crawler); @@ -492,15 +535,12 @@ public function getCharacterSearch(Request\Search\CharacterSearchRequest $reques */ public function getPersonSearch(Request\Search\PersonSearchRequest $request): Model\Search\PersonSearch { - // Person page for some reason returns 404 when there are no results :facepalm: try { $crawler = $this->ghoutte->request('GET', $request->getPath()); - } catch (\Exception $e) { + } catch (BadResponseException $e) { if ($e->getCode() === 404) { - return new Model\Search\PersonSearch(); + return Model\Search\PersonSearch::mock(); } - - throw $e; } try { @@ -534,17 +574,17 @@ public function getMangaCharacters(Request\Manga\MangaCharactersRequest $request /** * @param Request\Top\TopAnimeRequest $request * - * @return Model\Top\TopAnime[] + * @return Model\Top\TopAnimeListItem[] * @throws BadResponseException * @throws ParserException */ - public function getTopAnime(Request\Top\TopAnimeRequest $request): array + public function getTopAnime(Request\Top\TopAnimeRequest $request): Model\Top\TopAnime { $crawler = $this->ghoutte->request('GET', $request->getPath()); try { $parser = new Parser\Top\TopAnimeParser($crawler); - return $parser->getTopAnime(); + return $parser->getModel(); } catch (\Exception $e) { throw ParserException::fromRequest($request, $e); } @@ -553,17 +593,17 @@ public function getTopAnime(Request\Top\TopAnimeRequest $request): array /** * @param Request\Top\TopMangaRequest $request * - * @return Model\Top\TopManga[] + * @return Model\Top\TopMangaListItem[] * @throws BadResponseException * @throws ParserException */ - public function getTopManga(Request\Top\TopMangaRequest $request): array + public function getTopManga(Request\Top\TopMangaRequest $request): Model\Top\TopManga { $crawler = $this->ghoutte->request('GET', $request->getPath()); try { $parser = new Parser\Top\TopMangaParser($crawler); - return $parser->getTopManga(); + return $parser->getModel(); } catch (\Exception $e) { throw ParserException::fromRequest($request, $e); } @@ -572,17 +612,17 @@ public function getTopManga(Request\Top\TopMangaRequest $request): array /** * @param Request\Top\TopCharactersRequest $request * - * @return Model\Top\TopCharacter[] + * @return Model\Top\TopCharacterListItem[] * @throws BadResponseException * @throws ParserException */ - public function getTopCharacters(Request\Top\TopCharactersRequest $request): array + public function getTopCharacters(Request\Top\TopCharactersRequest $request): Model\Top\TopCharacters { $crawler = $this->ghoutte->request('GET', $request->getPath()); try { $parser = new Parser\Top\TopCharactersParser($crawler); - return $parser->getTopCharacters(); + return $parser->getModel(); } catch (\Exception $e) { throw ParserException::fromRequest($request, $e); } @@ -591,17 +631,17 @@ public function getTopCharacters(Request\Top\TopCharactersRequest $request): arr /** * @param Request\Top\TopPeopleRequest $request * - * @return Model\Top\TopPerson[] + * @return Model\Top\TopPersonListItem[] * @throws BadResponseException * @throws ParserException */ - public function getTopPeople(Request\Top\TopPeopleRequest $request): array + public function getTopPeople(Request\Top\TopPeopleRequest $request): Model\Top\TopPeople { $crawler = $this->ghoutte->request('GET', $request->getPath()); try { $parser = new Parser\Top\TopPeopleParser($crawler); - return $parser->getTopPeople(); + return $parser->getModel(); } catch (\Exception $e) { throw ParserException::fromRequest($request, $e); } @@ -722,7 +762,7 @@ public function getMangaMoreInfo(Request\Manga\MangaMoreInfoRequest $request): ? * @throws BadResponseException * @throws ParserException */ - public function getSeasonList(Request\SeasonList\SeasonListRequest $request): array + public function getSeasonList(Request\SeasonList\SeasonListRequest $request): Model\SeasonList\SeasonArchive { $crawler = $this->ghoutte->request('GET', $request->getPath()); try { @@ -760,8 +800,17 @@ public function getUserHistory(Request\User\UserHistoryRequest $request): array public function getUserAnimeList(Request\User\UserAnimeListRequest $request): array { try { - $response = $this->ghoutte->getClient()->get($request->getPath()); - $list = json_decode($response->getBody()->getContents()); + $response = $this->httpClient + ->request('GET', $request->getPath()); + + if ($response->getStatusCode() >= 400) { + throw new BadResponseException( + $response->getStatusCode().' on '.$response->getInfo('url'), + $response->getStatusCode() + ); + } + + $list = \json_decode($response->getContent()); $model = []; foreach ($list as $item) { @@ -785,8 +834,17 @@ public function getUserAnimeList(Request\User\UserAnimeListRequest $request): ar public function getUserMangaList(Request\User\UserMangaListRequest $request): array { try { - $response = $this->ghoutte->getClient()->get($request->getPath()); - $list = json_decode($response->getBody()->getContents()); + $response = $this->httpClient + ->request('GET', $request->getPath()); + + if ($response->getStatusCode() >= 400) { + throw new BadResponseException( + $response->getStatusCode().' on '.$response->getInfo('url'), + $response->getStatusCode() + ); + } + + $list = \json_decode($response->getContent()); $model = []; foreach ($list as $item) { @@ -808,7 +866,7 @@ public function getUserMangaList(Request\User\UserMangaListRequest $request): ar * @throws BadResponseException * @throws ParserException */ - public function getAnimeRecentlyUpdatedByUsers(Request\Anime\AnimeRecentlyUpdatedByUsersRequest $request): array + public function getAnimeRecentlyUpdatedByUsers(Request\Anime\AnimeRecentlyUpdatedByUsersRequest $request): Model\Anime\AnimeUserUpdates { $crawler = $this->ghoutte->request('GET', $request->getPath()); try { @@ -826,7 +884,7 @@ public function getAnimeRecentlyUpdatedByUsers(Request\Anime\AnimeRecentlyUpdate * @throws BadResponseException * @throws ParserException */ - public function getMangaRecentlyUpdatedByUsers(Request\Manga\MangaRecentlyUpdatedByUsersRequest $request): array + public function getMangaRecentlyUpdatedByUsers(Request\Manga\MangaRecentlyUpdatedByUsersRequest $request): Model\Manga\MangaUserUpdates { $crawler = $this->ghoutte->request('GET', $request->getPath()); try { @@ -878,30 +936,31 @@ public function getMangaRecommendations(Request\Manga\MangaRecommendationsReques /** * @param Request\Club\UserListRequest $request * - * @return Model\Club\UserProfile[] + * @return Model\Club\UserList * @throws BadResponseException * @throws ParserException */ - public function getClubUsers(Request\Club\UserListRequest $request): array + public function getClubUsers(Request\Club\UserListRequest $request): Model\Club\UserList { $crawler = $this->ghoutte->request('GET', $request->getPath()); try { $parser = new Parser\Club\UserListParser($crawler); - return $parser->getResults(); + return $parser->getModel(); } catch (\Exception $e) { throw ParserException::fromRequest($request, $e); } } + /** - * @param Request\Anime\AnimeReviewsRequest $request - * @return array + * @param Request\Anime\AnimeReviewsRequest $request + * @return Model\Anime\AnimeReviews * @throws BadResponseException * @throws ParserException */ - public function getAnimeReviews(Request\Anime\AnimeReviewsRequest $request): array + public function getAnimeReviews(Request\Anime\AnimeReviewsRequest $request): Model\Anime\AnimeReviews { $crawler = $this->ghoutte->request('GET', $request->getPath()); try { @@ -913,13 +972,14 @@ public function getAnimeReviews(Request\Anime\AnimeReviewsRequest $request): arr } } + /** - * @param Request\Manga\MangaReviewsRequest $request - * @return array + * @param Request\Manga\MangaReviewsRequest $request + * @return Model\Manga\MangaReviews * @throws BadResponseException * @throws ParserException */ - public function getMangaReviews(Request\Manga\MangaReviewsRequest $request): array + public function getMangaReviews(Request\Manga\MangaReviewsRequest $request): Model\Manga\MangaReviews { $crawler = $this->ghoutte->request('GET', $request->getPath()); @@ -1047,19 +1107,245 @@ public function getMangaGenres(Request\Genre\MangaGenresRequest $request): Model } /** - * @param Request\Top\TopReviewsRequest $request + * @param Request\Reviews\RecentReviewsRequest $request * * @return * @throws BadResponseException * @throws ParserException */ - public function getTopReviews(Request\Top\TopReviewsRequest $request): array + public function getRecentReviews(Request\Reviews\RecentReviewsRequest $request): Model\Reviews\RecentReviews + { + $crawler = $this->ghoutte->request('GET', $request->getPath()); + try { + $parser = new Parser\Reviews\RecentReviewsParser($crawler); + + return $parser->getModel(); + } catch (\Exception $e) { + throw ParserException::fromRequest($request, $e); + } + } + + /** + * @param Request\Recommendations\RecentRecommendationsRequest $request + * @return array + * @throws BadResponseException + * @throws ParserException + */ + public function getRecentRecommendations(Request\Recommendations\RecentRecommendationsRequest $request): Model\Recommendations\RecentRecommendations + { + $crawler = $this->ghoutte->request('GET', $request->getPath()); + try { + $parser = new Parser\Recommendations\RecentRecommendationsParser($crawler); + + return $parser->getModel(); + } catch (\Exception $e) { + throw ParserException::fromRequest($request, $e); + } + } + + /** + * @param Request\Search\UserSearchRequest $request + * + * @return Model\Search\UserSearch + * @throws BadResponseException + * @throws ParserException + */ + public function getUserSearch(Request\Search\UserSearchRequest $request): Model\Search\UserSearch + { + // Returns 404 when there are no results + try { + $crawler = $this->ghoutte->request('GET', $request->getPath()); + } catch (\Exception $e) { + if ($e->getCode() === 404) { + return new Model\Search\UserSearch(); + } + throw $e; + } + + try { + $parser = new Parser\Search\UserSearchParser($crawler); + + return $parser->getModel(); + } catch (\Exception $e) { + throw ParserException::fromRequest($request, $e); + } + } + + /** + * @param Request\User\RecentlyOnlineUsersRequest $request + * @return array + * @throws BadResponseException + * @throws ParserException + */ + public function getRecentOnlineUsers(Request\User\RecentlyOnlineUsersRequest $request): array + { + $crawler = $this->ghoutte->request('GET', $request->getPath()); + try { + $parser = new Parser\Search\UserSearchParser($crawler); + + return $parser->getResults(); + } catch (\Exception $e) { + throw ParserException::fromRequest($request, $e); + } + } + + /** + * @param Request\User\UsernameByIdRequest $request + * @return Model\Common\UserMetaBasic + * @throws BadResponseException + * @throws ParserException + */ + public function getUsernameById(Request\User\UsernameByIdRequest $request) : Model\Common\UserMetaBasic + { + $crawler = $this->ghoutte->request('GET', $request->getPath()); + try { + $parser = new Parser\User\UsernameByIdParser($crawler); + + return $parser->getUser(); + } catch (\Exception $e) { + throw ParserException::fromRequest($request, $e); + } + } + + /** + * @param Request\User\UserReviewsRequest $request + * @return Model\User\Reviews\UserReviews + * @throws BadResponseException + * @throws ParserException + */ + public function getUserReviews(Request\User\UserReviewsRequest $request) : Model\User\Reviews\UserReviews + { + try { + $crawler = $this->ghoutte->request('GET', $request->getPath()); + } catch (\Exception $e) { + if ($e->getCode() === 404) { + return Model\User\Reviews\UserReviews::mock(); + } + throw $e; + } + try { + $parser = new Parser\User\Reviews\UserReviewsParser($crawler); + return $parser->getModel(); + } catch (\Exception $e) { + throw ParserException::fromRequest($request, $e); + } + } + + /** + * @param Request\Watch\RecentEpisodesRequest $request + * @return Model\Watch\Episodes + * @throws BadResponseException + * @throws ParserException + */ + public function getRecentEpisodes(Request\Watch\RecentEpisodesRequest $request) : Model\Watch\Episodes { $crawler = $this->ghoutte->request('GET', $request->getPath()); try { - $parser = new Parser\Top\TopReviewsParser($crawler); + $parser = new Parser\Watch\WatchEpisodesParser($crawler); + + return $parser->getModel(); + } catch (\Exception $e) { + throw ParserException::fromRequest($request, $e); + } + } + + /** + * @param Request\Watch\PopularEpisodesRequest $request + * @return Model\Watch\Episodes + * @throws BadResponseException + * @throws ParserException + */ + public function getPopularEpisodes(Request\Watch\PopularEpisodesRequest $request) : Model\Watch\Episodes + { + $crawler = $this->ghoutte->request('GET', $request->getPath()); + try { + $parser = new Parser\Watch\WatchEpisodesParser($crawler); + + return $parser->getModel(); + } catch (\Exception $e) { + throw ParserException::fromRequest($request, $e); + } + } + + /** + * @param Request\Watch\RecentPromotionalVideosRequest $request + * @return Model\Watch\PromotionalVideos + * @throws BadResponseException + * @throws ParserException + */ + public function getRecentPromotionalVideos( + Request\Watch\RecentPromotionalVideosRequest $request + ) : Model\Watch\PromotionalVideos { + $crawler = $this->ghoutte->request('GET', $request->getPath()); + try { + $parser = new Parser\Watch\WatchPromotionalVideosParser($crawler); + + return $parser->getModel(); + } catch (\Exception $e) { + throw ParserException::fromRequest($request, $e); + } + } + + /** + * @param Request\Watch\PopularPromotionalVideosRequest $request + * @return Model\Watch\PromotionalVideos + * @throws BadResponseException + * @throws ParserException + */ + public function getPopularPromotionalVideos( + Request\Watch\PopularPromotionalVideosRequest $request + ) : Model\Watch\PromotionalVideos { + $crawler = $this->ghoutte->request('GET', $request->getPath()); + try { + $parser = new Parser\Watch\WatchPromotionalVideosParser($crawler); + + return $parser->getModel(); + } catch (\Exception $e) { + throw ParserException::fromRequest($request, $e); + } + } + + + /** + * @param Request\User\UserRecommendationsRequest $request + * @return Model\Recommendations\UserRecommendations + * @throws BadResponseException + * @throws ParserException + */ + public function getUserRecommendations(Request\User\UserRecommendationsRequest $request): Model\Recommendations\UserRecommendations + { + $crawler = $this->ghoutte->request('GET', $request->getPath()); + try { + $parser = new Parser\Recommendations\UserRecommendationsParser($crawler); + + return $parser->getModel(); + } catch (\Exception $e) { + throw ParserException::fromRequest($request, $e); + } + } + + /** + * @param Request\User\UserClubsRequest $request + * @return array + * @throws BadResponseException + * @throws ParserException + */ + public function getUserClubs(Request\User\UserClubsRequest $request) : array + { + // user clubs page returns 404 when there are none added + try { + $crawler = $this->ghoutte->request('GET', $request->getPath()); + } catch (\Exception $e) { + if ($e->getCode() === 404) { + return []; + } + + throw $e; + } + try { + $parser = new Parser\User\ClubParser($crawler); - return $parser->getTopReviews(); + return $parser->getClubs(); } catch (\Exception $e) { throw ParserException::fromRequest($request, $e); } diff --git a/src/Parser/Anime/AnimeParser.php b/src/Parser/Anime/AnimeParser.php index 42742331..c38d90fa 100644 --- a/src/Parser/Anime/AnimeParser.php +++ b/src/Parser/Anime/AnimeParser.php @@ -106,7 +106,7 @@ public function getTitleEnglish(): ?string } return JString::cleanse( - str_replace($title->text(), '', $title->parents()->text()) + str_replace($title->text(), '', $title->ancestors()->text()) ); } @@ -123,7 +123,7 @@ public function getTitleSynonyms(): array return []; } - $titles = str_replace($title->text(), '', $title->parents()->text()); + $titles = str_replace($title->text(), '', $title->ancestors()->text()); $titles = explode(', ', $titles); foreach ($titles as &$title) { @@ -146,7 +146,7 @@ public function getTitleJapanese(): ?string } return JString::cleanse( - str_replace($title->text(), '', $title->parents()->text()) + str_replace($title->text(), '', $title->ancestors()->text()) ); } @@ -163,7 +163,7 @@ public function getType(): ?string } return JString::cleanse( - str_replace($type->text(), '', $type->parents()->text()) + str_replace($type->text(), '', $type->ancestors()->text()) ); } @@ -184,7 +184,7 @@ public function getEpisodes(): ?int return ( trim( - str_replace($episodes->text(), '', $episodes->parents()->text()) + str_replace($episodes->text(), '', $episodes->ancestors()->text()) ) === 'Unknown' ) ? @@ -193,7 +193,7 @@ public function getEpisodes(): ?int (int)str_replace( $episodes->text(), '', - $episodes->parents()->text() + $episodes->ancestors()->text() ); } @@ -210,7 +210,7 @@ public function getStatus(): ?string } return JString::cleanse( - str_replace($status->text(), '', $status->parents()->text()) + str_replace($status->text(), '', $status->ancestors()->text()) ); } @@ -228,7 +228,7 @@ public function getPremiered(): ?string } $premiered = JString::cleanse( - str_replace($premiered->text(), '', $premiered->parents()->text()) + str_replace($premiered->text(), '', $premiered->ancestors()->text()) ); if ($premiered === '?') { @@ -252,7 +252,7 @@ public function getBroadcast(): ?string } return JString::cleanse( - str_replace($broadcast->text(), '', $broadcast->parents()->text()) + str_replace($broadcast->text(), '', $broadcast->ancestors()->text()) ); } @@ -266,8 +266,8 @@ public function getProducers(): array $producer = $this->crawler ->filterXPath('//span[text()="Producers:"]'); - if ($producer->count() && strpos($producer->parents()->text(), 'None found') === false) { - return $producer->parents()->first()->filterXPath('//a')->each( + if ($producer->count() && strpos($producer->ancestors()->text(), 'None found') === false) { + return $producer->ancestors()->first()->filterXPath('//a')->each( function (Crawler $crawler) { return (new MalUrlParser($crawler))->getModel(); } @@ -287,8 +287,8 @@ public function getLicensors(): array $licensor = $this->crawler ->filterXPath('//span[text()="Licensors:"]'); - if ($licensor->count() && strpos($licensor->parents()->text(), 'None found') === false) { - return $licensor->parents()->first()->filterXPath('//a')->each( + if ($licensor->count() && strpos($licensor->ancestors()->text(), 'None found') === false) { + return $licensor->ancestors()->first()->filterXPath('//a')->each( function (Crawler $crawler) { return (new MalUrlParser($crawler))->getModel(); } @@ -307,8 +307,8 @@ public function getStudios(): array { $studio = $this->crawler->filterXPath('//span[text()="Studios:"]'); - if ($studio->count() && strpos($studio->parents()->text(), 'None found') === false) { - return $studio->parents()->first()->filterXPath('//a')->each( + if ($studio->count() && strpos($studio->ancestors()->text(), 'None found') === false) { + return $studio->ancestors()->first()->filterXPath('//a')->each( function (Crawler $crawler) { return (new MalUrlParser($crawler))->getModel(); } @@ -332,7 +332,7 @@ public function getSource(): ?string } return JString::cleanse( - str_replace($source->text(), '', $source->parents()->text()) + str_replace($source->text(), '', $source->ancestors()->text()) ); } @@ -346,8 +346,8 @@ public function getGenres(): array $genre = $this->crawler ->filterXPath('//span[text()="Genres:"]'); - if ($genre->count() && strpos($genre->parents()->text(), 'No genres have been added yet') === false) { - return $genre->parents()->first()->filterXPath('//a')->each( + if ($genre->count() && strpos($genre->ancestors()->text(), 'No genres have been added yet') === false) { + return $genre->ancestors()->first()->filterXPath('//a')->each( function (Crawler $crawler) { return (new MalUrlParser($crawler))->getModel(); } @@ -357,8 +357,8 @@ function (Crawler $crawler) { $genre = $this->crawler ->filterXPath('//span[text()="Genre:"]'); - if ($genre->count() && strpos($genre->parents()->text(), 'No genres have been added yet') === false) { - return $genre->parents()->first()->filterXPath('//a')->each( + if ($genre->count() && strpos($genre->ancestors()->text(), 'No genres have been added yet') === false) { + return $genre->ancestors()->first()->filterXPath('//a')->each( function (Crawler $crawler) { return (new MalUrlParser($crawler))->getModel(); } @@ -378,8 +378,8 @@ public function getExplicitGenres(): array $genre = $this->crawler ->filterXPath('//span[text()="Explicit Genres:"]'); - if ($genre->count() && strpos($genre->parents()->text(), 'No genres have been added yet') === false) { - return $genre->parents()->first()->filterXPath('//a')->each( + if ($genre->count() && strpos($genre->ancestors()->text(), 'No genres have been added yet') === false) { + return $genre->ancestors()->first()->filterXPath('//a')->each( function (Crawler $crawler) { return (new MalUrlParser($crawler))->getModel(); } @@ -389,8 +389,8 @@ function (Crawler $crawler) { $genre = $this->crawler ->filterXPath('//span[text()="Explicit Genre:"]'); - if ($genre->count() && strpos($genre->parents()->text(), 'No genres have been added yet') === false) { - return $genre->parents()->first()->filterXPath('//a')->each( + if ($genre->count() && strpos($genre->ancestors()->text(), 'No genres have been added yet') === false) { + return $genre->ancestors()->first()->filterXPath('//a')->each( function (Crawler $crawler) { return (new MalUrlParser($crawler))->getModel(); } @@ -411,7 +411,7 @@ public function getDemographics(): array ->filterXPath('//span[text()="Demographic:"]'); if ($genre->count()) { - return $genre->parents()->first()->filterXPath('//a')->each( + return $genre->ancestors()->first()->filterXPath('//a')->each( function (Crawler $crawler) { return (new MalUrlParser($crawler))->getModel(); } @@ -422,7 +422,7 @@ function (Crawler $crawler) { ->filterXPath('//span[text()="Demographics:"]'); if ($genre->count()) { - return $genre->parents()->first()->filterXPath('//a')->each( + return $genre->ancestors()->first()->filterXPath('//a')->each( function (Crawler $crawler) { return (new MalUrlParser($crawler))->getModel(); } @@ -443,7 +443,7 @@ public function getThemes(): array ->filterXPath('//span[text()="Theme:"]'); if ($genre->count()) { - return $genre->parents()->first()->filterXPath('//a')->each( + return $genre->ancestors()->first()->filterXPath('//a')->each( function (Crawler $crawler) { return (new MalUrlParser($crawler))->getModel(); } @@ -454,7 +454,7 @@ function (Crawler $crawler) { ->filterXPath('//span[text()="Themes:"]'); if ($genre->count()) { - return $genre->parents()->first()->filterXPath('//a')->each( + return $genre->ancestors()->first()->filterXPath('//a')->each( function (Crawler $crawler) { return (new MalUrlParser($crawler))->getModel(); } @@ -481,7 +481,7 @@ public function getDuration(): ?string str_replace( '.', '', - str_replace($duration->text(), '', $duration->parents()->text()) + str_replace($duration->text(), '', $duration->ancestors()->text()) ) ); } @@ -500,7 +500,7 @@ public function getRating(): ?string } return JString::cleanse( - str_replace($rating->text(), '', $rating->parents()->text()) + str_replace($rating->text(), '', $rating->ancestors()->text()) ); } @@ -559,7 +559,7 @@ public function getRank(): ?int } $ranked = JString::cleanse( - Parser::removeChildNodes($rank->parents())->text() + Parser::removeChildNodes($rank->ancestors())->text() ); if ($ranked === 'N/A') { @@ -587,7 +587,7 @@ public function getPopularity(): ?int } return JString::cleanse( - str_replace([$popularity->text(), '#'], '', $popularity->parents()->text()) + str_replace([$popularity->text(), '#'], '', $popularity->ancestors()->text()) ); } @@ -605,7 +605,7 @@ public function getMembers(): ?int } return JString::cleanse( - str_replace([$member->text(), ','], '', $member->parents()->text()) + str_replace([$member->text(), ','], '', $member->ancestors()->text()) ); } @@ -623,7 +623,7 @@ public function getFavorites(): ?int } return JString::cleanse( - str_replace([$favorite->text(), ','], '', $favorite->parents()->text()) + str_replace([$favorite->text(), ','], '', $favorite->ancestors()->text()) ); } @@ -641,9 +641,9 @@ public function getExternalLinks(): array } return $links->nextAll()->filterXPath('//div[contains(@class, "pb16")]/a') - ->each(function(Crawler $c) { - return (new UrlParser($c))->getModel(); - }); + ->each(function(Crawler $c) { + return (new UrlParser($c))->getModel(); + }); } /** @@ -782,6 +782,7 @@ public function getAnimeAiredString(): ?string public function getPreview(): ?string { $video = $this->crawler->filterXPath('//div[contains(@class, "video-promotion")]/a'); + if (!$video->count()) { return null; } diff --git a/src/Parser/Anime/AnimeRecentlyUpdatedByUsersListParser.php b/src/Parser/Anime/AnimeRecentlyUpdatedByUsersListParser.php index 2adace82..e2d0e4a0 100644 --- a/src/Parser/Anime/AnimeRecentlyUpdatedByUsersListParser.php +++ b/src/Parser/Anime/AnimeRecentlyUpdatedByUsersListParser.php @@ -3,6 +3,7 @@ namespace Jikan\Parser\Anime; use Jikan\Model\Anime\AnimeRecentlyUpdatedByUser; +use Jikan\Model\Common\UserMeta; use Jikan\Parser\ParserInterface; use Symfony\Component\DomCrawler\Crawler; @@ -149,4 +150,13 @@ public function getModel(): AnimeRecentlyUpdatedByUser { return AnimeRecentlyUpdatedByUser::fromParser($this); } + + public function getUserMeta() : UserMeta + { + return new UserMeta( + $this->getUsername(), + $this->getUrl(), + $this->getImageUrl() + ); + } } diff --git a/src/Parser/Anime/AnimeRecentlyUpdatedByUsersParser.php b/src/Parser/Anime/AnimeRecentlyUpdatedByUsersParser.php index a2efba85..5f6ee973 100644 --- a/src/Parser/Anime/AnimeRecentlyUpdatedByUsersParser.php +++ b/src/Parser/Anime/AnimeRecentlyUpdatedByUsersParser.php @@ -2,6 +2,7 @@ namespace Jikan\Parser\Anime; +use Jikan\Model\Anime\AnimeUserUpdates; use Jikan\Parser\ParserInterface; use Symfony\Component\DomCrawler\Crawler; @@ -10,7 +11,7 @@ * * @package Jikan\Parser\Anime */ -class AnimeRecentlyUpdatedByUsersParser implements ParserInterface +class AnimeRecentlyUpdatedByUsersParser { /** * @var Crawler @@ -31,7 +32,7 @@ public function __construct(Crawler $crawler) * @return array * @throws \InvalidArgumentException */ - public function getModel(): array + public function getResults(): array { try { return $this->crawler @@ -46,4 +47,20 @@ function ($c) { return []; } } + + // @todo anime user updates pagination + public function getHasNextPage() : bool + { + return false; + } + + public function getLastPage() : int + { + return 1; + } + + public function getModel(): AnimeUserUpdates + { + return AnimeUserUpdates::fromParser($this); + } } diff --git a/src/Parser/Anime/AnimeReviewerParser.php b/src/Parser/Anime/AnimeReviewerParser.php deleted file mode 100644 index bddafd2c..00000000 --- a/src/Parser/Anime/AnimeReviewerParser.php +++ /dev/null @@ -1,19 +0,0 @@ -crawler = $crawler; } + /** + * @return AnimeReviews + */ + public function getModel() : AnimeReviews + { + return AnimeReviews::fromParser($this); + } + + /** + * @return Crawler + */ + public function getCrawler(): Crawler + { + return $this->crawler; + } + /** * @return array * @throws \RuntimeException * @throws \InvalidArgumentException */ - public function getModel(): array + public function getResults(): array { return $this->crawler ->filterXPath('//div[@class="borderDark"]') @@ -42,4 +60,19 @@ function (Crawler $c) { } ); } + + /** + * @return bool + */ + public function hasNextPage(): bool // @TODO WIP + { + $node = $this->crawler + ->filterXPath('//*[@id="horiznav_nav"]/div/a[contains(text(), "Next")]'); + + if ($node->count()) { + return true; + } + + return false; + } } diff --git a/src/Parser/Anime/AnimeStatsParser.php b/src/Parser/Anime/AnimeStatsParser.php index 1096a497..28781369 100644 --- a/src/Parser/Anime/AnimeStatsParser.php +++ b/src/Parser/Anime/AnimeStatsParser.php @@ -41,7 +41,7 @@ public function getWatching(): int return $this->sanitize( $this->crawler ->filterXPath('//div[@class="spaceit_pad"]/span[contains(text(), \'Watching:\')]') - ->parents() + ->ancestors() ->getNode(0)->textContent ); } catch (\Exception $e) { @@ -69,7 +69,7 @@ public function getCompleted(): int return $this->sanitize( $this->crawler ->filterXPath('//div[@class="spaceit_pad"]/span[contains(text(), \'Completed:\')]') - ->parents() + ->ancestors() ->getNode(0)->textContent ); } catch (\Exception $e) { @@ -87,7 +87,7 @@ public function getOnHold(): int return $this->sanitize( $this->crawler ->filterXPath('//div[@class="spaceit_pad"]/span[contains(text(), \'On-Hold:\')]') - ->parents() + ->ancestors() ->getNode(0)->textContent ); } catch (\Exception $e) { @@ -105,7 +105,7 @@ public function getDropped(): int return $this->sanitize( $this->crawler ->filterXPath('//div[@class="spaceit_pad"]/span[contains(text(), \'Dropped:\')]') - ->parents() + ->ancestors() ->getNode(0)->textContent ); } catch (\Exception $e) { @@ -123,7 +123,7 @@ public function getPlanToWatch(): int return $this->sanitize( $this->crawler ->filterXPath('//div[@class="spaceit_pad"]/span[contains(text(), \'Plan to Watch:\')]') - ->parents() + ->ancestors() ->getNode(0)->textContent ); } catch (\Exception $e) { @@ -141,7 +141,7 @@ public function getTotal(): int return $this->sanitize( $this->crawler ->filterXPath('//div[@class="spaceit_pad"]/span[contains(text(), \'Total:\')]') - ->parents() + ->ancestors() ->getNode(0)->textContent ); } catch (\Exception $e) { @@ -183,13 +183,13 @@ function (Crawler $crawler) use (&$scores) { ); $percentage = (float) JString::cleanse($percentage); - $scores[$score] = AnimeStatsScore::setProperties($votes, $percentage); + $scores[$score] = AnimeStatsScore::setProperties($score, $votes, $percentage); } ); for ($i=1; $i<=10; $i++) { if (!array_key_exists($i, $scores)) { - $scores[$i] = AnimeStatsScore::setProperties(0, 0); + $scores[$i] = AnimeStatsScore::setProperties($i, 0, 0); } } diff --git a/src/Parser/Anime/CharactersAndStaffParser.php b/src/Parser/Anime/CharactersAndStaffParser.php index 2ce30567..bc12b575 100644 --- a/src/Parser/Anime/CharactersAndStaffParser.php +++ b/src/Parser/Anime/CharactersAndStaffParser.php @@ -66,7 +66,7 @@ public function getStaff(): array { $node = $this->crawler ->filterXPath('//h2[text()="Staff"]') - ->parents()->nextAll() + ->ancestors()->nextAll() ->reduce( function (Crawler $crawler) { return (bool)$crawler->filterXPath( @@ -75,7 +75,6 @@ function (Crawler $crawler) { } ); - return $node ->each( function (Crawler $crawler) { diff --git a/src/Parser/Anime/EpisodesParser.php b/src/Parser/Anime/EpisodesParser.php index 808d01de..1d6d1513 100644 --- a/src/Parser/Anime/EpisodesParser.php +++ b/src/Parser/Anime/EpisodesParser.php @@ -54,39 +54,50 @@ function (Crawler $crawler) { * @return int * @throws \InvalidArgumentException */ - public function getEpisodesLastPage(): int + public function getLastPage(): int { - $episodesLastPage = $this->crawler - ->filterXPath('//div[contains(@class, \'pagination\')]'); + $pages = $this->crawler + ->filterXPath('//*[@id="content"]/table/tr/td[2]/div[2]/div[2]/div[2]/div/a[contains(@class, "link")]'); - if (!$episodesLastPage->count()) { + if (!$pages->count()) { return 1; } - $episodesLastPage = $episodesLastPage->children(); + $pages = $pages + ->nextAll() + ->last(); + if (!$pages->count()) { + return 1; + } - if ($episodesLastPage->getNode(1)->tagName === 'span') { - $episodesLastPage = $episodesLastPage - ->filterXPath('//a') - ->last(); + preg_match('~\?offset=(\d+)$~', $pages->getUri(), $page); - preg_match('~(\d+) - (\d+)~', $episodesLastPage->text(), $matches); + return ((int) $page[1]/100) + 1; + } - return ceil((int)$matches[2] / 100); + /** + * @return bool + */ + public function getHasNextPage(): bool + { + $pages = $this->crawler + ->filterXPath('//*[@id="content"]/table/tr/td[2]/div[2]/div[2]/div[2]/div/a[contains(@class, "link")]'); + + if (!$pages->count()) { + return false; } - $episodesLastPage = $this->crawler - ->filterXPath('//div[contains(@class, \'pagination\')]/a') - ->last(); + $pages = $pages + ->nextAll() + ->last() + ->filterXPath('//a[not(contains(@class, "current"))]'); - if (!$episodesLastPage->count()) { - return 1; + if (!$pages->count()) { + return false; } - preg_match('~(\d+) - (\d+)~', $episodesLastPage->text(), $matches); - - return ceil((int)$matches[2] / 100); + return true; } /** diff --git a/src/Parser/Anime/StaffListItemParser.php b/src/Parser/Anime/StaffListItemParser.php index cb524112..79c9ebbd 100644 --- a/src/Parser/Anime/StaffListItemParser.php +++ b/src/Parser/Anime/StaffListItemParser.php @@ -6,6 +6,7 @@ use Jikan\Helper\Parser; use Jikan\Model\Anime\StaffListItem; use Jikan\Model\Common\MalUrl; +use Jikan\Model\Common\PersonMeta; use Jikan\Parser\Common\MalUrlParser; use Jikan\Parser\ParserInterface; use Symfony\Component\DomCrawler\Crawler; @@ -105,4 +106,17 @@ public function getModel(): StaffListItem { return StaffListItem::fromParser($this); } + + /** + * @return PersonMeta + * @throws \InvalidArgumentException + */ + public function getPersonMeta(): PersonMeta + { + return new PersonMeta( + $this->getName(), + $this->getUrl(), + $this->getImage() + ); + } } diff --git a/src/Parser/Anime/StreamEpisodeListItemParser.php b/src/Parser/Anime/StreamEpisodeListItemParser.php index 0dcd68e6..73afb25e 100644 --- a/src/Parser/Anime/StreamEpisodeListItemParser.php +++ b/src/Parser/Anime/StreamEpisodeListItemParser.php @@ -66,11 +66,17 @@ public function getUrl(): string } /** - * @return string + * @return string|null * @throws \InvalidArgumentException */ - public function getImageUrl(): string + public function getImageUrl(): ?string { - return $this->crawler->filterXPath('//a/img')->attr('data-src'); + $imageUrl = $this->crawler->filterXPath('//a/img')->attr('data-src'); + + if ($imageUrl === 'https://cdn.myanimelist.net/images/icon-banned-youtube.png') { + return null; + } + + return $imageUrl; } } diff --git a/src/Parser/Anime/VideosParser.php b/src/Parser/Anime/VideosParser.php index 2b4e9607..1b73d8fd 100644 --- a/src/Parser/Anime/VideosParser.php +++ b/src/Parser/Anime/VideosParser.php @@ -36,7 +36,7 @@ public function __construct(Crawler $crawler) public function getEpisodes(): array { $episodes = $this->crawler - ->filterXPath('//div[@class="js-video-list-content"]/div[contains(@class, "video-list-outer")]'); + ->filterXPath('//*[@id="content"]/table/tr/td[2]/div[2]/div[2]/div[contains(@class, "video-block episode-video")]//*[contains(@class, "video-list-outer")]'); if (!$episodes->count()) { return []; diff --git a/src/Parser/Character/AnimeographyParser.php b/src/Parser/Character/AnimeographyParser.php index 85179729..94096db8 100644 --- a/src/Parser/Character/AnimeographyParser.php +++ b/src/Parser/Character/AnimeographyParser.php @@ -4,6 +4,7 @@ use Jikan\Model; use Jikan\Parser\ParserInterface; +use Symfony\Component\DomCrawler\Crawler; /** * Class AnimeographyParser @@ -12,6 +13,23 @@ */ class AnimeographyParser extends OgraphyParser implements ParserInterface { + + /** + * @var Crawler + */ + private $crawler; + + /** + * VoiceActingRoleParser constructor. + * + * @param Crawler $crawler + */ + public function __construct(Crawler $crawler) + { + $this->crawler = $crawler; + parent::__construct($this->crawler); + } + /** * Return the model * @@ -22,4 +40,17 @@ public function getModel(): Model\Character\Animeography { return Model\Character\Animeography::fromParser($this); } + + /** + * @return \Jikan\Model\Common\AnimeMeta + * @throws \InvalidArgumentException + */ + public function getAnimeMeta(): Model\Common\AnimeMeta + { + return new Model\Common\AnimeMeta( + $this->getName(), + $this->getUrl(), + $this->getImage() + ); + } } diff --git a/src/Parser/Character/CharacterListItemParser.php b/src/Parser/Character/CharacterListItemParser.php index a0caf51a..c1351196 100644 --- a/src/Parser/Character/CharacterListItemParser.php +++ b/src/Parser/Character/CharacterListItemParser.php @@ -6,6 +6,7 @@ use Jikan\Helper\Parser; use Jikan\Model\Character\CharacterListItem; use Jikan\Model\Character\VoiceActor; +use Jikan\Model\Common\CharacterMeta; use Jikan\Parser\ParserInterface; use Symfony\Component\DomCrawler\Crawler; @@ -105,4 +106,17 @@ public function getRole(): string ) ); } + + /** + * @return CharacterMeta + * @throws \InvalidArgumentException + */ + public function getCharacterMeta(): CharacterMeta + { + return new CharacterMeta( + $this->getName(), + $this->getCharacterUrl(), + $this->getImage() + ); + } } diff --git a/src/Parser/Character/CharacterParser.php b/src/Parser/Character/CharacterParser.php index 81e9383d..3a903b2b 100644 --- a/src/Parser/Character/CharacterParser.php +++ b/src/Parser/Character/CharacterParser.php @@ -77,7 +77,7 @@ public function getName(): string public function getNameKanji(): ?string { $kanji = $this->crawler - ->filterXPath('//h2[contains(@class, "normal_header") and contains(@style, "height: 15px")]/span/small'); + ->filterXPath('//h2[contains(@class, "normal_header")]/span/small'); if (!$kanji->count()) { return null; @@ -107,10 +107,10 @@ public function getNameNicknames(): array } /** - * @return string + * @return string|null * @throws \InvalidArgumentException */ - public function getAbout(): string + public function getAbout(): ?string { $crawler = $this->crawler->filterXPath('//*[@id="content"]/table/tr/td[2]'); $aboutHtml = $crawler->html(); @@ -118,9 +118,15 @@ public function getAbout(): string $aboutHtml = str_replace(['
'], '\n', $aboutHtml); $about = Parser::removeChildNodes((new Crawler($aboutHtml))->filterXPath('//body')); - return JString::cleanse( + $string = JString::cleanse( $about->html() ); + + if (preg_match('~No biography written.~', $string)) { + return null; + } + + return $string; } /** diff --git a/src/Parser/Character/MangaographyParser.php b/src/Parser/Character/MangaographyParser.php index e0da52c2..268c9480 100644 --- a/src/Parser/Character/MangaographyParser.php +++ b/src/Parser/Character/MangaographyParser.php @@ -4,6 +4,7 @@ use Jikan\Model; use Jikan\Parser\ParserInterface; +use Symfony\Component\DomCrawler\Crawler; /** * Class AnimeographyParser @@ -12,6 +13,22 @@ */ class MangaographyParser extends OgraphyParser implements ParserInterface { + /** + * @var Crawler + */ + private $crawler; + + /** + * VoiceActingRoleParser constructor. + * + * @param Crawler $crawler + */ + public function __construct(Crawler $crawler) + { + $this->crawler = $crawler; + parent::__construct($this->crawler); + } + /** * Return the model * @@ -22,4 +39,17 @@ public function getModel(): Model\Character\Mangaography { return Model\Character\Mangaography::fromParser($this); } + + /** + * @return \Jikan\Model\Common\MangaMeta + * @throws \InvalidArgumentException + */ + public function getMangaMeta(): Model\Common\MangaMeta + { + return new Model\Common\MangaMeta( + $this->getName(), + $this->getUrl(), + $this->getImage() + ); + } } diff --git a/src/Parser/Character/VoiceActorParser.php b/src/Parser/Character/VoiceActorParser.php index 701eaabb..fbaeb0cd 100644 --- a/src/Parser/Character/VoiceActorParser.php +++ b/src/Parser/Character/VoiceActorParser.php @@ -128,4 +128,17 @@ function (Crawler $crawler) { ) ))->getModel(); } + + /** + * @return \Jikan\Model\Common\PersonMeta + * @throws \InvalidArgumentException + */ + public function getPersonMeta(): Model\Common\PersonMeta + { + return new Model\Common\PersonMeta( + $this->getName(), + $this->getUrl(), + $this->getImage() + ); + } } diff --git a/src/Parser/Club/ClubParser.php b/src/Parser/Club/ClubParser.php index 369ccaca..422a520a 100644 --- a/src/Parser/Club/ClubParser.php +++ b/src/Parser/Club/ClubParser.php @@ -7,6 +7,7 @@ use Jikan\Helper\Parser; use Jikan\Model\Club\Club; use Jikan\Model\Common\MalUrl; +use Jikan\Model\Common\UserMetaBasic; use Jikan\Parser\ParserInterface; use Symfony\Component\DomCrawler\Crawler; @@ -105,12 +106,14 @@ public function getPicturesCount(): int */ public function getCategory(): string { - return JString::cleanse( + $category = JString::cleanse( Parser::removeChildNodes( $this->crawler ->filterXPath('//div[@id="content"]/table/tr/td[2]/div/div[6]') )->text() ); + + return strtolower($category); } /** @@ -119,12 +122,14 @@ public function getCategory(): string */ public function getCreated(): \DateTimeImmutable { + $node = $this->crawler + ->filterXPath('//div[@id="content"]/table/tr/td[2]/div/div[contains(., "Created")]'); + $date = JString::cleanse( - Parser::removeChildNodes( - $this->crawler - ->filterXPath('//div[@id="content"]/table/tr/td[2]/div/div[7]') - )->text() + Parser::removeChildNodes($node) + ->text() ); + return new \DateTimeImmutable($date, new \DateTimeZone('UTC')); } @@ -279,7 +284,7 @@ function (Crawler $crawler) { foreach ($staffNode as $staffMember) { if ($staffMember instanceof Crawler) { - $staff[] = new MalUrl( + $staff[] = UserMetaBasic::fromMeta( $staffMember->text(), Constants::BASE_URL . $staffMember->attr('href') ); diff --git a/src/Parser/Club/UserListParser.php b/src/Parser/Club/UserListParser.php index 19927301..4c5f3733 100644 --- a/src/Parser/Club/UserListParser.php +++ b/src/Parser/Club/UserListParser.php @@ -51,4 +51,39 @@ function (Crawler $crawler) { } ); } + + /** + * @return bool + */ + public function hasNextPage(): bool + { + $node = $this->crawler + ->filterXPath('//*[@id="content"]/div/a[contains(., "Last")]'); + + if ($node->count()) { + return true; + } + + $node = $this->crawler + ->filterXPath('//*[@id="content"]/div/a[contains(., "»")]'); + + if ($node->count()) { + return true; + } + + return false; + } + + /** + * @return int + * @throws \InvalidArgumentException + */ + public function getLastPage(): int + { + $node = $this->crawler + ->filterXPath('//*[@id="content"]/div'); + + preg_match('~Pages \((.*)\)~', $node->text(), $pages); + return (int) $pages[1]; + } } diff --git a/src/Parser/Club/UserProfileParser.php b/src/Parser/Club/UserProfileParser.php index f1456fd8..37224dc6 100644 --- a/src/Parser/Club/UserProfileParser.php +++ b/src/Parser/Club/UserProfileParser.php @@ -60,8 +60,14 @@ public function getUrl(): string */ public function getImage(): string { - return Parser::parseImageThumbToHQ( + $imageUrl = Parser::parseImageThumbToHQ( $this->crawler->filterXPath('//img[1]')->attr('data-src') ); + + if (!preg_match("~^".Constants::BASE_URL."~", $imageUrl)) { + $imageUrl = Constants::BASE_URL.$imageUrl; + } + + return $imageUrl; } } diff --git a/src/Parser/Common/AnimeCardParser.php b/src/Parser/Common/AnimeCardParser.php index 985cd17b..64aa0cdb 100644 --- a/src/Parser/Common/AnimeCardParser.php +++ b/src/Parser/Common/AnimeCardParser.php @@ -65,7 +65,6 @@ public function getMalId(): int */ public function getAnimeUrl(): string { - $node = $this->crawler->filterXPath('//div/div/h2/a'); if ($node->count()) { @@ -200,7 +199,6 @@ public function getType(): ?string { // this information is no longer available return null; - $text = $this->crawler->filterXPath('//div[contains(@class, "info")]'); if (!$text->count()) { @@ -269,6 +267,7 @@ public function getMembers(): int if ($node->count()) { $count = JString::cleanse($node->text()); + return (int)str_replace([',', '.'], '', $count); } } @@ -351,6 +350,7 @@ public function getAnimeScore(): ?float $score = JString::cleanse($node->text()); if ($score === 'N/A') return null; } + return (float) $score; } @@ -363,7 +363,6 @@ public function getLicensors(): array { // this information is no longer available return []; - // if anyone can fix this spaghetti code, most welcome $node = $this->crawler->filterXPath('//div[contains(@class, "synopsis")]//p[contains(@class, "mb4 mt8")]'); @@ -376,7 +375,7 @@ public function getLicensors(): array $node->nextAll()->filterXPath('//a') ->each(function(Crawler $c) use(&$malUrl) { $malUrl[] = $c->text(); - }); + }); } }); @@ -390,7 +389,6 @@ public function getLicensors(): array */ public function getThemes(): array { - $node = $this->crawler->filterXPath('//div[contains(@class, "synopsis")]/div[contains(@class, "properties")]/div[3]/span'); $malUrl = []; @@ -462,6 +460,6 @@ public function isKids(): bool */ public function isContinuing(): bool { - return strpos($this->crawler->parents()->text(), '(Continuing)') !== false; + return strpos($this->crawler->ancestors()->text(), '(Continuing)') !== false; } } diff --git a/src/Parser/Common/DefaultPicturesPageParser.php b/src/Parser/Common/DefaultPicturesPageParser.php index 82c8c55f..81a099f6 100644 --- a/src/Parser/Common/DefaultPicturesPageParser.php +++ b/src/Parser/Common/DefaultPicturesPageParser.php @@ -3,6 +3,8 @@ namespace Jikan\Parser\Common; use Jikan\Model\Common\DefaultPicture; +use Jikan\Model\Common\Picture; +use Jikan\Model\Resource\PersonImageResource\PersonImageResource; use Jikan\Parser\ParserInterface; use Symfony\Component\DomCrawler\Crawler; @@ -41,8 +43,11 @@ public function getModel(): array ->filterXPath('//a[@class="js-picture-gallery"]') ->each( function (Crawler $crawler) { - return DefaultPicture::fromParser(new PictureParser($crawler)); + return PersonImageResource::factory( + DefaultPicture::fromParser(new PictureParser($crawler)) + ->getImageUrl() + ); } ); } -} \ No newline at end of file +} diff --git a/src/Parser/Common/MangaCardParser.php b/src/Parser/Common/MangaCardParser.php index a9f15c03..64e32cee 100644 --- a/src/Parser/Common/MangaCardParser.php +++ b/src/Parser/Common/MangaCardParser.php @@ -95,7 +95,7 @@ public function getVolumes(): ?int $text = JString::cleanse($node->text()); - if (!preg_match('~([0-9]{1,})~', $text, $matches)) { + if (!preg_match('~([0-9]+)~', $text, $matches)) { return null; } @@ -109,25 +109,9 @@ public function getVolumes(): ?int */ public function getType(): ?string { - // this information is no longer available + // This information is no longer available return null; - - $text = $this->crawler->filterXPath('//div[contains(@class, "info")]'); - - if (!$text->count()) { - return null; - } - - $text = JString::cleanse($text->text()); - preg_match('/^([a-zA-Z-\.]+)/', $text, $matches); - - $type = $matches[1]; - - if ($type === '-') { - $type = 'Unknown'; - } - - return $type; + return JString::cleanse($this->crawler->filterXPath('//span[contains(@class, "source")]')->text()); } /** @@ -179,7 +163,7 @@ public function getPublishDates(): ?\DateTimeImmutable $node = $this->crawler->filterXPath('//div/div[2]/div/span[contains(@class, "item")][1]'); if ( - !preg_match('~(.*), ([0-9]{1,})~', $node->text(), $matches) + !preg_match('~(.*), ([0-9]{1,})~', $node->text(), $matches) ) { return null; } @@ -188,7 +172,8 @@ public function getPublishDates(): ?\DateTimeImmutable try { return (new \DateTimeImmutable($date, new \DateTimeZone('JST'))) - ->setTimezone(new \DateTimeZone('UTC')); + ->setTimezone(new \DateTimeZone('UTC')) + ->setTime(0, 0); } catch (\Exception $e) { return null; } @@ -204,7 +189,6 @@ public function getMembers(): int $count = $this->crawler->filterXPath('//div[contains(@class, "information")]/div/div/div[2]')->text(); $count = JString::cleanse($count); - $count = str_replace('K', '000', $count); $count = str_replace('M', '000000', $count); @@ -272,7 +256,6 @@ public function getMangaImage(): ?string public function getMangaScore(): ?float { $score = JString::cleanse($this->crawler->filterXPath('//div[contains(@class, "information")]/div/div/div[1]')->text()); - if ($score === 'N/A') { return null; } diff --git a/src/Parser/Common/PicturesPageParser.php b/src/Parser/Common/PicturesPageParser.php index 610aaa65..c8573bcd 100644 --- a/src/Parser/Common/PicturesPageParser.php +++ b/src/Parser/Common/PicturesPageParser.php @@ -3,6 +3,8 @@ namespace Jikan\Parser\Common; use Jikan\Model\Common\Picture; +use Jikan\Model\Resource\AnimeImageResource\AnimePicturesImageResource; +use Jikan\Model\Resource\CommonImageResource\CommonImageResource; use Jikan\Parser\ParserInterface; use Symfony\Component\DomCrawler\Crawler; @@ -38,7 +40,10 @@ public function getModel(): array ->filterXPath('//a[@class="js-picture-gallery"]') ->each( function (Crawler $crawler) { - return Picture::fromParser(new PictureParser($crawler)); + return CommonImageResource::factory( + Picture::fromParser(new PictureParser($crawler)) + ->getImageUrl() + ); } ); } diff --git a/src/Parser/Common/Recommendation.php b/src/Parser/Common/Recommendation.php index 0bdd1849..0b3792af 100644 --- a/src/Parser/Common/Recommendation.php +++ b/src/Parser/Common/Recommendation.php @@ -4,6 +4,8 @@ use Jikan\Helper\Constants; use Jikan\Helper\Parser; +use Jikan\Model\Common\CommonMeta; +use Jikan\Model\Common\ItemMeta; use Jikan\Parser\ParserInterface; use Symfony\Component\DomCrawler\Crawler; @@ -95,4 +97,13 @@ public function getModel(): \Jikan\Model\Common\Recommendation { return \Jikan\Model\Common\Recommendation::fromParser($this); } + + public function getEntryMeta() : CommonMeta + { + return new CommonMeta( + $this->getTitle(), + $this->getUrl(), + $this->getImageUrl() + ); + } } diff --git a/src/Parser/Common/UrlParser.php b/src/Parser/Common/UrlParser.php index 1798a32a..c3d43b85 100644 --- a/src/Parser/Common/UrlParser.php +++ b/src/Parser/Common/UrlParser.php @@ -39,4 +39,4 @@ public function getModel(): Url $this->crawler->attr('href') ); } -} +} \ No newline at end of file diff --git a/src/Parser/Forum/ForumTopicParser.php b/src/Parser/Forum/ForumTopicParser.php index a93b0927..6ec54113 100644 --- a/src/Parser/Forum/ForumTopicParser.php +++ b/src/Parser/Forum/ForumTopicParser.php @@ -7,7 +7,6 @@ use Jikan\Helper\Parser; use Jikan\Model\Forum\ForumPost; use Symfony\Component\DomCrawler\Crawler; -use function GuzzleHttp\Psr7\parse_query; /** * Class ForumPostParser @@ -37,7 +36,7 @@ public function __construct(Crawler $crawler) */ public function getTopicId(): int { - $query = parse_query(explode('?', $this->getUrl())[1]); + parse_str(explode('?', $this->getUrl())[1], $query); return (int)$query['topicid']; } diff --git a/src/Parser/Magazine/MagazineListItemParser.php b/src/Parser/Magazine/MagazineListItemParser.php index 2aaed465..37c9f31f 100644 --- a/src/Parser/Magazine/MagazineListItemParser.php +++ b/src/Parser/Magazine/MagazineListItemParser.php @@ -56,7 +56,7 @@ public function getUrl(): string */ public function getName(): string { - preg_match('~(.+)\s\(\d+\)~', $this->crawler->text(), $node); + preg_match('~(.+)\s\(.*\)~', $this->crawler->text(), $node); return $node[1]; } @@ -69,6 +69,11 @@ public function getName(): string public function getCount(): int { preg_match('~.+\s\((.+)\)~', $this->crawler->text(), $node); + + if ($node[1] === '-') { + return 0; + } + $count = str_replace(',', '', $node[1]); return $count; diff --git a/src/Parser/Manga/MangaParser.php b/src/Parser/Manga/MangaParser.php index 46505035..736115ae 100644 --- a/src/Parser/Manga/MangaParser.php +++ b/src/Parser/Manga/MangaParser.php @@ -110,7 +110,7 @@ public function getMangaTitleEnglish(): ?string } return JString::cleanse( - str_replace($title->text(), '', $title->parents()->text()) + str_replace($title->text(), '', $title->ancestors()->text()) ); } @@ -128,8 +128,8 @@ public function getMangaTitleSynonyms(): array return []; } - $titles = str_replace($title->text(), '', $title->parents()->text()); - $titles = explode(',', $titles); + $titles = str_replace($title->text(), '', $title->ancestors()->text()); + $titles = explode(', ', $titles); foreach ($titles as &$title) { $title = JString::cleanse($title); @@ -152,7 +152,7 @@ public function getMangaTitleJapanese(): ?string } return JString::cleanse( - str_replace($title->text(), '', $title->parents()->text()) + str_replace($title->text(), '', $title->ancestors()->text()) ); } @@ -170,7 +170,7 @@ public function getMangaType(): ?string } return JString::cleanse( - str_replace($type->text(), '', $type->parents()->text()) + str_replace($type->text(), '', $type->ancestors()->text()) ); } @@ -191,7 +191,7 @@ public function getMangaChapters(): ?int return ( trim( - str_replace($chapters->text(), '', $chapters->parents()->text()) + str_replace($chapters->text(), '', $chapters->ancestors()->text()) ) === 'Unknown' ) ? @@ -200,7 +200,7 @@ public function getMangaChapters(): ?int (int)str_replace( $chapters->text(), '', - $chapters->parents()->text() + $chapters->ancestors()->text() ); } @@ -221,7 +221,7 @@ public function getMangaVolumes(): ?int return ( trim( - str_replace($volumes->text(), '', $volumes->parents()->text()) + str_replace($volumes->text(), '', $volumes->ancestors()->text()) ) === 'Unknown' ) ? @@ -230,7 +230,7 @@ public function getMangaVolumes(): ?int (int)str_replace( $volumes->text(), '', - $volumes->parents()->text() + $volumes->ancestors()->text() ); } @@ -248,7 +248,7 @@ public function getMangaStatus(): ?string } return JString::cleanse( - str_replace($status->text(), '', $status->parents()->text()) + str_replace($status->text(), '', $status->ancestors()->text()) ); } @@ -293,8 +293,8 @@ public function getGenres(): array $genre = $this->crawler ->filterXPath('//span[text()="Genres:"]'); - if ($genre->count() && strpos($genre->parents()->text(), 'No genres have been added yet') === false) { - return $genre->parents()->first()->filterXPath('//a')->each( + if ($genre->count() && strpos($genre->ancestors()->text(), 'No genres have been added yet') === false) { + return $genre->ancestors()->first()->filterXPath('//a')->each( function (Crawler $crawler) { return (new MalUrlParser($crawler))->getModel(); } @@ -304,8 +304,8 @@ function (Crawler $crawler) { $genre = $this->crawler ->filterXPath('//span[text()="Genre:"]'); - if ($genre->count() && strpos($genre->parents()->text(), 'No genres have been added yet') === false) { - return $genre->parents()->first()->filterXPath('//a')->each( + if ($genre->count() && strpos($genre->ancestors()->text(), 'No genres have been added yet') === false) { + return $genre->ancestors()->first()->filterXPath('//a')->each( function (Crawler $crawler) { return (new MalUrlParser($crawler))->getModel(); } @@ -325,8 +325,8 @@ public function getExplicitGenres(): array $genre = $this->crawler ->filterXPath('//span[text()="Explicit Genres:"]'); - if ($genre->count() && strpos($genre->parents()->text(), 'No genres have been added yet') === false) { - return $genre->parents()->first()->filterXPath('//a')->each( + if ($genre->count() && strpos($genre->ancestors()->text(), 'No genres have been added yet') === false) { + return $genre->ancestors()->first()->filterXPath('//a')->each( function (Crawler $crawler) { return (new MalUrlParser($crawler))->getModel(); } @@ -336,8 +336,8 @@ function (Crawler $crawler) { $genre = $this->crawler ->filterXPath('//span[text()="Explicit Genre:"]'); - if ($genre->count() && strpos($genre->parents()->text(), 'No genres have been added yet') === false) { - return $genre->parents()->first()->filterXPath('//a')->each( + if ($genre->count() && strpos($genre->ancestors()->text(), 'No genres have been added yet') === false) { + return $genre->ancestors()->first()->filterXPath('//a')->each( function (Crawler $crawler) { return (new MalUrlParser($crawler))->getModel(); } @@ -358,7 +358,7 @@ public function getDemographics(): array ->filterXPath('//span[text()="Demographics:"]'); if ($genre->count()) { - return $genre->parents()->first()->filterXPath('//a')->each( + return $genre->ancestors()->first()->filterXPath('//a')->each( function (Crawler $crawler) { return (new MalUrlParser($crawler))->getModel(); } @@ -369,7 +369,7 @@ function (Crawler $crawler) { ->filterXPath('//span[text()="Demographic:"]'); if ($genre->count()) { - return $genre->parents()->first()->filterXPath('//a')->each( + return $genre->ancestors()->first()->filterXPath('//a')->each( function (Crawler $crawler) { return (new MalUrlParser($crawler))->getModel(); } @@ -390,7 +390,7 @@ public function getThemes(): array ->filterXPath('//span[text()="Theme:"]'); if ($genre->count()) { - return $genre->parents()->first()->filterXPath('//a')->each( + return $genre->ancestors()->first()->filterXPath('//a')->each( function (Crawler $crawler) { return (new MalUrlParser($crawler))->getModel(); } @@ -401,7 +401,7 @@ function (Crawler $crawler) { ->filterXPath('//span[text()="Themes:"]'); if ($genre->count()) { - return $genre->parents()->first()->filterXPath('//a')->each( + return $genre->ancestors()->first()->filterXPath('//a')->each( function (Crawler $crawler) { return (new MalUrlParser($crawler))->getModel(); } @@ -463,7 +463,7 @@ public function getMangaRank(): ?int return null; } - $rank = Parser::removeChildNodes($rank->parents()); + $rank = Parser::removeChildNodes($rank->ancestors()); $ranked = trim( str_replace( '#', @@ -490,7 +490,7 @@ public function getMangaPopularity(): ?int } return JString::cleanse( - str_replace([$popularity->text(), '#'], '', $popularity->parents()->text()) + str_replace([$popularity->text(), '#'], '', $popularity->ancestors()->text()) ); } @@ -509,7 +509,7 @@ public function getMangaMembers(): ?int } return JString::cleanse( - str_replace([$member->text(), ','], '', $member->parents()->text()) + str_replace([$member->text(), ','], '', $member->ancestors()->text()) ); } @@ -528,7 +528,7 @@ public function getMangaFavorites(): ?int } return JString::cleanse( - str_replace([$favorite->text(), ','], '', $favorite->parents()->text()) + str_replace([$favorite->text(), ','], '', $favorite->ancestors()->text()) ); } @@ -636,7 +636,7 @@ public function getMangaPublishedString(): ?string } return JString::cleanse( - str_replace($aired->text(), '', $aired->parents()->text()) + str_replace($aired->text(), '', $aired->ancestors()->text()) ); } } diff --git a/src/Parser/Manga/MangaRecentlyUpdatedByUsersListParser.php b/src/Parser/Manga/MangaRecentlyUpdatedByUsersListParser.php index bccb8eb4..fa2f63bb 100644 --- a/src/Parser/Manga/MangaRecentlyUpdatedByUsersListParser.php +++ b/src/Parser/Manga/MangaRecentlyUpdatedByUsersListParser.php @@ -2,6 +2,7 @@ namespace Jikan\Parser\Manga; +use Jikan\Model\Common\UserMeta; use Jikan\Model\Manga\MangaRecentlyUpdatedByUser; use Jikan\Parser\ParserInterface; use Symfony\Component\DomCrawler\Crawler; @@ -193,4 +194,13 @@ public function getModel(): MangaRecentlyUpdatedByUser { return MangaRecentlyUpdatedByUser::fromParser($this); } + + public function getUserMeta() : UserMeta + { + return new UserMeta( + $this->getUsername(), + $this->getUrl(), + $this->getImageUrl() + ); + } } diff --git a/src/Parser/Manga/MangaRecentlyUpdatedByUsersParser.php b/src/Parser/Manga/MangaRecentlyUpdatedByUsersParser.php index ab31d497..c7c3efe3 100644 --- a/src/Parser/Manga/MangaRecentlyUpdatedByUsersParser.php +++ b/src/Parser/Manga/MangaRecentlyUpdatedByUsersParser.php @@ -2,6 +2,8 @@ namespace Jikan\Parser\Manga; +use Jikan\Model\Manga\Manga; +use Jikan\Model\Manga\MangaUserUpdates; use Jikan\Parser\ParserInterface; use Symfony\Component\DomCrawler\Crawler; @@ -10,7 +12,7 @@ * * @package Jikan\Parser\Manag */ -class MangaRecentlyUpdatedByUsersParser implements ParserInterface +class MangaRecentlyUpdatedByUsersParser { /** * @var Crawler @@ -31,7 +33,7 @@ public function __construct(Crawler $crawler) * @return array * @throws \InvalidArgumentException */ - public function getModel(): array + public function getResults(): array { try { return $this->crawler @@ -46,4 +48,21 @@ function ($c) { return []; } } + + + // @todo anime user updates pagination + public function getHasNextPage() : bool + { + return false; + } + + public function getLastPage() : int + { + return 1; + } + + public function getModel(): MangaUserUpdates + { + return MangaUserUpdates::fromParser($this); + } } diff --git a/src/Parser/Manga/MangaReviewsParser.php b/src/Parser/Manga/MangaReviewsParser.php index fcc858ce..ac82f608 100644 --- a/src/Parser/Manga/MangaReviewsParser.php +++ b/src/Parser/Manga/MangaReviewsParser.php @@ -2,7 +2,9 @@ namespace Jikan\Parser\Manga; +use Jikan\Model\Manga\MangaReviews; use Jikan\Parser\ParserInterface; +use Jikan\Parser\Reviews\MangaReviewParser; use Symfony\Component\DomCrawler\Crawler; /** @@ -27,12 +29,17 @@ public function __construct(Crawler $crawler) $this->crawler = $crawler; } + public function getModel() : MangaReviews + { + return MangaReviews::fromParser($this); + } + /** * @return array * @throws \RuntimeException * @throws \InvalidArgumentException */ - public function getModel(): array + public function getResults(): array { return $this->crawler ->filterXPath('//div[@class="borderDark"]') @@ -42,4 +49,19 @@ function (Crawler $c) { } ); } + + /** + * @return bool + */ + public function hasNextPage(): bool // @TODO WIP + { + $node = $this->crawler + ->filterXPath('//*[@id="horiznav_nav"]/div/a[contains(text(), "Next")]'); + + if ($node->count()) { + return true; + } + + return false; + } } diff --git a/src/Parser/Manga/MangaStatsParser.php b/src/Parser/Manga/MangaStatsParser.php index f7315154..6bb7c0f8 100644 --- a/src/Parser/Manga/MangaStatsParser.php +++ b/src/Parser/Manga/MangaStatsParser.php @@ -41,7 +41,7 @@ public function getReading(): int return $this->sanitize( $this->crawler ->filterXPath('//div[@class="spaceit_pad"]/span[contains(text(), \'Reading:\')]') - ->parents() + ->ancestors() ->getNode(0)->textContent ); } catch (\Exception $e) { @@ -69,7 +69,7 @@ public function getCompleted(): int return $this->sanitize( $this->crawler ->filterXPath('//div[@class="spaceit_pad"]/span[contains(text(), \'Completed:\')]') - ->parents() + ->ancestors() ->getNode(0)->textContent ); } catch (\Exception $e) { @@ -87,7 +87,7 @@ public function getOnHold(): int return $this->sanitize( $this->crawler ->filterXPath('//div[@class="spaceit_pad"]/span[contains(text(), \'On-Hold:\')]') - ->parents() + ->ancestors() ->getNode(0)->textContent ); } catch (\Exception $e) { @@ -105,7 +105,7 @@ public function getDropped(): int return $this->sanitize( $this->crawler ->filterXPath('//div[@class="spaceit_pad"]/span[contains(text(), \'Dropped:\')]') - ->parents() + ->ancestors() ->getNode(0)->textContent ); } catch (\Exception $e) { @@ -123,7 +123,7 @@ public function getPlanToRead(): int return $this->sanitize( $this->crawler ->filterXPath('//div[@class="spaceit_pad"]/span[contains(text(), \'Plan to Read:\')]') - ->parents() + ->ancestors() ->getNode(0)->textContent ); } catch (\Exception $e) { @@ -141,7 +141,7 @@ public function getTotal(): int return $this->sanitize( $this->crawler ->filterXPath('//div[@class="spaceit_pad"]/span[contains(text(), \'Total:\')]') - ->parents() + ->ancestors() ->getNode(0)->textContent ); } catch (\Exception $e) { @@ -175,13 +175,13 @@ function (Crawler $crawler) use (&$scores) { ); $percentage = (float) JString::cleanse($percentage); - $scores[$score] = MangaStatsScore::setProperties($votes, $percentage); + $scores[$score] = MangaStatsScore::setProperties($score, $votes, $percentage); } ); for ($i=1; $i<=10; $i++) { if (!array_key_exists($i, $scores)) { - $scores[$i] = MangaStatsScore::setProperties(0, 0); + $scores[$i] = MangaStatsScore::setProperties(0, 0, 0); } } diff --git a/src/Parser/Person/AnimeStaffPositionParser.php b/src/Parser/Person/AnimeStaffPositionParser.php index aed36cf7..6aa86357 100644 --- a/src/Parser/Person/AnimeStaffPositionParser.php +++ b/src/Parser/Person/AnimeStaffPositionParser.php @@ -47,10 +47,11 @@ public function getModel(): Model\Person\AnimeStaffPosition */ public function getPosition(): string { + $role = $this->crawler + ->filterXPath('//td[2]/div[2]'); + return JString::cleanse( - $this->crawler - ->filterXPath('//small') - ->text() + $role->text() ); } diff --git a/src/Parser/Person/PersonParser.php b/src/Parser/Person/PersonParser.php index c9ccac7a..16f52042 100644 --- a/src/Parser/Person/PersonParser.php +++ b/src/Parser/Person/PersonParser.php @@ -97,7 +97,7 @@ public function getPersonGivenName(): ?string } return JString::cleanse( - str_replace($node->text(), '', $node->parents()->text()) + str_replace($node->text(), '', $node->ancestors()->text()) ); } @@ -117,7 +117,7 @@ public function getPersonFamilyName(): ?string // MAL screwed up the HTML here preg_match( '~Family name:(.*?)(Alternate names|Birthday|Website|Member Favorites|More)~', - $node->parents()->text(), + $node->ancestors()->text(), $matches ); @@ -149,7 +149,7 @@ public function getPersonAlternateNames(): array $names = explode( ',', - str_replace($node->text(), '', $node->parents()->text()) + str_replace($node->text(), '', $node->ancestors()->text()) ); foreach ($names as &$name) { @@ -202,7 +202,7 @@ public function getPersonBirthday(): ?\DateTimeImmutable return Parser::parseDateMDYReadable( JString::cleanse( - str_replace($node->text(), '', $node->parents()->text()) + str_replace($node->text(), '', $node->ancestors()->text()) ) ); } @@ -222,7 +222,7 @@ public function getPersonFavorites(): ?int } return (int)JString::cleanse( - str_replace([$node->text(), ','], '', $node->parents()->text()) + str_replace([$node->text(), ','], '', $node->ancestors()->text()) ); } @@ -259,7 +259,7 @@ public function getPersonAbout(): ?string public function getPersonVoiceActingRoles(): array { $node = $this->crawler - ->filterXPath('//table[contains(@class, "js-table-people-anime")]/tr[contains(@class, "js-people-anime")]'); + ->filterXPath('//table[contains(@class, "js-table-people-character")]/tr[contains(@class, "js-people-character")]'); if (!$node->count()) { return []; @@ -280,7 +280,7 @@ function (Crawler $c) { public function getPersonAnimeStaffPositions(): array { $node = $this->crawler - ->filterXPath('//table[contains(@class, \'js-table-people-staff\')]/tr'); + ->filterXPath('//table[contains(@class, "js-table-people-staff")]/tr[contains(@class, "js-people-staff")]'); if (!$node->count()) { return []; @@ -301,13 +301,12 @@ function (Crawler $c) { public function getPersonPublishedManga(): array { $node = $this->crawler - ->filterXPath('//table[contains(@class, \'js-table-people-manga\')]/tr'); + ->filterXPath('//table[contains(@class, "js-table-people-manga")]/tr[contains(@class, "js-people-manga")]'); if (!$node->count()) { return []; } - return $node->each( function (Crawler $c) { return (new PublishedMangaParser($c))->getModel(); diff --git a/src/Parser/Person/PublishedMangaParser.php b/src/Parser/Person/PublishedMangaParser.php index 68c813dc..3754a656 100644 --- a/src/Parser/Person/PublishedMangaParser.php +++ b/src/Parser/Person/PublishedMangaParser.php @@ -47,10 +47,11 @@ public function getModel(): Model\Person\PublishedManga */ public function getPosition(): string { + $role = $this->crawler + ->filterXPath('//td[2]/div[2]/small'); + return JString::cleanse( - $this->crawler - ->filterXPath('//small') - ->text() + $role->text() ); } diff --git a/src/Parser/Producer/ProducerListItemParser.php b/src/Parser/Producer/ProducerListItemParser.php index dd9695ad..80fb1713 100644 --- a/src/Parser/Producer/ProducerListItemParser.php +++ b/src/Parser/Producer/ProducerListItemParser.php @@ -59,7 +59,7 @@ public function getUrl(): string */ public function getName(): string { - preg_match('~(.+)\s\(\d+\)~', $this->crawler->text(), $node); + preg_match('~(.+)\s\(.*\)~', $this->crawler->text(), $node); return $node[1]; } @@ -72,6 +72,11 @@ public function getName(): string public function getCount(): int { preg_match('~.+\s\((.+)\)~', $this->crawler->text(), $node); + + if ($node[1] === '-') { + return 0; + } + $count = str_replace(',', '', $node[1]); return $count; diff --git a/src/Parser/Recommendations/RecentRecommendationsParser.php b/src/Parser/Recommendations/RecentRecommendationsParser.php new file mode 100644 index 00000000..56d4ca7a --- /dev/null +++ b/src/Parser/Recommendations/RecentRecommendationsParser.php @@ -0,0 +1,113 @@ +crawler = $crawler; + } + + /** + * @return RecentReviews + * @throws \Exception + */ + public function getModel(): RecentRecommendations + { + return RecentRecommendations::fromParser($this); + } + + /** + * @return array + * @throws \RuntimeException + * @throws \InvalidArgumentException + */ + public function getRecentRecommendations(): array + { + return $this->crawler + ->filterXPath('//*[@id="content"]/div[3]/div[contains(@class, "spaceit borderClass")]') + ->each( + function (Crawler $crawler) { + return RecommendationListItem::fromParser(new RecommendationListItemParser($crawler)); + } + ); + } + + /** + * @return array + * @throws \RuntimeException + * @throws \InvalidArgumentException + */ + public function getUserRecommendations(): array + { + return $this->crawler + ->filterXPath('//*[@id="content"]/div/div[2]/div/div[2]/div[contains(@class, "spaceit borderClass")]') + ->each( + function (Crawler $crawler) { + return RecommendationListItem::fromParser(new RecommendationListItemParser($crawler)); + } + ); + } + + /** + * @return bool + */ + public function hasNextPage(): bool + { + $pages = $this->crawler + ->filterXPath('//*[@id="horiznav_nav"]/div/span'); + + if (!$pages->count()) { + return false; + } + + if (preg_match('~\[\d+]\s(\d+)~', $pages->text())) { + return true; + } + + return false; + } + + /** + * @return int + * @throws \InvalidArgumentException + */ + public function getLastPage(): int + { + $pages = $this->crawler + ->filterXPath('//*[@id="horiznav_nav"]/div/span'); + + if (!$pages->count()) { + return 1; + } + + $pages = explode(' ', $pages->text()); + + return (int) str_replace(['[', ']'], '', end($pages)); + } +} diff --git a/src/Parser/Recommendations/RecommendationListItemParser.php b/src/Parser/Recommendations/RecommendationListItemParser.php new file mode 100644 index 00000000..23c40b86 --- /dev/null +++ b/src/Parser/Recommendations/RecommendationListItemParser.php @@ -0,0 +1,101 @@ +crawler = $crawler; + } + + /** + * @return Model\Recommendations\RecommendationListItem + * @throws \RuntimeException + * @throws \InvalidArgumentException + */ + public function getModel(): Model\Recommendations\RecommendationListItem + { + return Model\Recommendations\RecommendationListItem::fromParser($this); + } + + public function getRecommendations(): array + { + return $this->crawler + ->filterXPath('//table/tr/td') + ->each(function (Crawler $crawler) { + return new Model\Common\CommonMeta( + $crawler->filterXPath('//a/strong')->text(), + $crawler->filterXPath('//a')->attr('href'), + $crawler->filterXPath('//div[1]/a/img')->attr('data-src') + ); + }); + } + + public function getContent(): string + { + // User Profile Recommendations + $node = $this->crawler + ->filterXPath('//p[contains(@class, "profile-user-recs-text")]'); + + if ($node->count()) { + return $node->text(); + } + + // Recent Recommendations + return $this->crawler + ->filterXPath('//div[contains(@class, "recommendations-user-recs-text")]')->text(); + } + + public function getDate(): ?\DateTimeImmutable + { + $node = Parser::removeChildNodes( + $this->crawler + ->filterXPath('//div[contains(@class, "lightLink")]') + ); + + $date = JString::cleanse($node->text()); + + preg_match('~- (.*)$~', $date, $time); + + try { + return new \DateTimeImmutable( + $time[1], + new \DateTimeZone('UTC') + ); + } catch (\Exception $e) { + return null; + } + } + + public function getRecommender(): Model\Recommendations\Recommender + { + return Model\Recommendations\Recommender::fromMeta( + Constants::BASE_URL . $this->crawler->filterXPath('//div[contains(@class, "lightLink")]/a')->attr('href'), + $this->crawler->filterXPath('//div[contains(@class, "lightLink")]/a')->text() + ); + } +} diff --git a/src/Parser/Recommendations/UserRecommendationsParser.php b/src/Parser/Recommendations/UserRecommendationsParser.php new file mode 100644 index 00000000..49f7ab14 --- /dev/null +++ b/src/Parser/Recommendations/UserRecommendationsParser.php @@ -0,0 +1,100 @@ +crawler = $crawler; + } + + /** + * @return RecentReviews + * @throws \Exception + */ + public function getModel(): UserRecommendations + { + return UserRecommendations::fromParser($this); + } + + /** + * @return array + * @throws \RuntimeException + * @throws \InvalidArgumentException + */ + public function getUserRecommendations(): array + { + return $this->crawler + ->filterXPath('//*[@id="content"]/div/div[2]/div/div[2]/div[contains(@class, "spaceit borderClass")]') + ->each( + function (Crawler $crawler) { + return RecommendationListItem::fromParser(new RecommendationListItemParser($crawler)); + } + ); + } + + /** + * @return bool + */ + public function hasNextPage(): bool + { + $node = $this->crawler + ->filterXPath('//*[@id="content"]/div/div[2]/div/div[2]/div[1]/a[contains(text(), "More Recommendations")]'); + + if ($node->count()) { + return true; + } + + return false; + } + + /** + * @return int + * @throws \InvalidArgumentException + */ + public function getLastPage(): int + { + $pages = $this->crawler + ->filterXPath('//*[@id="content"]/div/div[2]/div/div[2]/div[2]/div[contains(text(), "Total Recommendations:")]'); + + if (!$pages->count()) { + return 1; + } + + preg_match('~Total Recommendations: (.*)$~', $pages->text(), $pages); + + if (empty($pages)) { + return 1; + } + + $recommendationsCount = (int) str_replace(',', '', $pages[1]); + + return ceil($recommendationsCount/30); + } +} diff --git a/src/Parser/Search/PersonSearchParser.php b/src/Parser/Search/PersonSearchParser.php index 48a7e627..4cf3a331 100644 --- a/src/Parser/Search/PersonSearchParser.php +++ b/src/Parser/Search/PersonSearchParser.php @@ -70,7 +70,6 @@ function (Crawler $c) { return (new PersonSearchListItemParser($c))->getModel(); } ); - } /** @@ -80,12 +79,33 @@ function (Crawler $c) { public function getLastPage(): int { $pages = $this->crawler - ->filterXPath('//div[@id="content"]/div[@class="borderClass"][1]/div/span/a'); + ->filterXPath('//div[contains(@class, "normal_header")]/div/div/span'); if (!$pages->count()) { return 1; } - return (int)$pages->last()->text(); + $pages = explode(' ', $pages->text()); + + return (int) str_replace(['[', ']'], '', end($pages)); + } + + /** + * @return bool + */ + public function getHasNextPage(): bool + { + $pages = $this->crawler + ->filterXPath('//div[contains(@class, "normal_header")]/div/div/span'); + + if (!$pages->count()) { + return false; + } + + if (preg_match('~\[\d+]\s(\d+)~', $pages->text())) { + return true; + } + + return false; } } diff --git a/src/Parser/Search/UserSearchListItemParser.php b/src/Parser/Search/UserSearchListItemParser.php new file mode 100644 index 00000000..3e787a52 --- /dev/null +++ b/src/Parser/Search/UserSearchListItemParser.php @@ -0,0 +1,93 @@ +crawler = $crawler; + } + + /** + * @return UserSearchListItem + * @throws \Exception + * @throws \RuntimeException + * @throws \InvalidArgumentException + */ + public function getModel(): UserSearchListItem + { + return UserSearchListItem::fromParser($this); + } + + /** + * @return string + * @throws \InvalidArgumentException + */ + public function getUsername(): string + { + return $this->crawler->filterXPath('//div[1]/a')->text(); + } + + /** + * @return string + * @throws \InvalidArgumentException + */ + public function getUrl(): string + { + return Constants::BASE_URL . $this->crawler->filterXPath('//div[1]/a')->attr('href'); + } + + /** + * @return string + * @throws \InvalidArgumentException + */ + public function getImageUrl(): string + { + return Parser::parseImageThumbToHQ( + $this->crawler->filterXPath('//div[2]/a/img') + ->attr('data-src') + ); + } + + /** + * @return ?\DateTimeImmutable + * @throws \InvalidArgumentException + */ + public function getLastOnline(): ?\DateTimeImmutable + { + $lastOnline = JString::UTF8NbspTrim( + $this->crawler->filterXPath('//div[3]/small')->text() + ); + + try { + return new \DateTimeImmutable( + $lastOnline, + new \DateTimeZone('UTC') + ); + } catch (\Exception $e) { + return null; + } + } +} diff --git a/src/Parser/SeasonList/SeasonListItemParser.php b/src/Parser/SeasonList/SeasonListItemParser.php index 0d44d39b..50a3d82a 100644 --- a/src/Parser/SeasonList/SeasonListItemParser.php +++ b/src/Parser/SeasonList/SeasonListItemParser.php @@ -62,11 +62,13 @@ public function getSeasons(): array { $seasons = $this->crawler->text(); - return array_filter( + $seasons = array_filter( Constants::SEASONS, function ($season) use ($seasons) { return preg_match("/$season/", $seasons); } ); + + return array_map('strtolower', $seasons); } } diff --git a/src/Parser/SeasonList/SeasonListParser.php b/src/Parser/SeasonList/SeasonListParser.php index 1c06ee17..c83611a3 100644 --- a/src/Parser/SeasonList/SeasonListParser.php +++ b/src/Parser/SeasonList/SeasonListParser.php @@ -2,6 +2,8 @@ namespace Jikan\Parser\SeasonList; +use Jikan\Model\Anime\AnimeReviews; +use Jikan\Model\SeasonList\SeasonArchive; use Jikan\Model\SeasonList\SeasonListItem; use Jikan\Parser\ParserInterface; use Symfony\Component\DomCrawler\Crawler; @@ -11,7 +13,7 @@ * * @package Jikan\Parser\SeasonList */ -class SeasonListParser implements ParserInterface +class SeasonListParser { /** * @var Crawler @@ -28,12 +30,20 @@ public function __construct(Crawler $crawler) $this->crawler = $crawler; } + /** + * @return SeasonArchive + */ + public function getModel() : SeasonArchive + { + return SeasonArchive::fromParser($this); + } + /** * @return SeasonListItem[] * @throws \RuntimeException * @throws \InvalidArgumentException */ - public function getModel(): array + public function getResults(): array { return $this->crawler ->filterXPath('//table[contains(@class, "anime-seasonal-byseason")]//tr') diff --git a/src/Parser/Anime/AnimeReviewParser.php b/src/Parser/Top/AnimeReviewParser.php similarity index 56% rename from src/Parser/Anime/AnimeReviewParser.php rename to src/Parser/Top/AnimeReviewParser.php index 40f644a0..c9cce376 100644 --- a/src/Parser/Anime/AnimeReviewParser.php +++ b/src/Parser/Top/AnimeReviewParser.php @@ -1,11 +1,14 @@ getReviewedTitle(), + $this->getReviewedUrl(), + $this->getReviewedImageUrl() + ); + } + /** * @return int * @throws \InvalidArgumentException @@ -61,19 +76,78 @@ public function getUrl(): string return $node->attr('href'); } + /** + * @return string + * @throws \InvalidArgumentException + */ + public function getReviewedTitle(): string + { + return $this->crawler + ->filterXPath('//div[1]/div[1]/div[2]/strong/a') + ->text(); + } + + /** + * @return string + * @throws \InvalidArgumentException + */ + public function getReviewedUrl(): string + { + // User UserReviews page + $node = $this->crawler + ->filterXPath('//div[12]/div[1]/div[1]/a'); + + if ($node->count()) { + return $node->attr('href'); + } + + // Recent UserReviews page + $node = $this->crawler + ->filterXPath('//div[1]/div[2]/div[1]/div[1]/a'); + + return $node->attr('href'); + } + + /** + * @return string + * @throws \InvalidArgumentException + */ + public function getReviewedImageUrl(): string + { + // User UserReviews page + $node = $this->crawler + ->filterXPath('//div[12]/div[1]/div[1]/a/img'); + + if ($node->count()) { + return Parser::parseImageQuality($node->attr('data-src')); + } + + // Recent UserReviews page + $node = $this->crawler + ->filterXPath('//div[1]/div[2]/div[1]/div[1]/a/img'); + + return Parser::parseImageQuality($node->attr('data-src')); + } + /** * @return int * @throws \InvalidArgumentException */ public function getHelpfulCount(): int { + // works on Profile pages + $node = $this->crawler->filterXPath('//div[1]/div[1]/div[4]/table/tr/td[1]/div/strong/span'); + if ($node->count()) { + return $node->text(); + } + // works on Anime/Manga Review pages $node = $this->crawler->filterXPath('//div[1]/div[1]/div[2]/table/tr/td[2]/div/strong/span'); if ($node->count()) { return $node->text(); } - // works on Top Reviews pages, the div is shifted + // works on Top UserReviewsParser pages, the div is shifted $node = $this->crawler->filterXPath('//div[1]/div[1]/div[4]/table/tr/td[2]/div/strong/span'); return $node->text(); } @@ -121,14 +195,22 @@ public function getContent(): string return $content; } + /** - * @return AnimeReviewer - * @throws \Exception + * @return Reviewer + */ + public function getReviewer(): Reviewer + { + return (new ReviewerParser($this->crawler))->getModel(); + } + + /** + * @return AnimeReviewScores * @throws \InvalidArgumentException */ - public function getReviewer(): AnimeReviewer + public function getAnimeScores(): AnimeReviewScores { - return (new AnimeReviewerParser($this->crawler))->getModel(); + return (new AnimeReviewScoresParser($this->crawler))->getModel(); } /** @@ -150,4 +232,23 @@ public function getType(): ?string ) ); } + + /** + * @return int + * @throws \InvalidArgumentException + */ + public function getEpisodesWatched(): int + { + $nodeText = JString::cleanse( + $this->crawler->filterXPath('//div[1]/div[1]/div[1]/div[2]')->text() + ); + + preg_match('~(\d+) of (.*) episodes seen~', $nodeText, $episodesSeen); + + if (empty($episodesSeen)) { + return 0; + } + + return (int) $episodesSeen[1]; + } } diff --git a/src/Parser/Anime/AnimeReviewScoresParser.php b/src/Parser/Top/AnimeReviewScoresParser.php similarity index 98% rename from src/Parser/Anime/AnimeReviewScoresParser.php rename to src/Parser/Top/AnimeReviewScoresParser.php index fb71d6b7..2c990235 100644 --- a/src/Parser/Anime/AnimeReviewScoresParser.php +++ b/src/Parser/Top/AnimeReviewScoresParser.php @@ -1,6 +1,6 @@ getReviewedTitle(), + $this->getReviewedUrl(), + $this->getReviewedImageUrl() + ); + } + /** * @return int * @throws \InvalidArgumentException @@ -73,8 +87,14 @@ public function getHelpfulCount(): int return $node->text(); } - // works on Top Reviews pages, the div is shifted + // works on Top UserReviewsParser pages, the div is shifted $node = $this->crawler->filterXPath('//div[1]/div[1]/div[4]/table/tr/td[2]/div/strong/span'); + if ($node->count()) { + return $node->text(); + } + + // works on User UserReviews pages + $node = $this->crawler->filterXPath('//div[1]/div[1]/div[4]/table/tr/td/div/strong/span'); return $node->text(); } @@ -122,15 +142,21 @@ public function getContent(): string } /** - * @return MangaReviewer - * @throws \Exception - * @throws \InvalidArgumentException + * @return Reviewer */ - public function getReviewer(): MangaReviewer + public function getReviewer(): Reviewer { - return (new MangaReviewerParser($this->crawler))->getModel(); + return (new ReviewerParser($this->crawler))->getModel(); } + /** + * @return MangaReviewScores + * @throws \InvalidArgumentException + */ + public function getMangaScores(): MangaReviewScores + { + return (new MangaReviewScoresParser($this->crawler))->getModel(); + } /** * @return string|null @@ -151,4 +177,78 @@ public function getType(): ?string ) ); } + + /** + * @return string + * @throws \InvalidArgumentException + */ + public function getReviewedTitle(): string + { + return $this->crawler + ->filterXPath('//div[1]/div[1]/div[2]/strong/a') + ->text(); + } + + /** + * @return string + * @throws \InvalidArgumentException + */ + public function getReviewedImageUrl(): string + { + // User UserReviews page + $node = $this->crawler + ->filterXPath('//div[12]/div[1]/div[1]/a/img'); + + if ($node->count()) { + return Parser::parseImageQuality($node->attr('data-src')); + } + + // Recent UserReviews Anime page + $node = $this->crawler + ->filterXPath('//div[1]/div[2]/div[1]/div[1]/a/img'); + + if ($node->count()) { + return Parser::parseImageQuality($node->attr('data-src')); + } + } + + /** + * @return string + * @throws \InvalidArgumentException + */ + public function getReviewedUrl(): string + { + // User UserReviews page + $node = $this->crawler + ->filterXPath('//div[12]/div[1]/div[1]/a'); + + if ($node->count()) { + return $node->attr('href'); + } + + // Recent UserReviews Anime page + $node = $this->crawler + ->filterXPath('//div[1]/div[2]/div[1]/div[1]/a'); + + return $node->attr('href'); + } + + /** + * @return int + * @throws \InvalidArgumentException + */ + public function getChaptersRead(): int + { + $nodeText = JString::cleanse( + $this->crawler->filterXPath('//div[1]/div[1]/div[1]/div[2]')->text() + ); + + preg_match('~(\d+) of (.*) chapters read~', $nodeText, $chaptersRead); + + if (empty($chaptersRead)) { + return 0; + } + + return (int) $chaptersRead[1]; + } } diff --git a/src/Parser/Common/ReviewerParser.php b/src/Parser/Top/ReviewerParser.php similarity index 69% rename from src/Parser/Common/ReviewerParser.php rename to src/Parser/Top/ReviewerParser.php index 4e62d76d..7b67ec36 100644 --- a/src/Parser/Common/ReviewerParser.php +++ b/src/Parser/Top/ReviewerParser.php @@ -1,11 +1,12 @@ crawler = $crawler; } + public function getModel() + { + return Reviewer::fromParser($this); + } + /** * @return string * @throws \InvalidArgumentException @@ -45,9 +51,11 @@ public function getUrl(): string return $node->attr('href'); } - // works on Top Reviews pages, the div is shifted + // works on Top UserReviewsParser pages, the div is shifted $node = $this->crawler->filterXPath('//div[1]/div[1]/div[4]/table/tr/td[2]/a'); - return $node->attr('href'); + if ($node->count()) { + return $node->attr('href'); + } } /** @@ -62,7 +70,7 @@ public function getUsername(): string return $node->text(); } - // works on Top Reviews pages, the div is shifted + // works on Top UserReviewsParser pages, the div is shifted return $this->crawler ->filterXPath('//div[1]/div[1]/div[4]/table/tr/td[2]/a') ->text(); @@ -82,7 +90,7 @@ public function getImageUrl(): string ); } - // works on Top Reviews pages, the div is shifted + // works on Top UserReviewsParser pages, the div is shifted $node = $this->crawler->filterXPath('//div[1]/div[1]/div[4]/table/tr/td[1]/div/a/img'); return Parser::parseImageThumbToHQ( $node @@ -90,44 +98,6 @@ public function getImageUrl(): string ); } - /** - * @return int - * @throws \InvalidArgumentException - */ - public function getEpisodesSeen(): int - { - $nodeText = JString::cleanse( - $this->crawler->filterXPath('//div[1]/div[1]/div[1]/div[2]')->text() - ); - - preg_match('~(\d+) of (.*) episodes seen~', $nodeText, $episodesSeen); - - if (empty($episodesSeen)) { - return 0; - } - - return (int) $episodesSeen[1]; - } - - /** - * @return int - * @throws \InvalidArgumentException - */ - public function getChaptersRead(): int - { - $nodeText = JString::cleanse( - $this->crawler->filterXPath('//div[1]/div[1]/div[1]/div[2]')->text() - ); - - preg_match('~(\d+) of (.*) chapters read~', $nodeText, $chaptersRead); - - if (empty($chaptersRead)) { - return 0; - } - - return (int) $chaptersRead[1]; - } - /** * @return AnimeReviewScores * @throws \InvalidArgumentException diff --git a/src/Parser/Top/TopReviewsParser.php b/src/Parser/Top/TopReviewsParser.php index df598e07..5d808ffc 100644 --- a/src/Parser/Top/TopReviewsParser.php +++ b/src/Parser/Top/TopReviewsParser.php @@ -1,12 +1,10 @@ crawler ->filterXPath('//*[@id="content"]/div[@class="borderDark"]') @@ -48,14 +55,29 @@ function (Crawler $crawler) { // Anime Review if ($crawler->filterXPath('//div[1]/div[1]/div[2]/small')->text() === '(Anime)') { - return AnimeReview::fromParser(new AnimeReviewParser($crawler)); + return RecentAnimeReview::fromParser(new AnimeReviewParser($crawler)); } // Manga Review if ($crawler->filterXPath('//div[1]/div[1]/div[2]/small')->text() === '(Manga)') { - return MangaReview::fromParser(new MangaReviewParser($crawler)); + return RecentMangaReview::fromParser(new MangaReviewParser($crawler)); } } ); } + + /** + * @return bool + */ + public function hasNextPage(): bool + { + $node = $this->crawler + ->filterXPath('//*[@id="horiznav_nav"]/div/a[contains(text(), "Next")]'); + + if ($node->count()) { + return true; + } + + return false; + } } diff --git a/src/Parser/User/Friends/FriendParser.php b/src/Parser/User/Friends/FriendParser.php index a7139318..e823f087 100644 --- a/src/Parser/User/Friends/FriendParser.php +++ b/src/Parser/User/Friends/FriendParser.php @@ -4,6 +4,7 @@ use Jikan\Helper\JString; use Jikan\Helper\Parser; +use Jikan\Model\Common\UserMeta; use Jikan\Model\User\Friend; use Jikan\Parser\ParserInterface; use Symfony\Component\DomCrawler\Crawler; @@ -106,4 +107,13 @@ public function getLastOnline(): \DateTimeImmutable new \DateTimeZone('UTC') ); } + + public function getUserMeta() : UserMeta + { + return new UserMeta( + $this->getName(), + $this->getUrl(), + $this->getAvatar() + ); + } } diff --git a/src/Parser/User/Friends/FriendsParser.php b/src/Parser/User/Friends/FriendsParser.php index f3b93c2f..cf6888e1 100644 --- a/src/Parser/User/Friends/FriendsParser.php +++ b/src/Parser/User/Friends/FriendsParser.php @@ -3,6 +3,7 @@ namespace Jikan\Parser\User\Friends; use Jikan\Model\User\Friend; +use Jikan\Model\User\Friends; use Jikan\Parser\ParserInterface; use Symfony\Component\DomCrawler\Crawler; @@ -28,11 +29,20 @@ public function __construct(Crawler $crawler) $this->crawler = $crawler; } + + /** + * @return Friends + */ + public function getModel(): Friends + { + return Friends::fromParser($this); + } + /** * @return Friend[] * @throws \InvalidArgumentException */ - public function getModel(): array + public function getResults(): array { return $this->crawler->filterXPath('//div[contains(@class, "boxlist-container")]/div[contains(@class, "boxlist")]')->each( function (Crawler $c) { @@ -40,4 +50,53 @@ function (Crawler $c) { } ); } + + /** + * @return int + * @throws \InvalidArgumentException + */ + public function getLastPage(): int + { + $pages = $this->crawler + ->filterXPath('//*[@id="content"]/table/tr/td[2]/div[2]/div[contains(@class, "mt12 mb12")]/div[contains(@class, "pagination")]'); + + if (!$pages->count()) { + return 1; + } + + $pages = $pages + ->filterXPath('//a[contains(@class, "link")]') + ->last(); + + if (empty($pages)) { + return 1; + } + + preg_match('~\?offset=(\d+)$~', $pages->attr('href'), $page); + + return ((int) $page[1]/100) + 1; + } + + /** + * @return bool + */ + public function getHasNextPage(): bool + { + $pages = $this->crawler + ->filterXPath('//*[@id="content"]/table/tr/td[2]/div[2]/div[contains(@class, "mt12 mb12")]/div[contains(@class, "pagination")]'); + + if (!$pages->count()) { + return false; + } + + $pages = $pages + ->filterXPath('//a[contains(@class, "link")]') + ->last(); + + if (strpos($pages->attr('class'), 'current')) { + return false; + } + + return true; + } } diff --git a/src/Parser/User/Profile/FavoritesParser.php b/src/Parser/User/Profile/FavoritesParser.php index 2a5257b6..f614069b 100644 --- a/src/Parser/User/Profile/FavoritesParser.php +++ b/src/Parser/User/Profile/FavoritesParser.php @@ -4,10 +4,12 @@ use Jikan\Helper\Constants; use Jikan\Helper\Parser; -use Jikan\Model\Common\AnimeMeta; use Jikan\Model\Common\CharacterMeta; -use Jikan\Model\Common\MangaMeta; +use Jikan\Model\User\FavoriteAnime; +use Jikan\Model\User\FavoriteCharacter; +use Jikan\Model\User\FavoriteManga; use Jikan\Model\Common\PersonMeta; +use Jikan\Model\Common\MalUrl; use Jikan\Model\User\Favorites; use Symfony\Component\DomCrawler\Crawler; @@ -52,11 +54,12 @@ public function getAnime(): array return $this->crawler->filterXPath('//div[@id=\'anime_favorites\']/div[@class=\'fav-slide-outer\']/ul/li') ->each( function (Crawler $crawler) { - return new AnimeMeta( + return new FavoriteAnime( $crawler->filterXPath('//a/span[contains(@class, \'title\')]')->text(), $crawler->filterXPath('//a')->attr('href'), Parser::parseImageQuality($crawler->filterXPath('//a/img') ->attr('data-src')), + $crawler->filterXPath('//a/span[contains(@class, \'users\')]')->text() ); } ); @@ -68,14 +71,16 @@ function (Crawler $crawler) { */ public function getManga(): array { + return $this->crawler->filterXPath('//div[@id=\'manga_favorites\']/div[@class=\'fav-slide-outer\']/ul/li') ->each( function (Crawler $crawler) { - return new MangaMeta( + return new FavoriteManga( $crawler->filterXPath('//a/span[contains(@class, \'title\')]')->text(), $crawler->filterXPath('//a')->attr('href'), Parser::parseImageQuality($crawler->filterXPath('//a/img') ->attr('data-src')), + $crawler->filterXPath('//a/span[contains(@class, \'users\')]')->text() ); } ); diff --git a/src/Parser/User/Profile/LastUpdatesParser.php b/src/Parser/User/Profile/LastUpdatesParser.php new file mode 100644 index 00000000..c188456a --- /dev/null +++ b/src/Parser/User/Profile/LastUpdatesParser.php @@ -0,0 +1,115 @@ +crawler = $crawler; + } + + /** + * @return LastUpdates + */ + public function getModel(): LastUpdates + { + return LastUpdates::fromParser($this); + } + + /** + * @return array + * + */ + public function getLastAnimeUpdates(): array + { + $arr = $this->parseBaseListUpdates('anime'); + $results = []; + /** + * @var $baseLastUpdate BaseLastUpdate + */ + foreach ($arr as $baseLastUpdate) { + $results[] = new LastAnimeUpdate($baseLastUpdate); + } + return $results; + } + + /** + * @return array + * + */ + public function getLastMangaUpdates(): array + { + $arr = $this->parseBaseListUpdates('manga'); + $results = []; + /** + * @var $baseLastUpdate BaseLastUpdate + */ + foreach ($arr as $baseLastUpdate) { + $results[] = new LastMangaUpdate($baseLastUpdate); + } + return $results; + } + + private function parseBaseListUpdates(string $updateType): array + { + return $this->crawler->filterXPath("//div[contains(@class, 'updates {$updateType}')]/div") + ->each(function (Crawler $crawler) { + $a = $crawler->filterXPath('//a')->first(); + $img = $a->filterXPath('//img'); + $title = $img->attr('alt'); + $url = $a->attr('href'); + $imageUrl = $img->attr('data-src'); + $date = Parser::parseDate($crawler->filterXPath('//div/div[1]/span')->text()); + $progressScoreDiv = $crawler->filterXPath('//div/div[2]'); + $text = $progressScoreDiv->text(); + $scoreUnparsed = trim(substr($text, strpos($text, 'Scored') + strlen('Scored'))); + $score = ctype_digit($scoreUnparsed) ? intval($scoreUnparsed) : 0; + $progressTypeValueUnparsed = explode('·', $text)[0]; + /** @var $total int|null */ + $total = null; + /** @var $progressed int|null */ + $progressed = null; + + $progressedTotalSeparatorIndex = strpos($progressTypeValueUnparsed, '/'); + if ($progressedTotalSeparatorIndex != false) { + $totalUnparsed = trim(substr($progressTypeValueUnparsed, $progressedTotalSeparatorIndex + 1)); + + preg_match('~(\d+)\/(\d+)~', $progressTypeValueUnparsed, $progress); + + $progressed = $progress[1] ?? null; + $total = $progress[2] ?? null; + + preg_match('~([a-zA-Z\s\-]+)~', $progressTypeValueUnparsed, $status); + $status = $status[1] ?? null; + + if ($status !== null) { + $status = JString::cleanse($status); + } + + return new BaseLastUpdate($url, $title, $imageUrl, $progressed, $total, $status, $score, $date); + } + $progressTypeValueUnparsed = str_replace(" -", "", $progressTypeValueUnparsed); + $status = trim($progressTypeValueUnparsed); + return new BaseLastUpdate($url, $title, $imageUrl, $progressed, $total, $status, $score, $date); + }); + } +} diff --git a/src/Parser/User/Profile/UserProfileParser.php b/src/Parser/User/Profile/UserProfileParser.php index e5885b06..21979095 100644 --- a/src/Parser/User/Profile/UserProfileParser.php +++ b/src/Parser/User/Profile/UserProfileParser.php @@ -42,7 +42,7 @@ public function getModel(): Model\User\Profile return Model\User\Profile::fromParser($this); } - public function getUserId() : ?int + public function getUserId(): ?int { $node = $this->crawler->filterXPath("//a[contains(@class, 'header-right')]"); if (!$node->count()) { @@ -52,7 +52,7 @@ public function getUserId() : ?int preg_match('#id=(.*)#', $node->attr('href'), $id); if (!empty($id)) { - return (int) $id[1]; + return (int)$id[1]; } return null; @@ -108,15 +108,9 @@ public function getJoinDate(): ?\DateTimeImmutable */ public function getLastOnline(): ?\DateTimeImmutable { - try { - return new \DateTimeImmutable( - $this->crawler->filterXPath('//span[contains(text(), \'Last Online\')]/following-sibling::span') - ->text(), - new \DateTimeZone('UTC') - ); - } catch (\Exception $e) { - return null; - } + return Parser::parseDateTimePST( + $this->crawler->filterXPath('//span[contains(text(), \'Last Online\')]/following-sibling::span') + ->text()); } /** @@ -221,4 +215,12 @@ public function getFavorites(): Model\User\Favorites return (new FavoritesParser($node))->getModel(); } + + /** + * @return Model\User\LastUpdates + */ + public function getUserLastUpdates(): Model\User\LastUpdates + { + return (new LastUpdatesParser($this->crawler))->getModel(); + } } diff --git a/src/Parser/User/Reviews/UserReviewsParser.php b/src/Parser/User/Reviews/UserReviewsParser.php new file mode 100644 index 00000000..5bae12f1 --- /dev/null +++ b/src/Parser/User/Reviews/UserReviewsParser.php @@ -0,0 +1,70 @@ +crawler = $crawler; + } + + public function getModel(): Model\User\Reviews\UserReviews + { + return Model\User\Reviews\UserReviews::fromParser($this); + } + + public function getReviews() : array + { + $node = $this->crawler->filterXPath('//*[@id="content"]/table/tr/td[2]/div[@class="borderDark"]'); + + if (!$node->count()) { + return []; + } + + return $node->each(function (Crawler $crawler) { + + // Anime Review + if ($crawler->filterXPath('//div[2]/div[2]/small[1]')->text() === '(Anime)') { + return Model\User\Reviews\UserAnimeReview::fromParser(new AnimeReviewParser($crawler)); + } + + // Manga Review + if ($crawler->filterXPath('//div[2]/div[2]/small[1]')->text() === '(Manga)') { + return Model\User\Reviews\UserMangaReview::fromParser(new MangaReviewParser($crawler)); + } + }); + } + + public function hasNextPage() : bool + { + // TODO: Add implementation + return true; + } + + public function getLastVisiblePage() : ?int + { + // TODO: Add implementation + return 1; + } +} diff --git a/src/Parser/User/UsernameByIdParser.php b/src/Parser/User/UsernameByIdParser.php new file mode 100644 index 00000000..f0ee0d7f --- /dev/null +++ b/src/Parser/User/UsernameByIdParser.php @@ -0,0 +1,45 @@ +crawler = $crawler; + } + + public function getUser() : Model\Common\UserMetaBasic + { + $node = $this->crawler->filterXPath("//*[@id=\"content\"]/div[1]/div[1]/a"); + + preg_match('~(.*?)\'s Profile~', $node->text(), $username); + + return Model\Common\UserMetaBasic::fromMeta( + $username[1], + Constants::BASE_URL . $node->attr('href') + ); + } +} diff --git a/src/Parser/Watch/EpisodeListItemParser.php b/src/Parser/Watch/EpisodeListItemParser.php new file mode 100644 index 00000000..140d0964 --- /dev/null +++ b/src/Parser/Watch/EpisodeListItemParser.php @@ -0,0 +1,138 @@ +crawler = $crawler; + } + + /** + * @return EpisodeListItem + * @throws \Exception + * @throws \RuntimeException + */ + public function getModel(): EpisodeListItem + { + return EpisodeListItem::fromParser($this); + } + + /** + * @return int + * @throws \InvalidArgumentException + */ + public function getId(): int + { + return Parser::idFromUrl($this->getUrl()); + } + + /** + * @return string + * @throws \InvalidArgumentException + */ + public function getUrl(): string + { + $node = $this->crawler->filterXPath('//div[@class="video-info-title"]/a[2]'); + return $node->attr('href'); + } + + /** + * @return string + * @throws \InvalidArgumentException + */ + public function getTitle(): string + { + $node = $this->crawler->filterXPath('//div[@class="video-info-title"]/a[2]'); + return $node->text(); + } + + /** + * @return string + * @throws \InvalidArgumentException + */ + public function getImageUrl(): string + { + return Parser::parseImageQuality( + $this->crawler->filterXPath('//div[contains(@class, "video-list")]/img')->attr('data-src') + ); + } + + /** + * @return string + * @throws \InvalidArgumentException + */ + public function getImages(): string + { + return Parser::parseImageQuality( + $this->crawler->filterXPath('//div[contains(@class, "video-list")]/img')->attr('data-src') + ); + } + + /** + * @return array + * @throws \InvalidArgumentException + */ + public function getEpisodes(): array + { + $episodes = []; + + $node = $this->crawler->filterXPath( + '//div[contains(@class, "video-list")] + /div[contains(@class, "info-container")]/div[contains(@class, "title")]/a' + ); + + $episodes = $node->each(function (Crawler $crawler) { + return RecentEpisodeListItem::factory( + Parser::suffixIdFromUrl( + $crawler->attr('href') + ), + $crawler->attr('href'), + $crawler->text(), + $crawler->filterXPath('//span[contains(@class, "icon-pay")]')->count() + ); + }); + + return $episodes; + } + + public function getRegionLocked() : bool + { + $node = $this->crawler->filterXPath('//div[contains(@class, "is_blocked")]'); + + return $node->count(); + } + + public function getAnimeMeta() : AnimeMeta + { + return new AnimeMeta( + $this->getTitle(), + $this->getUrl(), + $this->getImageUrl() + ); + } +} diff --git a/src/Request/Anime/AnimeCharactersAndStaffRequest.php b/src/Request/Anime/AnimeCharactersAndStaffRequest.php index a9530f5a..eba68de1 100644 --- a/src/Request/Anime/AnimeCharactersAndStaffRequest.php +++ b/src/Request/Anime/AnimeCharactersAndStaffRequest.php @@ -33,4 +33,12 @@ public function getPath(): string { return sprintf('https://myanimelist.net/anime/%s/_/characters', $this->id); } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } } diff --git a/src/Request/Anime/AnimeEpisodeRequest.php b/src/Request/Anime/AnimeEpisodeRequest.php index 964bef6b..bcb8955f 100644 --- a/src/Request/Anime/AnimeEpisodeRequest.php +++ b/src/Request/Anime/AnimeEpisodeRequest.php @@ -40,4 +40,20 @@ public function getPath(): string { return sprintf('https://myanimelist.net/anime/%s/_/episode/%s', $this->id, $this->episodeId); } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } + + /** + * @return int + */ + public function getEpisodeId(): int + { + return $this->episodeId; + } } diff --git a/src/Request/Anime/AnimeEpisodesRequest.php b/src/Request/Anime/AnimeEpisodesRequest.php index 8d2268e4..6b01bffd 100644 --- a/src/Request/Anime/AnimeEpisodesRequest.php +++ b/src/Request/Anime/AnimeEpisodesRequest.php @@ -40,4 +40,20 @@ public function getPath(): string { return sprintf('https://myanimelist.net/anime/%s/_/episode?offset=%s', $this->id, $this->page); } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } + + /** + * @return int + */ + public function getPage() + { + return $this->page; + } } diff --git a/src/Request/Anime/AnimeForumRequest.php b/src/Request/Anime/AnimeForumRequest.php index 0341588e..83ee686c 100644 --- a/src/Request/Anime/AnimeForumRequest.php +++ b/src/Request/Anime/AnimeForumRequest.php @@ -50,4 +50,28 @@ public function getPath(): string return sprintf('https://myanimelist.net/anime/%s/_/forum%s', $this->id, $query); } + + /** + * @return array + */ + public static function getValidTypes(): array + { + return self::$validTypes; + } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } + + /** + * @return string + */ + public function getTopic(): ?string + { + return $this->topic; + } } diff --git a/src/Request/Anime/AnimeMoreInfoRequest.php b/src/Request/Anime/AnimeMoreInfoRequest.php index b72868a6..8833c57d 100644 --- a/src/Request/Anime/AnimeMoreInfoRequest.php +++ b/src/Request/Anime/AnimeMoreInfoRequest.php @@ -33,4 +33,12 @@ public function getPath(): string { return sprintf('https://myanimelist.net/anime/%d/_/moreinfo', $this->id); } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } } diff --git a/src/Request/Anime/AnimeNewsRequest.php b/src/Request/Anime/AnimeNewsRequest.php index 54f33da0..bbc92dcf 100644 --- a/src/Request/Anime/AnimeNewsRequest.php +++ b/src/Request/Anime/AnimeNewsRequest.php @@ -33,4 +33,20 @@ public function getPath(): string { return sprintf('https://myanimelist.net/anime/%s/_/news', $this->id); } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } + + /** + * @return int + */ + public function getPage(): ?int + { + return $this->page; + } } diff --git a/src/Request/Anime/AnimePicturesRequest.php b/src/Request/Anime/AnimePicturesRequest.php index 91714552..32d69254 100644 --- a/src/Request/Anime/AnimePicturesRequest.php +++ b/src/Request/Anime/AnimePicturesRequest.php @@ -34,4 +34,12 @@ public function getPath(): string // MyAnimeList wants after //... it happily accepts jikan as a valid parameter though return sprintf('https://myanimelist.net/anime/%d/jikan/pics', $this->id); } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } } diff --git a/src/Request/Anime/AnimeRecentlyUpdatedByUsersRequest.php b/src/Request/Anime/AnimeRecentlyUpdatedByUsersRequest.php index d9e86933..3662f63e 100644 --- a/src/Request/Anime/AnimeRecentlyUpdatedByUsersRequest.php +++ b/src/Request/Anime/AnimeRecentlyUpdatedByUsersRequest.php @@ -40,4 +40,20 @@ public function getPath(): string { return sprintf('https://myanimelist.net/anime/%d/jikan/stats?show=%d', $this->id, $this->page); } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } + + /** + * @return int + */ + public function getPage() + { + return $this->page; + } } diff --git a/src/Request/Anime/AnimeRecommendationsRequest.php b/src/Request/Anime/AnimeRecommendationsRequest.php index 4d04388a..205868f5 100644 --- a/src/Request/Anime/AnimeRecommendationsRequest.php +++ b/src/Request/Anime/AnimeRecommendationsRequest.php @@ -33,4 +33,12 @@ public function getPath(): string { return sprintf('https://myanimelist.net/anime/%d/jikan/userrecs', $this->id); } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } } diff --git a/src/Request/Anime/AnimeRequest.php b/src/Request/Anime/AnimeRequest.php index 0a7c5e41..c9a16f7d 100644 --- a/src/Request/Anime/AnimeRequest.php +++ b/src/Request/Anime/AnimeRequest.php @@ -33,4 +33,12 @@ public function getPath(): string { return sprintf('https://myanimelist.net/anime/%s/', $this->id); } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } } diff --git a/src/Request/Anime/AnimeReviewsRequest.php b/src/Request/Anime/AnimeReviewsRequest.php index 179be1e6..3035b80f 100644 --- a/src/Request/Anime/AnimeReviewsRequest.php +++ b/src/Request/Anime/AnimeReviewsRequest.php @@ -40,4 +40,20 @@ public function getPath(): string { return sprintf('https://myanimelist.net/anime/%d/jikan/reviews?p=%d', $this->id, $this->page); } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } + + /** + * @return int + */ + public function getPage(): int + { + return $this->page; + } } diff --git a/src/Request/Anime/AnimeStatsRequest.php b/src/Request/Anime/AnimeStatsRequest.php index b2f23134..a7ce985c 100644 --- a/src/Request/Anime/AnimeStatsRequest.php +++ b/src/Request/Anime/AnimeStatsRequest.php @@ -34,4 +34,12 @@ public function getPath(): string // MyAnimeList wants after //... it happily accepts jikan as a valid parameter though return sprintf('https://myanimelist.net/anime/%d/jikan/stats', $this->id); } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } } diff --git a/src/Request/Anime/AnimeVideosRequest.php b/src/Request/Anime/AnimeVideosRequest.php index 23787541..1e6cb755 100644 --- a/src/Request/Anime/AnimeVideosRequest.php +++ b/src/Request/Anime/AnimeVideosRequest.php @@ -33,4 +33,12 @@ public function getPath(): string { return sprintf('https://myanimelist.net/anime/%d/_/video', $this->id); } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } } diff --git a/src/Request/Character/CharacterPicturesRequest.php b/src/Request/Character/CharacterPicturesRequest.php index c0098c7c..0028feeb 100644 --- a/src/Request/Character/CharacterPicturesRequest.php +++ b/src/Request/Character/CharacterPicturesRequest.php @@ -34,4 +34,12 @@ public function getPath(): string // MyAnimeList wants after //... it happily accepts jikan as a valid parameter though return sprintf('https://myanimelist.net/character/%d/jikan/pics', $this->id); } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } } diff --git a/src/Request/Character/CharacterRequest.php b/src/Request/Character/CharacterRequest.php index bc853fd6..dba765de 100644 --- a/src/Request/Character/CharacterRequest.php +++ b/src/Request/Character/CharacterRequest.php @@ -35,4 +35,12 @@ public function getPath(): string { return sprintf('https://myanimelist.net/character/%s', $this->id); } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } } diff --git a/src/Request/Club/ClubRequest.php b/src/Request/Club/ClubRequest.php index 5f96034d..20451b5b 100644 --- a/src/Request/Club/ClubRequest.php +++ b/src/Request/Club/ClubRequest.php @@ -39,4 +39,12 @@ public function getPath(): string $this->clubId ); } + + /** + * @return int + */ + public function getClubId(): int + { + return $this->clubId; + } } diff --git a/src/Request/Club/UserListRequest.php b/src/Request/Club/UserListRequest.php index 7ab83f16..4fec66c0 100644 --- a/src/Request/Club/UserListRequest.php +++ b/src/Request/Club/UserListRequest.php @@ -47,4 +47,20 @@ public function getPath(): string $this->page ); } + + /** + * @return int + */ + public function getClubId(): int + { + return $this->clubId; + } + + /** + * @return int + */ + public function getPage() + { + return $this->page; + } } diff --git a/src/Request/Genre/AnimeGenreRequest.php b/src/Request/Genre/AnimeGenreRequest.php index b8b831a1..051aca56 100644 --- a/src/Request/Genre/AnimeGenreRequest.php +++ b/src/Request/Genre/AnimeGenreRequest.php @@ -40,4 +40,20 @@ public function getPath(): string { return sprintf('https://myanimelist.net/anime/genre/%s?page=%s', $this->id, $this->page); } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } + + /** + * @return int + */ + public function getPage(): int + { + return $this->page; + } } diff --git a/src/Request/Genre/AnimeGenresRequest.php b/src/Request/Genre/AnimeGenresRequest.php index 60bb4208..13ce7a5f 100644 --- a/src/Request/Genre/AnimeGenresRequest.php +++ b/src/Request/Genre/AnimeGenresRequest.php @@ -11,14 +11,6 @@ */ class AnimeGenresRequest implements RequestInterface { - /** - * AnimeGenreRequest constructor. - - */ - public function __construct() - { - } - /** * @return string */ diff --git a/src/Request/Genre/MangaGenreRequest.php b/src/Request/Genre/MangaGenreRequest.php index a4778cf8..15d29ac4 100644 --- a/src/Request/Genre/MangaGenreRequest.php +++ b/src/Request/Genre/MangaGenreRequest.php @@ -40,4 +40,20 @@ public function getPath(): string { return sprintf('https://myanimelist.net/manga/genre/%s?page=%s', $this->id, $this->page); } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } + + /** + * @return int + */ + public function getPage(): int + { + return $this->page; + } } diff --git a/src/Request/Genre/MangaGenresRequest.php b/src/Request/Genre/MangaGenresRequest.php index 9e07fd2c..5ae56b70 100644 --- a/src/Request/Genre/MangaGenresRequest.php +++ b/src/Request/Genre/MangaGenresRequest.php @@ -11,14 +11,6 @@ */ class MangaGenresRequest implements RequestInterface { - /** - * MangaGenreRequest constructor. - - */ - public function __construct() - { - } - /** * @return string */ diff --git a/src/Request/Magazine/MagazineRequest.php b/src/Request/Magazine/MagazineRequest.php index 3493e744..992b2900 100644 --- a/src/Request/Magazine/MagazineRequest.php +++ b/src/Request/Magazine/MagazineRequest.php @@ -40,4 +40,20 @@ public function getPath(): string { return sprintf('https://myanimelist.net/manga/magazine/%s?page=%s', $this->id, $this->page); } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } + + /** + * @return int + */ + public function getPage(): int + { + return $this->page; + } } diff --git a/src/Request/Magazine/MagazinesRequest.php b/src/Request/Magazine/MagazinesRequest.php index 0bd07fd2..78a98b12 100644 --- a/src/Request/Magazine/MagazinesRequest.php +++ b/src/Request/Magazine/MagazinesRequest.php @@ -11,13 +11,6 @@ */ class MagazinesRequest extends \Jikan\Request\Magazine\MagazineRequest implements RequestInterface { - /** - * ProducersRequest constructor. - */ - public function __construct() - { - } - /** * @return string */ diff --git a/src/Request/Manga/MangaCharactersRequest.php b/src/Request/Manga/MangaCharactersRequest.php index cbe80b62..e38d6112 100644 --- a/src/Request/Manga/MangaCharactersRequest.php +++ b/src/Request/Manga/MangaCharactersRequest.php @@ -33,4 +33,12 @@ public function getPath(): string { return sprintf('https://myanimelist.net/manga/%s/_/characters', $this->id); } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } } diff --git a/src/Request/Manga/MangaForumRequest.php b/src/Request/Manga/MangaForumRequest.php index 5c2eeb38..81e50879 100644 --- a/src/Request/Manga/MangaForumRequest.php +++ b/src/Request/Manga/MangaForumRequest.php @@ -50,4 +50,28 @@ public function getPath(): string return sprintf('https://myanimelist.net/manga/%s/_/forum%s', $this->id, $query); } + + /** + * @return array + */ + public static function getValidTypes(): array + { + return self::$validTypes; + } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } + + /** + * @return string + */ + public function getTopic(): ?string + { + return $this->topic; + } } diff --git a/src/Request/Manga/MangaMoreInfoRequest.php b/src/Request/Manga/MangaMoreInfoRequest.php index bdd00f64..60555528 100644 --- a/src/Request/Manga/MangaMoreInfoRequest.php +++ b/src/Request/Manga/MangaMoreInfoRequest.php @@ -33,4 +33,12 @@ public function getPath(): string { return sprintf('https://myanimelist.net/manga/%d/_/moreinfo', $this->id); } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } } diff --git a/src/Request/Manga/MangaNewsRequest.php b/src/Request/Manga/MangaNewsRequest.php index 56948aaf..9f130f1e 100644 --- a/src/Request/Manga/MangaNewsRequest.php +++ b/src/Request/Manga/MangaNewsRequest.php @@ -33,4 +33,20 @@ public function getPath(): string { return sprintf('https://myanimelist.net/manga/%s/_/news', $this->id); } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } + + /** + * @return int + */ + public function getPage(): ?int + { + return $this->page; + } } diff --git a/src/Request/Manga/MangaPicturesRequest.php b/src/Request/Manga/MangaPicturesRequest.php index 3c5f954a..5323da27 100644 --- a/src/Request/Manga/MangaPicturesRequest.php +++ b/src/Request/Manga/MangaPicturesRequest.php @@ -34,4 +34,12 @@ public function getPath(): string // MyAnimeList wants after //... it happily accepts jikan as a valid parameter though return sprintf('https://myanimelist.net/manga/%d/jikan/pics', $this->id); } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } } diff --git a/src/Request/Manga/MangaRecentlyUpdatedByUsersRequest.php b/src/Request/Manga/MangaRecentlyUpdatedByUsersRequest.php index c4ccfbc7..f181fee1 100644 --- a/src/Request/Manga/MangaRecentlyUpdatedByUsersRequest.php +++ b/src/Request/Manga/MangaRecentlyUpdatedByUsersRequest.php @@ -40,4 +40,20 @@ public function getPath(): string { return sprintf('https://myanimelist.net/manga/%d/jikan/stats?show=%d', $this->id, $this->page); } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } + + /** + * @return int + */ + public function getPage() + { + return $this->page; + } } diff --git a/src/Request/Manga/MangaRecommendationsRequest.php b/src/Request/Manga/MangaRecommendationsRequest.php index c6e7c845..d1139dbd 100644 --- a/src/Request/Manga/MangaRecommendationsRequest.php +++ b/src/Request/Manga/MangaRecommendationsRequest.php @@ -33,4 +33,12 @@ public function getPath(): string { return sprintf('https://myanimelist.net/manga/%d/jikan/userrecs', $this->id); } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } } diff --git a/src/Request/Manga/MangaRequest.php b/src/Request/Manga/MangaRequest.php index 13976436..e5bac3de 100644 --- a/src/Request/Manga/MangaRequest.php +++ b/src/Request/Manga/MangaRequest.php @@ -34,4 +34,12 @@ public function getPath(): string { return sprintf('https://myanimelist.net/manga/%s/', $this->id); } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } } diff --git a/src/Request/Manga/MangaReviewsRequest.php b/src/Request/Manga/MangaReviewsRequest.php index ff2b3fd9..16a5bdf3 100644 --- a/src/Request/Manga/MangaReviewsRequest.php +++ b/src/Request/Manga/MangaReviewsRequest.php @@ -40,4 +40,20 @@ public function getPath(): string { return sprintf('https://myanimelist.net/manga/%d/jikan/reviews?p=%d', $this->id, $this->page); } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } + + /** + * @return int + */ + public function getPage(): int + { + return $this->page; + } } diff --git a/src/Request/Manga/MangaStatsRequest.php b/src/Request/Manga/MangaStatsRequest.php index df2bc43b..7e63fabb 100644 --- a/src/Request/Manga/MangaStatsRequest.php +++ b/src/Request/Manga/MangaStatsRequest.php @@ -34,4 +34,12 @@ public function getPath(): string // MyAnimeList wants after //... it happily accepts jikan as a valid parameter though return sprintf('https://myanimelist.net/manga/%d/jikan/stats', $this->id); } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } } diff --git a/src/Request/Person/PersonPicturesRequest.php b/src/Request/Person/PersonPicturesRequest.php index 0850ec22..bcdb923f 100644 --- a/src/Request/Person/PersonPicturesRequest.php +++ b/src/Request/Person/PersonPicturesRequest.php @@ -34,4 +34,12 @@ public function getPath(): string // MyAnimeList wants after //... it happily accepts jikan as a valid parameter though return sprintf('https://myanimelist.net/people/%d/jikan/pics', $this->id); } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } } diff --git a/src/Request/Person/PersonRequest.php b/src/Request/Person/PersonRequest.php index e7921307..9d7f0a06 100644 --- a/src/Request/Person/PersonRequest.php +++ b/src/Request/Person/PersonRequest.php @@ -35,4 +35,12 @@ public function getPath(): string { return sprintf('https://myanimelist.net/people/%s', $this->id); } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } } diff --git a/src/Request/Producer/ProducerRequest.php b/src/Request/Producer/ProducerRequest.php index c767406b..a10b5fd2 100644 --- a/src/Request/Producer/ProducerRequest.php +++ b/src/Request/Producer/ProducerRequest.php @@ -40,4 +40,20 @@ public function getPath(): string { return sprintf('https://myanimelist.net/anime/producer/%s?page=%s', $this->id, $this->page); } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } + + /** + * @return int + */ + public function getPage(): int + { + return $this->page; + } } diff --git a/src/Request/Producer/ProducersRequest.php b/src/Request/Producer/ProducersRequest.php index 18342bdc..0d4a2a8c 100644 --- a/src/Request/Producer/ProducersRequest.php +++ b/src/Request/Producer/ProducersRequest.php @@ -11,13 +11,6 @@ */ class ProducersRequest implements RequestInterface { - /** - * ProducersRequest constructor. - */ - public function __construct() - { - } - /** * @return string */ diff --git a/src/Request/Recommendations/RecentRecommendationsRequest.php b/src/Request/Recommendations/RecentRecommendationsRequest.php new file mode 100644 index 00000000..cf7287ec --- /dev/null +++ b/src/Request/Recommendations/RecentRecommendationsRequest.php @@ -0,0 +1,85 @@ +page = $page; + + if (null !== $type) { + if (!\in_array( + $type, + [ + Constants::RECENT_RECOMMENDATION_ANIME, + Constants::RECENT_RECOMMENDATION_MANGA + ], + true + ) + ) { + throw new \InvalidArgumentException(sprintf('Recommendation type %s is not valid', $type)); + } + + $this->type = $type; + } + } + + /** + * Get the path to request + * + * @return string + */ + public function getPath(): string + { + return 'https://myanimelist.net/recommendations.php?'.http_build_query( + [ + 's' => 'recentrecs', + 't' => $this->type, + 'show' => ($this->page !== 1) ? 100 * ($this->page - 1) : null + ] + ); + } + + /** + * @return int + */ + public function getPage(): int + { + return $this->page; + } + + /** + * @return string + */ + public function getType() + { + return $this->type; + } +} diff --git a/src/Request/Search/AnimeSearchRequest.php b/src/Request/Search/AnimeSearchRequest.php index bd17d490..b3ad5f83 100644 --- a/src/Request/Search/AnimeSearchRequest.php +++ b/src/Request/Search/AnimeSearchRequest.php @@ -330,4 +330,117 @@ public function setSort(int $sort): AnimeSearchRequest $this->sort = $sort; return $this; } + + /** + * @return string|null + */ + public function getQuery(): ?string + { + return $this->query; + } + + /** + * @return int + */ + public function getPage(): int + { + return $this->page; + } + + /** + * @return string + */ + public function getChar(): string + { + return $this->char; + } + + /** + * @return string + */ + public function getType() + { + return $this->type; + } + + /** + * @return float + */ + public function getScore() + { + return $this->score; + } + + /** + * @return int + */ + public function getStatus(): int + { + return $this->status; + } + + /** + * @return int + */ + public function getProducer(): int + { + return $this->producer; + } + + /** + * @return int + */ + public function getRated(): int + { + return $this->rated; + } + + /** + * @return int[] + */ + public function getStartDate(): array + { + return $this->startDate; + } + + /** + * @return int[] + */ + public function getEndDate(): array + { + return $this->endDate; + } + + /** + * @return int[] + */ + public function getGenre(): array + { + return $this->genre; + } + + /** + * @return bool + */ + public function isGenreExclude(): bool + { + return $this->genreExclude; + } + + /** + * @return int + */ + public function getOrderBy(): int + { + return $this->orderBy; + } + + /** + * @return int + */ + public function getSort(): int + { + return $this->sort; + } + } diff --git a/src/Request/Search/CharacterSearchRequest.php b/src/Request/Search/CharacterSearchRequest.php index 6c1e277b..86706586 100644 --- a/src/Request/Search/CharacterSearchRequest.php +++ b/src/Request/Search/CharacterSearchRequest.php @@ -109,4 +109,29 @@ public function setStartsWithChar(string $char): self return $this; } + + /** + * @return string + */ + public function getQuery(): string + { + return $this->query; + } + + /** + * @return int + */ + public function getPage(): int + { + return $this->page; + } + + /** + * @return string + */ + public function getChar(): string + { + return $this->char; + } + } diff --git a/src/Request/Search/MangaSearchRequest.php b/src/Request/Search/MangaSearchRequest.php index 7afd764a..9640101c 100644 --- a/src/Request/Search/MangaSearchRequest.php +++ b/src/Request/Search/MangaSearchRequest.php @@ -312,4 +312,109 @@ public function setSort(int $sort): MangaSearchRequest $this->sort = $sort; return $this; } + + /** + * @return string + */ + public function getQuery(): string + { + return $this->query; + } + + /** + * @return int + */ + public function getPage(): int + { + return $this->page; + } + + /** + * @return string + */ + public function getChar(): string + { + return $this->char; + } + + /** + * @return string + */ + public function getType() + { + return $this->type; + } + + /** + * @return float + */ + public function getScore() + { + return $this->score; + } + + /** + * @return int + */ + public function getStatus(): int + { + return $this->status; + } + + /** + * @return int + */ + public function getMagazine(): int + { + return $this->magazine; + } + + /** + * @return int[] + */ + public function getStartDate(): array + { + return $this->startDate; + } + + /** + * @return int[] + */ + public function getEndDate(): array + { + return $this->endDate; + } + + /** + * @return int[] + */ + public function getGenre(): array + { + return $this->genre; + } + + /** + * @return bool + */ + public function isGenreExclude(): bool + { + return $this->genreExclude; + } + + /** + * @return int + */ + public function getOrderBy(): int + { + return $this->orderBy; + } + + /** + * @return int + */ + public function getSort(): int + { + return $this->sort; + } + } diff --git a/src/Request/Search/PersonSearchRequest.php b/src/Request/Search/PersonSearchRequest.php index ab6fa599..f0525780 100644 --- a/src/Request/Search/PersonSearchRequest.php +++ b/src/Request/Search/PersonSearchRequest.php @@ -109,4 +109,28 @@ public function setStartsWithChar(string $char): self return $this; } + + /** + * @return string + */ + public function getQuery(): string + { + return $this->query; + } + + /** + * @return int + */ + public function getPage(): int + { + return $this->page; + } + + /** + * @return string + */ + public function getChar(): string + { + return $this->char; + } } diff --git a/src/Request/Search/UserSearchRequest.php b/src/Request/Search/UserSearchRequest.php new file mode 100644 index 00000000..680053fb --- /dev/null +++ b/src/Request/Search/UserSearchRequest.php @@ -0,0 +1,197 @@ +query = $query; + $this->page = $page; + + $this->query = $this->query ?? ''; + + $querySize = strlen($this->query); + + if ($querySize > 0 && $querySize < 3) { + throw new BadResponseException('Search with queries require at least 3 characters'); + } + } + + /** + * Get the path to request + * + * @return string + */ + public function getPath(): string + { + $query = http_build_query( + [ + 'q' => $this->query, + 'show' => ($this->page !== 1) ? 24 * ($this->page - 1) : null, + 'loc' => $this->location, + 'agelow' => $this->minAge, + 'agehigh' => $this->maxAge, + 'g' => $this->gender, + ] + ); + + return sprintf( + 'https://myanimelist.net/users.php?%s', + $query + ); + } + + /** + * @param string|null $query + * @return UserSearchRequest + */ + public function setQuery(?string $query): UserSearchRequest + { + $this->query = $query; + return $this; + } + + /** + * @param int $page + * @return UserSearchRequest + */ + public function setPage(?int $page): UserSearchRequest + { + $this->page = $page; + return $this; + } + + /** + * @param string|null $location + * @return UserSearchRequest + */ + public function setLocation(?string $location): UserSearchRequest + { + $this->location = $location; + return $this; + } + + /** + * @param int|null $minAge + * @return UserSearchRequest + */ + public function setMinAge(?int $minAge): UserSearchRequest + { + $this->minAge = $minAge; + return $this; + } + + /** + * @param int|null $maxAge + * @return UserSearchRequest + */ + public function setMaxAge(?int $maxAge): UserSearchRequest + { + $this->maxAge = $maxAge; + return $this; + } + + /** + * @param int|null $gender + * @return UserSearchRequest + */ + public function setGender(?int $gender): UserSearchRequest + { + $this->gender = $gender; + return $this; + } + + /** + * @return string|null + */ + public function getQuery(): ?string + { + return $this->query; + } + + /** + * @return int + */ + public function getPage(): int + { + return $this->page; + } + + /** + * @return string + */ + public function getLocation(): string + { + return $this->location; + } + + /** + * @return int + */ + public function getMinAge(): int + { + return $this->minAge; + } + + /** + * @return int + */ + public function getMaxAge(): int + { + return $this->maxAge; + } + + /** + * @return int + */ + public function getGender(): int + { + return $this->gender; + } +} diff --git a/src/Request/Seasonal/SeasonalRequest.php b/src/Request/Seasonal/SeasonalRequest.php index 6b94b815..f804900b 100644 --- a/src/Request/Seasonal/SeasonalRequest.php +++ b/src/Request/Seasonal/SeasonalRequest.php @@ -59,4 +59,28 @@ public function getPath(): string return sprintf('https://myanimelist.net/anime/season/%s/%s', $this->year, $this->season); } + + /** + * @return int|null + */ + public function getYear(): ?int + { + return $this->year; + } + + /** + * @return string|null + */ + public function getSeason() + { + return $this->season; + } + + /** + * @return bool + */ + public function isLater(): bool + { + return $this->later; + } } diff --git a/src/Request/Top/TopAnimeRequest.php b/src/Request/Top/TopAnimeRequest.php index a577192c..d96459d8 100644 --- a/src/Request/Top/TopAnimeRequest.php +++ b/src/Request/Top/TopAnimeRequest.php @@ -72,4 +72,20 @@ public function getPath(): string ] ); } + + /** + * @return int + */ + public function getPage(): int + { + return $this->page; + } + + /** + * @return string|null + */ + public function getType() + { + return $this->type; + } } diff --git a/src/Request/Top/TopCharactersRequest.php b/src/Request/Top/TopCharactersRequest.php index 29a9386c..8d8c43ad 100644 --- a/src/Request/Top/TopCharactersRequest.php +++ b/src/Request/Top/TopCharactersRequest.php @@ -35,4 +35,12 @@ public function getPath(): string { return 'https://myanimelist.net/character.php?'.http_build_query(['limit' => 50 * ($this->page-1)]); } + + /** + * @return int + */ + public function getPage(): int + { + return $this->page; + } } diff --git a/src/Request/Top/TopMangaRequest.php b/src/Request/Top/TopMangaRequest.php index b10e5a93..af870780 100644 --- a/src/Request/Top/TopMangaRequest.php +++ b/src/Request/Top/TopMangaRequest.php @@ -72,4 +72,20 @@ public function getPath(): string ] ); } + + /** + * @return int + */ + public function getPage(): int + { + return $this->page; + } + + /** + * @return string|null + */ + public function getType() + { + return $this->type; + } } diff --git a/src/Request/Top/TopPeopleRequest.php b/src/Request/Top/TopPeopleRequest.php index c48608f8..245cd0b8 100644 --- a/src/Request/Top/TopPeopleRequest.php +++ b/src/Request/Top/TopPeopleRequest.php @@ -35,4 +35,12 @@ public function getPath(): string { return 'https://myanimelist.net/people.php?'.http_build_query(['limit' => 50 * ($this->page-1)]); } + + /** + * @return int + */ + public function getPage(): int + { + return $this->page; + } } diff --git a/src/Request/Top/TopReviewsRequest.php b/src/Request/Top/TopReviewsRequest.php index 99aae2bd..0d232579 100644 --- a/src/Request/Top/TopReviewsRequest.php +++ b/src/Request/Top/TopReviewsRequest.php @@ -75,4 +75,20 @@ public function getPath(): string ] ); } + + /** + * @return int + */ + public function getPage(): int + { + return $this->page; + } + + /** + * @return string + */ + public function getType() + { + return $this->type; + } } diff --git a/src/Request/User/UserAnimeListRequest.php b/src/Request/User/UserAnimeListRequest.php index 4a134d2b..a75746c3 100644 --- a/src/Request/User/UserAnimeListRequest.php +++ b/src/Request/User/UserAnimeListRequest.php @@ -242,4 +242,100 @@ public function setProducer(int $producer): UserAnimeListRequest $this->producer = $producer; return $this; } + + /** + * @return string + */ + public function getUsername(): string + { + return $this->username; + } + + /** + * @return int + */ + public function getPage() + { + return $this->page; + } + + /** + * @return int + */ + public function getStatus(): int + { + return $this->status; + } + + /** + * @return int + */ + public function getOrderBy(): int + { + return $this->orderBy; + } + + /** + * @return int + */ + public function getOrderBy2(): int + { + return $this->orderBy2; + } + + /** + * @return string + */ + public function getTitle(): string + { + return $this->title; + } + + /** + * @return string + */ + public function getSeason(): string + { + return $this->season; + } + + /** + * @return int + */ + public function getSeasonYear(): int + { + return $this->seasonYear; + } + + /** + * @return array + */ + public function getAiredFrom(): array + { + return $this->airedFrom; + } + + /** + * @return array + */ + public function getAiredTo(): array + { + return $this->airedTo; + } + + /** + * @return int + */ + public function getAiringStatus(): int + { + return $this->airingStatus; + } + + /** + * @return int + */ + public function getProducer(): int + { + return $this->producer; + } } diff --git a/src/Request/User/UserClubsRequest.php b/src/Request/User/UserClubsRequest.php new file mode 100644 index 00000000..ff125ac1 --- /dev/null +++ b/src/Request/User/UserClubsRequest.php @@ -0,0 +1,44 @@ +username = $username; + } + + /** + * @return string + */ + public function getPath(): string + { + return sprintf('https://myanimelist.net/profile/%s/clubs', $this->username); + } + + /** + * @return string + */ + public function getUsername(): string + { + return $this->username; + } +} diff --git a/src/Request/User/UserFriendsRequest.php b/src/Request/User/UserFriendsRequest.php index cb79cd8e..79872dc3 100644 --- a/src/Request/User/UserFriendsRequest.php +++ b/src/Request/User/UserFriendsRequest.php @@ -45,4 +45,20 @@ public function getPath(): string return sprintf('https://myanimelist.net/profile/%s/friends%s', $this->username, $query); } + + /** + * @return string + */ + public function getUsername(): string + { + return $this->username; + } + + /** + * @return int + */ + public function getPage(): int + { + return $this->page; + } } diff --git a/src/Request/User/UserHistoryRequest.php b/src/Request/User/UserHistoryRequest.php index a83d4e75..1bb63b34 100644 --- a/src/Request/User/UserHistoryRequest.php +++ b/src/Request/User/UserHistoryRequest.php @@ -51,4 +51,20 @@ public function getPath(): string { return sprintf('https://myanimelist.net/history/%s/%s', $this->username, $this->type); } + + /** + * @return string + */ + public function getUsername(): string + { + return $this->username; + } + + /** + * @return string|null + */ + public function getType(): ?string + { + return $this->type; + } } diff --git a/src/Request/User/UserMangaListRequest.php b/src/Request/User/UserMangaListRequest.php index e97291b7..48e3b6d8 100644 --- a/src/Request/User/UserMangaListRequest.php +++ b/src/Request/User/UserMangaListRequest.php @@ -207,4 +207,84 @@ public function setMagazine(int $magazine): UserMangaListRequest $this->magazine = $magazine; return $this; } + + /** + * @return string + */ + public function getUsername(): string + { + return $this->username; + } + + /** + * @return int + */ + public function getPage() + { + return $this->page; + } + + /** + * @return int + */ + public function getStatus(): int + { + return $this->status; + } + + /** + * @return int + */ + public function getOrderBy(): int + { + return $this->orderBy; + } + + /** + * @return int + */ + public function getOrderBy2(): int + { + return $this->orderBy2; + } + + /** + * @return string + */ + public function getTitle(): string + { + return $this->title; + } + + /** + * @return array + */ + public function getPublishedFrom(): array + { + return $this->publishedFrom; + } + + /** + * @return array + */ + public function getPublishedTo(): array + { + return $this->publishedTo; + } + + /** + * @return int + */ + public function getPublishingStatus(): int + { + return $this->publishingStatus; + } + + /** + * @return int + */ + public function getMagazine(): int + { + return $this->magazine; + } } diff --git a/src/Request/User/UserProfileRequest.php b/src/Request/User/UserProfileRequest.php index 8b2a85be..29b45560 100644 --- a/src/Request/User/UserProfileRequest.php +++ b/src/Request/User/UserProfileRequest.php @@ -34,4 +34,12 @@ public function getPath(): string { return sprintf('https://myanimelist.net/profile/%s/', $this->username); } + + /** + * @return string + */ + public function getUsername(): string + { + return $this->username; + } } diff --git a/src/Request/User/UserRecommendationsRequest.php b/src/Request/User/UserRecommendationsRequest.php new file mode 100644 index 00000000..37e0f4fc --- /dev/null +++ b/src/Request/User/UserRecommendationsRequest.php @@ -0,0 +1,59 @@ +username = $username; + $this->page = $page; + } + + /** + * @return string + */ + public function getPath(): string + { + return sprintf('https://myanimelist.net/profile/%s/recommendations?p=%d', $this->username, $this->page); + } + + /** + * @return string + */ + public function getUsername(): string + { + return $this->username; + } + + /** + * @return int + */ + public function getPage(): ?int + { + return $this->page; + } +} diff --git a/src/Request/User/UserReviewsRequest.php b/src/Request/User/UserReviewsRequest.php new file mode 100644 index 00000000..a4cf4ce2 --- /dev/null +++ b/src/Request/User/UserReviewsRequest.php @@ -0,0 +1,59 @@ +username = $username; + $this->page = $page; + } + + /** + * @return string + */ + public function getPath(): string + { + return sprintf('https://myanimelist.net/profile/%s/reviews?p=%d', $this->username, $this->page); + } + + /** + * @return string + */ + public function getUsername(): string + { + return $this->username; + } + + /** + * @return int + */ + public function getPage(): ?int + { + return $this->page; + } +} diff --git a/src/Request/User/UsernameByIdRequest.php b/src/Request/User/UsernameByIdRequest.php new file mode 100644 index 00000000..30992be5 --- /dev/null +++ b/src/Request/User/UsernameByIdRequest.php @@ -0,0 +1,45 @@ +id = $id; + } + + /** + * @return string + */ + public function getPath(): string + { + return sprintf('https://myanimelist.net/comments.php?id=%d', $this->id); + } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } +} diff --git a/src/Request/Watch/RecentPromotionalVideosRequest.php b/src/Request/Watch/RecentPromotionalVideosRequest.php new file mode 100644 index 00000000..3df0935b --- /dev/null +++ b/src/Request/Watch/RecentPromotionalVideosRequest.php @@ -0,0 +1,45 @@ +page = $page; + } + + /** + * @return string + */ + public function getPath(): string + { + return sprintf('https://myanimelist.net/watch/promotion?p=%d', $this->page); + } + + /** + * @return int + */ + public function getPage(): int + { + return $this->page; + } +} diff --git a/test/JikanTest/JikanTest.php b/test/JikanTest/JikanTest.php index bb89d13a..e6be9e41 100644 --- a/test/JikanTest/JikanTest.php +++ b/test/JikanTest/JikanTest.php @@ -31,7 +31,7 @@ class JikanTest extends TestCase public function setUp(): void { - $this->jikan = new MalClient; + $this->jikan = new MalClient(); } /** @@ -62,9 +62,9 @@ public function it_gets_characters() { $character = $this->jikan->getCharacter(new \Jikan\Request\Character\CharacterRequest(116281)); self::assertInstanceOf(\Jikan\Model\Character\Character::class, $character); - self::assertCount(9, $character->getAnimeography()); + self::assertCount(11, $character->getAnimeography()); self::assertCount(2, $character->getMangaography()); - self::assertCount(4, $character->getVoiceActors()); + self::assertCount(5, $character->getVoiceActors()); } /** @@ -224,7 +224,7 @@ public function it_gets_character_pictures() */ public function it_gets_manga_news() { - $items = $this->jikan->getNewsList(new MangaNewsRequest(2)); + $items = $this->jikan->getNewsList(new MangaNewsRequest(2))->getResults(); self::assertCount(14, $items); self::assertContainsOnlyInstancesOf(NewsListItem::class, $items); } @@ -235,7 +235,7 @@ public function it_gets_manga_news() */ public function it_gets_anime_news() { - $items = $this->jikan->getNewsList(new AnimeNewsRequest(21)); + $items = $this->jikan->getNewsList(new AnimeNewsRequest(21))->getResults(); self::assertCount(30, $items); self::assertContainsOnlyInstancesOf(NewsListItem::class, $items); } @@ -249,7 +249,7 @@ public function it_gets_anime_search() $search = $this->jikan->getAnimeSearch(new \Jikan\Request\Search\AnimeSearchRequest('Fate')); self::assertCount(50, $search->getResults()); self::assertContainsOnlyInstancesOf(\Jikan\Model\Search\AnimeSearchListItem::class, $search->getResults()); - self::assertEquals(17, $search->getLastPage()); + self::assertEquals(17, $search->getLastVisiblePage()); } /** @@ -261,7 +261,7 @@ public function it_gets_manga_search() $search = $this->jikan->getMangaSearch(new \Jikan\Request\Search\MangaSearchRequest('Fate')); self::assertCount(50, $search->getResults()); self::assertContainsOnlyInstancesOf(\Jikan\Model\Search\MangaSearchListItem::class, $search->getResults()); - self::assertEquals(20, $search->getLastPage()); + self::assertEquals(20, $search->getLastVisiblePage()); } /** @@ -273,7 +273,7 @@ public function it_gets_character_search() $search = $this->jikan->getCharacterSearch(new \Jikan\Request\Search\CharacterSearchRequest('Fate')); self::assertCount(50, $search->getResults()); self::assertContainsOnlyInstancesOf(\Jikan\Model\Search\CharacterSearchListItem::class, $search->getResults()); - self::assertEquals(11, $search->getLastPage()); + self::assertEquals(11, $search->getLastVisiblePage()); } /** @@ -285,7 +285,7 @@ public function it_gets_person_search() $search = $this->jikan->getPersonSearch(new \Jikan\Request\Search\PersonSearchRequest('Ara')); self::assertCount(50, $search->getResults()); self::assertContainsOnlyInstancesOf(\Jikan\Model\Search\PersonSearchListItem::class, $search->getResults()); - self::assertEquals(20, $search->getLastPage()); + self::assertEquals(20, $search->getLastVisiblePage()); } /** diff --git a/test/JikanTest/Parser/Anime/AnimeParserTest.php b/test/JikanTest/Parser/Anime/AnimeParserTest.php index c8936c57..b75337cc 100644 --- a/test/JikanTest/Parser/Anime/AnimeParserTest.php +++ b/test/JikanTest/Parser/Anime/AnimeParserTest.php @@ -92,7 +92,7 @@ public function it_gets_the_anime_title_japanese(): void public function it_gets_the_anime_image_url(): void { self::assertEquals( - 'https://myanimelist.cdn-dena.com/images/anime/6/73245.jpg', + 'https://cdn.myanimelist.net/images/anime/6/73245.jpg', $this->parser->getImageURL() ); } @@ -284,7 +284,7 @@ public function it_gets_the_anime_rating(): void public function it_gets_the_anime_score(): void { self::assertEquals( - 8.54, + 8.51, $this->parser->getScore() ); } @@ -296,7 +296,7 @@ public function it_gets_the_anime_score(): void public function it_gets_the_anime_scored_by(): void { self::assertEquals( - 428921, + 705505, $this->parser->getScoredBy() ); } @@ -308,7 +308,7 @@ public function it_gets_the_anime_scored_by(): void public function it_gets_the_anime_rank(): void { self::assertEquals( - 89, + 100, $this->parser->getRank() ); } @@ -320,7 +320,7 @@ public function it_gets_the_anime_rank(): void public function it_gets_the_anime_popularity(): void { self::assertEquals( - 37, + 31, $this->parser->getPopularity() ); } @@ -332,7 +332,7 @@ public function it_gets_the_anime_popularity(): void public function it_gets_the_anime_members(): void { self::assertEquals( - 730240, + 1270781, $this->parser->getMembers() ); } @@ -344,7 +344,7 @@ public function it_gets_the_anime_members(): void public function it_gets_the_anime_favorites(): void { self::assertEquals( - 70500, + 117688, $this->parser->getFavorites() ); } @@ -366,10 +366,7 @@ public function it_gets_the_anime_related(): void */ public function it_gets_the_anime_background(): void { - self::assertEquals( - 'Several anime-original arcs have been adapted into light novels, and the series has inspired 40 video games as of 2016.', - $this->parser->getBackground() - ); + self::assertNull($this->parser->getBackground()); } /** @@ -379,7 +376,7 @@ public function it_gets_the_anime_background(): void public function it_gets_the_anime_opening(): void { $ops = $this->parser->getOpeningThemes(); - self::assertCount(19, $ops); + self::assertCount(23, $ops); self::assertContains('"We Are! (ウィーアー!)" by Hiroshi Kitadani (eps 1-47)', $ops); self::assertContains('"We Are (ウィーアー! 〜10周年Ver.〜)" by TVXQ (eps 373-394)', $ops); } @@ -391,7 +388,7 @@ public function it_gets_the_anime_opening(): void public function it_gets_the_anime_ending(): void { $eds = $this->parser->getEndingThemes(); - self::assertCount(21, $eds); + self::assertCount(22, $eds); self::assertContains('"memories" by Maki Otsuki (eps 1-30)', $eds); self::assertContains('"We go! (ウィーゴー!)" by Hiroshi Kitadani (eps 542, 590)', $eds); } @@ -403,6 +400,6 @@ public function it_gets_the_anime_ending(): void public function it_gets_the_preview_video() { $preview = $this->parser->getPreview(); - self::assertEquals('https://www.youtube.com/embed/um-tFlVamOI?enablejsapi=1&wmode=opaque&autoplay=1', $preview); + self::assertEquals('https://www.youtube.com/embed/l_98K4_6UQ0?enablejsapi=1&wmode=opaque&autoplay=1', $preview); } } diff --git a/test/JikanTest/Parser/Anime/AnimeRecommendationParserTest.php b/test/JikanTest/Parser/Anime/AnimeRecommendationParserTest.php index fbdad12f..64103459 100644 --- a/test/JikanTest/Parser/Anime/AnimeRecommendationParserTest.php +++ b/test/JikanTest/Parser/Anime/AnimeRecommendationParserTest.php @@ -47,7 +47,7 @@ public function it_gets_mal_id(): void public function it_gets_url(): void { self::assertEquals( - "https://myanimelist.net/anime/6702/Fairy_Tail", + "https://myanimelist.net/recommendations/anime/21-6702", $this->parser[0]->getUrl() ); } @@ -99,7 +99,7 @@ public function it_gets_title(): void public function it_gets_recommendation_count(): void { self::assertEquals( - 83, + 116, $this->parser[0]->getRecommendationCount() ); } diff --git a/test/JikanTest/Parser/Anime/AnimeStatsParserTest.php b/test/JikanTest/Parser/Anime/AnimeStatsParserTest.php index 3553624c..05d0c625 100644 --- a/test/JikanTest/Parser/Anime/AnimeStatsParserTest.php +++ b/test/JikanTest/Parser/Anime/AnimeStatsParserTest.php @@ -45,7 +45,7 @@ public function it_gets_numeric_statistics() public function it_gets_score_attributes() { self::assertEquals( - 126, $this->animeStatsParser->getScores()[10]->getVotes() + 677, $this->animeStatsParser->getScores()[10]->getVotes() ); } } diff --git a/test/JikanTest/Parser/Character/AnimeographyParserTest.php b/test/JikanTest/Parser/Character/AnimeographyParserTest.php index 6df87ffb..a094de4b 100644 --- a/test/JikanTest/Parser/Character/AnimeographyParserTest.php +++ b/test/JikanTest/Parser/Character/AnimeographyParserTest.php @@ -56,7 +56,7 @@ public function it_gets_the_anime_name() public function it_gets_the_anime_image() { self::assertEquals( - 'https://myanimelist.cdn-dena.com/images/anime/7/88019.jpg?s=ff141fea6f6c523c7205ff1957340003', + 'https://cdn.myanimelist.net/images/anime/7/88019.jpg?s=5a069ff3bdeebefc62a334e9a3a41c18', $this->parser->getImage() ); } diff --git a/test/JikanTest/Parser/Character/CharacterListItemParserTest.php b/test/JikanTest/Parser/Character/CharacterListItemParserTest.php index f09b44d4..d1e76a2d 100644 --- a/test/JikanTest/Parser/Character/CharacterListItemParserTest.php +++ b/test/JikanTest/Parser/Character/CharacterListItemParserTest.php @@ -82,7 +82,7 @@ public function it_gets_the_voice_actors() { $voiceActors = $this->parser->getVoiceActors(); self::assertContainsOnly(VoiceActor::class, $voiceActors); - self::assertCount(2, $voiceActors); + self::assertCount(0, $voiceActors); self::assertContains('Hara, Yumi', $voiceActors); self::assertEquals('Japanese', $voiceActors[0]->getLanguage()); self::assertEquals('English', $voiceActors[1]->getLanguage()); diff --git a/test/JikanTest/Parser/Character/CharacterParserTest.php b/test/JikanTest/Parser/Character/CharacterParserTest.php index 83137ff2..e0e536f3 100644 --- a/test/JikanTest/Parser/Character/CharacterParserTest.php +++ b/test/JikanTest/Parser/Character/CharacterParserTest.php @@ -55,7 +55,7 @@ public function it_gets_the_name() */ public function it_gets_the_name_in_kanji() { - self::assertEquals('モモンガ', $this->parser->getNameKanji()); + self::assertNull($this->parser->getNameKanji()); } /** @@ -86,7 +86,7 @@ public function it_gets_the_about() */ public function it_gets_the_member_favorites() { - self::assertEquals(3755, $this->parser->getMemberFavorites()); + self::assertEquals(9245, $this->parser->getMemberFavorites()); } /** @@ -96,7 +96,7 @@ public function it_gets_the_member_favorites() public function it_gets_the_image() { self::assertEquals( - 'https://myanimelist.cdn-dena.com/images/characters/3/288006.jpg', + 'https://cdn.myanimelist.net/images/characters/3/288006.jpg', $this->parser->getImage() ); } @@ -108,7 +108,7 @@ public function it_gets_the_image() public function it_gets_the_animeography() { $animeography = $this->parser->getAnimeography(); - self::assertCount(9, $animeography); + self::assertCount(11, $animeography); self::assertContainsOnly(\Jikan\Model\Character\Animeography::class, $animeography); } @@ -130,7 +130,7 @@ public function it_gets_the_mangaography() public function it_gets_the_voice_actors() { $voiceActors = $this->parser->getVoiceActors(); - self::assertCount(4, $voiceActors); + self::assertCount(5, $voiceActors); self::assertContainsOnlyInstancesOf(\Jikan\Model\Character\VoiceActor::class, $voiceActors); self::assertContains('Hino, Satoshi', $voiceActors); self::assertContains('Mendiant, Charles', $voiceActors); diff --git a/test/JikanTest/Parser/Character/VoiceActorParserTest.php b/test/JikanTest/Parser/Character/VoiceActorParserTest.php index ae2ff192..800e13fe 100644 --- a/test/JikanTest/Parser/Character/VoiceActorParserTest.php +++ b/test/JikanTest/Parser/Character/VoiceActorParserTest.php @@ -59,7 +59,7 @@ public function it_gets_the_person() public function it_gets_the_image() { self::assertEquals( - 'https://myanimelist.cdn-dena.com/images/voiceactors/3/18359v.jpg', + 'https://cdn.myanimelist.net/images/voiceactors/2/55555.jpg', $this->parser->getImage() ); } diff --git a/test/JikanTest/Parser/Club/ClubParserTest.php b/test/JikanTest/Parser/Club/ClubParserTest.php index c79c3935..77942a0b 100644 --- a/test/JikanTest/Parser/Club/ClubParserTest.php +++ b/test/JikanTest/Parser/Club/ClubParserTest.php @@ -80,7 +80,7 @@ public function it_gets_title(): void public function it_gets_members_count(): void { self::assertEquals( - 1297, + 1347, $this->parser->getMembersCount() ); } @@ -135,16 +135,6 @@ public function it_gets_staff(): void MalUrl::class, $this->parser->getStaff() ); - - self::assertEquals( - 'daya', - $this->parser->getStaff()[0]->getName() - ); - - self::assertEquals( - 'https://myanimelist.net/profile/daya', - $this->parser->getStaff()[0]->getUrl() - ); } /** diff --git a/test/JikanTest/Parser/Forum/ForumTopicParserTest.php b/test/JikanTest/Parser/Forum/ForumTopicParserTest.php index a0e62b6e..5b0e9dd1 100644 --- a/test/JikanTest/Parser/Forum/ForumTopicParserTest.php +++ b/test/JikanTest/Parser/Forum/ForumTopicParserTest.php @@ -31,7 +31,7 @@ public function setUp(): void */ public function it_gets_the_post_id(): void { - self::assertEquals(57389, $this->parser->getTopicId()); + self::assertEquals(1881620, $this->parser->getTopicId()); } /** @@ -40,7 +40,7 @@ public function it_gets_the_post_id(): void */ public function it_gets_the_post_url(): void { - self::assertEquals('https://myanimelist.net/forum/?topicid=57389', $this->parser->getUrl()); + self::assertEquals('https://myanimelist.net/forum/?topicid=1881620', $this->parser->getUrl()); } /** @@ -49,7 +49,7 @@ public function it_gets_the_post_url(): void */ public function it_gets_the_post_title(): void { - self::assertEquals('One Piece Episode 381 Discussion', $this->parser->getTitle()); + self::assertEquals('One Piece Episode 954 Discussion', $this->parser->getTitle()); } /** @@ -58,7 +58,7 @@ public function it_gets_the_post_title(): void */ public function it_gets_the_post_date(): void { - self::assertEquals('2008-12-14', $this->parser->getPostDate()->format('Y-m-d')); + self::assertEquals('2020-12-12', $this->parser->getPostDate()->format('Y-m-d')); } /** @@ -67,7 +67,7 @@ public function it_gets_the_post_date(): void */ public function it_gets_the_author_name(): void { - self::assertEquals('VK11', $this->parser->getAuthorName()); + self::assertEquals('xeonite', $this->parser->getAuthorName()); } /** @@ -76,7 +76,7 @@ public function it_gets_the_author_name(): void */ public function it_gets_the_author_url(): void { - self::assertEquals('https://myanimelist.net/profile/VK11', $this->parser->getAuthorUrl()); + self::assertEquals('https://myanimelist.net/profile/xeonite', $this->parser->getAuthorUrl()); } /** @@ -85,7 +85,7 @@ public function it_gets_the_author_url(): void */ public function it_gets_the_replies(): void { - self::assertEquals(69, $this->parser->getReplies()); + self::assertEquals(39, $this->parser->getReplies()); } /** diff --git a/test/JikanTest/Parser/Genre/AnimeGenreParserTest.php b/test/JikanTest/Parser/Genre/AnimeGenreParserTest.php index a9c95d39..788edeef 100644 --- a/test/JikanTest/Parser/Genre/AnimeGenreParserTest.php +++ b/test/JikanTest/Parser/Genre/AnimeGenreParserTest.php @@ -50,6 +50,6 @@ public function it_gets_anime() */ public function it_gets_the_count() { - self::assertEquals(3263, $this->parser->getCount()); + self::assertEquals(3855, $this->parser->getCount()); } } diff --git a/test/JikanTest/Parser/Genre/MangaGenreParserTest.php b/test/JikanTest/Parser/Genre/MangaGenreParserTest.php index 2d116d0b..42aae58e 100644 --- a/test/JikanTest/Parser/Genre/MangaGenreParserTest.php +++ b/test/JikanTest/Parser/Genre/MangaGenreParserTest.php @@ -51,6 +51,6 @@ public function it_gets_manga() */ public function it_gets_the_count() { - self::assertEquals(6187, $this->parser->getCount()); + self::assertEquals(7318, $this->parser->getCount()); } } diff --git a/test/JikanTest/Parser/Manga/MangaParserTest.php b/test/JikanTest/Parser/Manga/MangaParserTest.php index 0792cada..78751873 100644 --- a/test/JikanTest/Parser/Manga/MangaParserTest.php +++ b/test/JikanTest/Parser/Manga/MangaParserTest.php @@ -97,7 +97,7 @@ public function it_gets_the_manga_title_japanese() public function it_gets_the_manga_image_url() { self::assertEquals( - 'https://myanimelist.cdn-dena.com/images/manga/3/117681.jpg', + 'https://cdn.myanimelist.net/images/manga/3/117681.jpg', $this->parser->getMangaImageURL() ); } @@ -236,7 +236,7 @@ public function it_gets_the_manga_genre() public function it_gets_the_manga_score() { self::assertEquals( - 8.11, + 8.06, $this->manga->getScore() ); } @@ -248,7 +248,7 @@ public function it_gets_the_manga_score() public function it_gets_the_manga_scored_by() { self::assertEquals( - 177655, + 217694, $this->manga->getScoredBy() ); } @@ -260,7 +260,7 @@ public function it_gets_the_manga_scored_by() public function it_gets_the_manga_rank() { self::assertEquals( - 706, + 572, $this->manga->getRank() ); } @@ -272,7 +272,7 @@ public function it_gets_the_manga_rank() public function it_gets_the_manga_popularity() { self::assertEquals( - 1, + 4, $this->manga->getPopularity() ); } @@ -284,7 +284,7 @@ public function it_gets_the_manga_popularity() public function it_gets_the_manga_members() { self::assertEquals( - 258896, + 323346, $this->manga->getMembers() ); } @@ -296,7 +296,7 @@ public function it_gets_the_manga_members() public function it_gets_the_manga_favorites() { self::assertEquals( - 39966, + 47385, $this->manga->getFavorites() ); } diff --git a/test/JikanTest/Parser/Manga/MangaRecommendationParserTest.php b/test/JikanTest/Parser/Manga/MangaRecommendationParserTest.php index 4a53b6c3..adffcf48 100644 --- a/test/JikanTest/Parser/Manga/MangaRecommendationParserTest.php +++ b/test/JikanTest/Parser/Manga/MangaRecommendationParserTest.php @@ -47,7 +47,7 @@ public function it_gets_mal_id(): void public function it_gets_url(): void { self::assertEquals( - "https://myanimelist.net/manga/21/Death_Note", + "hhttps://myanimelist.net/recommendations/manga/1-3", $this->parser[0]->getUrl() ); } @@ -99,7 +99,7 @@ public function it_gets_title(): void public function it_gets_recommendation_count(): void { self::assertEquals( - 10, + 41, $this->parser[0]->getRecommendationCount() ); } diff --git a/test/JikanTest/Parser/Manga/MangaStatsParserTest.php b/test/JikanTest/Parser/Manga/MangaStatsParserTest.php index 6f75988a..9b940380 100644 --- a/test/JikanTest/Parser/Manga/MangaStatsParserTest.php +++ b/test/JikanTest/Parser/Manga/MangaStatsParserTest.php @@ -45,7 +45,7 @@ public function it_gets_numeric_statistics() public function it_gets_score_attributes() { self::assertEquals( - 1432, $this->mangaStatsParser->getScores()[10]->getVotes() + 4731, $this->mangaStatsParser->getScores()[10]->getVotes() ); } } diff --git a/test/JikanTest/Parser/News/NewsListItemParserTest.php b/test/JikanTest/Parser/News/NewsListItemParserTest.php index a2fcb180..fdf8e635 100644 --- a/test/JikanTest/Parser/News/NewsListItemParserTest.php +++ b/test/JikanTest/Parser/News/NewsListItemParserTest.php @@ -30,7 +30,7 @@ public function setUp(): void */ public function it_gets_the_title(): void { - self::assertEquals('Manga \'Berserk\' Resumes Serialization', $this->parser->getTitle()); + self::assertEquals('North American Anime & Manga Releases for July', $this->parser->getTitle()); } /** @@ -39,7 +39,7 @@ public function it_gets_the_title(): void */ public function it_gets_the_url(): void { - self::assertEquals('https://myanimelist.net/news/53304997', $this->parser->getUrl()); + self::assertEquals('https://myanimelist.net/news/60161703', $this->parser->getUrl()); } /** @@ -49,7 +49,7 @@ public function it_gets_the_url(): void public function it_gets_the_image(): void { self::assertEquals( - 'https://myanimelist.cdn-dena.com/s/common/uploaded_files/1512787795-f1674d6456f90126448afb689c3224be.jpeg?s=66f1c0637fa3b5b7e90dc0f40f608738', + 'https://cdn.myanimelist.net/s/common/uploaded_files/1594161493-e76e48dafd1b0f67ece6f1fa065db158.jpeg?s=e24b9ee8cfa8d123bf27fbbd9aef0d27', $this->parser->getImage() ); } @@ -60,7 +60,7 @@ public function it_gets_the_image(): void */ public function it_gets_the_date(): void { - self::assertEquals('2017-12-08 18:53', $this->parser->getDate()->format('Y-m-d H:i')); + self::assertEquals('2020-07-07 15:39', $this->parser->getDate()->format('Y-m-d H:i')); } /** @@ -69,7 +69,7 @@ public function it_gets_the_date(): void */ public function it_gets_the_author(): void { - self::assertEquals('Vindstot', (string)$this->parser->getAuthor()); + self::assertEquals('ImperfectBlue', (string)$this->parser->getAuthor()); } /** @@ -78,7 +78,7 @@ public function it_gets_the_author(): void */ public function it_gets_the_discussion_link(): void { - self::assertEquals('https://myanimelist.net/forum/?topicid=1690998', $this->parser->getDiscussionLink()); + self::assertEquals('https://myanimelist.net/forum/?topicid=1850747', $this->parser->getDiscussionLink()); } /** @@ -88,7 +88,7 @@ public function it_gets_the_discussion_link(): void public function it_gets_the_comments(): void { self::assertEquals( - 31, + 0, $this->parser->getComments() ); } @@ -99,8 +99,8 @@ public function it_gets_the_comments(): void */ public function it_gets_the_introduction(): void { - self::assertEquals( - 'The 24th issue of this year\'s Young Animal magazine has announced on Friday that Kentarou Miura\'s adventure fantasy manga Berserk will resume its serializa...', + self::assert( + 'Here are the North American anime & manga releases for July Week 1: July 7 - 13 Anime Releases Cop Craft Complete Collection Blu-ray Dumbbell Nan Kilo Moteru? (H...', $this->parser->getIntro() ); } diff --git a/test/JikanTest/Parser/Person/PersonParserTest.php b/test/JikanTest/Parser/Person/PersonParserTest.php index 09225723..10b3a865 100644 --- a/test/JikanTest/Parser/Person/PersonParserTest.php +++ b/test/JikanTest/Parser/Person/PersonParserTest.php @@ -83,7 +83,7 @@ public function it_gets_the_about() */ public function it_gets_the_member_favorites() { - self::assertEquals(26537, $this->parser->getPersonFavorites()); + self::assertEquals(38369, $this->parser->getPersonFavorites()); } /** @@ -93,7 +93,7 @@ public function it_gets_the_member_favorites() public function it_gets_the_image() { self::assertEquals( - 'https://myanimelist.cdn-dena.com/images/voiceactors/1/41394.jpg', + 'https://cdn.myanimelist.net/images/voiceactors/1/54600.jpg', $this->parser->getPersonImageUrl() ); } @@ -105,7 +105,7 @@ public function it_gets_the_image() public function it_gets_the_voice_acting_roles() { $voiceActingRoles = $this->parser->getPersonVoiceActingRoles(); - self::assertCount(439, $voiceActingRoles); + self::assertCount(488, $voiceActingRoles); self::assertContainsOnlyInstancesOf(\Jikan\Model\Person\VoiceActingRole::class, $voiceActingRoles); } @@ -116,7 +116,7 @@ public function it_gets_the_voice_acting_roles() public function it_gets_the_anime_staff_positions() { $animeStaffPositions = $this->parser->getPersonAnimeStaffPositions(); - self::assertCount(42, $animeStaffPositions); + self::assertCount(43, $animeStaffPositions); self::assertContainsOnlyInstancesOf(\Jikan\Model\Person\AnimeStaffPosition::class, $animeStaffPositions); } diff --git a/test/JikanTest/Parser/Schedule/ScheduleParserTest.php b/test/JikanTest/Parser/Schedule/ScheduleParserTest.php index 5a550830..4f60eb1e 100644 --- a/test/JikanTest/Parser/Schedule/ScheduleParserTest.php +++ b/test/JikanTest/Parser/Schedule/ScheduleParserTest.php @@ -54,7 +54,7 @@ public function it_gets_wednesdays() { $wednesday = $this->parser->getShedule('wednesday'); self::assertContainsOnlyInstancesOf(AnimeCard::class, $wednesday); - self::assertCount(5, $wednesday); + self::assertCount(13, $wednesday); } /** @@ -65,7 +65,7 @@ public function it_gets_thursdays() { $thursday = $this->parser->getShedule('thursday'); self::assertContainsOnlyInstancesOf(AnimeCard::class, $thursday); - self::assertCount(11, $thursday); + self::assertCount(9, $thursday); } /** @@ -87,7 +87,7 @@ public function it_gets_saturdays() { $saturday = $this->parser->getShedule('saturday'); self::assertContainsOnlyInstancesOf(AnimeCard::class, $saturday); - self::assertCount(14, $saturday); + self::assertCount(15, $saturday); } /** @@ -98,7 +98,7 @@ public function it_gets_sundays() { $sunday = $this->parser->getShedule('sunday'); self::assertContainsOnlyInstancesOf(AnimeCard::class, $sunday); - self::assertCount(18, $sunday); + self::assertCount(21, $sunday); } /** @@ -109,7 +109,7 @@ public function it_gets_all() { $all = $this->parser->getShedule('all'); self::assertContainsOnlyInstancesOf(AnimeCard::class, $all); - self::assertCount(148, $all); + self::assertCount(141, $all); } /** @@ -120,7 +120,7 @@ public function it_gets_other() { $other = $this->parser->getShedule('other'); self::assertContainsOnlyInstancesOf(AnimeCard::class, $other); - self::assertCount(17, $other); + self::assertCount(10, $other); } /** @@ -131,6 +131,6 @@ public function it_gets_unknown() { $unknown = $this->parser->getShedule('unknown'); self::assertContainsOnlyInstancesOf(AnimeCard::class, $unknown); - self::assertCount(36, $unknown); + self::assertCount(20, $unknown); } } diff --git a/test/JikanTest/Parser/Search/AnimeSearchAiringTest.php b/test/JikanTest/Parser/Search/AnimeSearchAiringTest.php index a287427b..3ceb8083 100644 --- a/test/JikanTest/Parser/Search/AnimeSearchAiringTest.php +++ b/test/JikanTest/Parser/Search/AnimeSearchAiringTest.php @@ -36,6 +36,6 @@ public function it_gets_airing_null() $this->search = $jikan->getAnimeSearch(new AnimeSearchRequest('Aikatsu Friends')); $anime = $this->search->getResults()[0]; self::assertEquals('Aikatsu Friends!', $anime->getTitle()); - self::assertTrue($anime->isAiring()); + self::assertFalse($anime->isAiring()); } } diff --git a/test/JikanTest/Parser/Search/CharacterSearchTest.php b/test/JikanTest/Parser/Search/CharacterSearchTest.php index c5d7dee3..82e7daac 100644 --- a/test/JikanTest/Parser/Search/CharacterSearchTest.php +++ b/test/JikanTest/Parser/Search/CharacterSearchTest.php @@ -2,6 +2,7 @@ namespace JikanTest\Parser\Search; +use Jikan\Model\Common\MalUrl; use PHPUnit\Framework\TestCase; use Jikan\MyAnimeList\MalClient; @@ -67,8 +68,8 @@ public function it_gets_the_alternative_names() public function it_gets_the_anime() { self::assertContainsOnlyInstancesOf(\Jikan\Model\Common\MalUrl::class, $this->anime->getAnime()); - self::assertEquals("Mahou Shoujo Lyrical Nanoha: The Movie 1st", $this->anime->getAnime()[0]->getName()); - self::assertEquals("https://myanimelist.net/anime/4985/Mahou_Shoujo_Lyrical_Nanoha__The_Movie_1st", $this->anime->getAnime()[0]->getUrl()); + self::assertEquals("Mahou Shoujo Lyrical Nanoha ViVid", $this->anime->getAnime()[0]->getName()); + self::assertEquals("https://myanimelist.net/anime/25939/Mahou_Shoujo_Lyrical_Nanoha_ViVid", $this->anime->getAnime()[0]->getUrl()); } /** @@ -77,6 +78,6 @@ public function it_gets_the_anime() */ public function it_gets_the_manga() { - self::assertEquals([], $this->anime->getManga()); + self::assertContainsOnlyInstancesOf(MalUrl::class, $this->anime->getManga()); } } diff --git a/test/JikanTest/Parser/Search/MangaSearchTest.php b/test/JikanTest/Parser/Search/MangaSearchTest.php index 9b30a7d8..0b142985 100644 --- a/test/JikanTest/Parser/Search/MangaSearchTest.php +++ b/test/JikanTest/Parser/Search/MangaSearchTest.php @@ -38,7 +38,7 @@ public function it_gets_the_title() */ public function it_gets_the_image_url() { - self::assertEquals("https://myanimelist.cdn-dena.com/images/manga/3/196931.jpg?s=7da8d65371bc975c9ecda0d30a832984", $this->manga->getImageUrl()); + self::assertEquals("https://cdn.myanimelist.net/images/manga/3/196931.jpg?s=7da8d65371bc975c9ecda0d30a832984", $this->manga->getImages()->); } /** diff --git a/test/JikanTest/Parser/SeasonList/SeasonListItemParserTest.php b/test/JikanTest/Parser/SeasonList/SeasonListItemParserTest.php index 8f39e8b3..b029d090 100644 --- a/test/JikanTest/Parser/SeasonList/SeasonListItemParserTest.php +++ b/test/JikanTest/Parser/SeasonList/SeasonListItemParserTest.php @@ -27,7 +27,7 @@ public function setUp(): void */ public function it_gets_the_year(): void { - self::assertEquals(2019, $this->parser->getYear()); + self::assertEquals(2021, $this->parser->getYear()); } /** @@ -37,6 +37,6 @@ public function it_gets_the_year(): void */ public function it_gets_the_seasons(): void { - self::assertContains('Winter', $this->parser->getSeasons()); + self::assertContains('winter', $this->parser->getSeasons()); } } diff --git a/test/JikanTest/Parser/Seasonal/SeasonalAnimeParserTest.php b/test/JikanTest/Parser/Seasonal/SeasonalAnimeParserTest.php index 05f502df..d3449e4a 100644 --- a/test/JikanTest/Parser/Seasonal/SeasonalAnimeParserTest.php +++ b/test/JikanTest/Parser/Seasonal/SeasonalAnimeParserTest.php @@ -63,7 +63,7 @@ public function it_gets_the_producer() self::assertEquals('https://myanimelist.net/anime/producer/4/Bones', $producer->getUrl()); $producer = $this->parser2->getProducer(); - self::assertCount(2, $producer); + self::assertCount(1, $producer); self::assertContainsOnly(\Jikan\Model\Common\MalUrl::class, $producer); self::assertContains('Pierrot Plus', $producer); self::assertContains('Studio Pierrot', $producer); @@ -77,7 +77,7 @@ public function it_gets_the_episodes() { $this->parser2 = new AnimeCardParser($this->crawler->filter('div.seasonal-anime')->eq(2)); self::assertEquals(25, $this->parser->getEpisodes()); - self::assertEquals(12, $this->parser2->getEpisodes()); + self::assertEquals(23, $this->parser2->getEpisodes()); } /** @@ -88,7 +88,7 @@ public function it_gets_the_source() { $this->parser2 = new AnimeCardParser($this->crawler->filter('div.seasonal-anime')->eq(2)); self::assertEquals('Manga', $this->parser->getSource()); - self::assertEquals('Manga', $this->parser2->getSource()); + self::assertEquals('Visual novel', $this->parser2->getSource()); } /** @@ -99,11 +99,9 @@ public function it_gets_the_genres() { $genres = $this->parser->getGenres(); self::assertContainsOnlyInstancesOf(\Jikan\Model\Common\MalUrl::class, $genres); - self::assertContains('Action', $genres); - self::assertContains('Comedy', $genres); - self::assertContains('School', $genres); - self::assertContains('Shounen', $genres); - self::assertContains('Super Power', $genres); + self::assertContains('Action', $genres[0]->getName()); + self::assertContains('Comedy', $genres[1]->getName()); + self::assertContains('Super Power', $genres[2]->getName()); } /** @@ -121,7 +119,7 @@ public function it_gets_the_title() */ public function it_gets_the_description() { - self::assertEquals('Third season of Boku no Hero Academia.', $this->parser->getDescription()); + self::assertContains('As summer arrives for the students at UA Academy, each of these superheroes', $this->parser->getDescription()); } /** @@ -148,7 +146,7 @@ public function it_gets_the_air_dates() */ public function it_gets_the_air_members() { - self::assertEquals(329324, $this->parser->getMembers()); + self::assertEquals(1247636, $this->parser->getMembers()); } /** @@ -179,7 +177,7 @@ public function it_gets_the_anime_url() public function it_gets_the_anime_image() { self::assertEquals( - 'https://myanimelist.cdn-dena.com/images/anime/1319/92084.jpg?s=174e33772872a964b6c8b7668b46c2c5', + 'https://cdn.myanimelist.net/images/anime/1319/92084.jpg', $this->parser->getAnimeImage() ); } @@ -192,7 +190,7 @@ public function it_gets_the_anime_score() { $this->parser2 = new AnimeCardParser($this->crawler->filter('div.seasonal-anime')->eq(2)); self::assertEquals( - 7.57, + 8.52, $this->parser2->getAnimeScore() ); } diff --git a/test/JikanTest/Parser/Seasonal/SeasonalParserTest.php b/test/JikanTest/Parser/Seasonal/SeasonalParserTest.php index 140788f1..600c399f 100644 --- a/test/JikanTest/Parser/Seasonal/SeasonalParserTest.php +++ b/test/JikanTest/Parser/Seasonal/SeasonalParserTest.php @@ -38,7 +38,7 @@ public function it_gets_the_season() public function it_gets_the_anime() { $anime = $this->springParser->getSeasonalAnime(); - self::assertCount(234, $anime); + self::assertCount(267, $anime); self::assertContainsOnlyInstancesOf(\Jikan\Model\Seasonal\SeasonalAnime::class, $anime); } } diff --git a/test/JikanTest/Parser/Top/TopAnimeParserTest.php b/test/JikanTest/Parser/Top/TopAnimeParserTest.php index e3645f64..7435f950 100644 --- a/test/JikanTest/Parser/Top/TopAnimeParserTest.php +++ b/test/JikanTest/Parser/Top/TopAnimeParserTest.php @@ -33,8 +33,8 @@ public function setUp(): void public function it_gets_the_mal_url() { $url = $this->parser->getMalUrl(); - self::assertEquals('Koe no Katachi', $url); - self::assertEquals('https://myanimelist.net/anime/28851/Koe_no_Katachi', $url->getUrl()); + self::assertEquals('Gintama: The Final', $url); + self::assertEquals('https://myanimelist.net/anime/39486/Gintama__The_Final', $url->getUrl()); } /** @@ -53,7 +53,7 @@ public function it_gets_the_rank() public function it_gets_the_image() { self::assertEquals( - 'https://myanimelist.cdn-dena.com/images/anime/3/80136.jpg?s=a3b3a8039e99287c719995e564e3d084', + 'https://cdn.myanimelist.net/images/anime/1027/109706.jpg?s=29712c4254f5acc66580a2107fe6643d', $this->parser->getImage() ); } @@ -64,7 +64,7 @@ public function it_gets_the_image() */ public function it_gets_the_anime_score() { - self::assertEquals(9.04, $this->parser->getScore()); + self::assertEquals(9.0, $this->parser->getScore()); } /** @@ -91,7 +91,7 @@ public function it_gets_the_anime_episodes() */ public function it_gets_the_anime_members() { - self::assertEquals(533061, $this->parser->getMembers()); + self::assertEquals(22172, $this->parser->getMembers()); } /** @@ -100,7 +100,7 @@ public function it_gets_the_anime_members() */ public function it_gets_the_anime_start_date() { - self::assertEquals('Sep 2016', $this->parser->getStartDate()); + self::assertEquals('Jan 2021', $this->parser->getStartDate()); } /** @@ -109,6 +109,6 @@ public function it_gets_the_anime_start_date() */ public function it_gets_the_anime_end_date() { - self::assertEquals('Sep 2016', $this->parser->getEndDate()); + self::assertEquals('Jan 2021', $this->parser->getEndDate()); } } diff --git a/test/JikanTest/Parser/Top/TopCharacterParserTest.php b/test/JikanTest/Parser/Top/TopCharacterParserTest.php index 2140f0d0..f82e1e4f 100644 --- a/test/JikanTest/Parser/Top/TopCharacterParserTest.php +++ b/test/JikanTest/Parser/Top/TopCharacterParserTest.php @@ -34,8 +34,8 @@ public function setUp(): void public function it_gets_the_mal_url() { $url = $this->parser->getMalUrl(); - self::assertEquals('Monkey D., Luffy', $url); - self::assertEquals('https://myanimelist.net/character/40/Luffy_Monkey_D', $url->getUrl()); + self::assertEquals('Levi', $url); + self::assertEquals('https://myanimelist.net/character/45627/Levi', $url->getUrl()); } /** @@ -45,7 +45,7 @@ public function it_gets_the_mal_url() public function it_gets_the_image() { self::assertEquals( - 'https://myanimelist.cdn-dena.com/images/characters/9/310307.jpg?s=1422edf1e44c7b6262386330461eecfd', + 'https://cdn.myanimelist.net/images/characters/2/241413.jpg?s=be87b99243a15158d0c4234a2927742e', $this->parser->getImage() ); } @@ -65,7 +65,7 @@ public function it_gets_the_rank() */ public function it_gets_the_character_kanji() { - self::assertEquals('モンキー・D・ルフィ', $this->parser->getKanjiName()); + self::assertEquals('リヴァイ', $this->parser->getKanjiName()); } /** @@ -94,6 +94,6 @@ public function it_gets_the_mangaography() */ public function it_gets_the_favorites() { - self::assertEquals(49856, $this->parser->getFavorites()); + self::assertEquals(115146, $this->parser->getFavorites()); } } diff --git a/test/JikanTest/Parser/Top/TopMangaParserTest.php b/test/JikanTest/Parser/Top/TopMangaParserTest.php index b7f44a7a..b462bc4a 100644 --- a/test/JikanTest/Parser/Top/TopMangaParserTest.php +++ b/test/JikanTest/Parser/Top/TopMangaParserTest.php @@ -39,8 +39,8 @@ public function setUp(): void public function it_gets_the_mal_url() { $url = $this->parser->getMalUrl(); - self::assertEquals('One Piece', $url); - self::assertEquals('https://myanimelist.net/manga/13/One_Piece', $url->getUrl()); + self::assertEquals('Vagabond', $url); + self::assertEquals('https://myanimelist.net/manga/656/Vagabond', $url->getUrl()); } /** @@ -58,7 +58,7 @@ public function it_gets_the_rank() */ public function it_gets_the_manga_score() { - self::assertEquals(9.03, $this->parser->getScore()); + self::assertEquals(9.09, $this->parser->getScore()); } /** @@ -79,8 +79,7 @@ public function it_gets_the_manga_volumes() $parser2 = new TopListItemParser( $this->crawler->filterXPath('//tr[@class="ranking-list"]')->eq(1) ); - self::assertNull($this->parser->getVolumes()); - self::assertEquals(24, $parser2->getVolumes()); + self::assertEquals(37, $this->parser->getVolumes()); } /** @@ -89,7 +88,7 @@ public function it_gets_the_manga_volumes() */ public function it_gets_the_manga_members() { - self::assertEquals(212645, $this->parser->getMembers()); + self::assertEquals(160324, $this->parser->getMembers()); } /** @@ -98,7 +97,7 @@ public function it_gets_the_manga_members() */ public function it_gets_the_manga_start_date() { - self::assertEquals('Jul 1997', $this->parser->getStartDate()); + self::assertEquals('Sep 1998', $this->parser->getStartDate()); } /** @@ -107,7 +106,7 @@ public function it_gets_the_manga_start_date() */ public function it_gets_the_manga_end_date() { - self::assertEquals('', $this->parser->getEndDate()); + self::assertEquals('May 2015', $this->parser->getEndDate()); } /** @@ -117,7 +116,7 @@ public function it_gets_the_manga_end_date() public function it_gets_the_manga_image() { self::assertEquals( - 'https://myanimelist.cdn-dena.com/images/manga/3/55539.jpg?s=b4d9e935b7152f0c9e69b34a7797fe02', + 'https://cdn.myanimelist.net/images/manga/2/181787.jpg?s=bbd3ff81b5d8e50781531c60cd68773f', $this->parser->getImage() ); } diff --git a/test/JikanTest/Parser/Top/TopPeopleParserTest.php b/test/JikanTest/Parser/Top/TopPeopleParserTest.php index 3776636a..cf92604a 100644 --- a/test/JikanTest/Parser/Top/TopPeopleParserTest.php +++ b/test/JikanTest/Parser/Top/TopPeopleParserTest.php @@ -52,7 +52,7 @@ public function it_gets_the_rank() */ public function it_gets_the_favorites() { - self::assertEquals(24588, $this->parser->getPeopleFavorites()); + self::assertEquals(39630, $this->parser->getPeopleFavorites()); } /** @@ -62,7 +62,7 @@ public function it_gets_the_favorites() public function it_gets_the_image() { self::assertEquals( - 'https://myanimelist.cdn-dena.com/images/voiceactors/3/42163.jpg?s=e7aa2685616307adf04f3d1255e4dba3', + 'https://cdn.myanimelist.net/images/voiceactors/2/60638.jpg?s=5b39d822cfe1fe7c5dd164a0d4684a41', $this->parser->getImage() ); } diff --git a/test/JikanTest/Parser/UserFriend/FriendParserTest.php b/test/JikanTest/Parser/UserFriend/FriendParserTest.php index 98d0805f..c1d2a3d7 100644 --- a/test/JikanTest/Parser/UserFriend/FriendParserTest.php +++ b/test/JikanTest/Parser/UserFriend/FriendParserTest.php @@ -28,7 +28,7 @@ public function setUp(): void */ public function it_gets_the_name() { - self::assertEquals('Dinoe', $this->parser->getName()); + self::assertEquals('HeavyGod', $this->parser->getName()); } /** @@ -37,7 +37,7 @@ public function it_gets_the_name() */ public function it_gets_the_url() { - self::assertEquals('https://myanimelist.net/profile/Dinoe', $this->parser->getUrl()); + self::assertEquals('https://myanimelist.net/profile/HeavyGod', $this->parser->getUrl()); } /** @@ -47,7 +47,7 @@ public function it_gets_the_url() public function it_gets_the_avatar() { self::assertEquals( - 'https://myanimelist.cdn-dena.com/images/userimages/5082596.jpg', + 'https://cdn.myanimelist.net/images/userimages/6574969.jpg?t=1610778600', $this->parser->getAvatar() ); } @@ -59,7 +59,7 @@ public function it_gets_the_avatar() public function it_gets_friends_since() { self::assertEquals( - '2016-05-11 04:37', + '2018-01-16 07:34', $this->parser->getFriendsSince()->format('Y-m-d H:i') ); } diff --git a/test/JikanTest/Parser/UserProfile/UserProfileParserTest.php b/test/JikanTest/Parser/UserProfile/UserProfileParserTest.php index f37526e7..00454410 100644 --- a/test/JikanTest/Parser/UserProfile/UserProfileParserTest.php +++ b/test/JikanTest/Parser/UserProfile/UserProfileParserTest.php @@ -46,7 +46,7 @@ public function it_gets_the_url() public function it_gets_the_image() { self::assertEquals( - 'https://myanimelist.cdn-dena.com/images/userimages/3600201.jpg', + 'https://cdn.myanimelist.net/images/userimages/3600201.jpg?t=1610489400', $this->parser->getImageUrl() ); } @@ -93,7 +93,7 @@ public function it_gets_the_birthday() */ public function it_gets_the_location() { - self::assertEquals('101', $this->parser->getLocation()); + self::assertEquals('The wired', $this->parser->getLocation()); } /** @@ -121,16 +121,26 @@ public function it_gets_the_manga_stats() public function it_gets_the_favorites() { self::assertInstanceOf(\Jikan\Model\User\Favorites::class, $this->parser->getFavorites()); - self::assertContainsOnlyInstancesOf(\Jikan\Model\Common\AnimeMeta::class, $this->parser->getFavorites()->getAnime()); - self::assertContainsOnlyInstancesOf(\Jikan\Model\Common\MangaMeta::class, $this->parser->getFavorites()->getManga()); + self::assertContainsOnlyInstancesOf(\Jikan\Model\User\FavoriteAnime::class, $this->parser->getFavorites()->getAnime()); + self::assertContainsOnlyInstancesOf(\Jikan\Model\User\FavoriteManga::class, $this->parser->getFavorites()->getManga()); self::assertContainsOnlyInstancesOf( - \Jikan\Model\Common\CharacterMeta::class, + \Jikan\Model\User\FavoriteCharacter::class, $this->parser->getFavorites()->getCharacters() ); self::assertContainsOnlyInstancesOf(\Jikan\Model\Common\PersonMeta::class, $this->parser->getFavorites()->getPeople()); } + /** + * @test + * @vcr ProfileParserTest.yaml + */ + public function it_gets_last_updates(){ + $updates = $this->parser->getUserLastUpdates(); + self::assertContainsOnlyInstancesOf(\Jikan\Model\User\LastAnimeUpdate::class, $updates->getAnime()); + self::assertContainsOnlyInstancesOf(\Jikan\Model\User\LastMangaUpdate::class, $updates->getManga()); + } + /** * @test * @vcr MangaParserTest.yaml