@@ -171,14 +171,14 @@ discard block |
||
| 171 | 171 | } |
| 172 | 172 | |
| 173 | 173 | $idQuery = $this->db->select('id') |
| 174 | - ->where('user_id', $userID) |
|
| 175 | - ->where('title_id', $titleID) |
|
| 176 | - ->get('tracker_chapters'); |
|
| 174 | + ->where('user_id', $userID) |
|
| 175 | + ->where('title_id', $titleID) |
|
| 176 | + ->get('tracker_chapters'); |
|
| 177 | 177 | if($idQuery->num_rows() > 0) { |
| 178 | 178 | $success = (bool) $this->db->set(['current_chapter' => $chapter, 'active' => 'Y', 'last_updated' => NULL, 'ignore_chapter' => NULL]) |
| 179 | - ->where('user_id', $userID) |
|
| 180 | - ->where('title_id', $titleID) |
|
| 181 | - ->update('tracker_chapters'); |
|
| 179 | + ->where('user_id', $userID) |
|
| 180 | + ->where('title_id', $titleID) |
|
| 181 | + ->update('tracker_chapters'); |
|
| 182 | 182 | |
| 183 | 183 | if($success) { |
| 184 | 184 | $idQueryRow = $idQuery->row(); |
@@ -204,9 +204,9 @@ discard block |
||
| 204 | 204 | } |
| 205 | 205 | public function updateByID(int $userID, int $chapterID, string $chapter) : bool { |
| 206 | 206 | $success = (bool) $this->db->set(['current_chapter' => $chapter, 'active' => 'Y', 'last_updated' => NULL]) |
| 207 | - ->where('user_id', $userID) |
|
| 208 | - ->where('id', $chapterID) |
|
| 209 | - ->update('tracker_chapters'); |
|
| 207 | + ->where('user_id', $userID) |
|
| 208 | + ->where('id', $chapterID) |
|
| 209 | + ->update('tracker_chapters'); |
|
| 210 | 210 | |
| 211 | 211 | if($success) { |
| 212 | 212 | $this->History->userUpdateTitle($chapterID, $chapter); |
@@ -216,9 +216,9 @@ discard block |
||
| 216 | 216 | |
| 217 | 217 | public function ignoreByID(int $userID, int $chapterID, string $chapter) : bool { |
| 218 | 218 | $success = (bool) $this->db->set(['ignore_chapter' => $chapter, 'active' => 'Y', 'last_updated' => NULL]) |
| 219 | - ->where('user_id', $userID) |
|
| 220 | - ->where('id', $chapterID) |
|
| 221 | - ->update('tracker_chapters'); |
|
| 219 | + ->where('user_id', $userID) |
|
| 220 | + ->where('id', $chapterID) |
|
| 221 | + ->update('tracker_chapters'); |
|
| 222 | 222 | |
| 223 | 223 | if($success) { |
| 224 | 224 | $this->History->userIgnoreTitle($chapterID, $chapter); |
@@ -231,9 +231,9 @@ discard block |
||
| 231 | 231 | //This is to allow user history to function properly. |
| 232 | 232 | |
| 233 | 233 | $success = $this->db->set(['active' => 'N', 'last_updated' => NULL]) |
| 234 | - ->where('user_id', $userID) |
|
| 235 | - ->where('id', $chapterID) |
|
| 236 | - ->update('tracker_chapters'); |
|
| 234 | + ->where('user_id', $userID) |
|
| 235 | + ->where('id', $chapterID) |
|
| 236 | + ->update('tracker_chapters'); |
|
| 237 | 237 | |
| 238 | 238 | return (bool) $success; |
| 239 | 239 | } |
@@ -263,9 +263,9 @@ discard block |
||
| 263 | 263 | //TODO: OPTION, USE BACKEND MAL ID DB WHERE POSSIBLE (DEFAULT TRUE) |
| 264 | 264 | |
| 265 | 265 | $queryC = $this->db->select('mal_id') |
| 266 | - ->where('user_id', $userID) |
|
| 267 | - ->where('title_id', $titleID) |
|
| 268 | - ->get('tracker_chapters'); |
|
| 266 | + ->where('user_id', $userID) |
|
| 267 | + ->where('title_id', $titleID) |
|
| 268 | + ->get('tracker_chapters'); |
|
| 269 | 269 | |
| 270 | 270 | if($queryC->num_rows() > 0 && ($rowC = $queryC->row())) { |
| 271 | 271 | $malIDArr = [ |
@@ -274,8 +274,8 @@ discard block |
||
| 274 | 274 | ]; |
| 275 | 275 | } else { |
| 276 | 276 | $queryT = $this->db->select('mal_id') |
| 277 | - ->where('title_id', $titleID) |
|
| 278 | - ->get('tracker_titles'); |
|
| 277 | + ->where('title_id', $titleID) |
|
| 278 | + ->get('tracker_titles'); |
|
| 279 | 279 | |
| 280 | 280 | if($queryT->num_rows() > 0 && ($rowT = $queryT->row())) { |
| 281 | 281 | $malIDArr = [ |
@@ -289,9 +289,9 @@ discard block |
||
| 289 | 289 | //TODO: Remove after a few weeks! |
| 290 | 290 | if(is_null($malIDArr)) { |
| 291 | 291 | $queryC2 = $this->db->select('tags') |
| 292 | - ->where('user_id', $userID) |
|
| 293 | - ->where('title_id', $titleID) |
|
| 294 | - ->get('tracker_chapters'); |
|
| 292 | + ->where('user_id', $userID) |
|
| 293 | + ->where('title_id', $titleID) |
|
| 294 | + ->get('tracker_chapters'); |
|
| 295 | 295 | |
| 296 | 296 | if($queryC2->num_rows() > 0 && ($tag_string = $queryC2->row()->tags) && !is_null($tag_string)) { |
| 297 | 297 | $arr = preg_grep('/^mal:([0-9]+|none)$/', explode(',', $tag_string)); |
@@ -309,9 +309,9 @@ discard block |
||
| 309 | 309 | public function setMalID(int $userID, int $chapterID, ?int $malID) : bool { |
| 310 | 310 | //TODO: Handle NULL? |
| 311 | 311 | $success = (bool) $this->db->set(['mal_id' => $malID, 'active' => 'Y', 'last_updated' => NULL]) |
| 312 | - ->where('user_id', $userID) |
|
| 313 | - ->where('id', $chapterID) |
|
| 314 | - ->update('tracker_chapters'); |
|
| 312 | + ->where('user_id', $userID) |
|
| 313 | + ->where('id', $chapterID) |
|
| 314 | + ->update('tracker_chapters'); |
|
| 315 | 315 | |
| 316 | 316 | if($success) { |
| 317 | 317 | //MAL id update was successful, update history |
@@ -44,12 +44,12 @@ discard block |
||
| 44 | 44 | |
| 45 | 45 | private function _list_complete_titles() { |
| 46 | 46 | $query = $this->db->select('tracker_titles.id, tracker_sites.site_class, tracker_titles.title, tracker_titles.title_url') |
| 47 | - ->from('tracker_chapters') |
|
| 48 | - ->join('tracker_titles', 'tracker_chapters.title_id = tracker_titles.id', 'left') |
|
| 49 | - ->join('tracker_sites', 'tracker_sites.id = tracker_titles.site_id', 'left') |
|
| 50 | - ->like('tracker_chapters.tags', 'complete') |
|
| 51 | - ->where('tracker_titles.status', 0) |
|
| 52 | - ->get(); |
|
| 47 | + ->from('tracker_chapters') |
|
| 48 | + ->join('tracker_titles', 'tracker_chapters.title_id = tracker_titles.id', 'left') |
|
| 49 | + ->join('tracker_sites', 'tracker_sites.id = tracker_titles.site_id', 'left') |
|
| 50 | + ->like('tracker_chapters.tags', 'complete') |
|
| 51 | + ->where('tracker_titles.status', 0) |
|
| 52 | + ->get(); |
|
| 53 | 53 | |
| 54 | 54 | $completeList = []; |
| 55 | 55 | if($query->num_rows() > 0) { |
@@ -68,10 +68,10 @@ discard block |
||
| 68 | 68 | |
| 69 | 69 | private function _update_mal_id() : void { |
| 70 | 70 | $query = $this->db->select('id, tags') |
| 71 | - ->from('tracker_chapters') |
|
| 72 | - ->where('tags REGEXP "[[:<:]]mal:([0-9]+|none)[[:>:]]"', NULL, FALSE) |
|
| 73 | - ->where('mal_id', NULL) |
|
| 74 | - ->get(); |
|
| 71 | + ->from('tracker_chapters') |
|
| 72 | + ->where('tags REGEXP "[[:<:]]mal:([0-9]+|none)[[:>:]]"', NULL, FALSE) |
|
| 73 | + ->where('mal_id', NULL) |
|
| 74 | + ->get(); |
|
| 75 | 75 | |
| 76 | 76 | |
| 77 | 77 | if($query->num_rows() > 0) { |
@@ -83,8 +83,8 @@ discard block |
||
| 83 | 83 | $new_tags = implode(',', array_diff( explode(',', $row->tags), [$matches[0]])); |
| 84 | 84 | |
| 85 | 85 | $this->db->set(['mal_id' => $malID, 'tags' => $new_tags, 'last_updated' => NULL]) |
| 86 | - ->where('id', $row->id) |
|
| 87 | - ->update('tracker_chapters'); |
|
| 86 | + ->where('id', $row->id) |
|
| 87 | + ->update('tracker_chapters'); |
|
| 88 | 88 | } |
| 89 | 89 | } |
| 90 | 90 | } |
@@ -53,9 +53,9 @@ |
||
| 53 | 53 | ]; |
| 54 | 54 | |
| 55 | 55 | $this->output |
| 56 | - ->set_status_header('200') |
|
| 57 | - ->set_content_type('application/json', 'utf-8') |
|
| 58 | - ->set_output(json_encode($json)); |
|
| 56 | + ->set_status_header('200') |
|
| 57 | + ->set_content_type('application/json', 'utf-8') |
|
| 58 | + ->set_output(json_encode($json)); |
|
| 59 | 59 | } else { |
| 60 | 60 | //TODO: We should probably try and have more verbose errors here. Return via JSON or something. |
| 61 | 61 | $this->output->set_status_header('400', 'Unable to update?'); |
@@ -15,11 +15,11 @@ discard block |
||
| 15 | 15 | */ |
| 16 | 16 | public function getID(string $titleURL, int $siteID, bool $create = TRUE, bool $returnData = FALSE) { |
| 17 | 17 | $query = $this->db->select('tracker_titles.id, tracker_titles.title, tracker_titles.title_url, tracker_titles.latest_chapter, tracker_titles.status, tracker_sites.site_class, (tracker_titles.last_checked > DATE_SUB(NOW(), INTERVAL 3 DAY)) AS active', FALSE) |
| 18 | - ->from('tracker_titles') |
|
| 19 | - ->join('tracker_sites', 'tracker_sites.id = tracker_titles.site_id', 'left') |
|
| 20 | - ->where('tracker_titles.title_url', $titleURL) |
|
| 21 | - ->where('tracker_titles.site_id', $siteID) |
|
| 22 | - ->get(); |
|
| 18 | + ->from('tracker_titles') |
|
| 19 | + ->join('tracker_sites', 'tracker_sites.id = tracker_titles.site_id', 'left') |
|
| 20 | + ->where('tracker_titles.title_url', $titleURL) |
|
| 21 | + ->where('tracker_titles.site_id', $siteID) |
|
| 22 | + ->get(); |
|
| 23 | 23 | |
| 24 | 24 | if($query->num_rows() > 0) { |
| 25 | 25 | $id = (int) $query->row('id'); |
@@ -32,8 +32,8 @@ discard block |
||
| 32 | 32 | //Make sure last_checked is always updated on successful run. |
| 33 | 33 | //CHECK: Is there a reason we aren't just doing this in updateTitleById? |
| 34 | 34 | $this->db->set('last_checked', 'CURRENT_TIMESTAMP', FALSE) |
| 35 | - ->where('id', $id) |
|
| 36 | - ->update('tracker_titles'); |
|
| 35 | + ->where('id', $id) |
|
| 36 | + ->update('tracker_titles'); |
|
| 37 | 37 | } |
| 38 | 38 | } else { |
| 39 | 39 | log_message('error', "{$query->row('title')} failed to update successfully"); |
@@ -73,9 +73,9 @@ discard block |
||
| 73 | 73 | */ |
| 74 | 74 | private function addTitle(string $titleURL, int $siteID) : int { |
| 75 | 75 | $query = $this->db->select('site, site_class') |
| 76 | - ->from('tracker_sites') |
|
| 77 | - ->where('id', $siteID) |
|
| 78 | - ->get(); |
|
| 76 | + ->from('tracker_sites') |
|
| 77 | + ->where('id', $siteID) |
|
| 78 | + ->get(); |
|
| 79 | 79 | |
| 80 | 80 | $titleData = $this->sites->{$query->row()->site_class}->getTitleData($titleURL, TRUE); |
| 81 | 81 | |
@@ -101,20 +101,20 @@ discard block |
||
| 101 | 101 | public function updateByID(int $titleID, string $latestChapter) : bool { |
| 102 | 102 | //FIXME: Really not too happy with how we're doing history stuff here, it just feels messy. |
| 103 | 103 | $query = $this->db->select('latest_chapter AS current_chapter') |
| 104 | - ->from('tracker_titles') |
|
| 105 | - ->where('id', $titleID) |
|
| 106 | - ->get(); |
|
| 104 | + ->from('tracker_titles') |
|
| 105 | + ->where('id', $titleID) |
|
| 106 | + ->get(); |
|
| 107 | 107 | $row = $query->row(); |
| 108 | 108 | |
| 109 | 109 | $success = $this->db->set(['latest_chapter' => $latestChapter, 'failed_checks' => 0]) //last_updated gets updated via a trigger if something changes |
| 110 | - ->where('id', $titleID) |
|
| 111 | - ->update('tracker_titles'); |
|
| 110 | + ->where('id', $titleID) |
|
| 111 | + ->update('tracker_titles'); |
|
| 112 | 112 | |
| 113 | 113 | if($this->db->affected_rows() > 0) { |
| 114 | 114 | //Clear hidden latest chapter |
| 115 | 115 | $this->db->set(['ignore_chapter' => 'NULL', 'last_updated' => 'last_updated'], NULL, FALSE) |
| 116 | - ->where('title_id', $titleID) |
|
| 117 | - ->update('tracker_chapters'); |
|
| 116 | + ->where('title_id', $titleID) |
|
| 117 | + ->update('tracker_chapters'); |
|
| 118 | 118 | } |
| 119 | 119 | |
| 120 | 120 | //Update History |
@@ -127,8 +127,8 @@ discard block |
||
| 127 | 127 | |
| 128 | 128 | public function updateFailedChecksByID(int $titleID) : bool { |
| 129 | 129 | $success = $this->db->set('failed_checks', 'failed_checks + 1', FALSE) |
| 130 | - ->where('id', $titleID) |
|
| 131 | - ->update('tracker_titles'); |
|
| 130 | + ->where('id', $titleID) |
|
| 131 | + ->update('tracker_titles'); |
|
| 132 | 132 | |
| 133 | 133 | return $success; |
| 134 | 134 | } |
@@ -140,9 +140,9 @@ discard block |
||
| 140 | 140 | */ |
| 141 | 141 | public function getSiteDataFromURL(string $site_url) { |
| 142 | 142 | $query = $this->db->select('*') |
| 143 | - ->from('tracker_sites') |
|
| 144 | - ->where('site', $site_url) |
|
| 145 | - ->get(); |
|
| 143 | + ->from('tracker_sites') |
|
| 144 | + ->where('site', $site_url) |
|
| 145 | + ->get(); |
|
| 146 | 146 | |
| 147 | 147 | return $query->row(); |
| 148 | 148 | } |
@@ -71,32 +71,32 @@ |
||
| 71 | 71 | |
| 72 | 72 | ////We need the series to be tracked |
| 73 | 73 | $idCQuery = $this->db->select('id') |
| 74 | - ->where('user_id', $userID) |
|
| 75 | - ->where('title_id', $titleID) |
|
| 76 | - ->get('tracker_chapters'); |
|
| 74 | + ->where('user_id', $userID) |
|
| 75 | + ->where('title_id', $titleID) |
|
| 76 | + ->get('tracker_chapters'); |
|
| 77 | 77 | if(!($idCQuery->num_rows() > 0)) { |
| 78 | 78 | //NOTE: This pretty much repeats a lot of what we already did above. Is there a better way to do this? |
| 79 | 79 | $this->Tracker->list->update($userID, $site, $title, $chapter, FALSE); |
| 80 | 80 | |
| 81 | 81 | $idCQuery = $this->db->select('id') |
| 82 | - ->where('user_id', $userID) |
|
| 83 | - ->where('title_id', $titleID) |
|
| 84 | - ->get('tracker_chapters'); |
|
| 82 | + ->where('user_id', $userID) |
|
| 83 | + ->where('title_id', $titleID) |
|
| 84 | + ->get('tracker_chapters'); |
|
| 85 | 85 | } |
| 86 | 86 | if($idCQuery->num_rows() > 0) { |
| 87 | 87 | $idCQueryRow = $idCQuery->row(); |
| 88 | 88 | |
| 89 | 89 | //Check if it is already favourited |
| 90 | 90 | $idFQuery = $this->db->select('id') |
| 91 | - ->where('chapter_id', $idCQueryRow->id) |
|
| 92 | - ->where('chapter', $chapter) |
|
| 93 | - ->get('tracker_favourites'); |
|
| 91 | + ->where('chapter_id', $idCQueryRow->id) |
|
| 92 | + ->where('chapter', $chapter) |
|
| 93 | + ->get('tracker_favourites'); |
|
| 94 | 94 | if($idFQuery->num_rows() > 0) { |
| 95 | 95 | //Chapter is already favourited, so remove it from DB |
| 96 | 96 | $idFQueryRow = $idFQuery->row(); |
| 97 | 97 | |
| 98 | 98 | $isSuccess = (bool) $this->db->where('id', $idFQueryRow->id) |
| 99 | - ->delete('tracker_favourites'); |
|
| 99 | + ->delete('tracker_favourites'); |
|
| 100 | 100 | |
| 101 | 101 | if($isSuccess) { |
| 102 | 102 | $success = array( |
@@ -74,8 +74,8 @@ discard block |
||
| 74 | 74 | //Make sure last_checked is always updated on successful run. |
| 75 | 75 | //CHECK: Is there a reason we aren't just doing this in updateByID? |
| 76 | 76 | $this->db->set('last_checked', 'CURRENT_TIMESTAMP', FALSE) |
| 77 | - ->where('id', $row->title_id) |
|
| 78 | - ->update('tracker_titles'); |
|
| 77 | + ->where('id', $row->title_id) |
|
| 78 | + ->update('tracker_titles'); |
|
| 79 | 79 | |
| 80 | 80 | print " - ({$titleData['latest_chapter']})\n"; |
| 81 | 81 | } else { |
@@ -152,8 +152,8 @@ discard block |
||
| 152 | 152 | //Make sure last_checked is always updated on successful run. |
| 153 | 153 | //CHECK: Is there a reason we aren't just doing this in updateByID? |
| 154 | 154 | $this->db->set('last_checked', 'CURRENT_TIMESTAMP', FALSE) |
| 155 | - ->where('id', $row->title_id) |
|
| 156 | - ->update('tracker_titles'); |
|
| 155 | + ->where('id', $row->title_id) |
|
| 156 | + ->update('tracker_titles'); |
|
| 157 | 157 | |
| 158 | 158 | print " - ({$titleData['latest_chapter']})\n"; |
| 159 | 159 | } else { |
@@ -177,10 +177,10 @@ discard block |
||
| 177 | 177 | */ |
| 178 | 178 | public function updateCustom() { |
| 179 | 179 | $query = $this->db->select('*') |
| 180 | - ->from('tracker_sites') |
|
| 181 | - ->where('status', 'enabled') |
|
| 182 | - ->where('tracker_sites.use_custom', 'Y') |
|
| 183 | - ->get(); |
|
| 180 | + ->from('tracker_sites') |
|
| 181 | + ->where('status', 'enabled') |
|
| 182 | + ->where('tracker_sites.use_custom', 'Y') |
|
| 183 | + ->get(); |
|
| 184 | 184 | |
| 185 | 185 | $sites = $query->result_array(); |
| 186 | 186 | foreach ($sites as $site) { |
@@ -196,8 +196,8 @@ discard block |
||
| 196 | 196 | //Make sure last_checked is always updated on successful run. |
| 197 | 197 | //CHECK: Is there a reason we aren't just doing this in updateByID? |
| 198 | 198 | $this->db->set('last_checked', 'CURRENT_TIMESTAMP', FALSE) |
| 199 | - ->where('id', $titleID) |
|
| 200 | - ->update('tracker_titles'); |
|
| 199 | + ->where('id', $titleID) |
|
| 200 | + ->update('tracker_titles'); |
|
| 201 | 201 | |
| 202 | 202 | print " - ({$titleData['latest_chapter']})\n"; |
| 203 | 203 | } else { |
@@ -224,13 +224,13 @@ discard block |
||
| 224 | 224 | |
| 225 | 225 | public function refollowCustom() { |
| 226 | 226 | $query = $this->db->select('tracker_titles.id, tracker_titles.title_url, tracker_sites.site_class') |
| 227 | - ->from('tracker_titles') |
|
| 228 | - ->join('tracker_sites', 'tracker_sites.id = tracker_titles.site_id', 'left') |
|
| 229 | - ->where('tracker_titles.followed','N') |
|
| 230 | - ->where('tracker_titles !=', '255') |
|
| 231 | - ->where('tracker_sites.status', 'enabled') |
|
| 232 | - ->where('tracker_sites.use_custom', 'Y') |
|
| 233 | - ->get(); |
|
| 227 | + ->from('tracker_titles') |
|
| 228 | + ->join('tracker_sites', 'tracker_sites.id = tracker_titles.site_id', 'left') |
|
| 229 | + ->where('tracker_titles.followed','N') |
|
| 230 | + ->where('tracker_titles !=', '255') |
|
| 231 | + ->where('tracker_sites.status', 'enabled') |
|
| 232 | + ->where('tracker_sites.use_custom', 'Y') |
|
| 233 | + ->get(); |
|
| 234 | 234 | |
| 235 | 235 | if($query->num_rows() > 0) { |
| 236 | 236 | foreach($query->result() as $row) { |
@@ -241,8 +241,8 @@ discard block |
||
| 241 | 241 | |
| 242 | 242 | if(!empty($titleData)) { |
| 243 | 243 | $this->db->set($titleData) |
| 244 | - ->where('id', $row->id) |
|
| 245 | - ->update('tracker_titles'); |
|
| 244 | + ->where('id', $row->id) |
|
| 245 | + ->update('tracker_titles'); |
|
| 246 | 246 | |
| 247 | 247 | print "> {$row->site_class}:{$row->id}:{$row->title_url} FOLLOWED\n"; |
| 248 | 248 | } else { |
@@ -290,8 +290,8 @@ discard block |
||
| 290 | 290 | if($titleData['title'] && is_array($titleData) && !is_null($titleData['latest_chapter'])) { |
| 291 | 291 | if($titleData['title'] !== $row->title) { |
| 292 | 292 | $this->db->set('title', $titleData['title']) |
| 293 | - ->where('id', $row->id) |
|
| 294 | - ->update('tracker_titles'); |
|
| 293 | + ->where('id', $row->id) |
|
| 294 | + ->update('tracker_titles'); |
|
| 295 | 295 | //TODO: Add to history somehow? |
| 296 | 296 | print " - NEW TITLE ({$titleData['title']})\n"; |
| 297 | 297 | } else { |
@@ -301,8 +301,8 @@ discard block |
||
| 301 | 301 | //We might as well try to update as well. |
| 302 | 302 | if($this->Tracker->title->updateByID((int) $row->id, $titleData['latest_chapter'])) { |
| 303 | 303 | $this->db->set('last_checked', 'CURRENT_TIMESTAMP', FALSE) |
| 304 | - ->where('id', $row->id) |
|
| 305 | - ->update('tracker_titles'); |
|
| 304 | + ->where('id', $row->id) |
|
| 305 | + ->update('tracker_titles'); |
|
| 306 | 306 | } |
| 307 | 307 | } else { |
| 308 | 308 | log_message('error', "{$row->title} failed to update title successfully"); |
@@ -21,11 +21,11 @@ |
||
| 21 | 21 | $this->ci->load->config('recaptcha', TRUE); |
| 22 | 22 | if ($this->ci->config->item('recaptcha_secretkey', 'recaptcha') == NULL || $this->ci->config->item('recaptcha_secretkey', 'recaptcha') == "") { |
| 23 | 23 | die("To use reCAPTCHA you must get an API key from <a href='" |
| 24 | - . $this->signup_url . "'>" . $this->signup_url . "</a>"); |
|
| 24 | + . $this->signup_url . "'>" . $this->signup_url . "</a>"); |
|
| 25 | 25 | } |
| 26 | 26 | if ($this->ci->config->item('recaptcha_sitekey', 'recaptcha') == NULL || $this->ci->config->item('recaptcha_sitekey', 'recaptcha') == "") { |
| 27 | 27 | die("To use reCAPTCHA you must get an API key from <a href='" |
| 28 | - . $this->signup_url . "'>" . $this->signup_url . "</a>"); |
|
| 28 | + . $this->signup_url . "'>" . $this->signup_url . "</a>"); |
|
| 29 | 29 | } |
| 30 | 30 | $this->_secret = $this->ci->config->item('recaptcha_secretkey', 'recaptcha'); |
| 31 | 31 | $this->_sitekey = $this->ci->config->item('recaptcha_sitekey', 'recaptcha'); |
@@ -12,223 +12,223 @@ |
||
| 12 | 12 | |
| 13 | 13 | class Limiter { |
| 14 | 14 | |
| 15 | - /** @type CI_Controller */ |
|
| 16 | - protected $CI; |
|
| 17 | - protected $table = 'rate_limit'; |
|
| 18 | - protected $base_limit = 0; // infinite |
|
| 19 | - protected $whitelist = array('127.0.0.1'); |
|
| 20 | - protected $header_show = TRUE; |
|
| 21 | - protected $checksum_algorithm = 'md4'; |
|
| 22 | - protected $header_prefix = 'X-RateLimit-'; |
|
| 23 | - protected $flush_on_abort = FALSE; |
|
| 24 | - |
|
| 25 | - protected $user_data = array(); |
|
| 26 | - protected $user_hash = FALSE; |
|
| 27 | - |
|
| 28 | - private $_truncated = FALSE; |
|
| 29 | - private $_info_cache = array(); |
|
| 30 | - |
|
| 31 | - private $_sql_truncate = 'DELETE FROM `RATE_TABLE` WHERE `start` < (NOW() - INTERVAL 1 HOUR)'; |
|
| 32 | - private $_sql_info = 'SELECT `count`, `start`, (`start` + INTERVAL (1 - TIMESTAMPDIFF(HOUR, UTC_TIMESTAMP(), NOW())) HOUR) \'reset_epoch\' FROM `RATE_TABLE` WHERE `client` = ? AND `target` = ?'; |
|
| 33 | - private $_sql_update = 'INSERT INTO `RATE_TABLE` (`client`, `target`) VALUES (?, ?) ON DUPLICATE KEY UPDATE `count` = `count` + 1'; |
|
| 34 | - private $_config_fields = array( |
|
| 35 | - 'table', 'base_limit', 'checksum_algorithm', |
|
| 36 | - 'header', 'header_prefix', 'flush_on_abort' |
|
| 37 | - ); |
|
| 38 | - |
|
| 39 | - public function __construct($config = array()) { |
|
| 40 | - $this->CI = &get_instance(); |
|
| 41 | - |
|
| 42 | - if(!is_array($config)) { |
|
| 43 | - $config = array(); |
|
| 44 | - } |
|
| 45 | - |
|
| 46 | - foreach($this->_config_fields as $field) { |
|
| 47 | - if(array_key_exists($field, $config)) { |
|
| 48 | - $this->{$field} = $config[$field]; |
|
| 49 | - } |
|
| 50 | - } |
|
| 51 | - |
|
| 52 | - $sql = array('truncate', 'info', 'update'); |
|
| 53 | - foreach($sql as $s) { |
|
| 54 | - $this->{"_sql_$s"} = str_replace('RATE_TABLE', $this->table, $this->{"_sql_$s"}); |
|
| 55 | - } |
|
| 56 | - |
|
| 57 | - $this->add_user_data($this->CI->input->ip_address()); |
|
| 58 | - |
|
| 59 | - log_message('debug', 'Limiter Class Initialized'); |
|
| 60 | - } |
|
| 61 | - |
|
| 62 | - /** |
|
| 63 | - * Rate limits the amount of requests that can be sent by a client. |
|
| 64 | - * |
|
| 65 | - * @param string $target |
|
| 66 | - * @param int $req_per_hour Overrides base_limit setting if set |
|
| 67 | - * @param bool $flush_on_abort Overrides flush_on_abort setting if set |
|
| 68 | - * @param bool $show_header Overrides header_show setting if set |
|
| 69 | - * @return bool Should request be aborted |
|
| 70 | - */ |
|
| 71 | - public function limit($target = '_global', $req_per_hour = null, $flush_on_abort = null, $show_header = null) { |
|
| 72 | - $req_per_hour = $req_per_hour !== null ? $req_per_hour : $this->base_limit; |
|
| 73 | - $flush_on_abort = $flush_on_abort !== null ? $flush_on_abort : $this->flush_on_abort; |
|
| 74 | - $show_header = $show_header !== null ? $show_header : $this->header_show; |
|
| 75 | - |
|
| 76 | - $truncated = $this->_truncate(); |
|
| 77 | - if(!$truncated) { |
|
| 78 | - log_message('DEBUG', 'WARN: Could not truncate rate limit table'); |
|
| 79 | - } |
|
| 80 | - |
|
| 81 | - if($this->is_whitelisted()) { |
|
| 82 | - $req_per_hour = 0; |
|
| 83 | - } |
|
| 84 | - |
|
| 85 | - $abort = FALSE; |
|
| 86 | - if($req_per_hour > 0) { |
|
| 87 | - $info = $this->get_limit_info($target); |
|
| 88 | - |
|
| 89 | - if($info === FALSE) { |
|
| 90 | - $info = new stdClass(); |
|
| 91 | - $info->count = 0; |
|
| 92 | - $info->reset_epoch = gmdate('d M Y H:i:s', time() + (60 * 60)); |
|
| 93 | - $info->start = date('d M Y H:i:s'); |
|
| 94 | - } |
|
| 95 | - |
|
| 96 | - if($req_per_hour - $info->count > 0) { |
|
| 97 | - $data = array('client' => $this->get_hash(), 'target' => $target); |
|
| 98 | - $this->CI->db->query($this->_sql_update, $data); |
|
| 99 | - $info->count++; |
|
| 100 | - } else { |
|
| 101 | - $abort = TRUE; |
|
| 102 | - } |
|
| 103 | - |
|
| 104 | - if($show_header === TRUE) { |
|
| 105 | - $headers = array( |
|
| 106 | - 'Limit' => $req_per_hour, |
|
| 107 | - 'Remaining' => $req_per_hour - $info->count, |
|
| 108 | - 'Reset' => strtotime($info->reset_epoch), |
|
| 109 | - ); |
|
| 110 | - |
|
| 111 | - foreach(array_keys($headers) as $h) { |
|
| 112 | - $this->CI->output->set_header("$this->header_prefix$h: $headers[$h]"); |
|
| 113 | - } |
|
| 114 | - } |
|
| 115 | - |
|
| 116 | - $this->_info_cache[$target] = $info; |
|
| 117 | - |
|
| 118 | - |
|
| 119 | - if($abort) { |
|
| 120 | - $retry_seconds = strtotime($info->reset_epoch) - strtotime(gmdate('d M Y H:i:s')); |
|
| 121 | - $this->CI->output->set_header("Retry-After: $retry_seconds"); |
|
| 122 | - $this->CI->output->set_status_header(503, 'Rate limit reached'); |
|
| 123 | - |
|
| 124 | - if($flush_on_abort) { |
|
| 125 | - $this->CI->output->_display(); |
|
| 126 | - exit; |
|
| 127 | - } |
|
| 128 | - } |
|
| 129 | - } |
|
| 130 | - |
|
| 131 | - return $abort; |
|
| 132 | - } |
|
| 133 | - |
|
| 134 | - /** |
|
| 135 | - * Forget the client ever visited $target. |
|
| 136 | - * |
|
| 137 | - * @param string $target |
|
| 138 | - */ |
|
| 139 | - public function reset_rate($target = '_global') { |
|
| 140 | - $this->CI->db->delete($this->table, array( |
|
| 141 | - 'client' => $this->get_hash(), |
|
| 142 | - 'target' => $target |
|
| 143 | - )); |
|
| 144 | - } |
|
| 145 | - |
|
| 146 | - /** |
|
| 147 | - * Forgets all rate limits attached to the client. |
|
| 148 | - */ |
|
| 149 | - public function forget_client() { |
|
| 150 | - $this->CI->db->delete($this->table, array('client' => $this->get_hash())); |
|
| 151 | - } |
|
| 152 | - |
|
| 153 | - /** |
|
| 154 | - * Used to obtain the client hash. |
|
| 155 | - * |
|
| 156 | - * Returns false if hash generation failed |
|
| 157 | - * @return string |
|
| 158 | - */ |
|
| 159 | - public function get_hash() { |
|
| 160 | - if($this->user_hash === FALSE) { |
|
| 161 | - $this->user_hash = $this->_generate_hash(); |
|
| 162 | - } |
|
| 163 | - return $this->user_hash; |
|
| 164 | - } |
|
| 165 | - |
|
| 166 | - /** |
|
| 167 | - * Adds entropy to the client hash. Make |
|
| 168 | - * sure that this is some sort of static |
|
| 169 | - * data such as a username/id. |
|
| 170 | - * |
|
| 171 | - * @param string $data Any seeding data |
|
| 172 | - */ |
|
| 173 | - public function add_user_data($data) { |
|
| 174 | - array_push($this->user_data, (string) $data); |
|
| 175 | - |
|
| 176 | - if(count($this->_info_cache) !== 0) { |
|
| 177 | - log_message('DEBUG', 'WARN: Emptying info cache due to user data changing'); |
|
| 178 | - $this->_info_cache = array(); // Empty cache |
|
| 179 | - } |
|
| 180 | - |
|
| 181 | - if($this->user_hash !== FALSE) { |
|
| 182 | - log_message('DEBUG', 'WARN: Adding user data after hash was generated'); |
|
| 183 | - $this->user_hash = $this->_generate_hash(); |
|
| 184 | - } |
|
| 185 | - } |
|
| 186 | - |
|
| 187 | - /** |
|
| 188 | - * Get target rate info |
|
| 189 | - * |
|
| 190 | - * @param string $target |
|
| 191 | - * @return stdClass|false Info object, returns false if no info is present |
|
| 192 | - */ |
|
| 193 | - public function get_limit_info($target = '_global') { |
|
| 194 | - if(!array_key_exists($target, $this->_info_cache)) { |
|
| 195 | - $data = array('client' => $this->get_hash(), 'target' => $target); |
|
| 196 | - $info = $this->CI->db->query($this->_sql_info, $data)->row(); |
|
| 197 | - |
|
| 198 | - $this->_info_cache[$target] = $info; |
|
| 199 | - } else { |
|
| 200 | - $info = $this->_info_cache[$target]; |
|
| 201 | - } |
|
| 202 | - |
|
| 203 | - $valid_data = isset($info->count); |
|
| 204 | - return $valid_data ? $info : FALSE; |
|
| 205 | - } |
|
| 206 | - |
|
| 207 | - /** |
|
| 208 | - * @param $target |
|
| 209 | - * @return integer Amount of attempts |
|
| 210 | - */ |
|
| 211 | - public function get_attempts($target) { |
|
| 212 | - return $this->get_limit_info($target)->count; |
|
| 213 | - } |
|
| 214 | - |
|
| 215 | - /** |
|
| 216 | - * @param null $ip If null current IP |
|
| 217 | - * @return bool Is whitelisted |
|
| 218 | - */ |
|
| 219 | - public function is_whitelisted($ip = null) { |
|
| 220 | - $ip = $ip ?: $this->CI->input->ip_address(); |
|
| 221 | - return in_array($ip, $this->whitelist); |
|
| 222 | - } |
|
| 223 | - |
|
| 224 | - private function _truncate() { |
|
| 225 | - if(!$this->_truncated) { |
|
| 226 | - $this->_truncated = $this->CI->db->query($this->_sql_truncate); |
|
| 227 | - } |
|
| 228 | - return $this->_truncated; |
|
| 229 | - } |
|
| 230 | - |
|
| 231 | - private function _generate_hash() { |
|
| 232 | - return hash($this->checksum_algorithm, join('%', $this->user_data)); |
|
| 233 | - } |
|
| 15 | + /** @type CI_Controller */ |
|
| 16 | + protected $CI; |
|
| 17 | + protected $table = 'rate_limit'; |
|
| 18 | + protected $base_limit = 0; // infinite |
|
| 19 | + protected $whitelist = array('127.0.0.1'); |
|
| 20 | + protected $header_show = TRUE; |
|
| 21 | + protected $checksum_algorithm = 'md4'; |
|
| 22 | + protected $header_prefix = 'X-RateLimit-'; |
|
| 23 | + protected $flush_on_abort = FALSE; |
|
| 24 | + |
|
| 25 | + protected $user_data = array(); |
|
| 26 | + protected $user_hash = FALSE; |
|
| 27 | + |
|
| 28 | + private $_truncated = FALSE; |
|
| 29 | + private $_info_cache = array(); |
|
| 30 | + |
|
| 31 | + private $_sql_truncate = 'DELETE FROM `RATE_TABLE` WHERE `start` < (NOW() - INTERVAL 1 HOUR)'; |
|
| 32 | + private $_sql_info = 'SELECT `count`, `start`, (`start` + INTERVAL (1 - TIMESTAMPDIFF(HOUR, UTC_TIMESTAMP(), NOW())) HOUR) \'reset_epoch\' FROM `RATE_TABLE` WHERE `client` = ? AND `target` = ?'; |
|
| 33 | + private $_sql_update = 'INSERT INTO `RATE_TABLE` (`client`, `target`) VALUES (?, ?) ON DUPLICATE KEY UPDATE `count` = `count` + 1'; |
|
| 34 | + private $_config_fields = array( |
|
| 35 | + 'table', 'base_limit', 'checksum_algorithm', |
|
| 36 | + 'header', 'header_prefix', 'flush_on_abort' |
|
| 37 | + ); |
|
| 38 | + |
|
| 39 | + public function __construct($config = array()) { |
|
| 40 | + $this->CI = &get_instance(); |
|
| 41 | + |
|
| 42 | + if(!is_array($config)) { |
|
| 43 | + $config = array(); |
|
| 44 | + } |
|
| 45 | + |
|
| 46 | + foreach($this->_config_fields as $field) { |
|
| 47 | + if(array_key_exists($field, $config)) { |
|
| 48 | + $this->{$field} = $config[$field]; |
|
| 49 | + } |
|
| 50 | + } |
|
| 51 | + |
|
| 52 | + $sql = array('truncate', 'info', 'update'); |
|
| 53 | + foreach($sql as $s) { |
|
| 54 | + $this->{"_sql_$s"} = str_replace('RATE_TABLE', $this->table, $this->{"_sql_$s"}); |
|
| 55 | + } |
|
| 56 | + |
|
| 57 | + $this->add_user_data($this->CI->input->ip_address()); |
|
| 58 | + |
|
| 59 | + log_message('debug', 'Limiter Class Initialized'); |
|
| 60 | + } |
|
| 61 | + |
|
| 62 | + /** |
|
| 63 | + * Rate limits the amount of requests that can be sent by a client. |
|
| 64 | + * |
|
| 65 | + * @param string $target |
|
| 66 | + * @param int $req_per_hour Overrides base_limit setting if set |
|
| 67 | + * @param bool $flush_on_abort Overrides flush_on_abort setting if set |
|
| 68 | + * @param bool $show_header Overrides header_show setting if set |
|
| 69 | + * @return bool Should request be aborted |
|
| 70 | + */ |
|
| 71 | + public function limit($target = '_global', $req_per_hour = null, $flush_on_abort = null, $show_header = null) { |
|
| 72 | + $req_per_hour = $req_per_hour !== null ? $req_per_hour : $this->base_limit; |
|
| 73 | + $flush_on_abort = $flush_on_abort !== null ? $flush_on_abort : $this->flush_on_abort; |
|
| 74 | + $show_header = $show_header !== null ? $show_header : $this->header_show; |
|
| 75 | + |
|
| 76 | + $truncated = $this->_truncate(); |
|
| 77 | + if(!$truncated) { |
|
| 78 | + log_message('DEBUG', 'WARN: Could not truncate rate limit table'); |
|
| 79 | + } |
|
| 80 | + |
|
| 81 | + if($this->is_whitelisted()) { |
|
| 82 | + $req_per_hour = 0; |
|
| 83 | + } |
|
| 84 | + |
|
| 85 | + $abort = FALSE; |
|
| 86 | + if($req_per_hour > 0) { |
|
| 87 | + $info = $this->get_limit_info($target); |
|
| 88 | + |
|
| 89 | + if($info === FALSE) { |
|
| 90 | + $info = new stdClass(); |
|
| 91 | + $info->count = 0; |
|
| 92 | + $info->reset_epoch = gmdate('d M Y H:i:s', time() + (60 * 60)); |
|
| 93 | + $info->start = date('d M Y H:i:s'); |
|
| 94 | + } |
|
| 95 | + |
|
| 96 | + if($req_per_hour - $info->count > 0) { |
|
| 97 | + $data = array('client' => $this->get_hash(), 'target' => $target); |
|
| 98 | + $this->CI->db->query($this->_sql_update, $data); |
|
| 99 | + $info->count++; |
|
| 100 | + } else { |
|
| 101 | + $abort = TRUE; |
|
| 102 | + } |
|
| 103 | + |
|
| 104 | + if($show_header === TRUE) { |
|
| 105 | + $headers = array( |
|
| 106 | + 'Limit' => $req_per_hour, |
|
| 107 | + 'Remaining' => $req_per_hour - $info->count, |
|
| 108 | + 'Reset' => strtotime($info->reset_epoch), |
|
| 109 | + ); |
|
| 110 | + |
|
| 111 | + foreach(array_keys($headers) as $h) { |
|
| 112 | + $this->CI->output->set_header("$this->header_prefix$h: $headers[$h]"); |
|
| 113 | + } |
|
| 114 | + } |
|
| 115 | + |
|
| 116 | + $this->_info_cache[$target] = $info; |
|
| 117 | + |
|
| 118 | + |
|
| 119 | + if($abort) { |
|
| 120 | + $retry_seconds = strtotime($info->reset_epoch) - strtotime(gmdate('d M Y H:i:s')); |
|
| 121 | + $this->CI->output->set_header("Retry-After: $retry_seconds"); |
|
| 122 | + $this->CI->output->set_status_header(503, 'Rate limit reached'); |
|
| 123 | + |
|
| 124 | + if($flush_on_abort) { |
|
| 125 | + $this->CI->output->_display(); |
|
| 126 | + exit; |
|
| 127 | + } |
|
| 128 | + } |
|
| 129 | + } |
|
| 130 | + |
|
| 131 | + return $abort; |
|
| 132 | + } |
|
| 133 | + |
|
| 134 | + /** |
|
| 135 | + * Forget the client ever visited $target. |
|
| 136 | + * |
|
| 137 | + * @param string $target |
|
| 138 | + */ |
|
| 139 | + public function reset_rate($target = '_global') { |
|
| 140 | + $this->CI->db->delete($this->table, array( |
|
| 141 | + 'client' => $this->get_hash(), |
|
| 142 | + 'target' => $target |
|
| 143 | + )); |
|
| 144 | + } |
|
| 145 | + |
|
| 146 | + /** |
|
| 147 | + * Forgets all rate limits attached to the client. |
|
| 148 | + */ |
|
| 149 | + public function forget_client() { |
|
| 150 | + $this->CI->db->delete($this->table, array('client' => $this->get_hash())); |
|
| 151 | + } |
|
| 152 | + |
|
| 153 | + /** |
|
| 154 | + * Used to obtain the client hash. |
|
| 155 | + * |
|
| 156 | + * Returns false if hash generation failed |
|
| 157 | + * @return string |
|
| 158 | + */ |
|
| 159 | + public function get_hash() { |
|
| 160 | + if($this->user_hash === FALSE) { |
|
| 161 | + $this->user_hash = $this->_generate_hash(); |
|
| 162 | + } |
|
| 163 | + return $this->user_hash; |
|
| 164 | + } |
|
| 165 | + |
|
| 166 | + /** |
|
| 167 | + * Adds entropy to the client hash. Make |
|
| 168 | + * sure that this is some sort of static |
|
| 169 | + * data such as a username/id. |
|
| 170 | + * |
|
| 171 | + * @param string $data Any seeding data |
|
| 172 | + */ |
|
| 173 | + public function add_user_data($data) { |
|
| 174 | + array_push($this->user_data, (string) $data); |
|
| 175 | + |
|
| 176 | + if(count($this->_info_cache) !== 0) { |
|
| 177 | + log_message('DEBUG', 'WARN: Emptying info cache due to user data changing'); |
|
| 178 | + $this->_info_cache = array(); // Empty cache |
|
| 179 | + } |
|
| 180 | + |
|
| 181 | + if($this->user_hash !== FALSE) { |
|
| 182 | + log_message('DEBUG', 'WARN: Adding user data after hash was generated'); |
|
| 183 | + $this->user_hash = $this->_generate_hash(); |
|
| 184 | + } |
|
| 185 | + } |
|
| 186 | + |
|
| 187 | + /** |
|
| 188 | + * Get target rate info |
|
| 189 | + * |
|
| 190 | + * @param string $target |
|
| 191 | + * @return stdClass|false Info object, returns false if no info is present |
|
| 192 | + */ |
|
| 193 | + public function get_limit_info($target = '_global') { |
|
| 194 | + if(!array_key_exists($target, $this->_info_cache)) { |
|
| 195 | + $data = array('client' => $this->get_hash(), 'target' => $target); |
|
| 196 | + $info = $this->CI->db->query($this->_sql_info, $data)->row(); |
|
| 197 | + |
|
| 198 | + $this->_info_cache[$target] = $info; |
|
| 199 | + } else { |
|
| 200 | + $info = $this->_info_cache[$target]; |
|
| 201 | + } |
|
| 202 | + |
|
| 203 | + $valid_data = isset($info->count); |
|
| 204 | + return $valid_data ? $info : FALSE; |
|
| 205 | + } |
|
| 206 | + |
|
| 207 | + /** |
|
| 208 | + * @param $target |
|
| 209 | + * @return integer Amount of attempts |
|
| 210 | + */ |
|
| 211 | + public function get_attempts($target) { |
|
| 212 | + return $this->get_limit_info($target)->count; |
|
| 213 | + } |
|
| 214 | + |
|
| 215 | + /** |
|
| 216 | + * @param null $ip If null current IP |
|
| 217 | + * @return bool Is whitelisted |
|
| 218 | + */ |
|
| 219 | + public function is_whitelisted($ip = null) { |
|
| 220 | + $ip = $ip ?: $this->CI->input->ip_address(); |
|
| 221 | + return in_array($ip, $this->whitelist); |
|
| 222 | + } |
|
| 223 | + |
|
| 224 | + private function _truncate() { |
|
| 225 | + if(!$this->_truncated) { |
|
| 226 | + $this->_truncated = $this->CI->db->query($this->_sql_truncate); |
|
| 227 | + } |
|
| 228 | + return $this->_truncated; |
|
| 229 | + } |
|
| 230 | + |
|
| 231 | + private function _generate_hash() { |
|
| 232 | + return hash($this->checksum_algorithm, join('%', $this->user_data)); |
|
| 233 | + } |
|
| 234 | 234 | } |
@@ -1,7 +1,7 @@ |
||
| 1 | 1 | <?php |
| 2 | 2 | |
| 3 | 3 | if (! defined('BASEPATH')) { |
| 4 | - exit('No direct script access allowed'); |
|
| 4 | + exit('No direct script access allowed'); |
|
| 5 | 5 | } |
| 6 | 6 | |
| 7 | 7 | /** |