20 * @license GNU General Public License |
20 * @license GNU General Public License |
21 */ |
21 */ |
22 |
22 |
23 class LogDisplay |
23 class LogDisplay |
24 { |
24 { |
25 /** |
25 /** |
26 * Criteria for the search. |
26 * Criteria for the search. |
27 * Structure: |
27 * Structure: |
28 <code> |
28 <code> |
29 array( |
29 array( |
30 array( 'user', 'Dan' ), |
30 array( 'user', 'Dan' ), |
31 array( 'within', 86400 ), |
31 array( 'within', 86400 ), |
32 array( 'page', 'Main_Page' ) |
32 array( 'page', 'Main_Page' ) |
33 ) |
33 ) |
34 </code> |
34 </code> |
35 * @var array |
35 * @var array |
36 */ |
36 */ |
37 |
37 |
38 var $criteria = array(); |
38 var $criteria = array(); |
39 |
39 |
40 /** |
40 /** |
41 * Adds a criterion for the log display. |
41 * Adds a criterion for the log display. |
42 * @param string Criterion type - user, page, or within |
42 * @param string Criterion type - user, page, or within |
43 * @param string Value - username, page ID, or (int) within # seconds or (string) number + suffix (suffix: d = day, w = week, m = month, y = year) ex: "1w" |
43 * @param string Value - username, page ID, or (int) within # seconds or (string) number + suffix (suffix: d = day, w = week, m = month, y = year) ex: "1w" |
44 */ |
44 */ |
45 |
45 |
46 public function add_criterion($criterion, $value) |
46 public function add_criterion($criterion, $value) |
47 { |
47 { |
48 switch ( $criterion ) |
48 switch ( $criterion ) |
49 { |
49 { |
50 case 'user': |
50 case 'user': |
51 case 'page': |
51 case 'page': |
52 case 'action': |
52 case 'action': |
53 $this->criteria[] = array($criterion, $value); |
53 $this->criteria[] = array($criterion, $value); |
54 break; |
54 break; |
55 case 'minor': |
55 case 'minor': |
56 $this->criteria[] = array($criterion, intval($value)); |
56 $this->criteria[] = array($criterion, intval($value)); |
57 break; |
57 break; |
58 case 'within': |
58 case 'within': |
59 if ( is_int($value) ) |
59 if ( is_int($value) ) |
60 { |
60 { |
61 $this->criteria[] = array($criterion, $value); |
61 $this->criteria[] = array($criterion, $value); |
62 } |
62 } |
63 else if ( is_string($value) ) |
63 else if ( is_string($value) ) |
64 { |
64 { |
65 $lastchar = substr($value, -1); |
65 $lastchar = substr($value, -1); |
66 $amt = intval($value); |
66 $amt = intval($value); |
67 switch($lastchar) |
67 switch($lastchar) |
68 { |
68 { |
69 case 'd': |
69 case 'd': |
70 $amt = $amt * 86400; |
70 $amt = $amt * 86400; |
71 break; |
71 break; |
72 case 'w': |
72 case 'w': |
73 $amt = $amt * 604800; |
73 $amt = $amt * 604800; |
74 break; |
74 break; |
75 case 'm': |
75 case 'm': |
76 $amt = $amt * 2592000; |
76 $amt = $amt * 2592000; |
77 break; |
77 break; |
78 case 'y': |
78 case 'y': |
79 $amt = $amt * 31536000; |
79 $amt = $amt * 31536000; |
80 break; |
80 break; |
81 } |
81 } |
82 $this->criteria[] = array($criterion, $amt); |
82 $this->criteria[] = array($criterion, $amt); |
83 } |
83 } |
84 else |
84 else |
85 { |
85 { |
86 throw new Exception('Invalid value type for within'); |
86 throw new Exception('Invalid value type for within'); |
87 } |
87 } |
88 break; |
88 break; |
89 default: |
89 default: |
90 throw new Exception('Unknown criterion type'); |
90 throw new Exception('Unknown criterion type'); |
91 break; |
91 break; |
92 } |
92 } |
93 } |
93 } |
94 |
94 |
95 /** |
95 /** |
96 * Build the necessary SQL query. |
96 * Build the necessary SQL query. |
97 * @param int Optional: offset, defaults to 0 |
97 * @param int Optional: offset, defaults to 0 |
98 * @param int Optional: page size, defaults to 0; 0 = don't limit |
98 * @param int Optional: page size, defaults to 0; 0 = don't limit |
99 */ |
99 */ |
100 |
100 |
101 public function build_sql($offset = 0, $page_size = 0, $just_page_count = false) |
101 public function build_sql($offset = 0, $page_size = 0, $just_page_count = false) |
102 { |
102 { |
103 global $db, $session, $paths, $template, $plugins; // Common objects |
103 global $db, $session, $paths, $template, $plugins; // Common objects |
104 |
104 |
105 $where_extra = ''; |
105 $where_extra = ''; |
106 $where_bits = array( |
106 $where_bits = array( |
107 'user' => array(), |
107 'user' => array(), |
108 'page' => array(), |
108 'page' => array(), |
109 'action' => array() |
109 'action' => array() |
110 ); |
110 ); |
111 foreach ( $this->criteria as $criterion ) |
111 foreach ( $this->criteria as $criterion ) |
112 { |
112 { |
113 list($type, $value) = $criterion; |
113 list($type, $value) = $criterion; |
114 switch($type) |
114 switch($type) |
115 { |
115 { |
116 case 'user': |
116 case 'user': |
117 $where_bits['user'][] = "author = '" . $db->escape(str_replace('_', ' ', $value)) . "'"; |
117 $where_bits['user'][] = "author = '" . $db->escape(str_replace('_', ' ', $value)) . "'"; |
118 break; |
118 break; |
119 case 'action': |
119 case 'action': |
120 if ( $value === 'protect' ) |
120 if ( $value === 'protect' ) |
121 { |
121 { |
122 $where_bits['action'][] = "action = 'prot'"; |
122 $where_bits['action'][] = "action = 'prot'"; |
123 $where_bits['action'][] = "action = 'unprot'"; |
123 $where_bits['action'][] = "action = 'unprot'"; |
124 $where_bits['action'][] = "action = 'semiprot'"; |
124 $where_bits['action'][] = "action = 'semiprot'"; |
125 } |
125 } |
126 else |
126 else |
127 { |
127 { |
128 $where_bits['action'][] = "action = '" . $db->escape($value) . "'"; |
128 $where_bits['action'][] = "action = '" . $db->escape($value) . "'"; |
129 } |
129 } |
130 break; |
130 break; |
131 case 'page': |
131 case 'page': |
132 list($page_id, $namespace) = RenderMan::strToPageId($value); |
132 list($page_id, $namespace) = RenderMan::strToPageId($value); |
133 $where_bits['page'][] = "page_id = '" . $db->escape($page_id) . "' AND namespace = '" . $db->escape($namespace) . "'"; |
133 $where_bits['page'][] = "page_id = '" . $db->escape($page_id) . "' AND namespace = '" . $db->escape($namespace) . "'"; |
134 break; |
134 break; |
135 case 'within': |
135 case 'within': |
136 $threshold = time() - $value; |
136 $threshold = time() - $value; |
137 $where_extra .= "\n AND time_id > $threshold"; |
137 $where_extra .= "\n AND time_id > $threshold"; |
138 break; |
138 break; |
139 case 'minor': |
139 case 'minor': |
140 if ( $value == 1 ) |
140 if ( $value == 1 ) |
141 $where_extra .= "\n AND ( minor_edit = 1 OR action != 'edit' )"; |
141 $where_extra .= "\n AND ( minor_edit = 1 OR action != 'edit' )"; |
142 else |
142 else |
143 $where_extra .= "\n AND minor_edit != 1"; |
143 $where_extra .= "\n AND minor_edit != 1"; |
144 break; |
144 break; |
145 } |
145 } |
146 } |
146 } |
147 if ( !empty($where_bits['user']) ) |
147 if ( !empty($where_bits['user']) ) |
148 { |
148 { |
149 $where_extra .= "\n AND ( " . implode(" OR ", $where_bits['user']) . " )"; |
149 $where_extra .= "\n AND ( " . implode(" OR ", $where_bits['user']) . " )"; |
150 } |
150 } |
151 if ( !empty($where_bits['page']) ) |
151 if ( !empty($where_bits['page']) ) |
152 { |
152 { |
153 $where_extra .= "\n AND ( (" . implode(") OR (", $where_bits['page']) . ") )"; |
153 $where_extra .= "\n AND ( (" . implode(") OR (", $where_bits['page']) . ") )"; |
154 } |
154 } |
155 if ( !empty($where_bits['action']) ) |
155 if ( !empty($where_bits['action']) ) |
156 { |
156 { |
157 $where_extra .= "\n AND ( (" . implode(") OR (", $where_bits['action']) . ") )"; |
157 $where_extra .= "\n AND ( (" . implode(") OR (", $where_bits['action']) . ") )"; |
158 } |
158 } |
159 if ( ENANO_DBLAYER == 'PGSQL' ) |
159 if ( ENANO_DBLAYER == 'PGSQL' ) |
160 $limit = ( $page_size > 0 ) ? "\n LIMIT $page_size OFFSET $offset" : ''; |
160 $limit = ( $page_size > 0 ) ? "\n LIMIT $page_size OFFSET $offset" : ''; |
161 else |
161 else |
162 $limit = ( $page_size > 0 ) ? "\n LIMIT $offset, $page_size" : ''; |
162 $limit = ( $page_size > 0 ) ? "\n LIMIT $offset, $page_size" : ''; |
163 $columns = ( $just_page_count ) ? 'COUNT(*)' : 'log_id, action, page_id, namespace, CHAR_LENGTH(page_text) AS revision_size, author, author_uid, u.username, time_id, edit_summary, minor_edit'; |
163 $columns = ( $just_page_count ) ? 'COUNT(*)' : 'log_id, action, page_id, namespace, CHAR_LENGTH(page_text) AS revision_size, author, author_uid, u.username, time_id, edit_summary, minor_edit'; |
164 $sql = 'SELECT ' . $columns . ' FROM ' . table_prefix . "logs AS l\n" |
164 $sql = 'SELECT ' . $columns . ' FROM ' . table_prefix . "logs AS l\n" |
165 . " LEFT JOIN " . table_prefix . "users AS u\n" |
165 . " LEFT JOIN " . table_prefix . "users AS u\n" |
166 . " ON ( u.user_id = l.author_uid OR u.user_id IS NULL )\n" |
166 . " ON ( u.user_id = l.author_uid OR u.user_id IS NULL )\n" |
167 . " WHERE log_type = 'page' AND is_draft != 1$where_extra\n" |
167 . " WHERE log_type = 'page' AND is_draft != 1$where_extra\n" |
168 . " GROUP BY log_id, action, page_id, namespace, page_text, author, author_uid, username, time_id, edit_summary, minor_edit\n" |
168 . " GROUP BY log_id, action, page_id, namespace, page_text, author, author_uid, username, time_id, edit_summary, minor_edit\n" |
169 . " ORDER BY time_id DESC $limit;"; |
169 . " ORDER BY time_id DESC $limit;"; |
170 |
170 |
171 return $sql; |
171 return $sql; |
172 } |
172 } |
173 |
173 |
174 /** |
174 /** |
175 * Get data! |
175 * Get data! |
176 * @param int Offset, defaults to 0 |
176 * @param int Offset, defaults to 0 |
177 * @param int Page size, if 0 (default) returns entire table (danger Will Robinson!) |
177 * @param int Page size, if 0 (default) returns entire table (danger Will Robinson!) |
178 * @return array |
178 * @return array |
179 */ |
179 */ |
180 |
180 |
181 public function get_data($offset = 0, $page_size = 0) |
181 public function get_data($offset = 0, $page_size = 0) |
182 { |
182 { |
183 global $db, $session, $paths, $session, $plugins; // Common objects |
183 global $db, $session, $paths, $session, $plugins; // Common objects |
184 $sql = $this->build_sql($offset, $page_size); |
184 $sql = $this->build_sql($offset, $page_size); |
185 if ( !$db->sql_query($sql) ) |
185 if ( !$db->sql_query($sql) ) |
186 $db->_die(); |
186 $db->_die(); |
187 |
187 |
188 $return = array(); |
188 $return = array(); |
189 $deplist = array(); |
189 $deplist = array(); |
190 $idlist = array(); |
190 $idlist = array(); |
191 while ( $row = $db->fetchrow() ) |
191 while ( $row = $db->fetchrow() ) |
192 { |
192 { |
193 $return[ $row['log_id'] ] = $row; |
193 $return[ $row['log_id'] ] = $row; |
194 if ( $row['action'] === 'edit' ) |
194 if ( $row['action'] === 'edit' ) |
195 { |
195 { |
196 // This is a page revision; its parent needs to be found |
196 // This is a page revision; its parent needs to be found |
197 $pagekey = serialize(array($row['page_id'], $row['namespace'])); |
197 $pagekey = serialize(array($row['page_id'], $row['namespace'])); |
198 $deplist[$pagekey] = "( page_id = '" . $db->escape($row['page_id']) . "' AND namespace = '" . $db->escape($row['namespace']) . "' AND log_id < {$row['log_id']} )"; |
198 $deplist[$pagekey] = "( page_id = '" . $db->escape($row['page_id']) . "' AND namespace = '" . $db->escape($row['namespace']) . "' AND log_id < {$row['log_id']} )"; |
199 // if we already have a revision from this page in the dataset, we've found its parent |
199 // if we already have a revision from this page in the dataset, we've found its parent |
200 if ( isset($idlist[$pagekey]) ) |
200 if ( isset($idlist[$pagekey]) ) |
201 { |
201 { |
202 $child =& $return[ $idlist[$pagekey] ]; |
202 $child =& $return[ $idlist[$pagekey] ]; |
203 $child['parent_size'] = $row['revision_size']; |
203 $child['parent_size'] = $row['revision_size']; |
204 $child['parent_revid'] = $row['log_id']; |
204 $child['parent_revid'] = $row['log_id']; |
205 $child['parent_time'] = $row['time_id']; |
205 $child['parent_time'] = $row['time_id']; |
206 unset($child); |
206 unset($child); |
207 } |
207 } |
208 $idlist[$pagekey] = $row['log_id']; |
208 $idlist[$pagekey] = $row['log_id']; |
209 } |
209 } |
210 } |
210 } |
211 |
211 |
212 // Second query fetches all parent revision data |
212 // Second query fetches all parent revision data |
213 // (maybe we have no edits?? check deplist) |
213 // (maybe we have no edits?? check deplist) |
214 |
214 |
215 if ( !empty($deplist) ) |
215 if ( !empty($deplist) ) |
216 { |
216 { |
217 // FIXME: inefficient. damn GROUP BY for not obeying ORDER BY, it means we can't group and instead have to select |
217 // FIXME: inefficient. damn GROUP BY for not obeying ORDER BY, it means we can't group and instead have to select |
218 // all previous revisions of page X and discard all but the first one we find. |
218 // all previous revisions of page X and discard all but the first one we find. |
219 $where_extra = implode("\n OR ", $deplist); |
219 $where_extra = implode("\n OR ", $deplist); |
220 $sql = 'SELECT log_id, page_id, namespace, CHAR_LENGTH(page_text) AS revision_size, time_id FROM ' . table_prefix . "logs\n" |
220 $sql = 'SELECT log_id, page_id, namespace, CHAR_LENGTH(page_text) AS revision_size, time_id FROM ' . table_prefix . "logs\n" |
221 . " WHERE log_type = 'page' AND action = 'edit'\n AND ( $where_extra )\n" |
221 . " WHERE log_type = 'page' AND action = 'edit'\n AND ( $where_extra )\n" |
222 // . " GROUP BY page_id, namespace\n" |
222 // . " GROUP BY page_id, namespace\n" |
223 . " ORDER BY log_id DESC;"; |
223 . " ORDER BY log_id DESC;"; |
224 if ( !$db->sql_query($sql) ) |
224 if ( !$db->sql_query($sql) ) |
225 $db->_die(); |
225 $db->_die(); |
226 |
226 |
227 while ( $row = $db->fetchrow() ) |
227 while ( $row = $db->fetchrow() ) |
228 { |
228 { |
229 $pagekey = serialize(array($row['page_id'], $row['namespace'])); |
229 $pagekey = serialize(array($row['page_id'], $row['namespace'])); |
230 if ( isset($idlist[$pagekey]) ) |
230 if ( isset($idlist[$pagekey]) ) |
231 { |
231 { |
232 $child =& $return[ $idlist[$pagekey] ]; |
232 $child =& $return[ $idlist[$pagekey] ]; |
233 $child['parent_size'] = $row['revision_size']; |
233 $child['parent_size'] = $row['revision_size']; |
234 $child['parent_revid'] = $row['log_id']; |
234 $child['parent_revid'] = $row['log_id']; |
235 $child['parent_time'] = $row['time_id']; |
235 $child['parent_time'] = $row['time_id']; |
236 unset($child, $idlist[$pagekey]); |
236 unset($child, $idlist[$pagekey]); |
237 } |
237 } |
238 } |
238 } |
239 } |
239 } |
240 |
240 |
241 // final iteration goes through all edits and if there's not info on the parent, sets to 0. It also calculates size change. |
241 // final iteration goes through all edits and if there's not info on the parent, sets to 0. It also calculates size change. |
242 foreach ( $return as &$row ) |
242 foreach ( $return as &$row ) |
243 { |
243 { |
244 if ( $row['action'] === 'edit' && !isset($row['parent_revid']) ) |
244 if ( $row['action'] === 'edit' && !isset($row['parent_revid']) ) |
245 { |
245 { |
246 $row['parent_revid'] = 0; |
246 $row['parent_revid'] = 0; |
247 $row['parent_size'] = 0; |
247 $row['parent_size'] = 0; |
248 } |
248 } |
249 if ( $row['action'] === 'edit' ) |
249 if ( $row['action'] === 'edit' ) |
250 { |
250 { |
251 $row['size_delta'] = $row['revision_size'] - $row['parent_size']; |
251 $row['size_delta'] = $row['revision_size'] - $row['parent_size']; |
252 } |
252 } |
253 } |
253 } |
254 |
254 |
255 return array_values($return); |
255 return array_values($return); |
256 } |
256 } |
257 |
257 |
258 /** |
258 /** |
259 * Get the number of rows that will be in the result set. |
259 * Get the number of rows that will be in the result set. |
260 * @return int |
260 * @return int |
261 */ |
261 */ |
262 |
262 |
263 public function get_row_count() |
263 public function get_row_count() |
264 { |
264 { |
265 global $db, $session, $paths, $session, $plugins; // Common objects |
265 global $db, $session, $paths, $session, $plugins; // Common objects |
266 |
266 |
267 if ( !$db->sql_query( $this->build_sql(0, 0, true) ) ) |
267 if ( !$db->sql_query( $this->build_sql(0, 0, true) ) ) |
268 $db->_die(); |
268 $db->_die(); |
269 |
269 |
270 list($count) = $db->fetchrow_num(); |
270 list($count) = $db->fetchrow_num(); |
271 return $count; |
271 return $count; |
272 } |
272 } |
273 |
273 |
274 /** |
274 /** |
275 * Returns the list of criteria |
275 * Returns the list of criteria |
276 * @return array |
276 * @return array |
277 */ |
277 */ |
278 |
278 |
279 public function get_criteria() |
279 public function get_criteria() |
280 { |
280 { |
281 return $this->criteria; |
281 return $this->criteria; |
282 } |
282 } |
283 |
283 |
284 /** |
284 /** |
285 * Formats a result row into pretty HTML. |
285 * Formats a result row into pretty HTML. |
286 * @param array dataset from LogDisplay::get_data() |
286 * @param array dataset from LogDisplay::get_data() |
287 * @param bool If true (default), shows action buttons. |
287 * @param bool If true (default), shows action buttons. |
288 * @param bool If true (default), shows page title; good for integrated displays |
288 * @param bool If true (default), shows page title; good for integrated displays |
289 * @static |
289 * @static |
290 * @return string |
290 * @return string |
291 */ |
291 */ |
292 |
292 |
293 public static function render_row($row, $show_buttons = true, $show_pagetitle = true) |
293 public static function render_row($row, $show_buttons = true, $show_pagetitle = true) |
294 { |
294 { |
295 global $db, $session, $paths, $session, $plugins; // Common objects |
295 global $db, $session, $paths, $session, $plugins; // Common objects |
296 global $lang; |
296 global $lang; |
297 |
297 |
298 $html = ''; |
298 $html = ''; |
299 |
299 |
300 $pagekey = ( isset($paths->nslist[$row['namespace']]) ) ? $paths->nslist[$row['namespace']] . $row['page_id'] : $row['namespace'] . ':' . $row['page_id']; |
300 $pagekey = ( isset($paths->nslist[$row['namespace']]) ) ? $paths->nslist[$row['namespace']] . $row['page_id'] : $row['namespace'] . ':' . $row['page_id']; |
301 $pagekey = sanitize_page_id($pagekey); |
301 $pagekey = sanitize_page_id($pagekey); |
302 |
302 |
303 // diff button |
303 // diff button |
304 if ( $show_buttons ) |
304 if ( $show_buttons ) |
305 { |
305 { |
306 if ( $row['action'] == 'edit' && !empty($row['parent_revid']) ) |
306 if ( $row['action'] == 'edit' && !empty($row['parent_revid']) ) |
307 { |
307 { |
308 $html .= '('; |
308 $html .= '('; |
309 $ispage = isPage($pagekey); |
309 $ispage = isPage($pagekey); |
310 |
310 |
311 if ( $ispage ) |
311 if ( $ispage ) |
312 $html .= '<a href="' . makeUrlNS($row['namespace'], $row['page_id'], "do=diff&diff1={$row['parent_revid']}&diff2={$row['log_id']}", true) . '">'; |
312 $html .= '<a href="' . makeUrlNS($row['namespace'], $row['page_id'], "do=diff&diff1={$row['parent_revid']}&diff2={$row['log_id']}", true) . '">'; |
313 |
313 |
314 $html .= $lang->get('pagetools_rc_btn_diff'); |
314 $html .= $lang->get('pagetools_rc_btn_diff'); |
315 |
315 |
316 if ( $ispage ) |
316 if ( $ispage ) |
317 $html .= '</a>'; |
317 $html .= '</a>'; |
318 |
318 |
319 if ( $ispage ) |
319 if ( $ispage ) |
320 $html .= ', <a href="' . makeUrlNS($row['namespace'], $row['page_id'], "oldid={$row['log_id']}", true) . '">'; |
320 $html .= ', <a href="' . makeUrlNS($row['namespace'], $row['page_id'], "oldid={$row['log_id']}", true) . '">'; |
321 |
321 |
322 $html .= $lang->get('pagetools_rc_btn_view'); |
322 $html .= $lang->get('pagetools_rc_btn_view'); |
323 |
323 |
324 if ( $ispage ) |
324 if ( $ispage ) |
325 $html .= '</a>'; |
325 $html .= '</a>'; |
326 |
326 |
327 if ( $row['parent_revid'] > 0 && isPage($pagekey) ) |
327 if ( $row['parent_revid'] > 0 && isPage($pagekey) ) |
328 { |
328 { |
329 $html .= ', <a href="' . makeUrlNS($row['namespace'], $row['page_id'], false, true) . '#do:edit;rev:' . $row['parent_revid'] . '">' . $lang->get('pagetools_rc_btn_undo') . '</a>'; |
329 $html .= ', <a href="' . makeUrlNS($row['namespace'], $row['page_id'], false, true) . '#do:edit;rev:' . $row['parent_revid'] . '">' . $lang->get('pagetools_rc_btn_undo') . '</a>'; |
330 } |
330 } |
331 $html .= ') '; |
331 $html .= ') '; |
332 } |
332 } |
333 else if ( $row['action'] != 'edit' && ( isPage($pagekey) || $row['action'] == 'delete' ) ) |
333 else if ( $row['action'] != 'edit' && ( isPage($pagekey) || $row['action'] == 'delete' ) ) |
334 { |
334 { |
335 $html .= '('; |
335 $html .= '('; |
336 $html .= '<a href="' . makeUrlNS($row['namespace'], $row['page_id'], "do=rollback&id={$row['log_id']}", true). '">' . $lang->get('pagetools_rc_btn_undo') . '</a>'; |
336 $html .= '<a href="' . makeUrlNS($row['namespace'], $row['page_id'], "do=rollback&id={$row['log_id']}", true). '">' . $lang->get('pagetools_rc_btn_undo') . '</a>'; |
337 $html .= ') '; |
337 $html .= ') '; |
338 } |
338 } |
339 |
339 |
340 // hist button |
340 // hist button |
341 $html .= '('; |
341 $html .= '('; |
342 if ( isPage($pagekey) ) |
342 if ( isPage($pagekey) ) |
343 { |
343 { |
344 $html .= '<a href="' . makeUrlNS($row['namespace'], $row['page_id'], "do=history", true) . '">'; |
344 $html .= '<a href="' . makeUrlNS($row['namespace'], $row['page_id'], "do=history", true) . '">'; |
345 } |
345 } |
346 $html .= $lang->get('pagetools_rc_btn_hist'); |
346 $html .= $lang->get('pagetools_rc_btn_hist'); |
347 if ( isPage($pagekey) ) |
347 if ( isPage($pagekey) ) |
348 { |
348 { |
349 $html .= '</a>'; |
349 $html .= '</a>'; |
350 } |
350 } |
351 $html .= ') . . '; |
351 $html .= ') . . '; |
352 } |
352 } |
353 |
353 |
354 if ( $show_pagetitle ) |
354 if ( $show_pagetitle ) |
355 { |
355 { |
356 // new page? |
356 // new page? |
357 if ( $row['action'] == 'edit' && empty($row['parent_revid']) ) |
357 if ( $row['action'] == 'edit' && empty($row['parent_revid']) ) |
358 { |
358 { |
359 $html .= '<b>N</b> '; |
359 $html .= '<b>N</b> '; |
360 } |
360 } |
361 // minor edit? |
361 // minor edit? |
362 if ( $row['action'] == 'edit' && $row['minor_edit'] ) |
362 if ( $row['action'] == 'edit' && $row['minor_edit'] ) |
363 { |
363 { |
364 $html .= '<b>m</b> '; |
364 $html .= '<b>m</b> '; |
365 } |
365 } |
366 |
366 |
367 // link to the page |
367 // link to the page |
368 $cls = ( isPage($pagekey) ) ? '' : ' class="wikilink-nonexistent"'; |
368 $cls = ( isPage($pagekey) ) ? '' : ' class="wikilink-nonexistent"'; |
369 $html .= '<a href="' . makeUrlNS($row['namespace'], $row['page_id']) . '"' . $cls . '>' . htmlspecialchars(get_page_title_ns($row['page_id'], $row['namespace'])) . '</a>; '; |
369 $html .= '<a href="' . makeUrlNS($row['namespace'], $row['page_id']) . '"' . $cls . '>' . htmlspecialchars(get_page_title_ns($row['page_id'], $row['namespace'])) . '</a>; '; |
370 } |
370 } |
371 |
371 |
372 // date |
372 // date |
373 $today = time() - ( time() % 86400 ); |
373 $today = time() - ( time() % 86400 ); |
374 $date = MemberlistFormatter::format_date($row['time_id']) . ' '; |
374 $date = MemberlistFormatter::format_date($row['time_id']) . ' '; |
375 $date .= date('h:i:s', $row['time_id']); |
375 $date .= date('h:i:s', $row['time_id']); |
376 $html .= "$date . . "; |
376 $html .= "$date . . "; |
377 |
377 |
378 // size counter |
378 // size counter |
379 if ( $row['action'] == 'edit' ) |
379 if ( $row['action'] == 'edit' ) |
380 { |
380 { |
381 $css = self::get_css($row['size_delta']); |
381 $css = self::get_css($row['size_delta']); |
382 $size_change = number_format($row['size_delta']); |
382 $size_change = number_format($row['size_delta']); |
383 if ( substr($size_change, 0, 1) != '-' ) |
383 if ( substr($size_change, 0, 1) != '-' ) |
384 $size_change = "+$size_change"; |
384 $size_change = "+$size_change"; |
385 |
385 |
386 $html .= "<span style=\"$css\">({$size_change})</span>"; |
386 $html .= "<span style=\"$css\">({$size_change})</span>"; |
387 $html .= ' . . '; |
387 $html .= ' . . '; |
388 } |
388 } |
389 |
389 |
390 // link to userpage |
390 // link to userpage |
391 $real_username = $row['author_uid'] > 1 && !empty($row['username']) ? $row['username'] : $row['author']; |
391 $real_username = $row['author_uid'] > 1 && !empty($row['username']) ? $row['username'] : $row['author']; |
392 $cls = ( isPage($paths->nslist['User'] . $real_username) ) ? '' : ' class="wikilink-nonexistent"'; |
392 $cls = ( isPage($paths->nslist['User'] . $real_username) ) ? '' : ' class="wikilink-nonexistent"'; |
393 $rank_info = $session->get_user_rank($row['author_uid']); |
393 $rank_info = $session->get_user_rank($row['author_uid']); |
394 $html .= '<a style="' . $rank_info['rank_style'] . '" href="' . makeUrlNS('User', sanitize_page_id($real_username), false, true) . '"' . $cls . '>' . htmlspecialchars($real_username) . '</a> '; |
394 $html .= '<a style="' . $rank_info['rank_style'] . '" href="' . makeUrlNS('User', sanitize_page_id($real_username), false, true) . '"' . $cls . '>' . htmlspecialchars($real_username) . '</a> '; |
395 $html .= '('; |
395 $html .= '('; |
396 $html .= '<a href="' . makeUrlNS('Special', 'PrivateMessages/Compose/To/' . sanitize_page_id($real_username), false, true) . '">'; |
396 $html .= '<a href="' . makeUrlNS('Special', 'PrivateMessages/Compose/To/' . sanitize_page_id($real_username), false, true) . '">'; |
397 $html .= $lang->get('pagetools_rc_btn_pm'); |
397 $html .= $lang->get('pagetools_rc_btn_pm'); |
398 $html .= '</a>, '; |
398 $html .= '</a>, '; |
399 $html .= '<a href="' . makeUrlNS('User', sanitize_page_id($real_username), false, true) . '#do:comments">'; |
399 $html .= '<a href="' . makeUrlNS('User', sanitize_page_id($real_username), false, true) . '#do:comments">'; |
400 $html .= $lang->get('pagetools_rc_btn_usertalk'); |
400 $html .= $lang->get('pagetools_rc_btn_usertalk'); |
401 $html .= '</a>'; |
401 $html .= '</a>'; |
402 $html .= ') . . '; |
402 $html .= ') . . '; |
403 |
403 |
404 // Edit summary |
404 // Edit summary |
405 |
405 |
406 if ( $row['action'] == 'edit' ) |
406 if ( $row['action'] == 'edit' ) |
407 { |
407 { |
408 $html .= '<i>('; |
408 $html .= '<i>('; |
409 if ( empty($row['edit_summary']) ) |
409 if ( empty($row['edit_summary']) ) |
410 { |
410 { |
411 $html .= '<span style="color: #808080;">' . $lang->get('history_summary_none_given') . '</span>'; |
411 $html .= '<span style="color: #808080;">' . $lang->get('history_summary_none_given') . '</span>'; |
412 } |
412 } |
413 else |
413 else |
414 { |
414 { |
415 $html .= RenderMan::parse_internal_links(htmlspecialchars($row['edit_summary'])); |
415 $html .= RenderMan::parse_internal_links(htmlspecialchars($row['edit_summary'])); |
416 } |
416 } |
417 $html .= ')</i>'; |
417 $html .= ')</i>'; |
418 } |
418 } |
419 else |
419 else |
420 { |
420 { |
421 switch($row['action']) |
421 switch($row['action']) |
422 { |
422 { |
423 default: |
423 default: |
424 $html .= $row['action']; |
424 $html .= $row['action']; |
425 break; |
425 break; |
426 case 'rename': |
426 case 'rename': |
427 $html .= $lang->get('log_action_rename', array('old_name' => htmlspecialchars($row['edit_summary']))); |
427 $html .= $lang->get('log_action_rename', array('old_name' => htmlspecialchars($row['edit_summary']))); |
428 break; |
428 break; |
429 case 'create': |
429 case 'create': |
430 $html .= $lang->get('log_action_create'); |
430 $html .= $lang->get('log_action_create'); |
431 break; |
431 break; |
432 case 'votereset': |
432 case 'votereset': |
433 $html .= $lang->get('log_action_votereset', array('num_votes' => $row['edit_summary'], 'plural' => ( intval($row['edit_summary']) == 1 ? '' : $lang->get('meta_plural')))); |
433 $html .= $lang->get('log_action_votereset', array('num_votes' => $row['edit_summary'], 'plural' => ( intval($row['edit_summary']) == 1 ? '' : $lang->get('meta_plural')))); |
434 break; |
434 break; |
435 case 'prot': |
435 case 'prot': |
436 case 'unprot': |
436 case 'unprot': |
437 case 'semiprot': |
437 case 'semiprot': |
438 case 'delete': |
438 case 'delete': |
439 case 'reupload': |
439 case 'reupload': |
440 $stringmap = array( |
440 $stringmap = array( |
441 'prot' => 'log_action_protect_full', |
441 'prot' => 'log_action_protect_full', |
442 'unprot' => 'log_action_protect_none', |
442 'unprot' => 'log_action_protect_none', |
443 'semiprot' => 'log_action_protect_semi', |
443 'semiprot' => 'log_action_protect_semi', |
444 'delete' => 'log_action_delete', |
444 'delete' => 'log_action_delete', |
445 'reupload' => 'log_action_reupload' |
445 'reupload' => 'log_action_reupload' |
446 ); |
446 ); |
447 |
447 |
448 if ( $row['edit_summary'] === '__REVERSION__' ) |
448 if ( $row['edit_summary'] === '__REVERSION__' ) |
449 $reason = '<span style="color: #808080;">' . $lang->get('log_msg_reversion') . '</span>'; |
449 $reason = '<span style="color: #808080;">' . $lang->get('log_msg_reversion') . '</span>'; |
450 else if ( $row['action'] == 'reupload' && $row['edit_summary'] === '__ROLLBACK__' ) |
450 else if ( $row['action'] == 'reupload' && $row['edit_summary'] === '__ROLLBACK__' ) |
451 $reason = '<span style="color: #808080;">' . $lang->get('log_msg_file_restored') . '</span>'; |
451 $reason = '<span style="color: #808080;">' . $lang->get('log_msg_file_restored') . '</span>'; |
452 else |
452 else |
453 $reason = ( !empty($row['edit_summary']) ) ? htmlspecialchars($row['edit_summary']) : '<span style="color: #808080;">' . $lang->get('log_msg_no_reason_provided') . '</span>'; |
453 $reason = ( !empty($row['edit_summary']) ) ? htmlspecialchars($row['edit_summary']) : '<span style="color: #808080;">' . $lang->get('log_msg_no_reason_provided') . '</span>'; |
454 |
454 |
455 $html .= $lang->get($stringmap[$row['action']], array('reason' => $reason)); |
455 $html .= $lang->get($stringmap[$row['action']], array('reason' => $reason)); |
456 } |
456 } |
457 } |
457 } |
458 |
458 |
459 return $html; |
459 return $html; |
460 } |
460 } |
461 |
461 |
462 /** |
462 /** |
463 * Return CSS blurb for size delta |
463 * Return CSS blurb for size delta |
464 * @return string |
464 * @return string |
465 * @static |
465 * @static |
466 * @access private |
466 * @access private |
467 */ |
467 */ |
468 |
468 |
469 private static function get_css($change_size) |
469 private static function get_css($change_size) |
470 { |
470 { |
471 // Hardly changed at all? Return a gray |
471 // Hardly changed at all? Return a gray |
472 if ( $change_size <= 5 && $change_size >= -5 ) |
472 if ( $change_size <= 5 && $change_size >= -5 ) |
473 return 'color: #808080;'; |
473 return 'color: #808080;'; |
474 // determine saturation based on size of change (1-500 bytes) |
474 // determine saturation based on size of change (1-500 bytes) |
475 $change_abs = abs($change_size); |
475 $change_abs = abs($change_size); |
476 $index = 0x70 * ( $change_abs / 500 ); |
476 $index = 0x70 * ( $change_abs / 500 ); |
477 if ( $index > 0x70 ) |
477 if ( $index > 0x70 ) |
478 $index = 0x70; |
478 $index = 0x70; |
479 $index = $index + 0x40; |
479 $index = $index + 0x40; |
480 $index = dechex($index); |
480 $index = dechex($index); |
481 if ( strlen($index) < 2 ) |
481 if ( strlen($index) < 2 ) |
482 $index = "0$index"; |
482 $index = "0$index"; |
483 $css = ( $change_size > 0 ) ? "color: #00{$index}00;" : "color: #{$index}0000;"; |
483 $css = ( $change_size > 0 ) ? "color: #00{$index}00;" : "color: #{$index}0000;"; |
484 if ( $change_abs > 500 ) |
484 if ( $change_abs > 500 ) |
485 $css .= ' font-weight: bold;'; |
485 $css .= ' font-weight: bold;'; |
486 return $css; |
486 return $css; |
487 } |
487 } |
488 } |
488 } |
489 |
489 |
490 ?> |
490 ?> |