forked from KyleAMathews/og_mailinglist
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathog_mailinglist.module
502 lines (450 loc) · 18.3 KB
/
og_mailinglist.module
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
<?php
// $Id$
// TODO -- rewrite this header part according to the normal Drupal style
// TODO write docs for functions.
###############################################################################
### This module allows users to email a Drupal installation running the
### Exim email server to create discussions and respond to comments.
### Because it is tied directly to Exim, email is processed immediately
### upon receipt in the mail server. Mails should be sent to [email protected]
### rather than to a single email address.
###
### Original version written by Conan Albrecht March 2009
### Maintained since by Kyle Mathews
###
/**
* @name OG Mailinglist build modes.
* @{
*/
define('OG_MAILINGLIST_BUILD_FULL', 'og_mailinglist full');
/**
* @} End of "Node as block build modes".
*/
require_once("og_mailinglist_phpmailer.inc");
require_once('og_mailinglist_api.inc');
og_mailinglist_phpmailer_load_library();
/**
* Implementation of hook_menu().
*/
function og_mailinglist_menu() {
# Administration
$items['admin/og/og_mailinglist'] = array(
'title' => 'OG Mailinglist',
'description' => t('Configure posts/comments generated from email'),
'page callback' => 'drupal_get_form',
'page arguments' => array('og_mailinglist_admin_settings'),
'access arguments' => array('access administration pages'),
);
$items['og_mailinglist/subscriptions'] = array(
'title' => t('Manage Group Subscriptions'),
'description' => t('Allows users to manage their group subscriptions'),
'page callback' => 'drupal_get_form',
'page arguments' => array('og_mailinglist_subscriptions_settings_form'),
'access arguments' => array('manage og_mailinglist subscriptions'),
);
$items['og_mailinglist/unsubscribe/%node'] = array(
'title' => t('Unsubscribe from post'),
'description' => t('Users who hit this page will not get more emails for
comments on the node.'),
'page callback' => 'og_mailinglist_unsubscribe_thread',
'page arguments' => array(2),
'access arguments' => array('manage og_mailinglist subscriptions'),
);
$items['og_mailinglist/subscribe/%node'] = array(
'title' => t('Subscribe to post'),
'description' => t('Users who hit this page will not get more emails for
comments on the node.'),
'page callback' => 'og_mailinglist_subscribe_thread',
'page arguments' => array(2),
'access arguments' => array('manage og_mailinglist subscriptions'),
);
$items['og_mailinglist'] = array(
'page callback' => 'og_mailinglist_post',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
'file' => 'og_mailinglist_transport.inc',
);
return $items;
}
/*
* Implementation of hook_perm().
*/
function og_mailinglist_perm() {
return array('manage og_mailinglist subscriptions');
}
/*
* Implementation of hook_init().
*/
function og_mailinglist_init() {
drupal_add_css(drupal_get_path('module', 'og_mailinglist') . "/og_mailinglist.css");
drupal_add_js(drupal_get_path('module', 'og_mailinglist') . "/og_mailinglist.js");
}
/**
* Admin settings form
*/
function og_mailinglist_admin_settings() {
$form['og_mailinglist_server_string'] = array(
'#title' => t('Domain name'),
'#type' => 'textfield',
'#default_value' => variable_get('og_mailinglist_server_string', $_SERVER['SERVER_NAME']),
'#description' => t('Domain name for outgoing/incoming emails, e.g. example.com.'),
);
$form['og_mailinglist_max_message_size'] = array(
'#title' => t('Maximum message body size (excluding attachments) (in Kb)'),
'#type' => 'textfield',
'#default_value' => variable_get('og_mailinglist_max_message_size', '100'),
'#description' => t('Any messages over this size will be rejected. Set to 0 for unlimited.'),
);
$form['og_mailinglist_max_posts_per_hour'] = array(
'#title' => t('Maximum posts per hour'),
'#type' => 'textfield',
'#default_value' => variable_get('og_mailinglist_max_posts_per_hour', '20'),
'#description' => t('The maximum number of messages a user is able to post per hour by email. Set to 0 for unlimited.'),
);
$form['og_mailinglist_reply_to_group'] = array(
'#title' => t('Add a Reply-To header to outgoing group emails'),
'#type' => 'checkbox',
'#default_value' => variable_get('og_mailinglist_reply_to_group', '0'),
'#description' => t('Set an explicit reply-to header. See http://wiki.list.org/pages/viewpage.action?pageId=4030691 for pros and cons on this setting.'),
);
$node_types = node_get_types();
$n_types = array();
foreach ($node_types as $type) {
$n_types[$type->type] = $type->name;
}
$form['og_mailinglist_default_content_type'] = array(
'#title' => t('Default content type'),
'#type' => 'select',
'#default_value' => variable_get('og_mailinglist_default_content_type', 'story'),
'#options' => $n_types,
'#description' => t('Choose the default content type to be created from new emails.'),
);
$form['og_mailinglist_exclude_content_types'] = array(
'#title' => t('Exclude the following content types'),
'#type' => 'select',
'#multiple' => TRUE,
'#default_value' => variable_get('og_mailinglist_exclude_content_types', 'group'),
'#options' => $n_types,
'#description' => t('Do not send emails on creation of these content types.'),
);
$form['og_mailinglist_default_group_subscription_type'] = array(
'#title' => t('Default group email subscription type'),
'#type' => 'select',
'#default_value' => variable_get('og_mailinglist_default_group_subscription_type', 'email'),
'#options' => array('email' => 'email', 'no email' => 'no email', 'digest email' => 'digest email'),
'#description' => t('Choose the default email subscription for users joining a new group. "Email" means the user will receive an email for each new post. "No email" means the user will recieve no emails except for discussion threads they participate in. "Digest" is the same as "no email" except the user will also receive digest emails. (Users can change this later at http://yoursite.com/og_mailinglist/subscriptions)'),
);
// Save an incoming key by default.
if ((variable_get('og_mailinglist_incoming_key', '')) == '') {
variable_set('og_mailinglist_incoming_key', md5(rand()));
}
$form['og_mailinglist_incoming_key'] = array(
'#type' => 'textfield',
'#title' => t('Message validation string'),
'#default_value' => variable_get('og_mailinglist_incoming_key', md5(rand())),
'#required' => TRUE,
'#description' => t('This string will be used to validate incoming messages. It can be anything, but must be used on both sides of the transfer. For more see the INSTALL.txt for your Mail Transfer Agent.'),
);
$form['og_mailinglist_test_email_address'] = array(
'#title' => t('DEBUGGING: Send an email for all events to a user account'),
'#type' => 'textfield',
'#default_value' => variable_get('og_mailinglist_test_email_address', ''),
'#description' => t('For testing / monitoring purposes, you can set one user account to receive all emails sent by OG Mailinglist. Enter the User ID of the user who should receive all emails.'),
);
return system_settings_form($form);
}
function og_mailinglist_subscriptions_settings_form() {
global $user;
$sql = 'SELECT m.nid as gid, m.subscription_type, n.title
FROM {og_mailinglist_subscription} m, {node} n
WHERE m.nid = n.nid
AND m.uid = %d
ORDER BY n.title';
$results = db_query($sql, $user->uid);
$subscription_options = array(
'email' => t('Email'),
'no email' => t('No email'),
'digest email' => t('Digest email'),
);
$form = array();
while ($data = db_fetch_array($results)) {
$form[$data['gid']] = array(
'#type' => 'fieldset',
'#title' => l(t($data['title']), "node/" . $data['gid']),
'#tree' => TRUE,
);
$form[$data['gid']]['subscription-type'] = array(
'#type' => 'select',
'#title' => "Email Settings",
'#default_value' => $data['subscription_type'],
'#options' => $subscription_options,
);
$form[$data['gid']]["leave-group"] = array(
'#type' => 'checkbox',
'#title' => "Leave the " . t($data['title']) . " group",
'#suffix' => "<hr />",
);
}
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save Settings')
);
return $form;
}
function og_mailinglist_subscriptions_settings_form_submit($form, &$form_state) {
global $user;
foreach ($form_state['values'] as $gid => $settings) {
// We only care about GIDs and their values.
if (is_numeric($gid)) {
og_mailinglist_update_group_subcription_type($gid, $user->uid, $settings['subscription-type']);
if ($sub_type != "email") {
og_mailinglist_delete_group_threads($gid, $user->uid);
}
// If they choose to leave the group.
if ($settings['leave-group']) {
og_delete_subscription($gid, $user->uid);
$group_name = db_result(db_query("SELECT title FROM {node} WHERE nid = %d", $gid));
drupal_set_message(t("You are no longer in the <a href='@gid'>@group_name</a> group", array("@gid" => url("node/" . $gid), "@group_name" => $group_name)));
}
}
}
drupal_set_message("Your group subscriptions were updated.");
}
function og_mailinglist_unsubscribe_thread($node) {
global $user;
$success = og_mailinglist_delete_thread_subscription($node->nid, $user->uid);
if ($success) {
return "<div class='messages success'>You were successfully unsubscribed from
the post <em>" . l($node->title, "node/" . $node->nid) . " </em>
" . l("Undo", "og_mailinglist/subscribe/" . $node->nid, array("attributes" => array("id" => "og_mailinglist_undo")))
. "</div>";
}
}
function og_mailinglist_subscribe_thread($node) {
global $user;
og_mailinglist_save_thread_subscriptions($node->nid, array($user->uid));
return "<div class='messages success'>You were successfully subscribed to
the post <em>" . l($node->title, "node/" . $node->nid) . " </em>
" . l("Undo", "og_mailinglist/unsubscribe/" . $node->nid, array("attributes" => array("id" => "og_mailinglist_undo")))
. "</div>";
}
/*
* Implementation of hook_form_alter().
*/
function og_mailinglist_form_alter(&$form, $form_state, $form_id) {
if ($form['#id'] == 'node-form' && (arg(0) .'/'. arg(1) != 'admin/content')) {
// Group nodes
if (og_is_group_type($form['#node']->type)) {
if (!module_exists('purl') && !module_exists('spaces_og')) {
$group_email = "";
if (isset($form['nid']['#value'])) {
$group_email = db_result(db_query("SELECT group_email
FROM {og_mailinglist}
WHERE nid = %d", $form['nid']['#value']));
}
// Add our form, compatible with purl's form.
$form['og_mailinglist'] = array(
'#title' => 'Group Email Address',
'#type' => 'textfield',
'#description' => 'Choose an email address for your group. May contain only lowercase letters, numbers, dashes and underscores. e.g. "my-group"',
'#size' => 20,
'#default_value' => $group_email,
'#weight' => -1,
'#maxlength' => 255,
'#required' => TRUE,
'#tree' => TRUE,
'#element_validate' => array('og_mailinglist_group_form_validate'),
);
// Make sure our submit function is second after node_form_submit.
$first = array_shift($form['buttons']['submit']['#submit']);
array_unshift($form['buttons']['submit']['#submit'], $first, "og_mailinglist_group_form_submit");
}
// If Spaces OG is already using purl to get a shortcode, we'll use that
// shortcode instead of collecting another one.
else {
// Make sure our submit function is second after node_form_submit.
$first = array_shift($form['buttons']['submit']['#submit']);
array_unshift($form['buttons']['submit']['#submit'], $first, "og_mailinglist_group_form_submit");
}
}
}
}
/**
* Validation handler for og_mailinglist_group_form. Check that submitted
* email username is valid.
*/
function og_mailinglist_group_form_validate($element, &$form_state) {
$sql = "SELECT group_email FROM {og_mailinglist} WHERE group_email = '%s'";
if ($form_state['values']['nid']) {
$sql .= ' AND nid != ' . $form_state['values']['nid'];
}
if (db_result(db_query($sql, $element['#value']))) {
form_error($element, t('Someone has already choosen that group email address. Please choose another.'));
}
else if (preg_match('!^[\.a-z0-9_-]+$!', $element['#value'])) {
return true;
}
else {
form_error($element, t('Your group email address may contain only lowercase letters, numbers, dashes and underscores. e.g. "my-group'));
}
}
/*
* Submit handler for og_mailinglist_group_form.
*/
function og_mailinglist_group_form_submit($form, &$form_state) {
$group_email = "";
if (isset($form_state['values']['purl']['value'])) {
$group_email = $form_state['values']['purl']['value'];
}
else {
$group_email = $form_state['values']['og_mailinglist'];
}
og_mailinglist_save_group($form_state['nid'], $group_email);
}
/*
* Implementation of hook_nodeapi().
*/
function og_mailinglist_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
if ($op == "insert" && $node->status) {
$group_node = _og_mailinglist_load_group($node);
// If this node isn't part of a group, return.
if (empty($group_node)) {
return;
}
// If this content type doesn't use email notifications, then return.
$excluded_content_types = variable_get('og_mailinglist_exclude_content_types', array());
if (in_array($node->type, $excluded_content_types)) {
return;
}
// User might not be automatically subscribed to new threads. Subscribe now if they aren't signed up to get emails normally.
if (og_mailinglist_get_group_subscription_type($group_node->nid, $node->uid) != "email") {
og_mailinglist_save_thread_subscriptions($node->nid, array($node->uid));
}
// Send emails
og_mailinglist_send_node_email($node);
}
// Node is a group
if (og_is_group_type($node->type)) {
switch ($op) {
case 'load':
// Load the group's email username.
if (isset($node->nid)) {
$ogm_email = db_result(db_query("SELECT group_email
FROM {og_mailinglist}
WHERE nid = %d", $node->nid));
$node->ogm_email = $ogm_email;
}
break;
case 'insert':
case 'update':
case 'delete':
// Disabling this for now. Spaces deletes and recreates a group when you switch presets.
// og_mailinglist_delete_group($node->nid);
break;
}
}
}
/**
* Implmentation of hook_comment().
*/
function og_mailinglist_comment($comment, $op) {
// $comment can be an object or an array.
$comment = (object)$comment;
if ($op == 'publish') {
// Check that the node is published.
$node = node_load($comment->nid);
if ($node->status) {
og_mailinglist_send_comment_email($comment, $node);
// User might not be subscribed to thread. Subscribe them now if not
// already subscribed.
if (!og_mailinglist_check_user_subscribed_to_thread($comment->nid, $comment->uid)) {
og_mailinglist_save_thread_subscriptions($comment->nid, array($comment->uid));
}
}
}
}
/**
* Implementation of hook_og().
*
* Add a og_mailinglist subscription when a user joins a group
* and delete should they leave.
*/
function og_mailinglist_og($op, $gid, $uid, $args) {
switch ($op) {
case 'user insert':
og_mailinglist_save_group_subscriptions($gid, array($uid));
break;
case 'user delete':
og_mailinglist_delete_group_subscriptions($gid, array($uid));
break;
}
}
/**
* Implementation of hook_filter().
*/
function og_mailinglist_filter($op, $delta = 0, $format = -1, $text = "") {
switch ($op) {
case 'list':
return array(
0 => t('Hide quoted text from comments created via email')
);
case 'description':
return t('Finds quoted text from comments created via email and hides them.');
case 'prepare':
return $text;
case 'process':
return _og_mailinglist_build_quotes_toggle($text);
}
}
function _og_mailinglist_build_quotes_toggle($text) {
module_load_include('inc', 'og_mailinglist', 'og_mailinglist_filter');
$quotes = _og_mailinglist_find_quoted_sections($text);
if (!empty($quotes)) {
foreach ($quotes as $quote) {
$replace = '<br /><span class="toggle-quoted-text">- Show quoted text -</span><div class="quoted-text">'. $quote .'</div>';
$text = str_replace($quote, $replace, $text);
// Remove email addresses. Regex borrowed from valid_email_adddress().
$regex = "([a-zA-Z0-9_\-\.\+\^!#\$%&*+\/\=\?\`\|\{\}~\']+@(?:(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.?)+)";
preg_match_all($regex, $quote, $matches);
foreach($matches[0] as $email) {
$text = str_replace($email, "***@***.***", $text);
}
}
}
return $text;
}
function _og_mailinglist_remove_quotes($text) {
module_load_include('inc', 'og_mailinglist', 'og_mailinglist_filter');
$quotes = _og_mailinglist_find_quoted_sections($text);
if (!empty($quotes)) {
foreach ($quotes as $quote) {
$text = str_replace($quote, '', $text);
}
}
return $text;
}
/*
* Implementation of hook_cron().
*/
function og_mailinglist_cron() {
// On first run, set digest to run today.
$next_digest_runtime = variable_get('og_mailinglist_digest_runtime',
mktime(17, date("I"), date("s"), date("n"), date("j")));
if (time() > $next_digest_runtime) {
module_load_include('inc', 'og_mailinglist', 'og_mailinglist_digest_email');
// Send off digest emails.
_og_mailinglist_send_digest_emails();
// Set tomorrow's run time.
variable_set('og_mailinglist_digest_runtime', mktime(17, date("I"), date("s"), date("n"), date("j") + 1));
}
}
/**
* Implementation of hook_help().
*/
function og_mailinglist_help($path, $args) {
switch ($path) {
case 'admin/help#og_mailinglist':
// Return a line-break version of the module README
return filter_filter('process', 1, NULL, file_get_contents( dirname(__FILE__) . "/README.txt"));
}
}