Browse Source

More classes

pjc 5 years ago
parent
commit
14dcbf65eb

+ 39
- 11
classes/cache.class.php View File

51
     public $Time = 0;
51
     public $Time = 0;
52
     private $Servers = [];
52
     private $Servers = [];
53
     private $PersistentKeys = [
53
     private $PersistentKeys = [
54
-    'ajax_requests_*',
55
-    'query_lock_*',
56
-    'stats_*',
57
-    'top10tor_*',
58
-    'users_snatched_*',
59
-
60
-    // Cache-based features
61
-    'global_notification',
62
-    'notifications_one_reads_*',
63
-  ];
54
+        'ajax_requests_*',
55
+        'query_lock_*',
56
+        'stats_*',
57
+        'top10tor_*',
58
+        'users_snatched_*',
59
+
60
+            // Cache-based features
61
+            'global_notification',
62
+            'notifications_one_reads_*',
63
+    ];
64
     private $ClearedKeys = [];
64
     private $ClearedKeys = [];
65
-
66
     public $CanClear = false;
65
     public $CanClear = false;
67
     public $InternalCache = true;
66
     public $InternalCache = true;
68
 
67
 
71
         if (is_subclass_of($this, 'Memcached')) {
70
         if (is_subclass_of($this, 'Memcached')) {
72
             parent::__construct();
71
             parent::__construct();
73
         }
72
         }
73
+
74
         $this->Servers = $Servers;
74
         $this->Servers = $Servers;
75
         foreach ($Servers as $Server) {
75
         foreach ($Servers as $Server) {
76
             if (is_subclass_of($this, 'Memcache')) {
76
             if (is_subclass_of($this, 'Memcache')) {
99
         if (empty($Key)) {
99
         if (empty($Key)) {
100
             trigger_error('Cache insert failed for empty key');
100
             trigger_error('Cache insert failed for empty key');
101
         }
101
         }
102
+
102
         $SetParams = [$Key, $Value, 0, $Duration];
103
         $SetParams = [$Key, $Value, 0, $Duration];
103
         if (is_subclass_of($this, 'Memcached')) {
104
         if (is_subclass_of($this, 'Memcached')) {
104
             unset($SetParams[2]);
105
             unset($SetParams[2]);
105
         }
106
         }
107
+
106
         if (!$this->set(...$SetParams)) {
108
         if (!$this->set(...$SetParams)) {
107
             trigger_error("Cache insert failed for key $Key");
109
             trigger_error("Cache insert failed for key $Key");
108
         }
110
         }
111
+
109
         if ($this->InternalCache && array_key_exists($Key, $this->CacheHits)) {
112
         if ($this->InternalCache && array_key_exists($Key, $this->CacheHits)) {
110
             $this->CacheHits[$Key] = $Value;
113
             $this->CacheHits[$Key] = $Value;
111
         }
114
         }
125
     {
128
     {
126
         $StartTime = microtime(true);
129
         $StartTime = microtime(true);
127
         $ReplaceParams = [$Key, $Value, false, $Duration];
130
         $ReplaceParams = [$Key, $Value, false, $Duration];
131
+
128
         if (is_subclass_of($this, 'Memcached')) {
132
         if (is_subclass_of($this, 'Memcached')) {
129
             unset($ReplaceParams[2]);
133
             unset($ReplaceParams[2]);
130
         }
134
         }
131
         $this->replace(...$ReplaceParams);
135
         $this->replace(...$ReplaceParams);
136
+
132
         if ($this->InternalCache && array_key_exists($Key, $this->CacheHits)) {
137
         if ($this->InternalCache && array_key_exists($Key, $this->CacheHits)) {
133
             $this->CacheHits[$Key] = $Value;
138
             $this->CacheHits[$Key] = $Value;
134
         }
139
         }
140
         if (!$this->InternalCache) {
145
         if (!$this->InternalCache) {
141
             $NoCache = true;
146
             $NoCache = true;
142
         }
147
         }
148
+
143
         $StartTime = microtime(true);
149
         $StartTime = microtime(true);
144
         if (empty($Key)) {
150
         if (empty($Key)) {
145
             trigger_error('Cache retrieval failed for empty key');
151
             trigger_error('Cache retrieval failed for empty key');
158
                         }
164
                         }
159
                     }
165
                     }
160
                 }
166
                 }
167
+
161
                 $this->delete($Key);
168
                 $this->delete($Key);
162
                 $this->Time += (microtime(true) - $StartTime) * 1000;
169
                 $this->Time += (microtime(true) - $StartTime) * 1000;
163
                 return false;
170
                 return false;
186
         if ($Return !== false) {
193
         if ($Return !== false) {
187
             $this->CacheHits[$Key] = $NoCache ? null : $Return;
194
             $this->CacheHits[$Key] = $NoCache ? null : $Return;
188
         }
195
         }
196
+
189
         $this->Time += (microtime(true) - $StartTime) * 1000;
197
         $this->Time += (microtime(true) - $StartTime) * 1000;
190
         return $Return;
198
         return $Return;
191
     }
199
     }
197
         if (empty($Key)) {
205
         if (empty($Key)) {
198
             trigger_error('Cache deletion failed for empty key');
206
             trigger_error('Cache deletion failed for empty key');
199
         }
207
         }
208
+
200
         if (!$this->delete($Key)) {
209
         if (!$this->delete($Key)) {
201
             //trigger_error("Cache delete failed for key $Key");
210
             //trigger_error("Cache delete failed for key $Key");
202
         }
211
         }
212
+
203
         unset($this->CacheHits[$Key]);
213
         unset($this->CacheHits[$Key]);
204
         $this->Time += (microtime(true) - $StartTime) * 1000;
214
         $this->Time += (microtime(true) - $StartTime) * 1000;
205
     }
215
     }
208
     {
218
     {
209
         $StartTime = microtime(true);
219
         $StartTime = microtime(true);
210
         $NewVal = $this->increment($Key, $Value);
220
         $NewVal = $this->increment($Key, $Value);
221
+
211
         if (isset($this->CacheHits[$Key])) {
222
         if (isset($this->CacheHits[$Key])) {
212
             $this->CacheHits[$Key] = $NewVal;
223
             $this->CacheHits[$Key] = $NewVal;
213
         }
224
         }
218
     {
229
     {
219
         $StartTime = microtime(true);
230
         $StartTime = microtime(true);
220
         $NewVal = $this->decrement($Key, $Value);
231
         $NewVal = $this->decrement($Key, $Value);
232
+
221
         if (isset($this->CacheHits[$Key])) {
233
         if (isset($this->CacheHits[$Key])) {
222
             $this->CacheHits[$Key] = $NewVal;
234
             $this->CacheHits[$Key] = $NewVal;
223
         }
235
         }
235
             $this->MemcacheDBKey = '';
247
             $this->MemcacheDBKey = '';
236
             return false;
248
             return false;
237
         }
249
         }
250
+
238
         $this->MemcacheDBArray = $Value;
251
         $this->MemcacheDBArray = $Value;
239
         $this->MemcacheDBKey = $Key;
252
         $this->MemcacheDBKey = $Key;
240
         $this->InTransaction = true;
253
         $this->InTransaction = true;
253
         if (!$this->InTransaction) {
266
         if (!$this->InTransaction) {
254
             return false;
267
             return false;
255
         }
268
         }
269
+
256
         $this->cache_value($this->MemcacheDBKey, $this->MemcacheDBArray, $Time);
270
         $this->cache_value($this->MemcacheDBKey, $this->MemcacheDBArray, $Time);
257
         $this->InTransaction = false;
271
         $this->InTransaction = false;
258
     }
272
     }
263
         if (!$this->InTransaction) {
277
         if (!$this->InTransaction) {
264
             return false;
278
             return false;
265
         }
279
         }
280
+
266
         $Array = $this->MemcacheDBArray;
281
         $Array = $this->MemcacheDBArray;
267
         if (is_array($Rows)) {
282
         if (is_array($Rows)) {
268
             $i = 0;
283
             $i = 0;
285
         if (!$this->InTransaction) {
300
         if (!$this->InTransaction) {
286
             return false;
301
             return false;
287
         }
302
         }
303
+
288
         if ($Row === false) {
304
         if ($Row === false) {
289
             $UpdateArray = $this->MemcacheDBArray;
305
             $UpdateArray = $this->MemcacheDBArray;
290
         } else {
306
         } else {
291
             $UpdateArray = $this->MemcacheDBArray[$Row];
307
             $UpdateArray = $this->MemcacheDBArray[$Row];
292
         }
308
         }
309
+
293
         foreach ($Values as $Key => $Value) {
310
         foreach ($Values as $Key => $Value) {
294
             if (!array_key_exists($Key, $UpdateArray)) {
311
             if (!array_key_exists($Key, $UpdateArray)) {
295
                 trigger_error('Bad transaction key ('.$Key.') for cache '.$this->MemcacheDBKey);
312
                 trigger_error('Bad transaction key ('.$Key.') for cache '.$this->MemcacheDBKey);
296
             }
313
             }
314
+
297
             if ($Value === '+1') {
315
             if ($Value === '+1') {
298
                 if (!is_number($UpdateArray[$Key])) {
316
                 if (!is_number($UpdateArray[$Key])) {
299
                     trigger_error('Tried to increment non-number ('.$Key.') for cache '.$this->MemcacheDBKey);
317
                     trigger_error('Tried to increment non-number ('.$Key.') for cache '.$this->MemcacheDBKey);
308
                 $UpdateArray[$Key] = $Value; // Otherwise, just alter value
326
                 $UpdateArray[$Key] = $Value; // Otherwise, just alter value
309
             }
327
             }
310
         }
328
         }
329
+
311
         if ($Row === false) {
330
         if ($Row === false) {
312
             $this->MemcacheDBArray = $UpdateArray;
331
             $this->MemcacheDBArray = $UpdateArray;
313
         } else {
332
         } else {
322
         if (!$this->InTransaction) {
341
         if (!$this->InTransaction) {
323
             return false;
342
             return false;
324
         }
343
         }
344
+
325
         if ($Row === false) {
345
         if ($Row === false) {
326
             $UpdateArray = $this->MemcacheDBArray;
346
             $UpdateArray = $this->MemcacheDBArray;
327
         } else {
347
         } else {
328
             $UpdateArray = $this->MemcacheDBArray[$Row];
348
             $UpdateArray = $this->MemcacheDBArray[$Row];
329
         }
349
         }
350
+
330
         foreach ($Values as $Key => $Value) {
351
         foreach ($Values as $Key => $Value) {
331
             if (!array_key_exists($Key, $UpdateArray)) {
352
             if (!array_key_exists($Key, $UpdateArray)) {
332
                 trigger_error("Bad transaction key ($Key) for cache ".$this->MemcacheDBKey);
353
                 trigger_error("Bad transaction key ($Key) for cache ".$this->MemcacheDBKey);
333
             }
354
             }
355
+
334
             if (!is_number($Value)) {
356
             if (!is_number($Value)) {
335
                 trigger_error("Tried to increment with non-number ($Key) for cache ".$this->MemcacheDBKey);
357
                 trigger_error("Tried to increment with non-number ($Key) for cache ".$this->MemcacheDBKey);
336
             }
358
             }
337
             $UpdateArray[$Key] += $Value; // Increment value
359
             $UpdateArray[$Key] += $Value; // Increment value
338
         }
360
         }
361
+
339
         if ($Row === false) {
362
         if ($Row === false) {
340
             $this->MemcacheDBArray = $UpdateArray;
363
             $this->MemcacheDBArray = $UpdateArray;
341
         } else {
364
         } else {
349
         if (!$this->InTransaction) {
372
         if (!$this->InTransaction) {
350
             return false;
373
             return false;
351
         }
374
         }
375
+
352
         if ($Key === '') {
376
         if ($Key === '') {
353
             array_unshift($this->MemcacheDBArray, $Value);
377
             array_unshift($this->MemcacheDBArray, $Value);
354
         } else {
378
         } else {
362
         if (!$this->InTransaction) {
386
         if (!$this->InTransaction) {
363
             return false;
387
             return false;
364
         }
388
         }
389
+
365
         if ($Key === '') {
390
         if ($Key === '') {
366
             array_push($this->MemcacheDBArray, $Value);
391
             array_push($this->MemcacheDBArray, $Value);
367
         } else {
392
         } else {
374
         if (!$this->InTransaction) {
399
         if (!$this->InTransaction) {
375
             return false;
400
             return false;
376
         }
401
         }
402
+
377
         if ($Key === '') {
403
         if ($Key === '') {
378
             $this->MemcacheDBArray[] = $Value;
404
             $this->MemcacheDBArray[] = $Value;
379
         } else {
405
         } else {
386
         if (!$this->InTransaction) {
412
         if (!$this->InTransaction) {
387
             return false;
413
             return false;
388
         }
414
         }
415
+
389
         if (!isset($this->MemcacheDBArray[$Row])) {
416
         if (!isset($this->MemcacheDBArray[$Row])) {
390
             trigger_error("Tried to delete non-existent row ($Row) for cache ".$this->MemcacheDBKey);
417
             trigger_error("Tried to delete non-existent row ($Row) for cache ".$this->MemcacheDBKey);
391
         }
418
         }
435
         if (is_subclass_of($this, 'Memcached')) {
462
         if (is_subclass_of($this, 'Memcached')) {
436
             $MemcachedStats = $this->getStats();
463
             $MemcachedStats = $this->getStats();
437
         }
464
         }
465
+        
438
         foreach ($this->Servers as $Server) {
466
         foreach ($this->Servers as $Server) {
439
             if (is_subclass_of($this, 'Memcached')) {
467
             if (is_subclass_of($this, 'Memcached')) {
440
                 $Status["$Server[host]:$Server[port]"] = gettype($MemcachedStats["$Server[host]:$Server[port]"]) === 'array' ? 1 : 0;
468
                 $Status["$Server[host]:$Server[port]"] = gettype($MemcachedStats["$Server[host]:$Server[port]"]) === 'array' ? 1 : 0;

+ 206
- 178
classes/donationsbitcoin.class.php View File

1
-<?
2
-class DonationsBitcoin {
3
-  /**
4
-   * Ask bitcoind for a list of all addresses that have received bitcoins
5
-   *
6
-   * @return array (BitcoinAddress => Amount, ...)
7
-   */
8
-  public static function get_received() {
9
-    if (defined('BITCOIN_RPC_URL')) {
10
-      $Donations = BitcoinRpc::listreceivedbyaddress();
11
-    }
12
-    if (empty($Donations)) {
13
-      return [];
14
-    }
15
-    $BTCUsers = [];
16
-    foreach ($Donations as $Account) {
17
-      $BTCUsers[$Account->address] = $Account->amount;
18
-    }
19
-    return $BTCUsers;
20
-  }
21
-
22
-  /**
23
-   * Ask bitcoind for the current account balance
24
-   *
25
-   * @return float balance
26
-   */
27
-  public static function get_balance() {
28
-    if (defined('BITCOIN_RPC_URL')) {
29
-      return BitcoinRpc::getbalance();
30
-    }
31
-  }
32
-
33
-  /**
34
-   * Get a user's existing bitcoin address or generate a new one
35
-   *
36
-   * @param int $UserID
37
-   * @param bool $GenAddress whether to create a new address if it doesn't exist
38
-   * @return false if no address exists and $GenAddress is false
39
-   *         string bitcoin address otherwise
40
-   */
41
-  public static function get_address($UserID, $GenAddress = false) {
42
-    $UserID = (int)$UserID;
43
-    $QueryID = G::$DB->get_query_id();
44
-    G::$DB->query("
45
-      SELECT BitcoinAddress
46
-      FROM users_info
47
-      WHERE UserID = '$UserID'");
48
-    list($Addr) = G::$DB->next_record();
49
-    G::$DB->set_query_id($QueryID);
50
-
51
-    if (!empty($Addr)) {
52
-      return $Addr;
53
-    } elseif ($GenAddress) {
54
-      if (defined('BITCOIN_RPC_URL')) {
55
-        $NewAddr = BitcoinRpc::getnewaddress();
56
-      }
57
-      if (empty($NewAddr)) {
58
-        error(0);
59
-      }
60
-      $QueryID = G::$DB->get_query_id();
61
-      G::$DB->query("
62
-        UPDATE users_info
63
-        SET BitcoinAddress = '".db_string($NewAddr)."'
64
-        WHERE UserID = '$UserID'
65
-          AND BitcoinAddress IS NULL");
66
-      G::$DB->set_query_id($QueryID);
67
-      return $NewAddr;
68
-    } else {
69
-      return false;
70
-    }
71
-  }
72
-
73
-  /**
74
-   * Ask bitcoind for the total amount of bitcoins received
75
-   *
76
-   * @return float amount
77
-   */
78
-  public static function get_total_received() {
79
-    if (defined('BITCOIN_RPC_URL')) {
80
-      $Accounts = BitcoinRpc::listreceivedbyaccount();
81
-    }
82
-    if (empty($Accounts)) {
83
-      return 0.0;
84
-    }
85
-    foreach ($Accounts as $Account) {
86
-      if ($Account->account == '') {
87
-        return $Account->amount;
88
-      }
1
+<?php
2
+
3
+class DonationsBitcoin
4
+{
5
+    /**
6
+     * Ask bitcoind for a list of all addresses that have received bitcoins
7
+     *
8
+     * @return array (BitcoinAddress => Amount, ...)
9
+     */
10
+    public static function get_received()
11
+    {
12
+        if (defined('BITCOIN_RPC_URL')) {
13
+            $Donations = BitcoinRpc::listreceivedbyaddress();
14
+        }
15
+
16
+        if (empty($Donations)) {
17
+            return [];
18
+        }
19
+
20
+        $BTCUsers = [];
21
+        foreach ($Donations as $Account) {
22
+            $BTCUsers[$Account->address] = $Account->amount;
23
+        }
24
+        return $BTCUsers;
89
     }
25
     }
90
-    return 0.0;
91
-  }
92
-
93
-  /**
94
-   * Translate bitcoin addresses to user IDs
95
-   *
96
-   * @param array $Addresses list of bitcoin addresses
97
-   * @return array (BitcoinAddress => UserID, ...)
98
-   */
99
-  public static function get_userids($Addresses) {
100
-    if (!is_array($Addresses) || empty($Addresses)) {
101
-      return false;
26
+
27
+    /**
28
+     * Ask bitcoind for the current account balance
29
+     *
30
+     * @return float balance
31
+     */
32
+    public static function get_balance()
33
+    {
34
+        if (defined('BITCOIN_RPC_URL')) {
35
+            return BitcoinRpc::getbalance();
36
+        }
102
     }
37
     }
103
-    $QueryID = G::$DB->get_query_id();
104
-    G::$DB->query("
105
-      SELECT BitcoinAddress, UserID
106
-      FROM users_info
107
-      WHERE BitcoinAddress IN ('" . implode("', '", $Addresses) . "')");
108
-    if (G::$DB->has_results()) {
109
-      $UserIDs = G::$DB->to_pair(0, 1);
110
-    } else {
111
-      $UserIDs = [];
38
+
39
+    /**
40
+     * Get a user's existing bitcoin address or generate a new one
41
+     *
42
+     * @param int $UserID
43
+     * @param bool $GenAddress whether to create a new address if it doesn't exist
44
+     * @return false if no address exists and $GenAddress is false
45
+     *         string bitcoin address otherwise
46
+     */
47
+    public static function get_address($UserID, $GenAddress = false)
48
+    {
49
+        $UserID = (int)$UserID;
50
+        $QueryID = G::$DB->get_query_id();
51
+        G::$DB->query("
52
+        SELECT BitcoinAddress
53
+        FROM users_info
54
+          WHERE UserID = '$UserID'");
55
+
56
+        list($Addr) = G::$DB->next_record();
57
+        G::$DB->set_query_id($QueryID);
58
+
59
+        if (!empty($Addr)) {
60
+            return $Addr;
61
+        } elseif ($GenAddress) {
62
+            if (defined('BITCOIN_RPC_URL')) {
63
+                $NewAddr = BitcoinRpc::getnewaddress();
64
+            }
65
+
66
+            if (empty($NewAddr)) {
67
+                error(0);
68
+            }
69
+
70
+            $QueryID = G::$DB->get_query_id();
71
+            G::$DB->query("
72
+            UPDATE users_info
73
+            SET BitcoinAddress = '".db_string($NewAddr)."'
74
+              WHERE UserID = '$UserID'
75
+              AND BitcoinAddress IS NULL");
76
+
77
+            G::$DB->set_query_id($QueryID);
78
+            return $NewAddr;
79
+        } else {
80
+            return false;
81
+        }
112
     }
82
     }
113
-    G::$DB->set_query_id($QueryID);
114
-    return $UserIDs;
115
-  }
116
-
117
-  /**
118
-   * Find and process new donations since the last time this function was called.
119
-   */
120
-  public static function find_new_donations() {
121
-    global $Debug;
122
-    if (($OldAmount = G::$Cache->get_value('btc_total_received')) === false) {
123
-      $QueryID = G::$DB->get_query_id();
124
-      G::$DB->query("
125
-        SELECT IFNULL(SUM(Amount), 0)
126
-        FROM donations_bitcoin");
127
-      list($OldAmount) = G::$DB->next_record(MYSQLI_NUM, false);
128
-      G::$DB->set_query_id($QueryID);
83
+
84
+    /**
85
+     * Ask bitcoind for the total amount of bitcoins received
86
+     *
87
+     * @return float amount
88
+     */
89
+    public static function get_total_received()
90
+    {
91
+        if (defined('BITCOIN_RPC_URL')) {
92
+            $Accounts = BitcoinRpc::listreceivedbyaccount();
93
+        }
94
+
95
+        if (empty($Accounts)) {
96
+            return 0.0;
97
+        }
98
+
99
+        foreach ($Accounts as $Account) {
100
+            if ($Account->account === '') {
101
+                return $Account->amount;
102
+            }
103
+        }
104
+        return 0.0;
129
     }
105
     }
130
-    $NewAmount = self::get_total_received();
131
-    if ($NewAmount < $OldAmount) {
132
-      // This shouldn't happen. Perhaps bitcoind was restarted recently
133
-      // or the block index was removed. Either way, try again later
134
-      send_irc('PRIVMSG ' . LAB_CHAN . " :Bad bitcoin donation data (is $NewAmount, was $OldAmount). If this persists, something is probably wrong");
135
-      return false;
106
+
107
+    /**
108
+     * Translate bitcoin addresses to user IDs
109
+     *
110
+     * @param array $Addresses list of bitcoin addresses
111
+     * @return array (BitcoinAddress => UserID, ...)
112
+     */
113
+    public static function get_userids($Addresses)
114
+    {
115
+        if (!is_array($Addresses) || empty($Addresses)) {
116
+            return false;
117
+        }
118
+
119
+        $QueryID = G::$DB->get_query_id();
120
+        G::$DB->query("
121
+        SELECT BitcoinAddress, UserID
122
+        FROM users_info
123
+          WHERE BitcoinAddress IN ('" . implode("', '", $Addresses) . "')");
124
+
125
+        if (G::$DB->has_results()) {
126
+            $UserIDs = G::$DB->to_pair(0, 1);
127
+        } else {
128
+            $UserIDs = [];
129
+        }
130
+
131
+        G::$DB->set_query_id($QueryID);
132
+        return $UserIDs;
136
     }
133
     }
137
-    if ($NewAmount > $OldAmount) {
138
-      // I really wish we didn't have to do it like this
139
-      $QueryID = G::$DB->get_query_id();
140
-      G::$DB->query("
141
-        SELECT BitcoinAddress, SUM(Amount)
142
-        FROM donations_bitcoin
143
-        GROUP BY BitcoinAddress");
144
-      $OldDonations = G::$DB->to_pair(0, 1, false);
145
-      G::$DB->set_query_id($QueryID);
146
-      $NewDonations = self::get_received();
147
-      foreach ($NewDonations as $Address => &$Amount) {
148
-        if (isset($OldDonations[$Address])) {
149
-          if ($Amount == $OldDonations[$Address]) { // Direct comparison should be fine as everything comes from bitcoind
150
-            unset($NewDonations[$Address]);
151
-            continue;
152
-          }
153
-          $Debug->log_var(array('old' => $OldDonations[$Address], 'new' => $Amount), "New donations from $Address");
154
-          // PHP doesn't do fixed-point math, and json_decode has already botched the precision
155
-          // so let's just round this off to satoshis and pray that we're on a 64 bit system
156
-          $Amount = round($Amount - $OldDonations[$Address], 8);
134
+
135
+    /**
136
+     * Find and process new donations since the last time this function was called.
137
+     */
138
+    public static function find_new_donations()
139
+    {
140
+        global $Debug;
141
+        if (($OldAmount = G::$Cache->get_value('btc_total_received')) === false) {
142
+            $QueryID = G::$DB->get_query_id();
143
+            G::$DB->query("
144
+            SELECT IFNULL(SUM(Amount), 0)
145
+            FROM donations_bitcoin");
146
+
147
+            list($OldAmount) = G::$DB->next_record(MYSQLI_NUM, false);
148
+            G::$DB->set_query_id($QueryID);
149
+        }
150
+
151
+        $NewAmount = self::get_total_received();
152
+        if ($NewAmount < $OldAmount) {
153
+            // This shouldn't happen. Perhaps bitcoind was restarted recently
154
+            // or the block index was removed. Either way, try again later
155
+            send_irc('PRIVMSG ' . LAB_CHAN . " :Bad bitcoin donation data (is $NewAmount, was $OldAmount). If this persists, something is probably wrong");
156
+            return false;
157
+        }
158
+
159
+        if ($NewAmount > $OldAmount) {
160
+            // I really wish we didn't have to do it like this
161
+            $QueryID = G::$DB->get_query_id();
162
+            G::$DB->query("
163
+            SELECT BitcoinAddress, SUM(Amount)
164
+            FROM donations_bitcoin
165
+              GROUP BY BitcoinAddress");
166
+
167
+            $OldDonations = G::$DB->to_pair(0, 1, false);
168
+            G::$DB->set_query_id($QueryID);
169
+            $NewDonations = self::get_received();
170
+
171
+            foreach ($NewDonations as $Address => &$Amount) {
172
+                if (isset($OldDonations[$Address])) {
173
+                    if ($Amount == $OldDonations[$Address]) { // Direct comparison should be fine as everything comes from bitcoind
174
+                        unset($NewDonations[$Address]);
175
+                        continue;
176
+                    }
177
+
178
+                    $Debug->log_var(array('old' => $OldDonations[$Address], 'new' => $Amount), "New donations from $Address");
179
+                    // PHP doesn't do fixed-point math, and json_decode has already botched the precision
180
+                    // so let's just round this off to satoshis and pray that we're on a 64 bit system
181
+                    $Amount = round($Amount - $OldDonations[$Address], 8);
182
+                }
183
+                $NewDonations[$Address] = $Amount;
184
+            }
185
+
186
+            $Debug->log_var($NewDonations, '$NewDonations');
187
+            foreach (self::get_userids(array_keys($NewDonations)) as $Address => $UserID) {
188
+                Donations::regular_donate($UserID, $NewDonations[$Address], 'Bitcoin Parser', '', 'BTC');
189
+                self::store_donation($Address, $NewDonations[$Address]);
190
+            }
191
+            G::$Cache->cache_value('btc_total_received', $NewAmount, 0);
157
         }
192
         }
158
-        $NewDonations[$Address] = $Amount;
159
-      }
160
-      $Debug->log_var($NewDonations, '$NewDonations');
161
-      foreach (self::get_userids(array_keys($NewDonations)) as $Address => $UserID) {
162
-        Donations::regular_donate($UserID, $NewDonations[$Address], 'Bitcoin Parser', '', 'BTC');
163
-        self::store_donation($Address, $NewDonations[$Address]);
164
-      }
165
-      G::$Cache->cache_value('btc_total_received', $NewAmount, 0);
166
     }
193
     }
167
-  }
168
-
169
-  /**
170
-   * Record a donation in the database
171
-   *
172
-   * @param string $Address bitcoin address
173
-   * @param double $Amount amount of bitcoins transferred
174
-   */
175
-  public static function store_donation($Address, $Amount) {
176
-    if (!is_numeric($Amount) || $Amount <= 0) {
177
-      // Panic!
178
-      return false;
194
+
195
+    /**
196
+     * Record a donation in the database
197
+     *
198
+     * @param string $Address bitcoin address
199
+     * @param double $Amount amount of bitcoins transferred
200
+     */
201
+    public static function store_donation($Address, $Amount)
202
+    {
203
+        if (!is_numeric($Amount) || $Amount <= 0) {
204
+            // Panic!
205
+            return false;
206
+        }
207
+
208
+        G::$DB->query("
209
+        INSERT INTO donations_bitcoin
210
+          (BitcoinAddress, Amount)
211
+        VALUES
212
+          ('$Address', $Amount)");
179
     }
213
     }
180
-    G::$DB->query("
181
-      INSERT INTO donations_bitcoin
182
-        (BitcoinAddress, Amount)
183
-      VALUES
184
-        ('$Address', $Amount)");
185
-  }
186
-}
214
+}

+ 229
- 213
classes/forums.class.php View File

1
-<?
2
-class Forums {
3
-  /**
4
-   * Get information on a thread.
5
-   *
6
-   * @param int $ThreadID the thread ID.
7
-   * @param boolean $Return indicates whether thread info should be returned.
8
-   * @param Boolean $SelectiveCache cache thread info.
9
-   * @return array holding thread information.
10
-   */
11
-  public static function get_thread_info($ThreadID, $Return = true, $SelectiveCache = false) {
12
-    if ((!$ThreadInfo = G::$Cache->get_value('thread_' . $ThreadID . '_info')) || !isset($ThreadInfo['Ranking'])) {
13
-      $QueryID = G::$DB->get_query_id();
14
-      G::$DB->query("
1
+<?php
2
+
3
+class Forums
4
+{
5
+    /**
6
+     * Get information on a thread.
7
+     *
8
+     * @param int $ThreadID the thread ID.
9
+     * @param boolean $Return indicates whether thread info should be returned.
10
+     * @param Boolean $SelectiveCache cache thread info.
11
+     * @return array holding thread information.
12
+     */
13
+    public static function get_thread_info($ThreadID, $Return = true, $SelectiveCache = false)
14
+    {
15
+        if ((!$ThreadInfo = G::$Cache->get_value('thread_' . $ThreadID . '_info')) || !isset($ThreadInfo['Ranking'])) {
16
+            $QueryID = G::$DB->get_query_id();
17
+            G::$DB->query("
15
         SELECT
18
         SELECT
16
           t.Title,
19
           t.Title,
17
           t.ForumID,
20
           t.ForumID,
28
           LEFT JOIN forums_polls AS p ON p.TopicID = t.ID
31
           LEFT JOIN forums_polls AS p ON p.TopicID = t.ID
29
         WHERE t.ID = ?
32
         WHERE t.ID = ?
30
         GROUP BY fp.TopicID", $ThreadID);
33
         GROUP BY fp.TopicID", $ThreadID);
31
-      if (!G::$DB->has_results()) {
32
-        G::$DB->set_query_id($QueryID);
33
-        return null;
34
-      }
35
-      $ThreadInfo = G::$DB->next_record(MYSQLI_ASSOC, false);
36
-      if ($ThreadInfo['StickyPostID']) {
37
-        $ThreadInfo['Posts']--;
38
-        G::$DB->query(
39
-          "SELECT
34
+            if (!G::$DB->has_results()) {
35
+                G::$DB->set_query_id($QueryID);
36
+                return null;
37
+            }
38
+            $ThreadInfo = G::$DB->next_record(MYSQLI_ASSOC, false);
39
+            if ($ThreadInfo['StickyPostID']) {
40
+                $ThreadInfo['Posts']--;
41
+                G::$DB->query(
42
+            "SELECT
40
             p.ID,
43
             p.ID,
41
             p.AuthorID,
44
             p.AuthorID,
42
             p.AddedTime,
45
             p.AddedTime,
47
             FROM forums_posts AS p
50
             FROM forums_posts AS p
48
               LEFT JOIN users_main AS ed ON ed.ID = p.EditedUserID
51
               LEFT JOIN users_main AS ed ON ed.ID = p.EditedUserID
49
             WHERE p.TopicID = ?
52
             WHERE p.TopicID = ?
50
-              AND p.ID = ?", $ThreadID, $ThreadInfo['StickyPostID']);
51
-        list ($ThreadInfo['StickyPost']) = G::$DB->to_array(false, MYSQLI_ASSOC);
52
-      }
53
-      G::$DB->set_query_id($QueryID);
54
-      if (!$SelectiveCache || !$ThreadInfo['IsLocked'] || $ThreadInfo['IsSticky']) {
55
-        G::$Cache->cache_value('thread_' . $ThreadID . '_info', $ThreadInfo, 0);
56
-      }
57
-    }
58
-    if ($Return) {
59
-      return $ThreadInfo;
53
+              AND p.ID = ?",
54
+            $ThreadID,
55
+            $ThreadInfo['StickyPostID']
56
+        );
57
+                list($ThreadInfo['StickyPost']) = G::$DB->to_array(false, MYSQLI_ASSOC);
58
+            }
59
+            G::$DB->set_query_id($QueryID);
60
+            if (!$SelectiveCache || !$ThreadInfo['IsLocked'] || $ThreadInfo['IsSticky']) {
61
+                G::$Cache->cache_value('thread_' . $ThreadID . '_info', $ThreadInfo, 0);
62
+            }
63
+        }
64
+        if ($Return) {
65
+            return $ThreadInfo;
66
+        }
60
     }
67
     }
61
-  }
62
 
68
 
63
-  /**
64
-   * Checks whether user has permissions on a forum.
65
-   *
66
-   * @param int $ForumID the forum ID.
67
-   * @param string $Perm the permissision to check, defaults to 'Read'
68
-   * @return boolean true if user has permission
69
-   */
70
-  public static function check_forumperm($ForumID, $Perm = 'Read') {
71
-    $Forums = self::get_forums();
72
-    if (isset(G::$LoggedUser['CustomForums'][$ForumID]) && G::$LoggedUser['CustomForums'][$ForumID] == 1) {
73
-      return true;
74
-    }
75
-    if ($ForumID == DONOR_FORUM && Donations::has_donor_forum(G::$LoggedUser['ID'])) {
76
-      return true;
77
-    }
78
-    if ($Forums[$ForumID]['MinClass' . $Perm] > G::$LoggedUser['Class'] && (!isset(G::$LoggedUser['CustomForums'][$ForumID]) || G::$LoggedUser['CustomForums'][$ForumID] == 0)) {
79
-      return false;
80
-    }
81
-    if (isset(G::$LoggedUser['CustomForums'][$ForumID]) && G::$LoggedUser['CustomForums'][$ForumID] == 0) {
82
-      return false;
69
+    /**
70
+     * Checks whether user has permissions on a forum.
71
+     *
72
+     * @param int $ForumID the forum ID.
73
+     * @param string $Perm the permissision to check, defaults to 'Read'
74
+     * @return boolean true if user has permission
75
+     */
76
+    public static function check_forumperm($ForumID, $Perm = 'Read')
77
+    {
78
+        $Forums = self::get_forums();
79
+        if (isset(G::$LoggedUser['CustomForums'][$ForumID]) && G::$LoggedUser['CustomForums'][$ForumID] == 1) {
80
+            return true;
81
+        }
82
+        if ($ForumID == DONOR_FORUM && Donations::has_donor_forum(G::$LoggedUser['ID'])) {
83
+            return true;
84
+        }
85
+        if ($Forums[$ForumID]['MinClass' . $Perm] > G::$LoggedUser['Class'] && (!isset(G::$LoggedUser['CustomForums'][$ForumID]) || G::$LoggedUser['CustomForums'][$ForumID] == 0)) {
86
+            return false;
87
+        }
88
+        if (isset(G::$LoggedUser['CustomForums'][$ForumID]) && G::$LoggedUser['CustomForums'][$ForumID] == 0) {
89
+            return false;
90
+        }
91
+        return true;
83
     }
92
     }
84
-    return true;
85
-  }
86
 
93
 
87
-  /**
88
-   * Gets basic info on a forum.
89
-   *
90
-   * @param int $ForumID the forum ID.
91
-   */
92
-  public static function get_forum_info($ForumID) {
93
-    $Forum = G::$Cache->get_value("ForumInfo_$ForumID");
94
-    if (!$Forum) {
95
-      $QueryID = G::$DB->get_query_id();
96
-      G::$DB->query("
94
+    /**
95
+     * Gets basic info on a forum.
96
+     *
97
+     * @param int $ForumID the forum ID.
98
+     */
99
+    public static function get_forum_info($ForumID)
100
+    {
101
+        $Forum = G::$Cache->get_value("ForumInfo_$ForumID");
102
+        if (!$Forum) {
103
+            $QueryID = G::$DB->get_query_id();
104
+            G::$DB->query("
97
         SELECT
105
         SELECT
98
           Name,
106
           Name,
99
           MinClassRead,
107
           MinClassRead,
104
           LEFT JOIN forums_topics ON forums_topics.ForumID = forums.ID
112
           LEFT JOIN forums_topics ON forums_topics.ForumID = forums.ID
105
         WHERE forums.ID = ?
113
         WHERE forums.ID = ?
106
         GROUP BY ForumID", $ForumID);
114
         GROUP BY ForumID", $ForumID);
107
-      if (!G::$DB->has_results()) {
108
-        return false;
109
-      }
110
-      // Makes an array, with $Forum['Name'], etc.
111
-      $Forum = G::$DB->next_record(MYSQLI_ASSOC);
115
+            if (!G::$DB->has_results()) {
116
+                return false;
117
+            }
118
+            // Makes an array, with $Forum['Name'], etc.
119
+            $Forum = G::$DB->next_record(MYSQLI_ASSOC);
112
 
120
 
113
-      G::$DB->set_query_id($QueryID);
121
+            G::$DB->set_query_id($QueryID);
114
 
122
 
115
-      G::$Cache->cache_value("ForumInfo_$ForumID", $Forum, 86400);
123
+            G::$Cache->cache_value("ForumInfo_$ForumID", $Forum, 86400);
124
+        }
125
+        return $Forum;
116
     }
126
     }
117
-    return $Forum;
118
-  }
119
 
127
 
120
-  /**
121
-   * Get the forum categories
122
-   * @return array ForumCategoryID => Name
123
-   */
124
-  public static function get_forum_categories() {
125
-    $ForumCats = G::$Cache->get_value('forums_categories');
126
-    if ($ForumCats === false) {
127
-      $QueryID = G::$DB->get_query_id();
128
-      G::$DB->query("
128
+    /**
129
+     * Get the forum categories
130
+     * @return array ForumCategoryID => Name
131
+     */
132
+    public static function get_forum_categories()
133
+    {
134
+        $ForumCats = G::$Cache->get_value('forums_categories');
135
+        if ($ForumCats === false) {
136
+            $QueryID = G::$DB->get_query_id();
137
+            G::$DB->query("
129
         SELECT ID, Name
138
         SELECT ID, Name
130
         FROM forums_categories");
139
         FROM forums_categories");
131
-      $ForumCats = [];
132
-      while (list ($ID, $Name) = G::$DB->next_record()) {
133
-        $ForumCats[$ID] = $Name;
134
-      }
135
-      G::$DB->set_query_id($QueryID);
136
-      G::$Cache->cache_value('forums_categories', $ForumCats, 0);
140
+            $ForumCats = [];
141
+            while (list($ID, $Name) = G::$DB->next_record()) {
142
+                $ForumCats[$ID] = $Name;
143
+            }
144
+            G::$DB->set_query_id($QueryID);
145
+            G::$Cache->cache_value('forums_categories', $ForumCats, 0);
146
+        }
147
+        return $ForumCats;
137
     }
148
     }
138
-    return $ForumCats;
139
-  }
140
 
149
 
141
-  /**
142
-   * Get the forums
143
-   * @return array ForumID => (various information about the forum)
144
-   */
145
-  public static function get_forums() {
146
-    if (!$Forums = G::$Cache->get_value('forums_list')) {
147
-      $QueryID = G::$DB->get_query_id();
148
-      G::$DB->query("
150
+    /**
151
+     * Get the forums
152
+     * @return array ForumID => (various information about the forum)
153
+     */
154
+    public static function get_forums()
155
+    {
156
+        if (!$Forums = G::$Cache->get_value('forums_list')) {
157
+            $QueryID = G::$DB->get_query_id();
158
+            G::$DB->query("
149
         SELECT
159
         SELECT
150
           f.ID,
160
           f.ID,
151
           f.CategoryID,
161
           f.CategoryID,
169
           LEFT JOIN forums_topics AS t ON t.ID = f.LastPostTopicID
179
           LEFT JOIN forums_topics AS t ON t.ID = f.LastPostTopicID
170
         GROUP BY f.ID
180
         GROUP BY f.ID
171
         ORDER BY fc.Sort, fc.Name, f.CategoryID, f.Sort");
181
         ORDER BY fc.Sort, fc.Name, f.CategoryID, f.Sort");
172
-      $Forums = G::$DB->to_array('ID', MYSQLI_ASSOC, false);
182
+            $Forums = G::$DB->to_array('ID', MYSQLI_ASSOC, false);
173
 
183
 
174
-      G::$DB->query("
184
+            G::$DB->query("
175
         SELECT ForumID, ThreadID
185
         SELECT ForumID, ThreadID
176
         FROM forums_specific_rules");
186
         FROM forums_specific_rules");
177
-      $SpecificRules = [];
178
-      while (list($ForumID, $ThreadID) = G::$DB->next_record(MYSQLI_NUM, false)) {
179
-        $SpecificRules[$ForumID][] = $ThreadID;
180
-      }
181
-      G::$DB->set_query_id($QueryID);
182
-      foreach ($Forums as $ForumID => &$Forum) {
183
-        if (isset($SpecificRules[$ForumID])) {
184
-          $Forum['SpecificRules'] = $SpecificRules[$ForumID];
185
-        } else {
186
-          $Forum['SpecificRules'] = [];
187
+            $SpecificRules = [];
188
+            while (list($ForumID, $ThreadID) = G::$DB->next_record(MYSQLI_NUM, false)) {
189
+                $SpecificRules[$ForumID][] = $ThreadID;
190
+            }
191
+            G::$DB->set_query_id($QueryID);
192
+            foreach ($Forums as $ForumID => &$Forum) {
193
+                if (isset($SpecificRules[$ForumID])) {
194
+                    $Forum['SpecificRules'] = $SpecificRules[$ForumID];
195
+                } else {
196
+                    $Forum['SpecificRules'] = [];
197
+                }
198
+            }
199
+            G::$Cache->cache_value('forums_list', $Forums, 0);
187
         }
200
         }
188
-      }
189
-      G::$Cache->cache_value('forums_list', $Forums, 0);
201
+        return $Forums;
190
     }
202
     }
191
-    return $Forums;
192
-  }
193
 
203
 
194
-  /**
195
-   * Get all forums that the current user has special access to ("Extra forums" in the profile)
196
-   * @return array Array of ForumIDs
197
-   */
198
-  public static function get_permitted_forums() {
199
-    if (isset(G::$LoggedUser['CustomForums'])) {
200
-      return (array)array_keys(G::$LoggedUser['CustomForums'], 1);
201
-    } else {
202
-      return [];
204
+    /**
205
+     * Get all forums that the current user has special access to ("Extra forums" in the profile)
206
+     * @return array Array of ForumIDs
207
+     */
208
+    public static function get_permitted_forums()
209
+    {
210
+        if (isset(G::$LoggedUser['CustomForums'])) {
211
+            return (array)array_keys(G::$LoggedUser['CustomForums'], 1);
212
+        } else {
213
+            return [];
214
+        }
203
     }
215
     }
204
-  }
205
 
216
 
206
-  /**
207
-   * Get all forums that the current user does not have access to ("Restricted forums" in the profile)
208
-   * @return array Array of ForumIDs
209
-   */
210
-  public static function get_restricted_forums() {
211
-    if (isset(G::$LoggedUser['CustomForums'])) {
212
-      return (array)array_keys(G::$LoggedUser['CustomForums'], 0);
213
-    } else {
214
-      return [];
217
+    /**
218
+     * Get all forums that the current user does not have access to ("Restricted forums" in the profile)
219
+     * @return array Array of ForumIDs
220
+     */
221
+    public static function get_restricted_forums()
222
+    {
223
+        if (isset(G::$LoggedUser['CustomForums'])) {
224
+            return (array)array_keys(G::$LoggedUser['CustomForums'], 0);
225
+        } else {
226
+            return [];
227
+        }
215
     }
228
     }
216
-  }
217
 
229
 
218
-  /**
219
-   * Get the last read posts for the current user
220
-   * @param array $Forums Array of forums as returned by self::get_forums()
221
-   * @return array TopicID => array(TopicID, PostID, Page) where PostID is the ID of the last read post and Page is the page on which that post is
222
-   */
223
-  public static function get_last_read($Forums) {
224
-    if (isset(G::$LoggedUser['PostsPerPage'])) {
225
-      $PerPage = G::$LoggedUser['PostsPerPage'];
226
-    } else {
227
-      $PerPage = POSTS_PER_PAGE;
228
-    }
229
-    $TopicIDs = [];
230
-    foreach ($Forums as $Forum) {
231
-      if (!empty($Forum['LastPostTopicID'])) {
232
-        $TopicIDs[] = $Forum['LastPostTopicID'];
233
-      }
234
-    }
235
-    if (!empty($TopicIDs)) {
236
-      $QueryID = G::$DB->get_query_id();
237
-      G::$DB->query("
230
+    /**
231
+     * Get the last read posts for the current user
232
+     * @param array $Forums Array of forums as returned by self::get_forums()
233
+     * @return array TopicID => array(TopicID, PostID, Page) where PostID is the ID of the last read post and Page is the page on which that post is
234
+     */
235
+    public static function get_last_read($Forums)
236
+    {
237
+        if (isset(G::$LoggedUser['PostsPerPage'])) {
238
+            $PerPage = G::$LoggedUser['PostsPerPage'];
239
+        } else {
240
+            $PerPage = POSTS_PER_PAGE;
241
+        }
242
+        $TopicIDs = [];
243
+        foreach ($Forums as $Forum) {
244
+            if (!empty($Forum['LastPostTopicID'])) {
245
+                $TopicIDs[] = $Forum['LastPostTopicID'];
246
+            }
247
+        }
248
+        if (!empty($TopicIDs)) {
249
+            $QueryID = G::$DB->get_query_id();
250
+            G::$DB->query("
238
         SELECT
251
         SELECT
239
           l.TopicID,
252
           l.TopicID,
240
           l.PostID,
253
           l.PostID,
250
         FROM forums_last_read_topics AS l
263
         FROM forums_last_read_topics AS l
251
         WHERE l.TopicID IN(" . implode(',', $TopicIDs) . ") AND
264
         WHERE l.TopicID IN(" . implode(',', $TopicIDs) . ") AND
252
           l.UserID = ?", $PerPage, G::$LoggedUser['ID']);
265
           l.UserID = ?", $PerPage, G::$LoggedUser['ID']);
253
-      $LastRead = G::$DB->to_array('TopicID', MYSQLI_ASSOC);
254
-      G::$DB->set_query_id($QueryID);
255
-    } else {
256
-      $LastRead = [];
266
+            $LastRead = G::$DB->to_array('TopicID', MYSQLI_ASSOC);
267
+            G::$DB->set_query_id($QueryID);
268
+        } else {
269
+            $LastRead = [];
270
+        }
271
+        return $LastRead;
257
     }
272
     }
258
-    return $LastRead;
259
-  }
260
 
273
 
261
-  /**
262
-   * Add a note to a topic.
263
-   * @param int $TopicID
264
-   * @param string $Note
265
-   * @param int|null $UserID
266
-   * @return boolean
267
-   */
268
-  public static function add_topic_note($TopicID, $Note, $UserID = null) {
269
-    if ($UserID === null) {
270
-      $UserID = G::$LoggedUser['ID'];
271
-    }
272
-    $QueryID = G::$DB->get_query_id();
273
-    G::$DB->query("
274
+    /**
275
+     * Add a note to a topic.
276
+     * @param int $TopicID
277
+     * @param string $Note
278
+     * @param int|null $UserID
279
+     * @return boolean
280
+     */
281
+    public static function add_topic_note($TopicID, $Note, $UserID = null)
282
+    {
283
+        if ($UserID === null) {
284
+            $UserID = G::$LoggedUser['ID'];
285
+        }
286
+        $QueryID = G::$DB->get_query_id();
287
+        G::$DB->query("
274
       INSERT INTO forums_topic_notes
288
       INSERT INTO forums_topic_notes
275
         (TopicID, AuthorID, AddedTime, Body)
289
         (TopicID, AuthorID, AddedTime, Body)
276
       VALUES
290
       VALUES
277
         (?, ?, NOW(), ?)", $TopicID, $UserID, $Note);
291
         (?, ?, NOW(), ?)", $TopicID, $UserID, $Note);
278
-    G::$DB->set_query_id($QueryID);
279
-    return (bool)G::$DB->affected_rows();
280
-  }
281
-
282
-  /**
283
-   * Determine if a thread is unread
284
-   * @param bool $Locked
285
-   * @param bool $Sticky
286
-   * @param int $LastPostID
287
-   * @param array $LastRead An array as returned by self::get_last_read
288
-   * @param int $LastTopicID TopicID of the thread where the most recent post was made
289
-   * @param string $LastTime Datetime of the last post
290
-   * @return bool
291
-   */
292
-  public static function is_unread($Locked, $Sticky, $LastPostID, $LastRead, $LastTopicID, $LastTime) {
293
-    return (!$Locked || $Sticky) && $LastPostID != 0 && ((empty($LastRead[$LastTopicID]) || $LastRead[$LastTopicID]['PostID'] < $LastPostID) && strtotime($LastTime) > G::$LoggedUser['CatchupTime']);
294
-  }
295
-
296
-  /**
297
-   * Create the part of WHERE in the sql queries used to filter forums for a
298
-   * specific user (MinClassRead, restricted and permitted forums).
299
-   * @return string
300
-   */
301
-  public static function user_forums_sql() {
302
-    // I couldn't come up with a good name, please rename this if you can. -- Y
303
-    $RestrictedForums = self::get_restricted_forums();
304
-    $PermittedForums = self::get_permitted_forums();
305
-    if (Donations::has_donor_forum(G::$LoggedUser['ID']) && !in_array(DONOR_FORUM, $PermittedForums)) {
306
-      $PermittedForums[] = DONOR_FORUM;
292
+        G::$DB->set_query_id($QueryID);
293
+        return (bool)G::$DB->affected_rows();
307
     }
294
     }
308
-    $SQL = "((f.MinClassRead <= '" . G::$LoggedUser['Class'] . "'";
309
-    if (count($RestrictedForums)) {
310
-      $SQL .= " AND f.ID NOT IN ('" . implode("', '", $RestrictedForums) . "')";
295
+
296
+    /**
297
+     * Determine if a thread is unread
298
+     * @param bool $Locked
299
+     * @param bool $Sticky
300
+     * @param int $LastPostID
301
+     * @param array $LastRead An array as returned by self::get_last_read
302
+     * @param int $LastTopicID TopicID of the thread where the most recent post was made
303
+     * @param string $LastTime Datetime of the last post
304
+     * @return bool
305
+     */
306
+    public static function is_unread($Locked, $Sticky, $LastPostID, $LastRead, $LastTopicID, $LastTime)
307
+    {
308
+        return (!$Locked || $Sticky) && $LastPostID != 0 && ((empty($LastRead[$LastTopicID]) || $LastRead[$LastTopicID]['PostID'] < $LastPostID) && strtotime($LastTime) > G::$LoggedUser['CatchupTime']);
311
     }
309
     }
312
-    $SQL .= ')';
313
-    if (count($PermittedForums)) {
314
-      $SQL .= " OR f.ID IN ('" . implode("', '", $PermittedForums) . "')";
310
+
311
+    /**
312
+     * Create the part of WHERE in the sql queries used to filter forums for a
313
+     * specific user (MinClassRead, restricted and permitted forums).
314
+     * @return string
315
+     */
316
+    public static function user_forums_sql()
317
+    {
318
+        // I couldn't come up with a good name, please rename this if you can. -- Y
319
+        $RestrictedForums = self::get_restricted_forums();
320
+        $PermittedForums = self::get_permitted_forums();
321
+        if (Donations::has_donor_forum(G::$LoggedUser['ID']) && !in_array(DONOR_FORUM, $PermittedForums)) {
322
+            $PermittedForums[] = DONOR_FORUM;
323
+        }
324
+        $SQL = "((f.MinClassRead <= '" . G::$LoggedUser['Class'] . "'";
325
+        if (count($RestrictedForums)) {
326
+            $SQL .= " AND f.ID NOT IN ('" . implode("', '", $RestrictedForums) . "')";
327
+        }
328
+        $SQL .= ')';
329
+        if (count($PermittedForums)) {
330
+            $SQL .= " OR f.ID IN ('" . implode("', '", $PermittedForums) . "')";
331
+        }
332
+        $SQL .= ')';
333
+        return $SQL;
315
     }
334
     }
316
-    $SQL .= ')';
317
-    return $SQL;
318
-  }
319
 }
335
 }

+ 15
- 12
classes/g.class.php View File

1
-<?
2
-class G {
3
-  public static $DB;
4
-  public static $Cache;
5
-  public static $LoggedUser;
1
+<?php
6
 
2
 
7
-  public static function initialize() {
8
-    global $DB, $Cache, $LoggedUser;
9
-    self::$DB = $DB;
10
-    self::$Cache = $Cache;
11
-    self::$LoggedUser =& $LoggedUser;
12
-  }
13
-}
3
+class G
4
+{
5
+    public static $DB;
6
+    public static $Cache;
7
+    public static $LoggedUser;
8
+
9
+    public static function initialize()
10
+    {
11
+        global $DB, $Cache, $LoggedUser;
12
+        self::$DB = $DB;
13
+        self::$Cache = $Cache;
14
+        self::$LoggedUser =& $LoggedUser;
15
+    }
16
+}

+ 48
- 43
classes/image.class.php View File

1
-<?
1
+<?php
2
+
2
 if (!extension_loaded('gd')) {
3
 if (!extension_loaded('gd')) {
3
-  error('GD Extension not loaded.');
4
+    error('GD Extension not loaded.');
4
 }
5
 }
5
 
6
 
6
-class IMAGE {
7
-  var $Image = false;
8
-  var $FontSize = 10;
9
-  var $Font = '';
10
-  var $TextAngle = 0;
11
-
12
-  function create($Width, $Height) {
13
-    $this->Image = imagecreate($Width, $Height);
14
-    $this->Font = SERVER_ROOT.'/classes/fonts/VERDANA.TTF';
15
-    if (function_exists('imageantialias')) {
16
-      imageantialias($this->Image, true);
7
+class IMAGE
8
+{
9
+    public $Image = false;
10
+    public $FontSize = 10;
11
+    public $Font = '';
12
+    public $TextAngle = 0;
13
+
14
+    public function create($Width, $Height)
15
+    {
16
+        $this->Image = imagecreate($Width, $Height);
17
+        $this->Font = SERVER_ROOT.'/classes/fonts/VERDANA.TTF';
18
+        if (function_exists('imageantialias')) {
19
+            imageantialias($this->Image, true);
20
+        }
17
     }
21
     }
18
-  }
19
-
20
-  function color($Red, $Green, $Blue, $Alpha = 0) {
21
-    return imagecolorallocatealpha($this->Image, $Red, $Green, $Blue, $Alpha);
22
-  }
23
 
22
 
24
-  function line($x1, $y1, $x2, $y2, $Color, $Thickness = 1) {
25
-    if ($Thickness == 1) {
26
-      return imageline($this->Image, $x1, $y1, $x2, $y2, $Color);
27
-    }
28
-    $t = $Thickness / 2 - 0.5;
29
-    if ($x1 == $x2 || $y1 == $y2) {
30
-      return imagefilledrectangle($this->Image, round(min($x1, $x2) - $t), round(min($y1, $y2) - $t), round(max($x1, $x2) + $t), round(max($y1, $y2) + $t), $color);
23
+    public function color($Red, $Green, $Blue, $Alpha = 0)
24
+    {
25
+        return imagecolorallocatealpha($this->Image, $Red, $Green, $Blue, $Alpha);
31
     }
26
     }
32
-    $k = ($y2 - $y1) / ($x2 - $x1); //y = kx + q
33
-    $a = $t / sqrt(1 + pow($k, 2));
34
-    $Points = array(
27
+
28
+    public function line($x1, $y1, $x2, $y2, $Color, $Thickness = 1)
29
+    {
30
+        if ($Thickness == 1) {
31
+            return imageline($this->Image, $x1, $y1, $x2, $y2, $Color);
32
+        }
33
+        $t = $Thickness / 2 - 0.5;
34
+        if ($x1 == $x2 || $y1 == $y2) {
35
+            return imagefilledrectangle($this->Image, round(min($x1, $x2) - $t), round(min($y1, $y2) - $t), round(max($x1, $x2) + $t), round(max($y1, $y2) + $t), $color);
36
+        }
37
+        $k = ($y2 - $y1) / ($x2 - $x1); //y = kx + q
38
+        $a = $t / sqrt(1 + pow($k, 2));
39
+        $Points = array(
35
       round($x1 - (1 + $k) * $a), round($y1 + (1 - $k) * $a),
40
       round($x1 - (1 + $k) * $a), round($y1 + (1 - $k) * $a),
36
       round($x1 - (1 - $k) * $a), round($y1 - (1 + $k) * $a),
41
       round($x1 - (1 - $k) * $a), round($y1 - (1 + $k) * $a),
37
       round($x2 + (1 + $k) * $a), round($y2 - (1 - $k) * $a),
42
       round($x2 + (1 + $k) * $a), round($y2 - (1 - $k) * $a),
38
       round($x2 + (1 - $k) * $a), round($y2 + (1 + $k) * $a),
43
       round($x2 + (1 - $k) * $a), round($y2 + (1 + $k) * $a),
39
     );
44
     );
40
-    imagefilledpolygon($this->Image, $Points, 4, $Color);
41
-    return imagepolygon($this->Image, $Points, 4, $Color);
42
-  }
43
-
44
-  function ellipse($x, $y, $Width, $Height, $Color) {
45
-    return imageEllipse($this->Image, $x, $y, $Width, $Height, $Color);
46
-  }
47
-
48
-  function text($x, $y, $Color, $Text) {
49
-    return imagettftext ($this->Image, $this->FontSize, $this->TextAngle, $x, $y, $Color, $this->Font, $Text);
50
-  }
45
+        imagefilledpolygon($this->Image, $Points, 4, $Color);
46
+        return imagepolygon($this->Image, $Points, 4, $Color);
47
+    }
51
 
48
 
52
-  function make_png($FileName = null) {
53
-    return imagepng($this->Image, $FileName);
54
-  }
49
+    public function ellipse($x, $y, $Width, $Height, $Color)
50
+    {
51
+        return imageEllipse($this->Image, $x, $y, $Width, $Height, $Color);
52
+    }
55
 
53
 
54
+    public function text($x, $y, $Color, $Text)
55
+    {
56
+        return imagettftext($this->Image, $this->FontSize, $this->TextAngle, $x, $y, $Color, $this->Font, $Text);
57
+    }
56
 
58
 
59
+    public function make_png($FileName = null)
60
+    {
61
+        return imagepng($this->Image, $FileName);
62
+    }
57
 }
63
 }
58
-?>

+ 37
- 31
classes/imagetools.class.php View File

4
  * ImageTools Class
4
  * ImageTools Class
5
  * Thumbnail aide, mostly
5
  * Thumbnail aide, mostly
6
  */
6
  */
7
-class ImageTools {
8
-
9
-  /**
10
-   * Determine the image URL. This takes care of the image proxy and thumbnailing.
11
-   * @param string $Url
12
-   * @param string $Thumb image proxy scale profile to use
13
-   * @return string
14
-   */
15
-  public static function process($Url = '', $Thumb = false) {
16
-    if (!$Url) return '';
17
-    if (preg_match('/^https:\/\/('.SITE_DOMAIN.'|'.IMAGE_DOMAIN.')\//', $Url) || $Url[0]=='/') {
18
-      if (strpos($Url, '?') === false) $Url .= '?';
19
-      return $Url;
20
-    } else {
21
-      return 'https://'.IMAGE_DOMAIN.($Thumb?"/$Thumb/":'/').'?h='.rawurlencode(base64_encode(hash_hmac('sha256', $Url, IMAGE_PSK, true))).'&i='.urlencode($Url);
7
+class ImageTools
8
+{
9
+    /**
10
+     * Determine the image URL. This takes care of the image proxy and thumbnailing.
11
+     * @param string $Url
12
+     * @param string $Thumb image proxy scale profile to use
13
+     * @return string
14
+     */
15
+    public static function process($Url = '', $Thumb = false)
16
+    {
17
+        if (!$Url) {
18
+            return '';
19
+        }
20
+        if (preg_match('/^https:\/\/('.SITE_DOMAIN.'|'.IMAGE_DOMAIN.')\//', $Url) || $Url[0]=='/') {
21
+            if (strpos($Url, '?') === false) {
22
+                $Url .= '?';
23
+            }
24
+            return $Url;
25
+        } else {
26
+            return 'https://'.IMAGE_DOMAIN.($Thumb?"/$Thumb/":'/').'?h='.rawurlencode(base64_encode(hash_hmac('sha256', $Url, IMAGE_PSK, true))).'&i='.urlencode($Url);
27
+        }
22
     }
28
     }
23
-  }
24
 
29
 
25
-  /**
26
-   * Checks if a link's host is (not) good, otherwise displays an error.
27
-   * @param string $Url Link to an image
28
-   * @return boolean
29
-   */
30
-  public static function blacklisted($Url, $ShowError = true) {
31
-    $Blacklist = ['tinypic.com'];
32
-    foreach ($Blacklist as $Value) {
33
-      if (stripos($Url, $Value) !== false) {
34
-        if ($ShowError) {
35
-          error($Value . ' is not an allowed image host. Please use a different host.');
30
+    /**
31
+     * Checks if a link's host is (not) good, otherwise displays an error.
32
+     * @param string $Url Link to an image
33
+     * @return boolean
34
+     */
35
+    public static function blacklisted($Url, $ShowError = true)
36
+    {
37
+        $Blacklist = ['tinypic.com'];
38
+        foreach ($Blacklist as $Value) {
39
+            if (stripos($Url, $Value) !== false) {
40
+                if ($ShowError) {
41
+                    error($Value . ' is not an allowed image host. Please use a different host.');
42
+                }
43
+                return true;
44
+            }
36
         }
45
         }
37
-        return true;
38
-      }
46
+        return false;
39
     }
47
     }
40
-    return false;
41
-  }
42
 }
48
 }

+ 26
- 26
classes/inbox.class.php View File

1
 <?php
1
 <?php
2
 
2
 
3
-class Inbox {
4
-  /*
5
-   * Get the link to a user's inbox.
6
-   * This is what handles the ListUnreadPMsFirst setting
7
-   *
8
-   * @param string - whether the inbox or sentbox should be loaded
9
-   * @return string - the URL to a user's inbox
10
-   */
11
-  public static function get_inbox_link($WhichBox = 'inbox') {
3
+class Inbox
4
+{
5
+    /*
6
+     * Get the link to a user's inbox.
7
+     * This is what handles the ListUnreadPMsFirst setting
8
+     *
9
+     * @param string - whether the inbox or sentbox should be loaded
10
+     * @return string - the URL to a user's inbox
11
+     */
12
+    public static function get_inbox_link($WhichBox = 'inbox')
13
+    {
14
+        $ListFirst = isset(G::$LoggedUser['ListUnreadPMsFirst']) ? G::$LoggedUser['ListUnreadPMsFirst'] : false;
12
 
15
 
13
-    $ListFirst = isset(G::$LoggedUser['ListUnreadPMsFirst']) ? G::$LoggedUser['ListUnreadPMsFirst'] : false;
14
-
15
-    if ($WhichBox == 'inbox') {
16
-      if ($ListFirst) {
17
-        $InboxURL = 'inbox.php?sort=unread';
18
-      } else {
19
-        $InboxURL = 'inbox.php';
20
-      }
21
-    } else {
22
-      if ($ListFirst) {
23
-        $InboxURL = 'inbox.php?action=sentbox&amp;sort=unread';
24
-      } else {
25
-        $InboxURL = 'inbox.php?action=sentbox';
26
-      }
16
+        if ($WhichBox === 'inbox') {
17
+            if ($ListFirst) {
18
+                $InboxURL = 'inbox.php?sort=unread';
19
+            } else {
20
+                $InboxURL = 'inbox.php';
21
+            }
22
+        } else {
23
+            if ($ListFirst) {
24
+                $InboxURL = 'inbox.php?action=sentbox&amp;sort=unread';
25
+            } else {
26
+                $InboxURL = 'inbox.php?action=sentbox';
27
+            }
28
+        }
29
+        return $InboxURL;
27
     }
30
     }
28
-    return $InboxURL;
29
-  }
30
 }
31
 }
31
-?>

+ 186
- 193
classes/invite_tree.class.php View File

1
-<?
1
+<?php
2
+
2
 /**************************************************************************/
3
 /**************************************************************************/
3
 /*-- Invite tree class -----------------------------------------------------
4
 /*-- Invite tree class -----------------------------------------------------
4
-
5
-
6
-
7
 ***************************************************************************/
5
 ***************************************************************************/
8
 
6
 
9
-class INVITE_TREE {
10
-  var $UserID = 0;
11
-  var $Visible = true;
12
-
13
-  // Set things up
14
-  function INVITE_TREE($UserID, $Options = []) {
15
-    $this->UserID = $UserID;
16
-    if ($Options['visible'] === false) {
17
-      $this->Visible = false;
7
+class INVITE_TREE
8
+{
9
+    public $UserID = 0;
10
+    public $Visible = true;
11
+
12
+    // Set things up
13
+    public function INVITE_TREE($UserID, $Options = [])
14
+    {
15
+        $this->UserID = $UserID;
16
+        if ($Options['visible'] === false) {
17
+            $this->Visible = false;
18
+        }
18
     }
19
     }
19
-  }
20
 
20
 
21
-  function make_tree() {
22
-    $QueryID = G::$DB->get_query_id();
21
+    public function make_tree()
22
+    {
23
+        $QueryID = G::$DB->get_query_id();
23
 
24
 
24
-    $UserID = $this->UserID;
25
-?>
26
-    <div class="invitetree pad">
27
-<?
25
+        $UserID = $this->UserID; ?>
26
+<div class="invitetree pad">
27
+  <?php
28
     G::$DB->query("
28
     G::$DB->query("
29
       SELECT TreePosition, TreeID, TreeLevel
29
       SELECT TreePosition, TreeID, TreeLevel
30
       FROM invite_tree
30
       FROM invite_tree
31
       WHERE UserID = $UserID");
31
       WHERE UserID = $UserID");
32
-    list($TreePosition, $TreeID, $TreeLevel) = G::$DB->next_record(MYSQLI_NUM, false);
32
+        list($TreePosition, $TreeID, $TreeLevel) = G::$DB->next_record(MYSQLI_NUM, false);
33
 
33
 
34
-    if (!$TreeID) {
35
-      return;
36
-    }
37
-    G::$DB->query("
34
+        if (!$TreeID) {
35
+            return;
36
+        }
37
+        G::$DB->query("
38
       SELECT TreePosition
38
       SELECT TreePosition
39
       FROM invite_tree
39
       FROM invite_tree
40
       WHERE TreeID = $TreeID
40
       WHERE TreeID = $TreeID
42
         AND TreePosition > $TreePosition
42
         AND TreePosition > $TreePosition
43
       ORDER BY TreePosition ASC
43
       ORDER BY TreePosition ASC
44
       LIMIT 1");
44
       LIMIT 1");
45
-    if (G::$DB->has_results()) {
46
-      list($MaxPosition) = G::$DB->next_record(MYSQLI_NUM, false);
47
-    } else {
48
-      $MaxPosition = false;
49
-    }
50
-    $TreeQuery = G::$DB->query("
45
+        if (G::$DB->has_results()) {
46
+            list($MaxPosition) = G::$DB->next_record(MYSQLI_NUM, false);
47
+        } else {
48
+            $MaxPosition = false;
49
+        }
50
+        $TreeQuery = G::$DB->query("
51
       SELECT
51
       SELECT
52
         it.UserID,
52
         it.UserID,
53
         Enabled,
53
         Enabled,
67
         AND TreeLevel > $TreeLevel
67
         AND TreeLevel > $TreeLevel
68
       ORDER BY TreePosition");
68
       ORDER BY TreePosition");
69
 
69
 
70
-    $PreviousTreeLevel = $TreeLevel;
70
+        $PreviousTreeLevel = $TreeLevel;
71
 
71
 
72
-    // Stats for the summary
72
+        // Stats for the summary
73
     $MaxTreeLevel = $TreeLevel; // The deepest level (this changes)
73
     $MaxTreeLevel = $TreeLevel; // The deepest level (this changes)
74
     $OriginalTreeLevel = $TreeLevel; // The level of the user we're viewing
74
     $OriginalTreeLevel = $TreeLevel; // The level of the user we're viewing
75
     $BaseTreeLevel = $TreeLevel + 1; // The level of users invited by our user
75
     $BaseTreeLevel = $TreeLevel + 1; // The level of users invited by our user
76
     $Count = 0;
76
     $Count = 0;
77
-    $Branches = 0;
78
-    $DisabledCount = 0;
79
-    $DonorCount = 0;
80
-    $ParanoidCount = 0;
81
-    $TotalUpload = 0;
82
-    $TotalDownload = 0;
83
-    $TopLevelUpload = 0;
84
-    $TopLevelDownload = 0;
85
-
86
-    $ClassSummary = [];
87
-    global $Classes;
88
-    foreach ($Classes as $ClassID => $Val) {
89
-      $ClassSummary[$ClassID] = 0;
90
-    }
77
+        $Branches = 0;
78
+        $DisabledCount = 0;
79
+        $DonorCount = 0;
80
+        $ParanoidCount = 0;
81
+        $TotalUpload = 0;
82
+        $TotalDownload = 0;
83
+        $TopLevelUpload = 0;
84
+        $TopLevelDownload = 0;
85
+
86
+        $ClassSummary = [];
87
+        global $Classes;
88
+        foreach ($Classes as $ClassID => $Val) {
89
+            $ClassSummary[$ClassID] = 0;
90
+        }
91
 
91
 
92
-    // We store this in an output buffer, so we can show the summary at the top without having to loop through twice
93
-    ob_start();
94
-    while (list($ID, $Enabled, $Class, $Donor, $Uploaded, $Downloaded, $Paranoia, $TreePosition, $TreeLevel) = G::$DB->next_record(MYSQLI_NUM, false)) {
92
+        // We store this in an output buffer, so we can show the summary at the top without having to loop through twice
93
+        ob_start();
94
+        while (list($ID, $Enabled, $Class, $Donor, $Uploaded, $Downloaded, $Paranoia, $TreePosition, $TreeLevel) = G::$DB->next_record(MYSQLI_NUM, false)) {
95
 
95
 
96
       // Do stats
96
       // Do stats
97
-      $Count++;
98
-
99
-      if ($TreeLevel > $MaxTreeLevel) {
100
-        $MaxTreeLevel = $TreeLevel;
101
-      }
102
-
103
-      if ($TreeLevel == $BaseTreeLevel) {
104
-        $Branches++;
105
-        $TopLevelUpload += $Uploaded;
106
-        $TopLevelDownload += $Downloaded;
107
-      }
108
-
109
-      $ClassSummary[$Class]++;
110
-      if ($Enabled == 2) {
111
-        $DisabledCount++;
112
-      }
113
-      if ($Donor) {
114
-        $DonorCount++;
115
-      }
116
-
117
-      // Manage tree depth
118
-      if ($TreeLevel > $PreviousTreeLevel) {
119
-        for ($i = 0; $i < $TreeLevel - $PreviousTreeLevel; $i++) {
120
-          echo "\n\n<ul class=\"invitetree\">\n\t<li>\n";
121
-        }
122
-      } elseif ($TreeLevel < $PreviousTreeLevel) {
123
-        for ($i = 0; $i < $PreviousTreeLevel - $TreeLevel; $i++) {
124
-          echo "\t</li>\n</ul>\n";
125
-        }
126
-        echo "\t</li>\n\t<li>\n";
127
-      } else {
128
-        echo "\t</li>\n\t<li>\n";
129
-      }
130
-      $UserClass = $Classes[$Class]['Level'];
131
-?>
132
-    <strong><?=Users::format_username($ID, true, true, ($Enabled != 2 ? false : true), true)?></strong>
133
-<?
97
+            $Count++;
98
+
99
+            if ($TreeLevel > $MaxTreeLevel) {
100
+                $MaxTreeLevel = $TreeLevel;
101
+            }
102
+
103
+            if ($TreeLevel == $BaseTreeLevel) {
104
+                $Branches++;
105
+                $TopLevelUpload += $Uploaded;
106
+                $TopLevelDownload += $Downloaded;
107
+            }
108
+
109
+            $ClassSummary[$Class]++;
110
+            if ($Enabled == 2) {
111
+                $DisabledCount++;
112
+            }
113
+            if ($Donor) {
114
+                $DonorCount++;
115
+            }
116
+
117
+            // Manage tree depth
118
+            if ($TreeLevel > $PreviousTreeLevel) {
119
+                for ($i = 0; $i < $TreeLevel - $PreviousTreeLevel; $i++) {
120
+                    echo "\n\n<ul class=\"invitetree\">\n\t<li>\n";
121
+                }
122
+            } elseif ($TreeLevel < $PreviousTreeLevel) {
123
+                for ($i = 0; $i < $PreviousTreeLevel - $TreeLevel; $i++) {
124
+                    echo "\t</li>\n</ul>\n";
125
+                }
126
+                echo "\t</li>\n\t<li>\n";
127
+            } else {
128
+                echo "\t</li>\n\t<li>\n";
129
+            }
130
+            $UserClass = $Classes[$Class]['Level']; ?>
131
+  <strong><?=Users::format_username($ID, true, true, ($Enabled != 2 ? false : true), true)?></strong>
132
+  <?php
134
       if (check_paranoia(array('uploaded', 'downloaded'), $Paranoia, $UserClass)) {
133
       if (check_paranoia(array('uploaded', 'downloaded'), $Paranoia, $UserClass)) {
135
-        $TotalUpload += $Uploaded;
136
-        $TotalDownload += $Downloaded;
137
-?>
138
-    &nbsp;Uploaded: <strong><?=Format::get_size($Uploaded)?></strong>
139
-    &nbsp;Downloaded: <strong><?=Format::get_size($Downloaded)?></strong>
140
-    &nbsp;Ratio: <strong><?=Format::get_ratio_html($Uploaded, $Downloaded)?></strong>
141
-<?
134
+          $TotalUpload += $Uploaded;
135
+          $TotalDownload += $Downloaded; ?>
136
+  &nbsp;Uploaded: <strong><?=Format::get_size($Uploaded)?></strong>
137
+  &nbsp;Downloaded: <strong><?=Format::get_size($Downloaded)?></strong>
138
+  &nbsp;Ratio: <strong><?=Format::get_ratio_html($Uploaded, $Downloaded)?></strong>
139
+  <?php
142
       } else {
140
       } else {
143
-        $ParanoidCount++;
144
-?>
145
-    &nbsp;Hidden
146
-<?
147
-      }
148
-?>
149
-
150
-<?
151
-      $PreviousTreeLevel = $TreeLevel;
152
-      G::$DB->set_query_id($TreeQuery);
153
-    }
141
+          $ParanoidCount++; ?>
142
+  &nbsp;Hidden
143
+  <?php
144
+      } ?>
154
 
145
 
155
-    $Tree = ob_get_clean();
156
-    for ($i = 0; $i < $PreviousTreeLevel - $OriginalTreeLevel; $i++) {
157
-      $Tree .= "\t</li>\n</ul>\n";
158
-    }
146
+  <?php
147
+      $PreviousTreeLevel = $TreeLevel;
148
+            G::$DB->set_query_id($TreeQuery);
149
+        }
159
 
150
 
160
-    if ($Count) {
151
+        $Tree = ob_get_clean();
152
+        for ($i = 0; $i < $PreviousTreeLevel - $OriginalTreeLevel; $i++) {
153
+            $Tree .= "\t</li>\n</ul>\n";
154
+        }
161
 
155
 
162
-?>
163
-    <p style="font-weight: bold;">
164
-      This tree has <?=number_format($Count)?> entries, <?=number_format($Branches)?> branches, and a depth of <?=number_format($MaxTreeLevel - $OriginalTreeLevel)?>.
165
-      It has
166
-<?
156
+        if ($Count) {
157
+            ?>
158
+  <p style="font-weight: bold;">
159
+    This tree has <?=number_format($Count)?> entries, <?=number_format($Branches)?> branches, and a depth of <?=number_format($MaxTreeLevel - $OriginalTreeLevel)?>.
160
+    It has
161
+    <?php
167
       $ClassStrings = [];
162
       $ClassStrings = [];
168
-      foreach ($ClassSummary as $ClassID => $ClassCount) {
169
-        if ($ClassCount == 0) {
170
-          continue;
171
-        }
172
-        $LastClass = Users::make_class_string($ClassID);
173
-        if ($ClassCount > 1) {
174
-          if ($LastClass == 'Torrent Celebrity') {
175
-             $LastClass = 'Torrent Celebrities';
176
-          } else {
177
-            // Prevent duplicate letterss
178
-            if (substr($LastClass, -1) != 's') {
179
-              $LastClass.='s';
163
+            foreach ($ClassSummary as $ClassID => $ClassCount) {
164
+                if ($ClassCount == 0) {
165
+                    continue;
166
+                }
167
+                $LastClass = Users::make_class_string($ClassID);
168
+                if ($ClassCount > 1) {
169
+                    if ($LastClass == 'Torrent Celebrity') {
170
+                        $LastClass = 'Torrent Celebrities';
171
+                    } else {
172
+                        // Prevent duplicate letterss
173
+                        if (substr($LastClass, -1) != 's') {
174
+                            $LastClass.='s';
175
+                        }
176
+                    }
177
+                }
178
+                $LastClass = "$ClassCount $LastClass (" . number_format(($ClassCount / $Count) * 100) . '%)';
179
+
180
+                $ClassStrings[] = $LastClass;
180
             }
181
             }
181
-          }
182
-        }
183
-        $LastClass = "$ClassCount $LastClass (" . number_format(($ClassCount / $Count) * 100) . '%)';
184
-
185
-        $ClassStrings[] = $LastClass;
186
-      }
187
-      if (count($ClassStrings) > 1) {
188
-        array_pop($ClassStrings);
189
-        echo implode(', ', $ClassStrings);
190
-        echo ' and '.$LastClass;
191
-      } else {
192
-        echo $LastClass;
193
-      }
194
-      echo '. ';
195
-      echo $DisabledCount;
196
-      echo ($DisabledCount == 1) ? ' user is' : ' users are';
197
-      echo ' disabled (';
198
-      if ($DisabledCount == 0) {
199
-        echo '0%)';
200
-      } else {
201
-        echo number_format(($DisabledCount / $Count) * 100) . '%)';
202
-      }
203
-      echo ', and ';
204
-      echo $DonorCount;
205
-      echo ($DonorCount == 1) ? ' user has' : ' users have';
206
-      echo ' donated (';
207
-      if ($DonorCount == 0) {
208
-        echo '0%)';
209
-      } else {
210
-        echo number_format(($DonorCount / $Count) * 100) . '%)';
211
-      }
212
-      echo '. </p>';
213
-
214
-      echo '<p style="font-weight: bold;">';
215
-      echo 'The total amount uploaded by the entire tree was '.Format::get_size($TotalUpload);
216
-      echo '; the total amount downloaded was '.Format::get_size($TotalDownload);
217
-      echo '; and the total ratio is '.Format::get_ratio_html($TotalUpload, $TotalDownload).'. ';
218
-      echo '</p>';
219
-
220
-      echo '<p style="font-weight: bold;">';
221
-      echo 'The total amount uploaded by direct invitees (the top level) was '.Format::get_size($TopLevelUpload);
222
-      echo '; the total amount downloaded was '.Format::get_size($TopLevelDownload);
223
-      echo '; and the total ratio is '.Format::get_ratio_html($TopLevelUpload, $TopLevelDownload).'. ';
224
-
225
-      echo "These numbers include the stats of paranoid users and will be factored into the invitation giving script.\n\t\t</p>\n";
226
-
227
-      if ($ParanoidCount) {
228
-        echo '<p style="font-weight: bold;">';
229
-        echo $ParanoidCount;
230
-        echo ($ParanoidCount == 1) ? ' user (' : ' users (';
231
-        echo number_format(($ParanoidCount / $Count) * 100);
232
-        echo '%) ';
233
-        echo ($ParanoidCount == 1) ? ' is' : ' are';
234
-        echo ' too paranoid to have their stats shown here, and ';
235
-        echo ($ParanoidCount == 1) ? ' was' : ' were';
236
-        echo ' not factored into the stats for the total tree.';
237
-        echo '</p>';
238
-      }
239
-    }
240
-?>
241
-      <br />
242
-<?=     $Tree?>
243
-    </div>
244
-<?
182
+            if (count($ClassStrings) > 1) {
183
+                array_pop($ClassStrings);
184
+                echo implode(', ', $ClassStrings);
185
+                echo ' and '.$LastClass;
186
+            } else {
187
+                echo $LastClass;
188
+            }
189
+            echo '. ';
190
+            echo $DisabledCount;
191
+            echo ($DisabledCount == 1) ? ' user is' : ' users are';
192
+            echo ' disabled (';
193
+            if ($DisabledCount == 0) {
194
+                echo '0%)';
195
+            } else {
196
+                echo number_format(($DisabledCount / $Count) * 100) . '%)';
197
+            }
198
+            echo ', and ';
199
+            echo $DonorCount;
200
+            echo ($DonorCount == 1) ? ' user has' : ' users have';
201
+            echo ' donated (';
202
+            if ($DonorCount == 0) {
203
+                echo '0%)';
204
+            } else {
205
+                echo number_format(($DonorCount / $Count) * 100) . '%)';
206
+            }
207
+            echo '. </p>';
208
+
209
+            echo '<p style="font-weight: bold;">';
210
+            echo 'The total amount uploaded by the entire tree was '.Format::get_size($TotalUpload);
211
+            echo '; the total amount downloaded was '.Format::get_size($TotalDownload);
212
+            echo '; and the total ratio is '.Format::get_ratio_html($TotalUpload, $TotalDownload).'. ';
213
+            echo '</p>';
214
+
215
+            echo '<p style="font-weight: bold;">';
216
+            echo 'The total amount uploaded by direct invitees (the top level) was '.Format::get_size($TopLevelUpload);
217
+            echo '; the total amount downloaded was '.Format::get_size($TopLevelDownload);
218
+            echo '; and the total ratio is '.Format::get_ratio_html($TopLevelUpload, $TopLevelDownload).'. ';
219
+
220
+            echo "These numbers include the stats of paranoid users and will be factored into the invitation giving script.\n\t\t</p>\n";
221
+
222
+            if ($ParanoidCount) {
223
+                echo '<p style="font-weight: bold;">';
224
+                echo $ParanoidCount;
225
+                echo ($ParanoidCount == 1) ? ' user (' : ' users (';
226
+                echo number_format(($ParanoidCount / $Count) * 100);
227
+                echo '%) ';
228
+                echo ($ParanoidCount == 1) ? ' is' : ' are';
229
+                echo ' too paranoid to have their stats shown here, and ';
230
+                echo ($ParanoidCount == 1) ? ' was' : ' were';
231
+                echo ' not factored into the stats for the total tree.';
232
+                echo '</p>';
233
+            }
234
+        } ?>
235
+    <br />
236
+    <?=     $Tree?>
237
+</div>
238
+<?php
245
     G::$DB->set_query_id($QueryID);
239
     G::$DB->set_query_id($QueryID);
246
-  }
240
+    }
247
 }
241
 }
248
-?>

+ 70
- 62
classes/mass_user_bookmarks_editor.class.php View File

8
  * It can later be used for other bookmark tables.
8
  * It can later be used for other bookmark tables.
9
  *
9
  *
10
  */
10
  */
11
-class MASS_USER_BOOKMARKS_EDITOR extends MASS_USER_TORRENTS_EDITOR {
12
-  public function __construct($Table = 'bookmarks_torrents') {
13
-    $this->set_table($Table);
14
-  }
15
-
16
-  /**
17
-   * Runs a SQL query and clears the Cache key
18
-   *
19
-   * G::$Cache->delete_value didn't always work, but setting the key to null, did. (?)
20
-   *
21
-   * @param string $sql
22
-   */
23
-  protected function query_and_clear_cache($sql) {
24
-    $QueryID = G::$DB->get_query_id();
25
-    if (is_string($sql) && G::$DB->query($sql)) {
26
-      G::$Cache->delete_value('bookmarks_group_ids_' . G::$LoggedUser['ID']);
11
+class MASS_USER_BOOKMARKS_EDITOR extends MASS_USER_TORRENTS_EDITOR
12
+{
13
+    public function __construct($Table = 'bookmarks_torrents')
14
+    {
15
+        $this->set_table($Table);
27
     }
16
     }
28
-    G::$DB->set_query_id($QueryID);
29
-  }
30
 
17
 
31
-  /**
32
-   * Uses (checkboxes) $_POST['remove'] to delete entries.
33
-   *
34
-   * Uses an IN() to match multiple items in one query.
35
-   */
36
-  public function mass_remove() {
37
-    $SQL = [];
38
-    foreach ($_POST['remove'] as $GroupID => $K) {
39
-      if (is_number($GroupID)) {
40
-        $SQL[] = sprintf('%d', $GroupID);
41
-      }
18
+    /**
19
+     * Runs a SQL query and clears the Cache key
20
+     *
21
+     * G::$Cache->delete_value didn't always work, but setting the key to null, did. (?)
22
+     *
23
+     * @param string $sql
24
+     */
25
+    protected function query_and_clear_cache($sql)
26
+    {
27
+        $QueryID = G::$DB->get_query_id();
28
+        if (is_string($sql) && G::$DB->query($sql)) {
29
+            G::$Cache->delete_value('bookmarks_group_ids_' . G::$LoggedUser['ID']);
30
+        }
31
+        G::$DB->set_query_id($QueryID);
42
     }
32
     }
43
 
33
 
44
-    if (!empty($SQL)) {
45
-      $SQL = sprintf('
46
-          DELETE FROM %s
47
-          WHERE UserID = %d
48
-            AND GroupID IN (%s)',
49
-        $this->Table,
50
-        G::$LoggedUser['ID'],
51
-        implode(', ', $SQL)
52
-      );
53
-      $this->query_and_clear_cache($SQL);
54
-    }
55
-  }
34
+    /**
35
+     * Uses (checkboxes) $_POST['remove'] to delete entries.
36
+     *
37
+     * Uses an IN() to match multiple items in one query.
38
+     */
39
+    public function mass_remove()
40
+    {
41
+        $SQL = [];
42
+        foreach ($_POST['remove'] as $GroupID => $K) {
43
+            if (is_number($GroupID)) {
44
+                $SQL[] = sprintf('%d', $GroupID);
45
+            }
46
+        }
56
 
47
 
57
-  /**
58
-   * Uses $_POST['sort'] values to update the DB.
59
-   */
60
-  public function mass_update() {
61
-    $SQL = [];
62
-    foreach ($_POST['sort'] as $GroupID => $Sort) {
63
-      if (is_number($Sort) && is_number($GroupID)) {
64
-        $SQL[] = sprintf('(%d, %d, %d)', $GroupID, $Sort, G::$LoggedUser['ID']);
65
-      }
48
+        if (!empty($SQL)) {
49
+            $SQL = sprintf(
50
+                '
51
+            DELETE FROM %s
52
+              WHERE UserID = %d
53
+              AND GroupID IN (%s)',
54
+                $this->Table,
55
+                G::$LoggedUser['ID'],
56
+                implode(', ', $SQL)
57
+            );
58
+            $this->query_and_clear_cache($SQL);
59
+        }
66
     }
60
     }
67
 
61
 
68
-    if (!empty($SQL)) {
69
-      $SQL = sprintf('
70
-          INSERT INTO %s
71
-            (GroupID, Sort, UserID)
72
-          VALUES
73
-            %s
74
-          ON DUPLICATE KEY UPDATE
75
-            Sort = VALUES (Sort)',
76
-        $this->Table,
77
-        implode(', ', $SQL));
78
-      $this->query_and_clear_cache($SQL);
62
+    /**
63
+     * Uses $_POST['sort'] values to update the DB.
64
+     */
65
+    public function mass_update()
66
+    {
67
+        $SQL = [];
68
+        foreach ($_POST['sort'] as $GroupID => $Sort) {
69
+            if (is_number($Sort) && is_number($GroupID)) {
70
+                $SQL[] = sprintf('(%d, %d, %d)', $GroupID, $Sort, G::$LoggedUser['ID']);
71
+            }
72
+        }
73
+
74
+        if (!empty($SQL)) {
75
+            $SQL = sprintf(
76
+                '
77
+            INSERT INTO %s
78
+              (GroupID, Sort, UserID)
79
+            VALUES
80
+              %s
81
+            ON DUPLICATE KEY UPDATE
82
+              Sort = VALUES (Sort)',
83
+                $this->Table,
84
+                implode(', ', $SQL)
85
+            );
86
+            $this->query_and_clear_cache($SQL);
87
+        }
79
     }
88
     }
80
-  }
81
 }
89
 }

+ 332
- 294
classes/mysql.class.php View File

1
-<?
1
+<?php
2
 
2
 
3
 //-----------------------------------------------------------------------------------
3
 //-----------------------------------------------------------------------------------
4
 /////////////////////////////////////////////////////////////////////////////////////
4
 /////////////////////////////////////////////////////////////////////////////////////
115
 *///---------------------------------------------------------------------------------
115
 *///---------------------------------------------------------------------------------
116
 
116
 
117
 if (!extension_loaded('mysqli')) {
117
 if (!extension_loaded('mysqli')) {
118
-  die('Mysqli Extension not loaded.');
118
+    die('Mysqli Extension not loaded.');
119
 }
119
 }
120
 
120
 
121
 // Handles escaping
121
 // Handles escaping
122
-function db_string($String, $DisableWildcards = false) {
123
-  global $DB;
124
-  // Escape
125
-  $String = $DB->escape_str($String);
126
-  // Remove user input wildcards
127
-  if ($DisableWildcards) {
128
-    $String = str_replace(array('%','_'), array('\%','\_'), $String);
129
-  }
130
-  return $String;
122
+function db_string($String, $DisableWildcards = false)
123
+{
124
+    global $DB;
125
+
126
+    // Escape
127
+    $String = $DB->escape_str($String);
128
+
129
+    // Remove user input wildcards
130
+    if ($DisableWildcards) {
131
+        $String = str_replace(array('%','_'), array('\%','\_'), $String);
132
+    }
133
+    return $String;
131
 }
134
 }
132
 
135
 
133
-function db_array($Array, $DontEscape = [], $Quote = false) {
134
-  foreach ($Array as $Key => $Val) {
135
-    if (!in_array($Key, $DontEscape)) {
136
-      if ($Quote) {
137
-        $Array[$Key] = '\''.db_string(trim($Val)).'\'';
138
-      } else {
139
-        $Array[$Key] = db_string(trim($Val));
140
-      }
136
+function db_array($Array, $DontEscape = [], $Quote = false)
137
+{
138
+    foreach ($Array as $Key => $Val) {
139
+        if (!in_array($Key, $DontEscape)) {
140
+            if ($Quote) {
141
+                $Array[$Key] = '\''.db_string(trim($Val)).'\'';
142
+            } else {
143
+                $Array[$Key] = db_string(trim($Val));
144
+            }
145
+        }
141
     }
146
     }
142
-  }
143
-  return $Array;
147
+    return $Array;
144
 }
148
 }
145
 
149
 
146
 // todo: Revisit access levels once Drone is replaced by ZeRobot
150
 // todo: Revisit access levels once Drone is replaced by ZeRobot
147
-class DB_MYSQL {
148
-  public $LinkID = false;
149
-  protected $QueryID = false;
150
-  protected $StatementID = false;
151
-  protected $PreparedQuery = false;
152
-  protected $Record = [];
153
-  protected $Row;
154
-  protected $Errno = 0;
155
-  protected $Error = '';
156
-
157
-  public $Queries = [];
158
-  public $Time = 0.0;
159
-
160
-  protected $Database = '';
161
-  protected $Server = '';
162
-  protected $User = '';
163
-  protected $Pass = '';
164
-  protected $Port = 0;
165
-  protected $Socket = '';
166
-
167
-  function __construct($Database = SQLDB, $User = SQLLOGIN, $Pass = SQLPASS, $Server = SQLHOST, $Port = SQLPORT, $Socket = SQLSOCK) {
168
-    $this->Database = $Database;
169
-    $this->Server = $Server;
170
-    $this->User = $User;
171
-    $this->Pass = $Pass;
172
-    $this->Port = $Port;
173
-    $this->Socket = $Socket;
174
-  }
175
-
176
-  function halt($Msg) {
177
-    global $Debug, $argv;
178
-    $DBError = 'MySQL: '.strval($Msg).' SQL error: '.strval($this->Errno).' ('.strval($this->Error).')';
179
-    if ($this->Errno == 1194) {
180
-      send_irc('PRIVMSG '.ADMIN_CHAN.' :'.$this->Error);
151
+class DB_MYSQL
152
+{
153
+    public $LinkID = false;
154
+    protected $QueryID = false;
155
+    protected $StatementID = false;
156
+    protected $PreparedQuery = false;
157
+    protected $Record = [];
158
+    protected $Row;
159
+    protected $Errno = 0;
160
+    protected $Error = '';
161
+
162
+    public $Queries = [];
163
+    public $Time = 0.0;
164
+
165
+    protected $Database = '';
166
+    protected $Server = '';
167
+    protected $User = '';
168
+    protected $Pass = '';
169
+    protected $Port = 0;
170
+    protected $Socket = '';
171
+
172
+    public function __construct($Database = SQLDB, $User = SQLLOGIN, $Pass = SQLPASS, $Server = SQLHOST, $Port = SQLPORT, $Socket = SQLSOCK)
173
+    {
174
+        $this->Database = $Database;
175
+        $this->Server = $Server;
176
+        $this->User = $User;
177
+        $this->Pass = $Pass;
178
+        $this->Port = $Port;
179
+        $this->Socket = $Socket;
181
     }
180
     }
182
-    $Debug->analysis('!dev DB Error', $DBError, 3600 * 24);
183
-    if (DEBUG_MODE || check_perms('site_debug') || isset($argv[1])) {
184
-      echo '<pre>'.display_str($DBError).'</pre>';
185
-      if (DEBUG_MODE || check_perms('site_debug')) {
186
-        print_r($this->Queries);
187
-      }
188
-      die();
189
-    } else {
190
-      error('-1');
181
+
182
+    public function halt($Msg)
183
+    {
184
+        global $Debug, $argv;
185
+        $DBError = 'MySQL: '.strval($Msg).' SQL error: '.strval($this->Errno).' ('.strval($this->Error).')';
186
+
187
+        if ($this->Errno == 1194) {
188
+            send_irc('PRIVMSG '.ADMIN_CHAN.' :'.$this->Error);
189
+        }
190
+
191
+        $Debug->analysis('!dev DB Error', $DBError, 3600 * 24);
192
+        if (DEBUG_MODE || check_perms('site_debug') || isset($argv[1])) {
193
+            echo '<pre>'.display_str($DBError).'</pre>';
194
+            if (DEBUG_MODE || check_perms('site_debug')) {
195
+                print_r($this->Queries);
196
+            }
197
+            die();
198
+        } else {
199
+            error('-1');
200
+        }
191
     }
201
     }
192
-  }
193
-
194
-  function connect() {
195
-    if (!$this->LinkID) {
196
-      $this->LinkID = mysqli_connect($this->Server, $this->User, $this->Pass, $this->Database, $this->Port, $this->Socket); // defined in config.php
197
-      if (!$this->LinkID) {
198
-        $this->Errno = mysqli_connect_errno();
199
-        $this->Error = mysqli_connect_error();
200
-        $this->halt('Connection failed (host:'.$this->Server.':'.$this->Port.')');
201
-      }
202
+
203
+    public function connect()
204
+    {
205
+        if (!$this->LinkID) {
206
+            $this->LinkID = mysqli_connect($this->Server, $this->User, $this->Pass, $this->Database, $this->Port, $this->Socket); // defined in config.php
207
+            if (!$this->LinkID) {
208
+                $this->Errno = mysqli_connect_errno();
209
+                $this->Error = mysqli_connect_error();
210
+                $this->halt('Connection failed (host:'.$this->Server.':'.$this->Port.')');
211
+            }
212
+        }
213
+        mysqli_set_charset($this->LinkID, "utf8mb4");
202
     }
214
     }
203
-    mysqli_set_charset($this->LinkID, "utf8mb4");
204
-  }
205
-
206
-  function prepare_query($Query, &...$BindVars) {
207
-    $this->connect();
208
-
209
-    $this->StatementID = mysqli_prepare($this->LinkID, $Query);
210
-    if (!empty($BindVars)) {
211
-      $Types = '';
212
-      $TypeMap = ['string'=>'s', 'double'=>'d', 'integer'=>'i', 'boolean'=>'i'];
213
-      foreach ($BindVars as $BindVar) {
214
-        $Types .= $TypeMap[gettype($BindVar)] ?? 'b';
215
-      }
216
-      mysqli_stmt_bind_param($this->StatementID, $Types, ...$BindVars);
215
+
216
+    public function prepare_query($Query, &...$BindVars)
217
+    {
218
+        $this->connect();
219
+
220
+        $this->StatementID = mysqli_prepare($this->LinkID, $Query);
221
+        if (!empty($BindVars)) {
222
+            $Types = '';
223
+            $TypeMap = ['string'=>'s', 'double'=>'d', 'integer'=>'i', 'boolean'=>'i'];
224
+
225
+            foreach ($BindVars as $BindVar) {
226
+                $Types .= $TypeMap[gettype($BindVar)] ?? 'b';
227
+            }
228
+            mysqli_stmt_bind_param($this->StatementID, $Types, ...$BindVars);
229
+        }
230
+
231
+        $this->PreparedQuery = $Query;
232
+        return $this->StatementID;
217
     }
233
     }
218
-    $this->PreparedQuery = $Query;
219
-    return $this->StatementID;
220
-  }
221
-
222
-  function exec_prepared_query() {
223
-    $QueryStartTime = microtime(true);
224
-    mysqli_stmt_execute($this->StatementID);
225
-    $this->QueryID = mysqli_stmt_get_result($this->StatementID);
226
-    $QueryRunTime = (microtime(true) - $QueryStartTime) * 1000;
227
-    $this->Queries[] = [$this->PreppedQuery, $QueryRunTime, null];
228
-    $this->Time += $QueryRunTime;
229
-  }
230
-
231
-  function query($Query, &...$BindVars) {
232
-    global $Debug;
233
-    /*
234
-     * If there was a previous query, we store the warnings. We cannot do
235
-     * this immediately after mysqli_query because mysqli_insert_id will
236
-     * break otherwise due to mysqli_get_warnings sending a SHOW WARNINGS;
237
-     * query. When sending a query, however, we're sure that we won't call
238
-     * mysqli_insert_id (or any similar function, for that matter) later on,
239
-     * so we can safely get the warnings without breaking things.
240
-     * Note that this means that we have to call $this->warnings manually
241
-     * for the last query!
242
-     */
243
-    if ($this->QueryID) {
244
-      $this->warnings();
234
+
235
+    public function exec_prepared_query()
236
+    {
237
+        $QueryStartTime = microtime(true);
238
+        mysqli_stmt_execute($this->StatementID);
239
+        $this->QueryID = mysqli_stmt_get_result($this->StatementID);
240
+        $QueryRunTime = (microtime(true) - $QueryStartTime) * 1000;
241
+        $this->Queries[] = [$this->PreppedQuery, $QueryRunTime, null];
242
+        $this->Time += $QueryRunTime;
245
     }
243
     }
246
-    $QueryStartTime = microtime(true);
247
-    $this->connect();
248
-
249
-    // In the event of a MySQL deadlock, we sleep allowing MySQL time to unlock, then attempt again for a maximum of 5 tries
250
-    for ($i = 1; $i < 6; $i++) {
251
-      $this->StatementID = mysqli_prepare($this->LinkID, $Query);
252
-      if (!empty($BindVars)) {
253
-        $Types = '';
254
-        $TypeMap = ['string'=>'s', 'double'=>'d', 'integer'=>'i', 'boolean'=>'i'];
255
-        foreach ($BindVars as $BindVar) {
256
-          $Types .= $TypeMap[gettype($BindVar)] ?? 'b';
244
+
245
+    public function query($Query, &...$BindVars)
246
+    {
247
+        global $Debug;
248
+        /*
249
+         * If there was a previous query, we store the warnings. We cannot do
250
+         * this immediately after mysqli_query because mysqli_insert_id will
251
+         * break otherwise due to mysqli_get_warnings sending a SHOW WARNINGS;
252
+         * query. When sending a query, however, we're sure that we won't call
253
+         * mysqli_insert_id (or any similar function, for that matter) later on,
254
+         * so we can safely get the warnings without breaking things.
255
+         * Note that this means that we have to call $this->warnings manually
256
+         * for the last query!
257
+         */
258
+        if ($this->QueryID) {
259
+            $this->warnings();
257
         }
260
         }
258
-        mysqli_stmt_bind_param($this->StatementID, $Types, ...$BindVars);
259
-      }
260
-      mysqli_stmt_execute($this->StatementID);
261
-      $this->QueryID = mysqli_stmt_get_result($this->StatementID);
262
-
263
-      if (DEBUG_MODE) {
264
-        // In DEBUG_MODE, return the full trace on a SQL error (super useful
265
-        // For debugging). do not attempt to retry to query
266
-        if (!$this->QueryID) {
267
-          echo '<pre>' . mysqli_error($this->LinkID) . '<br><br>';
268
-          debug_print_backtrace();
269
-          echo '</pre>';
270
-          die();
261
+
262
+        $QueryStartTime = microtime(true);
263
+        $this->connect();
264
+
265
+        // In the event of a MySQL deadlock, we sleep allowing MySQL time to unlock, then attempt again for a maximum of 5 tries
266
+        for ($i = 1; $i < 6; $i++) {
267
+            $this->StatementID = mysqli_prepare($this->LinkID, $Query);
268
+            if (!empty($BindVars)) {
269
+                $Types = '';
270
+                $TypeMap = ['string'=>'s', 'double'=>'d', 'integer'=>'i', 'boolean'=>'i'];
271
+
272
+                foreach ($BindVars as $BindVar) {
273
+                    $Types .= $TypeMap[gettype($BindVar)] ?? 'b';
274
+                }
275
+                mysqli_stmt_bind_param($this->StatementID, $Types, ...$BindVars);
276
+            }
277
+
278
+            mysqli_stmt_execute($this->StatementID);
279
+            $this->QueryID = mysqli_stmt_get_result($this->StatementID);
280
+
281
+            if (DEBUG_MODE) {
282
+                // In DEBUG_MODE, return the full trace on a SQL error (super useful
283
+                // For debugging). do not attempt to retry to query
284
+                if (!$this->QueryID) {
285
+                    echo '<pre>' . mysqli_error($this->LinkID) . '<br><br>';
286
+                    debug_print_backtrace();
287
+                    echo '</pre>';
288
+                    die();
289
+                }
290
+            }
291
+
292
+            if (!in_array(mysqli_errno($this->LinkID), array(1213, 1205))) {
293
+                break;
294
+            }
295
+
296
+            $Debug->analysis('Non-Fatal Deadlock:', $Query, 3600 * 24);
297
+            trigger_error("Database deadlock, attempt $i");
298
+            sleep($i * rand(2, 5)); // Wait longer as attempts increase
271
         }
299
         }
272
-      }
273
 
300
 
274
-      if (!in_array(mysqli_errno($this->LinkID), array(1213, 1205))) {
275
-        break;
276
-      }
277
-      $Debug->analysis('Non-Fatal Deadlock:', $Query, 3600 * 24);
278
-      trigger_error("Database deadlock, attempt $i");
301
+        $QueryEndTime = microtime(true);
302
+        $this->Queries[] = array($Query, ($QueryEndTime - $QueryStartTime) * 1000, null);
303
+        $this->Time += ($QueryEndTime - $QueryStartTime) * 1000;
279
 
304
 
280
-      sleep($i * rand(2, 5)); // Wait longer as attempts increase
305
+        if (!$this->QueryID && !$this->StatementID) {
306
+            $this->Errno = mysqli_errno($this->LinkID);
307
+            $this->Error = mysqli_error($this->LinkID);
308
+            $this->halt("Invalid Query: $Query");
309
+        }
310
+
311
+        $this->Row = 0;
312
+        return $this->QueryID;
281
     }
313
     }
282
 
314
 
283
-    $QueryEndTime = microtime(true);
284
-    $this->Queries[] = array($Query, ($QueryEndTime - $QueryStartTime) * 1000, null);
285
-    $this->Time += ($QueryEndTime - $QueryStartTime) * 1000;
315
+    public function query_unb($Query)
316
+    {
317
+        $this->connect();
318
+        mysqli_real_query($this->LinkID, $Query);
319
+    }
286
 
320
 
287
-    if (!$this->QueryID && !$this->StatementID) {
288
-      $this->Errno = mysqli_errno($this->LinkID);
289
-      $this->Error = mysqli_error($this->LinkID);
290
-      $this->halt("Invalid Query: $Query");
321
+    public function inserted_id()
322
+    {
323
+        if ($this->LinkID) {
324
+            return mysqli_insert_id($this->LinkID);
325
+        }
291
     }
326
     }
292
 
327
 
293
-    $this->Row = 0;
294
-    return $this->QueryID;
295
-  }
328
+    public function next_record($Type = MYSQLI_BOTH, $Escape = true)
329
+    { // $Escape can be true, false, or an array of keys to not escape
330
+        if ($this->LinkID) {
331
+            $this->Record = mysqli_fetch_array($this->QueryID, $Type);
332
+            $this->Row++;
333
+
334
+            if (!is_array($this->Record)) {
335
+                $this->QueryID = false;
336
+            } elseif ($Escape !== false) {
337
+                $this->Record = Misc::display_array($this->Record, $Escape);
338
+            }
339
+            return $this->Record;
340
+        }
341
+    }
296
 
342
 
297
-  function query_unb($Query) {
298
-    $this->connect();
299
-    mysqli_real_query($this->LinkID, $Query);
300
-  }
343
+    public function close()
344
+    {
345
+        if ($this->LinkID) {
346
+            if (!mysqli_close($this->LinkID)) {
347
+                $this->halt('Cannot close connection or connection did not open.');
348
+            }
349
+            $this->LinkID = false;
350
+        }
351
+    }
301
 
352
 
302
-  function inserted_id() {
303
-    if ($this->LinkID) {
304
-      return mysqli_insert_id($this->LinkID);
353
+    /*
354
+     * Returns an integer with the number of rows found
355
+     * Returns a string if the number of rows found exceeds MAXINT
356
+     */
357
+    public function record_count()
358
+    {
359
+        if ($this->QueryID) {
360
+            return mysqli_num_rows($this->QueryID);
361
+        }
305
     }
362
     }
306
-  }
307
-
308
-  function next_record($Type = MYSQLI_BOTH, $Escape = true) { // $Escape can be true, false, or an array of keys to not escape
309
-    if ($this->LinkID) {
310
-      $this->Record = mysqli_fetch_array($this->QueryID, $Type);
311
-      $this->Row++;
312
-      if (!is_array($this->Record)) {
313
-        $this->QueryID = false;
314
-      } elseif ($Escape !== false) {
315
-        $this->Record = Misc::display_array($this->Record, $Escape);
316
-      }
317
-      return $this->Record;
363
+
364
+    /*
365
+     * Returns true if the query exists and there were records found
366
+     * Returns false if the query does not exist or if there were 0 records returned
367
+     */
368
+    public function has_results()
369
+    {
370
+        return ($this->QueryID && $this->record_count() !== 0);
318
     }
371
     }
319
-  }
320
-
321
-  function close() {
322
-    if ($this->LinkID) {
323
-      if (!mysqli_close($this->LinkID)) {
324
-        $this->halt('Cannot close connection or connection did not open.');
325
-      }
326
-      $this->LinkID = false;
372
+
373
+    public function affected_rows()
374
+    {
375
+        if ($this->LinkID) {
376
+            return mysqli_affected_rows($this->LinkID);
377
+        }
327
     }
378
     }
328
-  }
329
-
330
-  /*
331
-   * Returns an integer with the number of rows found
332
-   * Returns a string if the number of rows found exceeds MAXINT
333
-   */
334
-  function record_count() {
335
-    if ($this->QueryID) {
336
-      return mysqli_num_rows($this->QueryID);
379
+
380
+    public function info()
381
+    {
382
+        return mysqli_get_host_info($this->LinkID);
337
     }
383
     }
338
-  }
339
-
340
-  /*
341
-   * Returns true if the query exists and there were records found
342
-   * Returns false if the query does not exist or if there were 0 records returned
343
-   */
344
-  function has_results() {
345
-    return ($this->QueryID && $this->record_count() !== 0);
346
-  }
347
-
348
-  function affected_rows() {
349
-    if ($this->LinkID) {
350
-      return mysqli_affected_rows($this->LinkID);
384
+
385
+    // You should use db_string() instead
386
+    public function escape_str($Str)
387
+    {
388
+        $this->connect(0);
389
+        if (is_array($Str)) {
390
+            trigger_error('Attempted to escape array.');
391
+            return '';
392
+        }
393
+        return mysqli_real_escape_string($this->LinkID, $Str);
351
     }
394
     }
352
-  }
353
-
354
-  function info() {
355
-    return mysqli_get_host_info($this->LinkID);
356
-  }
357
-
358
-  // You should use db_string() instead
359
-  function escape_str($Str) {
360
-    $this->connect(0);
361
-    if (is_array($Str)) {
362
-      trigger_error('Attempted to escape array.');
363
-      return '';
395
+
396
+    // Creates an array from a result set
397
+    // If $Key is set, use the $Key column in the result set as the array key
398
+    // Otherwise, use an integer
399
+    public function to_array($Key = false, $Type = MYSQLI_BOTH, $Escape = true)
400
+    {
401
+        $Return = [];
402
+        while ($Row = mysqli_fetch_array($this->QueryID, $Type)) {
403
+            if ($Escape !== false) {
404
+                $Row = Misc::display_array($Row, $Escape);
405
+            }
406
+
407
+            if ($Key !== false) {
408
+                $Return[$Row[$Key]] = $Row;
409
+            } else {
410
+                $Return[] = $Row;
411
+            }
412
+        }
413
+
414
+        mysqli_data_seek($this->QueryID, 0);
415
+        return $Return;
364
     }
416
     }
365
-    return mysqli_real_escape_string($this->LinkID, $Str);
366
-  }
367
-
368
-  // Creates an array from a result set
369
-  // If $Key is set, use the $Key column in the result set as the array key
370
-  // Otherwise, use an integer
371
-  function to_array($Key = false, $Type = MYSQLI_BOTH, $Escape = true) {
372
-    $Return = [];
373
-    while ($Row = mysqli_fetch_array($this->QueryID, $Type)) {
374
-      if ($Escape !== false) {
375
-        $Row = Misc::display_array($Row, $Escape);
376
-      }
377
-      if ($Key !== false) {
378
-        $Return[$Row[$Key]] = $Row;
379
-      } else {
380
-        $Return[] = $Row;
381
-      }
417
+
418
+    //  Loops through the result set, collecting the $ValField column into an array with $KeyField as keys
419
+    public function to_pair($KeyField, $ValField, $Escape = true)
420
+    {
421
+        $Return = [];
422
+        while ($Row = mysqli_fetch_array($this->QueryID)) {
423
+            if ($Escape) {
424
+                $Key = display_str($Row[$KeyField]);
425
+                $Val = display_str($Row[$ValField]);
426
+            } else {
427
+                $Key = $Row[$KeyField];
428
+                $Val = $Row[$ValField];
429
+            }
430
+            $Return[$Key] = $Val;
431
+        }
432
+
433
+        mysqli_data_seek($this->QueryID, 0);
434
+        return $Return;
382
     }
435
     }
383
-    mysqli_data_seek($this->QueryID, 0);
384
-    return $Return;
385
-  }
386
-
387
-  //  Loops through the result set, collecting the $ValField column into an array with $KeyField as keys
388
-  function to_pair($KeyField, $ValField, $Escape = true) {
389
-    $Return = [];
390
-    while ($Row = mysqli_fetch_array($this->QueryID)) {
391
-      if ($Escape) {
392
-        $Key = display_str($Row[$KeyField]);
393
-        $Val = display_str($Row[$ValField]);
394
-      } else {
395
-        $Key = $Row[$KeyField];
396
-        $Val = $Row[$ValField];
397
-      }
398
-      $Return[$Key] = $Val;
436
+
437
+    //  Loops through the result set, collecting the $Key column into an array
438
+    public function collect($Key, $Escape = true)
439
+    {
440
+        $Return = [];
441
+        while ($Row = mysqli_fetch_array($this->QueryID)) {
442
+            $Return[] = $Escape ? display_str($Row[$Key]) : $Row[$Key];
443
+        }
444
+        
445
+        mysqli_data_seek($this->QueryID, 0);
446
+        return $Return;
399
     }
447
     }
400
-    mysqli_data_seek($this->QueryID, 0);
401
-    return $Return;
402
-  }
403
-
404
-  //  Loops through the result set, collecting the $Key column into an array
405
-  function collect($Key, $Escape = true) {
406
-    $Return = [];
407
-    while ($Row = mysqli_fetch_array($this->QueryID)) {
408
-      $Return[] = $Escape ? display_str($Row[$Key]) : $Row[$Key];
448
+
449
+    public function set_query_id(&$ResultSet)
450
+    {
451
+        $this->QueryID = $ResultSet;
452
+        $this->Row = 0;
409
     }
453
     }
410
-    mysqli_data_seek($this->QueryID, 0);
411
-    return $Return;
412
-  }
413
-
414
-  function set_query_id(&$ResultSet) {
415
-    $this->QueryID = $ResultSet;
416
-    $this->Row = 0;
417
-  }
418
-
419
-  function get_query_id() {
420
-    return $this->QueryID;
421
-  }
422
-
423
-  function beginning() {
424
-    mysqli_data_seek($this->QueryID, 0);
425
-    $this->Row = 0;
426
-  }
427
-
428
-  /**
429
-   * This function determines whether the last query caused warning messages
430
-   * and stores them in $this->Queries
431
-   */
432
-  function warnings() {
433
-    $Warnings = [];
434
-    if (!is_bool($this->LinkID) && mysqli_warning_count($this->LinkID)) {
435
-      $e = mysqli_get_warnings($this->LinkID);
436
-      do {
437
-        if ($e->errno == 1592) {
438
-          // 1592: Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT
439
-          continue;
454
+
455
+    public function get_query_id()
456
+    {
457
+        return $this->QueryID;
458
+    }
459
+
460
+    public function beginning()
461
+    {
462
+        mysqli_data_seek($this->QueryID, 0);
463
+        $this->Row = 0;
464
+    }
465
+
466
+    /**
467
+     * This function determines whether the last query caused warning messages
468
+     * and stores them in $this->Queries
469
+     */
470
+    public function warnings()
471
+    {
472
+        $Warnings = [];
473
+        if (!is_bool($this->LinkID) && mysqli_warning_count($this->LinkID)) {
474
+            $e = mysqli_get_warnings($this->LinkID);
475
+            do {
476
+                if ($e->errno == 1592) {
477
+                    // 1592: Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT
478
+                    continue;
479
+                }
480
+                $Warnings[] = 'Code ' . $e->errno . ': ' . display_str($e->message);
481
+            } while ($e->next());
440
         }
482
         }
441
-        $Warnings[] = 'Code ' . $e->errno . ': ' . display_str($e->message);
442
-      } while ($e->next());
483
+        $this->Queries[count($this->Queries) - 1][2] = $Warnings;
443
     }
484
     }
444
-    $this->Queries[count($this->Queries) - 1][2] = $Warnings;
445
-  }
446
 }
485
 }
447
-?>

+ 109
- 112
classes/permissions_form.php View File

1
-<?
1
+<?php
2
 
2
 
3
 /********************************************************************************
3
 /********************************************************************************
4
  ************ Permissions form ********************** user.php and tools.php ****
4
  ************ Permissions form ********************** user.php and tools.php ****
112
   'site_tag_aliases_read' => 'Can view the list of tag aliases.'
112
   'site_tag_aliases_read' => 'Can view the list of tag aliases.'
113
 );
113
 );
114
 
114
 
115
-function permissions_form() {
116
-?>
115
+function permissions_form()
116
+{
117
+    ?>
117
 <div class="permissions">
118
 <div class="permissions">
118
   <div class="permission_container">
119
   <div class="permission_container">
119
     <table>
120
     <table>
122
       </tr>
123
       </tr>
123
       <tr>
124
       <tr>
124
         <td>
125
         <td>
125
-<?
126
-          display_perm('site_leech','Can leech.');
127
-          display_perm('site_upload','Can upload.');
128
-          display_perm('site_vote','Can vote on requests.');
129
-          display_perm('site_submit_requests','Can submit requests.');
130
-          display_perm('site_advanced_search','Can use advanced search.');
131
-          display_perm('site_top10','Can access top 10.');
132
-          display_perm('site_torrents_notify','Can access torrents notifications system.');
133
-          display_perm('site_collages_create','Can create collages.');
134
-          display_perm('site_collages_manage','Can manage collages (add torrents, sorting).');
135
-          display_perm('site_collages_delete','Can delete collages.');
136
-          display_perm('site_collages_subscribe','Can access collage subscriptions.');
137
-          display_perm('site_collages_personal','Can have a personal collage.');
138
-          display_perm('site_collages_renamepersonal','Can rename own personal collages.');
139
-          display_perm('site_advanced_top10','Can access advanced top 10.');
140
-          display_perm('site_make_bookmarks','Can make bookmarks.');
141
-          display_perm('site_edit_wiki','Can edit wiki pages.');
142
-          display_perm('site_can_invite_always', 'Can invite users even when invites are closed.');
143
-          display_perm('site_send_unlimited_invites', 'Can send unlimited invites.');
144
-          display_perm('site_moderate_requests', 'Can moderate any request.');
145
-          display_perm('site_delete_artist', 'Can delete artists (must be able to delete torrents+requests).');
146
-          display_perm('forums_polls_create','Can create polls in the forums.');
147
-          display_perm('forums_polls_moderate','Can feature and close polls.');
148
-          display_perm('site_moderate_forums', 'Can moderate the forums.');
149
-          display_perm('site_admin_forums', 'Can administrate the forums.');
150
-          display_perm('site_view_flow', 'Can view site stats and data pools.');
151
-          display_perm('site_view_full_log', 'Can view the full site log.');
152
-          display_perm('site_view_torrent_snatchlist', 'Can view torrent snatch lists.');
153
-          display_perm('site_recommend_own', 'Can add own torrents to recommendations list.');
154
-          display_perm('site_manage_recommendations', 'Can edit recommendations list.');
155
-          display_perm('site_delete_tag', 'Can delete tags.');
156
-          display_perm('site_disable_ip_history', 'Disable IP history.');
157
-          display_perm('zip_downloader', 'Download multiple torrents at once.');
158
-          display_perm('site_debug', 'View site debug tables.');
159
-          display_perm('site_proxy_images', 'Proxy images through the server.');
160
-          display_perm('site_search_many', 'Can go past low limit of search results.');
161
-          display_perm('site_collages_recover', 'Can recover \'deleted\' collages.');
162
-          display_perm('site_forums_double_post', 'Can double post in the forums.');
163
-          display_perm('project_team', 'Part of the project team.');
164
-          display_perm('site_tag_aliases_read', 'Can view the list of tag aliases.');
165
-          display_perm('site_ratio_watch_immunity', 'Immune from being put on ratio watch.');
166
-?>
126
+          <?php
127
+          display_perm('site_leech', 'Can leech.');
128
+    display_perm('site_upload', 'Can upload.');
129
+    display_perm('site_vote', 'Can vote on requests.');
130
+    display_perm('site_submit_requests', 'Can submit requests.');
131
+    display_perm('site_advanced_search', 'Can use advanced search.');
132
+    display_perm('site_top10', 'Can access top 10.');
133
+    display_perm('site_torrents_notify', 'Can access torrents notifications system.');
134
+    display_perm('site_collages_create', 'Can create collages.');
135
+    display_perm('site_collages_manage', 'Can manage collages (add torrents, sorting).');
136
+    display_perm('site_collages_delete', 'Can delete collages.');
137
+    display_perm('site_collages_subscribe', 'Can access collage subscriptions.');
138
+    display_perm('site_collages_personal', 'Can have a personal collage.');
139
+    display_perm('site_collages_renamepersonal', 'Can rename own personal collages.');
140
+    display_perm('site_advanced_top10', 'Can access advanced top 10.');
141
+    display_perm('site_make_bookmarks', 'Can make bookmarks.');
142
+    display_perm('site_edit_wiki', 'Can edit wiki pages.');
143
+    display_perm('site_can_invite_always', 'Can invite users even when invites are closed.');
144
+    display_perm('site_send_unlimited_invites', 'Can send unlimited invites.');
145
+    display_perm('site_moderate_requests', 'Can moderate any request.');
146
+    display_perm('site_delete_artist', 'Can delete artists (must be able to delete torrents+requests).');
147
+    display_perm('forums_polls_create', 'Can create polls in the forums.');
148
+    display_perm('forums_polls_moderate', 'Can feature and close polls.');
149
+    display_perm('site_moderate_forums', 'Can moderate the forums.');
150
+    display_perm('site_admin_forums', 'Can administrate the forums.');
151
+    display_perm('site_view_flow', 'Can view site stats and data pools.');
152
+    display_perm('site_view_full_log', 'Can view the full site log.');
153
+    display_perm('site_view_torrent_snatchlist', 'Can view torrent snatch lists.');
154
+    display_perm('site_recommend_own', 'Can add own torrents to recommendations list.');
155
+    display_perm('site_manage_recommendations', 'Can edit recommendations list.');
156
+    display_perm('site_delete_tag', 'Can delete tags.');
157
+    display_perm('site_disable_ip_history', 'Disable IP history.');
158
+    display_perm('zip_downloader', 'Download multiple torrents at once.');
159
+    display_perm('site_debug', 'View site debug tables.');
160
+    display_perm('site_proxy_images', 'Proxy images through the server.');
161
+    display_perm('site_search_many', 'Can go past low limit of search results.');
162
+    display_perm('site_collages_recover', 'Can recover \'deleted\' collages.');
163
+    display_perm('site_forums_double_post', 'Can double post in the forums.');
164
+    display_perm('project_team', 'Part of the project team.');
165
+    display_perm('site_tag_aliases_read', 'Can view the list of tag aliases.');
166
+    display_perm('site_ratio_watch_immunity', 'Immune from being put on ratio watch.'); ?>
167
         </td>
167
         </td>
168
       </tr>
168
       </tr>
169
     </table>
169
     </table>
175
       </tr>
175
       </tr>
176
       <tr>
176
       <tr>
177
         <td>
177
         <td>
178
-<?
178
+          <?php
179
           display_perm('users_edit_usernames', 'Can edit usernames.');
179
           display_perm('users_edit_usernames', 'Can edit usernames.');
180
-          display_perm('users_edit_ratio', 'Can edit anyone\'s upload/download amounts.');
181
-          display_perm('users_edit_own_ratio', 'Can edit own upload/download amounts.');
182
-          display_perm('users_edit_titles', 'Can edit titles.');
183
-          display_perm('users_edit_avatars', 'Can edit avatars.');
184
-          display_perm('users_edit_invites', 'Can edit invite numbers and cancel sent invites.');
185
-          display_perm('users_edit_watch_hours', 'Can edit contrib watch hours.');
186
-          display_perm('users_edit_reset_keys', 'Can reset any passkey/authkey.');
187
-          display_perm('users_edit_profiles', 'Can edit anyone\'s profile.');
188
-          display_perm('users_edit_badges', 'Can edit anyone\'s badges.');
189
-          display_perm('users_view_friends', 'Can view anyone\'s friends.');
190
-          display_perm('users_reset_own_keys', 'Can reset own passkey/authkey.');
191
-          display_perm('users_edit_password', 'Can change password.');
192
-          display_perm('users_promote_below', 'Can promote users to below current level.');
193
-          display_perm('users_promote_to', 'Can promote users up to current level.');
194
-          display_perm('users_give_donor', 'Can give donor access.');
195
-          display_perm('users_warn', 'Can warn users.');
196
-          display_perm('users_disable_users', 'Can disable users.');
197
-          display_perm('users_disable_posts', 'Can disable users\' posting privileges.');
198
-          display_perm('users_disable_any', 'Can disable any users\' rights.');
199
-          display_perm('users_delete_users', 'Can delete anyone\'s account');
200
-          display_perm('users_view_invites', 'Can view who user has invited');
201
-          display_perm('users_view_seedleech', 'Can view what a user is seeding or leeching');
202
-          display_perm('users_view_uploaded', 'Can view a user\'s uploads, regardless of privacy level');
203
-          display_perm('users_view_keys', 'Can view passkeys');
204
-          display_perm('users_view_ips', 'Can view IP addresses');
205
-          display_perm('users_view_email', 'Can view email addresses');
206
-          display_perm('users_invite_notes', 'Can add a staff note when inviting someone.');
207
-          display_perm('users_override_paranoia', 'Can override paranoia');
208
-          display_perm('users_make_invisible', 'Can make users invisible');
209
-          display_perm('users_logout', 'Can log users out');
210
-          display_perm('users_mod', 'Can access basic moderator tools (Admin comment)');
211
-?>
180
+    display_perm('users_edit_ratio', 'Can edit anyone\'s upload/download amounts.');
181
+    display_perm('users_edit_own_ratio', 'Can edit own upload/download amounts.');
182
+    display_perm('users_edit_titles', 'Can edit titles.');
183
+    display_perm('users_edit_avatars', 'Can edit avatars.');
184
+    display_perm('users_edit_invites', 'Can edit invite numbers and cancel sent invites.');
185
+    display_perm('users_edit_watch_hours', 'Can edit contrib watch hours.');
186
+    display_perm('users_edit_reset_keys', 'Can reset any passkey/authkey.');
187
+    display_perm('users_edit_profiles', 'Can edit anyone\'s profile.');
188
+    display_perm('users_edit_badges', 'Can edit anyone\'s badges.');
189
+    display_perm('users_view_friends', 'Can view anyone\'s friends.');
190
+    display_perm('users_reset_own_keys', 'Can reset own passkey/authkey.');
191
+    display_perm('users_edit_password', 'Can change password.');
192
+    display_perm('users_promote_below', 'Can promote users to below current level.');
193
+    display_perm('users_promote_to', 'Can promote users up to current level.');
194
+    display_perm('users_give_donor', 'Can give donor access.');
195
+    display_perm('users_warn', 'Can warn users.');
196
+    display_perm('users_disable_users', 'Can disable users.');
197
+    display_perm('users_disable_posts', 'Can disable users\' posting privileges.');
198
+    display_perm('users_disable_any', 'Can disable any users\' rights.');
199
+    display_perm('users_delete_users', 'Can delete anyone\'s account');
200
+    display_perm('users_view_invites', 'Can view who user has invited');
201
+    display_perm('users_view_seedleech', 'Can view what a user is seeding or leeching');
202
+    display_perm('users_view_uploaded', 'Can view a user\'s uploads, regardless of privacy level');
203
+    display_perm('users_view_keys', 'Can view passkeys');
204
+    display_perm('users_view_ips', 'Can view IP addresses');
205
+    display_perm('users_view_email', 'Can view email addresses');
206
+    display_perm('users_invite_notes', 'Can add a staff note when inviting someone.');
207
+    display_perm('users_override_paranoia', 'Can override paranoia');
208
+    display_perm('users_make_invisible', 'Can make users invisible');
209
+    display_perm('users_logout', 'Can log users out');
210
+    display_perm('users_mod', 'Can access basic moderator tools (Admin comment)'); ?>
212
           *Everything is only applicable to users with the same or lower class level
211
           *Everything is only applicable to users with the same or lower class level
213
         </td>
212
         </td>
214
       </tr>
213
       </tr>
221
       </tr>
220
       </tr>
222
       <tr>
221
       <tr>
223
         <td>
222
         <td>
224
-<?
223
+          <?php
225
           display_perm('torrents_edit', 'Can edit any torrent');
224
           display_perm('torrents_edit', 'Can edit any torrent');
226
-          display_perm('torrents_delete', 'Can delete torrents');
227
-          display_perm('torrents_delete_fast', 'Can delete more than 3 torrents at a time.');
228
-          display_perm('torrents_freeleech', 'Can make torrents freeleech');
229
-          display_perm('torrents_search_fast', 'Unlimit search frequency (for scripts).');
230
-          display_perm('torrents_add_artist', 'Can add artists to any group.');
231
-          display_perm('edit_unknowns', 'Can edit unknown release information.');
232
-          display_perm('torrents_edit_vanityhouse', 'Can mark groups as part of Vanity House.');
233
-          display_perm('artist_edit_vanityhouse', 'Can mark artists as part of Vanity House.');
234
-          display_perm('torrents_hide_dnu', 'Hide the Do Not Upload list by default.');
235
-          display_perm('torrents_fix_ghosts', 'Can fix ghost groups on artist pages.');
236
-          display_perm('screenshots_add', 'Can add screenshots to any torrent and delete their own screenshots.');
237
-          display_perm('screenshots_delete', 'Can delete any screenshot from any torrent.');
238
-?>
225
+    display_perm('torrents_delete', 'Can delete torrents');
226
+    display_perm('torrents_delete_fast', 'Can delete more than 3 torrents at a time.');
227
+    display_perm('torrents_freeleech', 'Can make torrents freeleech');
228
+    display_perm('torrents_search_fast', 'Unlimit search frequency (for scripts).');
229
+    display_perm('torrents_add_artist', 'Can add artists to any group.');
230
+    display_perm('edit_unknowns', 'Can edit unknown release information.');
231
+    display_perm('torrents_edit_vanityhouse', 'Can mark groups as part of Vanity House.');
232
+    display_perm('artist_edit_vanityhouse', 'Can mark artists as part of Vanity House.');
233
+    display_perm('torrents_hide_dnu', 'Hide the Do Not Upload list by default.');
234
+    display_perm('torrents_fix_ghosts', 'Can fix ghost groups on artist pages.');
235
+    display_perm('screenshots_add', 'Can add screenshots to any torrent and delete their own screenshots.');
236
+    display_perm('screenshots_delete', 'Can delete any screenshot from any torrent.'); ?>
239
         </td>
237
         </td>
240
       </tr>
238
       </tr>
241
     </table>
239
     </table>
247
       </tr>
245
       </tr>
248
       <tr>
246
       <tr>
249
         <td>
247
         <td>
250
-<?
248
+          <?php
251
           display_perm('admin_manage_news', 'Can manage site news');
249
           display_perm('admin_manage_news', 'Can manage site news');
252
-          display_perm('admin_manage_blog', 'Can manage the site blog');
253
-          display_perm('admin_manage_polls', 'Can manage polls');
254
-          display_perm('admin_manage_forums', 'Can manage forums (add/edit/delete)');
255
-          display_perm('admin_manage_fls', 'Can manage FLS');
256
-          display_perm('admin_reports', 'Can access reports system');
257
-          display_perm('admin_advanced_user_search', 'Can access advanced user search');
258
-          display_perm('admin_create_users', 'Can create users through an administrative form');
259
-          display_perm('admin_donor_log', 'Can view the donor log');
260
-          display_perm('admin_manage_ipbans', 'Can manage IP bans');
261
-          display_perm('admin_dnu', 'Can manage do not upload list');
262
-          display_perm('admin_clear_cache', 'Can clear cached pages');
263
-          display_perm('admin_whitelist', 'Can manage the list of allowed clients.');
264
-          display_perm('admin_manage_permissions', 'Can edit permission classes/user permissions.');
265
-          display_perm('admin_schedule', 'Can run the site schedule.');
266
-          display_perm('admin_login_watch', 'Can manage login watch.');
267
-          display_perm('admin_manage_wiki', 'Can manage wiki access.');
268
-          display_perm('admin_update_geoip', 'Can update geoIP data.');
269
-?>
250
+    display_perm('admin_manage_blog', 'Can manage the site blog');
251
+    display_perm('admin_manage_polls', 'Can manage polls');
252
+    display_perm('admin_manage_forums', 'Can manage forums (add/edit/delete)');
253
+    display_perm('admin_manage_fls', 'Can manage FLS');
254
+    display_perm('admin_reports', 'Can access reports system');
255
+    display_perm('admin_advanced_user_search', 'Can access advanced user search');
256
+    display_perm('admin_create_users', 'Can create users through an administrative form');
257
+    display_perm('admin_donor_log', 'Can view the donor log');
258
+    display_perm('admin_manage_ipbans', 'Can manage IP bans');
259
+    display_perm('admin_dnu', 'Can manage do not upload list');
260
+    display_perm('admin_clear_cache', 'Can clear cached pages');
261
+    display_perm('admin_whitelist', 'Can manage the list of allowed clients.');
262
+    display_perm('admin_manage_permissions', 'Can edit permission classes/user permissions.');
263
+    display_perm('admin_schedule', 'Can run the site schedule.');
264
+    display_perm('admin_login_watch', 'Can manage login watch.');
265
+    display_perm('admin_manage_wiki', 'Can manage wiki access.');
266
+    display_perm('admin_update_geoip', 'Can update geoIP data.'); ?>
270
         </td>
267
         </td>
271
       </tr>
268
       </tr>
272
     </table>
269
     </table>
273
   </div>
270
   </div>
274
   <div class="submit_container"><input type="submit" name="submit" value="Save Permission Class" /></div>
271
   <div class="submit_container"><input type="submit" name="submit" value="Save Permission Class" /></div>
275
 </div>
272
 </div>
276
-<?
273
+<?php
277
 }
274
 }

+ 269
- 234
classes/sitehistory.class.php View File

1
-<?
2
-
3
-class SiteHistory {
4
-  private static $Categories = array(1 => "Code", "Event", "Milestone", "Policy", "Release", "Staff Change");
5
-  private static $SubCategories = array(1 => "Announcement", "Blog Post", "Change Log", "Forum Post", "Wiki", "Other", "External Source");
6
-  private static $Tags = array(
7
-                "api",
8
-                "celebration",
9
-                "class.primary",
10
-                "class.secondary",
11
-                "collage",
12
-                "community",
13
-                "conclusion",
14
-                "contest",
15
-                "design",
16
-                "donate",
17
-                "editing",
18
-                "editorial",
19
-                "feature",
20
-                "featured.article",
21
-                "featured.album",
22
-                "featured.product",
23
-                "finances",
24
-                "format",
25
-                "forum",
26
-                "freeleech",
27
-                "freeleech.tokens",
28
-                "gazelle",
29
-                "hierarchy",
30
-                "inbox",
31
-                "infrastructure",
32
-                "interview",
33
-                "irc",
34
-                "log",
35
-                "neutral.leech",
36
-                "notifications",
37
-                "ocelot",
38
-                "paranoia",
39
-                "picks.guest",
40
-                "picks.staff",
41
-                "promotion",
42
-                "ratio",
43
-                "record",
44
-                "report",
45
-                "request",
46
-                "requirement",
47
-                "retirement",
48
-                "rippy",
49
-                "search",
50
-                "settings",
51
-                "start",
52
-                "stats",
53
-                "store",
54
-                "stylesheet",
55
-                "tagging",
56
-                "transcode",
57
-                "toolbox",
58
-                "top.10",
59
-                "torrent",
60
-                "torrent.group",
61
-                "upload",
62
-                "vanity.house",
63
-                "voting",
64
-                "whitelist",
65
-                "wiki");
66
-
67
-  public static function get_months() {
68
-    $Results = G::$Cache->get_value("site_history_months");
69
-    if (!$Results) {
70
-      $QueryID = G::$DB->get_query_id();
71
-      G::$DB->query("
72
-          SELECT DISTINCT
73
-            YEAR(DATE) AS Year, MONTH(Date) AS Month, MONTHNAME(Date) AS MonthName
74
-          FROM site_history
75
-          ORDER BY Date DESC");
76
-      $Results = G::$DB->to_array();
77
-      G::$DB->set_query_id($QueryID);
78
-      G::$Cache->cache_value("site_history_months", $Results, 0);
79
-    }
80
-    return $Results;
81
-  }
82
-
83
-  public static function get_event($ID) {
84
-    if (!empty($ID)) {
85
-      $QueryID = G::$DB->get_query_id();
86
-      G::$DB->query("
87
-          SELECT
88
-            ID, Title, Url, Category, SubCategory, Tags, Body, AddedBy, Date
89
-          FROM site_history
90
-          WHERE ID = '$ID'
91
-          ORDER BY Date DESC");
92
-      $Event = G::$DB->next_record();
93
-      G::$DB->set_query_id($QueryID);
94
-      return $Event;
95
-    }
96
-  }
97
-
98
-  public static function get_latest_events($Limit) {
99
-    self::get_events(null, null, null, null, null, null, $Limit);
100
-  }
101
-
102
-  public static function get_events($Month, $Year, $Title, $Category, $SubCategory, $Tags, $Limit) {
103
-    $Month = (int)$Month;
104
-    $Year = (int)$Year;
105
-    $Title = db_string($Title);
106
-    $Category = (int)$Category;
107
-    $SubCategory = (int)$SubCategory;
108
-    $Tags = db_string($Tags);
109
-    $Limit = (int)$Limit;
110
-    $Where = [];
111
-    if (!empty($Month)) {
112
-      $Where[] = " MONTH(Date) = '$Month' ";
113
-    }
114
-    if (!empty($Year)) {
115
-      $Where[] = " YEAR(Date) = '$Year' ";
116
-    }
117
-    if (!empty($Title)) {
118
-      $Where[] = " Title LIKE '%$Title%' ";
119
-    }
120
-    if (!empty($Category)) {
121
-      $Where[] = " Category = '$Category '";
122
-    }
123
-    if (!empty($SubCategory)) {
124
-      $Where[] = " SubCategory = '$SubCategory '";
125
-    }
126
-    if (!empty($Tags)) {
127
-      $Tags = explode(',', $Tags);
128
-      $Or = '(';
129
-      foreach ($Tags as $Tag) {
130
-        $Tag = trim($Tag);
131
-        $Or .= " Tags LIKE '%$Tag%' OR ";
132
-      }
133
-      if (strlen($Or) > 1) {
134
-        $Or = rtrim($Or, 'OR ');
135
-        $Or .= ')';
136
-        $Where[] = $Or;
137
-      }
1
+<?php
2
+
3
+class SiteHistory
4
+{
5
+    private static $Categories = array(1 => "Code", "Event", "Milestone", "Policy", "Release", "Staff Change");
6
+    private static $SubCategories = array(1 => "Announcement", "Blog Post", "Change Log", "Forum Post", "Wiki", "Other", "External Source");
7
+    private static $Tags = array(
8
+        "api",
9
+        "celebration",
10
+        "class.primary",
11
+        "class.secondary",
12
+        "collage",
13
+        "community",
14
+        "conclusion",
15
+        "contest",
16
+        "design",
17
+        "donate",
18
+        "editing",
19
+        "editorial",
20
+        "feature",
21
+        "featured.article",
22
+        "featured.album",
23
+        "featured.product",
24
+        "finances",
25
+        "format",
26
+        "forum",
27
+        "freeleech",
28
+        "freeleech.tokens",
29
+        "gazelle",
30
+        "hierarchy",
31
+        "inbox",
32
+        "infrastructure",
33
+        "interview",
34
+        "irc",
35
+        "log",
36
+        "neutral.leech",
37
+        "notifications",
38
+        "ocelot",
39
+        "paranoia",
40
+        "picks.guest",
41
+        "picks.staff",
42
+        "promotion",
43
+        "ratio",
44
+        "record",
45
+        "report",
46
+        "request",
47
+        "requirement",
48
+        "retirement",
49
+        "rippy",
50
+        "search",
51
+        "settings",
52
+        "start",
53
+        "stats",
54
+        "store",
55
+        "stylesheet",
56
+        "tagging",
57
+        "transcode",
58
+        "toolbox",
59
+        "top.10",
60
+        "torrent",
61
+        "torrent.group",
62
+        "upload",
63
+        "vanity.house",
64
+        "voting",
65
+        "whitelist",
66
+        "wiki"
67
+    );
68
+
69
+    public static function get_months()
70
+    {
71
+        $Results = G::$Cache->get_value("site_history_months");
72
+        if (!$Results) {
73
+            $QueryID = G::$DB->get_query_id();
74
+            G::$DB->query("
75
+            SELECT DISTINCT
76
+              YEAR(DATE) AS Year, MONTH(Date) AS Month, MONTHNAME(Date) AS MonthName
77
+            FROM site_history
78
+              ORDER BY Date DESC");
79
+
80
+            $Results = G::$DB->to_array();
81
+            G::$DB->set_query_id($QueryID);
82
+            G::$Cache->cache_value("site_history_months", $Results, 0);
83
+        }
84
+        return $Results;
138
     }
85
     }
139
-    if (!empty($Limit)) {
140
-      $Limit = " LIMIT $Limit";
141
-    } else {
142
-      $Limit = '';
86
+
87
+    public static function get_event($ID)
88
+    {
89
+        if (!empty($ID)) {
90
+            $QueryID = G::$DB->get_query_id();
91
+            G::$DB->query("
92
+            SELECT
93
+              ID, Title, Url, Category, SubCategory, Tags, Body, AddedBy, Date
94
+            FROM site_history
95
+              WHERE ID = '$ID'
96
+              ORDER BY Date DESC");
97
+
98
+            $Event = G::$DB->next_record();
99
+            G::$DB->set_query_id($QueryID);
100
+            return $Event;
101
+        }
143
     }
102
     }
144
-    if (count($Where) > 0) {
145
-      $Query = ' WHERE ' . implode('AND', $Where);
146
-    } else {
147
-      $Query = '';
103
+
104
+    public static function get_latest_events($Limit)
105
+    {
106
+        self::get_events(null, null, null, null, null, null, $Limit);
148
     }
107
     }
149
 
108
 
150
-    $QueryID = G::$DB->get_query_id();
151
-    G::$DB->query("
109
+    public static function get_events($Month, $Year, $Title, $Category, $SubCategory, $Tags, $Limit)
110
+    {
111
+        $Month = (int)$Month;
112
+        $Year = (int)$Year;
113
+        $Title = db_string($Title);
114
+        $Category = (int)$Category;
115
+        $SubCategory = (int)$SubCategory;
116
+        $Tags = db_string($Tags);
117
+        $Limit = (int)$Limit;
118
+        $Where = [];
119
+
120
+        if (!empty($Month)) {
121
+            $Where[] = " MONTH(Date) = '$Month' ";
122
+        }
123
+
124
+        if (!empty($Year)) {
125
+            $Where[] = " YEAR(Date) = '$Year' ";
126
+        }
127
+
128
+        if (!empty($Title)) {
129
+            $Where[] = " Title LIKE '%$Title%' ";
130
+        }
131
+
132
+        if (!empty($Category)) {
133
+            $Where[] = " Category = '$Category '";
134
+        }
135
+
136
+        if (!empty($SubCategory)) {
137
+            $Where[] = " SubCategory = '$SubCategory '";
138
+        }
139
+
140
+        if (!empty($Tags)) {
141
+            $Tags = explode(',', $Tags);
142
+            $Or = '(';
143
+
144
+            foreach ($Tags as $Tag) {
145
+                $Tag = trim($Tag);
146
+                $Or .= " Tags LIKE '%$Tag%' OR ";
147
+            }
148
+
149
+            if (strlen($Or) > 1) {
150
+                $Or = rtrim($Or, 'OR ');
151
+                $Or .= ')';
152
+                $Where[] = $Or;
153
+            }
154
+        }
155
+
156
+        if (!empty($Limit)) {
157
+            $Limit = " LIMIT $Limit";
158
+        } else {
159
+            $Limit = '';
160
+        }
161
+
162
+        if (count($Where) > 0) {
163
+            $Query = ' WHERE ' . implode('AND', $Where);
164
+        } else {
165
+            $Query = '';
166
+        }
167
+
168
+        $QueryID = G::$DB->get_query_id();
169
+        G::$DB->query("
152
         SELECT
170
         SELECT
153
           ID, Title, Url, Category, SubCategory, Tags, Body, AddedBy, Date
171
           ID, Title, Url, Category, SubCategory, Tags, Body, AddedBy, Date
154
         FROM site_history
172
         FROM site_history
155
-        $Query
156
-        ORDER BY Date DESC
157
-        $Limit");
158
-    $Events = G::$DB->to_array();
159
-    G::$DB->set_query_id($QueryID);
160
-    return $Events;
161
-  }
162
-
163
-  public static function add_event($Date, $Title, $Link, $Category, $SubCategory, $Tags, $Body, $UserID) {
164
-    if (empty($Date)) {
165
-      $Date = sqltime();
166
-    } else {
167
-      list($Y, $M, $D) = explode('-', $Date);
168
-      if (!checkdate($M, $D, $Y)) {
169
-        error("Error");
170
-      }
171
-    }
172
-    $Title = db_string($Title);
173
-    $Link = db_string($Link);
174
-    $Category = (int)$Category;
175
-    $SubCategory = (int)$SubCategory;
176
-    $Tags = db_string(strtolower((preg_replace('/\s+/', '', $Tags))));
177
-    $ExplodedTags = explode(',', $Tags);
178
-    foreach ($ExplodedTags as $Tag) {
179
-      if (!in_array($Tag, self::get_tags())) {
180
-        error("Invalid tag");
181
-      }
182
-    }
183
-    $Body = db_string($Body);
184
-    $UserID = (int)$UserID;
173
+          $Query
174
+          ORDER BY Date DESC
175
+          $Limit");
185
 
176
 
186
-    if (empty($Title) || empty($Category) || empty($SubCategory)) {
187
-      error("Error");
177
+        $Events = G::$DB->to_array();
178
+        G::$DB->set_query_id($QueryID);
179
+        return $Events;
188
     }
180
     }
189
 
181
 
190
-    $QueryID = G::$DB->get_query_id();
191
-    G::$DB->query("
182
+    public static function add_event($Date, $Title, $Link, $Category, $SubCategory, $Tags, $Body, $UserID)
183
+    {
184
+        if (empty($Date)) {
185
+            $Date = sqltime();
186
+        } else {
187
+            list($Y, $M, $D) = explode('-', $Date);
188
+            if (!checkdate($M, $D, $Y)) {
189
+                error("Error");
190
+            }
191
+        }
192
+
193
+        $Title = db_string($Title);
194
+        $Link = db_string($Link);
195
+        $Category = (int)$Category;
196
+        $SubCategory = (int)$SubCategory;
197
+        $Tags = db_string(strtolower((preg_replace('/\s+/', '', $Tags))));
198
+        $ExplodedTags = explode(',', $Tags);
199
+
200
+        foreach ($ExplodedTags as $Tag) {
201
+            if (!in_array($Tag, self::get_tags())) {
202
+                error("Invalid tag");
203
+            }
204
+        }
205
+
206
+        $Body = db_string($Body);
207
+        $UserID = (int)$UserID;
208
+
209
+        if (empty($Title) || empty($Category) || empty($SubCategory)) {
210
+            error("Error");
211
+        }
212
+
213
+        $QueryID = G::$DB->get_query_id();
214
+        G::$DB->query("
192
         INSERT INTO site_history
215
         INSERT INTO site_history
193
           (Title, Url, Category, SubCategory, Tags, Body, AddedBy, Date)
216
           (Title, Url, Category, SubCategory, Tags, Body, AddedBy, Date)
194
         VALUES
217
         VALUES
195
           ('$Title', '$Link', '$Category', '$SubCategory', '$Tags', '$Body', '$UserID', '$Date')");
218
           ('$Title', '$Link', '$Category', '$SubCategory', '$Tags', '$Body', '$UserID', '$Date')");
196
-    G::$DB->set_query_id($QueryID);
197
-    G::$Cache->delete_value("site_history_months");
198
-  }
199
-
200
-  public static function update_event($ID, $Date, $Title, $Link, $Category, $SubCategory, $Tags, $Body, $UserID) {
201
-    if (empty($Date)) {
202
-      $Date = sqltime();
203
-    } else {
204
-      $Date = db_string($Date);
205
-      list($Y, $M, $D) = explode('-', $Date);
206
-      if (!checkdate($M, $D, $Y)) {
207
-        error("Error");
208
-      }
209
-    }
210
-    $ID = (int)$ID;
211
-    $Title = db_string($Title);
212
-    $Link = db_string($Link);
213
-    $Category = (int)$Category;
214
-    $SubCategory = (int)$SubCategory;
215
-    $Tags = db_string(strtolower((preg_replace('/\s+/', '', $Tags))));
216
-    $ExplodedTags = explode(",", $Tags);
217
-    foreach ($ExplodedTags as $Tag) {
218
-      if (!in_array($Tag, self::get_tags())) {
219
-        error("Invalid tag");
220
-      }
221
-    }
222
-    $Body = db_string($Body);
223
-    $UserID = (int)$UserID;
224
 
219
 
225
-    if (empty($ID) || empty($Title) || empty($Category) || empty($SubCategory)) {
226
-      error("Error");
220
+        G::$DB->set_query_id($QueryID);
221
+        G::$Cache->delete_value("site_history_months");
227
     }
222
     }
228
 
223
 
229
-    $QueryID = G::$DB->get_query_id();
230
-    G::$DB->query("
224
+    public static function update_event($ID, $Date, $Title, $Link, $Category, $SubCategory, $Tags, $Body, $UserID)
225
+    {
226
+        if (empty($Date)) {
227
+            $Date = sqltime();
228
+        } else {
229
+            $Date = db_string($Date);
230
+            list($Y, $M, $D) = explode('-', $Date);
231
+            if (!checkdate($M, $D, $Y)) {
232
+                error("Error");
233
+            }
234
+        }
235
+
236
+        $ID = (int)$ID;
237
+        $Title = db_string($Title);
238
+        $Link = db_string($Link);
239
+        $Category = (int)$Category;
240
+        $SubCategory = (int)$SubCategory;
241
+        $Tags = db_string(strtolower((preg_replace('/\s+/', '', $Tags))));
242
+        $ExplodedTags = explode(",", $Tags);
243
+
244
+        foreach ($ExplodedTags as $Tag) {
245
+            if (!in_array($Tag, self::get_tags())) {
246
+                error("Invalid tag");
247
+            }
248
+        }
249
+
250
+        $Body = db_string($Body);
251
+        $UserID = (int)$UserID;
252
+
253
+        if (empty($ID) || empty($Title) || empty($Category) || empty($SubCategory)) {
254
+            error("Error");
255
+        }
256
+
257
+        $QueryID = G::$DB->get_query_id();
258
+        G::$DB->query("
231
         UPDATE site_history
259
         UPDATE site_history
232
         SET
260
         SET
233
           Title = '$Title',
261
           Title = '$Title',
239
           AddedBy = '$UserID',
267
           AddedBy = '$UserID',
240
           Date = '$Date'
268
           Date = '$Date'
241
         WHERE ID = '$ID'");
269
         WHERE ID = '$ID'");
242
-    G::$DB->set_query_id($QueryID);
243
-    G::$Cache->delete_value("site_history_months");
244
-  }
245
 
270
 
246
-  public static function delete_event($ID) {
247
-    if (!is_numeric($ID)) {
248
-      error(404);
271
+        G::$DB->set_query_id($QueryID);
272
+        G::$Cache->delete_value("site_history_months");
249
     }
273
     }
250
-    $QueryID = G::$DB->get_query_id();
251
-    G::$DB->query("
274
+
275
+    public static function delete_event($ID)
276
+    {
277
+        if (!is_numeric($ID)) {
278
+            error(404);
279
+        }
280
+
281
+        $QueryID = G::$DB->get_query_id();
282
+        G::$DB->query("
252
         DELETE FROM site_history
283
         DELETE FROM site_history
253
-        WHERE ID = '$ID'");
254
-    G::$DB->set_query_id($QueryID);
255
-    G::$Cache->delete_value("site_history_months");
256
-  }
284
+          WHERE ID = '$ID'");
285
+          
286
+        G::$DB->set_query_id($QueryID);
287
+        G::$Cache->delete_value("site_history_months");
288
+    }
257
 
289
 
258
-  public static function get_categories() {
259
-    return self::$Categories;
260
-  }
290
+    public static function get_categories()
291
+    {
292
+        return self::$Categories;
293
+    }
261
 
294
 
262
-  public static function get_sub_categories() {
263
-    return self::$SubCategories;
264
-  }
295
+    public static function get_sub_categories()
296
+    {
297
+        return self::$SubCategories;
298
+    }
265
 
299
 
266
-  public static function get_tags() {
267
-    return self::$Tags;
268
-  }
300
+    public static function get_tags()
301
+    {
302
+        return self::$Tags;
303
+    }
269
 }
304
 }

+ 226
- 196
classes/sitehistoryview.class.php View File

1
-<?
1
+<?php
2
 
2
 
3
-class SiteHistoryView {
4
-
5
-  public static function render_linkbox() {
6
-    if (check_perms('users_mod')
3
+class SiteHistoryView
4
+{
5
+    public static function render_linkbox()
6
+    {
7
+        if (check_perms('users_mod')
7
       ) {
8
       ) {
8
-?>
9
-  <div class="linkbox">
10
-    <a href="sitehistory.php?action=edit" class="brackets">Create new event</a>
11
-  </div>
12
-<?
9
+            ?>
10
+<div class="linkbox">
11
+  <a href="sitehistory.php?action=edit" class="brackets">Create new event</a>
12
+</div>
13
+<?php
14
+        }
13
     }
15
     }
14
-  }
15
 
16
 
16
-  public static function render_events($Events) {
17
-    $Categories = SiteHistory::get_categories();
18
-    $SubCategories = SiteHistory::get_sub_categories();
19
-    $CanEdit = check_perms('users_mod') ;
20
-    foreach ($Events as $Event) {
21
-?>
22
-      <div class="box">
23
-        <div class="head colhead_dark">
24
-          <div class="title">
25
-<?      if ($CanEdit) { ?>
26
-            <a class="brackets" href="sitehistory.php?action=edit&amp;id=<?=$Event['ID']?>">Edit</a>
27
-<?      } ?>
17
+    public static function render_events($Events)
18
+    {
19
+        $Categories = SiteHistory::get_categories();
20
+        $SubCategories = SiteHistory::get_sub_categories();
21
+        $CanEdit = check_perms('users_mod') ;
22
+        foreach ($Events as $Event) {
23
+            ?>
24
+<div class="box">
25
+  <div class="head colhead_dark">
26
+    <div class="title">
27
+      <?php if ($CanEdit) { ?>
28
+      <a class="brackets"
29
+        href="sitehistory.php?action=edit&amp;id=<?=$Event['ID']?>">Edit</a>
30
+      <?php } ?>
28
 
31
 
29
-            <?=date('F d, Y', strtotime($Event['Date']));?>
30
-              -
31
-            <a href="sitehistory.php?action=search&amp;category=<?=$Event['Category']?>" class="brackets"><?=$Categories[$Event['Category']]?></a>
32
-            <a href="sitehistory.php?action=search&amp;subcategory=<?=$Event['SubCategory']?>" class="brackets"><?=$SubCategories[$Event['SubCategory']]?></a>
32
+      <?=date('F d, Y', strtotime($Event['Date'])); ?>
33
+      -
34
+      <a href="sitehistory.php?action=search&amp;category=<?=$Event['Category']?>"
35
+        class="brackets"><?=$Categories[$Event['Category']]?></a>
36
+      <a href="sitehistory.php?action=search&amp;subcategory=<?=$Event['SubCategory']?>"
37
+        class="brackets"><?=$SubCategories[$Event['SubCategory']]?></a>
33
 
38
 
34
-<?      if (!empty($Event['Url'])) { ?>
35
-            <a href="<?=$Event['Url']?>"><?=$Event['Title']?></a>
36
-<?      } else { ?>
37
-            <?=$Event['Title']?>
38
-<?      } ?>
39
-          </div>
40
-          <div class="tags">
41
-            <? self::render_tags($Event['Tags'])?>
42
-          </div>
43
-          </div>
44
-<?      if (!empty($Event['Body'])) { ?>
45
-          <div class="body">
46
-            <?=Text::full_format($Event['Body'])?>
47
-          </div>
48
-<?      } ?>
49
-      </div>
50
-<?
39
+      <?php if (!empty($Event['Url'])) { ?>
40
+      <a href="<?=$Event['Url']?>"><?=$Event['Title']?></a>
41
+      <?php } else { ?>
42
+      <?=$Event['Title']?>
43
+      <?php } ?>
44
+    </div>
45
+    <div class="tags">
46
+      <?php self::render_tags($Event['Tags'])?>
47
+    </div>
48
+  </div>
49
+  <?php if (!empty($Event['Body'])) { ?>
50
+  <div class="body">
51
+    <?=Text::full_format($Event['Body'])?>
52
+  </div>
53
+  <?php } ?>
54
+</div>
55
+<?php
56
+        }
51
     }
57
     }
52
-  }
53
 
58
 
54
-  private static function render_tags($Tags) {
55
-    $Tags = explode(',', $Tags);
56
-    natcasesort($Tags);
57
-    $FormattedTags = '';
58
-    foreach ($Tags as $Tag) {
59
-      $FormattedTags .= "<a href=\"sitehistory.php?action=search&amp;tags=$Tag\">$Tag" . "</a>, ";
59
+    private static function render_tags($Tags)
60
+    {
61
+        $Tags = explode(',', $Tags);
62
+        natcasesort($Tags);
63
+        $FormattedTags = '';
64
+        foreach ($Tags as $Tag) {
65
+            $FormattedTags .= "<a href=\"sitehistory.php?action=search&amp;tags=$Tag\">$Tag" . "</a>, ";
66
+        }
67
+        echo rtrim($FormattedTags, ', ');
60
     }
68
     }
61
-    echo rtrim($FormattedTags, ', ');
62
-  }
63
 
69
 
64
-  public static function render_months($Months) { ?>
65
-    <div class="box">
66
-      <div class="head">Calendar</div>
67
-      <div class="pad">
68
-<?
70
+    public static function render_months($Months) { ?>
71
+<div class="box">
72
+  <div class="head">Calendar</div>
73
+  <div class="pad">
74
+    <?php
69
     $Year = "";
75
     $Year = "";
70
     foreach ($Months as $Month) {
76
     foreach ($Months as $Month) {
71
-      if ($Month['Year'] != $Year) {
72
-        $Year = $Month['Year'];
73
-        echo "<h2>$Year</h2>";
74
-      }
75
-?>
76
-        <a style="margin-left: 5px;" href="sitehistory.php?month=<?=$Month['Month']?>&amp;year=<?=$Month['Year']?>"><?=$Month['MonthName']?></a>
77
-<?    } ?>
78
-      </div>
79
-    </div>
80
-<?
77
+        if ($Month['Year'] != $Year) {
78
+            $Year = $Month['Year'];
79
+            echo "<h2>$Year</h2>";
80
+        } ?>
81
+    <a style="margin-left: 5px;"
82
+      href="sitehistory.php?month=<?=$Month['Month']?>&amp;year=<?=$Month['Year']?>"><?=$Month['MonthName']?></a>
83
+    <?php
84
+    } ?>
85
+  </div>
86
+</div>
87
+<?php
81
   }
88
   }
82
 
89
 
83
-  public static function render_search() { ?>
84
-      <div class="box">
85
-        <div class="head">Search</div>
86
-        <div class="pad">
87
-          <form class="search_form" action="sitehistory.php" method="get">
88
-            <input type="hidden" name="action" value="search" />
89
-            <input type="text" id="title" name="title" size="20" placeholder="Title" />
90
-            <br /><br/>
91
-            <input type="text" id="tags" name="tags" size="20" placeholder="Comma-separated tags" />
92
-            <br /><br/>
93
-            <select name="category" id="category">
94
-              <option value="0">Choose a category</option>
95
-<?
90
+    public static function render_search() { ?>
91
+<div class="box">
92
+  <div class="head">Search</div>
93
+  <div class="pad">
94
+    <form class="search_form" action="sitehistory.php" method="get">
95
+      <input type="hidden" name="action" value="search" />
96
+      <input type="text" id="title" name="title" size="20" placeholder="Title" />
97
+      <br /><br />
98
+      <input type="text" id="tags" name="tags" size="20" placeholder="Comma-separated tags" />
99
+      <br /><br />
100
+      <select name="category" id="category">
101
+        <option value="0">Choose a category</option>
102
+        <?php
96
       $Categories = SiteHistory::get_categories();
103
       $Categories = SiteHistory::get_categories();
97
       foreach ($Categories as $Key => $Value) {
104
       foreach ($Categories as $Key => $Value) {
98
-?>
99
-              <option<?=$Key == $Event['Category'] ? ' selected="selected"' : ''?> value="<?=$Key?>"><?=$Value?></option>
100
-<?      } ?>
101
-            </select>
102
-            <br /><br/>
103
-            <select name="subcategory">
104
-              <option value="0">Choose a subcategory</option>
105
-<?
105
+          ?>
106
+        <option<?=$Key == $Event['Category'] ? ' selected="selected"' : ''?>
107
+          value="<?=$Key?>"><?=$Value?>
108
+          </option>
109
+          <?php
110
+      } ?>
111
+      </select>
112
+      <br /><br />
113
+      <select name="subcategory">
114
+        <option value="0">Choose a subcategory</option>
115
+        <?php
106
       $SubCategories = SiteHistory::get_sub_categories();
116
       $SubCategories = SiteHistory::get_sub_categories();
107
       foreach ($SubCategories as $Key => $Value) {
117
       foreach ($SubCategories as $Key => $Value) {
108
-?>
109
-              <option<?=$Key == $Event['SubCategory'] ? ' selected="selected"' : ''?> value="<?=$Key?>"><?=$Value?></option>
110
-<?      } ?>
111
-            </select>
112
-            <br /><br/>
113
-            <input value="Search" type="submit" />
114
-          </form>
115
-        </div>
116
-      </div>
117
-<?  }
118
+          ?>
119
+        <option<?=$Key == $Event['SubCategory'] ? ' selected="selected"' : ''?>
120
+          value="<?=$Key?>"><?=$Value?>
121
+          </option>
122
+          <?php
123
+      } ?>
124
+      </select>
125
+      <br /><br />
126
+      <input value="Search" type="submit" />
127
+    </form>
128
+  </div>
129
+</div>
130
+<?php  }
118
 
131
 
119
-  public static function render_edit_form($Event) { ?>
120
-    <form id="event_form" method="post" action="">
121
-<?    if ($Event) { ?>
122
-      <input type="hidden" name="action" value="take_edit" />
123
-      <input type="hidden" name="id" value="<?=$Event['ID']?>" />
124
-<?    } else { ?>
125
-      <input type="hidden" name="action" value="take_create" />
126
-<?    } ?>
127
-      <input type="hidden" name="auth" value="<?=G::$LoggedUser['AuthKey']?>" />
128
-      <table cellpadding="6" cellspacing="1" border="0" class="layout border" width="100%">
129
-        <tr>
130
-          <td class="label">Title:</td>
131
-          <td>
132
-            <input type="text" id="title" name="title" size="50" class="required" value="<?=$Event['Title']?>" />
133
-          </td>
134
-        </tr>
135
-        <tr>
136
-          <td class="label">Link:</td>
137
-          <td>
138
-            <input type="text" id="url" name="url" size="50" value="<?=$Event['Url']?>" />
139
-          </td>
140
-        </tr>
141
-        <tr>
142
-          <td class="label">Date:</td>
143
-          <td>
144
-            <input type="date" id="date" name="date" class="required"<?=$Event ? ' value="' . date('Y-m-d', strtotime($Event['Date'])) . '"' : ''?> />
145
-          </td>
146
-        </tr>
147
-        <tr>
148
-          <td class="label">Category:</td>
149
-          <td>
150
-            <select id="category" name="category" class="required">
151
-              <option value="0">Choose a category</option>
152
-<?
132
+    public static function render_edit_form($Event) { ?>
133
+<form id="event_form" method="post" action="">
134
+  <?php if ($Event) { ?>
135
+  <input type="hidden" name="action" value="take_edit" />
136
+  <input type="hidden" name="id"
137
+    value="<?=$Event['ID']?>" />
138
+  <?php } else { ?>
139
+  <input type="hidden" name="action" value="take_create" />
140
+  <?php } ?>
141
+  <input type="hidden" name="auth"
142
+    value="<?=G::$LoggedUser['AuthKey']?>" />
143
+  <table cellpadding="6" cellspacing="1" border="0" class="layout border" width="100%">
144
+    <tr>
145
+      <td class="label">Title:</td>
146
+      <td>
147
+        <input type="text" id="title" name="title" size="50" class="required"
148
+          value="<?=$Event['Title']?>" />
149
+      </td>
150
+    </tr>
151
+    <tr>
152
+      <td class="label">Link:</td>
153
+      <td>
154
+        <input type="text" id="url" name="url" size="50"
155
+          value="<?=$Event['Url']?>" />
156
+      </td>
157
+    </tr>
158
+    <tr>
159
+      <td class="label">Date:</td>
160
+      <td>
161
+        <input type="date" id="date" name="date" class="required" <?=$Event ? ' value="' . date('Y-m-d', strtotime($Event['Date'])) . '"' : ''?>
162
+        />
163
+      </td>
164
+    </tr>
165
+    <tr>
166
+      <td class="label">Category:</td>
167
+      <td>
168
+        <select id="category" name="category" class="required">
169
+          <option value="0">Choose a category</option>
170
+          <?php
153
     $Categories = SiteHistory::get_categories();
171
     $Categories = SiteHistory::get_categories();
154
     foreach ($Categories as $Key => $Value) {
172
     foreach ($Categories as $Key => $Value) {
155
-?>
156
-              <option<?=$Key == $Event['Category'] ? ' selected="selected"' : ''?> value="<?=$Key?>"><?=$Value?></option>
157
-<?    } ?>
158
-            </select>
159
-          </td>
160
-        </tr>
161
-        <tr>
162
-          <td class="label">Subcategory:</td>
163
-          <td>
164
-            <select id="category" name="sub_category" class="required">
165
-              <option value="0">Choose a subcategory</option>
166
-<?    $SubCategories = SiteHistory::get_sub_categories();
173
+        ?>
174
+          <option<?=$Key == $Event['Category'] ? ' selected="selected"' : ''?>
175
+            value="<?=$Key?>"><?=$Value?>
176
+            </option>
177
+            <?php
178
+    } ?>
179
+        </select>
180
+      </td>
181
+    </tr>
182
+    <tr>
183
+      <td class="label">Subcategory:</td>
184
+      <td>
185
+        <select id="category" name="sub_category" class="required">
186
+          <option value="0">Choose a subcategory</option>
187
+          <?php $SubCategories = SiteHistory::get_sub_categories();
167
     foreach ($SubCategories as $Key => $Value) { ?>
188
     foreach ($SubCategories as $Key => $Value) { ?>
168
-              <option<?=$Key == $Event['SubCategory'] ? ' selected="selected"' : ''?> value="<?=$Key?>"><?=$Value?></option>
169
-<?    } ?>
170
-            </select>
171
-          </td>
172
-        </tr>
173
-        <tr>
174
-          <td class="label">Tags:</td>
175
-          <td>
176
-            <input type="text" id="tags" name="tags" placeholder="Comma-separated tags; use periods/dots for spaces" size="50" value="<?=$Event['Tags']?>" />
177
-            <select id="tag_list">
178
-              <option>Choose tags</option>
179
-<?
189
+          <option<?=$Key == $Event['SubCategory'] ? ' selected="selected"' : ''?>
190
+            value="<?=$Key?>"><?=$Value?>
191
+            </option>
192
+            <?php } ?>
193
+        </select>
194
+      </td>
195
+    </tr>
196
+    <tr>
197
+      <td class="label">Tags:</td>
198
+      <td>
199
+        <input type="text" id="tags" name="tags" placeholder="Comma-separated tags; use periods/dots for spaces"
200
+          size="50"
201
+          value="<?=$Event['Tags']?>" />
202
+        <select id="tag_list">
203
+          <option>Choose tags</option>
204
+          <?php
180
     $Tags = SiteHistory::get_tags();
205
     $Tags = SiteHistory::get_tags();
181
     foreach ($Tags as $Tag) {
206
     foreach ($Tags as $Tag) {
182
-?>
183
-              <option><?=$Tag?></option>
184
-<?    } ?>
185
-            </select>
186
-          </td>
187
-        </tr>
188
-        <tr>
189
-          <td class="label">Body:</td>
190
-          <td>
191
-            <textarea id="body" name="body" cols="90" rows="8" tabindex="1" onkeyup="resize('body');"><?=$Event['Body']?></textarea>
192
-          </td>
193
-        </tr>
194
-      </table>
195
-      <input type="submit" name="submit" value="Submit" />
196
-<?    if ($Event) { ?>
197
-      <input type="submit" name="delete" value="Delete" />
198
-<?    } ?>
199
-    </form>
200
-<?
207
+        ?>
208
+          <option><?=$Tag?>
209
+          </option>
210
+          <?php
211
+    } ?>
212
+        </select>
213
+      </td>
214
+    </tr>
215
+    <tr>
216
+      <td class="label">Body:</td>
217
+      <td>
218
+        <textarea id="body" name="body" cols="90" rows="8" tabindex="1"
219
+          onkeyup="resize('body');"><?=$Event['Body']?></textarea>
220
+      </td>
221
+    </tr>
222
+  </table>
223
+  <input type="submit" name="submit" value="Submit" />
224
+  <?php if ($Event) { ?>
225
+  <input type="submit" name="delete" value="Delete" />
226
+  <?php } ?>
227
+</form>
228
+<?php
201
   }
229
   }
202
 
230
 
203
-  public static function render_recent_sidebar($Events) { ?>
204
-    <div class="box">
205
-      <div class="head colhead_dark">
206
-        <strong><a href="sitehistory.php">Latest site history</a></strong>
207
-      </div>
208
-      <ul class="stats nobullet">
209
-<?
231
+    public static function render_recent_sidebar($Events) { ?>
232
+<div class="box">
233
+  <div class="head colhead_dark">
234
+    <strong><a href="sitehistory.php">Latest site history</a></strong>
235
+  </div>
236
+  <ul class="stats nobullet">
237
+    <?php
210
     $Categories = SiteHistory::get_categories();
238
     $Categories = SiteHistory::get_categories();
211
     foreach ($Events as $Event) {
239
     foreach ($Events as $Event) {
212
-?>
213
-        <li>
214
-          <a href="sitehistory.php?action=search&amp;category=<?=$Event['Category']?>" class="brackets"><?=$Categories[$Event['Category']]?></a>
215
-<?      if (!empty($Event['Url'])) { ?>
216
-          <a href="<?=$Event['Url']?>"><?=Format::cut_string($Event['Title'], 20)?></a>
217
-<?      } else { ?>
218
-          <?=Format::cut_string($Event['Title'], 20)?>
219
-<?      } ?>
220
-        </li>
221
-<?    } ?>
222
-      </ul>
223
-    </div>
224
-<?
240
+        ?>
241
+    <li>
242
+      <a href="sitehistory.php?action=search&amp;category=<?=$Event['Category']?>"
243
+        class="brackets"><?=$Categories[$Event['Category']]?></a>
244
+      <?php if (!empty($Event['Url'])) { ?>
245
+      <a href="<?=$Event['Url']?>"><?=Format::cut_string($Event['Title'], 20)?></a>
246
+      <?php } else { ?>
247
+      <?=Format::cut_string($Event['Title'], 20)?>
248
+      <?php } ?>
249
+    </li>
250
+    <?php
251
+    } ?>
252
+  </ul>
253
+</div>
254
+<?php
225
   }
255
   }
226
 }
256
 }

Loading…
Cancel
Save