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 |
||
0 ignored issues
–
show
|
|||
2 | |||
3 | /** |
||
4 | * Created by PhpStorm. |
||
5 | * User: steve |
||
6 | * Date: 4/17/2018 |
||
7 | * Time: 10:09 PM |
||
8 | */ |
||
9 | |||
10 | if ( !class_exists("FooGallery_Pro_Video_YouTube") ){ |
||
11 | |||
12 | require_once dirname(__FILE__) . '/class-foogallery-pro-video-base.php'; |
||
13 | |||
14 | class FooGallery_Pro_Video_YouTube extends FooGallery_Pro_Video_Base { |
||
0 ignored issues
–
show
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.
You can fix this by adding a namespace to your class: namespace YourVendor;
class YourClass { }
When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries. ![]() |
|||
15 | |||
16 | // region Properties |
||
17 | |||
18 | /** |
||
19 | * The regular expression used to match a YouTube video URL. |
||
20 | * @var string |
||
21 | */ |
||
22 | public $regex_pattern; |
||
23 | |||
24 | // endregion |
||
25 | |||
26 | function __construct() { |
||
0 ignored issues
–
show
|
|||
27 | $this->regex_pattern = '/(www\.)?youtube|youtu\.be/i'; |
||
28 | } |
||
29 | |||
30 | /** |
||
31 | * Takes a URL and checks if this class handles it. |
||
32 | * |
||
33 | * @param string $url The URL to check. |
||
34 | * @param array &$matches Optional. If matches is provided, it is passed to the `preg_match` call used to check the URL. |
||
35 | * @return int Returns 1 if the URL is handled, 0 if it is not, or FALSE if an error occurred. |
||
36 | */ |
||
37 | function handles($url, &$matches = array()){ |
||
0 ignored issues
–
show
|
|||
38 | return preg_match($this->regex_pattern, $url, $matches); |
||
39 | } |
||
40 | |||
41 | /** |
||
42 | * Takes a string value and determines whether or not it is a YouTube video id. |
||
43 | * |
||
44 | * @param string $value The value to test. |
||
45 | * @return bool |
||
46 | * |
||
47 | * @see https://stackoverflow.com/questions/6180138/whats-the-maximum-length-of-a-youtube-video-id |
||
48 | * |
||
49 | * @description At present YouTube's video ids always have 11 characters, while this is not |
||
50 | * guaranteed it should stay that way until all 73,786,976,294,838,206,464 possible combinations |
||
51 | * are exhausted. |
||
52 | */ |
||
53 | function is_video_id($value) { |
||
0 ignored issues
–
show
|
|||
54 | return !empty($value) && is_string($value) && strlen($value) === 11 && strpos($value, " ") === false && $this->url_exists("https://www.youtube.com/watch?v=" . $value); |
||
55 | } |
||
56 | |||
57 | /** |
||
58 | * Takes a string value and determines whether or not it is a YouTube playlist id. |
||
59 | * |
||
60 | * @param string $value The value to test. |
||
61 | * @return bool |
||
62 | * |
||
63 | * @description At present YouTube's playlist ids always have 34 characters and begin with "PL", while |
||
64 | * this is not guaranteed it should stay that way until all possible combinations are exhausted. |
||
65 | */ |
||
66 | function is_playlist_id($value) { |
||
0 ignored issues
–
show
|
|||
67 | return !empty($value) && is_string($value) && strlen($value) === 34 && strpos($value, " ") === false && $this->url_exists("https://www.youtube.com/playlist?list=" . $value); |
||
68 | } |
||
69 | |||
70 | /** |
||
71 | * Takes the supplied query and optional page number, determines the correct method to call and then returns its' data. |
||
72 | * |
||
73 | * @param string $query The query value to parse. |
||
74 | * @param int [$page=1] If this is a search query the page number could also be supplied. |
||
75 | * @param int [$offset=0] The number of items already retrieved for the query. |
||
76 | * @return array |
||
77 | */ |
||
78 | function query($query, $page = 1, $offset = 0) { |
||
0 ignored issues
–
show
|
|||
79 | if ($this->is_playlist_id($query)) { |
||
80 | return $this->fetch_playlist($query); |
||
81 | } |
||
82 | |||
83 | if ($this->is_video_id($query)) { |
||
84 | return $this->fetch_video($query); |
||
85 | } |
||
86 | |||
87 | // if we get here we assume the query is a search |
||
88 | return $this->search($query, $page, $offset); |
||
89 | } |
||
90 | |||
91 | /** |
||
92 | * Takes the supplied YouTube url and attempts to fetch its' data. |
||
93 | * |
||
94 | * @description At present this method supports the following url patterns: |
||
95 | * |
||
96 | * - http(s)://www.youtube.com/watch?v=[ID] |
||
97 | * - http(s)://youtu.be/[ID] |
||
98 | * - http(s)://www.youtube.com/embed/[ID] |
||
99 | * - http(s)://www.youtube.com/playlist?list=[ID] |
||
100 | * |
||
101 | * @param string $url The url to fetch the data for. |
||
102 | * @return array |
||
103 | */ |
||
104 | function fetch($url) { |
||
0 ignored issues
–
show
|
|||
105 | // make sure we're dealing with a YouTube url in case this method is called externally |
||
106 | if (preg_match($this->regex_pattern, $url)) { |
||
107 | $query_string = array(); |
||
108 | $url_parts = parse_url($url); |
||
109 | // check if we were supplied a query string i.e. anything after ? |
||
110 | if (!empty($url_parts["query"])) { |
||
111 | // if we have a query string then parse it into an array of key value pairs |
||
112 | parse_str($url_parts["query"], $query_string); |
||
113 | } |
||
114 | |||
115 | // check if we are dealing with a playlist url |
||
116 | if (preg_match('/(www\.)?youtube\.com\/playlist/i', $url)) { |
||
117 | return $this->fetch_playlist($query_string["list"]); |
||
118 | } |
||
119 | |||
120 | // otherwise we are dealing with one of the single video supported formats |
||
121 | $id = $query_string["v"]; |
||
122 | // if the id does not exist in the query string then we are dealing with a YouTube |
||
123 | // short or embed url so grab the id from the last part of the url |
||
124 | if (empty($id) && preg_match('/(www\.)?youtube\.com\/embed|youtu\.be/i', $url)) { |
||
125 | // here we split the url on all forward-slashes |
||
126 | $parts = explode("/", $url); |
||
127 | // then grab the last part to use as the id |
||
128 | $id = end($parts); |
||
129 | } |
||
130 | |||
131 | return $this->fetch_video($id); |
||
132 | } |
||
133 | return $this->error_response("Unrecognized YouTube url."); |
||
134 | } |
||
135 | |||
136 | /** |
||
137 | * Takes the supplied YouTube playlist id and fetches its' data. |
||
138 | * |
||
139 | * @param string $id The playlist id to fetch. |
||
140 | * @return array( |
||
0 ignored issues
–
show
The doc-type
array( could not be parsed: Expected "|" or "end of type", but got "(" at position 5. (view supported doc-types)
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types. ![]() |
|||
141 | * "mode" => "playlist", |
||
142 | * "thumbnail" => string, |
||
143 | * "title" => string, |
||
144 | * "description" => string, |
||
145 | * "videos" => array, |
||
146 | * "total" => number |
||
147 | * ) |
||
148 | * @return array( |
||
0 ignored issues
–
show
The doc-type
array( could not be parsed: Expected "|" or "end of type", but got "(" at position 5. (view supported doc-types)
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types. ![]() |
|||
149 | * "mode" => "error", |
||
150 | * "message" => string |
||
151 | * ) |
||
152 | */ |
||
153 | function fetch_playlist($id) { |
||
0 ignored issues
–
show
|
|||
154 | |||
155 | if (!$this->is_playlist_id($id)) { |
||
156 | return $this->error_response("Invalid playlist id supplied."); |
||
157 | } |
||
158 | |||
159 | // we have as valid an id as we can hope for until we make the actual request so request it |
||
160 | $url = "https://www.youtube.com/list_ajax?style=json&action_get_list=true&list=" . $id; |
||
161 | // get the json object from the supplied url |
||
162 | $json = $this->json_get($url); |
||
163 | |||
164 | // if an error occurred return it |
||
165 | if ($this->is_error($json)) { |
||
166 | return $json; |
||
167 | } |
||
168 | |||
169 | // do basic validation on the json object |
||
170 | if (empty($json) || empty($json->video) || !is_array($json->video)) { |
||
171 | return $this->error_response("No videos in response."); |
||
172 | } |
||
173 | |||
174 | // if we get here we need to build a response to return to the frontend |
||
175 | $response = array( |
||
176 | "mode" => "playlist", |
||
177 | "id" => $id, |
||
178 | "total" => 0, |
||
179 | "page" => 1, |
||
180 | "nextPage" => 0, |
||
181 | "offset" => 0, |
||
182 | "videos" => array() |
||
183 | ); |
||
184 | |||
185 | // iterate each of the returned videos and add them to the response in our desired format |
||
186 | foreach ($json->video as $video) { |
||
187 | if (!empty($video->thumbnail) && !empty($video->encrypted_id) && !empty($video->title)) { |
||
188 | $response["videos"][] = array( |
||
189 | "provider" => "youtube", |
||
190 | "id" => $video->encrypted_id, |
||
191 | "url" => "https://www.youtube.com/embed/" . $video->encrypted_id, |
||
192 | "thumbnail" => $video->thumbnail, |
||
193 | "title" => $video->title, |
||
194 | "description" => !empty($video->description) ? $video->description : "" |
||
195 | ); |
||
196 | } |
||
197 | } |
||
198 | |||
199 | // update the offset and total with the current video count |
||
200 | $response["offset"] = $response["total"] = count($response["videos"]); |
||
201 | |||
202 | // if we have no videos then none were valid |
||
203 | if ($response["total"] === 0) { |
||
204 | return $this->error_response("No valid videos in response."); |
||
205 | } |
||
206 | |||
207 | return $response; |
||
208 | } |
||
209 | |||
210 | /** |
||
211 | * Takes the supplied YouTube video id and fetches its' data. |
||
212 | * |
||
213 | * @param string $id The video id to fetch. |
||
214 | * @return array( |
||
0 ignored issues
–
show
The doc-type
array( could not be parsed: Expected "|" or "end of type", but got "(" at position 5. (view supported doc-types)
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types. ![]() |
|||
215 | * "mode" => "video", |
||
216 | * "url" => string, |
||
217 | * "thumbnail" => string, |
||
218 | * "title" => string, |
||
219 | * "description" => string |
||
220 | * ) |
||
221 | * @return array( |
||
0 ignored issues
–
show
The doc-type
array( could not be parsed: Expected "|" or "end of type", but got "(" at position 5. (view supported doc-types)
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types. ![]() |
|||
222 | * "mode" => "error", |
||
223 | * "message" => string |
||
224 | * ) |
||
225 | */ |
||
226 | function fetch_video($id) { |
||
0 ignored issues
–
show
|
|||
227 | |||
228 | if (!$this->is_video_id($id)) { |
||
229 | return $this->error_response("Invalid video id supplied."); |
||
230 | } |
||
231 | |||
232 | // we have as valid an id as we can hope for until we make the actual request so request it |
||
233 | $url = "http://www.youtube.com/oembed?url=" . urlencode("https://www.youtube.com/watch?v=" . $id); |
||
234 | // get the json object from the supplied url |
||
235 | $json = $this->json_get($url); |
||
236 | |||
237 | // if an error occurred return it |
||
238 | if ($this->is_error($json)) { |
||
239 | return $json; |
||
240 | } |
||
241 | |||
242 | // do basic validation on the parsed object |
||
243 | if (empty($json) || empty($json->thumbnail_url) || empty($json->title)) { |
||
244 | return $this->error_response("No video in response."); |
||
245 | } |
||
246 | |||
247 | $response = array( |
||
248 | "mode" => "single", |
||
249 | "videos" => array() |
||
250 | ); |
||
251 | |||
252 | $response["videos"][] = array( |
||
253 | "provider" => "youtube", |
||
254 | "id" => $id, |
||
255 | "url" => "https://www.youtube.com/embed/" . $id, |
||
256 | "thumbnail" => $json->thumbnail_url, |
||
257 | "title" => $json->title, |
||
258 | "description" => !empty($json->description) ? $json->description : "" |
||
259 | ); |
||
260 | |||
261 | return $response; |
||
262 | } |
||
263 | |||
264 | /** |
||
265 | * Takes the supplied query and optional page number and performs a YouTube search. |
||
266 | * |
||
267 | * @param string $query The query to use as a search term. |
||
268 | * @param int [$page=1] The page number to retrieve. |
||
269 | * @param int [$offset=0] The number of items already retrieved for the query. |
||
270 | * @return array( |
||
0 ignored issues
–
show
The doc-type
array( could not be parsed: Expected "|" or "end of type", but got "(" at position 5. (view supported doc-types)
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types. ![]() |
|||
271 | * "mode" => "search", |
||
272 | * "total" => number, |
||
273 | * "page" => number, |
||
274 | * "offset" => number, |
||
275 | * "nextPage" => number, |
||
276 | * "videos" => array( |
||
277 | * array( |
||
278 | * "provider" => "youtube", |
||
279 | * "id" => string, |
||
280 | * "url" => string, |
||
281 | * "thumbnail" => string, |
||
282 | * "title" => string, |
||
283 | * "description" => string |
||
284 | * ) |
||
285 | * ) |
||
286 | * ) |
||
287 | * @return array( |
||
0 ignored issues
–
show
The doc-type
array( could not be parsed: Expected "|" or "end of type", but got "(" at position 5. (view supported doc-types)
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types. ![]() |
|||
288 | * "mode" => "error", |
||
289 | * "title" => string, |
||
290 | * "message" => string |
||
291 | * ) |
||
292 | */ |
||
293 | function search($query, $page = 1, $offset = 0) { |
||
0 ignored issues
–
show
|
|||
294 | if (empty($query)) { |
||
295 | return $this->error_response("Empty search query."); |
||
296 | } |
||
297 | |||
298 | if ($query === "!ERROR"){ |
||
299 | return $this->error_response("Dummy error."); |
||
300 | } |
||
301 | |||
302 | $url = "https://www.youtube.com/search_ajax?style=json&search_query=" . urlencode($query) . "&page=" . $page; |
||
303 | // get the json object from the supplied url |
||
304 | $json = $this->json_get($url); |
||
305 | |||
306 | // if an error occurred return it |
||
307 | if ($this->is_error($json)) { |
||
308 | return $json; |
||
309 | } |
||
310 | |||
311 | // do basic validation on the parsed object |
||
312 | if (empty($json) || empty($json->hits) || empty($json->video) || !is_array($json->video)) { |
||
313 | return $this->error_response("No videos in response."); |
||
314 | } |
||
315 | |||
316 | // if we get here we need to build a response to return to the frontend |
||
317 | $response = array( |
||
318 | "mode" => "search", |
||
319 | "total" => $json->hits, |
||
320 | "page" => $page, |
||
321 | "offset" => $offset, |
||
322 | "nextPage" => 0, |
||
323 | "videos" => array() |
||
324 | ); |
||
325 | |||
326 | // iterate each of the returned videos and add them to the response in our desired format |
||
327 | foreach ($json->video as $video) { |
||
328 | if (!empty($video->thumbnail) && !empty($video->encrypted_id) && !empty($video->title)) { |
||
329 | $response["videos"][] = array( |
||
330 | "provider" => "youtube", |
||
331 | "id" => $video->encrypted_id, |
||
332 | "url" => "https://www.youtube.com/embed/" . $video->encrypted_id, |
||
333 | "thumbnail" => $video->thumbnail, |
||
334 | "title" => $video->title, |
||
335 | "description" => !empty($video->description) ? $video->description : "" |
||
336 | ); |
||
337 | } |
||
338 | } |
||
339 | |||
340 | // if we have no videos then none of the videos were valid |
||
341 | if ($response["total"] === 0) { |
||
342 | return $this->error_response("No valid videos in response."); |
||
343 | } |
||
344 | |||
345 | $response["offset"] = $response["offset"] + count($response["videos"]); |
||
346 | if ($response["total"] > $response["offset"]){ |
||
347 | $response["nextPage"] = $response["page"] + 1; |
||
348 | } |
||
349 | |||
350 | return $response; |
||
351 | } |
||
352 | |||
353 | } |
||
354 | |||
355 | } |
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.