| 1 |
<?php |
<?php |
| 2 |
/* $Id: subscription.module,v 1.7 2005/09/23 14:31:08 ee Exp $ */ |
/* $Id: subscription.module,v 1.10 2005/09/30 06:41:49 ee Exp $ */ |
| 3 |
|
|
| 4 |
function subscription_help($section) { |
function subscription_help($section) { |
| 5 |
switch ($section) { |
switch ($section) { |
| 6 |
case 'admin/modules#description': |
case 'admin/modules#description': |
| 7 |
$output = t("Enables subscription to content."); |
$output = t("Users may be notified of new content according to preference."); |
| 8 |
break; |
break; |
| 9 |
} |
} |
| 10 |
return $output; |
return $output; |
| 15 |
function subscription_menu($may_cache) { |
function subscription_menu($may_cache) { |
| 16 |
global $user; |
global $user; |
| 17 |
$items = array(); |
$items = array(); |
| 18 |
if ($may_cache) { |
if (!$may_cache && $user->uid) { |
|
if ($user->uid > 0) { |
|
| 19 |
$items[] = array('path' => "user/$user->uid/subscriptions", |
$items[] = array('path' => "user/$user->uid/subscriptions", |
| 20 |
'title' => t('my subscriptions'), |
'title' => t('my subscriptions'), |
| 21 |
'access' => user_access('manage subscriptions'), |
'access' => user_access('manage subscriptions'), |
| 22 |
'callback' => 'subscription_list', |
'callback' => 'subscription_list', |
| 23 |
'type' => MENU_LOCAL_TASK); |
'type' => MENU_LOCAL_TASK); |
| 24 |
|
} |
| 25 |
|
elseif ($may_cache) { |
| 26 |
$items[] = array('path' => 'subscription/add', |
$items[] = array('path' => 'subscription/add', |
| 27 |
'title' => t('Subscribe to content'), |
'title' => t('Subscribe to content'), |
| 28 |
'access' => user_access('manage subscriptions'), |
'access' => user_access('manage subscriptions'), |
| 42 |
'access' => user_access('manage global channels'), |
'access' => user_access('manage global channels'), |
| 43 |
'callback' => 'subscription_admin_delete_channel', |
'callback' => 'subscription_admin_delete_channel', |
| 44 |
'type' => MENU_CALLBACK); |
'type' => MENU_CALLBACK); |
|
} |
|
| 45 |
} |
} |
| 46 |
return $items; |
return $items; |
| 47 |
} |
} |
| 48 |
/** |
/** |
| 49 |
* Implementation of hook_perm(). |
* Implementation of hook_perm(). |
| 50 |
|
* TODO: rename manage subscriptions to something less admin sounding, like create subscriptions |
| 51 |
*/ |
*/ |
| 52 |
function subscription_perm() { |
function subscription_perm() { |
| 53 |
return array('manage subscriptions', 'manage global channels'); |
return array('manage subscriptions', 'manage global channels'); |
| 90 |
$new_objects['comment'] = $comments; |
$new_objects['comment'] = $comments; |
| 91 |
return array($new_objects); |
return array($new_objects); |
| 92 |
case 'special': |
case 'special': |
| 93 |
return '<p>'.l(t("Subscribe to all comments"), 'subscription/add/comment').'</p>'; |
return l(t("Subscribe to all comments"), 'subscription/add/comment'); |
| 94 |
} |
} |
| 95 |
} |
} |
| 96 |
/** |
/** |
| 115 |
|
|
| 116 |
} |
} |
| 117 |
/** |
/** |
| 118 |
* Subscription modul admin page |
* Main admin page |
| 119 |
*/ |
*/ |
| 120 |
function subscription_admin_channels() { |
function subscription_admin_channels() { |
| 121 |
$avail_channels = subscription_get_available_channels(); |
$avail_channels = subscription_get_available_channels(); |
| 122 |
if (!empty($_POST)) { |
if (!empty($_POST)) { |
| 123 |
$edit = $_POST['edit']; |
$edit = $_POST['edit']; |
| 124 |
if (empty($edit['name'])) { |
if (empty($edit['name'])) { |
| 125 |
form_set_error("ads", t("The name is empty")); |
form_set_error("name", t("The name is empty")); |
| 126 |
} |
} |
| 127 |
else { |
else { |
| 128 |
$cid = db_next_id("subscription_channels", "cid"); |
$cid = db_next_id("subscription_channels", "cid"); |
| 129 |
db_query("INSERT INTO subscription_channels (cid,name,id,daily) VALUES (%d,'%s','%s',%d)", $cid, $edit['name'], $edit['id'], $edit['daily']); |
db_query("INSERT INTO subscription_channels (cid,name,id,daily) VALUES (%d,'%s','%s',%d)", $cid, $edit['name'], $edit['id'], $edit['daily']); |
| 130 |
drupal_set_message("ads", t("Channel created succesfully")); |
drupal_set_message(t("Channel created succesfully")); |
| 131 |
} |
} |
| 132 |
} |
} |
| 133 |
$channels = subscription_getchannels(); |
$channels = subscription_getchannels(); |
| 157 |
echo theme('page', $page); |
echo theme('page', $page); |
| 158 |
} |
} |
| 159 |
/** |
/** |
| 160 |
* Subscription modul remove a channel |
* remove a channel |
| 161 |
|
* TODO: add confirmation page. Do this when porting to 4.7 |
| 162 |
*/ |
*/ |
| 163 |
function subscription_admin_delete_channel() { |
function subscription_admin_delete_channel() { |
| 164 |
db_query("DELETE FROM {subscription_channels} WHERE cid=%d", arg(4)); |
db_query("DELETE FROM {subscription_channels} WHERE cid=%d", arg(4)); |
| 178 |
$name = node_invoke($node, 'node_name'); |
$name = node_invoke($node, 'node_name'); |
| 179 |
if ($main) { |
if ($main) { |
| 180 |
if (arg(0) == 'taxonomy' && arg(1) == 'term') { |
if (arg(0) == 'taxonomy' && arg(1) == 'term') { |
| 181 |
$links[] = l(t('subscribe to this category'), 'subscription/add/taxonomy/'. arg(2), array('title' => t('Receive e-mail whenever a content is posted to this %n.', array('%n' => $name)))); |
$links[] = l(t('subscribe to this category'), 'subscription/add/taxonomy/'. arg(2), array('title' => t('Receive e-mail whenever new content is posted to "%n".', array('%n' => $name)))); |
| 182 |
} |
} |
| 183 |
else { |
else { |
| 184 |
$links[] = l(t('subscribe to '.$node->type.'s'), 'subscription/add/node/'. $node->type, array('title' => t('Receive e-mail whenever a new %n is posted.', array('%n' => $name)))); |
//TODO: use proper node->type description and theme('placeholder') |
| 185 |
|
$links[] = l(t('subscribe to '.$node->type.'s'), 'subscription/add/node/'. $node->type, array('title' => t('Receive e-mail whenever a new "%n" is posted.', array('%n' => $name)))); |
| 186 |
} |
} |
| 187 |
} |
} |
| 188 |
else { |
else { |
| 189 |
// Attention, we use $node, because $node is about some format as $comment |
// Attention, we use $node, because $node is about some format as $comment |
| 190 |
// ex. exists an 'uid' key |
// ex. exists an 'uid' key |
| 191 |
if (subscription_subscribed('comment', $node)) { |
if (subscription_subscribed('comment', $node)) { |
| 192 |
$links[] = l(t('unsubscribe'), 'user/'.$user->uid.'/subscriptions', array('title' => t('Stop receiving e-mail whenever a new comment is posted here.'))); |
$links[] = l(t('unsubscribe'), 'user/'.$user->uid.'/subscriptions', array('title' => t('Stop receiving e-mail whenever a new comment is posted to "%title".', array('title' => $node->title)))); |
| 193 |
} |
} |
| 194 |
else { |
else { |
| 195 |
$links[] = l(t('subscribe to comments'), 'subscription/add/comment/'. $node->nid, array('title' => t('Receive e-mail whenever a comment is posted here.'))); |
$links[] = l(t('subscribe to comments'), 'subscription/add/comment/'. $node->nid, array('title' => t('Receive e-mail whenever a comment is posted to "%title."', array('%title' => $node->title)))); |
| 196 |
} |
} |
| 197 |
} |
} |
| 198 |
} |
} |
| 205 |
if (variable_get('subscription_instant_mode', 0)) { |
if (variable_get('subscription_instant_mode', 0)) { |
| 206 |
return; |
return; |
| 207 |
} |
} |
|
global $user; |
|
| 208 |
switch ($op) { |
switch ($op) { |
| 209 |
case 'insert': |
case 'insert': |
| 210 |
subscription_trigger(array('node' => array($node))); |
subscription_trigger(array('node' => array($node))); |
| 224 |
subscription_store('comment', array('nid' => $comment['nid'])); |
subscription_store('comment', array('nid' => $comment['nid'])); |
| 225 |
} |
} |
| 226 |
$parent_node = node_load(array('nid' => $comment['nid'])); |
$parent_node = node_load(array('nid' => $comment['nid'])); |
| 227 |
$new_object = (array_merge($comment, array('parent_uid' => $parent_node['uid']))); |
$new_object = (array_merge($comment, array('parent_uid' => $parent_node->uid))); |
| 228 |
$newobject = array('comment' => array($comment)); |
$newobject = array('comment' => array($comment)); |
| 229 |
subscription_trigger($newobject); |
subscription_trigger($newobject); |
| 230 |
} |
} |
| 231 |
} |
} |
| 232 |
/** |
/** |
| 233 |
* Invoke hook_subscription and prepare the result |
* Invoke hook_subscription and prepare the result |
|
* |
|
|
* |
|
| 234 |
*/ |
*/ |
| 235 |
function _subscription_invoke_cron($last_time, $now) { |
function _subscription_invoke_cron($last_time, $now) { |
| 236 |
$new = module_invoke_all('subscription', 'cron', $last_time, $now); |
$new = module_invoke_all('subscription', 'cron', $last_time, $now); |
| 248 |
return $summa; |
return $summa; |
| 249 |
} |
} |
| 250 |
/** |
/** |
| 251 |
* Implement hook_comment() |
* Implement hook_cron() |
| 252 |
*/ |
*/ |
| 253 |
function subscription_cron() { |
function subscription_cron() { |
| 254 |
$now = time(); |
$now = time(); |
| 256 |
$last_time = variable_get('subscription_last_cron', 0); |
$last_time = variable_get('subscription_last_cron', 0); |
| 257 |
subscription_trigger(_subscription_invoke_cron($last_time, $now)); |
subscription_trigger(_subscription_invoke_cron($last_time, $now)); |
| 258 |
variable_set('subscription_last_cron', $now); |
variable_set('subscription_last_cron', $now); |
| 259 |
/* daily diggest */ |
/* daily digest */ |
| 260 |
$last_daily = floor(variable_get('subscription_last_daily', 0) / (60 * 60 * 24)); |
$last_daily = floor(variable_get('subscription_last_daily', 0) / (60 * 60 * 24)); |
| 261 |
if (floor($now / (60 * 60 * 24)) > $last_daily) { |
if (floor($now / (60 * 60 * 24)) > $last_daily) { |
| 262 |
subscription_trigger(_subscription_invoke_cron($last_daily, $now), true); |
subscription_trigger(_subscription_invoke_cron($last_daily, $now), true); |
| 263 |
} |
} |
| 264 |
variable_set('subscription_last_daily', $now); |
variable_set('subscription_last_daily', $now); |
|
|
|
| 265 |
} |
} |
| 266 |
|
|
| 267 |
/** |
/** |
| 268 |
* |
* |
| 269 |
*/ |
*/ |
| 270 |
function subscription_get_all($diggest = false) { |
function subscription_get_all($digest = false) { |
| 271 |
$rules = array(); |
$rules = array(); |
| 272 |
$diggest = ($diggest ? 1 : 0); |
$digest = ($digest ? 1 : 0); |
| 273 |
$result = db_query("SELECT s.*,c.name,c.id FROM {subscription_subscriptions} s LEFT JOIN {subscription_channels} c ON s.cid=c.cid WHERE c.daily=%d ORDER BY uid, cid, object, condition", $diggest); |
$result = db_query("SELECT s.*,c.name,c.id FROM {subscription_subscriptions} s LEFT JOIN {subscription_channels} c ON s.cid=c.cid WHERE c.daily=%d ORDER BY uid, cid, object, condition", $digest); |
| 274 |
while ($rule = db_fetch_array($result)) { |
while ($rule = db_fetch_array($result)) { |
| 275 |
$rules[] = $rule; |
$rules[] = $rule; |
| 276 |
} |
} |
| 368 |
/** |
/** |
| 369 |
* Notify the users that new object created |
* Notify the users that new object created |
| 370 |
*/ |
*/ |
| 371 |
function subscription_trigger($object, $diggest = false) { |
function subscription_trigger($object, $digest = false) { |
| 372 |
$active = array(); |
$active = array(); |
| 373 |
$rules = subscription_get_all($diggest); |
$rules = subscription_get_all($digest); |
| 374 |
foreach ($rules as $rule) { |
foreach ($rules as $rule) { |
| 375 |
foreach ($object as $object_type => $group) { |
foreach ($object as $object_type => $group) { |
| 376 |
foreach ($group as $okey => $content) { |
foreach ($group as $okey => $content) { |
| 402 |
return $sid; |
return $sid; |
| 403 |
} |
} |
| 404 |
/** |
/** |
| 405 |
* Return if exist already such role |
* Return if exist current user already has a given subscription |
| 406 |
*/ |
*/ |
| 407 |
function subscription_is_subscribed($type, $condition) { |
function subscription_is_subscribed($type, $condition) { |
| 408 |
global $user; |
global $user; |
| 414 |
} |
} |
| 415 |
/** |
/** |
| 416 |
* Subscribe to some core object (node,comment...) |
* Subscribe to some core object (node,comment...) |
| 417 |
|
* TODO: use drupal_get_destination() on the subscribe links so we return user to current page and not my subscriptions page |
| 418 |
*/ |
*/ |
| 419 |
function subscription_subscribe() { |
function subscription_subscribe() { |
| 420 |
global $user; |
global $user; |
| 426 |
$condition = array('nid' => arg(3)); |
$condition = array('nid' => arg(3)); |
| 427 |
} |
} |
| 428 |
$type = arg(2); |
$type = arg(2); |
| 429 |
} |
} |
| 430 |
else if (arg(2) == "user") { |
else if (arg(2) == "user") { |
| 431 |
if (arg(3) == 'all') { |
if (arg(3) == 'all') { |
| 432 |
$condition = array('uid' => arg(4)); |
$condition = array('uid' => arg(4)); |
| 465 |
drupal_goto('user/'.$user->uid.'/subscriptions'); |
drupal_goto('user/'.$user->uid.'/subscriptions'); |
| 466 |
} |
} |
| 467 |
/** |
/** |
| 468 |
* Retrun the current users default channel cid |
* Return the current user's default channel cid |
| 469 |
* |
* |
| 470 |
* It is useful when previous current channel was deleted by admin |
* It is useful when previous current channel was deleted by admin |
| 471 |
*/ |
*/ |
| 483 |
return null; |
return null; |
| 484 |
} |
} |
| 485 |
} |
} |
| 486 |
|
|
| 487 |
/** |
/** |
| 488 |
* Implementation of hook_user(). |
* Implementation of hook_user(). |
| 489 |
*/ |
*/ |
| 490 |
function subscription_user($type, &$edit, &$user, $category = NULL) { |
function subscription_user($type, &$edit, &$account, $category = NULL) { |
| 491 |
|
global $user; |
| 492 |
|
|
| 493 |
switch ($type) { |
switch ($type) { |
| 494 |
case 'form': |
case 'form': |
| 495 |
if ($category == 'account') { |
if ($category == 'account') { |
| 503 |
'subscription_channel', |
'subscription_channel', |
| 504 |
subscription_get_default_channel(), |
subscription_get_default_channel(), |
| 505 |
$channel_select, |
$channel_select, |
| 506 |
t('Select the current destination for subscriptions.')); |
t('Select the destination for new subscriptions.')); |
| 507 |
$group .= form_checkbox(t('Automatically subscribe to threads in which you post.'), |
$group .= form_checkbox(t('Automatically subscribe to those posts in which you have participated.'), |
| 508 |
'subscription_auto', |
'subscription_auto', |
| 509 |
1, |
1, |
| 510 |
isset($edit->subscriptions_auto) ? $edit->subscriptions_auto : $user->subscriptions_auto, |
isset($edit->subscriptions_auto) ? $edit->subscriptions_auto : $account->subscriptions_auto); |
|
t('Checking this box allows you to be automatically subscribed to any thread you create, or post a comment to.')); |
|
| 511 |
} |
} |
| 512 |
return array(array('title '=> t('Subscription settings'), 'data' => $group, 'weight' => 2)); |
return array(array('title '=> t('Subscription settings'), 'data' => form_group(t('Subscription settings'), $group), 'weight' => 2)); |
| 513 |
case 'view': |
case 'view': |
| 514 |
if (user_access('manage subscriptions')) { |
if (user_access('manage subscriptions') && $user->uid != $account->uid) { |
| 515 |
return array(t('Subscribe') => |
$links[] = l(t("Subscribe to content created by this user"), 'subscription/add/user/all/' . $account->uid); |
| 516 |
'<p>'.l(t("Subscribe to content created by this user"), 'subscription/add/user/all/' . $user->uid).'</p>' . |
$links[] = l(t("Subscribe to comments to this user's content"), 'subscription/add/user/comment/' . $account->uid); |
| 517 |
'<p>'.l(t("Subscribe to comments to this user's content"), 'subscription/add/user/comment/' . $user->uid).'</p>'); |
return array(t('Subscriptions') => theme('item_list', $links)); |
| 518 |
} |
} |
| 519 |
} |
} |
| 520 |
} |
} |
| 521 |
|
|
| 522 |
/** |
/** |
| 523 |
* Unsubscribe from an role |
* Unsubscribe the current user from a given subscription |
| 524 |
|
* TODO: add security, confirmation |
| 525 |
*/ |
*/ |
| 526 |
function subscription_unsubscribe() { |
function subscription_unsubscribe() { |
| 527 |
global $user; |
global $user; |
| 590 |
$page .= "<p>".t("There is an OR relationship between the lines. If you would like to use" . |
$page .= "<p>".t("There is an OR relationship between the lines. If you would like to use" . |
| 591 |
" AND relationships, use the 'Merge' button.")."</p> "; |
" AND relationships, use the 'Merge' button.")."</p> "; |
| 592 |
$page .= "<p>".t("Depending on the channel used, you may receive one message per channel with all events.")."</p>"; |
$page .= "<p>".t("Depending on the channel used, you may receive one message per channel with all events.")."</p>"; |
| 593 |
$page .= "<p>".t("You can change the subscription target channel from your ").l(t("subscription management page"),'user/'.$user->uid.'/subscription')."</p>"; |
$page .= "<p>".t("You can change the subscription target channel from your ").l(t("subscription management page"),'user/'.$user->uid.'/subscriptions')."</p>"; |
| 594 |
$page .= "<h1>". t("Available special subscriptions") ."</h1>"; |
$page .= "<h1>". t("Available special subscriptions") ."</h1>"; |
| 595 |
$page .= implode(" ", module_invoke_all('subscription', 'special')); |
$page .= theme('item_list', module_invoke_all('subscription', 'special')); |
| 596 |
|
|
| 597 |
print theme("page", $page); |
print theme("page", $page); |
| 598 |
} |
} |
| 619 |
'subscription_instant_mode', |
'subscription_instant_mode', |
| 620 |
variable_get('subscription_instant_mode', 0), |
variable_get('subscription_instant_mode', 0), |
| 621 |
array('0' => 'instant (small sites)', '1' => 'cronned (big sites)'), |
array('0' => 'instant (small sites)', '1' => 'cronned (big sites)'), |
| 622 |
t('When to look for new content: immediately after content is created (suggested for small sites), or with most frequent cron time (suggested for big sites) ')); |
t('When to notify on new content: immediately after content is created (suggested for small sites), or after next cron run (suggested for big sites) ')); |
| 623 |
return $output; |
return $output; |
| 624 |
} |
} |
| 625 |
/* DEFAULT CHANNELS */ |
/* DEFAULT CHANNELS */ |
| 660 |
""; |
""; |
| 661 |
$group_header = |
$group_header = |
| 662 |
"========================================================================\n". |
"========================================================================\n". |
| 663 |
" ". t("NEW") ." %type%\n". |
" ". t("New") ." %type%\n". |
| 664 |
"========================================================================\n"; |
"========================================================================\n"; |
| 665 |
$dump = $global_header; |
$dump = $global_header; |
| 666 |
foreach ($objects as $type => $group) { |
foreach ($objects as $type => $group) { |
| 676 |
/* |
/* |
| 677 |
* A simple debugger channel |
* A simple debugger channel |
| 678 |
* |
* |
| 679 |
* Make sure that debug folder is exist |
* Make sure that debug folder exists |
| 680 |
*/ |
*/ |
| 681 |
function subscription_debuggerchannel($op, $objects) { |
function subscription_debuggerchannel($op, $objects) { |
| 682 |
if ($op == 'notify') { |
if ($op == 'notify') { |
| 694 |
if ($op == 'notify') { |
if ($op == 'notify') { |
| 695 |
foreach ($objects as $uid => $group) { |
foreach ($objects as $uid => $group) { |
| 696 |
$body = subscription_simpleformat($group, 'simple_mail'); |
$body = subscription_simpleformat($group, 'simple_mail'); |
| 697 |
|
// TODO: vary subject by the contents of the mailing |
| 698 |
$subject = '['.variable_get('site_name', 'drupal').']'.t('Notification from subscriptions'); |
$subject = '['.variable_get('site_name', 'drupal').']'.t('Notification from subscriptions'); |
| 699 |
$from = variable_get("site_mail",''); |
$from = variable_get("site_mail", ini_get('sendmail_from')); |
| 700 |
$user = user_load(array('uid' => $uid)); |
$user = user_load(array('uid' => $uid)); |
| 701 |
if (empty($from) || empty($user->mail) || !user_mail($user->mail, $subject, wordwrap($body, 72), "From: $from\nReply-to: $from\nX-Mailer: Drupal\nReturn-path: <$from>\nErrors-to: $from\n")) { |
if (empty($from) || empty($user->mail) || !user_mail($user->mail, $subject, wordwrap($body, 72), "From: $from\nReply-to: $from\nX-Mailer: Drupal\nReturn-path: <$from>\nErrors-to: $from\n")) { |
| 702 |
watchdog('subscription', "Invalid site or user mail address."); |
watchdog('subscription', "Invalid site or user mail address."); |