/[drupal]/contributions/modules/guestbook/guestbook.module
ViewVC logotype

Contents of /contributions/modules/guestbook/guestbook.module

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


Revision 1.20 - (show annotations) (download) (as text)
Wed Jul 29 18:00:01 2009 UTC (4 months ago) by sun
Branch: MAIN
CVS Tags: HEAD
Changes since 1.19: +13 -3 lines
File MIME type: text/x-php
by sun: Added hook_guestbook() invocations.
1 <?php
2 // $Id: guestbook.module,v 1.19 2009/03/10 23:14:36 sun Exp $
3
4 if (module_exists("spam") == true) {
5 if (file_exists("modules/spam/spam.module")) {
6 include_once "modules/spam/spam.module";
7 }
8 else if (file_exists("sites/all/modules/spam/spam.module")) { include_once "sites/all/modules/spam/spam.module"; }
9 }
10
11 /**
12 * Flags for use in the "guestbook_mode" variable.
13 */
14 define('GUESTBOOK_SITE_GUESTBOOK', 0x0001);
15 define('GUESTBOOK_USER_GUESTBOOKS', 0x0002);
16
17 /**
18 * Flags for use in the "guestbook_pager_position" variable.
19 */
20 define('GUESTBOOK_PAGER_ABOVE', 0x0001);
21 define('GUESTBOOK_PAGER_BELOW', 0x0002);
22
23 define('GUESTBOOK_TEXTAREA_ROWS', 8);
24
25 /**
26 * Implementation of hook_menu().
27 */
28 function guestbook_menu() {
29 $items = array();
30 $guestbook_mode = variable_get('guestbook_mode', GUESTBOOK_SITE_GUESTBOOK | GUESTBOOK_USER_GUESTBOOKS);
31
32 $items['admin/settings/guestbook'] = array(
33 'title' => 'Guestbook',
34 'page callback' => 'drupal_get_form',
35 'page arguments' => array('guestbook_admin_settings'),
36 'access arguments' => array('administer site configuration'),
37 );
38
39 // User guestbooks.
40 if ($guestbook_mode & GUESTBOOK_USER_GUESTBOOKS) {
41 $items['guestbooks'] = array(
42 'title' => 'Guestbooks',
43 'page callback' => 'guestbook_list',
44 'access arguments' => array('access user guestbooks'),
45 );
46 $items['user/%user/guestbook'] = array(
47 'title' => 'User guestbook',
48 'title callback' => '_guestbook_info',
49 'title arguments' => array(1, 'title'),
50 'page callback' => 'guestbook_page',
51 'page arguments' => array(1),
52 'access callback' => 'user_access',
53 'access arguments' => array('access user guestbooks'),
54 'type' => MENU_LOCAL_TASK,
55 );
56 $items['user/%user/guestbook/sign'] = array(
57 'title' => 'Add guestbook entry',
58 'page callback' => 'guestbook_page_form',
59 'page arguments' => array(1),
60 'access arguments' => array('post in user guestbooks'),
61 'type' => MENU_CALLBACK,
62 );
63 }
64 // Site guestbook.
65 if ($guestbook_mode & GUESTBOOK_SITE_GUESTBOOK) {
66 $items['guestbook'] = array(
67 'title' => variable_get('guestbook_site_title', t('Site guestbook')),
68 'page callback' => 'guestbook_page',
69 'page arguments' => array(0),
70 'access arguments' => array('access site guestbook'),
71 );
72 $items['guestbook/sign'] = array(
73 'title' => 'Add guestbook entry',
74 'page callback' => 'guestbook_page_form',
75 'page arguments' => array(0),
76 'access arguments' => array('post in site guestbook'),
77 'type' => MENU_CALLBACK,
78 );
79 }
80
81 return $items;
82 }
83
84 /**
85 * Implementation of hook_user().
86 */
87 function guestbook_user($op, &$edit, &$user, $category = '') {
88 $guestbook_mode = variable_get('guestbook_mode', GUESTBOOK_SITE_GUESTBOOK | GUESTBOOK_USER_GUESTBOOKS);
89 if ($guestbook_mode & GUESTBOOK_USER_GUESTBOOKS) {
90 switch ($op) {
91 case 'view':
92 if (user_access('access user guestbooks') && empty($user->guestbook_status)) {
93 $title = t("Read @username's guestbook.", array('@username' => $user->name));
94 $link = l(t('View recent guestbook entries'), "user/$user->uid/guestbook", array('attributes' => array('title' => $title)));
95 $user->content['summary']['guestbook'] = array(
96 '#type' => 'user_profile_item',
97 '#title' => t('Guestbook'),
98 '#value' => $link,
99 '#attributes' => array('class' => 'guestbook'),
100 );
101 }
102 break;
103
104 case 'form':
105 if ($category == 'account') {
106 $form['guestbook'] = array(
107 '#type' => 'fieldset',
108 '#title' => t('User guestbook'),
109 );
110 $form['guestbook']['guestbook_status'] = array(
111 '#type' => 'radios',
112 '#title' => t('Status'),
113 '#default_value' => isset($edit['guestbook_status']) ? $edit['guestbook_status'] : 0,
114 '#options' => array(t('Enabled'), t('Disabled')),
115 );
116 $form['guestbook']['guestbook_send_email'] = array(
117 '#type' => 'checkbox',
118 '#title' => t('Send email notification'),
119 '#description' => t("Uncheck if you don't wish to be notified of new entries to your guestbook."),
120 '#default_value' => isset($edit['guestbook_send_email']) ? $edit['guestbook_send_email'] : 0,
121 );
122 $form['guestbook']['guestbook_intro'] = array(
123 '#type' => 'textarea',
124 '#title' => t('Intro text'),
125 '#default_value' => isset($edit['guestbook_intro']) ? $edit['guestbook_intro'] : '',
126 '#cols' => 70,
127 '#rows' => GUESTBOOK_TEXTAREA_ROWS,
128 '#description' => t('The text that appears on top of your guestbook.'),
129 );
130 return $form;
131 }
132 break;
133
134 case 'delete':
135 db_query("DELETE FROM {guestbook} WHERE recipient = %d", $user->uid);
136 db_query("UPDATE {guestbook} SET author = 0 WHERE author = %d", $user->uid);
137 db_query("UPDATE {guestbook} SET commentauthor = 0 WHERE commentauthor = %d", $user->uid);
138 break;
139 }
140 }
141 }
142
143 /**
144 * Implementation of hook_perm().
145 */
146 function guestbook_perm() {
147 return array(
148 'access site guestbook',
149 'access user guestbooks',
150 'post in site guestbook',
151 'post in user guestbooks',
152 'moderate all guestbooks',
153 'moderate own guestbook',
154 );
155 }
156
157 /**
158 * Implementation of hook_help().
159 */
160 function guestbook_help($path, $arg) {
161 switch ($path) {
162 case 'admin/modules#description':
163 return t('Adds a site guestbook and individual user guestbooks.');
164 }
165 }
166
167 /**
168 * Implementation of hook_settings().
169 */
170 function guestbook_admin_settings() {
171 $form['guestbook_mode'] = array(
172 '#type' => 'radios',
173 '#title' => t('Mode'),
174 '#default_value' => variable_get('guestbook_mode', GUESTBOOK_SITE_GUESTBOOK | GUESTBOOK_USER_GUESTBOOKS),
175 '#options' => array(
176 GUESTBOOK_SITE_GUESTBOOK | GUESTBOOK_USER_GUESTBOOKS => t('Site and user guestbooks'),
177 GUESTBOOK_SITE_GUESTBOOK => t('Site guestbook only'),
178 GUESTBOOK_USER_GUESTBOOKS => t('User guestbooks only'),
179 ),
180 );
181
182 // Site guestbook.
183 $form['site_guestbook'] = array(
184 '#type' => 'fieldset',
185 '#title' => t('Site guestbook'),
186 );
187 $form['site_guestbook']['guestbook_site_title'] = array(
188 '#type' => 'textfield',
189 '#title' => t('Title'),
190 '#default_value' => variable_get('guestbook_site_title', 'Site guestbook'),
191 '#size' => 30,
192 '#maxlength' => 128,
193 '#description' => t("The site guestbook's page title."),
194 );
195 $form['site_guestbook']['guestbook_site_intro'] = array(
196 '#type' => 'textarea',
197 '#title' => t('Intro text'),
198 '#default_value' => variable_get('guestbook_site_intro', ''),
199 '#cols' => 70,
200 '#rows' => GUESTBOOK_TEXTAREA_ROWS,
201 '#description' => t('The text that appears on top of the site guestbook.'),
202 );
203 $form['site_guestbook']['guestbook_send_email'] = array(
204 '#type' => 'textfield',
205 '#title' => t('Send an notification to the following e-mail address about new guestbook entries'),
206 '#description' => t("Leave blank if you don't wish to be notified"),
207 '#size' => 30,
208 '#maxlength' => 128,
209 '#default_value' => variable_get('guestbook_send_email', ''),
210 );
211
212 // User guestbooks.
213 $form['user_guestbooks'] = array(
214 '#type' => 'fieldset',
215 '#title' => t('User guestbooks'),
216 '#description' => t('Users can individually disable their guestbook or add an intro text on the user account page.'),
217 );
218
219 $form['user_guestbooks']['guestbook_user_link_to'] = array(
220 '#type' => 'radios',
221 '#title' => t('User link to profile or guestbook'),
222 '#description' => t('When displaying a user should the link show the user profile or the user guestbook?'),
223 '#options' => array('profile' => t('User profile'), 'guestbook' => t('User guestbook')),
224 '#default_value' => variable_get('guestbook_user_link_to', 'profile'),
225 );
226
227 // Display options.
228 $form['display_options'] = array(
229 '#type' => 'fieldset',
230 '#title' => t('Display options'),
231 );
232 $form['display_options']['guestbook_entries_per_page'] = array(
233 '#type' => 'textfield',
234 '#title' => t('Entries per page'),
235 '#default_value' => variable_get('guestbook_entries_per_page', 20),
236 '#size' => 3,
237 '#maxlength' => 3,
238 '#description' => t('The number of guestbook entries per page.'),
239 );
240 $form['display_options']['guestbook_display'] = array(
241 '#type' => 'checkboxes',
242 '#title' => t('Toggle display'),
243 '#default_value' => variable_get('guestbook_display', array('date', 'email', 'website', 'comments')),
244 '#options' => array(
245 'date' => t('Submission date'),
246 'email' => t('Anonymous poster e-mail'),
247 'website' => t('Anonymous poster website'),
248 'comments' => t('Comments'),
249 ),
250 );
251 $form['display_options']['guestbook_pager_position'] = array(
252 '#type' => 'radios',
253 '#title' => t('Position of pager'),
254 '#default_value' => variable_get('guestbook_pager_position', GUESTBOOK_PAGER_BELOW),
255 '#options' => array(
256 GUESTBOOK_PAGER_ABOVE => t('Above the entries'),
257 GUESTBOOK_PAGER_BELOW => t('Below the entries'),
258 GUESTBOOK_PAGER_ABOVE | GUESTBOOK_PAGER_BELOW => t('Above and below the entries'),
259 ),
260 );
261
262 // Posting settings.
263 $form['posting_settings'] = array(
264 '#type' => 'fieldset',
265 '#title' => t('Posting settings'),
266 );
267 $form['posting_settings']['guestbook_input_format'] = filter_form(variable_get('guestbook_input_format', 0), NULL, array('guestbook_input_format'));
268 $form['posting_settings']['guestbook_input_format']['#type'] = 'item';
269 $form['posting_settings']['guestbook_filter_tips'] = array(
270 '#type' => 'checkbox',
271 '#title' => t('Display filter tips'),
272 '#default_value' => variable_get('guestbook_filter_tips', TRUE),
273 '#description' => t('If enabled filter tips are displayed below the message textarea.'),
274 );
275 $form['posting_settings']['guestbook_anonymous_fields'] = array(
276 '#type' => 'checkboxes',
277 '#title' => t('Anonymous poster fields'),
278 '#default_value' => variable_get('guestbook_anonymous_fields', array('email', 'website')),
279 '#description' => t('Additional information that anonymous posters may supply.'),
280 '#options' => array(
281 'email' => 'E-mail',
282 'website' => 'Website',
283 ),
284 );
285 $form['posting_settings']['guestbook_form_location'] = array(
286 '#type' => 'radios',
287 '#title' => t('Location of entry submission form'),
288 '#default_value' => variable_get('guestbook_form_location', 'above'),
289 '#options' => array(
290 'above' => t('Above entries'),
291 'below' => t('Below entries'),
292 'separate page' => t('Separate page'),
293 ),
294 );
295
296 $form['array_filter'] = array('#type' => 'value', '#value' => TRUE);
297
298 return system_settings_form($form);
299 }
300
301 /**
302 * Output a guestbook page; menu callback.
303 */
304 function guestbook_page($account, $op = NULL, $op_id = NULL, $page = TRUE) {
305 global $user;
306
307 // Prepare site guestbook.
308 if ($account == 0) {
309 $account = new stdClass;
310 $account->uid = 0;
311 drupal_set_title(variable_get('guestbook_site_title', t('Site guestbook')));
312 }
313
314 if (!_guestbook_exists($account->uid)) {
315 if ($page) {
316 drupal_not_found();
317 }
318 return;
319 }
320
321 // Set last visited time for own guestbook
322 if ($account->uid > 0 && $account->uid == $user->uid) {
323 user_save($user, array('guestbook_visited' => time()));
324 }
325
326 // Delete or comment an entry
327 $comment_entry = $sql_where = '';
328 if (_guestbook_access('moderate', $account->uid) && is_numeric($op_id)) {
329 switch ($op) {
330 case 'edit':
331 return drupal_get_form('guestbook_form_entry_form', $account->uid, 'page', $op_id);
332
333 case 'delete':
334 return guestbook_delete_entry_confirm_page($account->uid, $op_id);
335
336 case 'comment':
337 $comment_entry = $op_id;
338 $sql_where = ' AND g.id = %d';
339 break;
340 }
341 }
342
343 // Fetch guestbook entries
344 $limit = variable_get('guestbook_entries_per_page', 20);
345 $sql = "SELECT g.*, u1.uid, u1.name, u1.data, u1.picture, u2.name as commentby
346 FROM {guestbook} g
347 LEFT JOIN {users} u1 ON g.author = u1.uid
348 LEFT JOIN {users} u2 ON g.commentauthor = u2.uid
349 WHERE g.recipient = %d $sql_where
350 ORDER BY g.created DESC";
351 if (!empty($comment_entry)) {
352 // Fetch only guestbook entry for administrative comment.
353 $result = db_query($sql, $uid, $comment_entry);
354 }
355 else {
356 $result = pager_query($sql, $limit, 0, "SELECT COUNT(*) FROM {guestbook} WHERE recipient = %d", $account->uid);
357 }
358 $entries = array();
359 while ($entry = db_fetch_array($result)) {
360 $entries[] = $entry;
361 }
362
363 return theme('guestbook', $account->uid, $entries, $comment_entry, $limit);
364 }
365
366 /**
367 * Display the guestbook form on a separate page; menu callback.
368 */
369 function guestbook_page_form($account) {
370 if (!_guestbook_exists($account->uid)) {
371 drupal_not_found();
372 return;
373 }
374 return guestbook_form_entry($account->uid, 'page');
375 }
376
377 /**
378 * Output a list of all guestbooks; menu callback.
379 */
380 function guestbook_list() {
381 $limit = 40;
382 $guestbooks = array();
383 $guestbook_mode = variable_get('guestbook_mode', GUESTBOOK_SITE_GUESTBOOK | GUESTBOOK_USER_GUESTBOOKS);
384
385 $header = array(
386 array('data' => t('user'), 'field' => 'u.name'),
387 array('data' => t('entries'), 'field' => 'num'),
388 array('data' => t('last update'), 'field' => 'created', 'sort' => 'desc'),
389 );
390 $result = pager_query(
391 "SELECT u.uid, u.name, u.data, MAX(g.created) as created, COUNT(g.recipient) as num
392 FROM {users} u
393 LEFT OUTER JOIN {guestbook} g ON u.uid = g.recipient
394 GROUP BY u.uid, u.name, u.data, g.recipient". tablesort_sql($header),
395 $limit, 0, "SELECT COUNT(*) FROM {users}"
396 );
397
398 while ($guestbook = db_fetch_array($result)) {
399 if ($guestbook['uid'] == 0 && user_access('access site guestbook') && $guestbook_mode & GUESTBOOK_SITE_GUESTBOOK) {
400 // Site guestbook.
401 $guestbooks[0] = $guestbook;
402 }
403 else if ($guestbook['uid'] > 0 && user_access('access user guestbooks')) {
404 // User guestbooks.
405 $data = unserialize($guestbook['data']);
406 if (empty($data['guestbook_status'])) {
407 $guestbooks[$guestbook['uid']] = $guestbook;
408 }
409 }
410 }
411 return theme('guestbook_list', $guestbooks, $header, $limit);
412 }
413
414 /**
415 * Retrieve a guestbook post form.
416 */
417 function guestbook_form_entry($uid, $display = '') {
418 return drupal_get_form('guestbook_form_entry_form', $uid, $display);
419 }
420
421 /**
422 * Form builder function for guestbook post form.
423 */
424 function guestbook_form_entry_form($form_state, $uid, $display = '', $entry_id = NULL) {
425 global $user;
426
427 $entry = array();
428 if (isset($entry_id) && _guestbook_access('moderate', $uid) && user_access('moderate own guestbook')) {
429 $entry = db_fetch_array(db_query("SELECT * FROM {guestbook} WHERE id = %d", $entry_id));
430 }
431
432 $form = array();
433 if (!empty($entry)) {
434 $form['entry_id'] = array('#type' => 'value', '#value' => $entry['id']);
435 $form['author'] = array('#type' => 'value', '#value' => $entry['author']);
436 // Re-route form submission to guestbook entry edit form submit handler.
437 $form['#submit'] = array('guestbook_form_entry_form_edit_submit');
438 }
439 if ($user->uid == 0 || (isset($entry['author']) && $entry['author'] == 0)) {
440 // fields for anonymous poster
441 $form['anonname'] = array(
442 '#type' => 'textfield', '#title' => t('Name'),
443 '#size' => 32, '#maxlength' => 64, '#required' => TRUE,
444 '#default_value' => !empty($entry['anonname']) ? $entry['anonname'] : '',
445 );
446 $anonymous_fields = (array) variable_get('guestbook_anonymous_fields', array('email', 'website'));
447 if (in_array('email', $anonymous_fields)) {
448 $form['anonemail'] = array(
449 '#type' => 'textfield', '#title' => t('E-mail'),
450 '#size' => 32, '#maxlength' => 128,
451 '#default_value' => !empty($entry['anonemail']) ? $entry['anonemail'] : '',
452 );
453 }
454 if (in_array('website', $anonymous_fields)) {
455 $form['anonwebsite'] = array(
456 '#type' => 'textfield', '#title' => t('Homepage'),
457 '#size' => 32, '#maxlength' => 128,
458 '#default_value' => !empty($entry['anonwebsite']) ? $entry['anonwebsite'] : '',
459 );
460 }
461 }
462 $filter_tips = variable_get('guestbook_filter_tips', TRUE) ? _guestbook_form_filter_tips() : NULL;
463 $form['message'] = array(
464 '#type' => 'textarea', '#title' => t('Message'),
465 '#cols' => 32, '#rows' => GUESTBOOK_TEXTAREA_ROWS, '#description' => $filter_tips, '#required' => TRUE,
466 '#default_value' => !empty($entry['message']) ? $entry['message'] : '',
467 );
468 $form['submit'] = array(
469 '#type' => 'submit', '#value' => t('Send'),
470 );
471 $form['uid'] = array(
472 '#type' => 'value', '#value' => $uid,
473 );
474 if (!empty($entry)) {
475 // Need to explicitly check for moderate when editing an existing post,
476 // because FAPI will output a WSOD (NULL) otherwise.
477 $form['#access'] = (_guestbook_access('moderate', $uid) ? TRUE : FALSE);
478 }
479 else {
480 $form['#access'] = (_guestbook_access('post', $uid) == 'allowed' ? TRUE : FALSE);
481 }
482 if (variable_get('guestbook_form_location', 'above') == 'separate page') {
483 $form['#redirect'] = !empty($_GET['destination']) ? $_GET['destination'] : guestbook_path($uid);
484 }
485 $form['display'] = array(
486 '#type' => 'value', '#value' => $display,
487 );
488 return $form;
489 }
490
491 function guestbook_form_entry_form_submit($form, &$form_state) {
492 global $user;
493
494 $uid = $form_state['values']['uid'];
495 $message = $form_state['values']['message'];
496
497 // Make sure this isn't a dupe.
498 $result = db_query("SELECT message FROM {guestbook} WHERE recipient = %d ORDER BY id DESC LIMIT 1", $uid);
499 $entry = db_fetch_array($result);
500 if ($entry['message'] == $message) {
501 return;
502 }
503 // No empty entries.
504 if ($message == '') {
505 return;
506 }
507
508 if (module_exists('spam')) {
509 // Is this spam?
510 $spamcheck = $form_state['values']['anonname'] .' '. $form_state['values']['anonemail'] .' '. $form_state['values']['anonwebsite'];
511 if (spam_content_filter('guestbook', 1, $spamcheck, $message, '_guestbook_spam')) {
512 return;
513 }
514 }
515
516 // E-mail notification.
517 $iSendEmail = '';
518 $guestbook_mode = variable_get('guestbook_mode', GUESTBOOK_SITE_GUESTBOOK | GUESTBOOK_USER_GUESTBOOKS);
519 if ($uid == 0 && ($guestbook_mode & GUESTBOOK_SITE_GUESTBOOK)) {
520 $iSendEmail = variable_get('guestbook_send_email', '');
521 }
522 else if ($guestbook_mode & GUESTBOOK_USER_GUESTBOOKS) {
523 $guestbook_user = ($uid != $user->uid) ? user_load(array('uid' => $uid, 'status' => 1)) : $user;
524 if ($guestbook_user->uid && empty($guestbook_user->guestbook_status) && !empty($guestbook_user->guestbook_send_email)) {
525 $iSendEmail = $guestbook_user->mail;
526 }
527 }
528
529 if ($iSendEmail) {
530 $params = array();
531 $params['body'] = $message;
532 $params['account'] = user_load(array('uid' => $uid));
533 drupal_mail('guestbook', 'notification', $iSendEmail, user_preferred_language($params['account']), $params);
534 }
535
536 // Insert new message
537 if ($user->uid == 0) {
538 // Anonymous user.
539 db_query("INSERT INTO {guestbook} (anonname, anonemail, anonwebsite, author, recipient, message, created)
540 VALUES('%s', '%s', '%s', %d, %d, '%s', %d)", $form_state['values']['anonname'], $form_state['values']['anonemail'], $form_state['values']['anonwebsite'], 0, $uid, $message, time());
541 }
542 else {
543 // Authenticated user.
544 db_query("INSERT INTO {guestbook} (author, recipient, message, created)
545 VALUES(%d, %d, '%s', %d)", $user->uid, $uid, $message, time());
546 }
547
548 // Notify other modules of the new guestbook entry.
549 $entryid = db_last_insert_id('guestbook', 'id');
550 $entry = db_fetch_array(db_query("SELECT * FROM {guestbook} WHERE id = %d", $entryid));
551 module_invoke_all('guestbook', 'insert', $entry);
552
553 drupal_set_message(t('Your message has been added.'));
554 }
555
556 /**
557 * Submit handler for editing guestbook entries.
558 */
559 function guestbook_form_entry_form_edit_submit($form, &$form_state) {
560 if (_guestbook_access('moderate', $form_state['values']['uid']) && $form_state['values']['submit'] == t('Send') && user_access('moderate own guestbook')) {
561 if ($form_state['values']['author'] == 0) {
562 // Post's author is an anonymous user.
563 db_query("UPDATE {guestbook} SET anonname = '%s', anonemail = '%s', anonwebsite = '%s', message = '%s' WHERE id = %d", $form_state['values']['anonname'], $form_state['values']['anonemail'], $form_state['values']['anonwebsite'], $form_state['values']['message'], $form_state['values']['entry_id']);
564 }
565 else if ($form_state['values']['author'] > 0) {
566 // Post's author is a registered user.
567 db_query("UPDATE {guestbook} SET message = '%s' WHERE id = %d", $form_state['values']['message'], $form_state['values']['entry_id']);
568 }
569 }
570
571 // Notify other modules of the new guestbook entry.
572 $entry = db_fetch_array(db_query("SELECT * FROM {guestbook} WHERE id = %d", $form_state['values']['entry_id']));
573 module_invoke_all('guestbook', 'update', $entry);
574
575 $form_state['redirect'] = guestbook_path($form_state['values']['uid']);
576 }
577
578 /**
579 * Implementation of hook_mail().
580 */
581 function guestbook_mail($key, &$message, $params) {
582 $language = $message['language'];
583 $variables = user_mail_tokens($params['account'], $language);
584 switch($key) {
585 case 'notification':
586 $message['subject'] = t('New guestbook entry at !site', $variables, $language->language);
587 $message['body'] = drupal_html_to_text($params['body']);
588 break;
589 }
590 }
591
592 /**
593 * Implementation of hook_theme()
594 */
595 function guestbook_theme() {
596 return array(
597 'guestbook_form_entry_form' => array(
598 'arguments' => array('form'),
599 ),
600 'guestbook_form_comment_form' => array(
601 'arguments' => array('form'),
602 ),
603 'guestbook' => array(
604 'arguments' => array('uid', 'entries', 'comment_entry', 'limit'),
605 ),
606 'guestbook_entry' => array(
607 'arguments' => array('uid', 'entry', 'comment_entry', 'zebra', 'confirm_delete'),
608 ),
609 'guestbook_user_picture' => array(
610 'arguments' => array('form'),
611 ),
612 'guestbook_entry_comment' => array(
613 'arguments' => array('uid', 'entry', 'comment_entry'),
614 ),
615 'guestbook_list' => array(
616 'arguments' => array('guestbooks', 'header', 'limit'),
617 ),
618 );
619 }
620
621 function theme_guestbook_form_entry_form($form_state) {
622 $output = '';
623 // @todo Since #access is set on the overall form now, this function along
624 // with the switch below is no longer executed.
625 $access = $form_state['access']['#value'];
626 $display = $form_state['display']['#value'];
627 $uid = $form_state['uid']['#value'];
628
629 switch ($access) {
630 case 'allowed':
631 if ($display == 'link') {
632 // Output only a link to a page with the form.
633 $output .= '<p>&raquo; '. l(t('Add guestbook entry'), guestbook_path($uid) .'/sign') .'</p>';
634 }
635 else {
636 $output .= $display == 'page' ? '' : '<h3>'. t('Add guestbook entry') .'</h3>';
637 $output .= drupal_render($form_state);
638 }
639 break;
640
641 case 'own guestbook':
642 if (isset($form_state['entry_id'])) {
643 drupal_set_title(t('Edit guestbook entry'));
644 $output .= drupal_render($form_state);
645 }
646 else {
647 $output .= ' ';
648 }
649 break;
650
651 case 'not logged in':
652 $output .= '<p class="links">&raquo; '. t('You must be logged in to post a comment.') .'</p>';
653 break;
654
655 case 'not allowed':
656 $output .= '<p class="links">&raquo; '. t('You are not allowed to post in this guestbook.') .'</p>';
657 break;
658 }
659 return $output;
660 }
661
662 function guestbook_form_comment($uid, $entry) {
663 return drupal_get_form('guestbook_form_comment_form', $uid, $entry);
664 }
665
666 function guestbook_form_comment_form($form_state, $uid, $entry) {
667 $form = array();
668 $form['comment'] = array(
669 '#type' => 'textarea',
670 '#default_value' => $entry['comment'],
671 '#description' => variable_get('guestbook_filter_tips', TRUE) ? _guestbook_form_filter_tips() : NULL,
672 );
673 $form['submit'] = array(
674 '#type' => 'submit',
675 '#value' => t('Reply'),
676 );
677 $form['entry_id'] = array('#type' => 'value', '#value' => $entry['id']);
678 $form['uid'] = array('#type' => 'value', '#value' => $uid);
679 $form['#redirect'] = !empty($_GET['destination']) ? $_GET['destination'] : guestbook_path($uid);
680 return $form;
681 }
682
683 function guestbook_form_comment_form_submit($form, &$form_state) {
684 global $user;
685 if (_guestbook_access('moderate', $form_state['values']['uid'])) {
686 db_query("UPDATE {guestbook} SET comment = '%s', commentauthor = %d WHERE id = %d", $form_state['values']['comment'], $user->uid, $form_state['values']['entry_id']);
687 }
688 }
689
690 function guestbook_delete_entry_confirm_page($uid, $entry_id) {
691 return drupal_get_form('guestbook_delete_entry_confirm', $uid, $entry_id);
692 }
693
694 function guestbook_delete_entry_confirm($form_state, $uid, $entry_id) {
695 $entry = db_fetch_array(db_query(
696 "SELECT g.*, u1.name, u1.data, u1.picture, u2.name as commentby
697 FROM {guestbook} g
698 LEFT JOIN {users} u1 ON g.author = u1.uid
699 LEFT JOIN {users} u2 ON g.commentauthor = u2.uid
700 WHERE g.id = %d", $entry_id));
701
702 $form = array();
703 $form['entry_id'] = array('#type' => 'value', '#value' => $entry_id);
704 $form['uid'] = array('#type' => 'value', '#value' => $uid);
705 $form['#redirect'] = !empty($_GET['destination']) ? $_GET['destination'] : guestbook_path($uid);
706 return confirm_form(
707 $form,
708 t('Are you sure you want to delete this guestbook entry?'),
709 !empty($_GET['destination']) ? $_GET['destination'] : referer_uri(),
710 theme('guestbook_entry', $uid, $entry, NULL, NULL, TRUE),
711 t('Delete'), t('Cancel')
712 );
713 }
714
715 function guestbook_delete_entry_confirm_submit($form, &$form_state) {
716 if (_guestbook_access('moderate', $form_state['values']['uid']) && $form_state['values']['confirm']) {
717 db_query("DELETE FROM {guestbook} WHERE id = %d", $form_state['values']['entry_id']);
718 }
719 }
720
721 /**
722 * Render a guestbook.
723 */
724 function theme_guestbook($uid, $entries, $comment_entry, $limit = 20) {
725 global $user;
726 $form_location = variable_get('guestbook_form_location', 'above');
727 $pager_position = variable_get('guestbook_pager_position', GUESTBOOK_PAGER_BELOW);
728
729 // Intro text.
730 $intro = _guestbook_info($uid, 'intro');
731 $output = $intro ? check_markup($intro) : '';
732 if ($_GET['q'] != 'user/'. $uid) {
733 $output .= _guestbook_user_profile_link($uid);
734 }
735
736 // Form on separate page.
737 $output .= ($form_location == 'separate page' ? guestbook_form_entry($uid, 'link') : '');
738 // Form and pager above entries.
739 $output .= ($form_location == 'above' ? guestbook_form_entry($uid) : '');
740 $output .= ($pager_position & GUESTBOOK_PAGER_ABOVE ? theme('pager', NULL, $limit, 0) : '');
741
742 $i = 0;
743 foreach ($entries as $entry) {
744 $zebra = ($i % 2) ? 'odd' : 'even';
745 $output .= theme('guestbook_entry', $uid, $entry, $comment_entry, $zebra);
746 $i++;
747 }
748
749 // Form and pager below entries.
750 $output .= $pager_position & GUESTBOOK_PAGER_BELOW ? theme('pager', NULL, $limit, 0) : '';
751 $output .= $form_location == 'below' ? guestbook_form_entry($uid) : '';
752
753 if ($output == '') {
754 $output = '<div class="guestbook-empty">'. t('Nobody has signed this guestbook yet.') .'</div>';
755 }
756
757 return '<div class="guestbook">'. $output ."</div>\n";
758 }
759
760 function theme_guestbook_entry($uid, $entry, $comment_entry = NULL, $zebra, $confirm_delete = false) {
761 global $user;
762 $output = '';
763 $display = (array) variable_get('guestbook_display', array('date', 'email', 'website', 'comments'));
764
765 $output .= "\n<div class=\"guestbook-entry clear-block $zebra\">\n";
766 if ($comment_entry == $entry['id']) {
767 $output .= '<a name="comment-entry"></a>';
768 }
769
770 // Author.
771 if ($entry['author'] == 0) {
772 $output .= "<b>". check_plain($entry['anonname']) ."</b>";
773 }
774 else {
775 $output .= theme('username', (object)$entry, 'guestbook');
776 }
777
778 // Date, email, website.
779 $output .= '<div class="submitted">';
780 if (in_array('date', $display)) {
781 $output .= format_date($entry['created'], 'medium');
782 }
783 if (in_array('email', $display) && !empty($entry['anonemail'])) {
784 $output .= '&nbsp;|&nbsp;<a href="mailto:'. check_url($entry['anonemail']) .'">'. t('E-mail') .'</a>';
785 }
786 if (in_array('website', $display) && !empty($entry['anonwebsite'])) {
787 // Auto-prepend HTTP protocol if website contains no protocol.
788 if (strpos($entry['anonwebsite'], '://') === FALSE) {
789 $entry['anonwebsite'] = 'http://'. $entry['anonwebsite'];
790 }
791 $output .= '&nbsp;|&nbsp;<a href="'. check_url($entry['anonwebsite']) .'">'. t('Website') .'</a>&nbsp;';
792 }
793 $output .= '</div>';
794
795 // Message.
796 $output .= '<div class="guestbook-message">'. check_markup($entry['message'], variable_get('guestbook_input_format', 1), FALSE) .'</div>';
797
798 // Guestbook owner comment.
799 $output .= theme('guestbook_entry_comment', $uid, $entry, $comment_entry);
800
801 // Links.
802 if (_guestbook_access('moderate', $uid) && !$confirm_delete) {
803 if ($comment_entry != $entry['id']) {
804 $links = array();
805 $pager = !empty($_GET['page']) ? '&page='. $_GET['page'] : '';
806 if (user_access('moderate own guestbook') || user_access('moderate all guestbooks')) {
807 $links['delete'] = array(
808 'title' => t('Delete entry'),
809 'href' => guestbook_path($uid) .'/delete/'. $entry['id'],
810 'query' => 'destination='. url($_GET['q']) . $pager,
811 );
812 $links['edit'] = array(
813 'title' => t('Edit entry'),
814 'href' => guestbook_path($uid) .'/edit/'. $entry['id'],
815 'query' => 'destination='. url($_GET['q']) . $pager,
816 );
817 }
818 $links['comment'] = array(
819 'title' => $entry['comment'] == '' ? t('Add comment') : t('Edit comment'),
820 'href' => guestbook_path($uid) .'/comment/'. $entry['id'],
821 'query' => 'destination='. url($_GET['q']) . $pager,
822 'fragment' => 'comment-entry',
823 );
824 $output .= theme('links', $links, array('class' => 'guestbook-links'));
825 }
826 }
827
828 $output .= "\n</div>";
829 return $output;
830 }
831
832 function theme_guestbook_entry_comment($uid, $entry, $comment_entry) {
833 $display = (array) variable_get('guestbook_display', array('date', 'email', 'website', 'comments'));
834 $output = '';
835 if ($comment_entry == $entry['id']) {
836 // Display owner comment edit form.
837 $output .= guestbook_form_comment($uid, $entry);
838 }
839 else if (in_array('comments', $display) && $entry['comment'] != '') {
840 // Display owner comment.
841 $author = user_access('access user profiles') ? l($entry['commentby'], "user/{$entry['commentauthor']}") : $entry['commentby'];
842 $output .= '<div class="guestbook-comment-submitted">';
843 $output .= t('Comment by') .' '. $author;
844 $output .= '</div>';
845 $output .= '<div class="guestbook-comment-content">';
846 $output .= check_markup($entry['comment'], variable_get('guestbook_input_format', 1), FALSE);
847 $output .= '</div>';
848 }
849 return (!empty($output) ? '<div class="guestbook-comment">'. $output .'</div>' : '');
850 }
851
852 function theme_guestbook_list($guestbooks, $header, $limit = 40) {
853 $output = '';
854 // Site guestbook.
855 if (isset($guestbooks[0])) {
856 $output .= '<p>'. l(variable_get('guestbook_site_title', t('Site guestbook')), 'guestbook');
857 $output .= ' ('. format_plural($guestbooks[0]['num'], '1 entry', '@count entries') .', '. t('last update') .': '. _guestbook_timeinterval($guestbooks[0]['created']) .')</p>';
858 unset($guestbooks[0]);
859 }
860 // User guestbooks.
861 if (count($guestbooks)) {
862 $output .= '<h4>'. t('User guestbooks') .'</h4>';
863 $rows = array();
864 foreach ($guestbooks as $guestbook) {
865 $rows[] = array(
866 l($guestbook['name'], guestbook_path($guestbook['uid'])),
867 format_plural($guestbook['num'], '1 entry', '@count entries'),
868 array('data' => _guestbook_timeinterval($guestbook['created']), 'align' => 'right'),
869 );
870 }
871 $output .= theme('table', $header, $rows);
872 }
873 $output .= theme('pager', NULL, $limit, 0);
874 return $output;
875 }
876
877 /**
878 * Returns the title or the intro text of the guestbook specified by $uid.
879 */
880 function _guestbook_info($uid, $data) {
881 global $user;
882 static $info;
883 $guestbook_mode = variable_get('guestbook_mode', GUESTBOOK_SITE_GUESTBOOK | GUESTBOOK_USER_GUESTBOOKS);
884
885 if (is_object($uid)) {
886 $uid = $uid->uid;
887 }
888 if (!isset($info[$uid])) {
889 if ($uid == 0 && ($guestbook_mode & GUESTBOOK_SITE_GUESTBOOK)) {
890 $info[$uid]['title'] = variable_get('guestbook_site_title', t('Site guestbook'));
891 $info[$uid]['intro'] = variable_get('guestbook_site_intro', '');
892 }
893 else if ($guestbook_mode & GUESTBOOK_USER_GUESTBOOKS) {
894 $guestbook_user = ($uid != $user->uid ? user_load(array('uid' => $uid)) : $user);
895 if ($guestbook_user->uid && ($guestbook_user->status || user_access('administer users')) && empty($guestbook_user->guestbook_status)) {
896 if ($uid != $user->uid) {
897 // Guestbook of other users.
898 $info[$uid]['title'] = t("@username's guestbook", array('@username' => $guestbook_user->name));
899 $info[$uid]['intro'] = !empty($guestbook_user->guestbook_intro) ? $guestbook_user->guestbook_intro : '';
900 }
901 else {
902 // Own guestbook.
903 $unread = _guestbook_newentries();
904 $info[$uid]['title'] = t('My guestbook') . ($unread ? ' ('. $unread .')' : '');
905 $info[$uid]['intro'] = !empty($guestbook_user->guestbook_intro) ? $guestbook_user->guestbook_intro : '';
906 }
907 }
908 }
909 }
910 return $info[$uid][$data];
911 }
912
913 /**
914 * Return a link to $uid's profile if context allows it.
915 */
916 function _guestbook_user_profile_link($uid) {
917 global $user;
918
919 $guestbook_mode = variable_get('guestbook_mode', GUESTBOOK_SITE_GUESTBOOK | GUESTBOOK_USER_GUESTBOOKS);
920 $output = '';
921 if ($guestbook_mode & GUESTBOOK_USER_GUESTBOOKS && user_access('access user profiles') && $uid != $user->uid) {
922 $guestbook_user = user_load(array('uid' => $uid, 'status' => 1));
923 if ($guestbook_user->uid && empty($guestbook_user->guestbook_status)) {
924 $namelink = l($guestbook_user->name, "user/$uid", array('attributes' => array('title' => t('View user profile.'))));
925 $output .= '<div class="submitted">'. t("Visit !username's profile", array('!username' => $namelink)) .'</div>';
926 }
927 }
928 return $output;
929 }
930
931 /**
932 * Helper function to return the guestbook path for a given uid.
933 */
934 function guestbook_path($uid = 0) {
935 $uid = (int)$uid;
936 if ($uid > 0) {
937 return 'user/'. $uid .'/guestbook';
938 }
939 else {
940 return 'guestbook';
941 }
942 }
943
944 /**
945 * Returns if the guestbook specified by $uid exists.
946 */
947 function _guestbook_exists($uid) {
948 $title = _guestbook_info($uid, 'title');
949 return !empty($title);
950 }
951
952 /**
953 * Returns if current user is allowed to perform $action in guestbook $uid.
954 */
955 function _guestbook_access($action, $uid) {
956 global $user;
957
958 switch ($action) {
959 case 'post':
960 // Check whether user has sufficient permissions to post in this guestbook.
961 if (($uid == 0 ? user_access('post in site guestbook') : user_access('post in user guestbooks'))) {
962 // Check whether an authenticated user tries to post in own guestbook,
963 // allowing to post to others only.
964 if (!($user->uid == $uid && $user->uid > 0)) {
965 return 'allowed';
966 }
967 // User is either anonymous and tries to post in site guestbook,
968 // or an authenticated user tries to post in own guestbook.
969 else {
970 return 'own guestbook';
971 }
972 }
973 else if ($user->uid == 0) {
974 return 'not logged in';
975 }
976 else if ($user->uid != $uid) {
977 return 'not allowed';
978 }
979 break;
980
981 case 'moderate':
982 return user_access('moderate all guestbooks') || ($uid == $user->uid && $user->uid > 0);
983 }
984 }
985
986 /**
987 * Returns a string representation of a time interval.
988 */
989 function _guestbook_timeinterval($time) {
990 if ($time == 0) {
991 return t('never');
992 }
993 else {
994 return format_interval(time() - $time, 1);
995 }
996 }
997
998 /**
999 * Fetches number of new entries for current user.
1000 */
1001 function _guestbook_newentries() {
1002 global $user;
1003
1004 $count = db_result(db_query("SELECT COUNT(created) FROM {guestbook} WHERE recipient = %d AND created > %d", $user->uid, isset($user->guestbook_visited) ? $user->guestbook_visited : time()));
1005 return $count;
1006 }
1007
1008 function _guestbook_form_filter_tips() {
1009 $format = variable_get('guestbook_input_format', 1);
1010 $tips = theme('filter_tips', _filter_tips($format));
1011 return $tips;
1012 }
1013
1014 function _guestbook_spam($source, $id, $header, $body, $probability, $old, $action) {
1015 if ($probability > 98) {
1016