This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php declare(strict_types=1); |
||
2 | /** |
||
3 | * Anime List Client |
||
4 | * |
||
5 | * An API client for Kitsu and MyAnimeList to manage anime and manga watch lists |
||
6 | * |
||
7 | * PHP version 7 |
||
8 | * |
||
9 | * @package AnimeListClient |
||
10 | * @author Timothy J. Warren <[email protected]> |
||
11 | * @copyright 2015 - 2017 Timothy J. Warren |
||
12 | * @license http://www.opensource.org/licenses/mit-license.html MIT License |
||
13 | * @version 4.0 |
||
14 | * @link https://github.com/timw4mail/HummingBirdAnimeClient |
||
15 | */ |
||
16 | |||
17 | namespace Aviat\AnimeClient\API; |
||
18 | |||
19 | use Aviat\AnimeClient\API\Kitsu\Enum\{ |
||
20 | AnimeAiringStatus, |
||
21 | AnimeWatchingStatus, |
||
22 | MangaReadingStatus |
||
23 | }; |
||
24 | use DateTimeImmutable; |
||
25 | |||
26 | const AUTH_URL = 'https://kitsu.io/api/oauth/token'; |
||
27 | const AUTH_USER_ID_KEY = 'kitsu-auth-userid'; |
||
28 | const AUTH_TOKEN_CACHE_KEY = 'kitsu-auth-token'; |
||
29 | |||
30 | /** |
||
31 | * Data massaging helpers for the Kitsu API |
||
32 | */ |
||
33 | class Kitsu { |
||
34 | const AUTH_URL = 'https://kitsu.io/api/oauth/token'; |
||
35 | const AUTH_USER_ID_KEY = 'kitsu-auth-userid'; |
||
36 | const AUTH_TOKEN_CACHE_KEY = 'kitsu-auth-token'; |
||
37 | |||
38 | /** |
||
39 | * Map of Kitsu status to label for select menus |
||
40 | * |
||
41 | * @return array |
||
42 | */ |
||
43 | View Code Duplication | public static function getStatusToSelectMap() |
|
0 ignored issues
–
show
|
|||
44 | { |
||
45 | return [ |
||
46 | AnimeWatchingStatus::WATCHING => 'Currently Watching', |
||
47 | AnimeWatchingStatus::PLAN_TO_WATCH => 'Plan to Watch', |
||
48 | AnimeWatchingStatus::COMPLETED => 'Completed', |
||
49 | AnimeWatchingStatus::ON_HOLD => 'On Hold', |
||
50 | AnimeWatchingStatus::DROPPED => 'Dropped' |
||
51 | ]; |
||
52 | } |
||
53 | |||
54 | /** |
||
55 | * Map of Kitsu Manga status to label for select menus |
||
56 | * |
||
57 | * @return array |
||
58 | */ |
||
59 | View Code Duplication | public static function getStatusToMangaSelectMap() |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
60 | { |
||
61 | return [ |
||
62 | MangaReadingStatus::READING => 'Currently Reading', |
||
63 | MangaReadingStatus::PLAN_TO_READ => 'Plan to Read', |
||
64 | MangaReadingStatus::COMPLETED => 'Completed', |
||
65 | MangaReadingStatus::ON_HOLD => 'On Hold', |
||
66 | MangaReadingStatus::DROPPED => 'Dropped' |
||
67 | ]; |
||
68 | } |
||
69 | |||
70 | /** |
||
71 | * Determine whether an anime is airing, finished airing, or has not yet aired |
||
72 | * |
||
73 | * @param string $startDate |
||
0 ignored issues
–
show
Should the type for parameter
$startDate not be null|string ?
This check looks for It makes a suggestion as to what type it considers more descriptive. Most often this is a case of a parameter that can be null in addition to its declared types. ![]() |
|||
74 | * @param string $endDate |
||
0 ignored issues
–
show
Should the type for parameter
$endDate not be null|string ?
This check looks for It makes a suggestion as to what type it considers more descriptive. Most often this is a case of a parameter that can be null in addition to its declared types. ![]() |
|||
75 | * @return string |
||
76 | */ |
||
77 | public static function getAiringStatus(string $startDate = null, string $endDate = null): string |
||
78 | { |
||
79 | $startAirDate = new DateTimeImmutable($startDate ?? 'tomorrow'); |
||
80 | $endAirDate = new DateTimeImmutable($endDate ?? 'next year'); |
||
81 | $now = new DateTimeImmutable(); |
||
82 | |||
83 | $isDoneAiring = $now > $endAirDate; |
||
84 | $isCurrentlyAiring = ($now > $startAirDate) && ! $isDoneAiring; |
||
85 | |||
86 | switch (true) |
||
87 | { |
||
88 | case $isCurrentlyAiring: |
||
0 ignored issues
–
show
case statements should be defined using a colon.
As per the PSR-2 coding standard, case statements should not be wrapped in curly braces.
There is no need for braces, since each case is terminated by the next There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages. switch ($expr) {
case "A": { //wrong
doSomething();
break;
}
case "B"; //wrong
doSomething();
break;
case "C": //right
doSomething();
break;
}
To learn more about the PSR-2 coding standard, please refer to the PHP-Fig. ![]() |
|||
89 | return AnimeAiringStatus::AIRING; |
||
90 | |||
91 | case $isDoneAiring: |
||
0 ignored issues
–
show
case statements should be defined using a colon.
As per the PSR-2 coding standard, case statements should not be wrapped in curly braces.
There is no need for braces, since each case is terminated by the next There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages. switch ($expr) {
case "A": { //wrong
doSomething();
break;
}
case "B"; //wrong
doSomething();
break;
case "C": //right
doSomething();
break;
}
To learn more about the PSR-2 coding standard, please refer to the PHP-Fig. ![]() |
|||
92 | return AnimeAiringStatus::FINISHED_AIRING; |
||
93 | |||
94 | default: |
||
0 ignored issues
–
show
DEFAULT statements must be defined using a colon
As per the PSR-2 coding standard, default statements should not be wrapped in curly braces. switch ($expr) {
default: { //wrong
doSomething();
break;
}
}
switch ($expr) {
default: //right
doSomething();
break;
}
To learn more about the PSR-2 coding standard, please refer to the PHP-Fig. ![]() |
|||
95 | return AnimeAiringStatus::NOT_YET_AIRED; |
||
96 | } |
||
97 | } |
||
98 | |||
99 | /** |
||
100 | * Get the name and logo for the streaming service of the current link |
||
101 | * |
||
102 | * @param string $hostname |
||
0 ignored issues
–
show
Should the type for parameter
$hostname not be null|string ?
This check looks for It makes a suggestion as to what type it considers more descriptive. Most often this is a case of a parameter that can be null in addition to its declared types. ![]() |
|||
103 | * @return array |
||
104 | */ |
||
105 | protected static function getServiceMetaData(string $hostname = null): array |
||
106 | { |
||
107 | switch($hostname) |
||
108 | { |
||
109 | case 'www.crunchyroll.com': |
||
110 | return [ |
||
111 | 'name' => 'Crunchyroll', |
||
112 | 'link' => true, |
||
113 | 'logo' => '<svg class="streaming-logo" viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg"><g fill="#F78B24" fill-rule="evenodd"><path d="M22.549 49.145c-.815-.077-2.958-.456-3.753-.663-6.873-1.79-12.693-6.59-15.773-13.009C1.335 31.954.631 28.807.633 24.788c.003-4.025.718-7.235 2.38-10.686 1.243-2.584 2.674-4.609 4.706-6.66 3.8-3.834 8.614-6.208 14.067-6.936 1.783-.239 5.556-.161 7.221.148 3.463.642 6.571 1.904 9.357 3.797 5.788 3.934 9.542 9.951 10.52 16.861.21 1.48.332 4.559.19 4.816-.077.14-.117-.007-.167-.615-.25-3.015-1.528-6.66-3.292-9.388C40.253 7.836 30.249 4.32 20.987 7.467c-7.15 2.43-12.522 8.596-13.997 16.06-.73 3.692-.51 7.31.658 10.882a21.426 21.426 0 0 0 13.247 13.518c1.475.515 3.369.944 4.618 1.047 1.496.122 1.119.239-.727.224-1.006-.008-2.013-.032-2.237-.053z"></path><path d="M27.685 46.1c-7.731-.575-14.137-6.455-15.474-14.204-.243-1.41-.29-4.047-.095-5.345 1.16-7.706 6.97-13.552 14.552-14.639 1.537-.22 4.275-.143 5.746.162 1.28.266 2.7.737 3.814 1.266l.865.411-.814.392c-2.936 1.414-4.748 4.723-4.323 7.892.426 3.173 2.578 5.664 5.667 6.56 1.112.322 2.812.322 3.925 0 1.438-.417 2.566-1.1 3.593-2.173.346-.362.652-.621.68-.576.027.046.106.545.176 1.11.171 1.395.07 4.047-.204 5.371-.876 4.218-3.08 7.758-6.463 10.374-3.2 2.476-7.434 3.711-11.645 3.399z"></path></g></svg>' |
||
0 ignored issues
–
show
|
|||
114 | ]; |
||
115 | |||
116 | case 'www.funimation.com': |
||
117 | return [ |
||
118 | 'name' => 'Funimation', |
||
119 | 'link' => true, |
||
120 | 'logo' => '<svg class="streaming-logo" viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg"><path d="M24.066.017a24.922 24.922 0 0 1 13.302 3.286 25.098 25.098 0 0 1 7.833 7.058 24.862 24.862 0 0 1 4.207 9.575c.82 4.001.641 8.201-.518 12.117a24.946 24.946 0 0 1-4.868 9.009 24.98 24.98 0 0 1-7.704 6.118 24.727 24.727 0 0 1-10.552 2.718A24.82 24.82 0 0 1 13.833 47.3c-5.815-2.872-10.408-8.107-12.49-14.25-2.162-6.257-1.698-13.375 1.303-19.28C5.483 8.07 10.594 3.55 16.602 1.435A24.94 24.94 0 0 1 24.066.017zm-8.415 33.31c.464 2.284 1.939 4.358 3.99 5.48 2.174 1.217 4.765 1.444 7.202 1.181 2.002-.217 3.986-.992 5.455-2.397 1.173-1.151 2.017-2.648 2.33-4.267-1.189-.027-2.378 0-3.566-.03-.568.082-1.137-.048-1.705.014-1.232.012-2.465.003-3.697-.01-.655.066-1.309-.035-1.963.013-1.166-.053-2.334.043-3.5-.025-1.515.08-3.03-.035-4.546.042z" fill="#411299" fill-rule="evenodd"></path></svg>' |
||
0 ignored issues
–
show
|
|||
121 | ]; |
||
122 | |||
123 | case 'www.hulu.com': |
||
124 | return [ |
||
125 | 'name' => 'Hulu', |
||
126 | 'link' => true, |
||
127 | 'logo' => '<svg class="streaming-logo" viewBox="0 0 34 50" xmlns="http://www.w3.org/2000/svg"><path d="M22.222 13.889h-11.11V0H0v50h11.111V27.778c0-1.39 1.111-2.778 2.778-2.778h5.555c1.39 0 2.778 1.111 2.778 2.778V50h11.111V25c0-6.111-5-11.111-11.11-11.111z" fill="#8BC34A" fill-rule="evenodd"></path></svg>' |
||
0 ignored issues
–
show
|
|||
128 | ]; |
||
129 | |||
130 | // Default to Netflix, because the API links are broken, |
||
131 | // and there's no other real identifier for Netflix |
||
132 | default: |
||
133 | return [ |
||
134 | 'name' => 'Netflix', |
||
135 | 'link' => false, |
||
136 | 'logo' => '<svg class="streaming-logo" viewBox="0 0 26 50" xmlns="http://www.w3.org/2000/svg"><path d="M.057.258C2.518.253 4.982.263 7.446.253c2.858 7.76 5.621 15.556 8.456 23.324.523 1.441 1.003 2.897 1.59 4.312.078-9.209.01-18.42.034-27.631h7.763v46.36c-2.812.372-5.637.627-8.457.957-1.203-3.451-2.396-6.902-3.613-10.348-1.796-5.145-3.557-10.302-5.402-15.428.129 8.954.015 17.912.057 26.871-2.603.39-5.227.637-7.815 1.119C.052 33.279.06 16.768.057.258z" fill="#E21221" fill-rule="evenodd"></path></svg>' |
||
0 ignored issues
–
show
|
|||
137 | ]; |
||
138 | } |
||
139 | } |
||
140 | |||
141 | /** |
||
142 | * Reorganize streaming links |
||
143 | * |
||
144 | * @param array $included |
||
145 | * @return array |
||
146 | */ |
||
147 | public static function parseStreamingLinks(array $included): array |
||
148 | { |
||
149 | if ( ! array_key_exists('streamingLinks', $included)) |
||
150 | { |
||
151 | return []; |
||
152 | } |
||
153 | |||
154 | $links = []; |
||
155 | |||
156 | View Code Duplication | foreach ($included['streamingLinks'] as $streamingLink) |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
157 | { |
||
158 | $host = parse_url($streamingLink['url'], \PHP_URL_HOST); |
||
159 | |||
160 | $links[] = [ |
||
161 | 'meta' => static::getServiceMetaData($host), |
||
0 ignored issues
–
show
It seems like
$host defined by parse_url($streamingLink['url'], \PHP_URL_HOST) on line 158 can also be of type false ; however, Aviat\AnimeClient\API\Kitsu::getServiceMetaData() does only seem to accept null|string , did you maybe forget to handle an error condition?
This check looks for type mismatches where the missing type is Consider the follow example <?php
function getDate($date)
{
if ($date !== null) {
return new DateTime($date);
}
return false;
}
This function either returns a new ![]() |
|||
162 | 'link' => $streamingLink['url'], |
||
163 | 'subs' => $streamingLink['subs'], |
||
164 | 'dubs' => $streamingLink['dubs'] |
||
165 | ]; |
||
166 | } |
||
167 | |||
168 | return $links; |
||
169 | } |
||
170 | |||
171 | /** |
||
172 | * Reorganize streaming links for the current list item |
||
173 | * |
||
174 | * @param array $included |
||
175 | * @return array |
||
176 | */ |
||
177 | public static function parseListItemStreamingLinks(array $included, string $animeId): array |
||
178 | { |
||
179 | // Anime lists have a different structure to search through |
||
180 | if (array_key_exists('anime', $included) && ! array_key_exists('streamingLinks', $included)) |
||
181 | { |
||
182 | $links = []; |
||
183 | $anime = $included['anime'][$animeId]; |
||
184 | |||
185 | if (count($anime['relationships']['streamingLinks']) > 0) |
||
186 | { |
||
187 | View Code Duplication | foreach ($anime['relationships']['streamingLinks'] as $streamingLink) |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
188 | { |
||
189 | $host = parse_url($streamingLink['url'], \PHP_URL_HOST); |
||
190 | |||
191 | $links[] = [ |
||
192 | 'meta' => static::getServiceMetaData($host), |
||
0 ignored issues
–
show
It seems like
$host defined by parse_url($streamingLink['url'], \PHP_URL_HOST) on line 189 can also be of type false ; however, Aviat\AnimeClient\API\Kitsu::getServiceMetaData() does only seem to accept null|string , did you maybe forget to handle an error condition?
This check looks for type mismatches where the missing type is Consider the follow example <?php
function getDate($date)
{
if ($date !== null) {
return new DateTime($date);
}
return false;
}
This function either returns a new ![]() |
|||
193 | 'link' => $streamingLink['url'], |
||
194 | 'subs' => $streamingLink['subs'], |
||
195 | 'dubs' => $streamingLink['dubs'] |
||
196 | ]; |
||
197 | } |
||
198 | } |
||
199 | |||
200 | return $links; |
||
201 | } |
||
202 | |||
203 | return []; |
||
204 | } |
||
205 | |||
206 | /** |
||
207 | * Filter out duplicate and very similar names from |
||
208 | * |
||
209 | * @param array $data The 'attributes' section of the api data response |
||
210 | * @return array List of alternate titles |
||
211 | */ |
||
212 | public static function filterTitles(array $data): array |
||
213 | { |
||
214 | // The 'canonical' title is always returned |
||
215 | $valid = [$data['canonicalTitle']]; |
||
216 | |||
217 | if (array_key_exists('titles', $data)) |
||
218 | { |
||
219 | foreach($data['titles'] as $alternateTitle) |
||
220 | { |
||
221 | if (self::titleIsUnique($alternateTitle, $valid)) |
||
222 | { |
||
223 | $valid[] = $alternateTitle; |
||
224 | } |
||
225 | } |
||
226 | } |
||
227 | |||
228 | return $valid; |
||
229 | } |
||
230 | |||
231 | /** |
||
232 | * Determine if an alternate title is unique enough to list |
||
233 | * |
||
234 | * @param string $title |
||
0 ignored issues
–
show
Should the type for parameter
$title not be null|string ?
This check looks for It makes a suggestion as to what type it considers more descriptive. Most often this is a case of a parameter that can be null in addition to its declared types. ![]() |
|||
235 | * @param array $existingTitles |
||
236 | * @return bool |
||
237 | */ |
||
238 | private static function titleIsUnique(string $title = null, array $existingTitles): bool |
||
0 ignored issues
–
show
Parameters which have default values should be placed at the end.
If you place a parameter with a default value before a parameter with a default value, the default value of the first parameter will never be used as it will always need to be passed anyway: // $a must always be passed; it's default value is never used.
function someFunction($a = 5, $b) { }
![]() |
|||
239 | { |
||
240 | if (empty($title)) |
||
241 | { |
||
242 | return false; |
||
243 | } |
||
244 | |||
245 | foreach($existingTitles as $existing) |
||
246 | { |
||
247 | $isSubset = stripos($existing, $title) !== FALSE; |
||
248 | $diff = levenshtein($existing, $title); |
||
249 | $onlydifferentCase = (mb_strtolower($existing) === mb_strtolower($title)); |
||
250 | |||
251 | if ($diff < 3 || $isSubset || $onlydifferentCase) |
||
252 | { |
||
253 | return false; |
||
254 | } |
||
255 | } |
||
256 | |||
257 | return true; |
||
258 | } |
||
259 | } |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.