Completed
Push — master ( af4d7b...afc361 )
by Angus
04:12
created

MangaPanda   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 51
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
dl 0
loc 51
ccs 17
cts 17
cp 1
rs 10
c 0
b 0
f 0
wmc 9
lcom 1
cbo 1

5 Methods

Rating   Name   Duplication   Size   Complexity  
A getFullTitleURL() 0 3 1
A getChapterData() 0 6 1
A isValidTitleURL() 0 6 2
A isValidChapter() 0 5 2
B getTitleData() 0 26 3
1
<?php declare(strict_types=1); defined('BASEPATH') OR exit('No direct script access allowed');
2
3
abstract class Site_Model extends CI_Model {
4 102
	public function __construct() {
5 102
		parent::__construct();
6
7 102
		$this->load->database();
8 102
	}
9
10
	abstract public function getFullTitleURL(string $title_url) : string;
11
12
	abstract public function getChapterData(string $title_url, string $chapter) : array;
13
14
	//TODO: When ci-phpunit-test supports PHP Parser 3.x, add " : ?array"
15
	abstract public function getTitleData(string $title_url);
16
17
	abstract public function isValidTitleURL(string $title_url) : bool;
18
	abstract public function isValidChapter(string $chapter) : bool;
19
20 14
	final protected function get_content(string $url, string $cookie_string = "", string $cookiejar_path = "", bool $follow_redirect = FALSE) {
21 14
		$ch = curl_init();
22 14
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
23 14
		curl_setopt($ch, CURLOPT_ENCODING , "gzip");
24
		//curl_setopt($ch, CURLOPT_VERBOSE, 1);
25 14
		curl_setopt($ch, CURLOPT_HEADER, 1);
26
27 14
		if($follow_redirect)        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
28
29 14
		if(!empty($cookie_string))  curl_setopt($ch, CURLOPT_COOKIE, $cookie_string);
30 14
		if(!empty($cookiejar_path)) curl_setopt($ch, CURLOPT_COOKIEFILE, $cookiejar_path);
31
32
		//Some sites check the useragent for stuff, use a pre-defined user-agent to avoid stuff.
33 14
		curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2824.0 Safari/537.36');
34
35
		//TODO: Check in a while if this being enabled still causes issues
36
		//curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); //FIXME: This isn't safe, but it allows us to grab SSL URLs
37
38 14
		curl_setopt($ch, CURLOPT_URL, $url);
39 14
		$response = curl_exec($ch);
40
41 14
		$status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
42 14
		$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
43 14
		$header      = http_parse_headers(substr($response, 0, $header_size));
44 14
		$body        = substr($response, $header_size);
45 14
		curl_close($ch);
46
47
		return [
48 14
			'headers'      => $header,
49 14
			'status_code' => $status_code,
50 14
			'body'        => $body
51
		];
52
	}
53
54
	/**
55
	 * @param array  $content
56
	 * @param string $site
57
	 * @param string $title_url
58
	 * @param string $node_title_string
59
	 * @param string $node_row_string
60
	 * @param string $node_latest_string
61
	 * @param string $node_chapter_string
62
	 * @param string $failure_string
63
	 *
64
	 * @return DOMElement[]|false
65
	 */
66 7
	final protected function parseTitleDataDOM(
67
		array $content, string $site, string $title_url,
68
		string $node_title_string, string $node_row_string,
69
		string $node_latest_string, string $node_chapter_string,
70
		string $failure_string = "") {
71
		//list('headers' => $headers, 'status_code' => $status_code, 'body' => $data) = $content; //TODO: PHP 7.1
72 7
		$headers     = $content['headers'];
0 ignored issues
show
Unused Code introduced by
$headers is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
73 7
		$status_code = $content['status_code'];
74 7
		$data        = $content['body'];
75
76 7
		if(!($status_code >= 200 && $status_code < 300)) {
77 3
			log_message('error', "{$site} : {$title_url} | Bad Status Code ({$status_code})");
78 4
		} else if(empty($data)) {
79
			log_message('error', "{$site} : {$title_url} | Data is empty? (Status code: {$status_code})");
80 4
		} else if($failure_string !== "" && strpos($data, $failure_string) !== FALSE) {
81 1
			log_message('error', "{$site} : {$title_url} | Failure string matched");
82
		} else {
83 3
			$data = $this->cleanTitleDataDOM($data); //This allows us to clean the DOM prior to parsing. It's faster to grab the only part we need THEN parse it.
84
85 3
			$dom = new DOMDocument();
86 3
			libxml_use_internal_errors(TRUE);
87 3
			$dom->loadHTML($data);
88 3
			libxml_use_internal_errors(FALSE);
89
90 3
			$xpath = new DOMXPath($dom);
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 7 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
91 3
			$nodes_title = $xpath->query($node_title_string);
92 3
			$nodes_row   = $xpath->query($node_row_string);
93 3
			if($nodes_title->length === 1 && $nodes_row->length === 1) {
94 3
				$firstRow      = $nodes_row->item(0);
95 3
				$nodes_latest  = $xpath->query($node_latest_string,  $firstRow);
96 3
				$nodes_chapter = $xpath->query($node_chapter_string, $firstRow);
97
98 3
				if($nodes_latest->length === 1 && $nodes_chapter->length === 1) {
99
					return [
100 3
						'nodes_title'   => $nodes_title->item(0),
101 3
						'nodes_latest'  => $nodes_latest->item(0),
102 3
						'nodes_chapter' => $nodes_chapter->item(0)
103
					];
104
				} else {
105
					log_message('error', "{$site} : {$title_url} | Invalid amount of nodes (LATEST: {$nodes_latest->length} | CHAPTER: {$nodes_chapter->length})");
106
				}
107
			} else {
108
				log_message('error', "{$site} : {$title_url} | Invalid amount of nodes (TITLE: {$nodes_title->length} | ROW: {$nodes_row->length})");
109
			}
110
		}
111 4
		return FALSE;
112
	}
113
114 3
	public function cleanTitleDataDOM(string $data) : string {
115 3
		return $data;
116
	}
117
}
118
class Sites_Model extends CI_Model {
119
	public $MangaFox;
120
	public $MangaHere;
121
	public $Batoto;
122
	public $DynastyScans;
123
	public $MangaPanda;
124
	public $MangaStream;
125
	public $WebToons;
126
	public $KissManga;
127
	public $KireiCake;
128
	public $GameOfScanlation;
129
	public $MangaCow;
130
	public $SeaOtterScans;
131
	public $HelveticaScans;
132
	public $SenseScans;
133
134 102
	public function __construct() {
135 102
		parent::__construct();
136
137 102
		$this->MangaFox         = new MangaFox();
138 102
		$this->MangaHere        = new MangaHere();
139 102
		$this->Batoto           = new Batoto();
140 102
		$this->DynastyScans     = new DynastyScans();
141 102
		$this->MangaPanda       = new MangaPanda();
142 102
		$this->MangaStream      = new MangaStream();
143 102
		$this->WebToons         = new WebToons();
144 102
		$this->KissManga        = new KissManga();
145 102
		$this->KireiCake        = new KireiCake();
146 102
		$this->GameOfScanlation = new GameOfScanlation();
147 102
		$this->MangaCow         = new MangaCow();
148 102
		$this->SeaOtterScans    = new SeaOtterScans();
149 102
		$this->HelveticaScans   = new HelveticaScans();
150 102
		$this->SenseScans       = new SenseScans();
151 102
	}
152
}
153
154
class MangaFox extends Site_Model {
155 2
	public function getFullTitleURL(string $title_url) : string {
156 2
		return "http://mangafox.me/manga/{$title_url}/";
157
	}
158
159
	public function isValidTitleURL(string $title_url) : bool {
160
		$success = (bool) preg_match('/^[a-z0-9_]+$/', $title_url);
161
		if(!$success) log_message('error', "Invalid Title URL (MangaFox): {$title_url}");
162
		return $success;
163
	}
164
	public function isValidChapter(string $chapter) : bool {
165
		$success = (bool) preg_match('/^(?:v[0-9a-zA-Z]+\/)?c[0-9\.]+$/', $chapter);
166
		if(!$success) log_message('error', 'Invalid Chapter (MangaFox): '.$chapter);
167
		return $success;
168
	}
169
170
	public function getChapterData(string $title_url, string $chapter) : array {
171
		return [
172
			'url'    => "http://mangafox.me/manga/{$title_url}/{$chapter}/",
173
			'number' => $chapter
174
		];
175
	}
176
177 2
	public function getTitleData(string $title_url) {
178 2
		$titleData = [];
179
180 2
		$fullURL = $this->getFullTitleURL($title_url);
181 2
		$content = $this->get_content($fullURL);
182
183 2
		$data = $this->parseTitleDataDOM(
184
			$content,
185 2
			'MangaFox',
186
			$title_url,
187 2
			"//meta[@property='og:title']/@content",
188 2
			"//body/div[@id='page']/div[@class='left']/div[@id='chapters']/ul[1]/li[1]",
189 2
			"div/span[@class='date']",
190 2
			"div/h3/a"
191
		);
192 2
		if($data) {
193 1
			$titleData['title'] = html_entity_decode(substr($data['nodes_title']->textContent, 0, -6));
194
195 1
			$link = preg_replace('/^(.*\/)(?:[0-9]+\.html)?$/', '$1', (string) $data['nodes_chapter']->getAttribute('href'));
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 24 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
196 1
			$chapterURLSegments = explode('/', $link);
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 10 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
197 1
			$titleData['latest_chapter'] = $chapterURLSegments[5] . (isset($chapterURLSegments[6]) && !empty($chapterURLSegments[6]) ? "/{$chapterURLSegments[6]}" : "");
198 1
			$titleData['last_updated'] =  date("Y-m-d H:i:s", strtotime((string) $data['nodes_latest']->nodeValue));
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
199
		}
200
201 2
		return (!empty($titleData) ? $titleData : NULL);
202
	}
203
}
204
205
class MangaHere extends Site_Model {
206 2
	public function getFullTitleURL(string $title_url) : string {
207 2
		return "http://www.mangahere.co/manga/{$title_url}/";
208
	}
209
210
	public function isValidTitleURL(string $title_url) : bool {
211
		$success = (bool) preg_match('/^[a-z0-9_]+$/', $title_url);
212
		if(!$success) log_message('error', "Invalid Title URL (MangaFox): {$title_url}");
213
		return $success;
214
	}
215
	public function isValidChapter(string $chapter) : bool {
216
		$success = (bool) preg_match('/^(?:v[0-9]+\/)?c[0-9]+(?:\.[0-9]+)?$/', $chapter);
217
		if(!$success) log_message('error', 'Invalid Chapter (MangaFox): '.$chapter);
218
		return $success;
219
	}
220
221
	public function getChapterData(string $title, string $chapter) : array {
222
		return [
223
			'url'    => "http://www.mangahere.co/manga/{$title}/{$chapter}/",
224
			'number' => $chapter
225
		];
226
	}
227
228 2
	public function getTitleData(string $title_url) {
229 2
		$titleData = [];
230
231 2
		$fullURL = $this->getFullTitleURL($title_url);
232 2
		$content = $this->get_content($fullURL);
233
234 2
		$data = $this->parseTitleDataDOM(
235
			$content,
236 2
			'MangaHere',
237
			$title_url,
238 2
			"//meta[@property='og:title']/@content",
239 2
			"//body/section/article/div/div[@class='manga_detail']/div[@class='detail_list']/ul[1]/li[1]",
240 2
			"span[@class='right']",
241 2
			"span[@class='left']/a",
242 2
			"<div class=\"error_text\">Sorry, the page you have requested can’t be found."
243
		);
244 2
		if($data) {
245 1
			$titleData['title'] = $data['nodes_title']->textContent;
246
247 1
			$link = preg_replace('/^(.*\/)(?:[0-9]+\.html)?$/', '$1', (string) $data['nodes_chapter']->getAttribute('href'));
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 24 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
248 1
			$chapterURLSegments = explode('/', $link);
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 10 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
249 1
			$titleData['latest_chapter'] = $chapterURLSegments[5] . (isset($chapterURLSegments[6]) && !empty($chapterURLSegments[6]) ? "/{$chapterURLSegments[6]}" : "");
250 1
			$titleData['last_updated'] =  date("Y-m-d H:i:s", strtotime((string) $data['nodes_latest']->nodeValue));
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
251
		}
252
253 2
		return (!empty($titleData) ? $titleData : NULL);
254
	}
255
}
256
257
class Batoto extends Site_Model {
258
	//Batoto is a bit tricky to track. Unlike MangaFox and MangaHere, it doesn't store anything in the title_url, which means we have to get the data via other methods.
259
	//One problem we have though, is the tracker must support multiple sites, so this means we need to do some weird things to track Batoto.
260
	//title_url is stored like: "TITLE_URL:--:LANGUAGE"
261
	//chapter_urls are stored like "CHAPTER_ID:--:CHAPTER_NUMBER"
262
263 1
	public function getFullTitleURL(string $title_string) : string {
264
		//FIXME: This does not point to the language specific title page. Should ask if it is possible to set LANG as arg?
265
		//FIXME: This points to a generic URL which will redirect according to the ID. Preferably we'd try and get the exact URL from the title, but we can't pass it here.
266 1
		$title_parts = explode(':--:', $title_string);
267 1
		return "http://bato.to/comic/_/comics/-r".$title_parts[0];
268
	}
269
270
	public function isValidTitleURL(string $title_url) : bool {
271
		$success = (bool) preg_match('/^[0-9]+:--:(?:English|Spanish|French|German|Portuguese|Turkish|Indonesian|Greek|Filipino|Italian|Polish|Thai|Malay|Hungarian|Romanian|Arabic|Hebrew|Russian|Vietnamese|Dutch)$/', $title_url);
272
		if(!$success) log_message('error', "Invalid Title URL (Batoto): {$title_url}");
273
		return $success;
274
	}
275
	public function isValidChapter(string $chapter) : bool {
276
		//FIXME: We're not validating the chapter name since we don't know what all the possible valid characters can be
277
		//       Preferably we'd just use /^[0-9a-z]+:--:(v[0-9]+\/)?c[0-9]+(\.[0-9]+)?$/
278
279
		$success = (bool) preg_match('/^[0-9a-z]+:--:.+$/', $chapter);
280
		if(!$success) log_message('error', 'Invalid Chapter (Batoto): '.$chapter);
281
		return $success;
282
	}
283
284 View Code Duplication
	public function getChapterData(string $title_string, string $chapter) : array {
285
		//$title_string isn't used here.
286
287
		$chapter_parts = explode(':--:', $chapter);
288
		return [
289
			'url'    => "http://bato.to/reader#" . $chapter_parts[0],
290
			'number' => $chapter_parts[1]
291
		];
292
	}
293
294 1
	public function getTitleData(string $title_url) {
295 1
		$titleData = [];
296
297 1
		$title_parts = explode(':--:', $title_url);
298 1
		$fullURL     = $this->getFullTitleURL($title_url);
299 1
		$lang        = $title_parts[1]; //TODO: Validate title_lang from array?
300
301
302
		//Bato.to is annoying and locks stuff behind auth. See: https://github.com/DakuTree/manga-tracker/issues/14#issuecomment-233830855
303
		$cookies = [
304 1
			"lang_option={$lang}",
305 1
			"member_id={$this->config->item('batoto_cookie_member_id')}",
306 1
			"pass_hash={$this->config->item('batoto_cookie_pass_hash')}"
307
		];
308 1
		$content = $this->get_content($fullURL, implode("; ", $cookies), "", TRUE);
309
310 1
		$data = $this->parseTitleDataDOM(
311
			$content,
312 1
			'Batoto',
313
			$title_url,
314 1
			"//h1[@class='ipsType_pagetitle']",
315 1
			"//table[contains(@class, 'chapters_list')]/tbody/tr[2]",
316 1
			"td[last()]",
317 1
			"td/a[contains(@href,'reader')]",
318 1
			">Register now<"
319
		);
320 1
		if($data) {
321
			$titleData['title'] = html_entity_decode(trim($data['nodes_title']->textContent));
322
323
			///^(?:Vol\.(?<volume>\S+) )?(?:Ch.(?<chapter>[^\s:]+)(?:\s?-\s?(?<extra>[0-9]+))?):?.*/
324
			preg_match('/^(?:Vol\.(?<volume>\S+) )?(?:Ch.(?<chapter>[^\s:]+)(?:\s?-\s?(?<extra>[0-9]+))?):?.*/', trim($data['nodes_chapter']->nodeValue), $text);
325
			$titleData['latest_chapter'] = substr($data['nodes_chapter']->getAttribute('href'), 22) . ':--:' . ((!empty($text['volume']) ? 'v'.$text['volume'].'/' : '') . 'c'.$text['chapter'] . (!empty($text['extra']) ? '-'.$text['extra'] : ''));
326
327
			$dateString = $data['nodes_latest']->nodeValue;
328
			if($dateString == 'An hour ago') {
329
				$dateString = '1 hour ago';
330
			}
331
			$titleData['last_updated']   = date("Y-m-d H:i:s", strtotime(preg_replace('/ (-|\[A\]).*$/', '', $dateString)));
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned correctly; expected 1 space but found 3 spaces

This check looks for improperly formatted assignments.

Every assignment must have exactly one space before and one space after the equals operator.

To illustrate:

$a = "a";
$ab = "ab";
$abc = "abc";

will have no issues, while

$a   = "a";
$ab  = "ab";
$abc = "abc";

will report issues in lines 1 and 2.

Loading history...
332
		}
333
334 1
		return (!empty($titleData) ? $titleData : NULL);
335
	}
336
337
	public function cleanTitleDataDOM(string $data) : string {
338
		$data = preg_replace('/^[\s\S]+<!-- ::: CONTENT ::: -->/', '<!-- ::: CONTENT ::: -->', $data);
339
		$data = preg_replace('/<!-- end mainContent -->[\s\S]+$/', '<!-- end mainContent -->', $data);
340
		$data = preg_replace('/<div id=\'commentsStart\' class=\'ipsBox\'>[\s\S]+$/', '</div></div><!-- end mainContent -->', $data);
341
342
		return $data;
343
	}
344
}
345
346
//FIXME: Convert DynastyScans to new format.
347
class DynastyScans extends Site_Model {
348
	//FIXME: This has some major issues. SEE: https://github.com/DakuTree/manga-tracker/issues/58
349
	public function getFullTitleURL(string $title_string) : string {
350
		$title_parts = explode(':--:', $title_string);
351
		$url_type = ($title_parts[1] == '0' ? 'series' : 'chapters');
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 4 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
352
353
		return 'http://dynasty-scans.com/'.$url_type.'/'.$title_parts[0];
354
	}
355
356
	public function isValidTitleURL(string $title_url) : bool {
357
		$success = (bool) preg_match('/^[a-z0-9_]+:--:(?:0|1)$/', $title_url);
358
		if(!$success) log_message('error', "Invalid Title URL (DynastyScans): {$title_url}");
359
		return $success;
360
	}
361
	public function isValidChapter(string $chapter) : bool {
362
		$success = (bool) preg_match('/^[0-9a-z_]+$/', $chapter);
363
		if(!$success) log_message('error', 'Invalid Chapter (DynastyScans): '.$chapter);
364
		return $success;
365
	}
366
367
	public function getChapterData(string $title_string, string $chapter) : array {
368
		$title_parts = explode(':--:', $title_string);
369
		/* Known chapter url formats (# is numbers):
370
		       chapters_#A_#B - Ch#A-#B
371
		       ch_#A          - Ch#A
372
		       ch_#A_#B       - Ch#A.#B
373
		       <NOTHING>      - Oneshot (This is passed as "oneshot")
374
		*/
375
376
		$chapterData = [
377
			'url'    => 'http://dynasty-scans.com/chapters/' . $title_parts[0].'_'.$chapter,
378
			'number' => ''
379
		];
380
381
		if($chapter == 'oneshot') {
382
			$chapterData['number'] = 'oneshot';
383
		} else {
384
			$chapter = preg_replace("/^([a-zA-Z]+)/", '$1_', $chapter);
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 9 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
385
			$chapterSegments = explode('_', $chapter);
386
			switch($chapterSegments[0]) {
387
				case 'ch':
388
					$chapterData['number'] = 'c'.$chapterSegments[1].(isset($chapterSegments[2]) && !empty($chapterSegments[2]) ? '.'.$chapterSegments[2] : '');
389
					break;
390
391
				case 'chapters':
392
					//This is barely ever used, but I have seen it.
393
					$chapterData['number'] = 'c'.$chapterSegments[1].'-'.$chapterSegments[2];
394
					break;
395
396
				default:
397
					//TODO: FALLBACK, ALERT ADMIN?
398
					$chapterData['number'] = $chapter;
399
					break;
400
			}
401
		}
402
		return $chapterData;
403
	}
404
405 1
	public function getTitleData(string $title_string) {
406 1
		$title_parts = explode(':--:', $title_string);
407 1
		$title_url   = $title_parts[0];
408
409 1
		$titleData = [];
410
		//FIXME: Using regex here is probably a terrible idea, but we're doing it anyway....
411
		//FIXME (ASAP): All the regex here should be checked to see if it even returns something, and we should probably error if possible.
412 1
		if($title_parts[1] == '0') {
413 1
			$content = $this->get_content('http://dynasty-scans.com/series/'.$title_url);
414 1
			$data = $content['body'];
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 4 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
415
416 1
			preg_match('/<b>.*<\/b>/', $data, $matchesT);
417 1
			preg_match('/\/doujins\/[^"]+">(.+)?(?=<\/a>)<\/a>/', $data, $matchesD);
418 1
			$titleData['title'] = (!empty($matchesD) ? (substr($matchesD[1], 0, -7) !== 'Original' ? substr($matchesD[1], 0, -7).' - ' : '') : '') . substr($matchesT[0], 3, -4);
419
420 1
			$data = preg_replace('/^[\S\s]*(<dl class=\'chapter-list\'>[\S\s]*<\/dl>)[\S\s]*$/', '$1', $data);
421 1
			preg_match_all('/<dd>[\s\S]+?(?=<\/dd>)<\/dd>/', $data, $matches);
422 1
			$latest_chapter_html = array_pop($matches[0]);
423
424 1
			preg_match('/\/chapters\/([^"]+)/', $latest_chapter_html, $matches);
425 1
			$titleData['latest_chapter'] = substr($matches[1], strlen($title_url)+1);
426
			//FIXME: THIS IS A TEMP FIX, SEE https://github.com/DakuTree/manga-tracker/issues/58
427 1
			if(!$titleData['latest_chapter']) {
428
				log_message('error', 'DynastyScans::getTitleData cannot parse title properly as it contains oneshot. || URL: '.$title_url);
429
				return NULL;
430
			}
431
432 1
			preg_match('/<small>released (.*)<\/small>/', $latest_chapter_html, $matches);
433 1
			$titleData['last_updated']   = date("Y-m-d H:i:s", strtotime(str_replace('\'', '', $matches[1])));
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned correctly; expected 1 space but found 3 spaces

This check looks for improperly formatted assignments.

Every assignment must have exactly one space before and one space after the equals operator.

To illustrate:

$a = "a";
$ab = "ab";
$abc = "abc";

will have no issues, while

$a   = "a";
$ab  = "ab";
$abc = "abc";

will report issues in lines 1 and 2.

Loading history...
434
		} elseif($title_parts[1] == '1') {
435
			$content = $this->get_content('http://dynasty-scans.com/chapters/'.$title_url);
436
			$data = $content['body'];
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 4 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
437
438
			preg_match('/<b>.*<\/b>/', $data, $matchesT);
439
			preg_match('/\/doujins\/[^"]+">(.+)?(?=<\/a>)<\/a>/', $data, $matchesD);
440
			$titleData['title'] = (!empty($matchesD) ? ($matchesD[1] !== 'Original' ? $matchesD[1].' - ' : '') : '') . substr($matchesT[0], 3, -4);
441
442
			$titleData['latest_chapter'] = 'oneshot'; //This will never change
443
444
			preg_match('/<i class="icon-calendar"><\/i> (.*)<\/span>/', $data, $matches);
445
			$titleData['last_updated']   = date("Y-m-d H:i:s", strtotime($matches[1]));
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned correctly; expected 1 space but found 3 spaces

This check looks for improperly formatted assignments.

Every assignment must have exactly one space before and one space after the equals operator.

To illustrate:

$a = "a";
$ab = "ab";
$abc = "abc";

will have no issues, while

$a   = "a";
$ab  = "ab";
$abc = "abc";

will report issues in lines 1 and 2.

Loading history...
446
447
			//Oneshots are special, and really shouldn't need to be re-tracked
448
			//FIXME: We need to have a specific "no-track" complete param.
449
			$titleData['complete'] = 'Y';
450
		} else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
451
			//FIXME: WTF?
452
		}
453 1
		return (!empty($titleData) ? $titleData : NULL);
454
	}
455
}
456
457
class MangaPanda extends Site_Model {
458 2
	public function getFullTitleURL(string $title_url) : string {
459 2
		return "http://www.mangapanda.com/{$title_url}";
460
	}
461
462
	public function getChapterData(string $title_url, string $chapter) : array {
463
		return [
464
			'url'    => "http://www.mangapanda.com/{$title_url}/{$chapter}/",
465
			'number' => 'c'.$chapter
466
		];
467
	}
468
469
	public function isValidTitleURL(string $title_url) : bool {
470
		//NOTE: MangaPanda has manga pages under the root URL, so we need to filter out pages we know that aren't manga.
471
		$success = (bool) preg_match('/^(?!(?:latest|search|popular|random|alphabetical|privacy)$)([a-z0-9-]+)$/', $title_url);
472
		if(!$success) log_message('error', "Invalid Title URL (MangaPanda): {$title_url}");
473
		return $success;
474
	}
475
	public function isValidChapter(string $chapter) : bool {
476
		$success = (bool) preg_match('/^[0-9]+$/', $chapter);
477
		if(!$success) log_message('error', 'Invalid Chapter (MangaPanda): '.$chapter);
478
		return $success;
479
	}
480
481 2
	public function getTitleData(string $title_url) {
482 2
		$titleData = [];
483
484 2
		$fullURL = $this->getFullTitleURL($title_url);
485 2
		$content = $this->get_content($fullURL);
486
487 2
		$data = $this->parseTitleDataDOM(
488
			$content,
489 2
			'MangaPanda',
490
			$title_url,
491 2
			"//h2[@class='aname']",
492 2
			"(//table[@id='listing']/tr)[last()]",
493 2
			"td[2]",
494 2
			"td[1]/a"
495
		);
496 2
		if($data) {
497 1
			$titleData['title'] = $data['nodes_title']->textContent;
498
499 1
			$titleData['latest_chapter'] = preg_replace('/^.*\/([0-9]+)$/', '$1', (string) $data['nodes_chapter']->getAttribute('href'));
500
501 1
			$titleData['last_updated'] =  date("Y-m-d H:i:s", strtotime((string) $data['nodes_latest']->nodeValue));
502
		}
503
504
505 2
		return (!empty($titleData) ? $titleData : NULL);
506
	}
507
}
508
509
class MangaStream extends Site_Model {
510
	public function getFullTitleURL(string $title_url) : string {
511
		return "https://mangastream.com/manga/{$title_url}/";
512
	}
513
514
	public function isValidTitleURL(string $title_url) : bool {
515
		$success = (bool) preg_match('/^[a-z0-9_]+$/', $title_url);
516
		if(!$success) log_message('error', "Invalid Title URL (MangaStream): {$title_url}");
517
		return $success;
518
	}
519
	public function isValidChapter(string $chapter) : bool {
520
		$success = (bool) preg_match('/^(.*?)\/[0-9]+$/', $chapter);
521
		if(!$success) log_message('error', 'Invalid Chapter (MangaStream): '.$chapter);
522
		return $success;
523
	}
524
525
	public function getChapterData(string $title_url, string $chapter) : array {
526
		return [
527
			'url'    => "https://mangastream.com/r/{$title_url}/{$chapter}",
528
			'number' => 'c'.explode('/', $chapter)[0]
529
		];
530
	}
531
532
	public function getTitleData(string $title_url) {
533
		$titleData = [];
534
535
		$fullURL = $this->getFullTitleURL($title_url);
536
537
		$content = $this->get_content($fullURL);
538
		$data = $content['body'];
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 4 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
539
		if($data !== 'Can\'t find the manga series.') { //FIXME: We should check for he proper error here.
540
			//$data = preg_replace('/^[\S\s]*(<body id="body">[\S\s]*<\/body>)[\S\s]*$/', '$1', $data);
541
542
			$dom = new DOMDocument();
543
			libxml_use_internal_errors(true);
544
			$dom->loadHTML($data);
545
			libxml_use_internal_errors(false);
546
547
			$xpath = new DOMXPath($dom);
548
549
			$nodes_title = $xpath->query("//div[contains(@class, 'content')]/div[1]/h1");
550
			$nodes_row   = $xpath->query("//div[contains(@class, 'content')]/div[1]/table/tr[2]"); //Missing tbody here..
551
			if($nodes_title->length === 1 && $nodes_row->length === 1) {
552
				$titleData['title'] = $nodes_title->item(0)->nodeValue;
553
554
				$firstRow      = $nodes_row->item(0);
555
				$nodes_latest  = $xpath->query("td[2]",   $firstRow);
556
				$nodes_chapter = $xpath->query("td[1]/a", $firstRow);
557
558
				$titleData['latest_chapter'] = preg_replace('/^.*\/(.*?\/[0-9]+)\/[0-9]+$/', '$1', (string) $nodes_chapter->item(0)->getAttribute('href'));
559
				$titleData['last_updated'] =  date("Y-m-d H:i:s", strtotime((string) $nodes_latest->item(0)->nodeValue));
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
560
			}
561
		} else {
562
			log_message('error', "Series missing? (MangaStream): {$title_url}");
563
			return NULL;
564
		}
565
566
		return (!empty($titleData) ? $titleData : NULL);
567
	}
568
}
569
570
class WebToons extends Site_Model {
571
	/* Webtoons.com has a very weird and pointless URL format.
572
	   TITLE URL:   /#LANG#/#GENRE#/#TITLE#/list?title_no=#TITLEID#
573
	   RSS URL:     /#LANG#/#GENRE#/#TITLE#/rss?title_no=#TITLEID#
574
	   CHAPTER URL: /#LANG#/#GENRE#/#TITLE#/#CHAPTER#/viewer?title_no=#TITLEID#&episode_no=#CHAPTERID#
575
576
	   For both the title and chapter URLs, only the TITLEID and CHAPTERID are needed. Everything else can be anything at all (Well, alphanumeric at least).
577
	   The RSS URL however, requires everything to be exactly correct. I have no idea why this is, but it does mean we need to store all that info too.
578
	   We <could> not use the RSS url, and just parse via the title url, but rss is much better in the long run as it shouldn't change much.
579
580
	   FORMATS:
581
	   TITLE_URL: ID:--:LANG:--:TITLE:--:GENRE
582
	   CHAPTER:   ID:--:CHAPTER_N
583
	*/
584
	//private $validLang = ['en', 'zh-hant', 'zh-hans', 'th', 'id'];
585
586
	public function getFullTitleURL(string $title_url) : string {
587
		$title_parts = explode(':--:', $title_url);
588
		return "http://www.webtoons.com/{$title_parts[1]}/{$title_parts[3]}/{$title_parts[2]}/list?title_no={$title_parts[0]}/";
589
	}
590
591
	public function isValidTitleURL(string $title_url) : bool {
592
		$success = (bool) preg_match('/^[0-9]+:--:(?:en|zh-hant|zh-hans|th|id):--:[a-z0-9-]+:--:(?:drama|fantasy|comedy|action|slice-of-life|romance|superhero|thriller|sports|sci-fi)$/', $title_url);
593
		if(!$success) log_message('error', "Invalid Title URL (WebToons): {$title_url}");
594
		return $success;
595
	}
596
	public function isValidChapter(string $chapter) : bool {
597
		$success = (bool) preg_match('/^[0-9]+:--:.*$/', $chapter);
598
		if(!$success) log_message('error', 'Invalid Chapter (WebToons): '.$chapter);
599
		return $success;
600
	}
601
602
	public function getChapterData(string $title_url, string $chapter) : array {
603
		$title_parts   = explode(':--:', $title_url);
604
		$chapter_parts = explode(':--:', $chapter);
605
606
		return [
607
			'url'    => "http://www.webtoons.com/{$title_parts[1]}/{$title_parts[3]}/{$title_parts[2]}/{$chapter_parts[1]}/viewer?title_no={$title_parts[0]}&episode_no={$chapter_parts[0]}",
608
			'number' => $chapter_parts[1] //TODO: Possibly replace certain formats in here? Since webtoons doesn't have a standard chapter format
609
		];
610
	}
611
612 1
	public function getTitleData(string $title_url) {
613 1
		$titleData = [];
614
615 1
		$title_parts = explode(':--:', $title_url);
616 1
		$fullURL = "http://www.webtoons.com/{$title_parts[1]}/{$title_parts[3]}/{$title_parts[2]}/rss?title_no={$title_parts[0]}";
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 5 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
617
618 1
		$content = $this->get_content($fullURL);
619 1
		$data = $content['body'];
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 4 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
620 1
		if($data !== 'Can\'t find the manga series.') { //FIXME: We should check for he proper error here.
621 1
			$xml = simplexml_load_string($data) or die("Error: Cannot create object");
622 1
			if(isset($xml->{'channel'}->item[0])) {
623 1
				$titleData['title'] = trim((string) $xml->{'channel'}->title);
624
625 1
				$chapterURLSegments = explode('/', ((string) $xml->{'channel'}->item[0]->link));
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 10 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
626 1
				$titleData['latest_chapter'] = preg_replace('/^.*?([0-9]+)$/', '$1', $chapterURLSegments[7]) . ':--:' . $chapterURLSegments[6];
627 1
				$titleData['last_updated'] =  date("Y-m-d H:i:s", strtotime((string) $xml->{'channel'}->item[0]->pubDate));
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
628
			}
629
		} else {
630
			log_message('error', "Series missing? (WebToons): {$title_url}");
631
			return NULL;
632
		}
633
634 1
		return (!empty($titleData) ? $titleData : NULL);
635
	}
636
}
637
638
class KissManga extends Site_Model {
639
	/* This site is a massive pain in the ass. The only reason I'm supporting it is it's one of the few aggregator sites which actually support more risqué manga.
640
	   The main problem with this site is it has some form of bot protection. To view any part of the site normally, you need a cookie set by the bot protection.
641
642
	   To generate this cookie, we need three variables. Two are static, but the other is generated by randomly generated JS on the page.
643
	   The randomly generated JS is the troublesome part. We can't easily parse this with PHP. Both V8JS & SpiderMonkey refuse to build properly for me, so that rules that out.
644
	   The other option is using regex, but that is a rabbit hole I don't want to touch with a ten-foot pole.
645
646
	   To make the entire site work, I've built a python script to handle grabbing this cookie. This is grabbed & updated at the same time the manga are updated. The script saves the cookiejar which the PHP later reads.
647
	   The cookie has a length of 1 year, but I don't think it actually lasts that long, so we update every 6hours instead.
648
	   I should probably also mention that the cookie generated also uses your user-agent, so if it changes the cookie will break.
649
	*/
650
651
	public function getFullTitleURL(string $title_url) : string {
652
		return "http://kissmanga.com/Manga/{$title_url}";
653
	}
654
655
	public function isValidTitleURL(string $title_url) : bool {
656
		$success = (bool) preg_match('/^[A-Za-z0-9-]+/', $title_url);
657
		if(!$success) log_message('error', "Invalid Title URL (KissManga): {$title_url}");
658
		return $success;
659
	}
660
	public function isValidChapter(string $chapter) : bool {
661
		$success = (bool) preg_match('/^.*?:--:[0-9]+$/', $chapter);
662
		if(!$success) log_message('error', 'Invalid Chapter (KissManga): '.$chapter);
663
		return $success;
664
	}
665
666 View Code Duplication
	public function getChapterData(string $title_url, string $chapter) : array {
667
		$chapter_parts = explode(':--:', $chapter);
668
669
		return [
670
			'url'    => "http://kissmanga.com/Manga/{$title_url}/{$chapter_parts[0]}?id={$chapter_parts[1]}",
671
			//FIXME: KM has an extremely inconsistant chapter format which makes it difficult to parse.
672
			'number' => /*preg_replace('/--.*?$/', '', */$chapter_parts[0]/*)*/
673
		];
674
	}
675
676
	public function getTitleData(string $title_url) {
677
		$titleData = [];
678
679
		//Check if cookiejar is a day old (so we can know if something went wrong)
680
		$cookiejar_path = str_replace("public/", "_scripts/cookiejar", FCPATH);
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 6 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
681
		$cookie_last_updated = filemtime($cookiejar_path);
682
		if($cookie_last_updated && ((time() - 86400) < $cookie_last_updated)) {
683
684
			$fullURL = $this->getFullTitleURL($title_url);
685
686
			$content = $this->get_content($fullURL, '', $cookiejar_path);
687
			$data = $content['body'];
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 4 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
688
			if(strpos($data, 'containerRoot') !== FALSE) {
689
				//FIXME: For whatever reason, we can't grab the entire div without simplexml shouting at us
690
				$data = preg_replace('/^[\S\s]*(<div id="leftside">[\S\s]*)<div id="rightside">[\S\s]*$/', '$1', $data);
691
692
				$dom = new DOMDocument();
693
				libxml_use_internal_errors(true);
694
				$dom->loadHTML($data);
695
				libxml_use_internal_errors(false);
696
697
				$xpath = new DOMXPath($dom);
698
699
				$nodes_title = $xpath->query("//a[@class='bigChar']");
700
				$nodes_row   = $xpath->query("//table[@class='listing']/tr[3]");
701
				if($nodes_title->length === 1 && $nodes_row->length === 1) {
702
					$titleData['title'] = $nodes_title->item(0)->textContent;
703
704
					$firstRow      = $nodes_row->item(0);
705
					$nodes_latest  = $xpath->query("td[2]",   $firstRow);
706
					$nodes_chapter = $xpath->query("td[1]/a", $firstRow);
707
708
					$link = (string) $nodes_chapter->item(0)->getAttribute('href');
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 24 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
709
					$chapterURLSegments = explode('/', preg_replace('/\?.*$/', '', $link));
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 10 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
710
					$titleData['latest_chapter'] = $chapterURLSegments[3] . ':--:' . preg_replace('/.*?([0-9]+)$/', '$1', $link);
711
					$titleData['last_updated'] =  date("Y-m-d H:i:s", strtotime((string) $nodes_latest->item(0)->textContent));
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
712
				}
713
			} else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
714
				//TODO: Throw ERRORS;
715
			}
716
		} else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
717
			//Do nothing, wait until next update.
718
			//TODO: NAG ADMIN??
719
		}
720
721
		return (!empty($titleData) ? $titleData : NULL);
722
	}
723
}
724
725
class KireiCake extends Site_Model {
726 1
	public function getFullTitleURL(string $title_url) : string {
727 1
		return "https://reader.kireicake.com/series/{$title_url}";
728
	}
729
730
	public function isValidTitleURL(string $title_url) : bool {
731
		$success = (bool) preg_match('/^[a-z0-9_]+/', $title_url);
732
		if(!$success) log_message('error', "Invalid Title URL (KireiCake): {$title_url}");
733
		return $success;
734
	}
735
	public function isValidChapter(string $chapter) : bool {
736
		$success = (bool) preg_match('/^en\/[0-9]+(?:\/[0-9]+(?:\/[0-9]+(?:\/[0-9]+)?)?)?$/', $chapter);
737
		if(!$success) log_message('error', 'Invalid Chapter (KireiCake): '.$chapter);
738
		return $success;
739
	}
740
741
	public function getChapterData(string $title_url, string $chapter) : array {
742
		//LANG/VOLUME/CHAPTER/CHAPTER_EXTRA(/page/)
743
		$chapter_parts = explode('/', $chapter);
744
		return [
745
			'url'    => "https://reader.kireicake.com/read/{$title_url}/{$chapter}/",
746
			'number' => ($chapter_parts[1] !== '0' ? "v{$chapter_parts[1]}/" : '') . "c{$chapter_parts[2]}" . (isset($chapter_parts[3]) ? ".{$chapter_parts[3]}" : '')/*)*/
747
		];
748
	}
749
750 1
	public function getTitleData(string $title_url) {
751 1
		$titleData = [];
752
753 1
		$fullURL = $this->getFullTitleURL($title_url);
754
755 1
		$content = $this->get_content($fullURL);
756 1
		$data = $content['body'];
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 4 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
757 1
		if(strpos($data, '404 Page Not Found') === FALSE) {
758
			//FIXME: For whatever reason, we can't grab the entire div without simplexml shouting at us
759 1
			$data = preg_replace('/^[\S\s]*(<article>[\S\s]*)<\/article>[\S\s]*$/', '$1', $data);
760
761 1
			$dom = new DOMDocument();
762 1
			libxml_use_internal_errors(true);
763 1
			$dom->loadHTML($data);
764 1
			libxml_use_internal_errors(false);
765
766 1
			$xpath = new DOMXPath($dom);
767
768 1
			$nodes_title = $xpath->query("//div[@class='large comic']/h1[@class='title']");
769 1
			$nodes_row   = $xpath->query("//div[@class='list']/div[@class='element'][1]");
770 1
			if($nodes_title->length === 1 && $nodes_row->length === 1) {
771 1
				$titleData['title'] = trim($nodes_title->item(0)->textContent);
772
773 1
				$firstRow      = $nodes_row->item(0);
774 1
				$nodes_latest  = $xpath->query("div[@class='meta_r']",  $firstRow);
775 1
				$nodes_chapter = $xpath->query("div[@class='title']/a", $firstRow);
776
777 1
				$link = (string) $nodes_chapter->item(0)->getAttribute('href');
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 24 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
778 1
				$titleData['latest_chapter'] = preg_replace('/.*\/read\/.*?\/(.*?)\/$/', '$1', $link);
779 1
				$titleData['last_updated'] =  date("Y-m-d H:i:s", strtotime((string) str_replace('.', '', explode(',', $nodes_latest->item(0)->textContent)[1])));
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
780
			}
781
		} else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
782
			//TODO: Throw ERRORS;
783
		}
784
785 1
		return (!empty($titleData) ? $titleData : NULL);
786
	}
787
}
788
789
class GameOfScanlation extends Site_Model {
790
	public function getFullTitleURL(string $title_url) : string {
791
		return "https://gameofscanlation.moe/forums/{$title_url}/";
792
	}
793
794
	public function isValidTitleURL(string $title_url) : bool {
795
		$success = (bool) preg_match('/^[a-z0-9-]+/', $title_url);
796
		if(!$success) log_message('error', "Invalid Title URL (GameOfScanlation): {$title_url}");
797
		return $success;
798
	}
799
	public function isValidChapter(string $chapter) : bool {
800
		$success = (bool) preg_match('/^[a-z0-9\.-]+$/', $chapter);
801
		if(!$success) log_message('error', 'Invalid Chapter (GameOfScanlation): '.$chapter);
802
		return $success;
803
	}
804
805
	public function getChapterData(string $title_url, string $chapter) : array {
806
		return [
807
			'url'    => "https://gameofscanlation.moe/projects/".preg_replace("/\\.[0-9]+$/", "", $title_url).'/'.$chapter.'/',
808
			'number' => preg_replace("/chapter-/", "c", preg_replace("/\\.[0-9]+$/", "", $chapter))
809
		];
810
	}
811
812
	public function getTitleData(string $title_url) {
813
		$titleData = [];
814
815
		$fullURL = $this->getFullTitleURL($title_url);
816
817
		$content = $this->get_content($fullURL);
818
		$data = $content['body'];
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 4 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
819
		if(strpos($data, '404 Page Not Found') === FALSE) {
820
			//$data = preg_replace('/^[\S\s]*(<ol[\S\s]*)<\/ol>[\S\s]*$/', '$1', $data);
821
822
			$dom = new DOMDocument();
823
			libxml_use_internal_errors(true);
824
			$dom->loadHTML($data);
825
			libxml_use_internal_errors(false);
826
827
			$xpath = new DOMXPath($dom);
828
829
			$nodes_title = $xpath->query("//meta[@property='og:title']");
830
			$nodes_row   = $xpath->query("//ol[@class='discussionListItems']/li[1]/div[@class='home_list']/ul/li/div[@class='list_press_text']");
831
			if($nodes_title->length === 1 && $nodes_row->length === 1) {
832
				$titleData['title'] = html_entity_decode($nodes_title->item(0)->getAttribute('content'));
833
834
				$firstRow      = $nodes_row->item(0);
835
				$nodes_latest  = $xpath->query("p[@class='author']/span|p[@class='author']/abbr", $firstRow);
836
				$nodes_chapter = $xpath->query("p[@class='text_work']/a",                         $firstRow);
837
838
				$link = (string) $nodes_chapter->item(0)->getAttribute('href');
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 24 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
839
				$titleData['latest_chapter'] = preg_replace('/^projects\/.*?\/(.*?)\/$/', '$1', $link);
840
				$titleData['last_updated'] =  date("Y-m-d H:i:s", (int) $nodes_latest->item(0)->getAttribute('data-time'));
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
841
			} else {
842
				log_message('error', "GameOfScanlation: Unable to find nodes.");
843
				return NULL;
844
			}
845
		} else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
846
			//TODO: Throw ERRORS;
847
		}
848
849
		return (!empty($titleData) ? $titleData : NULL);
850
	}
851
}
852
853
class MangaCow extends Site_Model {
854 1
	public function getFullTitleURL(string $title_url) : string {
855 1
		return "http://mngcow.co/{$title_url}/";
856
	}
857
858
	public function isValidTitleURL(string $title_url) : bool {
859
		$success = (bool) preg_match('/^[a-zA-Z0-9_]+/', $title_url);
860
		if(!$success) log_message('error', "Invalid Title URL (MangaCow): {$title_url}");
861
		return $success;
862
	}
863
	public function isValidChapter(string $chapter) : bool {
864
		$success = (bool) preg_match('/^[0-9]+$/', $chapter);
865
		if(!$success) log_message('error', 'Invalid Chapter (MangaCow): '.$chapter);
866
		return $success;
867
	}
868
869
	public function getChapterData(string $title_url, string $chapter) : array {
870
		return [
871
			'url'    => $this->getFullTitleURL($title_url).$chapter.'/',
872
			'number' => "c{$chapter}"
873
		];
874
	}
875
876 1
	public function getTitleData(string $title_url) {
877 1
		$titleData = [];
878
879 1
		$fullURL = $this->getFullTitleURL($title_url);
880
881 1
		$content = $this->get_content($fullURL);
882 1
		$data = $content['body'];
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 4 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
883 1
		if(strpos($data, '404 Page Not Found') === FALSE) {
884 1
			$dom = new DOMDocument();
885 1
			libxml_use_internal_errors(true);
886 1
			$dom->loadHTML($data);
887 1
			libxml_use_internal_errors(false);
888
889 1
			$xpath = new DOMXPath($dom);
890
891 1
			$nodes_title = $xpath->query("//h4");
892 1
			$nodes_row   = $xpath->query("//ul[contains(@class, 'mng_chp')]/li[1]/a[1]");
893 1
			if($nodes_title->length === 1 && $nodes_row->length === 1) {
894 1
				$titleData['title'] = trim($nodes_title->item(0)->nodeValue);
895
896 1
				$nodes_chapter = $nodes_row;
897 1
				$nodes_latest  = $xpath->query("b[@class='dte']", $nodes_row->item(0));
898
899 1
				$link = (string) $nodes_chapter->item(0)->getAttribute('href');
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 24 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
900 1
				$titleData['latest_chapter'] = preg_replace('/^.*\/([0-9]+)\/$/', '$1', $link);
901 1
				$titleData['last_updated'] =  date("Y-m-d H:i:s", strtotime((string) substr($nodes_latest->item(0)->getAttribute('title'), 13)));
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
902
			} else {
903
				log_message('error', "MangaCow: Unable to find nodes.");
904 1
				return NULL;
905
			}
906
		} else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
907
			//TODO: Throw ERRORS;
908
		}
909
910 1
		return (!empty($titleData) ? $titleData : NULL);
911
	}
912
}
913
914 View Code Duplication
class SeaOtterScans extends Site_Model {
0 ignored issues
show
Duplication introduced by
This class 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.

Loading history...
915 1
	public function getFullTitleURL(string $title_url) : string {
916 1
		return "http://reader.seaotterscans.com/series/{$title_url}";
917
	}
918
919
	public function isValidTitleURL(string $title_url) : bool {
920
		$success = (bool) preg_match('/^[a-z0-9_]+/', $title_url);
921
		if(!$success) log_message('error', "Invalid Title URL (SeaOtterScans): {$title_url}");
922
		return $success;
923
	}
924
	public function isValidChapter(string $chapter) : bool {
925
		$success = (bool) preg_match('/^en\/[0-9]+(?:\/[0-9]+(?:\/[0-9]+(?:\/[0-9]+)?)?)?$/', $chapter);
926
		if(!$success) log_message('error', 'Invalid Chapter (SeaOtterScans): '.$chapter);
927
		return $success;
928
	}
929
930
	public function getChapterData(string $title_url, string $chapter) : array {
931
		//LANG/VOLUME/CHAPTER/CHAPTER_EXTRA(/page/)
932
		$chapter_parts = explode('/', $chapter);
933
		return [
934
			'url'    => "https://reader.seaotterscans.com/read/{$title_url}/{$chapter}/",
935
			'number' => ($chapter_parts[1] !== '0' ? "v{$chapter_parts[1]}/" : '') . "c{$chapter_parts[2]}" . (isset($chapter_parts[3]) ? ".{$chapter_parts[3]}" : '')/*)*/
936
		];
937
	}
938
939 1
	public function getTitleData(string $title_url) {
940 1
		$titleData = [];
941
942 1
		$fullURL = $this->getFullTitleURL($title_url);
943
944 1
		$content = $this->get_content($fullURL);
945 1
		$data = $content['body'];
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 4 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
946 1
		if(strpos($data, '404 Page Not Found') === FALSE) {
947
			//FIXME: For whatever reason, we can't grab the entire div without simplexml shouting at us
948 1
			$data = preg_replace('/^[\S\s]*(<article[\S\s]*)<\/article>[\S\s]*$/', '$1', $data);
949
950 1
			$dom = new DOMDocument();
951 1
			libxml_use_internal_errors(true);
952 1
			$dom->loadHTML($data);
953 1
			libxml_use_internal_errors(false);
954
955 1
			$xpath = new DOMXPath($dom);
956
957 1
			$nodes_title = $xpath->query("//div[@class='large comic']/h1[@class='title']");
958
959
			//SOO sometimes uses volume groups which are above recent chapters (if they haven't been grouped yet), so make sure we check for both.
960 1
			$nodes_row   = $xpath->query("//div[@class='list']/div[@class='group']/div[@class='title' and text() = 'Chapters']/following-sibling::div[@class='element'][1]");
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned correctly; expected 1 space but found 3 spaces

This check looks for improperly formatted assignments.

Every assignment must have exactly one space before and one space after the equals operator.

To illustrate:

$a = "a";
$ab = "ab";
$abc = "abc";

will have no issues, while

$a   = "a";
$ab  = "ab";
$abc = "abc";

will report issues in lines 1 and 2.

Loading history...
961 1
			if($nodes_row->length !== 1) {
962 1
				$nodes_row   = $xpath->query("//div[@class='list']/div[@class='group'][1]/div[@class='element'][1]");
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned correctly; expected 1 space but found 3 spaces

This check looks for improperly formatted assignments.

Every assignment must have exactly one space before and one space after the equals operator.

To illustrate:

$a = "a";
$ab = "ab";
$abc = "abc";

will have no issues, while

$a   = "a";
$ab  = "ab";
$abc = "abc";

will report issues in lines 1 and 2.

Loading history...
963
			}
964 1
			if($nodes_title->length === 1 && $nodes_row->length === 1) {
965 1
				$titleData['title'] = trim($nodes_title->item(0)->textContent);
966
967 1
				$firstRow = $nodes_row->item(0);
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 6 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
968 1
				$nodes_latest  = $xpath->query("div[@class='meta_r']",  $firstRow);
969 1
				$nodes_chapter = $xpath->query("div[@class='title']/a", $firstRow);
970
971 1
				$link = (string) $nodes_chapter->item(0)->getAttribute('href');
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 24 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
972 1
				$titleData['latest_chapter'] = preg_replace('/.*\/read\/.*?\/(.*?)\/$/', '$1', $link);
973 1
				$titleData['last_updated'] =  date("Y-m-d H:i:s", strtotime((string) str_replace('.', '', explode(',', $nodes_latest[0]->textContent)[1])));
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
974
			}
975
		} else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
976
			//TODO: Throw ERRORS;
977
		}
978
979 1
		return (!empty($titleData) ? $titleData : NULL);
980
	}
981
}
982
983 View Code Duplication
class HelveticaScans extends Site_Model {
0 ignored issues
show
Duplication introduced by
This class 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.

Loading history...
984 1
	public function getFullTitleURL(string $title_url) : string {
985 1
		return "http://helveticascans.com/reader/series/{$title_url}";
986
	}
987
988
	public function isValidTitleURL(string $title_url) : bool {
989
		$success = (bool) preg_match('/^[a-z0-9_]+/', $title_url);
990
		if(!$success) log_message('error', "Invalid Title URL (HelveticaScans): {$title_url}");
991
		return $success;
992
	}
993
	public function isValidChapter(string $chapter) : bool {
994
		$success = (bool) preg_match('/^en\/[0-9]+(?:\/[0-9]+(?:\/[0-9]+(?:\/[0-9]+)?)?)?$/', $chapter);
995
		if(!$success) log_message('error', 'Invalid Chapter (HelveticaScans): '.$chapter);
996
		return $success;
997
	}
998
999
	public function getChapterData(string $title_url, string $chapter) : array {
1000
		//LANG/VOLUME/CHAPTER/CHAPTER_EXTRA(/page/)
1001
		$chapter_parts = explode('/', $chapter);
1002
		return [
1003
			'url'    => "http://helveticascans.com/reader/read/{$title_url}/{$chapter}/",
1004
			'number' => ($chapter_parts[1] !== '0' ? "v{$chapter_parts[1]}/" : '') . "c{$chapter_parts[2]}" . (isset($chapter_parts[3]) ? ".{$chapter_parts[3]}" : '')/*)*/
1005
		];
1006
	}
1007
1008 1
	public function getTitleData(string $title_url) {
1009 1
		$titleData = [];
1010
1011 1
		$fullURL = $this->getFullTitleURL($title_url);
1012
1013 1
		$content = $this->get_content($fullURL);
1014 1
		$data = $content['body'];
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 4 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
1015 1
		if(strpos($data, '404 Page Not Found') === FALSE) {
1016
			//FIXME: For whatever reason, we can't grab the entire div without simplexml shouting at us
1017 1
			$data = preg_replace('/^[\S\s]*(<article[\S\s]*)<\/article>[\S\s]*$/', '$1', $data);
1018
1019 1
			$dom = new DOMDocument();
1020 1
			libxml_use_internal_errors(true);
1021 1
			$dom->loadHTML($data);
1022 1
			libxml_use_internal_errors(false);
1023
1024 1
			$xpath = new DOMXPath($dom);
1025
1026 1
			$nodes_title = $xpath->query("//div[@class='large comic']/h1[@class='title']");
1027 1
			$nodes_row   = $xpath->query("//div[@class='list']/div[@class='group']/div[@class='title' and text() = 'Chapters']/following-sibling::div[@class='element'][1]");
1028 1
			if($nodes_row->length !== 1) {
1029
				$nodes_row   = $xpath->query("//div[@class='list']/div[@class='group'][1]/div[@class='element'][1]");
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned correctly; expected 1 space but found 3 spaces

This check looks for improperly formatted assignments.

Every assignment must have exactly one space before and one space after the equals operator.

To illustrate:

$a = "a";
$ab = "ab";
$abc = "abc";

will have no issues, while

$a   = "a";
$ab  = "ab";
$abc = "abc";

will report issues in lines 1 and 2.

Loading history...
1030
			}
1031 1
			if($nodes_title->length === 1 && $nodes_row->length === 1) {
1032 1
				$titleData['title'] = trim($nodes_title->item(0)->textContent);
1033
1034
1035 1
				$nodes_latest  = $xpath->query("div[@class='meta_r']", $nodes_row[0]);
1036 1
				$nodes_chapter = $xpath->query("div[@class='title']/a", $nodes_row[0]);
1037
1038 1
				$link = (string) $nodes_chapter->item(0)->getAttribute('href');
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 24 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
1039 1
				$titleData['latest_chapter'] = preg_replace('/.*\/read\/.*?\/(.*?)\/$/', '$1', $link);
1040 1
				$titleData['last_updated'] =  date("Y-m-d H:i:s", strtotime((string) str_replace('.', '', explode(',', $nodes_latest->item(0)->textContent)[1])));
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
1041
			}
1042
		} else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
1043
			//TODO: Throw ERRORS;
1044
		}
1045
1046 1
		return (!empty($titleData) ? $titleData : NULL);
1047
	}
1048
}
1049
1050 View Code Duplication
class SenseScans extends Site_Model {
0 ignored issues
show
Duplication introduced by
This class 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.

Loading history...
1051 1
	public function getFullTitleURL(string $title_url) : string {
1052 1
		return "http://reader.sensescans.com/series/{$title_url}";
1053
	}
1054
1055
	public function isValidTitleURL(string $title_url) : bool {
1056
		$success = (bool) preg_match('/^[a-z0-9_]+/', $title_url);
1057
		if(!$success) log_message('error', "Invalid Title URL (SenseScans): {$title_url}");
1058
		return $success;
1059
	}
1060
	public function isValidChapter(string $chapter) : bool {
1061
		$success = (bool) preg_match('/^en\/[0-9]+(?:\/[0-9]+(?:\/[0-9]+(?:\/[0-9]+)?)?)?$/', $chapter);
1062
		if(!$success) log_message('error', 'Invalid Chapter (SenseScans): '.$chapter);
1063
		return $success;
1064
	}
1065
1066
	public function getChapterData(string $title_url, string $chapter) : array {
1067
		//LANG/VOLUME/CHAPTER/CHAPTER_EXTRA(/page/)
1068
		$chapter_parts = explode('/', $chapter);
1069
		return [
1070
			'url'    => "http://reader.sensescans.com/read/{$title_url}/{$chapter}/",
1071
			'number' => ($chapter_parts[1] !== '0' ? "v{$chapter_parts[1]}/" : '') . "c{$chapter_parts[2]}" . (isset($chapter_parts[3]) ? ".{$chapter_parts[3]}" : '')/*)*/
1072
		];
1073
	}
1074
1075 1
	public function getTitleData(string $title_url) {
1076 1
		$titleData = [];
1077
1078 1
		$fullURL = $this->getFullTitleURL($title_url);
1079
1080 1
		$content = $this->get_content($fullURL);
1081 1
		$data = $content['body'];
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 4 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
1082 1
		if(strpos($data, '404 Page Not Found') === FALSE) {
1083
			//FIXME: For whatever reason, we can't grab the entire div without simplexml shouting at us
1084 1
			$data = preg_replace('/^[\S\s]*(<article[\S\s]*)<\/article>[\S\s]*$/', '$1', $data);
1085
1086 1
			$dom = new DOMDocument();
1087 1
			libxml_use_internal_errors(true);
1088 1
			$dom->loadHTML($data);
1089 1
			libxml_use_internal_errors(false);
1090
1091 1
			$xpath = new DOMXPath($dom);
1092
1093 1
			$nodes_title = $xpath->query("//div[@class='large comic']/h1[@class='title']");
1094 1
			$nodes_row   = $xpath->query("//div[@class='list']/div[@class='group']/div[@class='title' and text() = 'Chapters']/following-sibling::div[@class='element'][1]");
1095 1
			if($nodes_row->length !== 1) {
1096
				$nodes_row   = $xpath->query("//div[@class='list']/div[@class='group'][1]/div[@class='element'][1]");
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned correctly; expected 1 space but found 3 spaces

This check looks for improperly formatted assignments.

Every assignment must have exactly one space before and one space after the equals operator.

To illustrate:

$a = "a";
$ab = "ab";
$abc = "abc";

will have no issues, while

$a   = "a";
$ab  = "ab";
$abc = "abc";

will report issues in lines 1 and 2.

Loading history...
1097
			}
1098 1
			if($nodes_title->length === 1 && $nodes_row->length === 1) {
1099 1
				$titleData['title'] = trim($nodes_title->item(0)->textContent);
1100
1101 1
				$nodes_latest    = $xpath->query("div[@class='meta_r']", $nodes_row[0]);
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 2 spaces but found 4 spaces

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
1102 1
				$nodes_chapter   = $xpath->query("div[@class='title']/a", $nodes_row[0]);
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 1 space but found 3 spaces

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
1103
1104 1
				$link = (string) $nodes_chapter->item(0)->getAttribute('href');
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 24 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
1105 1
				$titleData['latest_chapter'] = preg_replace('/.*\/read\/.*?\/(.*?)\/$/', '$1', $link);
1106 1
				$titleData['last_updated'] =  date("Y-m-d H:i:s", strtotime((string) str_replace('.', '', explode(',', $nodes_latest->item(0)->textContent)[1])));
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
1107
			}
1108
		} else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
1109
			//TODO: Throw ERRORS;
1110
		}
1111
1112 1
		return (!empty($titleData) ? $titleData : NULL);
1113
	}
1114
}
1115