Another instance of theme('links') and drupal_set_message
[project/privatemsg.git] / privatemsg.module
1 <?php
2 // $Id$
3
4 /**
5 * Implementation of hook_help().
6 */
7 function privatemsg_help($section) {
8 switch ($section) {
9 case 'admin/modules#description':
10 return t('Allows private messages between users.');
11 }
12 }
13
14 /**
15 * Implementation of hook_link().
16 */
17 function privatemsg_link($type, $arg) {
18 if (user_access('access private messages')) {
19 switch ($type) {
20 case 'node':
21 if (variable_get('privatemsg_link_node', 0)) return array(l(t('write to author'), "privatemsg/msgto/$arg->uid"));
22 break;
23 case 'comment':
24 if (variable_get('privatemsg_link_comment', 0)) return array(l(t('write to author'), "privatemsg/msgto/$arg->uid"));
25 break;
26 }
27 }
28 }
29
30 /**
31 * Implementation of hook_menu().
32 */
33 function privatemsg_menu($may_cache) {
34 $items = array();
35
36 if (!$may_cache) {
37 $items[] = array('path' => 'privatemsg',
38 'title' => t('view inbox') . ' ('. (int)_privatemsg_get_new_messages() .')',
39 'callback' => 'privatemsg_page',
40 'access' => user_access('access private messages'),
41 'type' => MENU_DYNAMIC_ITEM);
42 }
43 return $items;
44 }
45
46 /**
47 * Implementation of hook_user().
48 */
49 function privatemsg_user($type, $edit, &$user, $category) {
50 if (user_access('access private messages')) {
51 switch ($type) {
52 case 'view':
53 return array(t('Private messages') => form_item('', l(t('send private message'), "privatemsg/msgto/$user->uid")));
54 case 'validate':
55 if (!$edit['privatemsg_mailalert']) {
56 $edit['privatemsg_mailalert'] = 0;
57 }
58 return $edit;
59 case 'form':
60 if ($category == 'account') {
61 return array(array('title' => t('Private message settings'), 'data' => form_checkbox(t('Receive daily e-mail for unread messages'), 'privatemsg_mailalert', 1, $user->privatemsg_mailalert, t('Check this box to receive e-mail notification for unread messages. Only one e-mail will be sent per day.'))));
62 }
63 }
64 }
65 }
66
67 /**
68 * Implementation of hook_settings().
69 */
70 function privatemsg_settings() {
71 $rate = drupal_map_assoc(array(5, 10, 15, 20, 30, 60), 'format_interval');
72 $output .= form_select(t('Private messaging max rate'), 'privatemsg_max_rate', variable_get('privatemsg_max_rate', 15), $rate, t('Max submit rate for private messaging. To prevent abuse.'));
73 $output .= form_select(t('Sent message status'), 'privatemsg_sent_status', variable_get('privatemsg_sent_status', 1), array(t('Disabled'), t('Enabled')), t('If enabled users can see whether a message has been read or not.'));
74 $number = drupal_map_assoc(array(5, 10, 15, 20, 25, 30, 35, 40, 50, 60, 80, 100));
75 $output .= form_select(t('Messages per page'), 'privatemsg_per_page', variable_get('privatemsg_per_page', 10), $number, t('The maximum number of messages displayed per page; links to browse messages automatically appear.'));
76
77 $group = form_checkbox(t('Display link with posts'), 'privatemsg_link_node', 1, variable_get('privatemsg_link_node', 0), t('Provide a link to send private messages to users with posts they start.'));
78 $group .= form_checkbox(t('Display link with comments'), 'privatemsg_link_comment', 1, variable_get('privatemsg_link_comment', 0), t('Provide a link to send private messages to users with their comments.'));
79 $output .= form_group(t('"Write to author" links'), $group);
80
81 return $output;
82 }
83
84 /**
85 * Implementation of hook_perm().
86 */
87 function privatemsg_perm() {
88 return array('access private messages');
89 }
90
91 /**
92 * Implementation of hook_cron().
93 */
94 function privatemsg_cron() {
95 // perform these actions just once per day
96 if (variable_get('privatemsg_last_cron', 0) < (time() - 3600*24)) {
97 _privatemsg_prune();
98 _privatemsg_mailalert();
99 variable_set('privatemsg_last_cron', time());
100 }
101 }
102
103 function _privatemsg_prune() {
104 // move deleted message older than 1 month to archive table, and optimize table
105 $result = db_query("SELECT * FROM {privatemsg} WHERE author_del = 1 AND recipient_del = 1 AND timestamp < '%d'", (time() - 3600*24*30));
106 while ($message = db_fetch_object($result)) {
107 db_query("INSERT INTO {privatemsg_archive} (id, author, recipient, subject, message, timestamp, hostname, folder) VALUES ('%d', '%d', '%d', '%s', '%s', '%d', '%s', '%d')", $message->id, $message->author, $message->recipient, $message->subject, $message->message, $message->timestamp, $message->hostname, $message->folder);
108 db_query("DELETE FROM {privatemsg} WHERE id = '%d'", $message->id);
109 }
110
111 // this is MySQL-specific
112 if ($GLOBALS['db_type'] == 'mysql') {
113 db_query("OPTIMIZE TABLE {privatemsg}");
114 }
115 }
116
117 function _privatemsg_mailalert() {
118 $result = db_query("SELECT COUNT(*) AS c, recipient FROM {privatemsg} WHERE new = 1 AND recipient_del = 0 GROUP BY recipient");
119
120 while ($alert = db_fetch_object($result)) {
121 $user = user_load(array("uid" => $alert->recipient));
122 if ($user->privatemsg_mailalert) {
123 user_mail($user->mail,
124 t('You have unread messages'),
125 t("Hi %name,\nthis is an automatic reminder from the site %site. You have %new unread private messages.\n\nTo read your messages, follow this link:\n%link1\n\nIf you don't want to receive these email again, change your preferences here:\n%link2\n\n",
126 array('%name' => $user->name, '%site' => variable_get('site_name', 'drupal'), '%new' => $alert->c, '%link1' => url('privatemsg', NULL, NULL, 1), '%link2' => url('user/'. $user->uid .'/edit'))),
127 t('New private messages at %site.', array('%site' => variable_get('site_name', 'drupal'))));
128 }
129 }
130 }
131
132 function privatemsg_page() {
133 global $user;
134
135 $breadcrumb = NULL;
136 $op = $_POST["op"];
137 $edit = $_POST["edit"];
138 $recipient = $_POST["recipient"];
139 $msg = $_POST["msg"];
140
141 if (empty($op)) {
142 $op = arg(1);
143 }
144 $arg = arg(2);
145
146 switch($op) {
147 case "list";
148 $output = _privatemsg_list($arg);
149 $title = t('Private messages');
150 break;
151 case "view";
152 $output = _privatemsg_view($arg);
153 $title = t("Read message");
154 $breadcrumb = array(l(t('Home'), ''), l('Private messages', 'privatemsg'));
155 break;
156 case t("Write a new message"):
157 $arg = "";
158 case "form";
159 case "reply";
160 $output = _privatemsg_form($arg);
161 $title = t("Write a new message");
162 $breadcrumb = array(l(t('Home'), ''), l('Private messages', 'privatemsg'));
163 break;
164 case "msgto";
165 $msg->name = db_result(db_query("SELECT name FROM {users} WHERE uid = '%d'", $arg));
166 $output = _privatemsg_form($msg);
167 $title = t("Write a new message");
168 $breadcrumb = array(l(t('Home'), ''), l('Private messages', 'privatemsg'));
169 break;
170 case "send";
171 case t("Send private message"):
172 if (!$edit["recipient"]) {
173 $edit["recipient"] = $recipient;
174 }
175 $breadcrumb = array(l(t('Home'), ''), l('Private messages', 'privatemsg'));
176 $output = _privatemsg_edit($edit);
177 break;
178 case t("Move to folder"):
179 if ($edit["folder"] == 0 || db_result(db_query("SELECT fid FROM {privatemsg_folder} WHERE fid = '%d' AND uid = '%d'", $edit["folder"], $user->uid))) {
180 // this folder belongs to him
181 if ($msg) {
182 foreach ($msg as $mid) {
183 _privatemsg_move($mid, $edit["folder"]);
184 }
185 $output = _privatemsg_list($edit["folder"]);
186 break;
187 }
188 }
189
190 $output = _privatemsg_list();
191 break;
192 case t("Delete messages"):
193 if ($msg) {
194 foreach ($msg as $id) {
195 _privatemsg_delete($id);
196 }
197 }
198 $output = _privatemsg_list();
199 break;
200
201 case "delete";
202 _privatemsg_delete($arg);
203 $output = _privatemsg_list();
204 break;
205
206 case t("New folder"):
207 case t("Add folder"):
208 if ($edit["name"]) {
209 // check for uniqueness
210 if (!db_result(db_query("SELECT name FROM {privatemsg_folder} WHERE name = '%s' AND uid = '%d'", $edit["name"], $user->uid))) {
211 db_query("INSERT INTO {privatemsg_folder} (uid, name) VALUES ('%d', '%s')", $user->uid, $edit["name"]);
212 }
213 $output = _privatemsg_list();
214 }
215 else {
216 $title = t('Create new folder');
217 $breadcrumb = array(l(t('Home'), ''), l('Private messages', 'privatemsg'));
218 $output = _privatemsg_new_folder($edit);
219 }
220 break;
221
222 case t("Delete folder");
223 // check ownership
224 if (db_result(db_query("SELECT fid FROM {privatemsg_folder} WHERE fid = '%d' AND uid = '%d'", $edit["current_folder"], $user->uid))) {
225 db_query("DELETE FROM {privatemsg_folder} WHERE fid = '%d'", $edit["current_folder"]);
226 db_query("UPDATE {privatemsg} SET recipient_del = 1 WHERE folder = '%d'", $edit["current_folder"]);
227 }
228
229 $output = _privatemsg_list();
230 break;
231 case t("Empty folder");
232 $fid = $edit["current_folder"];
233
234 if ($fid == 1) {
235 db_query("UPDATE {privatemsg} SET author_del = 1 WHERE author = '%d'", $user->uid);
236 }
237 else if ($fid == 0 || db_result(db_query("SELECT fid FROM {privatemsg_folder} WHERE fid = '%d' AND uid = '%d'", $fid, $user->uid))) {
238 // check ownership
239 db_query("UPDATE {privatemsg} SET recipient_del = 1 WHERE folder = '%d' AND recipient = '%d'", $edit["current_folder"], $user->uid);
240 }
241
242 $output = _privatemsg_list();
243 break;
244 default;
245 $output = _privatemsg_list();
246 $title = t('Private messages');
247 break;
248 }
249
250 print theme('page', $output, $title, $breadcrumb);
251
252 }
253
254 function _privatemsg_list($current_folder = 0) {
255 global $user;
256
257 if ($current_folder != 1) {
258 $result = pager_query("SELECT id, subject, p.timestamp, u.uid, u.name, new FROM {privatemsg} p, {users} u WHERE p.author = u.uid AND p.recipient = $user->uid AND folder = '".addslashes($current_folder)."' AND p.recipient_del = 0 ORDER BY p.timestamp DESC", variable_get("privatemsg_per_page", 10));
259
260 if ($current_folder > 0) {
261 $folder_name = db_result(db_query("SELECT name FROM {privatemsg_folder} WHERE fid = '%d' AND uid = '$user->uid'", $current_folder));
262 }
263 else {
264 $folder_name = t("Inbox");
265 }
266 }
267 else {
268 // sent messages
269 $result = pager_query("SELECT id, subject, p.timestamp, u.uid, u.name, new FROM {privatemsg} p, {users} u WHERE p.recipient = u.uid AND p.author = $user->uid AND p.author_del = 0 ORDER BY p.timestamp DESC", variable_get("privatemsg_per_page", 10));
270
271 $folder_name = t("Sent messages");
272 }
273
274 $messages = array();
275 while ($message = db_fetch_object($result)) {
276 $messages[] = $message;
277 }
278
279 $folders[] = array(0, t("Inbox"));
280 $result = db_query("SELECT fid, name FROM {privatemsg_folder} WHERE uid = '$user->uid'");
281 while ($folder = db_fetch_object($result)) {
282 $folders[] = array($folder->fid, $folder->name);
283 }
284 $folders[] = array(1, t("Sent messages"));
285
286 return theme("privatemsg_list", $current_folder, $messages, $folders);
287 }
288
289 function _privatemsg_format_folder($current, $fid, $name) {
290 if ($current == $fid) {
291 return "<b>$name</b>";
292 }
293 else {
294 return l($name, "privatemsg/list/$fid");
295 }
296 }
297
298 function _privatemsg_form($message = 0) {
299 global $user;
300
301 if ($message) {
302 if (!is_object($message)) {
303 $message = db_fetch_object(db_query("SELECT subject, message, u.name FROM {privatemsg} p, {users} u WHERE u.uid = p.author AND id = '%d' AND recipient = '%d'", $message, $user->uid));
304
305 if (!stristr($message->subject, t("Re:"))) {
306 $message->subject = t("Re:").' '.$message->subject;
307 }
308
309 // quoting
310 $message->message = "\n".str_replace ("\n", "\n> ", "\n".$message->message);
311 }
312 }
313
314 $to .= "<input type='text' name='recipient' value='".htmlentities($message->name, ENT_QUOTES)."' maxlength='64' size='50'>";
315
316 if (!$message->name) {
317 $to .= ' <select name="quick" onChange="recipient.value=quick.value"><option value="--'.t("contacts").'--" selected="selected">--'.t("contacts").'--</option>';
318 $result = db_query("SELECT DISTINCT(name) AS name FROM {privatemsg} p, {users} u WHERE p.author = u.uid AND recipient = '%d' AND p.timestamp > (UNIX_TIMESTAMP(NOW()) - (3600 * 24 * 30)) ORDER BY name", $user->uid);
319 while ($name = db_fetch_object($result)) {
320 $name = htmlentities($name->name);
321 $to .= "<option value='$name'>$name</option>";
322 }
323 $to .= '</select>';
324 }
325
326 $form .= form_item(t("To"), $to);
327
328 $form .= form_textfield(t("Subject"), "subject", $message->subject, 50, 64);
329 $form .= form_textarea(t("Message"), "message", $message->message, 80, 5);
330 $form .= form_submit(t("Send private message"));
331
332 return form($form);
333 }
334
335 function _privatemsg_edit($edit) {
336 global $user;
337 $recipient = db_result(db_query("SELECT uid FROM {users} WHERE name = '%s'", $edit["recipient"]));
338
339 if (!$edit["recipient"] || !$edit["subject"] || !$edit["message"]) {
340 drupal_set_message(t('Warning: every field required'), 'error');
341 return _privatemsg_form(array2object($edit));
342 }
343 elseif ($recipient == $user->uid) {
344 drupal_set_message(t('A message to yourself?'), 'error');
345 return _privatemsg_form(array2object($edit));
346 }
347 else {
348 if ($recipient) {
349 $result = db_query("INSERT INTO {privatemsg} (author, recipient, subject, message, timestamp, new, hostname) VALUES ('%d', '%d', '%s', '%s', '%d', '%d', '%s')", $user->uid, $recipient, strip_tags($edit['subject']), strip_tags($edit['message']), time(), 1, getenv("REMOTE_ADDR"));
350 drupal_set_message(t('Message sent.'));
351 return _privatemsg_list();
352 }
353 else {
354 drupal_set_message(t('Warning: user does not exist'), 'error');
355 return _privatemsg_form(array2object($edit));
356 }
357 }
358 }
359
360 function _privatemsg_view($message_id) {
361 global $user;
362
363 $result = db_query("SELECT p.id, u.uid, u.name, p.author, p.timestamp, p.subject, p.message, p.new, p.recipient FROM {privatemsg} p, {users} u WHERE (recipient = '%d' OR author = '%d') AND author = u.uid AND id = '%d'", $user->uid, $user->uid, $message_id);
364
365 $message = db_fetch_object($result);
366 if (($message->new) && ($user->uid != $message->author)) {
367 $result = db_query("UPDATE {privatemsg} SET new = 0 WHERE recipient = '$user->uid' AND id = '%d'", $message_id);
368 }
369
370 return theme("privatemsg_view", $message);
371 }
372
373 function _privatemsg_delete($id) {
374 global $user;
375
376 $result = db_query("SELECT author, recipient FROM {privatemsg} WHERE (recipient = '$user->uid' OR author = '$user->uid') AND id = '%d'", $id);
377
378 if ($message = db_fetch_object($result)) {
379 if ($message->author == $user->uid) {
380 db_query("UPDATE {privatemsg} SET author_del = 1 WHERE id = '%d'", $id);
381 }
382 else if ($message->recipient == $user->uid) {
383 db_query("UPDATE {privatemsg} SET recipient_del = 1 WHERE id = '%d'", $id);
384 }
385
386 return true;
387 }
388 else {
389 return false;
390 }
391 }
392
393 function _privatemsg_get_new_messages($uid = 0) {
394 global $user;
395 if ($uid == 0) {
396 $uid = $user->uid;
397 }
398 return db_result(db_query("SELECT COUNT(*) FROM {privatemsg} WHERE recipient = '%d' AND new = 1 AND recipient_del = 0", $uid));
399 }
400
401 function _privatemsg_new_folder($edit) {
402 $form = form_textfield(t("Name"), "name", "", 50, 64);
403 $form .= form_submit(t("Add folder"));
404
405 return form($form);
406 }
407
408 function _privatemsg_move($mid, $fid) {
409 global $user;
410 db_query("UPDATE {privatemsg} SET folder = '%d' WHERE id = '%d' AND recipient = '%d'", $fid, $mid, $user->uid);
411 }
412
413 /**
414 @addtogroup theme_system
415
416 Privatemsg module specific theme functions
417 @{
418 **/
419
420 /**
421 Returns content to view a private message
422
423 @param message
424 **/
425 function theme_privatemsg_view($message) {
426 global $user;
427
428 if ($message) {
429 $body = "
430 <p><b>".t("From").":</b> ".format_name($message)."<br />
431 <b>".t("To").":</b> ".format_name(user_load(array('uid' => $message->recipient)))."<br />
432 <b>".t("Subject").":</b> ".strip_tags($message->subject)."<br />
433 <b>".t("Date").":</b> ".format_date($message->timestamp)."</p>
434 ".check_output($message->message, 1);
435 $links = array();
436 if ($message->recipient == $user->uid) {
437 $links[] = l(t('Reply to this message'), "privatemsg/reply/$message->id");
438 }
439 if (($message->recipient == $user->uid) || (variable_get("privatemsg_sent_status", 1))) {
440 $links[] = l(t('Delete this message'), "privatemsg/delete/$message->id", array('onClick' => "return confirm('".t('Are you sure to delete this message?')."')"));
441 }
442
443 $links[] = l(t('List messages'), 'privatemsg');
444 $body .= theme('links', $links);
445 } else {
446 drupal_set_message(t('Error: you can\'t read this message'), 'error');
447 $body = '';
448 }
449
450 return $body;
451 }
452
453 /**
454 Returns content to view a list of private messages
455
456 @param current_folder
457 @param messages
458 @param folders
459 **/
460 function theme_privatemsg_list($current_folder, $messages, $folders) {
461 $extra_folders = array();
462 foreach ($folders as $folder) {
463 $folder_list[] = _privatemsg_format_folder($current_folder, $folder[0], $folder[1]);
464 if ($folder[0] != 1 && $folder[0] != $current_folder) {
465 $extra_folders[$folder[0]] = $folder[1];
466 }
467 }
468
469 $out = theme('links', $folder_list);
470
471 $rows = array();
472 foreach ($messages as $message) {
473 $row = array();
474 $row[] = array('data' => '<input type="checkbox" name="msg[]" value="'. $message->id .'">');
475 if ($current_folder != 1) {
476 $new = $message->new;
477 }
478 else {
479 if (variable_get("privatemsg_sent_status", 1)) {
480 $new = $message->new;
481 }
482 else {
483 $new = 0;
484 }
485 }
486 $row[] = array('data' => format_date($message->timestamp, 'small'));
487 $row[] = array('data' => format_name($message));
488 $row[] = array('data' => l(strip_tags($message->subject), 'privatemsg/view/'. $message->id) . ($new ? (' '. theme('mark')) : ''));
489
490 $rows[] = $row;
491 }
492
493 if (count($messages) < 1) {
494 $out .= t('<p>No messages</p>');
495 }
496 else {
497 $header = array(
498 array('data' => ''),
499 array('data' => t('Date')),
500 array('data' => ($current_folder == 1 ? t('To') : t('From'))),
501 array('data' => t('Subject')),
502 );
503
504 if ($pager = theme("pager_display", NULL, variable_get("privatemsg_per_page", 10))) {
505 $rows[] = array(array('data' => $pager, 'colspan' => 5));
506 }
507
508 $out .= theme('table', $header, $rows);
509 }
510
511 $out .= '<hr />'. form_submit(t("Write a new message"));
512 if (count($messages) > 0) {
513 $out .= form_submit(t("Delete messages"), "op", array("onClick" => "return confirm('".t("Are you sure you want to delete these messages?")."')"));
514 }
515
516 // folder management
517 if ((count($extra_folders) > 0) && ($current_folder != 1) && (count($messages) > 0)) {
518 $out .= '<br /><select name="edit[folder]">';
519 foreach ($extra_folders as $fid => $folder_name) {
520 $out .= "<option value='$fid'>$folder_name</option>";
521 }
522 $out .= '</select>';
523
524 $out .= form_submit(t("Move to folder"));
525 }
526
527 $out .= '<br />';
528 if ($current_folder > 1) {
529 // you can't delete Inbox
530 $out .= form_submit(t("Delete folder"), "op", array("onClick" => "return confirm('".t("Are you sure you want to delete this folder and all its messages?")."')"));
531 }
532 if (count($messages) > 0) {
533 $out .= form_submit(t("Empty folder"), "op", array("onClick" => "return confirm('".t("Are you sure you want to delete every message in this folder?")."')"));
534 }
535 $out .= form_hidden("current_folder", $current_folder);
536 $out .= form_submit(t("New folder"));
537
538 return form($out);
539 }
540
541 /** @} End of addtogroup theme_system **/
542
543 ?>