/[drupal]/contributions/modules/akismet/akismet.admin.inc
ViewVC logotype

Contents of /contributions/modules/akismet/akismet.admin.inc

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.3 - (show annotations) (download) (as text)
Fri Aug 1 23:14:51 2008 UTC (15 months, 3 weeks ago) by drewish
Branch: MAIN
CVS Tags: HEAD
Changes since 1.2: +3 -3 lines
File MIME type: text/x-php
#242339 (drolp) '#default_value' for checkboxes can't be NULL, follow up for admin pages.
1 <?php
2 // $Id: akismet.admin.inc,v 1.2 2008/05/26 23:37:31 drewish Exp $
3
4 /**
5 * Implementation of hook_settings().
6 */
7 function akismet_settings() {
8 return _akismet_settings_form();
9 }
10
11 /**
12 * Build the akismet settings form.
13 */
14 function _akismet_settings_form() {
15 $form = array();
16
17 $enable_options = array('1' => t('Enabled'), '0' => t('Disabled'));
18
19 $akismet_wpapikey = variable_get('akismet_wpapikey', '');
20 if (empty($akismet_wpapikey)) {
21 $service_fieldset_collapsed = FALSE;
22 }
23 else {
24 $service_fieldset_collapsed = $is_valid = (akismet_api_cmd_verify_key($akismet_wpapikey) == AKISMET_API_RESULT_SUCCESS ? TRUE : FALSE);
25 }
26 if ($service_fieldset_collapsed) {
27 $service_fieldset_collapsed = variable_get('akismet_connection_enabled', 1);
28 }
29
30 $form['service'] = array(
31 '#type' => 'fieldset', '#title' => t('Akismet Service Options'),
32 '#collapsible' => TRUE, '#collapsed' => $service_fieldset_collapsed
33 );
34 $form['service']['akismet_wpapikey'] = array(
35 '#type' => 'textfield', '#title' => t('WordPress.com API key'),
36 '#size' => 30, '#maxlength' => 60,
37 '#default_value' => $akismet_wpapikey,
38 '#description' => t('Please, enter here your <a href="!wpapikey">WordPress.com API key</a>. If you don\'t have one already, you can get it by simply signing up for a free account at <a href="!wordpress-com">WordPress.com</a>. Note that this information is required in order to use the <a href="!akismet">Akismet Service</a>. Please, consult the <a href="!akismet-faq">Akismet FAQ</a> for further information.',
39 array(
40 '!wpapikey' => url('http://wordpress.com/api-keys/'),
41 '!wordpress-com' => url('http://wordpress.com'),
42 '!akismet' => url('http://akismet.com'),
43 '!akismet-faq' => url('http://akismet.com/faq/'),
44 ))
45 );
46 if (!empty($akismet_wpapikey) && !$is_valid) {
47 $form['service']['akismet_wpapikey']['#description'] .= '<div class="marker">'. t('<strong>WARNING: Your API Key doesn\'t seem to be valid!</strong>') .'</div>';
48 }
49 $form['service']['akismet_connection_enabled'] = array(
50 '#type' => 'radios', '#title' => t('Akismet connections'),
51 '#options' => $enable_options,
52 '#default_value' => variable_get('akismet_connection_enabled', 1),
53 '#description' => t('<strong>This option must be enabled in order to perform real requests to the <a href="!akismet">Akismet Service</a>.</strong> You may want to disable this option for testing purposes, however. In this case, the <em>akismet module</em> will operate as normal, except sending real requests to the <a href="!akismet">Akismet Service</a>. ie. no automatic spam detection will be performed and no remote requests will be made when content is manually <em>marked</em>/<em>unmarked</em> as spam.<br />Note: regardless of this option, the <em>akismet module</em> will still connect, from this panel, to validate your <a href="!wpapikey">WordPress.com API key</a>, if specified.',
54 array(
55 '!akismet' => url('http://akismet.com'),
56 '!wpapikey' => url('http://wordpress.com/api-keys/'),
57 ))
58 );
59 $timeout_options = array();
60 for ($n = 1; $n <= 30; $n++) {
61 $timeout_options[$n] = $n;
62 }
63 $form['service']['akismet_connection_timeout'] = array(
64 '#type' => 'select', '#title' => t('Connection timeout'),
65 '#default_value' => variable_get('akismet_connection_timeout', 10),
66 '#options' => $timeout_options,
67 '#description' => t('This option allows you to specify the connection timeout in seconds that is used for real time Akismet connections.')
68 );
69
70 $form['general'] = array(
71 '#type' => 'fieldset', '#title' => t('General Options'),
72 '#collapsible' => TRUE, '#collapsed' => TRUE
73 );
74 $age_options = drupal_map_assoc(array(0, 3600, 10800, 21600, 32400, 43200, 86400, 172800, 259200, 604800, 1209600, 1814400), 'format_interval');
75 $age_options[0] = t('never');
76 $age_options[2592000] = t('1 month');
77 $age_options[5184000] = t('2 months');
78 $age_options[7776000] = t('3 months');
79 $age_options[10368000] = t('4 months');
80 $age_options[15768000] = t('6 months');
81 $age_options[31536000] = t('1 year');
82 $form['general']['akismet_remove_spam_age'] = array(
83 '#type' => 'select', '#title' => t('Remove spam older than'),
84 '#default_value' => variable_get('akismet_remove_spam_age', 259200),
85 '#options' => $age_options,
86 '#description' => t('Content marked as <em>spam</em> is still saved into database so it can be reviewed by content administrators. This option allows you to specify how long this information will be kept in the database. <em>Spam</em> older than the age specified here will be automatically removed. Requires crontab.')
87 );
88 $form['general']['akismet_records_per_page'] = array(
89 '#type' => 'select', '#title' => t('Records per page'),
90 '#default_value' => variable_get('akismet_records_per_page', 50),
91 '#options' => drupal_map_assoc(array(10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 200)),
92 '#description' => t('The maximum number of records per page on moderation queue.')
93 );
94 $form['general']['akismet_blocks_counter'] = array(
95 '#type' => 'select', '#title' => t('Number of blocks'),
96 '#default_value' => variable_get('akismet_blocks_counter', 1),
97 '#options' => array(0=>t('none'), 1=>1, 2=>2, 3=>3, 4=>4, 5=>5),
98 '#description' => t('The akismet module may generate a number of blocks for you to display the current spam counter anywhere on your site. The number of blocks is variable to help you keep your <a href="!admin-block">blocks administration panel</a> as clean as possible. This option allows you to specify how many blocks you wish to use. If you do not plan to show the spam counter to your visitors, set this option to <em>none</em>.',
99 array(
100 '!admin-block' => url('admin/block'),
101 ))
102 );
103 $form['general']['akismet_email_enabled'] = array(
104 '#type' => 'radios', '#title' => t('E-mail notifications'),
105 '#options' => $enable_options,
106 '#default_value' => variable_get('akismet_email_enabled', 1),
107 '#description' => t('Use this option to <em>enable</em> or <em>disable</em> e-mail notifications to content moderators. If enabled, users with proper permissions are allowed to set, from their user profiles, whether they wish to receive e-mail notications for all new (or updated) posts, just for content needing approval or no notifications at all. Users are notified about content types they are allowed to moderate only.')
108 );
109
110 $form['node_options'] = array(
111 '#type' => 'fieldset', '#title' => t('Node Options'),
112 '#collapsible' => TRUE, '#collapsed' => TRUE
113 );
114 $form['node_options']['akismet_check_nodetypes'] = array(
115 '#type' => 'checkboxes', '#title' => t('Check for spam in these node types'),
116 '#options' => node_get_types('names'),
117 '#default_value' => variable_get('akismet_check_nodetypes', array()),
118 '#description' => t('Use this option to <em>enable</em> or <em>disable</em> spam check for nodes of types specified here. When this option is enabled, a request will be sent to the <a href="!akismet">Akismet Service</a>, in real time. If the <a href="!akismet">Akismet Service</a> was down, nodes would simply be queued for manual moderation. Users with <a href="!admin-access">@admin-nodes</a> permission and <a href="!admin-access">spam moderators</a> are exempt from this check.',
119 array(
120 '!akismet' => url('http://akismet.com'),
121 '@admin-nodes' => t('administer nodes'),
122 '!admin-access' => url('admin/access'),
123 ))
124 );
125 $form['node_options']['akismet_node_publish_links'] = array(
126 '#type' => 'radios', '#title' => t('Show publish/unpublish links'),
127 '#options' => $enable_options,
128 '#default_value' => variable_get('akismet_node_publish_links', 0),
129 '#description' => t('Use this option to <em>enable</em> or <em>disable</em> links for <em>publish</em>/<em>unpublish</em> operations in nodes. If enabled, these links will only be displayed to <a href="!admin-access">spam moderators</a> and users with <a href="!admin-access">@admin-nodes</a> permission.',
130 array(
131 '@admin-nodes' => t('administer nodes'),
132 '!admin-access' => url('admin/access'),
133 ))
134 );
135 $form['node_options']['akismet_node_spam_links'] = array(
136 '#type' => 'radios', '#title' => t('Show submit spam/ham links'),
137 '#options' => $enable_options,
138 '#default_value' => variable_get('akismet_node_spam_links', 0),
139 '#description' => t('Use this option to <em>enable</em> or <em>disable</em> links for <em>submit spam</em>/<em>ham</em> operations in nodes. If enabled, these links will only be displayed to <a href="!admin-access">spam moderators</a> and users with <a href="!admin-access">@admin-nodes</a> permission.',
140 array(
141 '@admin-nodes' => t('administer nodes'),
142 '!admin-access' => url('admin/access'),
143 ))
144 .'<br />'. t('<strong>Note:</strong> To interact fully with the <a href="!akismet">Akismet Service</a> you really should try putting data back into the system as well as just taking it out. If it is at all possible, please use these links to submit missed spam and false positives (ham), otherwise Akismet will never learn from its mistakes. Thank you.',
145 array(
146 '!akismet' => url('http://akismet.com'),
147 ))
148 );
149
150 if (module_exists('comment')) {
151 $form['comment_options'] = array(
152 '#type' => 'fieldset', '#title' => t('Comment Options'),
153 '#collapsible' => TRUE, '#collapsed' => TRUE
154 );
155 $form['comment_options']['akismet_check_comments'] = array(
156 '#type' => 'radios', '#title' => t('Check for spam in comments'),
157 '#options' => $enable_options,
158 '#default_value' => variable_get('akismet_check_comments', 1),
159 '#description' => t('Use this option to <em>enable</em> or <em>disable</em> spam check for comments. When this option is enabled, a request will be sent to the <a href="!akismet">Akismet Service</a>, in real time. If the <a href="!akismet">Akismet Service</a> was down, comments would simply be queued for manual moderation. Users with <a href="!admin-access">@admin-comments</a> permission and <a href="!admin-access">spam moderators</a> are exempt from this check.',
160 array(
161 '!akismet' => url('http://akismet.com'),
162 '@admin-comments' => t('administer comments'),
163 '!admin-access' => url('admin/access'),
164 ))
165 );
166 $form['comment_options']['akismet_comment_publish_links'] = array(
167 '#type' => 'radios', '#title' => t('Show publish/unpublish links'),
168 '#options' => $enable_options,
169 '#default_value' => variable_get('akismet_comment_publish_links', 1),
170 '#description' => t('Use this option to <em>enable</em> or <em>disable</em> links for <em>publish</em>/<em>unpublish</em> operations in comments. If enabled, these links will only be displayed to <a href="!admin-access">spam moderators</a> and users with <a href="!admin-access">@admin-comments</a> permission.',
171 array(
172 '@admin-comments' => t('administer comments'),
173 '!admin-access' => url('admin/access'),
174 ))
175 );
176 $form['comment_options']['akismet_comment_spam_links'] = array(
177 '#type' => 'radios', '#title' => t('Show submit spam/ham links'),
178 '#options' => $enable_options,
179 '#default_value' => variable_get('akismet_comment_spam_links', 1),
180 '#description' => t('Use this option to <em>enable</em> or <em>disable</em> links for <em>submit spam</em>/<em>ham</em> operations in comments. If enabled, these links will only be displayed to <a href="!admin-access">spam moderators</a> and users with <a href="!admin-access">@admin-comments</a> permission.',
181 array(
182 '@admin-comments' => t('administer comments'),
183 '!admin-access' => url('admin/access'),
184 ))
185 .'<br />'. t('<strong>Note:</strong> To interact fully with the <a href="!akismet">Akismet Service</a> you really should try putting data back into the system as well as just taking it out. If it is at all possible, please use these links to submit missed spam and false positives (ham), otherwise Akismet will never learn from its mistakes. Thank you.',
186 array(
187 '!akismet' => url('http://akismet.com'),
188 ))
189 );
190 }
191
192 $date_formats = array(
193 'F j, Y', 'j F, Y', 'Y, F j',
194 'M j, Y', 'j M, Y', 'Y, M j',
195 'Y/m/d', 'm/d/Y', 'd/m/Y',
196 'Y-m-d', 'm-d-Y', 'd-m-Y'
197 );
198 $date_options = array();
199 $now = time();
200 foreach ($date_formats as $format) {
201 $date_options[$format] = format_date($now, 'custom', $format);
202 }
203
204 $form['counter_options'] = array(
205 '#type' => 'fieldset', '#title' => t('Spam Counter Options'),
206 '#collapsible' => TRUE, '#collapsed' => TRUE
207 );
208 $form['counter_options']['akismet_counter_spam'] = array(
209 '#type' => 'textfield', '#title' => t('Spam counter'),
210 '#default_value' => akismet_get_spam_counter(),
211 '#size' => 10, '#maxlength' => 10,
212 '#description' => t('This counter is incremented for every spam caught by Akismet.')
213 );
214 $form['counter_options']['akismet_counter_since'] = array(
215 '#type' => 'date', '#title' => t('Counting since'),
216 '#default_value' => variable_get('akismet_counter_since', array('day' => date('j'), 'month' => date('n'), 'year' => date('Y'))),
217 '#description' => t('This is the date that will tell your visitors when your Akismet spam counter started to increment.')
218 );
219 $form['counter_options']['akismet_counter_date_format'] = array(
220 '#type' => 'select', '#title' => t('Date format'),
221 '#default_value' => variable_get('akismet_counter_date_format', $date_formats[0]),
222 '#options' => $date_options,
223 '#description' => t('Date format used to render the <em>Counting since</em> date.')
224 );
225
226 $form['anti_spambot'] = array(
227 '#type' => 'fieldset', '#title' => t('Anti-Spambot Options'),
228 '#collapsible' => TRUE, '#collapsed' => TRUE,
229 '#description' => t('The goal of this section is not to replace anything that the <a href="!akismet">Akismet Service</a> itself can do a lot better than us, but to provide a set of simple rules aimed to prevent Denial of Service (DoS) situations that could be caused by certain spambots.',
230 array(
231 '!akismet' => url('http://akismet.com'),
232 ))
233 );
234 $delay_options = drupal_map_assoc(array(0, 30, 60, 90, 120, 150, 180), 'format_interval');
235 $delay_options[0] = t('none');
236 $form['anti_spambot']['akismet_antispambot_delay'] = array(
237 '#type' => 'select', '#title' => t('Delay when spam is detected'),
238 '#default_value' => variable_get('akismet_antispambot_delay', 60),
239 '#options' => $delay_options,
240 '#description' => t('Use this option to delay the response when content has been identified as spam or to requests that match the rules defined below.')
241 );
242 $anti_spambot_rules = array(
243 'ip' => t('IP addresses used by known spammers.'),
244 'mail' => t('E-mail addresses used by known spammers.'),
245 'body' => t('Content that has already been identified as spam.'),
246 );
247 $form['anti_spambot']['akismet_antispambot_rules'] = array(
248 '#type' => 'checkboxes', '#title' => t('Identify spambots by'),
249 '#options' => $anti_spambot_rules,
250 '#default_value' => variable_get('akismet_antispambot_rules', array()),
251 '#description' => t('These rules will be applied before sending any request to the <a href="!akismet">Akismet Service</a>. If a request to send content matches any of these rules, the actions defined below will be triggered. Requests to send content are checked against spam that is stored locally (visible from the <a href="!moderation-queue">moderation queue</a>).',
252 array(
253 '!akismet' => url('http://akismet.com'),
254 '!moderation-queue' => url('admin/content/akismet'),
255 ))
256 );
257 $anti_spambot_actions = array(
258 'none' => t('None (only the delay specified above, if any).'),
259 '503' => t('HTTP error 503 (Service Unavailable), showing a simple blank page.'),
260 '403' => t('HTTP error 403 (Forbidden), showing a simple blank page.'),
261 '403d' => t('HTTP error 403 (Forbidden), showing a Drupal generated page.')
262 );
263 $form['anti_spambot']['akismet_antispambot_action'] = array(
264 '#type' => 'radios', '#title' => t('Actions against spambots'),
265 '#options' => $anti_spambot_actions,
266 '#default_value' => variable_get('akismet_antispambot_action', '503'),
267 '#description' => t('Use this option to specify what to do against spambots identified by any of the above rules. When a <em>HTTP error</em> is generated (403 or 503), no request to the <a href="!akismet">Akismet Service</a> will be made, the request to post content will not be stored into database and no further moderator notifications will be sent. In any case, when a rule matches, a record of the event will be <a href="!admin-reports">logged</a> for further analysis.',
268 array(
269 '!akismet' => url('http://akismet.com'),
270 '!admin-reports' => url('admin/reports'),
271 ))
272 );
273
274 return system_settings_form($form);
275 }
276
277 /**
278 * Moderation queue operations.
279 */
280 function akismet_moderator_operations($mode, $submode) {
281 // Build operations array; based on current mode.
282 if ($mode == 'nodes') {
283 $operations = array(
284 'submit-spam' => array(
285 'title' => (variable_get('akismet_connection_enabled', 1) ? t('Submit selected nodes as spam') : t('Mark selected nodes as spam')),
286 'confirm' => (variable_get('akismet_connection_enabled', 1) ? t('Are you sure you want to submit these nodes as spam?') : t('Are you sure you want to mark these nodes as spam?')),
287 'button' => (variable_get('akismet_connection_enabled', 1) ? t('Submit nodes as spam') : t('Mark nodes as spam')),
288 ),
289 'submit-ham' => array(
290 'title' => (variable_get('akismet_connection_enabled', 1) ? t('Submit selected nodes as ham') : t('Mark selected nodes as ham')),
291 'confirm' => (variable_get('akismet_connection_enabled', 1) ? t('Are you sure you want to submit these nodes as ham?') : t('Are you sure you want to mark these nodes as ham?')),
292 'button' => (variable_get('akismet_connection_enabled', 1) ? t('Submit nodes as ham') : t('Mark nodes as ham')),
293 ),
294 'publish' => array(
295 'title' => t('Publish selected nodes'),
296 'confirm' => t('Are you sure you want to publish these nodes?'),
297 'button' => t('Publish nodes'),
298 ),
299 'unpublish' => array(
300 'title' => t('Unpublish selected nodes'),
301 'confirm' => t('Are you sure you want to unpublish these nodes?'),
302 'button' => t('Unpublish nodes'),
303 ),
304 'delete' => array(
305 'title' => t('Delete selected nodes'),
306 'confirm' => t('Are you sure you want to delete these nodes and all their comments?'),
307 'button' => t('Delete nodes'),
308 'warning' => t('This action cannot be undone.')
309 )
310 );
311 }
312 else if ($mode == 'comments') {
313 $operations = array(
314 'submit-spam' => array(
315 'title' => (variable_get('akismet_connection_enabled', 1) ? t('Submit selected comments as spam') : t('Mark selected comments as spam')),
316 'confirm' => (variable_get('akismet_connection_enabled', 1) ? t('Are you sure you want to submit these comments as spam?') : t('Are you sure you want to mark these comments as spam?')),
317 'button' => (variable_get('akismet_connection_enabled', 1) ? t('Submit comments as spam') : t('Mark comments as spam')),
318 ),
319 'submit-ham' => array(
320 'title' => (variable_get('akismet_connection_enabled', 1) ? t('Submit selected comments as ham') : t('Mark selected comments as ham')),
321 'confirm' => (variable_get('akismet_connection_enabled', 1) ? t('Are you sure you want to submit these comments as ham?') : t('Are you sure you want to mark these comments as ham?')),
322 'button' => (variable_get('akismet_connection_enabled', 1) ? t('Submit comments as ham') : t('Mark comments as ham')),
323 ),
324 'publish' => array(
325 'title' => t('Publish selected comments'),
326 'confirm' => t('Are you sure you want to publish these comments?'),
327 'button' => t('Publish comments'),
328 ),
329 'unpublish' => array(
330 'title' => t('Unpublish selected comments'),
331 'confirm' => t('Are you sure you want to unpublish these comments?'),
332 'button' => t('Unpublish comments'),
333 ),
334 'delete' => array(
335 'title' => t('Delete selected comments'),
336 'confirm' => t('Are you sure you want to delete these comments and all their replies?'),
337 'button' => t('Delete comments'),
338 'warning' => t('This action cannot be undone.')
339 )
340 );
341 }
342 else { // Unknown mode!
343 return array();
344 }
345
346 // Unset redundant operations; based on current submode.
347 if ($submode == 'spam') {
348 unset($operations['submit-spam']);
349 }
350 else if ($submode == 'unpublished') {
351 unset($operations['unpublish']);
352 }
353 else if ($submode == 'published') {
354 unset($operations['publish']);
355 }
356 else { // Unknown submode!
357 return array();
358 }
359
360 return $operations;
361 }
362
363 /**
364 * Menu callback; Moderation queue.
365 *
366 * @param string Mode: overview (default), nodes, comments.
367 * @param string Submode: spam (default), unpublished, published.
368 */
369 function akismet_callback_queue($mode = '', $submode = '') {
370 // Make sure we're dealing with a valid mode and submode.
371 $valid_modes = array('nodes', 'comments');
372 $valid_submodes = array(
373 'spam' => t('Spam'),
374 'unpublished' => t('Unpublished'),
375 'published' => t('Published')
376 );
377 if (empty($mode)) {
378 $mode = 'overview';
379 }
380 else if (!in_array($mode, $valid_modes)) {
381 drupal_not_found();
382 return;
383 }
384 if (empty($submode)) {
385 $submode = 'spam';
386 }
387 else if (!isset($valid_submodes[$submode])) {
388 drupal_not_found();
389 return;
390 }
391 // Compute exactly what the current user is allowed to moderate.
392 $moderator_types = akismet_get_moderator_types();
393 $moderator_types_count = count($moderator_types);
394 $allowed_comments = (isset($moderator_types['comments']) ? TRUE : FALSE);
395 $allowed_nodes = $moderator_types;
396 if ($allowed_comments) {
397 unset($allowed_nodes['comments']);
398 }
399 $allowed_nodes_count = count($allowed_nodes);
400
401 // Make sure the user has some kind of content administration/moderation permission.
402 if ($allowed_nodes_count <= 0 && !$allowed_comments) {
403 drupal_access_denied();
404 return;
405 }
406
407 // Dynamically build the queries using a write once method.
408 if ($allowed_nodes_count > 0) {
409 $sql_nodetypes = array();
410 foreach ($allowed_nodes as $type => $name) {
411 $sql_nodetypes[] = '\''. $type .'\'';
412 }
413 $sql_nodetypes = implode(', ', $sql_nodetypes);
414 $sql_from = 'FROM {node} n LEFT JOIN {akismet_spam_marks} s ON s.content_id = n.nid AND s.content_type = \'node\'';
415 $sql_where = 'WHERE n.type IN ('. $sql_nodetypes .') AND (%cond)';
416 $sql_nodes_cond = array(
417 'spam' => 's.content_id IS NOT NULL',
418 'unpublished' => 'n.status = 0',
419 'published' => 'n.status = 1'
420 );
421
422 $sql_nodes_stmt = 'SELECT n.*, u.name, IFNULL(s.content_id, 0) AS spam_mark '. $sql_from .' INNER JOIN {users} u ON n.uid = u.uid '. $sql_where;
423 $sql_nodes_cnt = 'SELECT COUNT(*) AS cnt '. $sql_from .' '. $sql_where;
424 }
425 if (module_exists('comment') && $allowed_comments) {
426 $sql_from = 'FROM {comments} c LEFT JOIN {akismet_spam_marks} s ON s.content_id = c.cid AND s.content_type = \'comment\'';
427 $sql_where = 'WHERE (%cond)';
428 $sql_comments_cond = array(
429 'spam' => 's.content_id IS NOT NULL',
430 'unpublished' => 'c.status = '. COMMENT_NOT_PUBLISHED,
431 'published' => 'c.status = '. COMMENT_PUBLISHED
432 );
433 $sql_comments_stmt = 'SELECT c.*, u.name AS registered_name, IFNULL(s.content_id, 0) AS spam_mark '. $sql_from .' INNER JOIN {users} u ON c.uid = u.uid '. $sql_where;
434 $sql_comments_cnt = 'SELECT COUNT(*) AS cnt '. $sql_from .' '. $sql_where;
435 }
436
437 $sql = array(
438 'sql_comments_cnt' => $sql_comments_cnt,
439 'sql_comments_stmt' => $sql_comments_stmt,
440 'sql_comments_cond' => $sql_comments_cond,
441 'sql_nodes_cnt' => $sql_nodes_cnt,
442 'sql_nodes_stmt' => $sql_nodes_stmt,
443 'sql_nodes_cond' => $sql_nodes_cond,
444 );
445
446 // Present the overview page (default).
447 if ($mode == 'overview') {
448 $items = array();
449 if ($allowed_nodes_count > 0) {
450 $subitems = array();
451 foreach ($valid_submodes as $key => $title) {
452 $sql_cnt = str_replace('%cond', $sql_nodes_cond[$key], $sql_nodes_cnt);
453 $count = db_result(db_query(db_rewrite_sql($sql_cnt)));
454 $path = 'admin/content/akismet/nodes'. ($key == 'spam' ? '' : '/'. $key);
455 $label = ($count > 0 ? l($title, $path) : $title);
456 $subitems[] = '<p><strong>'. $label .': '. $count .'</strong></p>';
457 }
458 $items[] = '<h4>'. t('Nodes') .'</h4>'. theme('item_list', $subitems);
459 }
460 if (module_exists('comment') && $allowed_comments) {
461 $subitems = array();
462 foreach ($valid_submodes as $key => $title) {
463 $sql_cnt = str_replace('%cond', $sql_comments_cond[$key], $sql_comments_cnt);
464 $count = db_result(db_query(db_rewrite_sql($sql_cnt, 'c', 'cid')));
465 $path = 'admin/content/akismet/comments'. ($key == 'spam' ? '' : '/'. $key);
466 $label = ($count > 0 ? l($title, $path) : $title);
467 $subitems[] = '<p><strong>'. $label .': '. $count .'</strong></p>';
468 }
469 $items[] = '<h4>'. t('Comments') .'</h4>'. theme('item_list', $subitems);
470 }
471 return '<h3>'. t('Summary of content:') .'</h3>'. theme('item_list', $items);
472 }
473 if (isset($_POST) && count($_POST['items']) > 0) {
474 return drupal_get_form('akismet_confirm_multiple_operation');
475 }
476 else {
477 return drupal_get_form('akismet_moderation_form', $mode, $submode, $sql);
478 }
479 }
480
481 function akismet_moderation_form($form_state, $mode = '', $submode = '', $sql = array()) {
482 // Build the moderation queue form.
483 $form = array();
484 $form['options'] = array(
485 '#type' => 'fieldset', '#title' => t('Moderator actions'),
486 '#prefix' => '<div class="container-inline">', '#suffix' => '</div>'
487 );
488
489 extract($sql);
490
491 $options = array('' => t('<select operation>'));
492 foreach (akismet_moderator_operations($mode, $submode) as $key => $operation_info) {
493 $options[$key] = $operation_info['title'];
494 }
495 $form['options']['operation'] = array('#type' => 'select', '#options' => $options, '#default_value' => '');
496 $form['options']['submit'] = array('#type' => 'submit', '#value' => t('Submit'));
497
498 if ($mode == 'nodes') {
499 $sql_stmt = str_replace('%cond', $sql_nodes_cond[$submode], $sql_nodes_stmt);
500 $sql_cnt = str_replace('%cond', $sql_nodes_cond[$submode], $sql_nodes_cnt);
501 $form['header'] = array('#type' => 'value', '#value' => array(
502 theme('table_select_header_cell'),
503 array('data' => t('Title'), 'field' => 'title'),
504 array('data' => t('Type'), 'field' => 'type'),
505 array('data' => t('Author'), 'field' => 'name'),
506 array('data' => t('Status'), 'field' => 'status'),
507 array('data' => t('Last changed'), 'field' => 'changed', 'sort' => 'desc')
508 ));
509 }
510 else { // comments
511 $sql_stmt = str_replace('%cond', $sql_comments_cond[$submode], $sql_comments_stmt);
512 $sql_cnt = str_replace('%cond', $sql_comments_cond[$submode], $sql_comments_cnt);
513 $form['header'] = array('#type' => 'value', '#value' => array(
514 theme('table_select_header_cell'),
515 array('data' => t('Subject'), 'field' => 'subject'),
516 array('data' => t('Author'), 'field' => 'name'),
517 array('data' => t('Status'), 'field' => 'status'),
518 array('data' => t('Last changed'), 'field' => 'timestamp', 'sort' => 'desc')
519 ));
520 }
521
522 $records_per_page = variable_get('akismet_records_per_page', 50);
523 $result = pager_query($sql_stmt . tablesort_sql($form['header']['#value']), $records_per_page, 0, $sql_cnt);
524 $items = array();
525 $now = time();
526 while ($content = db_fetch_object($result)) {
527 if ($mode == 'nodes') {
528 $items[$content->nid] = '';
529 $form['title'][$content->nid] = array('#value' => l($content->title, 'node/'. $content->nid, array('title' => truncate_utf8($content->body, 128))) .' '. theme('mark', node_mark($content->nid, $content->changed)));
530 $form['type'][$content->nid] = array('#value' => node_get_types('name', $content));
531 $form['author'][$content->nid] = array('#value' => theme('username', $content));
532 $form['status'][$content->nid] = array('#value' => ($content->status ? t('published') : t('not published')));
533 if ($content->spam_mark) {
534 $form['status'][$content->nid]['#value'] .= t('/spam');
535 }
536 $form['created'][$content->nid] = array('#value' => t('%time ago', array('%time' => format_interval($now - $content->changed))));
537 }
538 else { // comments
539 $items[$content->cid] = '';
540 $content->name = $content->uid ? $content->registered_name : $content->name;
541 $form['title'][$content->cid] = array('#value' => l($content->subject, 'node/'. $content->nid, array('title' => truncate_utf8($content->comment, 128)), NULL, 'comment-'. $content->cid) .' '. theme('mark', node_mark($content->nid, $content->timestamp)));
542 $form['author'][$content->cid] = array('#value' => theme('username', $content));
543 $form['status'][$content->cid] = array('#value' => ($content->status == COMMENT_PUBLISHED ? t('published') : t('not published')));
544 if ($content->spam_mark) {
545 $form['status'][$content->cid]['#value'] .= t('/spam');
546 }
547 $form['created'][$content->cid] = array('#value' => t('%time ago', array('%time' => format_interval($now - $content->timestamp))));
548 }
549 }
550
551 $form['mode'] = array('#type' => 'hidden', '#value' => $mode);
552 $form['submode'] = array('#type' => 'hidden', '#value' => $submode);
553 $form['items'] = array('#type' => 'checkboxes', '#options' => $items);
554 $form['pager'] = array('#value' => theme('pager', NULL, $records_per_page, 0));
555 return $form;
556 }
557
558 /**
559 * Theme callback; render the moderation queue form.
560 */
561 function theme_akismet_moderation_form($form) {
562 $mode = $form['mode']['#value'];
563 $submode = $form['submode']['#value'];
564 $output = drupal_render($form['options']);
565 $rows = array();
566 if (isset($form['author']) && is_array($form['author'])) {
567 foreach (element_children($form['author']) as $key) {
568 $row = array();
569 $row[] = array('data' => drupal_render($form['items'][$key]));
570 $row[] = drupal_render($form['title'][$key]);
571 if ($mode == 'nodes') {
572 $row[] = drupal_render($form['type'][$key]);
573 }
574 $row[] = drupal_render($form['author'][$key]);
575 $row[] = drupal_render($form['status'][$key]);
576 $row[] = drupal_render($form['created'][$key]);
577 $rows[] = $row;
578 }
579 }
580 else {
581 if ($submode == 'spam') {
582 $message = ($mode == 'nodes' ? t('There is no spam in the nodes moderation queue.') : t('There is no spam in the comments moderation queue.')) .'<br />'. t('It must be your lucky day! ;-)');
583 }
584 else if ($submode == 'unpublished') {
585 $message = ($mode == 'nodes' ? t('There are no unpublished nodes in the moderation queue.') : t('There are no unpublished comments in the moderation queue.'));
586 }
587 else { // published
588 $message = ($mode == 'nodes' ? t('There are no published nodes.') : t('There are no published comments.'));
589 }
590 $rows[] = array(array('data' => $message, 'align' => 'center', 'colspan' => ($mode == 'nodes' ? '6' : '5')));
591 }
592 $output .= theme('table', $form['header']['#value'], $rows);
593 if ($form['pager']['#value']) {
594 $output .= drupal_render($form['pager']);
595 }
596 $output .= drupal_render($form);
597 return $output;
598 }
599
600 /**
601 * Form API callback; Validate the moderation queue form.
602 */
603 function akismet_moderation_form_validate($form, &$form_state) {
604 $mode = $form_state['values']['mode'];
605 $submode = $form_state['values']['submode'];
606 $operation = $form_state['values']['operation'];
607 $valid_operations = akismet_moderator_operations($mode, $submode);
608
609 if (!isset($valid_operations[$operation])) {
610 form_set_error('', t('Please, choose a valid operation.'));
611 }
612 $form_state['values']['items'] = array_diff($form_state['values']['items'], array(0));
613 if (count($form_state['values']['items']) == 0) {
614 if ($operation == 'delete') {
615 form_set_error('', t('Please, select some items to perform the delete operation.'));
616 }
617 else {
618 form_set_error('', t('Please, select some items to perform the action on.'));
619 }
620 }
621 }
622
623 /**
624 * List the selected items and verify that the admin really wants to delete them.
625 */
626 function akismet_confirm_multiple_operation() {
627 $edit = $_POST;
628 $mode = $edit['mode'];
629 $submode = $edit['submode'];
630 $operation = $edit['operation'];
631 $valid_operations = akismet_moderator_operations($mode, $submode);
632
633 // Make sure we deal with a valid combination of mode, submode and operation.
634 if (!isset($valid_operations[$operation])) {
635 return;
636 }
637
638 $confirm_message = '<strong>'. $valid_operations[$operation]['confirm'] .'</strong>';
639 $confirm_button = $valid_operations[$operation]['button'];
640 $confirm_warning = '<p>'. (isset($valid_operations[$operation]['warning']) ? $valid_operations[$operation]['warning'] : '') .'</p>';
641 $content_type = ($mode == 'nodes' ? 'node' : 'comment');
642
643 $form = array();
644 $form['items'] = array('#prefix' => '<ul>', '#suffix' => '</ul>', '#tree' => TRUE);
645 // array_filter() returns only elements with actual values
646 foreach (array_filter($edit['items']) as $content_id => $value) {
647 if ($content = akismet_content_load($content_type, $content_id)) {
648 $title = '&quot;'. check_plain($content_type == 'node' ? $content->title : $content->subject) .'&quot;, '. t('by') .' '. theme('username', $content);
649 $form['items'][$content_id] = array('#type' => 'hidden', '#value' => $content_id, '#prefix' => '<li>', '#suffix' => $title .'</li>');
650 }
651 }
652 $form['mode'] = array('#type' => 'hidden', '#value' => $mode);
653 $form['submode'] = array('#type' => 'hidden', '#value' => $submode);
654 $form['operation'] = array('#type' => 'hidden', '#value' => $operation);
655
656 // Redirect to a non-existent menu item to make tabs disappear.
657 menu_set_active_item('');
658
659 $path = 'admin/content/akismet/'. $mode;
660 if ($submode != 'spam') {
661 $path .= '/'. $submode;
662 }
663 return confirm_form($form, $confirm_message, $path, $confirm_warning, $confirm_button, t('Cancel'));
664 }
665
666 /**
667 * confirm_form callback; perform the actual operation against selected content.
668 */
669 function akismet_confirm_multiple_operation_submit($form, &$form_state) {
670 $mode = $form_state['values']['mode'];
671 $submode = $form_state['values']['submode'];
672 $operation = $form_state['values']['operation'];
673 $valid_operations = akismet_moderator_operations($mode, $submode);
674
675 // Make sure we deal with a valid combination of mode, submode and operation.
676 if (!isset($valid_operations[$operation])) {
677 return 'admin/content/akismet';
678 }
679
680 if ($form_state['values']['confirm']) {
681 $content_type = ($mode == 'nodes' ? 'node' : 'comment');
682 foreach ($form_state['values']['items'] as $content_id => $value) {
683 if ($operation == 'delete') {
684 akismet_content_delete($content_type, $content_id);
685 $message = ($mode == 'nodes' ? t('The nodes have been deleted.') : t('The comments have been deleted.'));
686 }
687 else if ($content = akismet_content_load($content_type, $content_id)) {
688 if ($content_type == 'node') {
689 $is_published = ($content->status ? TRUE : FALSE);
690 }
691 else { // comment
692 $is_published = ($content->status == COMMENT_PUBLISHED ? TRUE : FALSE);
693 }
694 $is_spam = akismet_content_is_spam($content_type, $content_id);
695
696 if ($operation == 'submit-spam' && !$is_spam) {
697 akismet_content_spam_operation($content_type, $content, 'submit-spam');
698 }
699 else if ($operation == 'submit-ham' && $is_spam) {
700 akismet_content_spam_operation($content_type, $content, 'submit-ham');
701 }
702
703 if (in_array($operation, array('unpublish','submit-spam')) && $is_published) {
704 akismet_content_publish_operation($content_type, $content, 'unpublish');
705 }
706 else if (in_array($operation, array('publish','submit-ham')) && !$is_published) {
707 akismet_content_publish_operation($content_type, $content, 'publish');
708 }
709
710 $message = ($mode == 'nodes' ? t('The nodes have been updated.') : t('The comments have been updated.'));
711 }
712 }
713 drupal_set_message($message);
714 }
715
716 $path = 'admin/content/akismet/'. $mode;
717 if ($submode != 'spam') {
718 $path .= '/'. $submode;
719 }
720 return $path;
721 }

  ViewVC Help
Powered by ViewVC 1.1.2