pjc 5 years ago
parent
commit
a4373497e5

+ 25
- 16
classes/artists.class.php View File

1
 <?php
1
 <?php
2
+
2
 class Artists
3
 class Artists
3
 {
4
 {
4
 
5
 
23
     {
24
     {
24
         $Results = [];
25
         $Results = [];
25
         $DBs = [];
26
         $DBs = [];
27
+
26
         foreach ($GroupIDs as $GroupID) {
28
         foreach ($GroupIDs as $GroupID) {
27
             if (!is_number($GroupID)) {
29
             if (!is_number($GroupID)) {
28
                 continue;
30
                 continue;
29
             }
31
             }
32
+
30
             $Artists = G::$Cache->get_value('groups_artists_'.$GroupID);
33
             $Artists = G::$Cache->get_value('groups_artists_'.$GroupID);
31
             if (is_array($Artists)) {
34
             if (is_array($Artists)) {
32
                 $Results[$GroupID] = $Artists;
35
                 $Results[$GroupID] = $Artists;
34
                 $DBs[] = $GroupID;
37
                 $DBs[] = $GroupID;
35
             }
38
             }
36
         }
39
         }
40
+
37
         if (count($DBs) > 0) {
41
         if (count($DBs) > 0) {
38
             $IDs = implode(',', $DBs);
42
             $IDs = implode(',', $DBs);
39
             if (empty($IDs)) {
43
             if (empty($IDs)) {
40
                 $IDs = "null";
44
                 $IDs = "null";
41
             }
45
             }
46
+
42
             $QueryID = G::$DB->get_query_id();
47
             $QueryID = G::$DB->get_query_id();
43
             G::$DB->query("
48
             G::$DB->query("
44
-        SELECT ta.GroupID,
45
-          ta.ArtistID,
46
-          ag.Name
47
-        FROM torrents_artists AS ta
48
-          JOIN artists_group AS ag ON ta.ArtistID = ag.ArtistID
49
-        WHERE ta.GroupID IN ($IDs)
50
-        ORDER BY ta.GroupID ASC,
51
-          ag.Name ASC;");
49
+            SELECT ta.GroupID,
50
+              ta.ArtistID,
51
+              ag.Name
52
+            FROM torrents_artists AS ta
53
+              JOIN artists_group AS ag ON ta.ArtistID = ag.ArtistID
54
+              WHERE ta.GroupID IN ($IDs)
55
+              ORDER BY ta.GroupID ASC,
56
+              ag.Name ASC;");
57
+
52
             while (list($GroupID, $ArtistID, $ArtistName) = G::$DB->next_record(MYSQLI_BOTH, false)) {
58
             while (list($GroupID, $ArtistID, $ArtistName) = G::$DB->next_record(MYSQLI_BOTH, false)) {
53
                 $Results[$GroupID][] = array('id' => $ArtistID, 'name' => $ArtistName);
59
                 $Results[$GroupID][] = array('id' => $ArtistID, 'name' => $ArtistName);
54
                 $New[$GroupID][] = array('id' => $ArtistID, 'name' => $ArtistName);
60
                 $New[$GroupID][] = array('id' => $ArtistID, 'name' => $ArtistName);
55
             }
61
             }
62
+
56
             G::$DB->set_query_id($QueryID);
63
             G::$DB->set_query_id($QueryID);
57
             foreach ($DBs as $GroupID) {
64
             foreach ($DBs as $GroupID) {
58
                 if (isset($New[$GroupID])) {
65
                 if (isset($New[$GroupID])) {
61
                     G::$Cache->cache_value('groups_artists_'.$GroupID, []);
68
                     G::$Cache->cache_value('groups_artists_'.$GroupID, []);
62
                 }
69
                 }
63
             }
70
             }
71
+
64
             $Missing = array_diff($GroupIDs, array_keys($Results));
72
             $Missing = array_diff($GroupIDs, array_keys($Results));
65
             if (!empty($Missing)) {
73
             if (!empty($Missing)) {
66
                 $Results += array_fill_keys($Missing, []);
74
                 $Results += array_fill_keys($Missing, []);
112
             $link = Artists::display_artist($Artists[0], $MakeLink, $Escape).'  et al.'.($IncludeHyphen? ' – ':'');
120
             $link = Artists::display_artist($Artists[0], $MakeLink, $Escape).'  et al.'.($IncludeHyphen? ' – ':'');
113
             #$link = "Various".($IncludeHyphen?' – ':'');
121
             #$link = "Various".($IncludeHyphen?' – ':'');
114
         }
122
         }
115
-    
116
             return $link;
123
             return $link;
117
         } else {
124
         } else {
118
             return '';
125
             return '';
150
     {
157
     {
151
         $QueryID = G::$DB->get_query_id();
158
         $QueryID = G::$DB->get_query_id();
152
         G::$DB->query("
159
         G::$DB->query("
153
-      SELECT Name
154
-      FROM artists_group
155
-      WHERE ArtistID = ".$ArtistID);
160
+        SELECT Name
161
+        FROM artists_group
162
+          WHERE ArtistID = ".$ArtistID);
156
         list($Name) = G::$DB->next_record(MYSQLI_NUM, false);
163
         list($Name) = G::$DB->next_record(MYSQLI_NUM, false);
157
 
164
 
158
         // Delete requests
165
         // Delete requests
159
         G::$DB->query("
166
         G::$DB->query("
160
-      SELECT RequestID
161
-      FROM requests_artists
162
-      WHERE ArtistID = $ArtistID
163
-        AND ArtistID != 0");
167
+        SELECT RequestID
168
+        FROM requests_artists
169
+          WHERE ArtistID = $ArtistID
170
+          AND ArtistID != 0");
171
+
164
         $Requests = G::$DB->to_array();
172
         $Requests = G::$DB->to_array();
165
         foreach ($Requests as $Request) {
173
         foreach ($Requests as $Request) {
166
             list($RequestID) = $Request;
174
             list($RequestID) = $Request;
192
         } else {
200
         } else {
193
             $Username = 'System';
201
             $Username = 'System';
194
         }
202
         }
203
+        
195
         Misc::write_log("Artist $ArtistID ($Name) was deleted by $Username");
204
         Misc::write_log("Artist $ArtistID ($Name) was deleted by $Username");
196
         G::$DB->set_query_id($QueryID);
205
         G::$DB->set_query_id($QueryID);
197
     }
206
     }

+ 40
- 41
classes/autoenable.class.php View File

1
 <?php
1
 <?php
2
 
2
 
3
+# todo: Check strict equality gently
3
 class AutoEnable
4
 class AutoEnable
4
 {
5
 {
5
-
6
     // Constants for database values
6
     // Constants for database values
7
     const APPROVED = 1;
7
     const APPROVED = 1;
8
     const DENIED = 2;
8
     const DENIED = 2;
33
 
33
 
34
         // Get the user's ID
34
         // Get the user's ID
35
         G::$DB->query("
35
         G::$DB->query("
36
-                SELECT um.ID, ui.BanReason
37
-                FROM users_main AS um
38
-                JOIN users_info ui ON ui.UserID = um.ID
39
-                WHERE um.Username = '$Username'
40
-                  AND um.Enabled = '2'");
36
+        SELECT um.ID, ui.BanReason
37
+        FROM users_main AS um
38
+          JOIN users_info ui ON ui.UserID = um.ID
39
+          WHERE um.Username = '$Username'
40
+          AND um.Enabled = '2'");
41
 
41
 
42
         if (G::$DB->has_results()) {
42
         if (G::$DB->has_results()) {
43
             // Make sure the user can make another request
43
             // Make sure the user can make another request
46
             SELECT 1 FROM users_enable_requests
46
             SELECT 1 FROM users_enable_requests
47
             WHERE UserID = '$UserID'
47
             WHERE UserID = '$UserID'
48
               AND (
48
               AND (
49
-                    (
50
-                      Timestamp > NOW() - INTERVAL 1 WEEK
51
-                        AND HandledTimestamp IS NULL
52
-                    )
53
-                    OR
54
-                    (
55
-                      Timestamp > NOW() - INTERVAL 2 MONTH
56
-                      AND
57
-                      Outcome = '".self::DENIED."'
58
-                    )
59
-                  )");
49
+                (
50
+                  Timestamp > NOW() - INTERVAL 1 WEEK
51
+                  AND HandledTimestamp IS NULL
52
+                )
53
+                OR
54
+                (
55
+                  Timestamp > NOW() - INTERVAL 2 MONTH
56
+                  AND
57
+                  Outcome = '".self::DENIED."'
58
+                )
59
+            )");
60
         }
60
         }
61
 
61
 
62
         $IP = $_SERVER['REMOTE_ADDR'];
62
         $IP = $_SERVER['REMOTE_ADDR'];
92
                 //self::handle_requests([$RequestID], self::APPROVED, "Automatically approved (inactivity)");
92
                 //self::handle_requests([$RequestID], self::APPROVED, "Automatically approved (inactivity)");
93
             }
93
             }
94
         }
94
         }
95
-
96
         return $Output;
95
         return $Output;
97
     }
96
     }
98
 
97
 
132
             // Prepare email
131
             // Prepare email
133
             require_once(SERVER_ROOT . '/classes/templates.class.php');
132
             require_once(SERVER_ROOT . '/classes/templates.class.php');
134
             $TPL = new TEMPLATE;
133
             $TPL = new TEMPLATE;
134
+
135
             if ($Status == self::APPROVED) {
135
             if ($Status == self::APPROVED) {
136
                 $TPL->open(SERVER_ROOT . '/templates/enable_request_accepted.tpl');
136
                 $TPL->open(SERVER_ROOT . '/templates/enable_request_accepted.tpl');
137
                 $TPL->set('SITE_DOMAIN', SITE_DOMAIN);
137
                 $TPL->set('SITE_DOMAIN', SITE_DOMAIN);
172
         // User notes stuff
172
         // User notes stuff
173
         $StaffID = G::$LoggedUser['ID'] ?? 0;
173
         $StaffID = G::$LoggedUser['ID'] ?? 0;
174
         G::$DB->query("
174
         G::$DB->query("
175
-            SELECT Username
176
-            FROM users_main
177
-            WHERE ID = ?", $StaffID);
175
+        SELECT Username
176
+        FROM users_main
177
+          WHERE ID = ?", $StaffID);
178
         if (G::$DB->has_results()) {
178
         if (G::$DB->has_results()) {
179
             list($StaffUser) = G::$DB->next_record();
179
             list($StaffUser) = G::$DB->next_record();
180
         } else {
180
         } else {
191
 
191
 
192
         // Update database values and decrement cache
192
         // Update database values and decrement cache
193
         G::$DB->query("
193
         G::$DB->query("
194
-                UPDATE users_enable_requests
195
-                SET HandledTimestamp = NOW(),
196
-                    CheckedBy = ?,
197
-                    Outcome = ?
198
-                WHERE ID IN (".implode(',', $IDs).")", $StaffID, $Status);
194
+        UPDATE users_enable_requests
195
+        SET HandledTimestamp = NOW(),
196
+          CheckedBy = ?,
197
+          Outcome = ?
198
+          WHERE ID IN (".implode(',', $IDs).")", $StaffID, $Status);
199
         G::$Cache->decrement_value(self::CACHE_KEY_NAME, count($IDs));
199
         G::$Cache->decrement_value(self::CACHE_KEY_NAME, count($IDs));
200
     }
200
     }
201
 
201
 
213
         }
213
         }
214
 
214
 
215
         G::$DB->query("
215
         G::$DB->query("
216
-            SELECT UserID
217
-            FROM users_enable_requests
218
-            WHERE Outcome = '" . self::DISCARDED . "'
219
-              AND ID = '$ID'");
216
+        SELECT UserID
217
+        FROM users_enable_requests
218
+          WHERE Outcome = '" . self::DISCARDED . "'
219
+          AND ID = '$ID'");
220
 
220
 
221
         if (!G::$DB->has_results()) {
221
         if (!G::$DB->has_results()) {
222
             error(404);
222
             error(404);
225
         }
225
         }
226
 
226
 
227
         G::$DB->query("
227
         G::$DB->query("
228
-            SELECT Username
229
-            FROM users_main
230
-            WHERE ID = '" . G::$LoggedUser['ID'] . "'");
228
+        SELECT Username
229
+        FROM users_main
230
+          WHERE ID = '" . G::$LoggedUser['ID'] . "'");
231
         list($StaffUser) = G::$DB->next_record();
231
         list($StaffUser) = G::$DB->next_record();
232
 
232
 
233
         Tools::update_user_notes($UserID, sqltime() . " - Enable request $ID unresolved by [user]" . $StaffUser . '[/user]' . "\n\n");
233
         Tools::update_user_notes($UserID, sqltime() . " - Enable request $ID unresolved by [user]" . $StaffUser . '[/user]' . "\n\n");
234
         G::$DB->query("
234
         G::$DB->query("
235
-            UPDATE users_enable_requests
236
-            SET Outcome = NULL, HandledTimestamp = NULL, CheckedBy = NULL
237
-            WHERE ID = '$ID'");
235
+        UPDATE users_enable_requests
236
+        SET Outcome = NULL, HandledTimestamp = NULL, CheckedBy = NULL
237
+          WHERE ID = '$ID'");
238
         G::$Cache->increment_value(self::CACHE_KEY_NAME);
238
         G::$Cache->increment_value(self::CACHE_KEY_NAME);
239
     }
239
     }
240
 
240
 
269
     {
269
     {
270
         $Token = db_string($Token);
270
         $Token = db_string($Token);
271
         G::$DB->query("
271
         G::$DB->query("
272
-            SELECT uer.UserID, uer.HandledTimestamp, um.torrent_pass, um.Visible, um.IP
273
-            FROM users_enable_requests AS uer
274
-            LEFT JOIN users_main AS um ON uer.UserID = um.ID
275
-            WHERE Token = '$Token'");
272
+        SELECT uer.UserID, uer.HandledTimestamp, um.torrent_pass, um.Visible, um.IP
273
+        FROM users_enable_requests AS uer
274
+          LEFT JOIN users_main AS um ON uer.UserID = um.ID
275
+          WHERE Token = '$Token'");
276
 
276
 
277
         if (G::$DB->has_results()) {
277
         if (G::$DB->has_results()) {
278
             list($UserID, $Timestamp, $TorrentPass, $Visible, $IP) = G::$DB->next_record();
278
             list($UserID, $Timestamp, $TorrentPass, $Visible, $IP) = G::$DB->next_record();
294
         } else {
294
         } else {
295
             $Err = "Invalid token.";
295
             $Err = "Invalid token.";
296
         }
296
         }
297
-
298
         return $Err;
297
         return $Err;
299
     }
298
     }
300
 
299
 

+ 120
- 115
classes/badges.class.php View File

1
-<?
2
-class Badges {
3
-  /**
4
-   * Given a UserID, returns that user's badges
5
-   *
6
-   * @param int $UserID
7
-   * @return array of BadgeIDs
8
-   */
9
-  public static function get_badges($UserID) {
10
-    return Users::user_info($UserID)['Badges'];
11
-  }
12
-
13
-  /**
14
-   * Awards UserID the given BadgeID
15
-   *
16
-   * @param int $UserID
17
-   * @param int $BadgeID
18
-   * @return bool success?
19
-   */
20
-  public static function award_badge($UserID, $BadgeID) {
21
-    if (self::has_badge($UserID, $BadgeID)) {
22
-      return false;
23
-    } else {
24
-      $QueryID = G::$DB->get_query_id();
25
-      G::$DB->query("
26
-        INSERT INTO users_badges
27
-          (UserID, BadgeID)
28
-        VALUES
29
-          ($UserID, $BadgeID)");
30
-      G::$DB->set_query_id($QueryID);
31
-
32
-      G::$Cache->delete_value('user_info_'.$UserID);
33
-
34
-      return true;
1
+<?php
2
+
3
+class Badges
4
+{
5
+    /**
6
+     * Given a UserID, returns that user's badges
7
+     *
8
+     * @param int $UserID
9
+     * @return array of BadgeIDs
10
+     */
11
+    public static function get_badges($UserID)
12
+    {
13
+        return Users::user_info($UserID)['Badges'];
35
     }
14
     }
36
-  }
37
-
38
-  /**
39
-   * Given a UserID, return that user's displayed badges
40
-   *
41
-   * @param int $UserID
42
-   * @return array of BadgeIDs
43
-   */
44
-  public static function get_displayed_badges($UserID) {
45
-    $Result = [];
46
-
47
-    $Badges = self::get_badges($UserID);
48
 
15
 
49
-    foreach ($Badges as $Badge => $Displayed) {
50
-      if ($Displayed)
51
-        $Result[] = $Badge;
16
+    /**
17
+     * Awards UserID the given BadgeID
18
+     *
19
+     * @param int $UserID
20
+     * @param int $BadgeID
21
+     * @return bool success?
22
+     */
23
+    public static function award_badge($UserID, $BadgeID)
24
+    {
25
+        if (self::has_badge($UserID, $BadgeID)) {
26
+            return false;
27
+        } else {
28
+            $QueryID = G::$DB->get_query_id();
29
+            G::$DB->query("
30
+            INSERT INTO users_badges
31
+              (UserID, BadgeID)
32
+            VALUES
33
+              ($UserID, $BadgeID)");
34
+
35
+            G::$DB->set_query_id($QueryID);
36
+            G::$Cache->delete_value('user_info_'.$UserID);
37
+            return true;
38
+        }
52
     }
39
     }
53
-    return $Result;
54
-  }
55
-
56
-  /**
57
-   * Returns true if the given user owns the given badge
58
-   *
59
-   * @param int $UserID
60
-   * @param int $BadgeID
61
-   * @return bool
62
-   */
63
-  public static function has_badge($UserID, $BadgeID) {
64
-    $Badges = self::get_badges($UserID);
65
-
66
-    return array_key_exists($BadgeID, $Badges);
67
-  }
68
-
69
-  /**
70
-   * Creates HTML for displaying a badge.
71
-   *
72
-   * @param int $BadgeID
73
-   * @param bool $Tooltip Should HTML contain a tooltip?
74
-   * @return string HTML
75
-   */
76
-  public static function display_badge($BadgeID, $Tooltip = false) {
77
-    $html = "";
78
 
40
 
79
-    if (($Badges = G::$Cache->get_value('badges')) && array_key_exists($BadgeID, $Badges)) {
80
-      extract($Badges[$BadgeID]);
81
-    } else {
82
-      self::update_badge_cache();
83
-      if (($Badges = G::$Cache->get_value('badges')) && array_key_exists($BadgeID, $Badges)) {
84
-        extract($Badges[$BadgeID]);
85
-      } else {
86
-        global $Debug;
87
-        $Debug->analysis('Invalid BadgeID ' . $BadgeID . ' requested.');
88
-      }
41
+    /**
42
+     * Given a UserID, return that user's displayed badges
43
+     *
44
+     * @param int $UserID
45
+     * @return array of BadgeIDs
46
+     */
47
+    public static function get_displayed_badges($UserID)
48
+    {
49
+        $Result = [];
50
+        $Badges = self::get_badges($UserID);
51
+
52
+        foreach ($Badges as $Badge => $Displayed) {
53
+            if ($Displayed) {
54
+                $Result[] = $Badge;
55
+            }
56
+        }
57
+        return $Result;
89
     }
58
     }
90
 
59
 
91
-    if ($Tooltip) {
92
-      $html .= '<a class="badge_icon"><img class="tooltip" alt="'.$Name.'" title="'.$Name.'</br>'.$Description.'" src="'.$Icon.'" /></a>';
93
-    } else {
94
-      $html .= '<a class="badge_icon"><img alt="'.$Name.'" title="'.$Name.'" src="'.$Icon.'" /></a>';
60
+    /**
61
+     * Returns true if the given user owns the given badge
62
+     *
63
+     * @param int $UserID
64
+     * @param int $BadgeID
65
+     * @return bool
66
+     */
67
+    public static function has_badge($UserID, $BadgeID)
68
+    {
69
+        $Badges = self::get_badges($UserID);
70
+        return array_key_exists($BadgeID, $Badges);
95
     }
71
     }
96
 
72
 
97
-    return $html;
98
-  }
73
+    /**
74
+     * Creates HTML for displaying a badge.
75
+     *
76
+     * @param int $BadgeID
77
+     * @param bool $Tooltip Should HTML contain a tooltip?
78
+     * @return string HTML
79
+     */
80
+    public static function display_badge($BadgeID, $Tooltip = false)
81
+    {
82
+        $html = "";
83
+        if (($Badges = G::$Cache->get_value('badges')) && array_key_exists($BadgeID, $Badges)) {
84
+            extract($Badges[$BadgeID]);
85
+        } else {
86
+            self::update_badge_cache();
87
+            if (($Badges = G::$Cache->get_value('badges')) && array_key_exists($BadgeID, $Badges)) {
88
+                extract($Badges[$BadgeID]);
89
+            } else {
90
+                global $Debug;
91
+                $Debug->analysis('Invalid BadgeID ' . $BadgeID . ' requested.');
92
+            }
93
+        }
94
+
95
+        if ($Tooltip) {
96
+            $html .= '<a class="badge_icon"><img class="tooltip" alt="'.$Name.'" title="'.$Name.'</br>'.$Description.'" src="'.$Icon.'" /></a>';
97
+        } else {
98
+            $html .= '<a class="badge_icon"><img alt="'.$Name.'" title="'.$Name.'" src="'.$Icon.'" /></a>';
99
+        }
100
+        return $html;
101
+    }
99
 
102
 
100
-  public static function display_badges($BadgeIDs, $Tooltip = false) {
101
-    $html = "";
102
-    foreach ($BadgeIDs as $BadgeID) {
103
-      $html .= self::display_badge($BadgeID, $Tooltip);
103
+    public static function display_badges($BadgeIDs, $Tooltip = false)
104
+    {
105
+        $html = "";
106
+        foreach ($BadgeIDs as $BadgeID) {
107
+            $html .= self::display_badge($BadgeID, $Tooltip);
108
+        }
109
+        return $html;
104
     }
110
     }
105
-    return $html;
106
-  }
107
 
111
 
108
-  private static function update_badge_cache() {
109
-      $QueryID = G::$DB->get_query_id();
112
+    private static function update_badge_cache()
113
+    {
114
+        $QueryID = G::$DB->get_query_id();
110
 
115
 
111
-      G::$DB->query("
116
+        G::$DB->query("
112
         SELECT
117
         SELECT
113
         ID, Icon, Name, Description
118
         ID, Icon, Name, Description
114
         FROM badges");
119
         FROM badges");
115
 
120
 
116
-      $badges = [];
117
-      if (G::$DB->has_results()) {
118
-        while(list($id, $icon, $name, $description) = G::$DB->next_record()) {
119
-          $badges[$id] = array('Icon' => $icon, 'Name' => $name, 'Description' => $Description);
121
+        $badges = [];
122
+        if (G::$DB->has_results()) {
123
+            while (list($id, $icon, $name, $description) = G::$DB->next_record()) {
124
+                $badges[$id] = array('Icon' => $icon, 'Name' => $name, 'Description' => $Description);
125
+            }
126
+            G::$Cache->cache_value('badges', $badges);
120
         }
127
         }
121
-        G::$Cache->cache_value('badges', $badges);
122
-      }
123
 
128
 
124
-      G::$DB->set_query_id($QueryID);
125
-  }
129
+        G::$DB->set_query_id($QueryID);
130
+    }
126
 
131
 
127
-  public static function get_all_badges() {
128
-    if (($Badges = G::$Cache->get_value('badges'))) {
129
-      return $Badges;
130
-    } else {
131
-      self::update_badge_cache();
132
-      return G::$Cache->get_value('badges');
132
+    public static function get_all_badges()
133
+    {
134
+        if (($Badges = G::$Cache->get_value('badges'))) {
135
+            return $Badges;
136
+        } else {
137
+            self::update_badge_cache();
138
+            return G::$Cache->get_value('badges');
139
+        }
133
     }
140
     }
134
-  }
135
 }
141
 }
136
-?>

+ 6
- 0
classes/bencode.class.php View File

54
         } else {
54
         } else {
55
             $Data =& $Arg;
55
             $Data =& $Arg;
56
         }
56
         }
57
+
57
         if ($Keys === true) {
58
         if ($Keys === true) {
58
             $this->Data = $Data;
59
             $this->Data = $Data;
59
         } elseif ($Keys === false) {
60
         } elseif ($Keys === false) {
63
         } else {
64
         } else {
64
             $this->Data = isset($Data[$Keys]) ? $Data[$Keys] : false;
65
             $this->Data = isset($Data[$Keys]) ? $Data[$Keys] : false;
65
         }
66
         }
67
+
66
         if (!$this->Data) {
68
         if (!$this->Data) {
67
             return false;
69
             return false;
68
         }
70
         }
71
+
69
         $this->Enc = $this->_benc();
72
         $this->Enc = $this->_benc();
70
         return $this->Enc;
73
         return $this->Enc;
71
     }
74
     }
81
             if (Int64::is_int($this->Data)) { // Integer
84
             if (Int64::is_int($this->Data)) { // Integer
82
                 return 'i'.Int64::get($this->Data).'e';
85
                 return 'i'.Int64::get($this->Data).'e';
83
             }
86
             }
87
+
84
             if ($this->Data === true) { // Empty dictionary
88
             if ($this->Data === true) { // Empty dictionary
85
                 return 'de';
89
                 return 'de';
86
             }
90
             }
87
             return strlen($this->Data).':'.$this->Data; // String
91
             return strlen($this->Data).':'.$this->Data; // String
88
         }
92
         }
93
+
89
         if (empty($this->Data) || Int64::is_int(key($this->Data))) {
94
         if (empty($this->Data) || Int64::is_int(key($this->Data))) {
90
             $IsDict = false;
95
             $IsDict = false;
91
         } else {
96
         } else {
92
             $IsDict = true;
97
             $IsDict = true;
93
             ksort($this->Data); // Dictionaries must be sorted
98
             ksort($this->Data); // Dictionaries must be sorted
94
         }
99
         }
100
+        
95
         $Ret = $IsDict ? 'd' : 'l';
101
         $Ret = $IsDict ? 'd' : 'l';
96
         foreach ($this->Data as $Key => $Value) {
102
         foreach ($this->Data as $Key => $Value) {
97
             if ($IsDict) {
103
             if ($IsDict) {

+ 11
- 0
classes/bencodedecode.class.php View File

1
 <?php
1
 <?php
2
+
2
 /**
3
 /**
3
  * The decode class is simple and straightforward. The only thing to
4
  * The decode class is simple and straightforward. The only thing to
4
  * note is that empty dictionaries are represented by boolean trues
5
  * note is that empty dictionaries are represented by boolean trues
24
         if (!$Strict) {
25
         if (!$Strict) {
25
             $this->ExitOnError = false;
26
             $this->ExitOnError = false;
26
         }
27
         }
28
+
27
         if ($Arg === false) {
29
         if ($Arg === false) {
28
             if (empty($this->Enc)) {
30
             if (empty($this->Enc)) {
29
                 return false;
31
                 return false;
48
         if (empty($Path)) {
50
         if (empty($Path)) {
49
             return false;
51
             return false;
50
         }
52
         }
53
+
51
         if (!$this->Data = @file_get_contents($Path, FILE_BINARY)) {
54
         if (!$this->Data = @file_get_contents($Path, FILE_BINARY)) {
52
             return $this->error("Error: file '$Path' could not be opened.\n");
55
             return $this->error("Error: file '$Path' could not be opened.\n");
53
         }
56
         }
67
         } elseif (!$this->Data) {
70
         } elseif (!$this->Data) {
68
             $this->Data = $this->Enc;
71
             $this->Data = $this->Enc;
69
         }
72
         }
73
+
70
         if (!$this->Data) {
74
         if (!$this->Data) {
71
             return false;
75
             return false;
72
         }
76
         }
77
+
73
         $this->Length = strlen($this->Data);
78
         $this->Length = strlen($this->Data);
74
         $this->Pos = 0;
79
         $this->Pos = 0;
75
         $this->Dec = $this->_bdec();
80
         $this->Dec = $this->_bdec();
81
+
76
         if ($this->Pos < $this->Length) {
82
         if ($this->Pos < $this->Length) {
77
             // Not really necessary, but if the torrent is invalid, it's better to warn than to silently truncate it
83
             // Not really necessary, but if the torrent is invalid, it's better to warn than to silently truncate it
78
             return $this->error();
84
             return $this->error();
151
         if ($Data === false) {
157
         if ($Data === false) {
152
             $Data = $this->Dec;
158
             $Data = $this->Dec;
153
         }
159
         }
160
+
154
         if (Int64::is_int($Data)) {
161
         if (Int64::is_int($Data)) {
155
             return Int64::get($Data);
162
             return Int64::get($Data);
156
         }
163
         }
164
+
157
         if (is_bool($Data)) {
165
         if (is_bool($Data)) {
158
             return [];
166
             return [];
159
         }
167
         }
168
+
160
         if (is_array($Data)) {
169
         if (is_array($Data)) {
161
             $Output = [];
170
             $Output = [];
162
             foreach ($Data as $Key => $Val) {
171
             foreach ($Data as $Key => $Val) {
179
             // The recursive nature of the class requires this to avoid duplicate error messages
188
             // The recursive nature of the class requires this to avoid duplicate error messages
180
             return false;
189
             return false;
181
         }
190
         }
191
+
182
         if ($this->ExitOnError) {
192
         if ($this->ExitOnError) {
183
             if ($ErrMsg === false) {
193
             if ($ErrMsg === false) {
184
                 printf(
194
                 printf(
191
             }
201
             }
192
             exit();
202
             exit();
193
         }
203
         }
204
+        
194
         $ErrorPos = $this->Pos;
205
         $ErrorPos = $this->Pos;
195
         return false;
206
         return false;
196
     }
207
     }

+ 3
- 0
classes/bencodetorrent.class.php View File

1
 <?php
1
 <?php
2
+
2
 /**
3
 /**
3
  * Torrent class that contains some convenient functions related to torrent meta data
4
  * Torrent class that contains some convenient functions related to torrent meta data
4
  */
5
  */
18
         if (empty($this->Dec)) {
19
         if (empty($this->Dec)) {
19
             return false;
20
             return false;
20
         }
21
         }
22
+
21
         $InfoDict =& $this->Dec['info'];
23
         $InfoDict =& $this->Dec['info'];
22
         if (!isset($InfoDict['files'])) {
24
         if (!isset($InfoDict['files'])) {
23
             // Single-file torrent
25
             // Single-file torrent
32
             if (isset($InfoDict['path.utf-8']['files'][0])) {
34
             if (isset($InfoDict['path.utf-8']['files'][0])) {
33
                 $this->PathKey = 'path.utf-8';
35
                 $this->PathKey = 'path.utf-8';
34
             }
36
             }
37
+            
35
             foreach ($InfoDict['files'] as $File) {
38
             foreach ($InfoDict['files'] as $File) {
36
                 $TmpPath = [];
39
                 $TmpPath = [];
37
                 foreach ($File[$this->PathKey] as $SubPath) {
40
                 foreach ($File[$this->PathKey] as $SubPath) {

+ 33
- 26
classes/bitcoinrpc.class.php View File

1
 <?php
1
 <?php
2
-class BitcoinRpc {
3
 
2
 
4
-  public static function __callStatic($Method, $Args) {
5
-    if (!defined('BITCOIN_RPC_URL')) {
6
-      return false;
7
-    }
8
-    $MessageID = mt_rand();
9
-    $Params = json_encode(array(
10
-      'method' => $Method,
11
-      'params' => $Args,
12
-      'id' => $MessageID)
13
-    );
3
+class BitcoinRpc
4
+{
5
+    public static function __callStatic($Method, $Args)
6
+    {
7
+        if (!defined('BITCOIN_RPC_URL')) {
8
+            return false;
9
+        }
14
 
10
 
15
-    $Request = array(
16
-      'http' => array(
17
-        'method' => 'POST',
18
-        'header' => 'Content-type: application/json',
19
-        'content' => $Params
20
-        )
21
-      );
11
+        $MessageID = mt_rand();
12
+        $Params = json_encode(
13
+            array(
14
+                'method' => $Method,
15
+                'params' => $Args,
16
+                'id' => $MessageID
17
+            )
18
+        );
22
 
19
 
23
-    if (!$Response = file_get_contents(BITCOIN_RPC_URL, false, stream_context_create($Request))) {
24
-      return false;
25
-    }
26
-    $Response = json_decode($Response);
27
-    if ($Response->id != $MessageID || !empty($Response->error) || empty($Response->result)) {
28
-      return false;
20
+        $Request = array(
21
+            'http' => array(
22
+                'method' => 'POST',
23
+                'header' => 'Content-type: application/json',
24
+                'content' => $Params
25
+            )
26
+        );
27
+
28
+        if (!$Response = file_get_contents(BITCOIN_RPC_URL, false, stream_context_create($Request))) {
29
+            return false;
30
+        }
31
+
32
+        $Response = json_decode($Response);
33
+        if ($Response->id != $MessageID || !empty($Response->error) || empty($Response->result)) {
34
+            return false;
35
+        }
36
+        
37
+        return $Response->result;
29
     }
38
     }
30
-    return $Response->result;
31
-  }
32
 }
39
 }

+ 98
- 87
classes/bookmarks.class.php View File

1
-<?
2
-class Bookmarks {
1
+<?php
3
 
2
 
4
-  /**
5
-   * Check if can bookmark
6
-   *
7
-   * @param string $Type
8
-   * @return boolean
9
-   */
10
-  public static function can_bookmark($Type) {
11
-    return in_array($Type, array(
3
+class Bookmarks
4
+{
5
+    /**
6
+     * Check if can bookmark
7
+     *
8
+     * @param string $Type
9
+     * @return boolean
10
+     */
11
+    public static function can_bookmark($Type)
12
+    {
13
+        return in_array($Type, array(
12
         'torrent',
14
         'torrent',
13
         'artist',
15
         'artist',
14
         'collage',
16
         'collage',
15
         'request'
17
         'request'
16
     ));
18
     ));
17
-  }
18
-
19
-  /**
20
-   * Get the bookmark schema.
21
-   * Recommended usage:
22
-   * list($Table, $Col) = bookmark_schema('torrent');
23
-   *
24
-   * @param string $Type the type to get the schema for
25
-   */
26
-  public static function bookmark_schema($Type) {
27
-    switch ($Type) {
28
-      case 'torrent':
29
-        return array(
30
-            'bookmarks_torrents',
31
-            'GroupID'
32
-        );
33
-        break;
34
-      case 'artist':
35
-        return array(
36
-            'bookmarks_artists',
37
-            'ArtistID'
38
-        );
39
-        break;
40
-      case 'collage':
41
-        return array(
42
-            'bookmarks_collages',
43
-            'CollageID'
44
-        );
45
-        break;
46
-      case 'request':
47
-        return array(
48
-            'bookmarks_requests',
49
-            'RequestID'
50
-        );
51
-        break;
52
-      default:
53
-        die('HAX');
54
     }
19
     }
55
-  }
56
 
20
 
57
-  /**
58
-   * Check if something is bookmarked
59
-   *
60
-   * @param string $Type
61
-   *          type of bookmarks to check
62
-   * @param int $ID
63
-   *          bookmark's id
64
-   * @return boolean
65
-   */
66
-  public static function has_bookmarked($Type, $ID) {
67
-    return in_array($ID, self::all_bookmarks($Type));
68
-  }
21
+    /**
22
+     * Get the bookmark schema.
23
+     * Recommended usage:
24
+     * list($Table, $Col) = bookmark_schema('torrent');
25
+     *
26
+     * @param string $Type the type to get the schema for
27
+     */
28
+    public static function bookmark_schema($Type)
29
+    {
30
+        switch ($Type) {
31
+          case 'torrent':
32
+            return array(
33
+              'bookmarks_torrents',
34
+              'GroupID'
35
+            );
36
+            break;
37
+
38
+          case 'artist':
39
+            return array(
40
+              'bookmarks_artists',
41
+              'ArtistID'
42
+            );
43
+            break;
44
+
45
+          case 'collage':
46
+            return array(
47
+              'bookmarks_collages',
48
+              'CollageID'
49
+             );
50
+            break;
51
+
52
+          case 'request':
53
+            return array(
54
+              'bookmarks_requests',
55
+              'RequestID'
56
+            );
57
+            break;
58
+
59
+          default:
60
+            die('h4x');
61
+        }
62
+    }
69
 
63
 
70
-  /**
71
-   * Fetch all bookmarks of a certain type for a user.
72
-   * If UserID is false than defaults to G::$LoggedUser['ID']
73
-   *
74
-   * @param string $Type
75
-   *          type of bookmarks to fetch
76
-   * @param int $UserID
77
-   *          userid whose bookmarks to get
78
-   * @return array the bookmarks
79
-   */
80
-  public static function all_bookmarks($Type, $UserID = false) {
81
-    if ($UserID === false) {
82
-      $UserID = G::$LoggedUser['ID'];
64
+    /**
65
+     * Check if something is bookmarked
66
+     *
67
+     * @param string $Type
68
+     *          type of bookmarks to check
69
+     * @param int $ID
70
+     *          bookmark's id
71
+     * @return boolean
72
+     */
73
+    public static function has_bookmarked($Type, $ID)
74
+    {
75
+        return in_array($ID, self::all_bookmarks($Type));
83
     }
76
     }
84
-    $CacheKey = 'bookmarks_' . $Type . '_' . $UserID;
85
-    if (($Bookmarks = G::$Cache->get_value($CacheKey)) === false) {
86
-      list ($Table, $Col) = self::bookmark_schema($Type);
87
-      $QueryID = G::$DB->get_query_id();
88
-      G::$DB->query("
89
-        SELECT $Col
90
-        FROM $Table
91
-        WHERE UserID = '$UserID'");
92
-      $Bookmarks = G::$DB->collect($Col);
93
-      G::$DB->set_query_id($QueryID);
94
-      G::$Cache->cache_value($CacheKey, $Bookmarks, 0);
77
+
78
+    /**
79
+     * Fetch all bookmarks of a certain type for a user.
80
+     * If UserID is false than defaults to G::$LoggedUser['ID']
81
+     *
82
+     * @param string $Type
83
+     *          type of bookmarks to fetch
84
+     * @param int $UserID
85
+     *          userid whose bookmarks to get
86
+     * @return array the bookmarks
87
+     */
88
+    public static function all_bookmarks($Type, $UserID = false)
89
+    {
90
+        if ($UserID === false) {
91
+            $UserID = G::$LoggedUser['ID'];
92
+        }
93
+
94
+        $CacheKey = 'bookmarks_' . $Type . '_' . $UserID;
95
+        if (($Bookmarks = G::$Cache->get_value($CacheKey)) === false) {
96
+            list($Table, $Col) = self::bookmark_schema($Type);
97
+            $QueryID = G::$DB->get_query_id();
98
+
99
+            G::$DB->query("
100
+            SELECT $Col
101
+            FROM $Table
102
+              WHERE UserID = '$UserID'");
103
+
104
+            $Bookmarks = G::$DB->collect($Col);
105
+            G::$DB->set_query_id($QueryID);
106
+            G::$Cache->cache_value($CacheKey, $Bookmarks, 0);
107
+        }
108
+        return $Bookmarks;
95
     }
109
     }
96
-    return $Bookmarks;
97
-  }
98
 }
110
 }
99
-?>

+ 1
- 0
classes/cache.class.php View File

1
 <?php
1
 <?php
2
+
2
 /*************************************************************************|
3
 /*************************************************************************|
3
 |--------------- Caching class -------------------------------------------|
4
 |--------------- Caching class -------------------------------------------|
4
 |*************************************************************************|
5
 |*************************************************************************|

+ 145
- 130
classes/calendar.class.php View File

1
-<?
2
-class Calendar {
3
-  public static $Categories = array(1 => "IRC Meeting", "IRC Brainstorm", "Poll Deadline", "Feature Release", "Blog Post", "Announcement", "Featured Album", "Product Release", "Staff Picks", "Forum Brainstorm", "Forum Discussion", "Promotion", "Absence", "Task");
4
-  public static $Importances = array(1 => "Critical", "Important", "Average", "Meh");
5
-  public static $Colors = array(
6
-                  "Critical" => "red",
7
-                  "Important" => "yellow",
8
-                  "Average" => "green",
9
-                  "Meh" => "blue");
10
-
11
-  public static $Teams = array(
12
-                  0 => "Everyone",
13
-                  1 => "Staff"
14
-
15
-                  );
16
-
17
-  public static function can_view() {
18
-    return check_perms('users_mod')
19
-
20
-      ;
21
-  }
22
-
23
-  private static function get_teams_query() {
24
-    $Teams = array(0);
25
-    $IsMod = check_perms("users_mod");
26
-    if ($IsMod) {
27
-      $Teams[] = 1;
1
+<?php
2
+
3
+class Calendar
4
+{
5
+    public static $Categories = array(1 => "IRC Meeting", "IRC Brainstorm", "Poll Deadline", "Feature Release", "Blog Post", "Announcement", "Featured Album", "Product Release", "Staff Picks", "Forum Brainstorm", "Forum Discussion", "Promotion", "Absence", "Task");
6
+    public static $Importances = array(1 => "Critical", "Important", "Average", "Meh");
7
+    public static $Colors = array(
8
+        "Critical" => "red",
9
+        "Important" => "yellow",
10
+        "Average" => "green",
11
+        "Meh" => "blue"
12
+      );
13
+
14
+    public static $Teams = array(
15
+        0 => "Everyone",
16
+        1 => "Staff"
17
+    );
18
+
19
+    public static function can_view()
20
+    {
21
+        return check_perms('users_mod');
28
     }
22
     }
29
 
23
 
30
-    return "Team IN (" . implode(",", $Teams) . ") ";
31
-  }
24
+    private static function get_teams_query()
25
+    {
26
+        $Teams = array(0);
27
+        $IsMod = check_perms("users_mod");
32
 
28
 
33
-  public static function get_events($Month, $Year) {
34
-    if (empty($Month) || empty($Year)) {
35
-      $Date = getdate();
36
-      $Month = $Date['mon'];
37
-      $Year = $Date['year'];
29
+        if ($IsMod) {
30
+            $Teams[] = 1;
31
+        }
32
+        return "Team IN (" . implode(",", $Teams) . ") ";
38
     }
33
     }
39
-    $Month = (int)$Month;
40
-    $Year = (int)$Year;
41
-
42
-    $TeamsSQL = self::get_teams_query();
43
-
44
-    $QueryID = G::$DB->get_query_id();
45
-    G::$DB->query("
46
-            SELECT
47
-              ID, Team, Title, Category, Importance, DAY(StartDate) AS StartDay, DAY(EndDate) AS EndDay
48
-            FROM calendar
49
-            WHERE
50
-              MONTH(StartDate) = '$Month'
51
-            AND
52
-              YEAR(StartDate) = '$Year'
53
-            AND
54
-              $TeamsSQL");
55
-    $Events = G::$DB->to_array();
56
-    G::$DB->set_query_id($QueryID);
57
-    return $Events;
58
-  }
59
-
60
-  public static function get_event($ID) {
61
-    $ID = (int)$ID;
62
-    if (empty($ID)) {
63
-      error("Invalid ID");
34
+
35
+    public static function get_events($Month, $Year)
36
+    {
37
+        if (empty($Month) || empty($Year)) {
38
+            $Date = getdate();
39
+            $Month = $Date['mon'];
40
+            $Year = $Date['year'];
41
+        }
42
+
43
+        $Month = (int)$Month;
44
+        $Year = (int)$Year;
45
+
46
+        $TeamsSQL = self::get_teams_query();
47
+
48
+        $QueryID = G::$DB->get_query_id();
49
+        G::$DB->query("
50
+        SELECT
51
+          ID, Team, Title, Category, Importance, DAY(StartDate) AS StartDay, DAY(EndDate) AS EndDay
52
+        FROM calendar
53
+          WHERE
54
+          MONTH(StartDate) = '$Month'
55
+          AND
56
+          YEAR(StartDate) = '$Year'
57
+          AND
58
+          $TeamsSQL");
59
+
60
+        $Events = G::$DB->to_array();
61
+        G::$DB->set_query_id($QueryID);
62
+        return $Events;
64
     }
63
     }
65
-    $TeamsSQL = self::get_teams_query();
66
-    $QueryID = G::$DB->get_query_id();
67
-    G::$DB->query("
68
-            SELECT
69
-              ID, Team, Title, Body, Category, Importance, AddedBy, StartDate, EndDate
70
-            FROM calendar
71
-            WHERE
72
-              ID = '$ID'
73
-            AND
74
-              $TeamsSQL");
75
-    $Event = G::$DB->next_record(MYSQLI_ASSOC);
76
-    G::$DB->set_query_id($QueryID);
77
-    return $Event;
78
-  }
79
-
80
-  public static function create_event($Title, $Body, $Category, $Importance, $Team, $UserID, $StartDate, $EndDate = null) {
81
-    if (empty($Title) || empty($Body) || !is_number($Category) || !is_number($Importance)  || !is_number($Team) || empty($StartDate)) {
82
-      error("Error adding event");
64
+
65
+    public static function get_event($ID)
66
+    {
67
+        $ID = (int)$ID;
68
+        if (empty($ID)) {
69
+            error("Invalid ID");
70
+        }
71
+
72
+        $TeamsSQL = self::get_teams_query();
73
+        $QueryID = G::$DB->get_query_id();
74
+
75
+        G::$DB->query("
76
+        SELECT
77
+          ID, Team, Title, Body, Category, Importance, AddedBy, StartDate, EndDate
78
+        FROM calendar
79
+          WHERE
80
+          ID = '$ID'
81
+          AND
82
+          $TeamsSQL");
83
+
84
+        $Event = G::$DB->next_record(MYSQLI_ASSOC);
85
+        G::$DB->set_query_id($QueryID);
86
+        return $Event;
83
     }
87
     }
84
-    $Title = db_string($Title);
85
-    $Body = db_string($Body);
86
-    $Category = (int)$Category;
87
-    $Importance = (int)$Importance;
88
-    $UserID = (int)$UserID;
89
-    $Team = (int)$Team;
90
-    $StartDate = db_string($StartDate);
91
-    $EndDate = db_string($EndDate);
92
-
93
-    $QueryID = G::$DB->get_query_id();
94
-    G::$DB->query("
95
-            INSERT INTO calendar
96
-              (Title, Body, Category, Importance, Team, StartDate, EndDate, AddedBy)
97
-            VALUES
98
-              ('$Title', '$Body', '$Category', '$Importance', '$Team', '$StartDate', '$EndDate', '$UserID')");
99
-    G::$DB->set_query_id($QueryID);
100
-    send_irc("PRIVMSG " . ADMIN_CHAN . " :!mod New calendar event created! Event: $Title; Starts: $StartDate; Ends: $EndDate.");
101
-  }
102
-
103
-  public static function update_event($ID, $Title, $Body, $Category, $Importance, $Team, $StartDate, $EndDate = null) {
104
-    if (!is_number($ID) || empty($Title) || empty($Body) || !is_number($Category) || !is_number($Importance) || !is_number($Team) || empty($StartDate)) {
105
-      error("Error updating event");
88
+
89
+    public static function create_event($Title, $Body, $Category, $Importance, $Team, $UserID, $StartDate, $EndDate = null)
90
+    {
91
+        if (empty($Title) || empty($Body) || !is_number($Category) || !is_number($Importance)  || !is_number($Team) || empty($StartDate)) {
92
+            error("Error adding event");
93
+        }
94
+
95
+        $Title = db_string($Title);
96
+        $Body = db_string($Body);
97
+        $Category = (int)$Category;
98
+        $Importance = (int)$Importance;
99
+        $UserID = (int)$UserID;
100
+        $Team = (int)$Team;
101
+        $StartDate = db_string($StartDate);
102
+        $EndDate = db_string($EndDate);
103
+
104
+        $QueryID = G::$DB->get_query_id();
105
+        G::$DB->query("
106
+        INSERT INTO calendar
107
+          (Title, Body, Category, Importance, Team, StartDate, EndDate, AddedBy)
108
+        VALUES
109
+          ('$Title', '$Body', '$Category', '$Importance', '$Team', '$StartDate', '$EndDate', '$UserID')");
110
+
111
+        G::$DB->set_query_id($QueryID);
112
+        send_irc("PRIVMSG " . ADMIN_CHAN . " :!mod New calendar event created! Event: $Title; Starts: $StartDate; Ends: $EndDate.");
106
     }
113
     }
107
-    $ID = (int)$ID;
108
-    $Title = db_string($Title);
109
-    $Body = db_string($Body);
110
-    $Category = (int)$Category;
111
-    $Importance = (int)$Importance;
112
-    $Team = (int)$Team;
113
-    $StartDate = db_string($StartDate);
114
-    $EndDate = db_string($EndDate);
115
-    $QueryID = G::$DB->get_query_id();
116
-    G::$DB->query("
117
-            UPDATE calendar
118
-            SET
119
-              Title = '$Title',
120
-              Body = '$Body',
121
-              Category = '$Category',
122
-              Importance = '$Importance',
123
-              Team = '$Team',
124
-              StartDate = '$StartDate',
125
-              EndDate = '$EndDate'
126
-            WHERE
127
-              ID = '$ID'");
128
-    G::$DB->set_query_id($QueryID);
129
-  }
130
-
131
-  public static function remove_event($ID) {
132
-    $ID = (int)$ID;
133
-    if (!empty($ID)) {
134
-      $QueryID = G::$DB->get_query_id();
135
-      G::$DB->query("DELETE FROM calendar WHERE ID = '$ID'");
136
-      G::$DB->set_query_id($QueryID);
114
+
115
+    public static function update_event($ID, $Title, $Body, $Category, $Importance, $Team, $StartDate, $EndDate = null)
116
+    {
117
+        if (!is_number($ID) || empty($Title) || empty($Body) || !is_number($Category) || !is_number($Importance) || !is_number($Team) || empty($StartDate)) {
118
+            error("Error updating event");
119
+        }
120
+
121
+        $ID = (int)$ID;
122
+        $Title = db_string($Title);
123
+        $Body = db_string($Body);
124
+        $Category = (int)$Category;
125
+        $Importance = (int)$Importance;
126
+        $Team = (int)$Team;
127
+        $StartDate = db_string($StartDate);
128
+        $EndDate = db_string($EndDate);
129
+        $QueryID = G::$DB->get_query_id();
130
+
131
+        G::$DB->query("
132
+        UPDATE calendar
133
+        SET
134
+          Title = '$Title',
135
+          Body = '$Body',
136
+          Category = '$Category',
137
+          Importance = '$Importance',
138
+          Team = '$Team',
139
+          StartDate = '$StartDate',
140
+          EndDate = '$EndDate'
141
+        WHERE
142
+          ID = '$ID'");
143
+        G::$DB->set_query_id($QueryID);
137
     }
144
     }
138
-  }
139
 
145
 
146
+    public static function remove_event($ID)
147
+    {
148
+        $ID = (int)$ID;
149
+        if (!empty($ID)) {
150
+            $QueryID = G::$DB->get_query_id();
151
+            G::$DB->query("DELETE FROM calendar WHERE ID = '$ID'");
152
+            G::$DB->set_query_id($QueryID);
153
+        }
154
+    }
140
 }
155
 }

+ 9
- 8
classes/classloader.php View File

1
-<?
1
+<?php
2
+
2
 /**
3
 /**
3
  * Load classes automatically when they're needed
4
  * Load classes automatically when they're needed
4
  *
5
  *
5
  * @param string $ClassName class name
6
  * @param string $ClassName class name
6
  */
7
  */
7
 spl_autoload_register(function ($ClassName) {
8
 spl_autoload_register(function ($ClassName) {
8
-  $FilePath = SERVER_ROOT . '/classes/' . strtolower($ClassName) . '.class.php';
9
-  if (!file_exists($FilePath)) {
10
-    // todo: Rename the following classes to conform with the code guidelines
11
-    switch ($ClassName) {
9
+    $FilePath = SERVER_ROOT . '/classes/' . strtolower($ClassName) . '.class.php';
10
+    if (!file_exists($FilePath)) {
11
+        // todo: Rename the following classes to conform with the code guidelines
12
+        switch ($ClassName) {
12
       case 'MASS_USER_BOOKMARKS_EDITOR':
13
       case 'MASS_USER_BOOKMARKS_EDITOR':
13
         $FileName = 'mass_user_bookmarks_editor.class';
14
         $FileName = 'mass_user_bookmarks_editor.class';
14
         break;
15
         break;
29
       default:
30
       default:
30
         die("Couldn't import class $ClassName");
31
         die("Couldn't import class $ClassName");
31
     }
32
     }
32
-    $FilePath = SERVER_ROOT . "/classes/$FileName.php";
33
-  }
34
-  require_once($FilePath);
33
+        $FilePath = SERVER_ROOT . "/classes/$FileName.php";
34
+    }
35
+    require_once($FilePath);
35
 });
36
 });

+ 18
- 16
classes/collages.class.php View File

1
 <?php
1
 <?php
2
+
2
 class Collages
3
 class Collages
3
 {
4
 {
4
     public static function increase_subscriptions($CollageID)
5
     public static function increase_subscriptions($CollageID)
5
     {
6
     {
6
         $QueryID = G::$DB->get_query_id();
7
         $QueryID = G::$DB->get_query_id();
7
         G::$DB->query("
8
         G::$DB->query("
8
-      UPDATE collages
9
-      SET Subscribers = Subscribers + 1
10
-      WHERE ID = '$CollageID'");
9
+        UPDATE collages
10
+        SET Subscribers = Subscribers + 1
11
+          WHERE ID = '$CollageID'");
11
         G::$DB->set_query_id($QueryID);
12
         G::$DB->set_query_id($QueryID);
12
     }
13
     }
13
 
14
 
15
     {
16
     {
16
         $QueryID = G::$DB->get_query_id();
17
         $QueryID = G::$DB->get_query_id();
17
         G::$DB->query("
18
         G::$DB->query("
18
-      UPDATE collages
19
-      SET Subscribers = IF(Subscribers < 1, 0, Subscribers - 1)
20
-      WHERE ID = '$CollageID'");
19
+        UPDATE collages
20
+        SET Subscribers = IF(Subscribers < 1, 0, Subscribers - 1)
21
+          WHERE ID = '$CollageID'");
21
         G::$DB->set_query_id($QueryID);
22
         G::$DB->set_query_id($QueryID);
22
     }
23
     }
23
 
24
 
24
     public static function create_personal_collage()
25
     public static function create_personal_collage()
25
     {
26
     {
26
         G::$DB->query("
27
         G::$DB->query("
27
-      SELECT
28
-        COUNT(ID)
29
-      FROM collages
30
-      WHERE UserID = '" . G::$LoggedUser['ID'] . "'
31
-        AND CategoryID = '0'
32
-        AND Deleted = '0'");
28
+        SELECT
29
+          COUNT(ID)
30
+        FROM collages
31
+          WHERE UserID = '" . G::$LoggedUser['ID'] . "'
32
+          AND CategoryID = '0'
33
+          AND Deleted = '0'");
33
         list($CollageCount) = G::$DB->next_record();
34
         list($CollageCount) = G::$DB->next_record();
34
 
35
 
35
         if ($CollageCount >= G::$LoggedUser['Permissions']['MaxCollages']) {
36
         if ($CollageCount >= G::$LoggedUser['Permissions']['MaxCollages']) {
41
         $NameStr = db_string(G::$LoggedUser['Username'] . "'s personal collage" . ($CollageCount > 0 ? ' no. ' . ($CollageCount + 1) : ''));
42
         $NameStr = db_string(G::$LoggedUser['Username'] . "'s personal collage" . ($CollageCount > 0 ? ' no. ' . ($CollageCount + 1) : ''));
42
         $Description = db_string('Personal collage for ' . G::$LoggedUser['Username'] . '. The first 5 albums will appear on his or her [url=' . site_url() . 'user.php?id= ' . G::$LoggedUser['ID'] . ']profile[/url].');
43
         $Description = db_string('Personal collage for ' . G::$LoggedUser['Username'] . '. The first 5 albums will appear on his or her [url=' . site_url() . 'user.php?id= ' . G::$LoggedUser['ID'] . ']profile[/url].');
43
         G::$DB->query("
44
         G::$DB->query("
44
-      INSERT INTO collages
45
-        (Name, Description, CategoryID, UserID)
46
-      VALUES
47
-        ('$NameStr', '$Description', '0', " . G::$LoggedUser['ID'] . ")");
45
+        INSERT INTO collages
46
+          (Name, Description, CategoryID, UserID)
47
+        VALUES
48
+          ('$NameStr', '$Description', '0', " . G::$LoggedUser['ID'] . ")");
49
+          
48
         $CollageID = G::$DB->inserted_id();
50
         $CollageID = G::$DB->inserted_id();
49
         header('Location: collage.php?id='.$CollageID);
51
         header('Location: collage.php?id='.$CollageID);
50
         die();
52
         die();

+ 836
- 755
classes/donations.class.php
File diff suppressed because it is too large
View File


+ 13
- 4
classes/notificationsmanager.class.php View File

14
     const INFO = 'confirmation';
14
     const INFO = 'confirmation';
15
 
15
 
16
     public static $Importances = array(
16
     public static $Importances = array(
17
-    'important' => self::IMPORTANT,
18
-    'critical' => self::CRITICAL,
19
-    'warning' => self::WARNING,
20
-    'info' => self::INFO);
17
+        'important' => self::IMPORTANT,
18
+        'critical' => self::CRITICAL,
19
+        'warning' => self::WARNING,
20
+        'info' => self::INFO
21
+    );
21
 
22
 
22
     // Types. These names must correspond to column names in users_notifications_settings
23
     // Types. These names must correspond to column names in users_notifications_settings
23
     const NEWS = 'News';
24
     const NEWS = 'News';
78
             if (!isset($this->Skipped[self::NEWS])) {
79
             if (!isset($this->Skipped[self::NEWS])) {
79
                 $this->load_news();
80
                 $this->load_news();
80
             }
81
             }
82
+
81
             if (!isset($this->Skipped[self::BLOG])) {
83
             if (!isset($this->Skipped[self::BLOG])) {
82
                 $this->load_blog();
84
                 $this->load_blog();
83
             }
85
             }
86
+
84
             // if (!isset($this->Skipped[self::STAFFBLOG])) {
87
             // if (!isset($this->Skipped[self::STAFFBLOG])) {
85
             //   $this->load_staff_blog();
88
             //   $this->load_staff_blog();
86
             // }
89
             // }
90
+
87
             if (!isset($this->Skipped[self::STAFFPM])) {
91
             if (!isset($this->Skipped[self::STAFFPM])) {
88
                 $this->load_staff_pms();
92
                 $this->load_staff_pms();
89
             }
93
             }
94
+
90
             if (!isset($this->Skipped[self::INBOX])) {
95
             if (!isset($this->Skipped[self::INBOX])) {
91
                 $this->load_inbox();
96
                 $this->load_inbox();
92
             }
97
             }
98
+
93
             if (!isset($this->Skipped[self::TORRENTS])) {
99
             if (!isset($this->Skipped[self::TORRENTS])) {
94
                 $this->load_torrent_notifications();
100
                 $this->load_torrent_notifications();
95
             }
101
             }
102
+
96
             if (!isset($this->Skipped[self::COLLAGES])) {
103
             if (!isset($this->Skipped[self::COLLAGES])) {
97
                 $this->load_collage_subscriptions();
104
                 $this->load_collage_subscriptions();
98
             }
105
             }
106
+
99
             if (!isset($this->Skipped[self::QUOTES])) {
107
             if (!isset($this->Skipped[self::QUOTES])) {
100
                 $this->load_quote_notifications();
108
                 $this->load_quote_notifications();
101
             }
109
             }
110
+            
102
             if (!isset($this->Skipped[self::SUBSCRIPTIONS])) {
111
             if (!isset($this->Skipped[self::SUBSCRIPTIONS])) {
103
                 $this->load_subscriptions();
112
                 $this->load_subscriptions();
104
             }
113
             }

+ 1
- 0
classes/regex.php View File

1
 <?php
1
 <?php
2
+
2
 // resource_type://username:password@domain:port/path?query_string#anchor
3
 // resource_type://username:password@domain:port/path?query_string#anchor
3
 define('RESOURCE_REGEX', '(https?|ftps?):\/\/');
4
 define('RESOURCE_REGEX', '(https?|ftps?):\/\/');
4
 define('IP_REGEX', '(\d{1,3}\.){3}\d{1,3}');
5
 define('IP_REGEX', '(\d{1,3}\.){3}\d{1,3}');

+ 1
- 0
classes/requests.class.php View File

1
 <?php
1
 <?php
2
+
2
 class Requests
3
 class Requests
3
 {
4
 {
4
     /**
5
     /**

+ 29
- 24
classes/revisionhistory.class.php View File

1
-<?
2
-class RevisionHistory {
3
-  /**
4
-   * Read the revision history of an artist or torrent page
5
-   * @param string $Page artists or torrents
6
-   * @param in $PageID
7
-   * @return array
8
-   */
9
-  public static function get_revision_history($Page, $PageID) {
10
-    $Table = ($Page == 'artists') ? 'wiki_artists' : 'wiki_torrents';
11
-    $QueryID = G::$DB->get_query_id();
12
-    G::$DB->query("
13
-      SELECT
14
-        RevisionID,
15
-        Summary,
16
-        Time,
17
-        UserID
18
-      FROM $Table
19
-      WHERE PageID = $PageID
20
-      ORDER BY RevisionID DESC");
21
-    $Ret = G::$DB->to_array();
22
-    G::$DB->set_query_id($QueryID);
23
-    return $Ret;
24
-  }
1
+<?php
2
+
3
+class RevisionHistory
4
+{
5
+    /**
6
+     * Read the revision history of an artist or torrent page
7
+     * @param string $Page artists or torrents
8
+     * @param in $PageID
9
+     * @return array
10
+     */
11
+    public static function get_revision_history($Page, $PageID)
12
+    {
13
+        $Table = ($Page == 'artists') ? 'wiki_artists' : 'wiki_torrents';
14
+        $QueryID = G::$DB->get_query_id();
15
+
16
+        G::$DB->query("
17
+        SELECT
18
+          RevisionID,
19
+          Summary,
20
+          Time,
21
+          UserID
22
+        FROM $Table
23
+          WHERE PageID = $PageID
24
+          ORDER BY RevisionID DESC");
25
+
26
+        $Ret = G::$DB->to_array();
27
+        G::$DB->set_query_id($QueryID);
28
+        return $Ret;
29
+    }
25
 }
30
 }

+ 44
- 41
classes/revisionhistoryview.class.php View File

1
-<?
2
-class RevisionHistoryView {
3
-  /**
4
-   * Render the revision history
5
-   * @param array $RevisionHistory see RevisionHistory::get_revision_history
6
-   * @param string $BaseURL
7
-   */
8
-  public static function render_revision_history($RevisionHistory, $BaseURL) {
9
-?>
10
-  <table cellpadding="6" cellspacing="1" border="0" width="100%" class="box">
11
-    <tr class="colhead">
12
-      <td>Revision</td>
13
-      <td>Date</td>
14
-<? if (check_perms('users_mod')) { ?>
15
-      <td>User</td>
16
-<? } ?>
17
-      <td>Summary</td>
18
-    </tr>
19
-<?
1
+<?php
2
+
3
+class RevisionHistoryView
4
+{
5
+    /**
6
+     * Render the revision history
7
+     * @param array $RevisionHistory see RevisionHistory::get_revision_history
8
+     * @param string $BaseURL
9
+     */
10
+    public static function render_revision_history($RevisionHistory, $BaseURL)
11
+    {
12
+        ?>
13
+<table cellpadding="6" cellspacing="1" border="0" width="100%" class="box">
14
+  <tr class="colhead">
15
+    <td>Revision</td>
16
+    <td>Date</td>
17
+    <?php if (check_perms('users_mod')) { ?>
18
+    <td>User</td>
19
+    <?php } ?>
20
+    <td>Summary</td>
21
+  </tr>
22
+  <?php
20
     foreach ($RevisionHistory as $Entry) {
23
     foreach ($RevisionHistory as $Entry) {
21
-      list($RevisionID, $Summary, $Time, $UserID) = $Entry;
22
-?>
23
-    <tr class="row">
24
-      <td>
25
-        <?= "<a href=\"$BaseURL&amp;revisionid=$RevisionID\">#$RevisionID</a>" ?>
26
-      </td>
27
-      <td>
28
-        <?=$Time?>
29
-      </td>
30
-<? if (check_perms('users_mod')) { ?>
31
-      <td>
32
-        <?=Users::format_username($UserID, false, false, false)?>
33
-      </td>
34
-<? } ?>
35
-      <td>
36
-        <?=($Summary ? $Summary : '(empty)')?>
37
-      </td>
38
-    </tr>
39
-<?    } ?>
40
-  </table>
41
-<?
42
-  }
24
+        list($RevisionID, $Summary, $Time, $UserID) = $Entry; ?>
25
+  <tr class="row">
26
+    <td>
27
+      <?= "<a href=\"$BaseURL&amp;revisionid=$RevisionID\">#$RevisionID</a>" ?>
28
+    </td>
29
+    <td>
30
+      <?=$Time?>
31
+    </td>
32
+    <?php if (check_perms('users_mod')) { ?>
33
+    <td>
34
+      <?=Users::format_username($UserID, false, false, false)?>
35
+    </td>
36
+    <?php } ?>
37
+    <td>
38
+      <?=($Summary ? $Summary : '(empty)')?>
39
+    </td>
40
+  </tr>
41
+  <?php
42
+    } ?>
43
+</table>
44
+<?php
45
+    }
43
 }
46
 }

+ 4
- 2
classes/rules.class.php View File

1
 <?php
1
 <?php
2
+
2
 class Rules
3
 class Rules
3
 {
4
 {
4
 
5
 
10
     {
11
     {
11
         ?>
12
         ?>
12
 <ul>
13
 <ul>
13
-<li><strong>No personally identifying patient data is allowed anywhere on the site.</strong></li>
14
+  <li><strong>No personally identifying patient data is allowed anywhere on the site.</strong></li>
14
 
15
 
15
   <li>Staff can do anything to anyone for any reason (or no reason). If you take issue with a decision, you must do so
16
   <li>Staff can do anything to anyone for any reason (or no reason). If you take issue with a decision, you must do so
16
     privately with the staff member who issued the decision or with an administrator of the site.</li>
17
     privately with the staff member who issued the decision or with an administrator of the site.</li>
114
     Thank you.</li>
115
     Thank you.</li>
115
 
116
 
116
   <li>No advertising, referrals, affiliate links, cryptocurrency pumps, or calls to action that involve using a
117
   <li>No advertising, referrals, affiliate links, cryptocurrency pumps, or calls to action that involve using a
117
-    financial instrument. You'll be banned on the spot. The exceptions: discussions about cryptocurrencies that derive their value from
118
+    financial instrument. You'll be banned on the spot. The exceptions: discussions about cryptocurrencies that derive
119
+    their value from
118
     work performed on distributed science networks, i.e., Curecoin, FoldingCoin, and Gridcoin.</li>
120
     work performed on distributed science networks, i.e., Curecoin, FoldingCoin, and Gridcoin.</li>
119
 
121
 
120
   <li>Feel free to post announcements for your own projects, even and especially if they're commercial ones, in the
122
   <li>Feel free to post announcements for your own projects, even and especially if they're commercial ones, in the

+ 260
- 238
classes/tags.class.php View File

24
  * Each time a new Tags object is instantiated, the tag list is merged with the
24
  * Each time a new Tags object is instantiated, the tag list is merged with the
25
  * overall total amount of tags to provide a Top Tags list. Merging is optional.
25
  * overall total amount of tags to provide a Top Tags list. Merging is optional.
26
  */
26
  */
27
-class Tags {
28
-  /**
29
-   * Collects all tags processed by the Tags Class
30
-   * @static
31
-   * @var array $All Class Tags
32
-   */
33
-  private static $All = [];
27
+class Tags
28
+{
29
+    /**
30
+     * Collects all tags processed by the Tags Class
31
+     * @static
32
+     * @var array $All Class Tags
33
+     */
34
+    private static $All = [];
34
 
35
 
35
-  /**
36
-   * All tags in the current instance
37
-   * @var array $Tags Instance Tags
38
-   */
39
-  private $Tags = null;
36
+    /**
37
+     * All tags in the current instance
38
+     * @var array $Tags Instance Tags
39
+     */
40
+    private $Tags = null;
40
 
41
 
41
-  /**
42
-   * @var array $TagLink Tag link list
43
-   */
44
-  private $TagLink = [];
42
+    /**
43
+     * @var array $TagLink Tag link list
44
+     */
45
+    private $TagLink = [];
45
 
46
 
46
-  /**
47
-   * @var string $Primary The primary tag
48
-   */
49
-  private $Primary = '';
47
+    /**
48
+     * @var string $Primary The primary tag
49
+     */
50
+    private $Primary = '';
50
 
51
 
51
-  /**
52
-   * Filter tags array to remove empty spaces.
53
-   *
54
-   * @param string $TagList A string of tags separated by a space
55
-   * @param boolean $Merge Merge the tag list with the Class' tags
56
-   *        E.g., compilations and soundtracks are skipped, so false
57
-   */
58
-  public function __construct($TagList, $Merge = true) {
59
-    if ($TagList) {
60
-      $this->Tags = array_filter(explode(' ', str_replace('_', '.', $TagList)));
52
+    /**
53
+     * Filter tags array to remove empty spaces.
54
+     *
55
+     * @param string $TagList A string of tags separated by a space
56
+     * @param boolean $Merge Merge the tag list with the Class' tags
57
+     *        E.g., compilations and soundtracks are skipped, so false
58
+     */
59
+    public function __construct($TagList, $Merge = true)
60
+    {
61
+        if ($TagList) {
62
+            $this->Tags = array_filter(explode(' ', str_replace('_', '.', $TagList)));
61
 
63
 
62
-      if ($Merge) {
63
-        self::$All = array_merge(self::$All, $this->Tags);
64
-      }
64
+            if ($Merge) {
65
+                self::$All = array_merge(self::$All, $this->Tags);
66
+            }
65
 
67
 
66
-      $this->Primary = $this->Tags[0];
67
-      sort($this->Tags);
68
-    } else {
69
-      $this->Tags = [];
68
+            $this->Primary = $this->Tags[0];
69
+            sort($this->Tags);
70
+        } else {
71
+            $this->Tags = [];
72
+        }
70
     }
73
     }
71
-  }
72
-
73
-  /**
74
-   * @return string Primary Tag
75
-   */
76
-  public function get_primary() {
77
-    return $this->Primary;
78
-  }
79
 
74
 
80
-  /**
81
-   * Set the primary tag
82
-   * @param string $Primary
83
-   */
84
-  public function set_primary($Primary) {
85
-    $this->Primary = (string)$Primary;
86
-  }
75
+    /**
76
+     * @return string Primary Tag
77
+     */
78
+    public function get_primary()
79
+    {
80
+        return $this->Primary;
81
+    }
87
 
82
 
88
-  /**
89
-   * Formats primary tag as a title
90
-   * @return string Title
91
-   */
92
-  public function title() {
93
-    return ucwords(str_replace('.', ' ', $this->Primary));
94
-  }
83
+    /**
84
+     * Set the primary tag
85
+     * @param string $Primary
86
+     */
87
+    public function set_primary($Primary)
88
+    {
89
+        $this->Primary = (string)$Primary;
90
+    }
95
 
91
 
96
-  /**
97
-   * Formats primary tag as a CSS class
98
-   * @return string CSS Class Name
99
-   */
100
-  public function css_name() {
101
-    return 'tags_' . str_replace('.', '_', $this->Primary);
102
-  }
92
+    /**
93
+     * Formats primary tag as a title
94
+     * @return string Title
95
+     */
96
+    public function title()
97
+    {
98
+        return ucwords(str_replace('.', ' ', $this->Primary));
99
+    }
103
 
100
 
104
-  /**
105
-   * @return array Tags
106
-   */
107
-  public function get_tags() {
108
-    return $this->Tags;
109
-  }
101
+    /**
102
+     * Formats primary tag as a CSS class
103
+     * @return string CSS Class Name
104
+     */
105
+    public function css_name()
106
+    {
107
+        return 'tags_' . str_replace('.', '_', $this->Primary);
108
+    }
110
 
109
 
111
-  /**
112
-   * @return array All tags
113
-   */
114
-  public static function all() {
115
-    return self::$All;
116
-  }
110
+    /**
111
+     * @return array Tags
112
+     */
113
+    public function get_tags()
114
+    {
115
+        return $this->Tags;
116
+    }
117
 
117
 
118
-  /**
119
-   * Counts and sorts All tags
120
-   * @return array All tags sorted
121
-   */
122
-  public static function sorted() {
123
-    $Sorted = array_count_values(self::$All);
124
-    arsort($Sorted);
125
-    return $Sorted;
126
-  }
118
+    /**
119
+     * @return array All tags
120
+     */
121
+    public static function all()
122
+    {
123
+        return self::$All;
124
+    }
127
 
125
 
128
-  /**
129
-   * Formats tags
130
-   * @param string $Link Link to a taglist page
131
-   * @param string $ArtistName Restrict tag search by this artist
132
-   * @return string List of tag links
133
-   */
134
-  public function format($Link = 'torrents.php?taglist=', $ArtistName = '') {
135
-    if (!empty($ArtistName)) {
136
-      $ArtistName = "&amp;artistname=" . urlencode($ArtistName) . "&amp;action=advanced&amp;searchsubmit=1";
126
+    /**
127
+     * Counts and sorts All tags
128
+     * @return array All tags sorted
129
+     */
130
+    public static function sorted()
131
+    {
132
+        $Sorted = array_count_values(self::$All);
133
+        arsort($Sorted);
134
+        return $Sorted;
137
     }
135
     }
138
-    foreach ($this->Tags as $Tag) {
139
-      $Split = self::get_name_and_class($Tag);
140
-      $Name = $Split['name'];
141
-      $Class = $Split['class'];
142
-      if (empty($this->TagLink[$Tag])) {
143
-        $this->TagLink[$Tag] = '<a class="' . $Class . '" href="' . $Link . $Tag . $ArtistName . '">' . $Name . '</a>';
144
-      }
136
+
137
+    /**
138
+     * Formats tags
139
+     * @param string $Link Link to a taglist page
140
+     * @param string $ArtistName Restrict tag search by this artist
141
+     * @return string List of tag links
142
+     */
143
+    public function format($Link = 'torrents.php?taglist=', $ArtistName = '')
144
+    {
145
+        if (!empty($ArtistName)) {
146
+            $ArtistName = "&amp;artistname=" . urlencode($ArtistName) . "&amp;action=advanced&amp;searchsubmit=1";
147
+        }
148
+
149
+        foreach ($this->Tags as $Tag) {
150
+            $Split = self::get_name_and_class($Tag);
151
+            $Name = $Split['name'];
152
+            $Class = $Split['class'];
153
+
154
+            if (empty($this->TagLink[$Tag])) {
155
+                $this->TagLink[$Tag] = '<a class="' . $Class . '" href="' . $Link . $Tag . $ArtistName . '">' . $Name . '</a>';
156
+            }
157
+        }
158
+        return implode(', ', $this->TagLink);
145
     }
159
     }
146
-    return implode(', ', $this->TagLink);
147
-  }
148
 
160
 
149
-  /**
150
-   * Format a list of top tags
151
-   * @param int $Max Max number of items to get
152
-   * @param string $Link  Page query where more items of this tag type can be found
153
-   * @param string $ArtistName Optional artist
154
-   */
155
-  public static function format_top($Max = 5, $Link = 'torrents.php?taglist=', $ArtistName = '') {
156
-    if (empty(self::$All)) { ?>
157
-      <li>No torrent tags</li>
158
-<?
161
+    /**
162
+     * Format a list of top tags
163
+     * @param int $Max Max number of items to get
164
+     * @param string $Link  Page query where more items of this tag type can be found
165
+     * @param string $ArtistName Optional artist
166
+     */
167
+    public static function format_top($Max = 5, $Link = 'torrents.php?taglist=', $ArtistName = '')
168
+    {
169
+        if (empty(self::$All)) { ?>
170
+<li>No torrent tags</li>
171
+<?php
159
       return;
172
       return;
160
     }
173
     }
161
-    if (!empty($ArtistName)) {
162
-      $ArtistName = '&amp;artistname=' . urlencode($ArtistName) . '&amp;action=advanced&amp;searchsubmit=1';
163
-    }
164
-    foreach (array_slice(self::sorted(), 0, $Max) as $Tag => $Total) {
165
-      $Split = self::get_name_and_class($Tag);
166
-      $Name = $Split['name'];
167
-      $Class = $Split['class'];
168
-    ?>
169
-      <li><a class="<?=$Class?>" href="<?=$Link . display_str($Name) . $ArtistName?>"><?=display_str($Name)?></a> (<?=$Total?>)</li>
170
-<?    }
171
-  }
172
 
174
 
173
-  /**
174
-   * General purpose method to get all tag aliases from the DB
175
-   * @return array
176
-   */
177
-  public static function get_aliases() {
178
-    $TagAliases = G::$Cache->get_value('tag_aliases_search');
179
-    if ($TagAliases === false) {
180
-      G::$DB->query('
181
-      SELECT ID, BadTag, AliasTag
182
-      FROM tag_aliases
183
-      ORDER BY BadTag');
184
-      $TagAliases = G::$DB->to_array(false, MYSQLI_ASSOC, false);
185
-      // Unify tag aliases to be in_this_format as tags not in.this.format
186
-      array_walk_recursive($TagAliases, function(&$val) {
187
-        $val = preg_replace("/\./","_", $val);
188
-      });
189
-      // Clean up the array for smaller cache size
190
-      foreach ($TagAliases as &$TagAlias) {
191
-        foreach (array_keys($TagAlias) as $Key) {
192
-          if (is_numeric($Key)) {
193
-            unset($TagAlias[$Key]);
194
-          }
175
+        if (!empty($ArtistName)) {
176
+            $ArtistName = '&amp;artistname=' . urlencode($ArtistName) . '&amp;action=advanced&amp;searchsubmit=1';
195
         }
177
         }
196
-      }
197
-      G::$Cache->cache_value('tag_aliases_search', $TagAliases, 3600 * 24 * 7); // cache for 7 days
198
-    }
199
-    return $TagAliases;
200
-  }
201
 
178
 
202
-  /**
203
-   * Replace bad tags with tag aliases
204
-   * @param array $Tags Array with sub-arrays 'include' and 'exclude'
205
-   * @return array
206
-   */
207
-  public static function remove_aliases($Tags) {
208
-    $TagAliases = self::get_aliases();
179
+        foreach (array_slice(self::sorted(), 0, $Max) as $Tag => $Total) {
180
+            $Split = self::get_name_and_class($Tag);
181
+            $Name = $Split['name'];
182
+            $Class = $Split['class']; ?>
209
 
183
 
210
-    if (isset($Tags['include'])) {
211
-      $End = count($Tags['include']);
212
-      for ($i = 0; $i < $End; $i++) {
213
-        foreach ($TagAliases as $TagAlias) {
214
-          if ($Tags['include'][$i] === $TagAlias['BadTag']) {
215
-            $Tags['include'][$i] = $TagAlias['AliasTag'];
216
-            break;
217
-          }
184
+<li><a class="<?=$Class?>"
185
+    href="<?=$Link . display_str($Name) . $ArtistName?>"><?=display_str($Name)?></a> (<?=$Total?>)</li>
186
+<?php
218
         }
187
         }
219
-      }
220
-      // Only keep unique entries after unifying tag standard
221
-      $Tags['include'] = array_unique($Tags['include']);
222
     }
188
     }
223
 
189
 
224
-    if (isset($Tags['exclude'])) {
225
-      $End = count($Tags['exclude']);
226
-      for ($i = 0; $i < $End; $i++) {
227
-        foreach ($TagAliases as $TagAlias) {
228
-          if (substr($Tags['exclude'][$i], 1) === $TagAlias['BadTag']) {
229
-            $Tags['exclude'][$i] = '!'.$TagAlias['AliasTag'];
230
-            break;
231
-          }
190
+    /**
191
+     * General purpose method to get all tag aliases from the DB
192
+     * @return array
193
+     */
194
+    public static function get_aliases()
195
+    {
196
+        $TagAliases = G::$Cache->get_value('tag_aliases_search');
197
+        if ($TagAliases === false) {
198
+            G::$DB->query('
199
+            SELECT ID, BadTag, AliasTag
200
+            FROM tag_aliases
201
+              ORDER BY BadTag');
202
+      
203
+            $TagAliases = G::$DB->to_array(false, MYSQLI_ASSOC, false);
204
+            // Unify tag aliases to be in_this_format as tags not in.this.format
205
+            array_walk_recursive($TagAliases, function (&$val) {
206
+                $val = preg_replace("/\./", "_", $val);
207
+            });
208
+            // Clean up the array for smaller cache size
209
+            foreach ($TagAliases as &$TagAlias) {
210
+                foreach (array_keys($TagAlias) as $Key) {
211
+                    if (is_numeric($Key)) {
212
+                        unset($TagAlias[$Key]);
213
+                    }
214
+                }
215
+            }
216
+            G::$Cache->cache_value('tag_aliases_search', $TagAliases, 3600 * 24 * 7); // cache for 7 days
232
         }
217
         }
233
-      }
234
-      // Only keep unique entries after unifying tag standard
235
-      $Tags['exclude'] = array_unique($Tags['exclude']);
218
+        return $TagAliases;
236
     }
219
     }
237
 
220
 
238
-    return $Tags;
239
-  }
221
+    /**
222
+     * Replace bad tags with tag aliases
223
+     * @param array $Tags Array with sub-arrays 'include' and 'exclude'
224
+     * @return array
225
+     */
226
+    public static function remove_aliases($Tags)
227
+    {
228
+        $TagAliases = self::get_aliases();
240
 
229
 
241
-  /**
242
-   * Filters a list of include and exclude tags to be used in a Sphinx search
243
-   * @param array $Tags An array of tags with sub-arrays 'include' and 'exclude'
244
-   * @param integer $TagType Search for Any or All of these tags.
245
-   * @return array Array keys predicate and input
246
-   *               Predicate for a Sphinx 'taglist' query
247
-   *               Input contains clean, aliased tags. Use it in a form instead of the user submitted string
248
-   */
249
-  public static function tag_filter_sph($Tags, $TagType) {
250
-    $QueryParts = [];
251
-    $Tags = Tags::remove_aliases($Tags);
252
-    $TagList = str_replace('_', '.', implode(', ', array_merge($Tags['include'], $Tags['exclude'])));
230
+        if (isset($Tags['include'])) {
231
+            $End = count($Tags['include']);
232
+            for ($i = 0; $i < $End; $i++) {
233
+                foreach ($TagAliases as $TagAlias) {
234
+                    if ($Tags['include'][$i] === $TagAlias['BadTag']) {
235
+                        $Tags['include'][$i] = $TagAlias['AliasTag'];
236
+                        break;
237
+                    }
238
+                }
239
+            }
240
+            // Only keep unique entries after unifying tag standard
241
+            $Tags['include'] = array_unique($Tags['include']);
242
+        }
253
 
243
 
254
-    foreach ($Tags['include'] as &$Tag) {
255
-      $Tag = Sphinxql::sph_escape_string($Tag);
244
+        if (isset($Tags['exclude'])) {
245
+            $End = count($Tags['exclude']);
246
+            for ($i = 0; $i < $End; $i++) {
247
+                foreach ($TagAliases as $TagAlias) {
248
+                    if (substr($Tags['exclude'][$i], 1) === $TagAlias['BadTag']) {
249
+                        $Tags['exclude'][$i] = '!'.$TagAlias['AliasTag'];
250
+                        break;
251
+                    }
252
+                }
253
+            }
254
+            // Only keep unique entries after unifying tag standard
255
+            $Tags['exclude'] = array_unique($Tags['exclude']);
256
+        }
257
+        return $Tags;
256
     }
258
     }
257
 
259
 
258
-    if (!empty($Tags['exclude'])) {
259
-      foreach ($Tags['exclude'] as &$Tag) {
260
-        $Tag = '!' . Sphinxql::sph_escape_string(substr($Tag, 1));
261
-      }
262
-    }
260
+    /**
261
+     * Filters a list of include and exclude tags to be used in a Sphinx search
262
+     * @param array $Tags An array of tags with sub-arrays 'include' and 'exclude'
263
+     * @param integer $TagType Search for Any or All of these tags.
264
+     * @return array Array keys predicate and input
265
+     *               Predicate for a Sphinx 'taglist' query
266
+     *               Input contains clean, aliased tags. Use it in a form instead of the user submitted string
267
+     */
268
+    public static function tag_filter_sph($Tags, $TagType)
269
+    {
270
+        $QueryParts = [];
271
+        $Tags = Tags::remove_aliases($Tags);
272
+        $TagList = str_replace('_', '.', implode(', ', array_merge($Tags['include'], $Tags['exclude'])));
263
 
273
 
264
-    // 'All' tags
265
-    if (!isset($TagType) || $TagType == 1) {
266
-      $SearchWords = array_merge($Tags['include'], $Tags['exclude']);
267
-      if (!empty($Tags)) {
268
-        $QueryParts[] = implode(' ', $SearchWords);
269
-      }
270
-    }
271
-    // 'Any' tags
272
-    else {
273
-      if (!empty($Tags['include'])) {
274
-        $QueryParts[] = '( ' . implode(' | ', $Tags['include']) . ' )';
275
-      }
276
-      if (!empty($Tags['exclude'])) {
277
-        $QueryParts[] = implode(' ', $Tags['exclude']);
278
-      }
279
-    }
274
+        foreach ($Tags['include'] as &$Tag) {
275
+            $Tag = Sphinxql::sph_escape_string($Tag);
276
+        }
280
 
277
 
281
-    return ['input' => $TagList, 'predicate' => implode(' ', $QueryParts)];
282
-  }
278
+        if (!empty($Tags['exclude'])) {
279
+            foreach ($Tags['exclude'] as &$Tag) {
280
+                $Tag = '!' . Sphinxql::sph_escape_string(substr($Tag, 1));
281
+            }
282
+        }
283
 
283
 
284
-  /**
285
-   * Breaks a tag down into name and namespace class
286
-   * @param string $Tag Tag of the form 'tag' or 'tag:namespace'
287
-   * @return array Array keys name and class
288
-   *               name is the name of the tag without a namespace
289
-   *               class is the HTML class that should be applied to the tag, empty string if the tag has no namespace
290
-   */
291
-   public static function get_name_and_class($Tag) {
292
-			$Name = $Tag;
293
-			$Class = "";
294
-			$Split = explode(':', $Tag);
295
-			if (count($Split) > 1 && in_array($Split[1], TAG_NAMESPACES)) {
296
-				$Name = $Split[0];
297
-				$Class = "tag_" . $Split[1];
298
-			}
299
-      return array("name" => display_str($Name), "class" => display_str($Class));
300
-   }
284
+        // 'All' tags
285
+        if (!isset($TagType) || $TagType == 1) {
286
+            $SearchWords = array_merge($Tags['include'], $Tags['exclude']);
287
+            if (!empty($Tags)) {
288
+                $QueryParts[] = implode(' ', $SearchWords);
289
+            }
290
+        }
291
+        // 'Any' tags
292
+        else {
293
+            if (!empty($Tags['include'])) {
294
+                $QueryParts[] = '( ' . implode(' | ', $Tags['include']) . ' )';
295
+            }
296
+            if (!empty($Tags['exclude'])) {
297
+                $QueryParts[] = implode(' ', $Tags['exclude']);
298
+            }
299
+        }
300
+
301
+        return ['input' => $TagList, 'predicate' => implode(' ', $QueryParts)];
302
+    }
303
+
304
+    /**
305
+     * Breaks a tag down into name and namespace class
306
+     * @param string $Tag Tag of the form 'tag' or 'tag:namespace'
307
+     * @return array Array keys name and class
308
+     *               name is the name of the tag without a namespace
309
+     *               class is the HTML class that should be applied to the tag, empty string if the tag has no namespace
310
+     */
311
+    public static function get_name_and_class($Tag)
312
+    {
313
+        $Name = $Tag;
314
+        $Class = "";
315
+        $Split = explode(':', $Tag);
316
+        
317
+        if (count($Split) > 1 && in_array($Split[1], TAG_NAMESPACES)) {
318
+            $Name = $Split[0];
319
+            $Class = "tag_" . $Split[1];
320
+        }
321
+        return array("name" => display_str($Name), "class" => display_str($Class));
322
+    }
301
 }
323
 }

+ 63
- 62
classes/templates.class.php View File

1
-<?
1
+<?php
2
+
2
 // Example :
3
 // Example :
3
 // $TPL = new TEMPLATE;
4
 // $TPL = new TEMPLATE;
4
 // $TPL->open('inv.tpl');
5
 // $TPL->open('inv.tpl');
5
 // $TPL->set('ADDRESS1', $TPL->str_align(57, $UADDRESS1, 'l', ' '));
6
 // $TPL->set('ADDRESS1', $TPL->str_align(57, $UADDRESS1, 'l', ' '));
6
 // $TPL->get();
7
 // $TPL->get();
7
 
8
 
8
-class TEMPLATE {
9
-  var $file = '';
10
-  var $vars = [];
11
-
12
-  function open($file) {
13
-    $this->file = file($file);
14
-  }
9
+class TEMPLATE
10
+{
11
+    public $file = '';
12
+    public $vars = [];
15
 
13
 
16
-  function set($name, $var, $ifnone = '<span style="font-style: italic;">-None-</span>') {
17
-    if ($name != '') {
18
-      $this->vars[$name][0] = $var;
19
-      $this->vars[$name][1] = $ifnone;
14
+    public function open($file)
15
+    {
16
+        $this->file = file($file);
20
     }
17
     }
21
-  }
22
 
18
 
23
-  function show() {
24
-    $TMPVAR = '';
25
-    for ($i = 0; $i < sizeof($this->file); $i++) {
26
-      $TMPVAR = $this->file[$i];
27
-      foreach ($this->vars as $k=>$v) {
28
-        if ($v[1] != '' && $v[0] == '') {
29
-          $v[0] = $v[1];
19
+    public function set($name, $var, $ifnone = '<span style="font-style: italic;">-None-</span>')
20
+    {
21
+        if ($name !== '') {
22
+            $this->vars[$name][0] = $var;
23
+            $this->vars[$name][1] = $ifnone;
30
         }
24
         }
31
-        $TMPVAR = str_replace('{{'.$k.'}}', $v[0], $TMPVAR);
32
-      }
33
-      print $TMPVAR;
34
     }
25
     }
35
-  }
36
 
26
 
37
-  function get() {
38
-    $RESULT = '';
39
-    $TMPVAR = '';
40
-    for ($i = 0; $i < sizeof($this->file); $i++) {
41
-      $TMPVAR = $this->file[$i];
42
-      foreach ($this->vars as $k=>$v) {
43
-        if ($v[1] != '' && $v[0] == '') {
44
-          $v[0] = $v[1];
27
+    public function show()
28
+    {
29
+        $TMPVAR = '';
30
+        for ($i = 0; $i < sizeof($this->file); $i++) {
31
+            $TMPVAR = $this->file[$i];
32
+            foreach ($this->vars as $k=>$v) {
33
+                if ($v[1] !== '' && $v[0] === '') {
34
+                    $v[0] = $v[1];
35
+                }
36
+                $TMPVAR = str_replace('{{'.$k.'}}', $v[0], $TMPVAR);
37
+            }
38
+            print $TMPVAR;
45
         }
39
         }
46
-        $TMPVAR = str_replace('{{'.$k.'}}', $v[0], $TMPVAR);
47
-      }
48
-      $RESULT.= $TMPVAR;
49
     }
40
     }
50
-    return $RESULT;
51
-  }
52
-
53
-  function str_align($len, $str, $align, $fill) {
54
-    $strlen = strlen($str);
55
-    if ($strlen > $len) {
56
-      return substr($str, 0, $len);
57
-
58
-    } elseif (($strlen == 0) || ($len == 0)) {
59
-      return '';
60
 
41
 
61
-    } else {
62
-      if (($align == 'l') || ($align == 'left')) {
63
-        $result = $str.str_repeat($fill, ($len - $strlen));
64
-
65
-      } elseif (($align == 'r') || ($align == 'right')) {
66
-        $result = str_repeat($fill, ($len - $strlen)).$str;
67
-
68
-      } elseif (($align == 'c') || ($align == 'center')) {
69
-        $snm = intval(($len - $strlen) / 2);
70
-        if (($strlen + ($snm * 2)) == $len) {
71
-          $result = str_repeat($fill, $snm).$str;
42
+    public function get()
43
+    {
44
+        $RESULT = '';
45
+        $TMPVAR = '';
46
+        for ($i = 0; $i < sizeof($this->file); $i++) {
47
+            $TMPVAR = $this->file[$i];
48
+            foreach ($this->vars as $k=>$v) {
49
+                if ($v[1] !== '' && $v[0] === '') {
50
+                    $v[0] = $v[1];
51
+                }
52
+                $TMPVAR = str_replace('{{'.$k.'}}', $v[0], $TMPVAR);
53
+            }
54
+            $RESULT.= $TMPVAR;
55
+        }
56
+        return $RESULT;
57
+    }
72
 
58
 
59
+    public function str_align($len, $str, $align, $fill)
60
+    {
61
+        $strlen = strlen($str);
62
+        if ($strlen > $len) {
63
+            return substr($str, 0, $len);
64
+        } elseif (($strlen === 0) || ($len === 0)) {
65
+            return '';
73
         } else {
66
         } else {
74
-          $result = str_repeat($fill, $snm + 1).$str;
67
+            if (($align === 'l') || ($align === 'left')) {
68
+                $result = $str.str_repeat($fill, ($len - $strlen));
69
+            } elseif (($align === 'r') || ($align === 'right')) {
70
+                $result = str_repeat($fill, ($len - $strlen)).$str;
71
+            } elseif (($align === 'c') || ($align === 'center')) {
72
+                $snm = intval(($len - $strlen) / 2);
73
+                if (($strlen + ($snm * 2)) === $len) {
74
+                    $result = str_repeat($fill, $snm).$str;
75
+                } else {
76
+                    $result = str_repeat($fill, $snm + 1).$str;
77
+                }
78
+                $result.= str_repeat($fill, $snm);
79
+            }
80
+            return $result;
75
         }
81
         }
76
-        $result.= str_repeat($fill, $snm);
77
-      }
78
-      return $result;
79
     }
82
     }
80
-  }
81
 }
83
 }
82
-?>

+ 160
- 141
classes/testing.class.php View File

1
-<?
2
-
3
-class Testing {
4
-  private static $ClassDirectories = array("classes");
5
-  private static $Classes = [];
6
-
7
-  /**
8
-   * Initialize the testasble classes into a map keyed by class name
9
-   */
10
-  public static function init() {
11
-    self::load_classes();
12
-  }
13
-
14
-  /**
15
-   * Gets the class
16
-   */
17
-  public static function get_classes() {
18
-    return self::$Classes;
19
-  }
20
-
21
-  /**
22
-   * Loads all the classes within given directories
23
-   */
24
-  private static function load_classes() {
25
-    foreach (self::$ClassDirectories as $Directory)  {
26
-      $Directory = SERVER_ROOT . "/" . $Directory . "/";
27
-      foreach (glob($Directory . "*.php") as $FileName) {
28
-        self::get_class_name($FileName);
29
-      }
1
+<?php
2
+
3
+class Testing
4
+{
5
+    private static $ClassDirectories = array("classes");
6
+    private static $Classes = [];
7
+
8
+    /**
9
+     * Initialize the testasble classes into a map keyed by class name
10
+     */
11
+    public static function init()
12
+    {
13
+        self::load_classes();
30
     }
14
     }
31
-  }
32
-
33
-  /**
34
-   * Gets the class and adds into the map
35
-   */
36
-  private static function get_class_name($FileName) {
37
-    $Tokens = token_get_all(file_get_contents($FileName));
38
-    $IsTestable = false;
39
-    $IsClass = false;
40
-
41
-    foreach ($Tokens as $Token) {
42
-      if (is_array($Token)) {
43
-        if (!$IsTestable && $Token[0] == T_DOC_COMMENT && strpos($Token[1], "@TestClass")) {
44
-          $IsTestable = true;
15
+
16
+    /**
17
+     * Gets the class
18
+     */
19
+    public static function get_classes()
20
+    {
21
+        return self::$Classes;
22
+    }
23
+
24
+    /**
25
+     * Loads all the classes within given directories
26
+     */
27
+    private static function load_classes()
28
+    {
29
+        foreach (self::$ClassDirectories as $Directory) {
30
+            $Directory = SERVER_ROOT . "/" . $Directory . "/";
31
+            foreach (glob($Directory . "*.php") as $FileName) {
32
+                self::get_class_name($FileName);
33
+            }
34
+        }
35
+    }
36
+
37
+    /**
38
+     * Gets the class and adds into the map
39
+     */
40
+    private static function get_class_name($FileName)
41
+    {
42
+        $Tokens = token_get_all(file_get_contents($FileName));
43
+        $IsTestable = false;
44
+        $IsClass = false;
45
+
46
+        foreach ($Tokens as $Token) {
47
+            if (is_array($Token)) {
48
+                if (!$IsTestable && $Token[0] == T_DOC_COMMENT && strpos($Token[1], "@TestClass")) {
49
+                    $IsTestable = true;
50
+                }
51
+
52
+                if ($IsTestable && $Token[0] == T_CLASS) {
53
+                    $IsClass = true;
54
+                } elseif ($IsClass && $Token[0] == T_STRING) {
55
+                    $ReflectionClass = new ReflectionClass($Token[1]);
56
+
57
+                    if (count(self::get_testable_methods($ReflectionClass))) {
58
+                        self::$Classes[$Token[1]] = new ReflectionClass($Token[1]);
59
+                    }
60
+
61
+                    $IsTestable = false;
62
+                    $IsClass = false;
63
+                }
64
+            }
65
+        }
66
+    }
67
+
68
+    /**
69
+     * Checks if class exists in the map
70
+     */
71
+    public static function has_class($Class)
72
+    {
73
+        return array_key_exists($Class, self::$Classes);
74
+    }
75
+
76
+    /**
77
+     * Checks if class has a given testable methood
78
+     */
79
+    public static function has_testable_method($Class, $Method)
80
+    {
81
+        $TestableMethods = self::get_testable_methods($Class);
82
+        foreach ($TestableMethods as $TestMethod) {
83
+            if ($TestMethod->getName() === $Method) {
84
+                return true;
85
+            }
86
+        }
87
+        return false;
88
+    }
89
+
90
+    /**
91
+     * Get testable methods in a class, a testable method has a @Test
92
+     */
93
+    public static function get_testable_methods($Class)
94
+    {
95
+        if (is_string($Class)) {
96
+            $ReflectionClass = self::$Classes[$Class];
97
+        } else {
98
+            $ReflectionClass = $Class;
45
         }
99
         }
46
-        if ($IsTestable && $Token[0] == T_CLASS) {
47
-          $IsClass = true;
48
-        } else if ($IsClass && $Token[0] == T_STRING) {
49
-          $ReflectionClass = new ReflectionClass($Token[1]);
50
-          if (count(self::get_testable_methods($ReflectionClass))) {
51
-            self::$Classes[$Token[1]] = new ReflectionClass($Token[1]);
52
-          }
53
-          $IsTestable = false;
54
-          $IsClass = false;
100
+
101
+        $ReflectionMethods = $ReflectionClass->getMethods();
102
+        $TestableMethods = [];
103
+
104
+        foreach ($ReflectionMethods as $Method) {
105
+            if ($Method->isPublic() && $Method->isStatic() && strpos($Method->getDocComment(), "@Test")) {
106
+                $TestableMethods[] = $Method;
107
+            }
55
         }
108
         }
56
-      }
109
+        return $TestableMethods;
57
     }
110
     }
58
-  }
59
-
60
-  /**
61
-   * Checks if class exists in the map
62
-   */
63
-  public static function has_class($Class) {
64
-    return array_key_exists($Class, self::$Classes);
65
-  }
66
-
67
-  /**
68
-   * Checks if class has a given testable methood
69
-   */
70
-  public static function has_testable_method($Class, $Method) {
71
-    $TestableMethods = self::get_testable_methods($Class);
72
-    foreach($TestableMethods as $TestMethod) {
73
-      if ($TestMethod->getName() === $Method) {
74
-        return true;
75
-      }
111
+
112
+
113
+    /**
114
+     * Get the class comment
115
+     */
116
+    public static function get_class_comment($Class)
117
+    {
118
+        $ReflectionClass = self::$Classes[$Class];
119
+        return trim(str_replace(array("@TestClass", "*", "/"), "", $ReflectionClass->getDocComment()));
76
     }
120
     }
77
-    return false;
78
-  }
79
-
80
-  /**
81
-   * Get testable methods in a class, a testable method has a @Test
82
-   */
83
-  public static function get_testable_methods($Class) {
84
-    if (is_string($Class)) {
85
-      $ReflectionClass = self::$Classes[$Class];
86
-    } else {
87
-      $ReflectionClass = $Class;
121
+
122
+    /**
123
+     * Get the undocumented methods in a class
124
+     */
125
+    public static function get_undocumented_methods($Class)
126
+    {
127
+        $ReflectionClass = self::$Classes[$Class];
128
+        $Methods = [];
129
+
130
+        foreach ($ReflectionClass->getMethods() as $Method) {
131
+            if (!$Method->getDocComment()) {
132
+                $Methods[] = $Method;
133
+            }
134
+        }
135
+        return $Methods;
88
     }
136
     }
89
-    $ReflectionMethods = $ReflectionClass->getMethods();
90
-    $TestableMethods = [];
91
-    foreach($ReflectionMethods as $Method) {
92
-      if ($Method->isPublic() && $Method->isStatic() && strpos($Method->getDocComment(), "@Test")) {
93
-        $TestableMethods[] = $Method;
94
-      }
137
+
138
+    /**
139
+     * Get the documented methods
140
+     */
141
+    public static function get_documented_methods($Class)
142
+    {
143
+        $ReflectionClass = self::$Classes[$Class];
144
+        $Methods = [];
145
+
146
+        foreach ($ReflectionClass->getMethods() as $Method) {
147
+            if ($Method->getDocComment()) {
148
+                $Methods[] = $Method;
149
+            }
150
+        }
151
+        return $Methods;
95
     }
152
     }
96
-    return $TestableMethods;
97
-  }
98
-
99
-
100
-  /**
101
-   * Get the class comment
102
-   */
103
-  public static function get_class_comment($Class) {
104
-    $ReflectionClass = self::$Classes[$Class];
105
-    return trim(str_replace(array("@TestClass", "*", "/"), "", $ReflectionClass->getDocComment()));
106
-  }
107
-
108
-  /**
109
-   * Get the undocumented methods in a class
110
-   */
111
-  public static function get_undocumented_methods($Class) {
112
-    $ReflectionClass = self::$Classes[$Class];
113
-    $Methods = [];
114
-    foreach($ReflectionClass->getMethods() as $Method) {
115
-      if (!$Method->getDocComment()) {
116
-        $Methods[] = $Method;
117
-      }
153
+
154
+    /**
155
+     * Get all methods in a class
156
+     */
157
+    public static function get_methods($Class)
158
+    {
159
+        return self::$Classes[$Class]->getMethods();
118
     }
160
     }
119
-    return $Methods;
120
-  }
121
-
122
-  /**
123
-   * Get the documented methods
124
-   */
125
-  public static function get_documented_methods($Class)  {
126
-    $ReflectionClass = self::$Classes[$Class];
127
-    $Methods = [];
128
-    foreach($ReflectionClass->getMethods() as $Method) {
129
-      if ($Method->getDocComment()) {
130
-        $Methods[] = $Method;
131
-      }
161
+
162
+    /**
163
+     * Get a method  comment
164
+     */
165
+    public static function get_method_comment($Method)
166
+    {
167
+        return trim(str_replace(array("*", "/"), "", $Method->getDocComment()));
132
     }
168
     }
133
-    return $Methods;
134
-  }
135
-
136
-  /**
137
-   * Get all methods in a class
138
-   */
139
-  public static function get_methods($Class) {
140
-    return self::$Classes[$Class]->getMethods();
141
-  }
142
-
143
-  /**
144
-   * Get a method  comment
145
-   */
146
-  public static function get_method_comment($Method) {
147
-    return trim(str_replace(array("*", "/"), "", $Method->getDocComment()));
148
-  }
149
-
150
-}
169
+}

+ 169
- 162
classes/testingview.class.php View File

1
-<?
1
+<?php
2
 
2
 
3
-class TestingView {
4
-  /**
5
-   * Render the linkbox
6
-   */
7
-  public static function render_linkbox($Page) { ?>
8
-    <div class="linkbox">
9
-<?      if ($Page != "classes") { ?>
10
-        <a href="testing.php" class="brackets">Classes</a>
11
-<?      }
3
+class TestingView
4
+{
5
+    /**
6
+     * Render the linkbox
7
+     */
8
+    public static function render_linkbox($Page) { ?>
9
+<div class="linkbox">
10
+  <?php if ($Page != "classes") { ?>
11
+  <a href="testing.php" class="brackets">Classes</a>
12
+  <?php }
12
       if ($Page != "comments") { ?>
13
       if ($Page != "comments") { ?>
13
-        <a href="testing.php?action=comments" class="brackets">Comments</a>
14
-<?      } ?>
15
-    </div>
16
-<?  }
14
+  <a href="testing.php?action=comments" class="brackets">Comments</a>
15
+  <?php } ?>
16
+</div>
17
+<?php  }
17
 
18
 
18
-  /**
19
-   * Render a list of classes
20
-   */
21
-  public static function render_classes($Classes) { ?>
22
-    <table>
23
-      <tr class="colhead">
24
-        <td>
25
-          Class
26
-        </td>
27
-        <td>
28
-          Testable functions
29
-        </td>
30
-      </tr>
31
-<?      foreach($Classes as $Key => $Value) {
19
+    /**
20
+     * Render a list of classes
21
+     */
22
+    public static function render_classes($Classes) { ?>
23
+<table>
24
+  <tr class="colhead">
25
+    <td>
26
+      Class
27
+    </td>
28
+    <td>
29
+      Testable functions
30
+    </td>
31
+  </tr>
32
+  <?php foreach ($Classes as $Key => $Value) {
32
         $Doc = Testing::get_class_comment($Key);
33
         $Doc = Testing::get_class_comment($Key);
33
-        $Methods = count(Testing::get_testable_methods($Key));
34
-?>
35
-        <tr>
36
-          <td>
37
-            <a href="testing.php?action=class&amp;name=<?=$Key?>" class="tooltip" title="<?=$Doc?>"><?=$Key?></a>
38
-          </td>
39
-          <td>
40
-            <?=$Methods?>
41
-          </td>
42
-        </tr>
43
-<?      } ?>
44
-    </table>
45
-<?  }
34
+        $Methods = count(Testing::get_testable_methods($Key)); ?>
35
+  <tr>
36
+    <td>
37
+      <a href="testing.php?action=class&amp;name=<?=$Key?>"
38
+        class="tooltip" title="<?=$Doc?>"><?=$Key?></a>
39
+    </td>
40
+    <td>
41
+      <?=$Methods?>
42
+    </td>
43
+  </tr>
44
+  <?php
45
+    } ?>
46
+</table>
47
+<?php }
46
 
48
 
47
-  /**
48
-   * Render functions in a class
49
-   */
50
-  public static function render_functions($Methods) {
51
-    foreach($Methods as $Index => $Method) {
52
-      $ClassName = $Method->getDeclaringClass()->getName();
53
-      $MethodName = $Method->getName();
54
-?>
55
-      <div class="box box2">
56
-        <div class="head">
57
-          <span><?=self::render_method_definition($Method)?></span>
58
-          <span class="float_right">
59
-            <a data-toggle-target="#method_params_<?=$Index?>" class="brackets">Params</a>
60
-            <a href="#" class="brackets run" data-gazelle-id="<?=$Index?>" data-gazelle-class="<?=$ClassName?>" data-gazelle-method="<?=$MethodName?>">Run</a>
61
-          </span>
62
-        </div>
63
-        <div class="pad hidden" id="method_params_<?=$Index?>">
64
-          <?self::render_method_params($Method);?>
65
-        </div>
66
-        <div class="pad hidden" id="method_results_<?=$Index?>">
67
-        </div>
68
-      </div>
69
-<?    }
70
-  }
71
-
72
-  /**
73
-   * Render method parameters
74
-   */
75
-  private static function render_method_params($Method) { ?>
76
-    <table>
77
-<?    foreach($Method->getParameters() as $Parameter) {
78
-      $DefaultValue = $Parameter->isDefaultValueAvailable() ? $Parameter->getDefaultValue() : "";
79
-?>
80
-      <tr>
81
-        <td class="label">
82
-          <?=$Parameter->getName()?>
83
-        </td>
84
-        <td>
85
-          <input type="text" name="<?=$Parameter->getName()?>" value="<?=$DefaultValue?>"/>
86
-        </td>
87
-      </tr>
88
-<?    } ?>
89
-    </table>
90
-<?  }
49
+    /**
50
+     * Render functions in a class
51
+     */
52
+    public static function render_functions($Methods)
53
+    {
54
+        foreach ($Methods as $Index => $Method) {
55
+            $ClassName = $Method->getDeclaringClass()->getName();
56
+            $MethodName = $Method->getName(); ?>
57
+<div class="box box2">
58
+  <div class="head">
59
+    <span><?=self::render_method_definition($Method)?></span>
60
+    <span class="float_right">
61
+      <a data-toggle-target="#method_params_<?=$Index?>"
62
+        class="brackets">Params</a>
63
+      <a href="#" class="brackets run" data-gazelle-id="<?=$Index?>"
64
+        data-gazelle-class="<?=$ClassName?>"
65
+        data-gazelle-method="<?=$MethodName?>">Run</a>
66
+    </span>
67
+  </div>
68
+  <div class="pad hidden" id="method_params_<?=$Index?>">
69
+    <?self::render_method_params($Method); ?>
70
+  </div>
71
+  <div class="pad hidden" id="method_results_<?=$Index?>">
72
+  </div>
73
+</div>
74
+<?php
75
+        }
76
+    }
91
 
77
 
92
-  /**
93
-   * Render the method definition
94
-   */
95
-  private static function render_method_definition($Method) {
96
-    $Title = "<span class='tooltip' title='" . Testing::get_method_comment($Method) . "'>" . $Method->getName() . "</span> (";
97
-    foreach($Method->getParameters() as $Parameter) {
98
-      $Color = "red";
99
-      if ($Parameter->isDefaultValueAvailable()) {
100
-        $Color = "green";
101
-      }
102
-      $Title .= "<span style='color: $Color'>";
103
-      $Title .= "$" . $Parameter->getName();
104
-      if ($Parameter->isDefaultValueAvailable()) {
105
-        $Title .= " = " . $Parameter->getDefaultValue();
106
-      }
107
-      $Title .= "</span>";
108
-      $Title .= ", ";
78
+    /**
79
+     * Render method parameters
80
+     */
81
+    private static function render_method_params($Method) { ?>
82
+<table>
83
+  <?php foreach ($Method->getParameters() as $Parameter) {
84
+        $DefaultValue = $Parameter->isDefaultValueAvailable() ? $Parameter->getDefaultValue() : ""; ?>
85
+  <tr>
86
+    <td class="label">
87
+      <?=$Parameter->getName()?>
88
+    </td>
89
+    <td>
90
+      <input type="text" name="<?=$Parameter->getName()?>"
91
+        value="<?=$DefaultValue?>" />
92
+    </td>
93
+  </tr>
94
+  <?php
95
+    } ?>
96
+</table>
97
+<?php }
109
 
98
 
99
+    /**
100
+     * Render the method definition
101
+     */
102
+    private static function render_method_definition($Method)
103
+    {
104
+        $Title = "<span class='tooltip' title='" . Testing::get_method_comment($Method) . "'>" . $Method->getName() . "</span> (";
105
+        foreach ($Method->getParameters() as $Parameter) {
106
+            $Color = "red";
107
+            if ($Parameter->isDefaultValueAvailable()) {
108
+                $Color = "green";
109
+            }
110
+            $Title .= "<span style='color: $Color'>";
111
+            $Title .= "$" . $Parameter->getName();
112
+            if ($Parameter->isDefaultValueAvailable()) {
113
+                $Title .= " = " . $Parameter->getDefaultValue();
114
+            }
115
+            $Title .= "</span>";
116
+            $Title .= ", ";
117
+        }
118
+        $Title = rtrim($Title, ", ");
119
+        $Title .= ")";
120
+        return $Title;
110
     }
121
     }
111
-    $Title = rtrim($Title, ", ");
112
-    $Title .= ")";
113
-    return $Title;
114
-  }
115
 
122
 
116
-  /**
117
-   * Renders class documentation stats
118
-   */
119
-  public static function render_missing_documentation($Classes) { ?>
120
-    <table>
121
-      <tr class="colhead">
122
-        <td>
123
-          Class
124
-        </td>
125
-        <td>
126
-          Class documented
127
-        </td>
128
-        <td>
129
-          Undocumented functions
130
-        </td>
131
-        <td>
132
-          Documented functions
133
-        </td>
134
-      </tr>
135
-<?      foreach($Classes as $Key => $Value) {
136
-        $ClassComment = Testing::get_class_comment($Key);
137
-?>
138
-        <tr>
139
-          <td>
140
-            <?=$Key?>
141
-          </td>
142
-          <td>
143
-            <?=!empty($ClassComment) ? "Yes" : "No"?>
144
-          <td>
145
-            <?=count(Testing::get_undocumented_methods($Key))?>
146
-          </td>
147
-          <td>
148
-            <?=count(Testing::get_documented_methods($Key))?>
149
-          </td>
150
-        </tr>
151
-<?      } ?>
152
-    </table>
153
-<?  }
123
+    /**
124
+     * Renders class documentation stats
125
+     */
126
+    public static function render_missing_documentation($Classes) { ?>
127
+<table>
128
+  <tr class="colhead">
129
+    <td>
130
+      Class
131
+    </td>
132
+    <td>
133
+      Class documented
134
+    </td>
135
+    <td>
136
+      Undocumented functions
137
+    </td>
138
+    <td>
139
+      Documented functions
140
+    </td>
141
+  </tr>
142
+  <?php foreach ($Classes as $Key => $Value) {
143
+        $ClassComment = Testing::get_class_comment($Key); ?>
144
+  <tr>
145
+    <td>
146
+      <?=$Key?>
147
+    </td>
148
+    <td>
149
+      <?=!empty($ClassComment) ? "Yes" : "No"?>
150
+    <td>
151
+      <?=count(Testing::get_undocumented_methods($Key))?>
152
+    </td>
153
+    <td>
154
+      <?=count(Testing::get_documented_methods($Key))?>
155
+    </td>
156
+  </tr>
157
+  <?php
158
+    } ?>
159
+</table>
160
+<?php }
154
 
161
 
155
-  /**
156
-   * Pretty print any data
157
-   */
158
-  public static function render_results($Data) {
159
-    $Results = '<pre><ul style="list-style-type: none">';
160
-    if (is_array($Data)) {
161
-      foreach ($Data as $Key => $Value){
162
-        if (is_array($Value)){
163
-          $Results .= '<li>' . $Key . ' => ' . self::render_results($Value) . '</li>';
164
-        } else{
165
-          $Results .= '<li>' . $Key . ' => ' . $Value . '</li>';
162
+    /**
163
+     * Pretty print any data
164
+     */
165
+    public static function render_results($Data)
166
+    {
167
+        $Results = '<pre><ul style="list-style-type: none">';
168
+        if (is_array($Data)) {
169
+            foreach ($Data as $Key => $Value) {
170
+                if (is_array($Value)) {
171
+                    $Results .= '<li>' . $Key . ' => ' . self::render_results($Value) . '</li>';
172
+                } else {
173
+                    $Results .= '<li>' . $Key . ' => ' . $Value . '</li>';
174
+                }
175
+            }
176
+        } else {
177
+            $Results .= '<li>' . $Data . '</li>';
166
         }
178
         }
167
-      }
168
-    } else {
169
-      $Results .= '<li>' . $Data . '</li>';
179
+        $Results .= '</ul></pre>';
180
+        echo $Results;
170
     }
181
     }
171
-    $Results .= '</ul></pre>';
172
-    echo $Results;
173
-  }
174
-
175
 }
182
 }

+ 155
- 131
classes/time.class.php View File

1
-<?
1
+<?php
2
+
2
 if (!extension_loaded('date')) {
3
 if (!extension_loaded('date')) {
3
-  error('Date extension not loaded.');
4
+    error('Date extension not loaded.');
4
 }
5
 }
5
 
6
 
6
-function time_ago($TimeStamp) {
7
-  if (!$TimeStamp) { return false; }
8
-  if (!is_number($TimeStamp)) { // Assume that $TimeStamp is SQL timestamp
9
-    $TimeStamp = strtotime($TimeStamp);
10
-  }
11
-  return time() - $TimeStamp;
7
+function time_ago($TimeStamp)
8
+{
9
+    if (!$TimeStamp) {
10
+        return false;
11
+    }
12
+    if (!is_number($TimeStamp)) { // Assume that $TimeStamp is SQL timestamp
13
+        $TimeStamp = strtotime($TimeStamp);
14
+    }
15
+    return time() - $TimeStamp;
12
 }
16
 }
13
 
17
 
14
 /*
18
 /*
15
  * Returns a <span> by default but can optionally return the raw time
19
  * Returns a <span> by default but can optionally return the raw time
16
  * difference in text (e.g. "16 hours and 28 minutes", "1 day, 18 hours").
20
  * difference in text (e.g. "16 hours and 28 minutes", "1 day, 18 hours").
17
  */
21
  */
18
-function time_diff($TimeStamp, $Levels = 2, $Span = true, $Lowercase = false) {
19
-  if (!$TimeStamp) { return 'Never'; }
20
-  if (!is_number($TimeStamp)) { // Assume that $TimeStamp is SQL timestamp
21
-    $TimeStamp = strtotime($TimeStamp);
22
-  }
23
-  $Time = time() - $TimeStamp;
24
-
25
-  // If the time is negative, then it expires in the future.
26
-  if ($Time < 0) {
27
-    $Time = -$Time;
28
-    $HideAgo = true;
29
-  }
30
-
31
-  $Years = floor($Time / 31556926); // seconds in one year
32
-  $Remain = $Time - $Years * 31556926;
33
-
34
-  $Months = floor($Remain / 2629744); // seconds in one month
35
-  $Remain = $Remain - $Months * 2629744;
36
-
37
-  $Weeks = floor($Remain / 604800); // seconds in one week
38
-  $Remain = $Remain - $Weeks * 604800;
39
-
40
-  $Days = floor($Remain / 86400); // seconds in one day
41
-  $Remain = $Remain - $Days * 86400;
42
-
43
-  $Hours=floor($Remain / 3600); // seconds in one hour
44
-  $Remain = $Remain - $Hours * 3600;
45
-
46
-  $Minutes = floor($Remain / 60); // seconds in one minute
47
-  $Remain = $Remain - $Minutes * 60;
48
-
49
-  $Seconds = $Remain;
50
-
51
-  $Return = '';
52
-
53
-  if ($Years > 0 && $Levels > 0) {
54
-    $Return .= "$Years year".(($Years > 1) ? 's' : '' );
55
-    $Levels--;
56
-  }
57
-
58
-  if ($Months > 0 && $Levels > 0) {
59
-    $Return .= ($Return != '') ? ', ' : '';
60
-    $Return .= "$Months month".(($Months > 1) ? 's' : '');
61
-    $Levels--;
62
-  }
63
-
64
-  if ($Weeks > 0 && $Levels > 0) {
65
-    $Return .= ($Return != '') ? ', ' : '';
66
-    $Return .= "$Weeks week".(($Weeks > 1) ? 's' : '');
67
-    $Levels--;
68
-  }
69
-
70
-  if ($Days > 0 && $Levels > 0) {
71
-    $Return .= ($Return != '') ? ', ' : '';
72
-    $Return .= "$Days day".(($Days > 1) ? 's' : '');
73
-    $Levels--;
74
-  }
75
-
76
-  if ($Hours > 0 && $Levels > 0) {
77
-    $Return .= ($Return != '') ? ', ' : '';
78
-    $Return .= "$Hours hour".(($Hours > 1) ? 's' : '');
79
-    $Levels--;
80
-  }
81
-
82
-  if ($Minutes > 0 && $Levels > 0) {
83
-    $Return .= ($Return != '') ? ' and ' : '';
84
-    $Return .= "$Minutes min".(($Minutes > 1) ? 's' : '');
85
-  }
86
-
87
-  if ($Return == '') {
88
-    $Return = 'Just now';
89
-  } elseif (!isset($HideAgo)) {
90
-    $Return .= ' ago';
91
-  }
92
-
93
-  if ($Lowercase) {
94
-    $Return = strtolower($Return);
95
-  }
96
-
97
-  if ($Span) {
98
-    return '<span class="time tooltip" title="'.date('M d Y, H:i', $TimeStamp).'">'.$Return.'</span>';
99
-  } else {
100
-    return $Return;
101
-  }
22
+function time_diff($TimeStamp, $Levels = 2, $Span = true, $Lowercase = false)
23
+{
24
+    if (!$TimeStamp) {
25
+        return 'Never';
26
+    }
27
+    if (!is_number($TimeStamp)) { // Assume that $TimeStamp is SQL timestamp
28
+        $TimeStamp = strtotime($TimeStamp);
29
+    }
30
+    $Time = time() - $TimeStamp;
31
+
32
+    // If the time is negative, then it expires in the future.
33
+    if ($Time < 0) {
34
+        $Time = -$Time;
35
+        $HideAgo = true;
36
+    }
37
+
38
+    $Years = floor($Time / 31556926); // seconds in one year
39
+    $Remain = $Time - $Years * 31556926;
40
+
41
+    $Months = floor($Remain / 2629744); // seconds in one month
42
+    $Remain = $Remain - $Months * 2629744;
43
+
44
+    $Weeks = floor($Remain / 604800); // seconds in one week
45
+    $Remain = $Remain - $Weeks * 604800;
46
+
47
+    $Days = floor($Remain / 86400); // seconds in one day
48
+    $Remain = $Remain - $Days * 86400;
49
+
50
+    $Hours=floor($Remain / 3600); // seconds in one hour
51
+    $Remain = $Remain - $Hours * 3600;
52
+
53
+    $Minutes = floor($Remain / 60); // seconds in one minute
54
+    $Remain = $Remain - $Minutes * 60;
55
+
56
+    $Seconds = $Remain;
57
+
58
+    $Return = '';
59
+
60
+    if ($Years > 0 && $Levels > 0) {
61
+        $Return .= "$Years year".(($Years > 1) ? 's' : '');
62
+        $Levels--;
63
+    }
64
+
65
+    if ($Months > 0 && $Levels > 0) {
66
+        $Return .= ($Return != '') ? ', ' : '';
67
+        $Return .= "$Months month".(($Months > 1) ? 's' : '');
68
+        $Levels--;
69
+    }
70
+
71
+    if ($Weeks > 0 && $Levels > 0) {
72
+        $Return .= ($Return != '') ? ', ' : '';
73
+        $Return .= "$Weeks week".(($Weeks > 1) ? 's' : '');
74
+        $Levels--;
75
+    }
76
+
77
+    if ($Days > 0 && $Levels > 0) {
78
+        $Return .= ($Return != '') ? ', ' : '';
79
+        $Return .= "$Days day".(($Days > 1) ? 's' : '');
80
+        $Levels--;
81
+    }
82
+
83
+    if ($Hours > 0 && $Levels > 0) {
84
+        $Return .= ($Return != '') ? ', ' : '';
85
+        $Return .= "$Hours hour".(($Hours > 1) ? 's' : '');
86
+        $Levels--;
87
+    }
88
+
89
+    if ($Minutes > 0 && $Levels > 0) {
90
+        $Return .= ($Return != '') ? ' and ' : '';
91
+        $Return .= "$Minutes min".(($Minutes > 1) ? 's' : '');
92
+    }
93
+
94
+    if ($Return == '') {
95
+        $Return = 'Just now';
96
+    } elseif (!isset($HideAgo)) {
97
+        $Return .= ' ago';
98
+    }
99
+
100
+    if ($Lowercase) {
101
+        $Return = strtolower($Return);
102
+    }
103
+
104
+    if ($Span) {
105
+        return '<span class="time tooltip" title="'.date('M d Y, H:i', $TimeStamp).'">'.$Return.'</span>';
106
+    } else {
107
+        return $Return;
108
+    }
102
 }
109
 }
103
 
110
 
104
 /* SQL utility functions */
111
 /* SQL utility functions */
105
 
112
 
106
-function time_plus($Offset) {
107
-  return date('Y-m-d H:i:s', time() + $Offset);
113
+function time_plus($Offset)
114
+{
115
+    return date('Y-m-d H:i:s', time() + $Offset);
108
 }
116
 }
109
 
117
 
110
-function time_minus($Offset, $Fuzzy = false) {
111
-  if ($Fuzzy) {
112
-    return date('Y-m-d 00:00:00', time() - $Offset);
113
-  } else {
114
-    return date('Y-m-d H:i:s', time() - $Offset);
115
-  }
118
+function time_minus($Offset, $Fuzzy = false)
119
+{
120
+    if ($Fuzzy) {
121
+        return date('Y-m-d 00:00:00', time() - $Offset);
122
+    } else {
123
+        return date('Y-m-d H:i:s', time() - $Offset);
124
+    }
116
 }
125
 }
117
 
126
 
118
 // This is never used anywhere with $timestamp set
127
 // This is never used anywhere with $timestamp set
119
 // todo: Why don't we just use NOW() in the sql queries?
128
 // todo: Why don't we just use NOW() in the sql queries?
120
-function sqltime($timestamp = NULL) {
121
-  return date('Y-m-d H:i:s', ($timestamp ?? time()));
129
+function sqltime($timestamp = null)
130
+{
131
+    return date('Y-m-d H:i:s', ($timestamp ?? time()));
122
 }
132
 }
123
 
133
 
124
-function validDate($DateString) {
125
-  $DateTime = explode(' ', $DateString);
126
-  if (count($DateTime) != 2) {
127
-    return false;
128
-  }
129
-  list($Date, $Time) = $DateTime;
130
-  $SplitTime = explode(':', $Time);
131
-  if (count($SplitTime) != 3) {
132
-    return false;
133
-  }
134
-  list($H, $M, $S) = $SplitTime;
135
-  if ($H != 0 && !(is_number($H) && $H < 24 && $H >= 0)) { return false; }
136
-  if ($M != 0 && !(is_number($M) && $M < 60 && $M >= 0)) { return false; }
137
-  if ($S != 0 && !(is_number($S) && $S < 60 && $S >= 0)) { return false; }
138
-  $SplitDate = explode('-', $Date);
139
-  if (count($SplitDate) != 3) {
140
-    return false;
141
-  }
142
-  list($Y, $M, $D) = $SplitDate;
143
-  return checkDate($M, $D, $Y);
134
+function validDate($DateString)
135
+{
136
+    $DateTime = explode(' ', $DateString);
137
+    if (count($DateTime) != 2) {
138
+        return false;
139
+    }
140
+
141
+    list($Date, $Time) = $DateTime;
142
+    $SplitTime = explode(':', $Time);
143
+    if (count($SplitTime) != 3) {
144
+        return false;
145
+    }
146
+
147
+    list($H, $M, $S) = $SplitTime;
148
+    if ($H != 0 && !(is_number($H) && $H < 24 && $H >= 0)) {
149
+        return false;
150
+    }
151
+
152
+    if ($M != 0 && !(is_number($M) && $M < 60 && $M >= 0)) {
153
+        return false;
154
+    }
155
+
156
+    if ($S != 0 && !(is_number($S) && $S < 60 && $S >= 0)) {
157
+        return false;
158
+    }
159
+
160
+    $SplitDate = explode('-', $Date);
161
+    if (count($SplitDate) != 3) {
162
+        return false;
163
+    }
164
+
165
+    list($Y, $M, $D) = $SplitDate;
166
+    return checkDate($M, $D, $Y);
144
 }
167
 }
145
 
168
 
146
-function is_valid_date($Date) {
147
-  return is_valid_datetime($Date, 'Y-m-d');
169
+function is_valid_date($Date)
170
+{
171
+    return is_valid_datetime($Date, 'Y-m-d');
148
 }
172
 }
149
 
173
 
150
-function is_valid_time($Time) {
151
-  return is_valid_datetime($Time, 'H:i');
174
+function is_valid_time($Time)
175
+{
176
+    return is_valid_datetime($Time, 'H:i');
152
 }
177
 }
153
 
178
 
154
-function is_valid_datetime($DateTime, $Format = 'Y-m-d H:i') {
155
-  $FormattedDateTime = DateTime::createFromFormat($Format, $DateTime);
156
-  return $FormattedDateTime && $FormattedDateTime->format($Format) == $DateTime;
179
+function is_valid_datetime($DateTime, $Format = 'Y-m-d H:i')
180
+{
181
+    $FormattedDateTime = DateTime::createFromFormat($Format, $DateTime);
182
+    return $FormattedDateTime && $FormattedDateTime->format($Format) == $DateTime;
157
 }
183
 }
158
-
159
-?>

+ 323
- 289
classes/tools.class.php View File

1
-<?
2
-class Tools {
3
-  /**
4
-   * Returns true if given IP is banned.
5
-   *
6
-   * @param string $IP
7
-   */
8
-  public static function site_ban_ip($IP) {
9
-    global $Debug;
10
-    $A = substr($IP, 0, strcspn($IP, '.:'));
11
-    $IPNum = Tools::ip_to_unsigned($IP);
12
-    $IPBans = G::$Cache->get_value('ip_bans_'.$A);
13
-    if (!is_array($IPBans)) {
14
-      $SQL = sprintf("
15
-        SELECT ID, FromIP, ToIP
16
-        FROM ip_bans
17
-        WHERE FromIP BETWEEN %d << 24 AND (%d << 24) - 1", $A, $A + 1);
18
-      $QueryID = G::$DB->get_query_id();
19
-      G::$DB->query($SQL);
20
-      $IPBans = G::$DB->to_array(0, MYSQLI_NUM);
21
-      G::$DB->set_query_id($QueryID);
22
-      G::$Cache->cache_value('ip_bans_'.$A, $IPBans, 0);
23
-    }
24
-    $Debug->log_var($IPBans, 'IP bans for class '.$A);
25
-    foreach ($IPBans as $Index => $IPBan) {
26
-      list ($ID, $FromIP, $ToIP) = $IPBan;
27
-      if ($IPNum >= $FromIP && $IPNum <= $ToIP) {
28
-        return true;
29
-      }
30
-    }
1
+<?php
31
 
2
 
32
-    return false;
33
-  }
34
-
35
-  /**
36
-   * Returns the unsigned form of an IP address.
37
-   *
38
-   * @param string $IP The IP address x.x.x.x
39
-   * @return string the long it represents.
40
-   */
41
-  public static function ip_to_unsigned($IP) {
42
-    $IPnum = sprintf('%u', ip2long($IP));
43
-    if (!$IPnum) {
44
-      // Try to encode as IPv6 (stolen from stackoverflow)
45
-      // Note that this is *wrong* and because of PHP's wankery stops being accurate after the most significant 16 digits or so
46
-      // But since this is only used for geolocation and IPv6 blocks are allocated in huge numbers, it's still fine
47
-      $IPnum = '';
48
-      foreach (unpack('C*', inet_pton($IP)) as $byte) {
49
-        $IPnum .= str_pad(decbin($byte), 8, "0", STR_PAD_LEFT);
50
-      }
51
-      $IPnum = base_convert(ltrim($IPnum, '0'), 2, 10);
52
-    }
53
-    return $IPnum;
54
-  }
55
-
56
-  /**
57
-   * Geolocate an IP address using the database
58
-   *
59
-   * @param $IP the ip to fetch the country for
60
-   * @return the country of origin
61
-   */
62
-  public static function geoip($IP) {
63
-    static $IPs = [];
64
-    if (isset($IPs[$IP])) {
65
-      return $IPs[$IP];
3
+# todo: Check strick equality gently
4
+class Tools
5
+{
6
+    /**
7
+     * Returns true if given IP is banned.
8
+     *
9
+     * @param string $IP
10
+     */
11
+    public static function site_ban_ip($IP)
12
+    {
13
+        global $Debug;
14
+        $A = substr($IP, 0, strcspn($IP, '.:'));
15
+        $IPNum = Tools::ip_to_unsigned($IP);
16
+        $IPBans = G::$Cache->get_value('ip_bans_'.$A);
17
+
18
+        if (!is_array($IPBans)) {
19
+            $SQL = sprintf("
20
+            SELECT ID, FromIP, ToIP
21
+            FROM ip_bans
22
+              WHERE FromIP BETWEEN %d << 24 AND (%d << 24) - 1", $A, $A + 1);
23
+
24
+            $QueryID = G::$DB->get_query_id();
25
+            G::$DB->query($SQL);
26
+            $IPBans = G::$DB->to_array(0, MYSQLI_NUM);
27
+            G::$DB->set_query_id($QueryID);
28
+            G::$Cache->cache_value('ip_bans_'.$A, $IPBans, 0);
29
+        }
30
+
31
+        $Debug->log_var($IPBans, 'IP bans for class '.$A);
32
+        foreach ($IPBans as $Index => $IPBan) {
33
+            list($ID, $FromIP, $ToIP) = $IPBan;
34
+            if ($IPNum >= $FromIP && $IPNum <= $ToIP) {
35
+                return true;
36
+            }
37
+        }
38
+        return false;
66
     }
39
     }
67
-    if (is_number($IP)) {
68
-      $Long = $IP;
69
-    } else {
70
-      $Long = Tools::ip_to_unsigned($IP);
40
+
41
+    /**
42
+     * Returns the unsigned form of an IP address.
43
+     *
44
+     * @param string $IP The IP address x.x.x.x
45
+     * @return string the long it represents.
46
+     */
47
+    public static function ip_to_unsigned($IP)
48
+    {
49
+        $IPnum = sprintf('%u', ip2long($IP));
50
+        if (!$IPnum) {
51
+            // Try to encode as IPv6 (stolen from stackoverflow)
52
+            // Note that this is *wrong* and because of PHP's wankery stops being accurate after the most significant 16 digits or so
53
+            // But since this is only used for geolocation and IPv6 blocks are allocated in huge numbers, it's still fine
54
+            $IPnum = '';
55
+            foreach (unpack('C*', inet_pton($IP)) as $byte) {
56
+                $IPnum .= str_pad(decbin($byte), 8, "0", STR_PAD_LEFT);
57
+            }
58
+            $IPnum = base_convert(ltrim($IPnum, '0'), 2, 10);
59
+        }
60
+        return $IPnum;
71
     }
61
     }
72
-    if (!$Long || $Long == 2130706433) { // No need to check cc for 127.0.0.1
73
-      return false;
62
+
63
+    /**
64
+     * Geolocate an IP address using the database
65
+     *
66
+     * @param $IP the ip to fetch the country for
67
+     * @return the country of origin
68
+     */
69
+    public static function geoip($IP)
70
+    {
71
+        static $IPs = [];
72
+        if (isset($IPs[$IP])) {
73
+            return $IPs[$IP];
74
+        }
75
+
76
+        if (is_number($IP)) {
77
+            $Long = $IP;
78
+        } else {
79
+            $Long = Tools::ip_to_unsigned($IP);
80
+        }
81
+
82
+        if (!$Long || $Long == 2130706433) { // No need to check cc for 127.0.0.1
83
+            return false;
84
+        }
85
+
86
+        $QueryID = G::$DB->get_query_id();
87
+        G::$DB->query("
88
+        SELECT EndIP, Code
89
+        FROM geoip_country
90
+          WHERE $Long >= StartIP
91
+          ORDER BY StartIP DESC
92
+          LIMIT 1");
93
+
94
+        if ((!list($EndIP, $Country) = G::$DB->next_record()) || $EndIP < $Long) {
95
+            $Country = '?';
96
+        }
97
+
98
+        G::$DB->set_query_id($QueryID);
99
+        $IPs[$IP] = $Country;
100
+        return $Country;
74
     }
101
     }
75
-    $QueryID = G::$DB->get_query_id();
76
-    G::$DB->query("
77
-      SELECT EndIP, Code
78
-      FROM geoip_country
79
-      WHERE $Long >= StartIP
80
-      ORDER BY StartIP DESC
81
-      LIMIT 1");
82
-    if ((!list($EndIP, $Country) = G::$DB->next_record()) || $EndIP < $Long) {
83
-      $Country = '?';
102
+
103
+    /**
104
+     * Gets the hostname for an IP address
105
+     *
106
+     * @param $IP the IP to get the hostname for
107
+     * @return hostname fetched
108
+     */
109
+    public static function get_host_by_ip($IP)
110
+    {
111
+        $testar = explode('.', $IP);
112
+        if (count($testar) != 4) {
113
+            return $IP;
114
+        }
115
+
116
+        for ($i = 0; $i < 4; ++$i) {
117
+            if (!is_numeric($testar[$i])) {
118
+                return $IP;
119
+            }
120
+        }
121
+
122
+        $host = `host -W 1 $IP`;
123
+        return ($host ? end(explode(' ', $host)) : $IP);
84
     }
124
     }
85
-    G::$DB->set_query_id($QueryID);
86
-    $IPs[$IP] = $Country;
87
-    return $Country;
88
-  }
89
-
90
-  /**
91
-   * Gets the hostname for an IP address
92
-   *
93
-   * @param $IP the IP to get the hostname for
94
-   * @return hostname fetched
95
-   */
96
-  public static function get_host_by_ip($IP) {
97
-    $testar = explode('.', $IP);
98
-    if (count($testar) != 4) {
99
-      return $IP;
125
+
126
+    /**
127
+     * Gets an hostname using AJAX
128
+     *
129
+     * @param $IP the IP to fetch
130
+     * @return a span with JavaScript code
131
+     */
132
+    public static function get_host_by_ajax($IP)
133
+    {
134
+        static $ID = 0;
135
+        ++$ID;
136
+        return '<span id="host_'.$ID.'">Resolving host...<script type="text/javascript">ajax.get(\'tools.php?action=get_host&ip='.$IP.'\',function(host) {$(\'#host_'.$ID.'\').raw().innerHTML=host;});</script></span>';
100
     }
137
     }
101
-    for ($i = 0; $i < 4; ++$i) {
102
-      if (!is_numeric($testar[$i])) {
103
-        return $IP;
104
-      }
138
+
139
+    /**
140
+     * Looks up the full host of an IP address, by system call.
141
+     * Used as the server-side counterpart to get_host_by_ajax.
142
+     *
143
+     * @param string $IP The IP address to look up.
144
+     * @return string the host.
145
+     */
146
+    public static function lookup_ip($IP)
147
+    {
148
+        // todo: Use the G::$Cache
149
+        $Output = explode(' ', shell_exec('host -W 1 '.escapeshellarg($IP)));
150
+        if (count($Output) == 1 && empty($Output[0])) {
151
+            return '';
152
+        }
153
+
154
+        if (count($Output) != 5) {
155
+            return false;
156
+        }
157
+
158
+        if ($Output[2].' '.$Output[3] == 'not found:') {
159
+            return false;
160
+        }
161
+        return trim($Output[4]);
105
     }
162
     }
106
 
163
 
107
-    $host = `host -W 1 $IP`;
108
-    return ($host ? end(explode(' ', $host)) : $IP);
109
-  }
110
-
111
-  /**
112
-   * Gets an hostname using AJAX
113
-   *
114
-   * @param $IP the IP to fetch
115
-   * @return a span with JavaScript code
116
-   */
117
-  public static function get_host_by_ajax($IP) {
118
-    static $ID = 0;
119
-    ++$ID;
120
-    return '<span id="host_'.$ID.'">Resolving host...<script type="text/javascript">ajax.get(\'tools.php?action=get_host&ip='.$IP.'\',function(host) {$(\'#host_'.$ID.'\').raw().innerHTML=host;});</script></span>';
121
-  }
122
-
123
-
124
-  /**
125
-   * Looks up the full host of an IP address, by system call.
126
-   * Used as the server-side counterpart to get_host_by_ajax.
127
-   *
128
-   * @param string $IP The IP address to look up.
129
-   * @return string the host.
130
-   */
131
-  public static function lookup_ip($IP) {
132
-    // todo: Use the G::$Cache
133
-    $Output = explode(' ',shell_exec('host -W 1 '.escapeshellarg($IP)));
134
-    if (count($Output) == 1 && empty($Output[0]))  { return ''; }
135
-    if (count($Output) != 5)                       { return false; }
136
-    if ($Output[2].' '.$Output[3] == 'not found:') { return false; }
137
-    return trim($Output[4]);
138
-  }
139
-
140
-  /**
141
-   * Format an IP address with links to IP history.
142
-   *
143
-   * @param string IP
144
-   * @return string The HTML
145
-   */
146
-  public static function display_ip($IP) {
147
-    $Line = display_str($IP).' ('.Tools::get_country_code_by_ajax($IP).') ';
148
-    $Line .= '<a href="user.php?action=search&amp;ip_history=on&amp;ip='.display_str($IP).'&amp;matchtype=strict" title="Search" class="brackets tooltip">S</a>';
149
-
150
-    return $Line;
151
-  }
152
-
153
-  public static function get_country_code_by_ajax($IP) {
154
-    static $ID = 0;
155
-    ++$ID;
156
-    return '<span id="cc_'.$ID.'">Resolving CC...<script type="text/javascript">ajax.get(\'tools.php?action=get_cc&ip='.$IP.'\', function(cc) {$(\'#cc_'.$ID.'\').raw().innerHTML = cc;});</script></span>';
157
-  }
158
-
159
-
160
-  /**
161
-   * Disable an array of users.
162
-   *
163
-   * @param array $UserIDs (You can also send it one ID as an int, because fuck types)
164
-   * @param BanReason 0 - Unknown, 1 - Manual, 2 - Ratio, 3 - Inactive, 4 - Unused.
165
-   */
166
-  public static function disable_users($UserIDs, $AdminComment, $BanReason = 1) {
167
-    $QueryID = G::$DB->get_query_id();
168
-    if (!is_array($UserIDs)) {
169
-      $UserIDs = array($UserIDs);
164
+    /**
165
+     * Format an IP address with links to IP history.
166
+     *
167
+     * @param string IP
168
+     * @return string The HTML
169
+     */
170
+    public static function display_ip($IP)
171
+    {
172
+        $Line = display_str($IP).' ('.Tools::get_country_code_by_ajax($IP).') ';
173
+        $Line .= '<a href="user.php?action=search&amp;ip_history=on&amp;ip='.display_str($IP).'&amp;matchtype=strict" title="Search" class="brackets tooltip">S</a>';
174
+        return $Line;
170
     }
175
     }
171
-    G::$DB->query("
172
-      UPDATE users_info AS i
173
-        JOIN users_main AS m ON m.ID = i.UserID
174
-      SET m.Enabled = '2',
175
-        m.can_leech = '0',
176
-        i.AdminComment = CONCAT('".sqltime()." - ".($AdminComment ? $AdminComment : 'Disabled by system')."\n\n', i.AdminComment),
177
-        i.BanDate = NOW(),
178
-        i.BanReason = '$BanReason',
179
-        i.RatioWatchDownload = ".($BanReason == 2 ? 'm.Downloaded' : "'0'")."
180
-      WHERE m.ID IN(".implode(',', $UserIDs).') ');
181
-    G::$Cache->decrement('stats_user_count', G::$DB->affected_rows());
182
-    foreach ($UserIDs as $UserID) {
183
-      G::$Cache->delete_value("enabled_$UserID");
184
-      G::$Cache->delete_value("user_info_$UserID");
185
-      G::$Cache->delete_value("user_info_heavy_$UserID");
186
-      G::$Cache->delete_value("user_stats_$UserID");
187
-
188
-      G::$DB->query("
189
-        SELECT SessionID
190
-        FROM users_sessions
191
-        WHERE UserID = '$UserID'
192
-          AND Active = 1");
193
-      while (list($SessionID) = G::$DB->next_record()) {
194
-        G::$Cache->delete_value("session_$UserID"."_$SessionID");
195
-      }
196
-      G::$Cache->delete_value("users_sessions_$UserID");
197
-
198
-      G::$DB->query("
199
-        DELETE FROM users_sessions
200
-        WHERE UserID = '$UserID'");
201
 
176
 
177
+    public static function get_country_code_by_ajax($IP)
178
+    {
179
+        static $ID = 0;
180
+        ++$ID;
181
+        return '<span id="cc_'.$ID.'">Resolving CC...<script type="text/javascript">ajax.get(\'tools.php?action=get_cc&ip='.$IP.'\', function(cc) {$(\'#cc_'.$ID.'\').raw().innerHTML = cc;});</script></span>';
202
     }
182
     }
203
 
183
 
204
-    // Remove the users from the tracker.
205
-    G::$DB->query('
206
-      SELECT torrent_pass
207
-      FROM users_main
208
-      WHERE ID in ('.implode(', ', $UserIDs).')');
209
-    $PassKeys = G::$DB->collect('torrent_pass');
210
-    $Concat = '';
211
-    foreach ($PassKeys as $PassKey) {
212
-      if (strlen($Concat) > 3950) { // Ocelot's read buffer is 4 KiB and anything exceeding it is truncated
184
+
185
+    /**
186
+     * Disable an array of users.
187
+     *
188
+     * @param array $UserIDs (You can also send it one ID as an int, because fuck types)
189
+     * @param BanReason 0 - Unknown, 1 - Manual, 2 - Ratio, 3 - Inactive, 4 - Unused.
190
+     */
191
+    public static function disable_users($UserIDs, $AdminComment, $BanReason = 1)
192
+    {
193
+        $QueryID = G::$DB->get_query_id();
194
+        if (!is_array($UserIDs)) {
195
+            $UserIDs = array($UserIDs);
196
+        }
197
+
198
+        G::$DB->query("
199
+        UPDATE users_info AS i
200
+          JOIN users_main AS m ON m.ID = i.UserID
201
+        SET m.Enabled = '2',
202
+          m.can_leech = '0',
203
+          i.AdminComment = CONCAT('".sqltime()." - ".($AdminComment ? $AdminComment : 'Disabled by system')."\n\n', i.AdminComment),
204
+          i.BanDate = NOW(),
205
+          i.BanReason = '$BanReason',
206
+          i.RatioWatchDownload = ".($BanReason == 2 ? 'm.Downloaded' : "'0'")."
207
+        WHERE m.ID IN(".implode(',', $UserIDs).') ');
208
+
209
+        G::$Cache->decrement('stats_user_count', G::$DB->affected_rows());
210
+        foreach ($UserIDs as $UserID) {
211
+            G::$Cache->delete_value("enabled_$UserID");
212
+            G::$Cache->delete_value("user_info_$UserID");
213
+            G::$Cache->delete_value("user_info_heavy_$UserID");
214
+            G::$Cache->delete_value("user_stats_$UserID");
215
+
216
+            G::$DB->query("
217
+            SELECT SessionID
218
+            FROM users_sessions
219
+              WHERE UserID = '$UserID'
220
+              AND Active = 1");
221
+
222
+            while (list($SessionID) = G::$DB->next_record()) {
223
+                G::$Cache->delete_value("session_$UserID"."_$SessionID");
224
+            }
225
+            G::$Cache->delete_value("users_sessions_$UserID");
226
+
227
+            G::$DB->query("
228
+            DELETE FROM users_sessions
229
+              WHERE UserID = '$UserID'");
230
+        }
231
+
232
+        // Remove the users from the tracker.
233
+        G::$DB->query('
234
+        SELECT torrent_pass
235
+        FROM users_main
236
+          WHERE ID in ('.implode(', ', $UserIDs).')');
237
+
238
+        $PassKeys = G::$DB->collect('torrent_pass');
239
+        $Concat = '';
240
+        foreach ($PassKeys as $PassKey) {
241
+            if (strlen($Concat) > 3950) { // Ocelot's read buffer is 4 KiB and anything exceeding it is truncated
242
+                Tracker::update_tracker('remove_users', array('passkeys' => $Concat));
243
+                $Concat = $PassKey;
244
+            } else {
245
+                $Concat .= $PassKey;
246
+            }
247
+        }
248
+
213
         Tracker::update_tracker('remove_users', array('passkeys' => $Concat));
249
         Tracker::update_tracker('remove_users', array('passkeys' => $Concat));
214
-        $Concat = $PassKey;
215
-      } else {
216
-        $Concat .= $PassKey;
217
-      }
250
+        G::$DB->set_query_id($QueryID);
218
     }
251
     }
219
-    Tracker::update_tracker('remove_users', array('passkeys' => $Concat));
220
-    G::$DB->set_query_id($QueryID);
221
-  }
222
-
223
-  /**
224
-   * Warn a user.
225
-   *
226
-   * @param int $UserID
227
-   * @param int $Duration length of warning in seconds
228
-   * @param string $reason
229
-   */
230
-  public static function warn_user($UserID, $Duration, $Reason) {
231
-    global $Time;
232
-
233
-    $QueryID = G::$DB->get_query_id();
234
-    G::$DB->query("
235
-      SELECT Warned
236
-      FROM users_info
237
-      WHERE UserID = $UserID
238
-        AND Warned IS NOT NULL");
239
-    if (G::$DB->has_results()) {
240
-      //User was already warned, appending new warning to old.
241
-      list($OldDate) = G::$DB->next_record();
242
-      $NewExpDate = date('Y-m-d H:i:s', strtotime($OldDate) + $Duration);
243
-
244
-      Misc::send_pm($UserID, 0,
245
-        'You have received multiple warnings.',
246
-        "When you received your latest warning (set to expire on ".date('Y-m-d', (time() + $Duration)).'), you already had a different warning (set to expire on '.date('Y-m-d', strtotime($OldDate)).").\n\n Due to this collision, your warning status will now expire at $NewExpDate.");
247
-
248
-      $AdminComment = date('Y-m-d')." - Warning (Clash) extended to expire at $NewExpDate by " . G::$LoggedUser['Username'] . "\nReason: $Reason\n\n";
249
-
250
-      G::$DB->query('
251
-        UPDATE users_info
252
-        SET
253
-          Warned = \''.db_string($NewExpDate).'\',
254
-          WarnedTimes = WarnedTimes + 1,
255
-          AdminComment = CONCAT(\''.db_string($AdminComment).'\', AdminComment)
256
-        WHERE UserID = \''.db_string($UserID).'\'');
257
-    } else {
258
-      //Not changing, user was not already warned
259
-      $WarnTime = time_plus($Duration);
260
-
261
-      G::$Cache->begin_transaction("user_info_$UserID");
262
-      G::$Cache->update_row(false, array('Warned' => $WarnTime));
263
-      G::$Cache->commit_transaction(0);
264
-
265
-      $AdminComment = date('Y-m-d')." - Warned until $WarnTime by " . G::$LoggedUser['Username'] . "\nReason: $Reason\n\n";
266
-
267
-      G::$DB->query('
252
+
253
+    /**
254
+     * Warn a user.
255
+     *
256
+     * @param int $UserID
257
+     * @param int $Duration length of warning in seconds
258
+     * @param string $reason
259
+     */
260
+    public static function warn_user($UserID, $Duration, $Reason)
261
+    {
262
+        global $Time;
263
+
264
+        $QueryID = G::$DB->get_query_id();
265
+        G::$DB->query("
266
+        SELECT Warned
267
+        FROM users_info
268
+          WHERE UserID = $UserID
269
+          AND Warned IS NOT NULL");
270
+          
271
+        if (G::$DB->has_results()) {
272
+            //User was already warned, appending new warning to old.
273
+            list($OldDate) = G::$DB->next_record();
274
+            $NewExpDate = date('Y-m-d H:i:s', strtotime($OldDate) + $Duration);
275
+
276
+            Misc::send_pm(
277
+                $UserID,
278
+                0,
279
+                'You have received multiple warnings.',
280
+                "When you received your latest warning (set to expire on ".date('Y-m-d', (time() + $Duration)).'), you already had a different warning (set to expire on '.date('Y-m-d', strtotime($OldDate)).").\n\n Due to this collision, your warning status will now expire at $NewExpDate."
281
+            );
282
+
283
+            $AdminComment = date('Y-m-d')." - Warning (Clash) extended to expire at $NewExpDate by " . G::$LoggedUser['Username'] . "\nReason: $Reason\n\n";
284
+
285
+            G::$DB->query('
286
+            UPDATE users_info
287
+            SET
288
+              Warned = \''.db_string($NewExpDate).'\',
289
+              WarnedTimes = WarnedTimes + 1,
290
+              AdminComment = CONCAT(\''.db_string($AdminComment).'\', AdminComment)
291
+              WHERE UserID = \''.db_string($UserID).'\'');
292
+        } else {
293
+            //Not changing, user was not already warned
294
+            $WarnTime = time_plus($Duration);
295
+
296
+            G::$Cache->begin_transaction("user_info_$UserID");
297
+            G::$Cache->update_row(false, array('Warned' => $WarnTime));
298
+            G::$Cache->commit_transaction(0);
299
+
300
+            $AdminComment = date('Y-m-d')." - Warned until $WarnTime by " . G::$LoggedUser['Username'] . "\nReason: $Reason\n\n";
301
+
302
+            G::$DB->query('
303
+            UPDATE users_info
304
+            SET
305
+              Warned = \''.db_string($WarnTime).'\',
306
+              WarnedTimes = WarnedTimes + 1,
307
+              AdminComment = CONCAT(\''.db_string($AdminComment).'\', AdminComment)
308
+              WHERE UserID = \''.db_string($UserID).'\'');
309
+        }
310
+        G::$DB->set_query_id($QueryID);
311
+    }
312
+
313
+    /**
314
+     * Update the notes of a user
315
+     * @param unknown $UserID ID of user
316
+     * @param unknown $AdminComment Comment to update with
317
+     */
318
+    public static function update_user_notes($UserID, $AdminComment)
319
+    {
320
+        $QueryID = G::$DB->get_query_id();
321
+        G::$DB->query('
268
         UPDATE users_info
322
         UPDATE users_info
269
-        SET
270
-          Warned = \''.db_string($WarnTime).'\',
271
-          WarnedTimes = WarnedTimes + 1,
272
-          AdminComment = CONCAT(\''.db_string($AdminComment).'\', AdminComment)
273
-        WHERE UserID = \''.db_string($UserID).'\'');
323
+        SET AdminComment = CONCAT(\''.db_string($AdminComment).'\', AdminComment)
324
+          WHERE UserID = \''.db_string($UserID).'\'');
325
+        G::$DB->set_query_id($QueryID);
274
     }
326
     }
275
-    G::$DB->set_query_id($QueryID);
276
-  }
277
-
278
-  /**
279
-   * Update the notes of a user
280
-   * @param unknown $UserID ID of user
281
-   * @param unknown $AdminComment Comment to update with
282
-   */
283
-  public static function update_user_notes($UserID, $AdminComment) {
284
-    $QueryID = G::$DB->get_query_id();
285
-    G::$DB->query('
286
-      UPDATE users_info
287
-      SET AdminComment = CONCAT(\''.db_string($AdminComment).'\', AdminComment)
288
-      WHERE UserID = \''.db_string($UserID).'\'');
289
-    G::$DB->set_query_id($QueryID);
290
-  }
291
-
292
-  /**
293
-  * Check if an IP address is part of a given CIDR range.
294
-  * @param string $CheckIP the IP address to be looked up
295
-  * @param string $Subnet the CIDR subnet to be checked against
296
-  */
297
-  public static function check_cidr_range($CheckIP, $Subnet) {
298
-    $IP = ip2long($CheckIP);
299
-    $CIDR = split('/', $Subnet);
300
-    $SubnetIP = ip2long($CIDR[0]);
301
-    $SubnetMaskBits = 32 - $CIDR[1];
302
-
303
-    return (($IP>>$SubnetMaskBits) == ($SubnetIP>>$SubnetMaskBits));
304
-  }
305
 
327
 
328
+    /**
329
+    * Check if an IP address is part of a given CIDR range.
330
+    * @param string $CheckIP the IP address to be looked up
331
+    * @param string $Subnet the CIDR subnet to be checked against
332
+    */
333
+    public static function check_cidr_range($CheckIP, $Subnet)
334
+    {
335
+        $IP = ip2long($CheckIP);
336
+        $CIDR = split('/', $Subnet);
337
+        $SubnetIP = ip2long($CIDR[0]);
338
+        $SubnetMaskBits = 32 - $CIDR[1];
339
+        return (($IP>>$SubnetMaskBits) == ($SubnetIP>>$SubnetMaskBits));
340
+    }
306
 }
341
 }
307
-?>

+ 100
- 89
classes/torrentsearch.class.php View File

9
 
9
 
10
     // Map of sort mode => attribute name for ungrouped torrent page
10
     // Map of sort mode => attribute name for ungrouped torrent page
11
     public static $SortOrders = [
11
     public static $SortOrders = [
12
-    'year' => 'year',
13
-    'time' => 'id',
14
-    'size' => 'size',
15
-    'seeders' => 'seeders',
16
-    'leechers' => 'leechers',
17
-    'snatched' => 'snatched',
18
-    'cataloguenumber' => 'cataloguenumber',
19
-    'random' => 1
20
-  ];
12
+        'year' => 'year',
13
+        'time' => 'id',
14
+        'size' => 'size',
15
+        'seeders' => 'seeders',
16
+        'leechers' => 'leechers',
17
+        'snatched' => 'snatched',
18
+        'cataloguenumber' => 'cataloguenumber',
19
+        'random' => 1
20
+    ];
21
 
21
 
22
     // Map of sort mode => attribute name for grouped torrent page
22
     // Map of sort mode => attribute name for grouped torrent page
23
     private static $SortOrdersGrouped = [
23
     private static $SortOrdersGrouped = [
24
-    'year' => 'year',
25
-    'time' => 'id',
26
-    'size' => 'maxsize',
27
-    'seeders' => 'sumseeders',
28
-    'leechers' => 'sumleechers',
29
-    'snatched' => 'sumsnatched',
30
-    'cataloguenumber' => 'cataloguenumber',
31
-    'random' => 1
32
-  ];
24
+        'year' => 'year',
25
+        'time' => 'id',
26
+        'size' => 'maxsize',
27
+        'seeders' => 'sumseeders',
28
+        'leechers' => 'sumleechers',
29
+        'snatched' => 'sumsnatched',
30
+        'cataloguenumber' => 'cataloguenumber',
31
+        'random' => 1
32
+    ];
33
 
33
 
34
     // Map of sort mode => aggregate expression required for some grouped sort orders
34
     // Map of sort mode => aggregate expression required for some grouped sort orders
35
     private static $AggregateExp = [
35
     private static $AggregateExp = [
36
-    'size' => 'MAX(size) AS maxsize',
37
-    'seeders' => 'SUM(seeders) AS sumseeders',
38
-    'leechers' => 'SUM(leechers) AS sumleechers',
39
-    'snatched' => 'SUM(snatched) AS sumsnatched'
40
-  ];
36
+        'size' => 'MAX(size) AS maxsize',
37
+        'seeders' => 'SUM(seeders) AS sumseeders',
38
+        'leechers' => 'SUM(leechers) AS sumleechers',
39
+        'snatched' => 'SUM(snatched) AS sumsnatched'
40
+    ];
41
 
41
 
42
     // Map of attribute name => global variable name with list of values that can be used for filtering
42
     // Map of attribute name => global variable name with list of values that can be used for filtering
43
     private static $Attributes = [
43
     private static $Attributes = [
44
-    'filter_cat' => false,
45
-    'releasetype' => 'ReleaseTypes',
46
-    'freetorrent' => false,
47
-    'censored' => false,
48
-    'size_unit' => false,
49
-    'year' => false
50
-  ];
44
+        'filter_cat' => false,
45
+        'releasetype' => 'ReleaseTypes',
46
+        'freetorrent' => false,
47
+        'censored' => false,
48
+        'size_unit' => false,
49
+        'year' => false
50
+    ];
51
 
51
 
52
     // List of fields that can be used for fulltext searches
52
     // List of fields that can be used for fulltext searches
53
     private static $Fields = [
53
     private static $Fields = [
54
-    'artistname' => 1, # Author
55
-    'audioformat' => 1, # Version
56
-    'cataloguenumber' => 1, # Accession Number
57
-    'numbers' => 1, # Combined ↑
58
-    'codec' => 1, # License
59
-    'container' => 1, # Format
60
-    'archive' => 0, # todo
61
-    'description' => 1, # Not group desc
62
-    'dlsiteid' => 1,
63
-    'filelist' => 1,
64
-    'groupname' => 1, # Title
65
-    'groupnamerj' => 1, # Organism
66
-    'groupnamejp' => 1, # Strain
67
-    'advgroupname' => 1,
68
-    'language' => 1,
69
-    'media' => 1, # Platform
70
-    'resolution' => 1, # Assembly Level
71
-    'searchstr' => 1,
72
-    'series' => 1, # Location
73
-    'studio' => 1, # Department/Lab
74
-    'location' => 1, # Combined ↑
75
-    'subber' => 1,
76
-    'subbing' => 1,
77
-    'taglist' => 1
54
+        'artistname' => 1, # Author
55
+        'audioformat' => 1, # Version
56
+        'cataloguenumber' => 1, # Accession Number
57
+        'numbers' => 1, # Combined ↑
58
+        'codec' => 1, # License
59
+        'container' => 1, # Format
60
+        'archive' => 0, # todo
61
+        'description' => 1, # Not group desc
62
+        'dlsiteid' => 1,
63
+        'filelist' => 1,
64
+        'groupname' => 1, # Title
65
+        'groupnamerj' => 1, # Organism
66
+        'groupnamejp' => 1, # Strain
67
+        'advgroupname' => 1,
68
+        'language' => 1,
69
+        'media' => 1, # Platform
70
+        'resolution' => 1, # Assembly Level
71
+        'searchstr' => 1,
72
+        'series' => 1, # Location
73
+        'studio' => 1, # Department/Lab
74
+        'location' => 1, # Combined ↑
75
+        'subber' => 1,
76
+        'subbing' => 1,
77
+        'taglist' => 1
78
   ];
78
   ];
79
 
79
 
80
     // List of torrent-specific fields that can be used for filtering
80
     // List of torrent-specific fields that can be used for filtering
81
     private static $TorrentFields = [
81
     private static $TorrentFields = [
82
-    'description' => 1,
83
-    'encoding' => 1,
84
-    'censored' => 1,
85
-    'language' => 1,
86
-    'filelist' => 1,
87
-    'format' => 1,
88
-    'media' => 1
82
+        'description' => 1,
83
+        'encoding' => 1,
84
+        'censored' => 1,
85
+        'language' => 1,
86
+        'filelist' => 1,
87
+        'format' => 1,
88
+        'media' => 1
89
   ];
89
   ];
90
 
90
 
91
     // Some form field names don't match the ones in the index
91
     // Some form field names don't match the ones in the index
101
 
101
 
102
     // Specify the operator type to use for fields. Empty key sets the default
102
     // Specify the operator type to use for fields. Empty key sets the default
103
     private static $FieldOperators = [
103
     private static $FieldOperators = [
104
-    '' => self::SPH_BOOL_AND,
105
-    'encoding' => self::SPH_BOOL_OR,
106
-    'format' => self::SPH_BOOL_OR,
107
-    'media' => self::SPH_BOOL_OR
108
-  ];
104
+        '' => self::SPH_BOOL_AND,
105
+        'encoding' => self::SPH_BOOL_OR,
106
+        'format' => self::SPH_BOOL_OR,
107
+        'media' => self::SPH_BOOL_OR
108
+    ];
109
 
109
 
110
     // Specify the separator character to use for fields. Empty key sets the default
110
     // Specify the separator character to use for fields. Empty key sets the default
111
     private static $FieldSeparators = [
111
     private static $FieldSeparators = [
112
-    '' => ' ',
113
-    'encoding' => '|',
114
-    'format' => '|',
115
-    'media' => '|',
116
-    'taglist' => ','
117
-  ];
112
+        '' => ' ',
113
+        'encoding' => '|',
114
+        'format' => '|',
115
+        'media' => '|',
116
+        'taglist' => ','
117
+    ];
118
 
118
 
119
     // Primary SphinxqlQuery object used to get group IDs or torrent IDs for ungrouped searches
119
     // Primary SphinxqlQuery object used to get group IDs or torrent IDs for ungrouped searches
120
     private $SphQL;
120
     private $SphQL;
173
             $Debug->analysis('Bad arguments in TorrentSearch constructor', $ErrMsg, 3600*24);
173
             $Debug->analysis('Bad arguments in TorrentSearch constructor', $ErrMsg, 3600*24);
174
             error('-1');
174
             error('-1');
175
         }
175
         }
176
+
176
         if (!is_number($Page) || $Page < 1) {
177
         if (!is_number($Page) || $Page < 1) {
177
             $Page = 1;
178
             $Page = 1;
178
         }
179
         }
180
+
179
         if (check_perms('site_search_many')) {
181
         if (check_perms('site_search_many')) {
180
             $this->Page = $Page;
182
             $this->Page = $Page;
181
         } else {
183
         } else {
182
             $this->Page = min($Page, SPHINX_MAX_MATCHES / $PageSize);
184
             $this->Page = min($Page, SPHINX_MAX_MATCHES / $PageSize);
183
         }
185
         }
186
+
184
         $ResultLimit = $PageSize;
187
         $ResultLimit = $PageSize;
185
         $this->PageSize = $PageSize;
188
         $this->PageSize = $PageSize;
186
         $this->GroupResults = $GroupResults;
189
         $this->GroupResults = $GroupResults;
187
         $this->SphQL = new SphinxqlQuery();
190
         $this->SphQL = new SphinxqlQuery();
188
         $this->SphQL->where_match('_all', 'fake', false);
191
         $this->SphQL->where_match('_all', 'fake', false);
192
+
189
         if ($OrderBy === 'random') {
193
         if ($OrderBy === 'random') {
190
             $this->SphQL->select('id, groupid')
194
             $this->SphQL->select('id, groupid')
191
         ->order_by('RAND()', '');
195
         ->order_by('RAND()', '');
208
             $this->SphQL->select('id, groupid')
212
             $this->SphQL->select('id, groupid')
209
         ->order_by(self::$SortOrders[$OrderBy], $OrderWay);
213
         ->order_by(self::$SortOrders[$OrderBy], $OrderWay);
210
         }
214
         }
215
+
211
         $Offset = ($this->Page - 1) * $ResultLimit;
216
         $Offset = ($this->Page - 1) * $ResultLimit;
212
         $MinMax = G::$Cache->get_value('sphinx_min_max_matches');
217
         $MinMax = G::$Cache->get_value('sphinx_min_max_matches');
213
         $MaxMatches = max($Offset + $ResultLimit, $MinMax ? $MinMax : 1000); # todo: Keep an eye on this
218
         $MaxMatches = max($Offset + $ResultLimit, $MinMax ? $MinMax : 1000); # todo: Keep an eye on this
245
             $this->SphResults = false;
250
             $this->SphResults = false;
246
             return;
251
             return;
247
         }
252
         }
253
+
248
         if ($this->Random && $this->GroupResults) {
254
         if ($this->Random && $this->GroupResults) {
249
             $TotalCount = $SphQLResult->get_meta('total_found');
255
             $TotalCount = $SphQLResult->get_meta('total_found');
250
             $this->SphResults = $SphQLResult->collect('groupid');
256
             $this->SphResults = $SphQLResult->collect('groupid');
254
                 // Make sure we get $PageSize results, or all of them if there are less than $PageSize hits
260
                 // Make sure we get $PageSize results, or all of them if there are less than $PageSize hits
255
                 $this->SphQL->where('groupid', $GroupIDs, true);
261
                 $this->SphQL->where('groupid', $GroupIDs, true);
256
                 $SphQLResult = $this->SphQL->query();
262
                 $SphQLResult = $this->SphQL->query();
263
+
257
                 if (!$SphQLResult->has_results()) {
264
                 if (!$SphQLResult->has_results()) {
258
                     break;
265
                     break;
259
                 }
266
                 }
267
+
260
                 $this->SphResults += $SphQLResult->collect('groupid');
268
                 $this->SphResults += $SphQLResult->collect('groupid');
261
                 $GroupIDs = array_keys($this->SphResults);
269
                 $GroupIDs = array_keys($this->SphResults);
262
                 $GroupCount = count($GroupIDs);
270
                 $GroupCount = count($GroupIDs);
263
             }
271
             }
272
+
264
             if ($GroupCount > $this->PageSize) {
273
             if ($GroupCount > $this->PageSize) {
265
                 $this->SphResults = array_slice($this->SphResults, 0, $this->PageSize, true);
274
                 $this->SphResults = array_slice($this->SphResults, 0, $this->PageSize, true);
266
             }
275
             }
283
     {
292
     {
284
         foreach ($this->Terms as $Field => $Words) {
293
         foreach ($this->Terms as $Field => $Words) {
285
             $SearchString = '';
294
             $SearchString = '';
295
+
286
             if (isset(self::$FormsToFields[$Field])) {
296
             if (isset(self::$FormsToFields[$Field])) {
287
                 $Field = self::$FormsToFields[$Field];
297
                 $Field = self::$FormsToFields[$Field];
288
             }
298
             }
299
+
289
             $QueryParts = ['include' => [], 'exclude' => []];
300
             $QueryParts = ['include' => [], 'exclude' => []];
290
             if (!empty($Words['include'])) {
301
             if (!empty($Words['include'])) {
291
                 foreach ($Words['include'] as $Word) {
302
                 foreach ($Words['include'] as $Word) {
292
                     $QueryParts['include'][] = Sphinxql::sph_escape_string($Word);
303
                     $QueryParts['include'][] = Sphinxql::sph_escape_string($Word);
293
                 }
304
                 }
294
             }
305
             }
306
+
295
             if (!empty($Words['exclude'])) {
307
             if (!empty($Words['exclude'])) {
296
                 foreach ($Words['exclude'] as $Word) {
308
                 foreach ($Words['exclude'] as $Word) {
297
                     $QueryParts['exclude'][] = '!' . Sphinxql::sph_escape_string(substr($Word, 1));
309
                     $QueryParts['exclude'][] = '!' . Sphinxql::sph_escape_string(substr($Word, 1));
298
                 }
310
                 }
299
             }
311
             }
312
+
300
             if (!empty($QueryParts)) {
313
             if (!empty($QueryParts)) {
301
                 if (isset($Words['operator'])) {
314
                 if (isset($Words['operator'])) {
302
                     // Is the operator already specified?
315
                     // Is the operator already specified?
308
                     // Go for the default operator
321
                     // Go for the default operator
309
                     $Operator = self::$FieldOperators[''];
322
                     $Operator = self::$FieldOperators[''];
310
                 }
323
                 }
324
+
311
                 if (!empty($QueryParts['include'])) {
325
                 if (!empty($QueryParts['include'])) {
312
                     if ($Field === 'taglist') {
326
                     if ($Field === 'taglist') {
313
                         foreach ($QueryParts['include'] as $key => $Tag) {
327
                         foreach ($QueryParts['include'] as $key => $Tag) {
316
                     }
330
                     }
317
                     $SearchString .= '( ' . implode($Operator, $QueryParts['include']) . ' ) ';
331
                     $SearchString .= '( ' . implode($Operator, $QueryParts['include']) . ' ) ';
318
                 }
332
                 }
333
+
319
                 if (!empty($QueryParts['exclude'])) {
334
                 if (!empty($QueryParts['exclude'])) {
320
                     $SearchString .= implode(' ', $QueryParts['exclude']);
335
                     $SearchString .= implode(' ', $QueryParts['exclude']);
321
                 }
336
                 }
337
+
322
                 $this->SphQL->where_match($SearchString, $Field, false);
338
                 $this->SphQL->where_match($SearchString, $Field, false);
323
                 if (isset(self::$TorrentFields[$Field])) {
339
                 if (isset(self::$TorrentFields[$Field])) {
324
                     $this->UsedTorrentFields[$Field] = $SearchString;
340
                     $this->UsedTorrentFields[$Field] = $SearchString;
420
         if ($Term === '') {
436
         if ($Term === '') {
421
             return;
437
             return;
422
         }
438
         }
439
+
423
         if ($Field === 'searchstr') {
440
         if ($Field === 'searchstr') {
424
             $this->search_basic($Term);
441
             $this->search_basic($Term);
425
         } elseif ($Field === 'filelist') {
442
         } elseif ($Field === 'filelist') {
442
             if (isset($this->RawTerms['tags_type']) && (int)$this->RawTerms['tags_type'] === self::TAGS_ANY) {
459
             if (isset($this->RawTerms['tags_type']) && (int)$this->RawTerms['tags_type'] === self::TAGS_ANY) {
443
                 $this->Terms['taglist']['operator'] = self::SPH_BOOL_OR;
460
                 $this->Terms['taglist']['operator'] = self::SPH_BOOL_OR;
444
             }
461
             }
462
+
445
             // Update the RawTerms array so get_terms() can return the corrected search terms
463
             // Update the RawTerms array so get_terms() can return the corrected search terms
446
             if (isset($this->Terms['taglist']['include'])) {
464
             if (isset($this->Terms['taglist']['include'])) {
447
                 $AllTags = $this->Terms['taglist']['include'];
465
                 $AllTags = $this->Terms['taglist']['include'];
448
             } else {
466
             } else {
449
                 $AllTags = [];
467
                 $AllTags = [];
450
             }
468
             }
469
+
451
             if (isset($this->Terms['taglist']['exclude'])) {
470
             if (isset($this->Terms['taglist']['exclude'])) {
452
                 $AllTags = array_merge($AllTags, $this->Terms['taglist']['exclude']);
471
                 $AllTags = array_merge($AllTags, $this->Terms['taglist']['exclude']);
453
             }
472
             }
476
               $this->add_word('format', $Word);
495
               $this->add_word('format', $Word);
477
             }
496
             }
478
             */
497
             */
498
+
479
             if (in_array($Word, $SearchMedia)) {
499
             if (in_array($Word, $SearchMedia)) {
480
                 $this->add_word('media', $Word);
500
                 $this->add_word('media', $Word);
481
             } else {
501
             } else {
555
         } else {
575
         } else {
556
             $Separator = self::$FieldSeparators[''];
576
             $Separator = self::$FieldSeparators[''];
557
         }
577
         }
578
+
558
         $Words = explode($Separator, $Term);
579
         $Words = explode($Separator, $Term);
559
         foreach ($Words as $Word) {
580
         foreach ($Words as $Word) {
560
             $this->add_word($Field, $Word);
581
             $this->add_word($Field, $Word);
574
         if ($Word === '' || $Word === '-') {
595
         if ($Word === '' || $Word === '-') {
575
             return;
596
             return;
576
         }
597
         }
598
+
577
         if ($Word[0] === '!' && strlen($Word) >= 2 && strpos($Word, '!', 1) === false) {
599
         if ($Word[0] === '!' && strlen($Word) >= 2 && strpos($Word, '!', 1) === false) {
578
             $this->Terms[$Field]['exclude'][] = $Word;
600
             $this->Terms[$Field]['exclude'][] = $Word;
579
         } else {
601
         } else {
630
         if (count($this->SphResults) === 0) {
652
         if (count($this->SphResults) === 0) {
631
             return;
653
             return;
632
         }
654
         }
655
+
633
         $this->Groups = Torrents::get_groups($this->SphResults);
656
         $this->Groups = Torrents::get_groups($this->SphResults);
634
         if ($this->need_torrent_ft()) {
657
         if ($this->need_torrent_ft()) {
635
             // Query Sphinx for torrent IDs if torrent-specific fulltext filters were used
658
             // Query Sphinx for torrent IDs if torrent-specific fulltext filters were used
653
                 $AllTorrents += array_fill_keys(array_keys($Group['Torrents']), $GroupID);
676
                 $AllTorrents += array_fill_keys(array_keys($Group['Torrents']), $GroupID);
654
             }
677
             }
655
         }
678
         }
679
+
656
         $TorrentCount = count($AllTorrents);
680
         $TorrentCount = count($AllTorrents);
657
         $this->SphQLTor = new SphinxqlQuery();
681
         $this->SphQLTor = new SphinxqlQuery();
658
         $this->SphQLTor->where_match('_all', 'fake', false);
682
         $this->SphQLTor->where_match('_all', 'fake', false);
659
         $this->SphQLTor->select('id')->from('torrents, delta');
683
         $this->SphQLTor->select('id')->from('torrents, delta');
684
+
660
         foreach ($this->UsedTorrentFields as $Field => $Term) {
685
         foreach ($this->UsedTorrentFields as $Field => $Term) {
661
             $this->SphQLTor->where_match($Term, $Field, false);
686
             $this->SphQLTor->where_match($Term, $Field, false);
662
         }
687
         }
688
+
663
         $this->SphQLTor->copy_attributes_from($this->SphQL);
689
         $this->SphQLTor->copy_attributes_from($this->SphQL);
664
         $this->SphQLTor->where('id', array_keys($AllTorrents))->limit(0, $TorrentCount, $TorrentCount);
690
         $this->SphQLTor->where('id', array_keys($AllTorrents))->limit(0, $TorrentCount, $TorrentCount);
665
         $SphQLResultTor = $this->SphQLTor->query();
691
         $SphQLResultTor = $this->SphQLTor->query();
666
         $MatchingTorrentIDs = $SphQLResultTor->to_pair('id', 'id');
692
         $MatchingTorrentIDs = $SphQLResultTor->to_pair('id', 'id');
693
+
667
         foreach ($AllTorrents as $TorrentID => $GroupID) {
694
         foreach ($AllTorrents as $TorrentID => $GroupID) {
668
             if (!isset($MatchingTorrentIDs[$TorrentID])) {
695
             if (!isset($MatchingTorrentIDs[$TorrentID])) {
669
                 unset($this->Groups[$GroupID]['Torrents'][$TorrentID]);
696
                 unset($this->Groups[$GroupID]['Torrents'][$TorrentID]);
681
             if (empty($Group['Torrents'])) {
708
             if (empty($Group['Torrents'])) {
682
                 continue;
709
                 continue;
683
             }
710
             }
711
+            
684
             foreach ($Group['Torrents'] as $TorrentID => $Torrent) {
712
             foreach ($Group['Torrents'] as $TorrentID => $Torrent) {
685
                 if (!$this->filter_torrent_internal($Torrent)) {
713
                 if (!$this->filter_torrent_internal($Torrent)) {
686
                     unset($this->Groups[$GroupID]['Torrents'][$TorrentID]);
714
                     unset($this->Groups[$GroupID]['Torrents'][$TorrentID]);
698
      * @return bool True if it's a real hit
726
      * @return bool True if it's a real hit
699
      */
727
      */
700
     private function filter_torrent_internal($Torrent)
728
     private function filter_torrent_internal($Torrent)
701
-    {
702
-        if (isset($this->UsedTorrentAttrs['freetorrent'])) {
703
-            $FilterValue = $this->UsedTorrentAttrs['freetorrent'];
704
-            if ($FilterValue === 3 && $Torrent['FreeTorrent'] === 0) {
705
-                // Either FL or NL is ok
706
-                return false;
707
-            } elseif ($FilterValue !== 3 && $FilterValue !== (int)$Torrent['FreeTorrent']) {
708
-                return false;
709
-            }
710
-        }
711
-        return true;
712
-    }
713
-}
714
-
715
-/* Not integers
716
-    private function filter_torrent_internal($Torrent)
717
     {
729
     {
718
         if (isset($this->UsedTorrentAttrs['freetorrent'])) {
730
         if (isset($this->UsedTorrentAttrs['freetorrent'])) {
719
             $FilterValue = $this->UsedTorrentAttrs['freetorrent'];
731
             $FilterValue = $this->UsedTorrentAttrs['freetorrent'];
727
         return true;
739
         return true;
728
     }
740
     }
729
 }
741
 }
730
-*/

+ 192
- 176
classes/tracker.class.php View File

1
-<?
1
+<?php
2
+
2
 // todo: Turn this into a class with nice functions like update_user, delete_torrent, etc.
3
 // todo: Turn this into a class with nice functions like update_user, delete_torrent, etc.
3
-class Tracker {
4
-  const STATS_MAIN = 0;
5
-  const STATS_USER = 1;
6
-
7
-  public static $Requests = [];
8
-
9
-  /**
10
-   * Send a GET request over a socket directly to the tracker
11
-   * For example, Tracker::update_tracker('change_passkey', array('oldpasskey' => OLD_PASSKEY, 'newpasskey' => NEW_PASSKEY)) will send the request:
12
-   * GET /tracker_32_char_secret_code/update?action=change_passkey&oldpasskey=OLD_PASSKEY&newpasskey=NEW_PASSKEY HTTP/1.1
13
-   *
14
-   * @param string $Action The action to send
15
-   * @param array $Updates An associative array of key->value pairs to send to the tracker
16
-   * @param boolean $ToIRC Sends a message to the channel #tracker with the GET URL.
17
-   */
18
-  public static function update_tracker($Action, $Updates, $ToIRC = false) {
19
-    // Build request
20
-    $Get = TRACKER_SECRET . "/update?action=$Action";
21
-    foreach ($Updates as $Key => $Value) {
22
-      $Get .= "&$Key=$Value";
23
-    }
4
+class Tracker
5
+{
6
+    const STATS_MAIN = 0;
7
+    const STATS_USER = 1;
8
+    public static $Requests = [];
24
 
9
 
25
-    $MaxAttempts = 3;
26
-    // don't wait around if we're debugging
27
-    if (DEBUG_MODE) {
28
-      $MaxAttempts = 1;
29
-    }
10
+    /**
11
+     * Send a GET request over a socket directly to the tracker
12
+     * For example, Tracker::update_tracker('change_passkey', array('oldpasskey' => OLD_PASSKEY, 'newpasskey' => NEW_PASSKEY)) will send the request:
13
+     * GET /tracker_32_char_secret_code/update?action=change_passkey&oldpasskey=OLD_PASSKEY&newpasskey=NEW_PASSKEY HTTP/1.1
14
+     *
15
+     * @param string $Action The action to send
16
+     * @param array $Updates An associative array of key->value pairs to send to the tracker
17
+     * @param boolean $ToIRC Sends a message to the channel #tracker with the GET URL.
18
+     */
19
+    public static function update_tracker($Action, $Updates, $ToIRC = false)
20
+    {
21
+        // Build request
22
+        $Get = TRACKER_SECRET . "/update?action=$Action";
23
+        foreach ($Updates as $Key => $Value) {
24
+            $Get .= "&$Key=$Value";
25
+        }
30
 
26
 
31
-    $Err = false;
32
-    if (self::send_request($Get, $MaxAttempts, $Err) === false) {
33
-      send_irc("PRIVMSG " . BOT_DEBUG_CHAN . " :$MaxAttempts $Err $Get");
34
-      if (G::$Cache->get_value('ocelot_error_reported') === false) {
35
-        send_irc('PRIVMSG ' . ADMIN_CHAN . " :Failed to update ocelot: $Err : $Get");
36
-        G::$Cache->cache_value('ocelot_error_reported', true, 3600);
37
-      }
38
-      return false;
39
-    }
40
-    return true;
41
-  }
42
-
43
-  /**
44
-   * Get global peer stats from the tracker
45
-   *
46
-   * @return array(0 => $Leeching, 1 => $Seeding) or false if request failed
47
-   */
48
-  public static function global_peer_count() {
49
-    $Stats = self::get_stats(self::STATS_MAIN);
50
-    if (isset($Stats['leechers tracked']) && isset($Stats['seeders tracked'])) {
51
-      $Leechers = $Stats['leechers tracked'];
52
-      $Seeders = $Stats['seeders tracked'];
53
-    } else {
54
-      return false;
55
-    }
56
-    return array($Leechers, $Seeders);
57
-  }
58
-
59
-  /**
60
-   * Get peer stats for a user from the tracker
61
-   *
62
-   * @param string $TorrentPass The user's pass key
63
-   * @return array(0 => $Leeching, 1 => $Seeding) or false if the request failed
64
-   */
65
-  public static function user_peer_count($TorrentPass) {
66
-    $Stats = self::get_stats(self::STATS_USER, array('key' => $TorrentPass));
67
-    if ($Stats === false) {
68
-      return false;
69
-    }
70
-    if (isset($Stats['leeching']) && isset($Stats['seeding'])) {
71
-      $Leeching = $Stats['leeching'];
72
-      $Seeding = $Stats['seeding'];
73
-    } else {
74
-      // User doesn't exist, but don't tell anyone
75
-      $Leeching = $Seeding = 0;
76
-    }
77
-    return array($Leeching, $Seeding);
78
-  }
79
-
80
-  /**
81
-   * Get whatever info the tracker has to report
82
-   *
83
-   * @return results from get_stats()
84
-   */
85
-  public static function info() {
86
-    return self::get_stats(self::STATS_MAIN);
87
-  }
88
-
89
-  /**
90
-   * Send a stats request to the tracker and process the results
91
-   *
92
-   * @param int $Type Stats type to get
93
-   * @param array $Params Parameters required by stats type
94
-   * @return array with stats in named keys or false if the request failed
95
-   */
96
-  private static function get_stats($Type, $Params = false) {
97
-    if (!defined('TRACKER_REPORTKEY')) {
98
-      return false;
27
+        $MaxAttempts = 3;
28
+        // don't wait around if we're debugging
29
+        if (DEBUG_MODE) {
30
+            $MaxAttempts = 1;
31
+        }
32
+
33
+        $Err = false;
34
+        if (self::send_request($Get, $MaxAttempts, $Err) === false) {
35
+            send_irc("PRIVMSG " . BOT_DEBUG_CHAN . " :$MaxAttempts $Err $Get");
36
+            if (G::$Cache->get_value('ocelot_error_reported') === false) {
37
+                send_irc('PRIVMSG ' . ADMIN_CHAN . " :Failed to update ocelot: $Err : $Get");
38
+                G::$Cache->cache_value('ocelot_error_reported', true, 3600);
39
+            }
40
+            return false;
41
+        }
42
+        return true;
99
     }
43
     }
100
-    $Get = TRACKER_REPORTKEY . '/report?';
101
-    if ($Type === self::STATS_MAIN) {
102
-      $Get .= 'get=stats';
103
-    } elseif ($Type === self::STATS_USER && !empty($Params['key'])) {
104
-      $Get .= "get=user&key=$Params[key]";
105
-    } else {
106
-      return false;
44
+
45
+    /**
46
+     * Get global peer stats from the tracker
47
+     *
48
+     * @return array(0 => $Leeching, 1 => $Seeding) or false if request failed
49
+     */
50
+    public static function global_peer_count()
51
+    {
52
+        $Stats = self::get_stats(self::STATS_MAIN);
53
+        if (isset($Stats['leechers tracked']) && isset($Stats['seeders tracked'])) {
54
+            $Leechers = $Stats['leechers tracked'];
55
+            $Seeders = $Stats['seeders tracked'];
56
+        } else {
57
+            return false;
58
+        }
59
+        return array($Leechers, $Seeders);
107
     }
60
     }
108
-    $Response = self::send_request($Get);
109
-    if ($Response === false) {
110
-      return false;
61
+
62
+    /**
63
+     * Get peer stats for a user from the tracker
64
+     *
65
+     * @param string $TorrentPass The user's pass key
66
+     * @return array(0 => $Leeching, 1 => $Seeding) or false if the request failed
67
+     */
68
+    public static function user_peer_count($TorrentPass)
69
+    {
70
+        $Stats = self::get_stats(self::STATS_USER, array('key' => $TorrentPass));
71
+        if ($Stats === false) {
72
+            return false;
73
+        }
74
+
75
+        if (isset($Stats['leeching']) && isset($Stats['seeding'])) {
76
+            $Leeching = $Stats['leeching'];
77
+            $Seeding = $Stats['seeding'];
78
+        } else {
79
+            // User doesn't exist, but don't tell anyone
80
+            $Leeching = $Seeding = 0;
81
+        }
82
+        return array($Leeching, $Seeding);
111
     }
83
     }
112
-    $Stats = [];
113
-    foreach (explode("\n", $Response) as $Stat) {
114
-      list($Val, $Key) = explode(" ", $Stat, 2);
115
-      $Stats[$Key] = $Val;
84
+
85
+    /**
86
+     * Get whatever info the tracker has to report
87
+     *
88
+     * @return results from get_stats()
89
+     */
90
+    public static function info()
91
+    {
92
+        return self::get_stats(self::STATS_MAIN);
116
     }
93
     }
117
-    return $Stats;
118
-  }
119
-
120
-  /**
121
-   * Send a request to the tracker
122
-   *
123
-   * @param string $Path GET string to send to the tracker
124
-   * @param int $MaxAttempts Maximum number of failed attempts before giving up
125
-   * @param $Err Variable to use as storage for the error string if the request fails
126
-   * @return tracker response message or false if the request failed
127
-   */
128
-  private static function send_request($Get, $MaxAttempts = 1, &$Err = false) {
129
-    $Header = "GET /$Get HTTP/1.1\r\nConnection: Close\r\n\r\n";
130
-    $Attempts = 0;
131
-    $Sleep = 0;
132
-    $Success = false;
133
-    $StartTime = microtime(true);
134
-    while (!$Success && $Attempts++ < $MaxAttempts) {
135
-      if ($Sleep) {
136
-        sleep($Sleep);
137
-      }
138
-
139
-      // spend some time retrying if we're not in DEBUG_MODE
140
-      if (!DEBUG_MODE) {
141
-        $Sleep = 6;
142
-      }
143
-
144
-      // Send request
145
-      $File = fsockopen(TRACKER_HOST, TRACKER_PORT, $ErrorNum, $ErrorString);
146
-      if ($File) {
147
-        if (fwrite($File, $Header) === false) {
148
-          $Err = "Failed to fwrite()";
149
-          $Sleep = 3;
150
-          continue;
94
+
95
+    /**
96
+     * Send a stats request to the tracker and process the results
97
+     *
98
+     * @param int $Type Stats type to get
99
+     * @param array $Params Parameters required by stats type
100
+     * @return array with stats in named keys or false if the request failed
101
+     */
102
+    private static function get_stats($Type, $Params = false)
103
+    {
104
+        if (!defined('TRACKER_REPORTKEY')) {
105
+            return false;
151
         }
106
         }
152
-      } else {
153
-        $Err = "Failed to fsockopen() - $ErrorNum - $ErrorString";
154
-        continue;
155
-      }
156
-
157
-      // Check for response.
158
-      $Response = '';
159
-      while (!feof($File)) {
160
-        $Response .= fread($File, 1024);
161
-      }
162
-      $DataStart = strpos($Response, "\r\n\r\n") + 4;
163
-      $DataEnd = strrpos($Response, "\n");
164
-      if ($DataEnd > $DataStart) {
165
-        $Data = substr($Response, $DataStart, $DataEnd - $DataStart);
166
-      } else {
167
-        $Data = "";
168
-      }
169
-      $Status = substr($Response, $DataEnd + 1);
170
-      if ($Status == "success") {
171
-        $Success = true;
172
-      }
107
+
108
+        $Get = TRACKER_REPORTKEY . '/report?';
109
+        if ($Type === self::STATS_MAIN) {
110
+            $Get .= 'get=stats';
111
+        } elseif ($Type === self::STATS_USER && !empty($Params['key'])) {
112
+            $Get .= "get=user&key=$Params[key]";
113
+        } else {
114
+            return false;
115
+        }
116
+
117
+        $Response = self::send_request($Get);
118
+        if ($Response === false) {
119
+            return false;
120
+        }
121
+
122
+        $Stats = [];
123
+        foreach (explode("\n", $Response) as $Stat) {
124
+            list($Val, $Key) = explode(" ", $Stat, 2);
125
+            $Stats[$Key] = $Val;
126
+        }
127
+        return $Stats;
173
     }
128
     }
174
-    $Request = array(
175
-      'path' => substr($Get, strpos($Get, '/')),
176
-      'response' => ($Success ? $Data : $Response),
177
-      'status' => ($Success ? 'ok' : 'failed'),
178
-      'time' => 1000 * (microtime(true) - $StartTime)
179
-    );
180
-    self::$Requests[] = $Request;
181
-    if ($Success) {
182
-      return $Data;
129
+
130
+    /**
131
+     * Send a request to the tracker
132
+     *
133
+     * @param string $Path GET string to send to the tracker
134
+     * @param int $MaxAttempts Maximum number of failed attempts before giving up
135
+     * @param $Err Variable to use as storage for the error string if the request fails
136
+     * @return tracker response message or false if the request failed
137
+     */
138
+    private static function send_request($Get, $MaxAttempts = 1, &$Err = false)
139
+    {
140
+        $Header = "GET /$Get HTTP/1.1\r\nConnection: Close\r\n\r\n";
141
+        $Attempts = 0;
142
+        $Sleep = 0;
143
+        $Success = false;
144
+        $StartTime = microtime(true);
145
+
146
+        while (!$Success && $Attempts++ < $MaxAttempts) {
147
+            if ($Sleep) {
148
+                sleep($Sleep);
149
+            }
150
+
151
+            // spend some time retrying if we're not in DEBUG_MODE
152
+            if (!DEBUG_MODE) {
153
+                $Sleep = 6;
154
+            }
155
+
156
+            // Send request
157
+            $File = fsockopen(TRACKER_HOST, TRACKER_PORT, $ErrorNum, $ErrorString);
158
+            if ($File) {
159
+                if (fwrite($File, $Header) === false) {
160
+                    $Err = "Failed to fwrite()";
161
+                    $Sleep = 3;
162
+                    continue;
163
+                }
164
+            } else {
165
+                $Err = "Failed to fsockopen() - $ErrorNum - $ErrorString";
166
+                continue;
167
+            }
168
+
169
+            // Check for response
170
+            $Response = '';
171
+            while (!feof($File)) {
172
+                $Response .= fread($File, 1024);
173
+            }
174
+
175
+            $DataStart = strpos($Response, "\r\n\r\n") + 4;
176
+            $DataEnd = strrpos($Response, "\n");
177
+
178
+            if ($DataEnd > $DataStart) {
179
+                $Data = substr($Response, $DataStart, $DataEnd - $DataStart);
180
+            } else {
181
+                $Data = "";
182
+            }
183
+
184
+            $Status = substr($Response, $DataEnd + 1);
185
+            if ($Status === "success") {
186
+                $Success = true;
187
+            }
188
+        }
189
+
190
+        $Request = array(
191
+            'path' => substr($Get, strpos($Get, '/')),
192
+            'response' => ($Success ? $Data : $Response),
193
+            'status' => ($Success ? 'ok' : 'failed'),
194
+            'time' => 1000 * (microtime(true) - $StartTime)
195
+        );
196
+
197
+        self::$Requests[] = $Request;
198
+        if ($Success) {
199
+            return $Data;
200
+        }
201
+        return false;
183
     }
202
     }
184
-    return false;
185
-  }
186
 }
203
 }
187
-?>

+ 13
- 8
classes/view.class.php View File

1
 <?php
1
 <?php
2
+
2
 class View
3
 class View
3
 {
4
 {
4
     /**
5
     /**
21
         if ($PageTitle !== '') {
22
         if ($PageTitle !== '') {
22
             $PageTitle .= ' :: ';
23
             $PageTitle .= ' :: ';
23
         }
24
         }
25
+
24
         $PageTitle .= SITE_NAME;
26
         $PageTitle .= SITE_NAME;
25
         $PageID = array(
27
         $PageID = array(
26
-      $Document, // Document
27
-      empty($_REQUEST['action']) ? false : $_REQUEST['action'], // Action
28
-      empty($_REQUEST['type']) ? false : $_REQUEST['type'] // Type
29
-    );
28
+            $Document, // Document
29
+            empty($_REQUEST['action']) ? false : $_REQUEST['action'], // Action
30
+            empty($_REQUEST['type']) ? false : $_REQUEST['type'] // Type
31
+        );
30
 
32
 
31
         if (!is_array(G::$LoggedUser) || empty(G::$LoggedUser['ID']) || $PageTitle === 'Recover Password :: ' . SITE_NAME) {
33
         if (!is_array(G::$LoggedUser) || empty(G::$LoggedUser['ID']) || $PageTitle === 'Recover Password :: ' . SITE_NAME) {
32
             require(SERVER_ROOT.'/design/publicheader.php');
34
             require(SERVER_ROOT.'/design/publicheader.php');
34
             // HTTP/2 Server Push headers for cloudflare
36
             // HTTP/2 Server Push headers for cloudflare
35
             $Scripts = array_merge(['jquery', 'global', 'ajax.class', 'jquery.autocomplete', 'autocomplete', 'tooltipster'], explode(',', $JSIncludes));
37
             $Scripts = array_merge(['jquery', 'global', 'ajax.class', 'jquery.autocomplete', 'autocomplete', 'tooltipster'], explode(',', $JSIncludes));
36
             $Styles = array_merge(['tooltipster'], explode(',', $CSSIncludes));
38
             $Styles = array_merge(['tooltipster'], explode(',', $CSSIncludes));
39
+
37
             foreach ($Scripts as $Script) {
40
             foreach ($Scripts as $Script) {
38
                 if (trim($Script) === '') {
41
                 if (trim($Script) === '') {
39
                     continue;
42
                     continue;
40
                 }
43
                 }
41
                 header('Link: <'.STATIC_SERVER.'functions/'.$Script.'.js?v='.filemtime(SERVER_ROOT.STATIC_SERVER.'functions/'.$Script.'.js').'>; rel=preload; as=script;', false);
44
                 header('Link: <'.STATIC_SERVER.'functions/'.$Script.'.js?v='.filemtime(SERVER_ROOT.STATIC_SERVER.'functions/'.$Script.'.js').'>; rel=preload; as=script;', false);
42
             }
45
             }
46
+
43
             header('Link: <'.STATIC_SERVER.'styles/global.css?v='.filemtime(SERVER_ROOT.STATIC_SERVER.'styles/global.css').'>; rel=preload; as=style', false);
47
             header('Link: <'.STATIC_SERVER.'styles/global.css?v='.filemtime(SERVER_ROOT.STATIC_SERVER.'styles/global.css').'>; rel=preload; as=style', false);
44
             foreach ($Styles as $Style) {
48
             foreach ($Styles as $Style) {
45
                 if (trim($Style) === '') {
49
                 if (trim($Style) === '') {
47
                 }
51
                 }
48
                 header('Link: <'.STATIC_SERVER.'styles/'.$Style.'/style.css?v='.filemtime(SERVER_ROOT.STATIC_SERVER.'styles/'.$Style.'/style.css').'>; rel=preload; as=style;', false);
52
                 header('Link: <'.STATIC_SERVER.'styles/'.$Style.'/style.css?v='.filemtime(SERVER_ROOT.STATIC_SERVER.'styles/'.$Style.'/style.css').'>; rel=preload; as=style;', false);
49
             }
53
             }
50
-            require(SERVER_ROOT.'/design/privateheader.php');
54
+            require SERVER_ROOT.'/design/privateheader.php';
51
         }
55
         }
52
     }
56
     }
53
 
57
 
63
     {
67
     {
64
         global $ScriptStartTime, $SessionID, $UserSessions, $Debug, $Time, $Mobile;
68
         global $ScriptStartTime, $SessionID, $UserSessions, $Debug, $Time, $Mobile;
65
         if (!is_array(G::$LoggedUser) || (isset($Options['recover']) && $Options['recover'] === true)) {
69
         if (!is_array(G::$LoggedUser) || (isset($Options['recover']) && $Options['recover'] === true)) {
66
-            require(SERVER_ROOT.'/design/publicfooter.php');
70
+            require SERVER_ROOT.'/design/publicfooter.php';
67
         } else {
71
         } else {
68
-            require(SERVER_ROOT.'/design/privatefooter.php');
72
+            require SERVER_ROOT.'/design/privatefooter.php';
69
         }
73
         }
70
     }
74
     }
71
 
75
 
91
         if (isset($LoadedTemplates[$TemplateName])) {
95
         if (isset($LoadedTemplates[$TemplateName])) {
92
             $ClassName = $LoadedTemplates[$TemplateName];
96
             $ClassName = $LoadedTemplates[$TemplateName];
93
         } else {
97
         } else {
94
-            include(SERVER_ROOT.'/design/' . $TemplateName . '.php');
98
+            include SERVER_ROOT.'/design/'.$TemplateName.'.php';
95
 
99
 
96
             // Turn template_name into TemplateName
100
             // Turn template_name into TemplateName
97
             $ClassNameParts = explode('_', $TemplateName);
101
             $ClassNameParts = explode('_', $TemplateName);
98
             foreach ($ClassNameParts as $Index => $Part) {
102
             foreach ($ClassNameParts as $Index => $Part) {
99
                 $ClassNameParts[$Index] = ucfirst($Part);
103
                 $ClassNameParts[$Index] = ucfirst($Part);
100
             }
104
             }
105
+            
101
             $ClassName = implode($ClassNameParts). 'Template';
106
             $ClassName = implode($ClassNameParts). 'Template';
102
             $LoadedTemplates[$TemplateName] = $ClassName;
107
             $LoadedTemplates[$TemplateName] = $ClassName;
103
         }
108
         }

+ 99
- 89
classes/wiki.class.php View File

1
-<?
2
-class Wiki {
3
-  /**
4
-   * Normalize an alias
5
-   * @param string $str
6
-   * @return string
7
-   */
8
-  public static function normalize_alias($str) {
9
-    return trim(substr(preg_replace('/[^a-z0-9]/', '', strtolower(htmlentities($str))), 0, 50));
10
-  }
1
+<?php
11
 
2
 
12
-  /**
13
-   * Get all aliases in an associative array of Alias => ArticleID
14
-   * @return array
15
-   */
16
-  public static function get_aliases() {
17
-    $Aliases = G::$Cache->get_value('wiki_aliases');
18
-    if (!$Aliases) {
19
-      $QueryID = G::$DB->get_query_id();
20
-      G::$DB->query("
21
-        SELECT Alias, ArticleID
22
-        FROM wiki_aliases");
23
-      $Aliases = G::$DB->to_pair('Alias', 'ArticleID');
24
-      G::$DB->set_query_id($QueryID);
25
-      G::$Cache->cache_value('wiki_aliases', $Aliases, 3600 * 24 * 14); // 2 weeks
3
+class Wiki
4
+{
5
+    /**
6
+     * Normalize an alias
7
+     * @param string $str
8
+     * @return string
9
+     */
10
+    public static function normalize_alias($str)
11
+    {
12
+        return trim(substr(preg_replace('/[^a-z0-9]/', '', strtolower(htmlentities($str))), 0, 50));
26
     }
13
     }
27
-    return $Aliases;
28
-  }
29
 
14
 
30
-  /**
31
-   * Flush the alias cache. Call this whenever you touch the wiki_aliases table.
32
-   */
33
-  public static function flush_aliases() {
34
-    G::$Cache->delete_value('wiki_aliases');
35
-  }
15
+    /**
16
+     * Get all aliases in an associative array of Alias => ArticleID
17
+     * @return array
18
+     */
19
+    public static function get_aliases()
20
+    {
21
+        $Aliases = G::$Cache->get_value('wiki_aliases');
22
+        if (!$Aliases) {
23
+            $QueryID = G::$DB->get_query_id();
24
+            G::$DB->query("
25
+            SELECT Alias, ArticleID
26
+            FROM wiki_aliases");
27
+            $Aliases = G::$DB->to_pair('Alias', 'ArticleID');
28
+            G::$DB->set_query_id($QueryID);
29
+            G::$Cache->cache_value('wiki_aliases', $Aliases, 3600 * 24 * 14); // 2 weeks
30
+        }
31
+        return $Aliases;
32
+    }
36
 
33
 
37
-  /**
38
-   * Get the ArticleID corresponding to an alias
39
-   * @param string $Alias
40
-   * @return int
41
-   */
42
-  public static function alias_to_id($Alias) {
43
-    $Aliases = self::get_aliases();
44
-    $Alias = self::normalize_alias($Alias);
45
-    if (!isset($Aliases[$Alias])) {
46
-      return false;
47
-    } else {
48
-      return (int)$Aliases[$Alias];
34
+    /**
35
+     * Flush the alias cache. Call this whenever you touch the wiki_aliases table.
36
+     */
37
+    public static function flush_aliases()
38
+    {
39
+        G::$Cache->delete_value('wiki_aliases');
49
     }
40
     }
50
-  }
51
 
41
 
52
-  /**
53
-   * Get an article; returns false on error if $Error = false
54
-   * @param int $ArticleID
55
-   * @param bool $Error
56
-   * @return array|bool
57
-   */
58
-  public static function get_article($ArticleID, $Error = true) {
59
-    $Contents = G::$Cache->get_value('wiki_article_'.$ArticleID);
60
-    if (!$Contents) {
61
-      $QueryID = G::$DB->get_query_id();
62
-      G::$DB->query("
63
-        SELECT
64
-          w.Revision,
65
-          w.Title,
66
-          w.Body,
67
-          w.MinClassRead,
68
-          w.MinClassEdit,
69
-          w.Date,
70
-          w.Author,
71
-          u.Username,
72
-          GROUP_CONCAT(a.Alias),
73
-          GROUP_CONCAT(a.UserID)
74
-        FROM wiki_articles AS w
75
-          LEFT JOIN wiki_aliases AS a ON w.ID=a.ArticleID
76
-          LEFT JOIN users_main AS u ON u.ID=w.Author
77
-        WHERE w.ID='$ArticleID'
78
-        GROUP BY w.ID");
79
-      if (!G::$DB->has_results()) {
80
-        if ($Error) {
81
-          error(404);
42
+    /**
43
+     * Get the ArticleID corresponding to an alias
44
+     * @param string $Alias
45
+     * @return int
46
+     */
47
+    public static function alias_to_id($Alias)
48
+    {
49
+        $Aliases = self::get_aliases();
50
+        $Alias = self::normalize_alias($Alias);
51
+        if (!isset($Aliases[$Alias])) {
52
+            return false;
82
         } else {
53
         } else {
83
-          return false;
54
+            return (int)$Aliases[$Alias];
84
         }
55
         }
85
-      }
86
-      $Contents = G::$DB->to_array();
87
-      G::$DB->set_query_id($QueryID);
88
-      G::$Cache->cache_value('wiki_article_'.$ArticleID, $Contents, 3600 * 24 * 14); // 2 weeks
89
     }
56
     }
90
-    return $Contents;
91
-  }
92
 
57
 
93
-  /**
94
-   * Flush an article's cache. Call this whenever you edited a wiki article or its aliases.
95
-   * @param int $ArticleID
96
-   */
97
-  public static function flush_article($ArticleID) {
98
-    G::$Cache->delete_value('wiki_article_'.$ArticleID);
99
-  }
58
+    /**
59
+     * Get an article; returns false on error if $Error = false
60
+     * @param int $ArticleID
61
+     * @param bool $Error
62
+     * @return array|bool
63
+     */
64
+    public static function get_article($ArticleID, $Error = true)
65
+    {
66
+        $Contents = G::$Cache->get_value('wiki_article_'.$ArticleID);
67
+        if (!$Contents) {
68
+            $QueryID = G::$DB->get_query_id();
69
+            G::$DB->query("
70
+            SELECT
71
+              w.Revision,
72
+              w.Title,
73
+              w.Body,
74
+              w.MinClassRead,
75
+              w.MinClassEdit,
76
+              w.Date,
77
+              w.Author,
78
+              u.Username,
79
+            GROUP_CONCAT(a.Alias),
80
+            GROUP_CONCAT(a.UserID)
81
+            FROM wiki_articles AS w
82
+              LEFT JOIN wiki_aliases AS a ON w.ID=a.ArticleID
83
+              LEFT JOIN users_main AS u ON u.ID=w.Author
84
+              WHERE w.ID='$ArticleID'
85
+              GROUP BY w.ID");
86
+
87
+            if (!G::$DB->has_results()) {
88
+                if ($Error) {
89
+                    error(404);
90
+                } else {
91
+                    return false;
92
+                }
93
+            }
94
+            
95
+            $Contents = G::$DB->to_array();
96
+            G::$DB->set_query_id($QueryID);
97
+            G::$Cache->cache_value('wiki_article_'.$ArticleID, $Contents, 3600 * 24 * 14); // 2 weeks
98
+        }
99
+        return $Contents;
100
+    }
101
+
102
+    /**
103
+     * Flush an article's cache. Call this whenever you edited a wiki article or its aliases.
104
+     * @param int $ArticleID
105
+     */
106
+    public static function flush_article($ArticleID)
107
+    {
108
+        G::$Cache->delete_value('wiki_article_'.$ArticleID);
109
+    }
100
 }
110
 }

+ 100
- 92
classes/zip.class.php View File

1
-<?
1
+<?php
2
+
2
 /*************************************************************************|
3
 /*************************************************************************|
3
 |--------------- Zip class -----------------------------------------------|
4
 |--------------- Zip class -----------------------------------------------|
4
 |*************************************************************************|
5
 |*************************************************************************|
74
 |*************************************************************************/
75
 |*************************************************************************/
75
 
76
 
76
 if (!extension_loaded('zlib')) {
77
 if (!extension_loaded('zlib')) {
77
-  error('Zlib Extension not loaded.');
78
+    error('Zlib Extension not loaded.');
78
 }
79
 }
79
 
80
 
80
-class Zip {
81
-  public $ArchiveSize = 0; // Total size
82
-  public $ArchiveFiles = 0; // Total files
83
-  private $Structure = ''; // Structure saved to memory
84
-  private $FileOffset = 0; // Offset to write data
85
-  private $Data = ''; //An idea
86
-
87
-  public function __construct ($ArchiveName = 'Archive') {
88
-    header("Content-type: application/octet-stream"); // Stream download
89
-    header("Content-disposition: attachment; filename=\"$ArchiveName.zip\""); // Name the archive - Should not be urlencoded
90
-  }
91
-
92
-  public static function unlimit () {
93
-    ob_end_clean();
94
-    set_time_limit(3600); // Limit 1 hour
95
-    ini_set('memory_limit', '1024M'); // Because the buffers can get extremely large
96
-  }
97
-
98
-  public function add_file ($FileData, $ArchivePath, $TimeStamp = 0) {
99
-    /* File header */
100
-    $this->Data = "\x50\x4b\x03\x04"; // PK signature
101
-    $this->Data .= "\x14\x00"; // Version requirements
102
-    $this->Data .= "\x00\x08"; // Bit flag - 0x8 = UTF-8 file names
103
-    $this->Data .= "\x08\x00"; // Compression
104
-    $this->Data .= "\x00\x00\x00\x00";
105
-    $DataLength = strlen($FileData); // Saved as variable to avoid wasting CPU calculating it multiple times.
106
-    $CRC32 = crc32($FileData); // Ditto.
107
-    $ZipData = gzcompress($FileData); // Ditto.
108
-    $ZipData = substr ($ZipData, 2, (strlen($ZipData) - 6)); // Checksum resolution
109
-    $ZipLength = strlen($ZipData); // Ditto.
110
-    $this->Data .= pack('V', $CRC32); // CRC-32
111
-    $this->Data .= pack('V', $ZipLength); // Compressed file size
112
-    $this->Data .= pack('V', $DataLength); // Uncompressed file size
113
-    $this->Data .= pack('v', strlen($ArchivePath)); // Path name length
114
-    $this->Data .="\x00\x00"; // Extra field length (0'd so we can ignore this)
115
-    $this->Data .= $ArchivePath; // File name & Extra Field (length set to 0 so ignored)
116
-    /* END file header */
117
-
118
-    /* File data */
119
-    $this->Data .= $ZipData; // File data
120
-    /* END file data */
121
-
122
-    /* Data descriptor
123
-    Not needed (only needed when 3rd bitflag is set), causes problems with OS X archive utility
124
-    $this->Data .= pack('V', $CRC32); // CRC-32
125
-    $this->Data .= pack('V', $ZipLength); // Compressed file size
126
-    $this->Data .= pack('V', $DataLength); // Uncompressed file size
127
-    END data descriptor */
128
-
129
-    $FileDataLength = strlen($this->Data);
130
-    $this->ArchiveSize = $this->ArchiveSize + $FileDataLength; // All we really need is the size
131
-    $CurrentOffset = $this->ArchiveSize; // Update offsets
132
-    echo $this->Data; // Get this out to reduce our memory consumption
133
-
134
-    /* Central Directory Structure */
135
-    $CDS = "\x50\x4b\x01\x02"; // CDS signature
136
-    $CDS .="\x14\x00"; // Constructor version
137
-    $CDS .="\x14\x00"; // Version requirements
138
-    $CDS .="\x00\x08"; // Bit flag - 0x8 = UTF-8 file names
139
-    $CDS .="\x08\x00"; // Compression
140
-    $CDS .="\x00\x00\x00\x00"; // Last modified
141
-    $CDS .= pack('V', $CRC32); // CRC-32
142
-    $CDS .= pack('V', $ZipLength); // Compressed file size
143
-    $CDS .= pack('V', $DataLength); // Uncompressed file size
144
-    $CDS .= pack('v', strlen($ArchivePath)); // Path name length
145
-    $CDS .="\x00\x00"; // Extra field length (0'd so we can ignore this)
146
-    $CDS .="\x00\x00"; // File comment length  (no comment, 0'd)
147
-    $CDS .="\x00\x00"; // Disk number start (0 seems valid)
148
-    $CDS .="\x00\x00"; // Internal file attributes (again with the 0's)
149
-    $CDS .="\x20\x00\x00\x00"; // External file attributes
150
-    $CDS .= pack('V', $this->FileOffset); // Offsets
151
-    $CDS .= $ArchivePath; // File name & Extra Field (length set to 0 so ignored)
152
-    /* END central Directory Structure */
153
-
154
-    $this->FileOffset = $CurrentOffset; // Update offsets
155
-    $this->Structure .= $CDS; // Append to structure
156
-    $this->ArchiveFiles++; // Increment file count
157
-  }
158
-
159
-  public function close_stream() {
160
-    echo $this->Structure; // Structure Root
161
-    echo "\x50\x4b\x05\x06"; // End of central directory signature
162
-    echo "\x00\x00"; // This disk
163
-    echo "\x00\x00"; // CDS start
164
-    echo pack('v', $this->ArchiveFiles); // Handle the number of entries
165
-    echo pack('v', $this->ArchiveFiles); // Ditto
166
-    echo pack('V', strlen($this->Structure)); //Size
167
-    echo pack('V', $this->ArchiveSize); // Offset
168
-    echo "\x00\x00"; // No comment, close it off
169
-  }
81
+class Zip
82
+{
83
+    public $ArchiveSize = 0; // Total size
84
+    public $ArchiveFiles = 0; // Total files
85
+    private $Structure = ''; // Structure saved to memory
86
+    private $FileOffset = 0; // Offset to write data
87
+    private $Data = ''; //An idea
88
+
89
+    public function __construct($ArchiveName = 'Archive')
90
+    {
91
+        header("Content-type: application/octet-stream"); // Stream download
92
+        header("Content-disposition: attachment; filename=\"$ArchiveName.zip\""); // Name the archive - Should not be urlencoded
93
+    }
94
+
95
+    public static function unlimit()
96
+    {
97
+        ob_end_clean();
98
+        set_time_limit(3600); // Limit 1 hour
99
+        ini_set('memory_limit', '1024M'); // Because the buffers can get extremely large
100
+    }
101
+
102
+    public function add_file($FileData, $ArchivePath, $TimeStamp = 0)
103
+    {
104
+        /* File header */
105
+        $this->Data = "\x50\x4b\x03\x04"; // PK signature
106
+        $this->Data .= "\x14\x00"; // Version requirements
107
+        $this->Data .= "\x00\x08"; // Bit flag - 0x8 = UTF-8 file names
108
+        $this->Data .= "\x08\x00"; // Compression
109
+        $this->Data .= "\x00\x00\x00\x00";
110
+
111
+        $DataLength = strlen($FileData); // Saved as variable to avoid wasting CPU calculating it multiple times
112
+        $CRC32 = crc32($FileData); // Ditto
113
+        $ZipData = gzcompress($FileData); // Ditto
114
+        $ZipData = substr($ZipData, 2, (strlen($ZipData) - 6)); // Checksum resolution
115
+        $ZipLength = strlen($ZipData); // Ditto
116
+
117
+        $this->Data .= pack('V', $CRC32); // CRC-32
118
+        $this->Data .= pack('V', $ZipLength); // Compressed file size
119
+        $this->Data .= pack('V', $DataLength); // Uncompressed file size
120
+        $this->Data .= pack('v', strlen($ArchivePath)); // Path name length
121
+        $this->Data .="\x00\x00"; // Extra field length (0'd so we can ignore this)
122
+        $this->Data .= $ArchivePath; // File name & Extra Field (length set to 0 so ignored)
123
+        /* END file header */
124
+
125
+        /* File data */
126
+        $this->Data .= $ZipData; // File data
127
+        /* END file data */
128
+
129
+        /* Data descriptor
130
+        Not needed (only needed when 3rd bitflag is set), causes problems with OS X archive utility
131
+        $this->Data .= pack('V', $CRC32); // CRC-32
132
+        $this->Data .= pack('V', $ZipLength); // Compressed file size
133
+        $this->Data .= pack('V', $DataLength); // Uncompressed file size
134
+        END data descriptor */
135
+
136
+        $FileDataLength = strlen($this->Data);
137
+        $this->ArchiveSize = $this->ArchiveSize + $FileDataLength; // All we really need is the size
138
+        $CurrentOffset = $this->ArchiveSize; // Update offsets
139
+        echo $this->Data; // Get this out to reduce our memory consumption
140
+
141
+        /* Central Directory Structure */
142
+        $CDS = "\x50\x4b\x01\x02"; // CDS signature
143
+        $CDS .="\x14\x00"; // Constructor version
144
+        $CDS .="\x14\x00"; // Version requirements
145
+        $CDS .="\x00\x08"; // Bit flag - 0x8 = UTF-8 file names
146
+        $CDS .="\x08\x00"; // Compression
147
+        $CDS .="\x00\x00\x00\x00"; // Last modified
148
+        $CDS .= pack('V', $CRC32); // CRC-32
149
+        $CDS .= pack('V', $ZipLength); // Compressed file size
150
+        $CDS .= pack('V', $DataLength); // Uncompressed file size
151
+        $CDS .= pack('v', strlen($ArchivePath)); // Path name length
152
+        $CDS .="\x00\x00"; // Extra field length (0'd so we can ignore this)
153
+        $CDS .="\x00\x00"; // File comment length  (no comment, 0'd)
154
+        $CDS .="\x00\x00"; // Disk number start (0 seems valid)
155
+        $CDS .="\x00\x00"; // Internal file attributes (again with the 0's)
156
+        $CDS .="\x20\x00\x00\x00"; // External file attributes
157
+        $CDS .= pack('V', $this->FileOffset); // Offsets
158
+        $CDS .= $ArchivePath; // File name & Extra Field (length set to 0 so ignored)
159
+        /* END central Directory Structure */
160
+
161
+        $this->FileOffset = $CurrentOffset; // Update offsets
162
+        $this->Structure .= $CDS; // Append to structure
163
+        $this->ArchiveFiles++; // Increment file count
164
+    }
165
+
166
+    public function close_stream()
167
+    {
168
+        echo $this->Structure; // Structure Root
169
+        echo "\x50\x4b\x05\x06"; // End of central directory signature
170
+        echo "\x00\x00"; // This disk
171
+        echo "\x00\x00"; // CDS start
172
+        echo pack('v', $this->ArchiveFiles); // Handle the number of entries
173
+        echo pack('v', $this->ArchiveFiles); // Ditto
174
+        echo pack('V', strlen($this->Structure)); //Size
175
+        echo pack('V', $this->ArchiveSize); // Offset
176
+        echo "\x00\x00"; // No comment, close it off
177
+    }
170
 }
178
 }

Loading…
Cancel
Save