Completed
Push — master ( 45893c...373238 )
by Angus
02:39
created

Tracker_List_Model::get()   D

Complexity

Conditions 20
Paths 12

Size

Total Lines 125
Code Lines 85

Duplication

Lines 42
Ratio 33.6 %

Code Coverage

Tests 0
CRAP Score 420

Importance

Changes 0
Metric Value
cc 20
eloc 85
nc 12
nop 0
dl 42
loc 125
ccs 0
cts 0
cp 0
crap 420
rs 4.7294
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php declare(strict_types=1); defined('BASEPATH') OR exit('No direct script access allowed');
2
3
class Tracker_List_Model extends Tracker_Base_Model {
4 112
	public function __construct() {
5 112
		parent::__construct();
6 112
	}
7
8
	public function get() {
9
		$query = $this->db
10
			->select('tracker_chapters.*,
11
			          tracker_titles.site_id, tracker_titles.title, tracker_titles.title_url, tracker_titles.latest_chapter, tracker_titles.last_updated AS title_last_updated, tracker_titles.status AS title_status, tracker_titles.last_checked > DATE_SUB(NOW(), INTERVAL 1 WEEK) AS title_active,
12
			          tracker_sites.site, tracker_sites.site_class, tracker_sites.status AS site_status')
13
			->from('tracker_chapters')
14
			->join('tracker_titles', 'tracker_chapters.title_id = tracker_titles.id', 'left')
15
			->join('tracker_sites', 'tracker_sites.id = tracker_titles.site_id', 'left')
16
			->where('tracker_chapters.user_id', $this->User->id)
17
			->where('tracker_chapters.active', 'Y')
18
			->get();
19
20
		$arr = ['series' => [], 'has_inactive' => FALSE];
21
		foreach($this->enabledCategories as $category => $name) {
22
			$arr['series'][$category] = [
23
				'name'         => $name,
24
				'manga'        => [],
25
				'unread_count' => 0
26
			];
27
		}
28
		if($query->num_rows() > 0) {
29
			foreach ($query->result() as $row) {
30
				$is_unread     = intval($row->latest_chapter == $row->current_chapter ? '1' : '0');
31
				$arr['series'][$row->category]['unread_count'] = (($arr['series'][$row->category]['unread_count'] ?? 0) + !$is_unread);
32
				$data = [
33
					'id' => $row->id,
34
					'generated_current_data' => $this->sites->{$row->site_class}->getChapterData($row->title_url, $row->current_chapter),
35
					'generated_latest_data'  => $this->sites->{$row->site_class}->getChapterData($row->title_url, $row->latest_chapter),
36
					'full_title_url'        =>  $this->sites->{$row->site_class}->getFullTitleURL($row->title_url),
37
38
					'new_chapter_exists'    => $is_unread,
39
					'tag_list'              => $row->tags,
40
					'has_tags'              => !empty($row->tags),
41
42
					'title_data' => [
43
						'id'              => $row->title_id,
44
						'title'           => $row->title,
45
						'title_url'       => $row->title_url,
46
						'latest_chapter'  => $row->latest_chapter,
47
						'current_chapter' => $row->current_chapter,
48
						'last_updated'    => $row->title_last_updated,
49
						//NOTE: active is used to warn the user if a title hasn't updated (Maybe due to nobody active tracking it or other reasons).
50
						//      This will ONLY be false when an actively updating series (site enabled & title status = 0) hasn't updated within the past week.
51
						'active'          => ($row->site_status == 'disabled' || in_array($row->title_status, [/*complete*/ 1, /* one-shot */ 2, /* ignored */ 255]) || $row->title_active == 1)
52
					],
53
					'site_data' => [
54
						'id'         => $row->site_id,
55
						'site'       => $row->site,
56
						'status'     => $row->site_status
57
					]
58
				];
59
				$arr['series'][$row->category]['manga'][] = $data;
60
61
				if(!$arr['has_inactive']) $arr['has_inactive'] = !$data['title_data']['active'];
62
			}
63
64
			//CHECK: Is this good for speed?
65
			//NOTE: This does not sort in the same way as tablesorter, but it works better.
66
			switch($this->User_Options->get('list_sort_type')) {
67
				case 'unread':
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
68
					foreach (array_keys($arr['series']) as $category) {
69
						usort($arr['series'][$category]['manga'], function ($a, $b) {
70
							$a_text = strtolower("{$a['new_chapter_exists']} - {$a['title_data']['title']}");
71
							$b_text = strtolower("{$b['new_chapter_exists']} - {$b['title_data']['title']}");
72
73
							if($this->User_Options->get('list_sort_order') == 'asc') {
74
								return $a_text <=> $b_text;
75
							} else {
76
								return $b_text <=> $a_text;
77
							}
78
						});
79
					}
80
					break;
81
82 View Code Duplication
				case 'alphabetical':
1 ignored issue
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
83
					foreach (array_keys($arr['series']) as $category) {
84
						usort($arr['series'][$category]['manga'], function ($a, $b) {
85
							$a_text = strtolower("{$a['title_data']['title']}");
86
							$b_text = strtolower("{$b['title_data']['title']}");
87
88
							if($this->User_Options->get('list_sort_order') == 'asc') {
89
								return $a_text <=> $b_text;
90
							} else {
91
								return $b_text <=> $a_text;
92
							}
93
						});
94
					}
95
					break;
96
97 View Code Duplication
				case 'my_status':
98
					foreach (array_keys($arr['series']) as $category) {
99
						usort($arr['series'][$category]['manga'], function ($a, $b) {
100
							$a_text = strtolower("{$a['generated_current_data']['number']}");
101
							$b_text = strtolower("{$b['generated_current_data']['number']}");
102
103
							if($this->User_Options->get('list_sort_order') == 'asc') {
104
								return $a_text <=> $b_text;
105
							} else {
106
								return $b_text <=> $a_text;
107
							}
108
						});
109
					}
110
					break;
111
112 View Code Duplication
				case 'latest':
113
					foreach (array_keys($arr['series']) as $category) {
114
						usort($arr['series'][$category]['manga'], function ($a, $b) {
115
							$a_text = strtolower("{$a['generated_latest_data']['number']}");
116
							$b_text = strtolower("{$b['generated_latest_data']['number']}");
117
118
							if($this->User_Options->get('list_sort_order') == 'asc') {
119
								return $a_text <=> $b_text;
120
							} else {
121
								return $b_text <=> $a_text;
122
							}
123
						});
124
					}
125
					break;
126
127
				default:
128
					break;
129
			}
130
		}
131
		return $arr;
132
	}
133
134
135
	public function update(int $userID, string $site, string $title, string $chapter) : bool {
136
		$success = FALSE;
137
		if($siteData = $this->Tracker->title->getSiteDataFromURL($site)) {
138
			//Validate user input
139
			if(!$this->sites->{$siteData->site_class}->isValidTitleURL($title)) {
140
				//Error is already logged via isValidTitleURL
141
				return FALSE;
142
			}
143
			if(!$this->sites->{$siteData->site_class}->isValidChapter($chapter)) {
144
				//Error is already logged via isValidChapter
145
				return FALSE;
146
			}
147
148
			//NOTE: If the title doesn't exist it will be created. This maybe isn't perfect, but it works for now.
149
			$titleID = $this->Tracker->title->getID($title, (int) $siteData->id);
150
			if($titleID === 0) {
151
				//Something went wrong.
152
				log_message('error', "TitleID = 0 for {$title} @ {$siteData->id}");
153
				return FALSE;
154
			}
155
156
			$idQuery = $this->db->select('id')
157
			                    ->where('user_id', $userID)
158
			                    ->where('title_id', $titleID)
159
			                    ->get('tracker_chapters');
160
			if($idQuery->num_rows() > 0) {
161
				$success = (bool) $this->db->set(['current_chapter' => $chapter, 'active' => 'Y', 'last_updated' => NULL])
162
				                           ->where('user_id', $userID)
163
				                           ->where('title_id', $titleID)
164
				                           ->update('tracker_chapters');
165
166
				if($success) {
167
					$idQueryRow = $idQuery->row();
168
					$this->History->userUpdateTitle((int) $idQueryRow->id, $chapter);
169
				}
170
			} else {
171
				$category = $this->User_Options->get_by_userid('default_series_category', $userID);
172
				$success = (bool) $this->db->insert('tracker_chapters', [
173
					'user_id'         => $userID,
174
					'title_id'        => $titleID,
175
					'current_chapter' => $chapter,
176
					'category'        => $category
177
				]);
178
179
				if($success) {
180
					$this->History->userAddTitle((int) $this->db->insert_id(), $chapter, $category);
0 ignored issues
show
Bug introduced by
The method insert_id() does not exist on CI_DB_query_builder. Did you maybe mean insert()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
181
				}
182
			}
183
		}
184
		return $success;
185
	}
186
	public function updateByID(int $userID, int $chapterID, string $chapter) : bool {
187
		$success = (bool) $this->db->set(['current_chapter' => $chapter, 'active' => 'Y', 'last_updated' => NULL])
188
		                           ->where('user_id', $userID)
189
		                           ->where('id', $chapterID)
190
		                           ->update('tracker_chapters');
191
192
		if($success) {
193
			$this->History->userUpdateTitle($chapterID, $chapter);
194
		}
195
		return  $success;
196
	}
197
198 View Code Duplication
	public function deleteByID(int $userID, int $chapterID) {
199
		//Series are not fully deleted, they are just marked as inactive as to hide them from the user.
200
		//This is to allow user history to function properly.
201
202
		$success = $this->db->set(['active' => 'N', 'last_updated' => NULL])
203
		                    ->where('user_id', $userID)
204
		                    ->where('id', $chapterID)
205
		                    ->update('tracker_chapters');
206
207
		return (bool) $success;
208
	}
209
	public function deleteByIDList(array $idList) : array {
210
		/*
211
		 * 0 = Success
212
		 * 1 = Invalid IDs
213
		 */
214
		$status = ['code' => 0];
215
216 View Code Duplication
		foreach($idList as $id) {
217
			if(!(ctype_digit($id) && $this->deleteByID($this->User->id, (int) $id))) {
218
				$status['code'] = 1;
219
			} else {
220
				//Delete was successful, update history too.
221
				$this->History->userRemoveTitle((int) $id);
222
			}
223
		}
224
225
		return $status;
226
	}
227
}
228