Parent Directory
|
Revision Log
|
Revision Graph
#611850: Really keep users from getting notifications from blocked content types, reported by Break9.
| 1 | <?php |
| 2 | // $Id: subscriptions_content.module,v 1.41 2009/09/28 13:26:15 salvis Exp $ |
| 3 | |
| 4 | /** |
| 5 | * @file |
| 6 | * Subscriptions to content events |
| 7 | * |
| 8 | * Subscriptions_content extends the Subscriptions module to allow users to |
| 9 | * subscribe by content type. If a user subscribes to a content he will receive |
| 10 | * notifications each time a node is published. |
| 11 | * Subscriptions_content also provides the ability to subscribe to comments and |
| 12 | * updates of nodes by content type or by other kinds of subscriptions (defined |
| 13 | * by other Subscriptions submodules). |
| 14 | */ |
| 15 | |
| 16 | /** |
| 17 | * Implementation of hook_subscriptions(). |
| 18 | * |
| 19 | * @ingroup hooks |
| 20 | */ |
| 21 | function subscriptions_content_subscriptions($op, $arg0 = NULL, $arg1 = NULL, $arg2 = NULL) { |
| 22 | static $stypes = array( |
| 23 | 'node' => array('node', 'nid'), |
| 24 | 'type' => array('node', 'type'), |
| 25 | ); |
| 26 | $function = '_subscriptions_content_'. $op; |
| 27 | if (function_exists($function)) { |
| 28 | return $function($arg0, $arg1, $arg2); |
| 29 | } |
| 30 | switch ($op) { |
| 31 | case 'queue': |
| 32 | // $arg0 is $event array. |
| 33 | if ($arg0['module'] == 'node') { |
| 34 | $node = $arg0['node']; |
| 35 | $params['node']['nid']['value'] = $node->nid; |
| 36 | $params['node']['type']['value'] = $node->type; |
| 37 | if ($arg0['type'] == 'comment') { |
| 38 | $where = 's.send_comments = 1'; |
| 39 | } |
| 40 | elseif ($arg0['type'] == 'node' && $arg0['action'] == 'update') { |
| 41 | $where = 's.send_updates = 1'; |
| 42 | } |
| 43 | if (isset($where)) { |
| 44 | $params['node']['nid']['where'] = $where; |
| 45 | $params['node']['type']['where'] = $where; |
| 46 | } |
| 47 | return $params; |
| 48 | } |
| 49 | break; |
| 50 | case 'fields': // Parameter is module |
| 51 | if ($arg0 == 'node' || $arg0 == 'comment') { |
| 52 | return array( |
| 53 | 'nid' => array( |
| 54 | 'mailvars_function' => '_subscriptions_content_node_mailvars', |
| 55 | 'mailkey' => 'subscriptions_content_node-nid', |
| 56 | '!subs_type' => t('thread'), |
| 57 | ), |
| 58 | 'type' => array( |
| 59 | 'mailvars_function' => '_subscriptions_content_node_mailvars', |
| 60 | 'mailkey' => 'subscriptions_content_node-type', |
| 61 | '!subs_type' => t('content type'), |
| 62 | ), |
| 63 | ); |
| 64 | } |
| 65 | break; |
| 66 | case 'stypes': |
| 67 | return $stypes; |
| 68 | case 'stype': |
| 69 | return (isset($stypes[$arg0]) ? array_merge( $stypes[$arg0], array($arg1, $arg2)) : NULL); |
| 70 | } |
| 71 | } |
| 72 | |
| 73 | /** |
| 74 | * Implementation of hook_node_options(), subhook of hook_subscriptions(). |
| 75 | * |
| 76 | * This is called by subscriptions_ui_node_form() in subscriptions_ui.module. |
| 77 | * |
| 78 | * @ingroup form |
| 79 | * @ingroup hooks |
| 80 | * |
| 81 | * @see subscriptions_ui_node_form() |
| 82 | */ |
| 83 | function _subscriptions_content_node_options($account, $node) { |
| 84 | // Default node, field are the first three indexes, but they can be overridden in params |
| 85 | // Thread |
| 86 | $options = array(); |
| 87 | $statics = variable_get('subscriptions_static_content_types', array()); |
| 88 | if (!in_array($node->type, $statics)) { |
| 89 | $options['nid'][] = array( |
| 90 | 'name' => t('Subscribe to this page'), |
| 91 | 'params' => array('module' => 'node', 'field' => 'nid', 'value' => $node->nid), |
| 92 | 'link' => 'node/'. $node->nid, |
| 93 | ); |
| 94 | $options['nid']['weight'] = -4; |
| 95 | } |
| 96 | $unlisteds = variable_get('subscriptions_unlisted_content_types', array()); |
| 97 | if (user_access('subscribe to content types', $account)) { |
| 98 | $unlisted_tag = ''; |
| 99 | if (in_array($node->type, $unlisteds)) { |
| 100 | if (user_access('subscribe to all content types', $account)) { |
| 101 | $unlisted_tag = ' '. SUBSCRIPTIONS_UNAVAILABLE; |
| 102 | } |
| 103 | else { |
| 104 | return $options; |
| 105 | } |
| 106 | } |
| 107 | // Content type |
| 108 | $type_name = node_get_types('name', $node->type); |
| 109 | if ($type_name) { |
| 110 | $options['type'][] = array( |
| 111 | 'name' => t('To %type content', array('%type' => $type_name)) . $unlisted_tag, |
| 112 | 'params' => array('module' => 'node', 'field' => 'type', 'value' => $node->type), |
| 113 | 'link' => 'type/'. $node->type, |
| 114 | ); |
| 115 | // Content type and author |
| 116 | $options['type'][] = array( |
| 117 | 'name' => t('To %type content by %name', array('%type' => $type_name, '%name' => ($node->uid ? $node->name : variable_get('anonymous', '???')))) . $unlisted_tag, |
| 118 | 'params' => array('module' => 'node', 'field' => 'type', 'value' => $node->type, 'author_uid' => $node->uid), |
| 119 | 'link' => 'type/'. $node->type .'/'. $node->uid, |
| 120 | ); |
| 121 | $options['type']['weight'] = -2; |
| 122 | } |
| 123 | } |
| 124 | return $options; |
| 125 | } |
| 126 | |
| 127 | /** |
| 128 | * Implementation of hook_access(), subhook of hook_subscriptions(). |
| 129 | * |
| 130 | * @ingroup hooks |
| 131 | */ |
| 132 | function _subscriptions_content_access($load_function, $load_args, $node) { |
| 133 | ///global $user; /// keep this for remote debugging |
| 134 | if (($load_function == 'subscriptions_content_node_load' || ($load_function == 'subscriptions_content_comment_load' && $node->_subscriptions_comments)) && |
| 135 | ($node->status || user_access('administer nodes')) && node_access('view', $node)) { |
| 136 | if (!empty($node->type) && subscriptions_content_type_is_blocked($node->type) && !user_access('subscribe to all content types')) { |
| 137 | return FALSE; |
| 138 | } |
| 139 | // We vote 'yes'. Other modules might vote 'no' and then that wins. |
| 140 | ///watchdog('subs debug', "_sca returns TRUE for node $node->nid, user $user->uid."); /// |
| 141 | return TRUE; |
| 142 | } |
| 143 | ///watchdog('subs debug', "_sca: node_access('view', $node->nid) returns ". node_access('view', $node) ." for user $user->uid."); /// |
| 144 | } |
| 145 | |
| 146 | /** |
| 147 | * Implementation of hook_types(), subhook of hook_subscriptions(). |
| 148 | * |
| 149 | * This is called by subscriptions_types() in subscriptions.module. |
| 150 | * |
| 151 | * @return |
| 152 | * Returns information about types for Subscriptions module interface. |
| 153 | * |
| 154 | * @ingroup form |
| 155 | * @ingroup hooks |
| 156 | * |
| 157 | * @see subscriptions_types() |
| 158 | */ |
| 159 | function _subscriptions_content_types() { |
| 160 | $tr = 't'; |
| 161 | $types['node'] = array( |
| 162 | 'title' => 'Pages/Threads', |
| 163 | 'access' => 'subscribe to content', |
| 164 | 'page' => 'subscriptions_content_page_node', |
| 165 | 'fields' => array('node', 'nid'), |
| 166 | 'weight' => -4, |
| 167 | ); |
| 168 | $types['type'] = array( |
| 169 | 'title' => 'Content types', |
| 170 | 'access' => 'subscribe to content types', |
| 171 | 'page' => 'subscriptions_content_page_type', |
| 172 | 'fields' => array('node', 'type'), |
| 173 | 'weight' => -2, |
| 174 | ); |
| 175 | return $types; |
| 176 | |
| 177 | // help potx to pick up these strings: |
| 178 | t('subscribe to content'); |
| 179 | t('subscribe to content types'); |
| 180 | } |
| 181 | |
| 182 | /** |
| 183 | * Implementation of hook_nodeapi(). |
| 184 | * |
| 185 | * Catch node inserts and updates and send them to the subscriptions queue; |
| 186 | * catch node deletes and remove any associated thread subscriptions. |
| 187 | */ |
| 188 | function subscriptions_content_nodeapi(&$node, $op, $arg = 0) { |
| 189 | global $user; |
| 190 | static $unpublished_nid; |
| 191 | switch ($op) { |
| 192 | case 'load': |
| 193 | case 'prepare': |
| 194 | $unpublished_nid = ($node->status ? NULL : $node->nid); |
| 195 | $node->subscriptions_notify = TRUE; |
| 196 | break; |
| 197 | |
| 198 | case 'update': |
| 199 | if ($unpublished_nid == $node->nid && $node->status) { |
| 200 | // An unpublished node just became published -- treat this as an 'insert'! |
| 201 | $op = 'insert'; |
| 202 | } |
| 203 | // fall through |
| 204 | |
| 205 | case 'insert': |
| 206 | $event = array( |
| 207 | 'module' => 'node', |
| 208 | 'uid' => $node->uid, |
| 209 | 'load_function' => 'subscriptions_content_node_load', |
| 210 | 'load_args' => $node->nid, |
| 211 | 'type' => 'node', |
| 212 | 'action' => $op, |
| 213 | 'is_new' => ($op == 'insert'), |
| 214 | 'node' => $node, |
| 215 | ); |
| 216 | $unpublished_nid = NULL; |
| 217 | |
| 218 | // Check direct subscription and auto subscription |
| 219 | //if (isset($node->subscriptions_subscribe)) { |
| 220 | // if ($node->subscriptions_subscribe) { |
| 221 | // subscriptions_write_subscription('node', 'nid', $node->nid, -1, $user->uid); |
| 222 | // } |
| 223 | //} else |
| 224 | if ($node->uid > 0 && !$arg) { |
| 225 | _subscriptions_content_autosubscribe($node->type, 'node', 'nid', $node->nid, ($op == 'insert' ? 'on_post' : 'on_update')); |
| 226 | } |
| 227 | |
| 228 | if (!isset($node->subscriptions_notify) || $node->subscriptions_notify) { |
| 229 | subscriptions_queue($event); |
| 230 | } |
| 231 | break; |
| 232 | |
| 233 | case 'delete': |
| 234 | db_query("DELETE FROM {subscriptions} WHERE module = 'node' AND field = 'nid' AND value = '%s'", $node->nid); |
| 235 | break; |
| 236 | } |
| 237 | } |
| 238 | |
| 239 | /** |
| 240 | * Implementation of hook_comment(). |
| 241 | * |
| 242 | * Catch comment inserts and updates and send them to the subscriptions queue. |
| 243 | */ |
| 244 | function subscriptions_content_comment($comment, $op) { |
| 245 | global $user; |
| 246 | static $is_unpublished; |
| 247 | static $inserted_cid = 0; |
| 248 | $comment = (array)$comment; // $comment can be an object or an array. |
| 249 | |
| 250 | if ($op == 'form') { |
| 251 | $is_unpublished = (isset($comment['admin']) ? $comment['admin']['status']['#default_value'] : !user_access('post comments without approval')); |
| 252 | if (user_access('administer comments')) { |
| 253 | $tr = 't'; |
| 254 | $form['subscriptions_notify'] = array( |
| 255 | '#type' => 'checkbox', |
| 256 | '#title' => t('Send subscriptions notifications'), |
| 257 | '#default_value' => TRUE, |
| 258 | ); // hook_form_alter() will move the checkbox inside the Administration fieldset! |
| 259 | |
| 260 | if (isset($comment['admin']) && $is_unpublished) { // for update |
| 261 | $form['subscriptions_notify']['#description'] = t('Subscriptions notifications are not sent for unpublished comments (except to users who have the %administer_comments permission), but when you change !Status to %Published, Subscriptions will send out "new" notifications, unless you suppress this here.', |
| 262 | array('%administer_comments' => $tr('administer comments'), |
| 263 | '!Status' => $tr('Status'), |
| 264 | '%Published' => $tr('Published'))); |
| 265 | } |
| 266 | elseif ($is_unpublished) { |
| 267 | $form['subscriptions_notify']['#description'] = t('Subscriptions notifications are not sent for unpublished comments, except to users who have the %administer_comments permission, and you can even suppress the latter here.', |
| 268 | array('%administer_comments' => $tr('administer comments'))); |
| 269 | } |
| 270 | else { |
| 271 | $form['subscriptions_notify']['#description'] = t('You can suppress sending subscriptions notifications here; this option is not saved.'); |
| 272 | } |
| 273 | } |
| 274 | return (isset($form) ? $form : NULL); |
| 275 | } |
| 276 | |
| 277 | if (!isset($comment['nomail']) && ($op == 'insert' || $op == 'update' || ($op == 'publish' && $comment['cid'] != $inserted_cid))) { |
| 278 | if (!isset($comment['subscriptions_notify']) || $comment['subscriptions_notify']) { |
| 279 | $node = node_load($comment['nid']); |
| 280 | $event = array( |
| 281 | 'module' => 'node', |
| 282 | 'load_function' => 'subscriptions_content_comment_load', |
| 283 | 'load_args' => $comment['cid'], |
| 284 | 'uid' => $comment['uid'], |
| 285 | 'type' => 'comment', |
| 286 | 'action' => $op, |
| 287 | 'is_new' => ($op != 'update' || $is_unpublished && $comment['status'] == COMMENT_PUBLISHED), |
| 288 | 'node' => $node, |
| 289 | 'comment' => (object)$comment, |
| 290 | ); |
| 291 | subscriptions_queue($event); |
| 292 | $inserted_cid = $comment['cid']; |
| 293 | } |
| 294 | _subscriptions_content_autosubscribe($node->type, 'node', 'nid', $comment['nid'], 'on_comment'); |
| 295 | } |
| 296 | } |
| 297 | |
| 298 | /** |
| 299 | * Implementation of hook_form_alter(). |
| 300 | * |
| 301 | * Add the Content Settings part to admin/settings/subscriptions, |
| 302 | * |
| 303 | * @ingroup hooks |
| 304 | * @ingroup form |
| 305 | */ |
| 306 | function subscriptions_content_form_subscriptions_settings_form_alter(&$form, &$form_state) { |
| 307 | $tr = 't'; |
| 308 | |
| 309 | // General content settings |
| 310 | $select = array(); |
| 311 | $select[0] = '<'. t('none') .'>'; |
| 312 | $nodetypes = node_get_types(); |
| 313 | foreach ($nodetypes as $ntype => $nname) { |
| 314 | $select[$ntype] = $nname->name; |
| 315 | } |
| 316 | $form['content'] = array( |
| 317 | '#type' => 'fieldset', |
| 318 | '#title' => t('Content settings'), |
| 319 | '#collapsible' => TRUE, |
| 320 | '#weight' => -10, |
| 321 | ); |
| 322 | $form['content']['subscriptions_unlisted_content_types'] = array( |
| 323 | '#type' => 'select', |
| 324 | '#title' => t('Unlisted content types'), |
| 325 | '#default_value' => variable_get('subscriptions_unlisted_content_types', array()), |
| 326 | '#options' => $select, |
| 327 | '#description' => t('Select content types which should be <strong>removed from subscription listings</strong>.<br />The content may still be available for subscribing via different kinds of subscriptions, but subscribing by content type will be unavailable for the selected types.'), |
| 328 | '#multiple' => TRUE, |
| 329 | ); |
| 330 | $form['content']['subscriptions_blocked_content_types'] = array( |
| 331 | '#type' => 'select', |
| 332 | '#title' => t('Blocked content types'), |
| 333 | '#default_value' => variable_get('subscriptions_blocked_content_types', array()), |
| 334 | '#options' => $select, |
| 335 | '#description' => t('Select content types which should be <strong>completely unavailable for subscribing</strong>, i.e. content of the selected types will never trigger notifications for regular users.'), |
| 336 | '#multiple' => TRUE, |
| 337 | ); |
| 338 | $form['content']['subscriptions_blocked_content_types_note'] = array( |
| 339 | '#type' => 'item', |
| 340 | '#title' => t('Note'), |
| 341 | '#value' => t("The %permission permission grants normal access to unlisted and blocked content types; this is intended as an administrative function, and the content types and links will be marked with a '!symbol' symbol (and appear !red_ON like this !red_OFF in the case of blocked types).", array('%permission' => t('subscribe to all content types'), '!symbol' => SUBSCRIPTIONS_UNAVAILABLE, '!red_ON' => '<span class="error">', '!red_OFF' => '</span>')), |
| 342 | ); |
| 343 | $form['content']['subscriptions_blocked_nodes'] = array( |
| 344 | '#type' => 'textfield', |
| 345 | '#title' => t('Blocked nodes'), |
| 346 | '#size' => 100, |
| 347 | '#maxlength' => 1000, |
| 348 | '#default_value' => variable_get('subscriptions_blocked_nodes', ''), |
| 349 | '#description' => t('Enter the IDs of nodes that should be <strong>completely unavailable for subscribing</strong>, separated by spaces.'), |
| 350 | ); |
| 351 | $form['#validate'][] = '_subscriptions_content_validate_blocked_nodes'; |
| 352 | |
| 353 | $statics = variable_get('subscriptions_static_content_types', array()); |
| 354 | $avoid_empty_subscribe_links = variable_get('subscriptions_avoid_empty_subscribe_links', 0); |
| 355 | $form['content']['static_content'] = array( |
| 356 | '#type' => 'fieldset', |
| 357 | '#title' => t('Static content'), |
| 358 | '#collapsible' => TRUE, |
| 359 | '#collapsed' => (empty($statics) || (count($statics) == 1 && isset($statics[0]))) && !$avoid_empty_subscribe_links, |
| 360 | ); |
| 361 | $form['content']['static_content']['subscriptions_static_content_types'] = array( |
| 362 | '#type' => 'select', |
| 363 | '#title' => t('Static content types'), |
| 364 | '#default_value' => $statics, |
| 365 | '#options' => $select, |
| 366 | '#description' => t('Select content types which do not change nor receive comments and thus should not have the %option option.', array('%option' => t('Subscribe to this page'))), |
| 367 | '#multiple' => TRUE, |
| 368 | ); |
| 369 | $form['content']['static_content']['subscriptions_avoid_empty_subscribe_links'] = array( |
| 370 | '#type' => 'checkbox', |
| 371 | '#title' => t('Avoid empty %Subscribe links', array('%Subscribe' => t('Subscribe'))), |
| 372 | '#default_value' => $avoid_empty_subscribe_links, |
| 373 | '#description' => t('Nodes of %Static_content_types may end up with no %Subscribe options at all. Turn this option on to avoid displaying %Subscribe links in this case. The default is OFF, because this option causes processing overhead for each node view operation.', array('%Static_content_types' => t('Static content types'), '%Subscribe' => t('Subscribe'))), |
| 374 | ); |
| 375 | |
| 376 | $form['content']['subscriptions_generate_full_node'] = array( |
| 377 | '#type' => 'checkbox', |
| 378 | '#title' => t('Generate the %full_node variable', array('%full_node' => '!full_node')), |
| 379 | '#default_value' => variable_get('subscriptions_generate_full_node', 0), |
| 380 | '#description' => t("Generating this variable causes considerable overhead even if it's not used, and <strong>it may even cause errors</strong>, depending on the !content_type! Default is OFF.", array('!content_type' => $tr('content type'))), |
| 381 | ); |
| 382 | } |
| 383 | |
| 384 | /** |
| 385 | * Validate the 'subscriptions_blocked_nodes' input. |
| 386 | */ |
| 387 | function _subscriptions_content_validate_blocked_nodes($form, $form_state) { |
| 388 | $form_values = $form_state['values']; |
| 389 | $values = $form_values['subscriptions_blocked_nodes']; |
| 390 | if (!empty($values)) { |
| 391 | $values = explode(' ', $values); |
| 392 | foreach ($values as $v) { |
| 393 | if (!empty($v) && !is_numeric($v)) { |
| 394 | form_set_error('subscriptions_blocked_nodes', t('Enter a series of numbers, separated by spaces.')); |
| 395 | break; |
| 396 | } |
| 397 | } |
| 398 | } |
| 399 | } |
| 400 | |
| 401 | /** |
| 402 | * Implementation of hook_form_alter(). |
| 403 | * |
| 404 | * Add the Send Subscriptions Notifications checkbox to the Publishing Options |
| 405 | * fieldset on the node edit form. |
| 406 | * |
| 407 | * @ingroup hooks |
| 408 | * @ingroup form |
| 409 | */ |
| 410 | function subscriptions_content_form_alter(&$form, &$form_state, $form_id) { |
| 411 | global $user; |
| 412 | |
| 413 | if (isset($form['type']['#value']) && $form['type']['#value'] .'_node_form' == $form_id) { |
| 414 | if (isset($form['options'])) { |
| 415 | $tr = 't'; |
| 416 | $form['options']['subscriptions_notify'] = array( |
| 417 | '#type' => 'checkbox', |
| 418 | '#title' => t('Send subscriptions notifications'), |
| 419 | '#description' => t('You may want to turn this OFF when you only change %Promoted_to_front_page or %Sticky_at_top_of_lists, otherwise Subscriptions will send out "update" notifications; this option is not saved.<br />Subscriptions does not send notifications for unpublished nodes (except to users who have the %administer_nodes permission), but when you set %Published to ON, Subscriptions will send out "new" notifications, unless you turn this off here.', |
| 420 | array('%Promoted_to_front_page' => $tr('Promoted to front page'), |
| 421 | '%Sticky_at_top_of_lists' => $tr('Sticky at top of lists'), |
| 422 | '%administer_nodes' => $tr('administer nodes'), |
| 423 | '%Published' => $tr('Published'))), |
| 424 | '#weight' => 5, |
| 425 | '#default_value' => (isset($form['#node']->subscriptions_notify) ? $form['#node']->subscriptions_notify : TRUE), |
| 426 | ); |
| 427 | } |
| 428 | } |
| 429 | } |
| 430 | |
| 431 | /** |
| 432 | * Implementation of hook_form_alter(). |
| 433 | * |
| 434 | * Add submit handler to catch bulk content moderation submissions. |
| 435 | * |
| 436 | * @ingroup hooks |
| 437 | * @ingroup form |
| 438 | */ |
| 439 | function subscriptions_content_form_node_admin_nodes_alter(&$form, &$form_state) { |
| 440 | |
| 441 | $handlers = array_reverse($form['#submit']); |
| 442 | $handlers[] = 'subscriptions_content_node_admin_nodes_submit'; |
| 443 | $form['#submit'] = array_reverse($handlers); // run before node_admin_nodes_submit()! |
| 444 | } |
| 445 | |
| 446 | /** |
| 447 | * Implementation of hook_form_alter(). |
| 448 | * |
| 449 | * Add the Send Subscriptions Notifications checkbox to the Administration Options |
| 450 | * fieldset on the comment edit form. |
| 451 | * |
| 452 | * @ingroup hooks |
| 453 | * @ingroup form |
| 454 | */ |
| 455 | function subscriptions_content_form_comment_form_alter(&$form, &$form_state) { |
| 456 | |
| 457 | if (isset($form['subscriptions_notify'])) { |
| 458 | // create the Administration fieldset if it doesn't exist: |
| 459 | if (!isset($form['admin'])) { |
| 460 | $tr = 't'; |
| 461 | $form['admin'] = array( |
| 462 | '#type' => 'fieldset', |
| 463 | '#title' => $tr('Administration'), |
| 464 | '#collapsible' => TRUE, |
| 465 | '#collapsed' => TRUE, |
| 466 | '#weight' => -2, |
| 467 | ); |
| 468 | } |
| 469 | // move the checkbox inside the Administration fieldset: |
| 470 | $form['admin']['subscriptions_notify'] = $form['subscriptions_notify']; |
| 471 | unset($form['subscriptions_notify']); |
| 472 | } |
| 473 | } |
| 474 | |
| 475 | /** |
| 476 | * Handle bulk publishing. |
| 477 | */ |
| 478 | function subscriptions_content_node_admin_nodes_submit($form, &$form_state) { |
| 479 | if ($form_state['values']['operation'] == 'publish') { |
| 480 | foreach ($form_state['values']['nodes'] as $nid) { |
| 481 | if ($nid != 0 && ($node = node_load($nid)) && !$node->status) { |
| 482 | subscriptions_content_nodeapi($node, 'prepare'); |
| 483 | subscriptions_content_nodeapi($node, 'update', TRUE); // (avoid autosubscribe) |
| 484 | } |
| 485 | } |
| 486 | } |
| 487 | } |
| 488 | |
| 489 | /** |
| 490 | * Auto-subscribe, if the content type is not blocked. |
| 491 | * |
| 492 | * @param $content_type |
| 493 | * Content type of the node to subscribe to. |
| 494 | * @param $module |
| 495 | * Parameter for subscriptions_autosubscribe(). |
| 496 | * @param $field |
| 497 | * Parameter for subscriptions_autosubscribe(). |
| 498 | * @param $value |
| 499 | * Parameter for subscriptions_autosubscribe(). |
| 500 | * @param $context |
| 501 | * Parameter for subscriptions_autosubscribe(). |
| 502 | */ |
| 503 | function _subscriptions_content_autosubscribe($content_type, $module, $field, $value, $context) |
| 504 | { |
| 505 | if (subscriptions_content_type_is_blocked($content_type)) { |
| 506 | return; |
| 507 | } |
| 508 | subscriptions_autosubscribe($module, $field, $value, $context); |
| 509 | } |
| 510 | |
| 511 | /** |
| 512 | * Return TRUE if the content type is blocked. |
| 513 | * |
| 514 | * @param $content_type |
| 515 | */ |
| 516 | function subscriptions_content_type_is_blocked($content_type) |
| 517 | { |
| 518 | $blockeds = variable_get('subscriptions_blocked_content_types', array()); |
| 519 | return in_array($content_type, $blockeds); |
| 520 | } |
| 521 | |
| 522 | /** |
| 523 | * Fill given array of mailvars with given node values. |
| 524 | * |
| 525 | * Callback of function _subscriptions_content_node_mailvars(). |
| 526 | * |
| 527 | * @param $mailvars |
| 528 | * Array of mailvars to be full-filled. |
| 529 | * @param $node |
| 530 | * Node object used to fill $mailvars. |
| 531 | * @param $field |
| 532 | * Internal use for filling variable !term_name. |
| 533 | * @param $s |
| 534 | * Subscription object. |
| 535 | */ |
| 536 | function _subscriptions_content_node_mailvars(&$mailvars, $node, $field, $s) { |
| 537 | global $language; |
| 538 | include_once drupal_get_path('module', 'subscriptions_mail') .'/subscriptions_mail.templates.inc'; |
| 539 | |
| 540 | $mailvars['!url'] = url('node/'. $node->nid, array('absolute' => TRUE)); |
| 541 | $mailvars['!node_type'] = $node->type; |
| 542 | $mailvars['!title'] = trim($node->title); |
| 543 | $mailvars['!teaser'] = _subscriptions_content_format_text($node->teaser, $node->format); |
| 544 | $mailvars['!body'] = _subscriptions_content_format_text($node->body, $node->format); |
| 545 | $mailvars['!full_node'] = (variable_get('subscriptions_generate_full_node', 0) ? _subscriptions_content_format_text(node_view($node, FALSE, TRUE, FALSE)) : '!full_node'); |
| 546 | $mailvars['!is_new'] = (integer) !empty($node->_subscriptions_is_new); |
| 547 | $mailvars['!is_updated'] = (integer) !empty($node->_subscriptions_is_updated); |
| 548 | $mailvars['!is_old'] = (integer)(empty($node->_subscriptions_is_new) && empty($node->_subscriptions_is_updated)); |
| 549 | $mailvars['!is_published'] = $node->status; |
| 550 | $mailvars['!has_new_comments'] = (integer)!empty($node->_subscriptions_comments); |
| 551 | if ($field == 'tid') { |
| 552 | $mailvars['!term_name'] = db_result(db_query('SELECT name FROM {term_data} WHERE tid = %d', $s['value'])); |
| 553 | } |
| 554 | elseif (!empty($node->tid)) { |
| 555 | $mailvars['!term_name'] = db_result(db_query('SELECT name FROM {term_data} WHERE tid = %d', $node->tid)); |
| 556 | } |
| 557 | else { |
| 558 | unset($mailvars['!term_name']); |
| 559 | } |
| 560 | if ($s['load_function'] == 'subscriptions_content_comment_load' || ($s['load_function'] == 'subscriptions_content_node_load' && isset($node->_subscriptions_comments))) { |
| 561 | $comment_template = subscriptions_mail_template_load(SUBSCRIPTIONS_COMMENT_MAILKEY, $language->language, 'body', 'CITEM'); |
| 562 | $separator = subscriptions_mail_template_load(SUBSCRIPTIONS_COMMENT_MAILKEY, $language->language, 'subject', 'SEP'); |
| 563 | $mailvars['!comments'] = _subscriptions_content_format_comments($node, $comment_template, $separator); |
| 564 | } |
| 565 | else { |
| 566 | $mailvars['!comments'] = ''; |
| 567 | } |
| 568 | $files = ''; |
| 569 | if (isset($node->files) && user_access('view uploaded files')) { |
| 570 | foreach($node->files as $file) { |
| 571 | $files .= file_create_url($file->filepath) ."\n"; |
| 572 | } |
| 573 | } |
| 574 | $mailvars['!has_files'] = empty($files) ? 0 : 1; |
| 575 | $mailvars['!files'] = $files; |
| 576 | } |
| 577 | |
| 578 | /** |
| 579 | * Convert text with formatting into plain text. |
| 580 | */ |
| 581 | function _subscriptions_content_format_text($text, $format = NULL) { |
| 582 | static $have_img_assist; |
| 583 | if (!isset($have_img_assist)) { |
| 584 | $have_img_assist = module_exists('img_assist'); |
| 585 | } |
| 586 | if (!empty($have_img_assist)) { |
| 587 | foreach (img_assist_get_macros($text) as $unexpanded_macro => $macro) { |
| 588 | $expanded_macro = img_assist_render_image($macro); |
| 589 | if (preg_match('/<img src="([^"]*)".*title="([^"]*)"/', $expanded_macro, $matches)) { |
| 590 | $text = str_replace($unexpanded_macro, " [<a href=\"$matches[1]\">$matches[2]</a>] ", $text); |
| 591 | } |
| 592 | } |
| 593 | } |
| 594 | |
| 595 | if (isset($format)) { |
| 596 | $text = check_markup($text, $format, FALSE); |
| 597 | } |
| 598 | $text = drupal_html_to_text($text); |
| 599 | return trim($text); |
| 600 | } |
| 601 | |
| 602 | /** |
| 603 | * Given a comment template returns a formatted text of comments for given |
| 604 | * node. |
| 605 | */ |
| 606 | function _subscriptions_content_format_comments($node, $comment_template, $separator) { |
| 607 | $comments = array(); |
| 608 | foreach ($node->_subscriptions_comments as $comment) { |
| 609 | $mailvars = array( |
| 610 | '!comment_name' => ($comment->uid == 0 ? variable_get('anonymous', '!comment_name') : $comment->name), |
| 611 | '!comment_title' => trim($comment->subject), |
| 612 | '!comment_text' => _subscriptions_content_format_text($comment->comment, $comment->format), |
| 613 | '!comment_url' => url('node/'. $comment->nid, array('fragment' => 'comment-'. $comment->cid, 'absolute' => TRUE)), |
| 614 | '!comment_is_new' => (integer)$comment->_subscriptions_is_new, |
| 615 | '!comment_is_published' => (integer)($comment->status == COMMENT_PUBLISHED), |
| 616 | ); |
| 617 | $template = module_invoke('subscriptions_mail', 'template_preprocess', $comment_template, $mailvars); |
| 618 | $comments[] = strtr($template ? $template : $comment_template, $mailvars); |
| 619 | } |
| 620 | return implode($separator, $comments); |
| 621 | } |
| 622 | |
| 623 | /** |
| 624 | * Custom function for loading nodes. |
| 625 | * Loads not only the node but also any attached comments that are in the queue. |
| 626 | * |
| 627 | * Function name stored in {subscriptions_queue}.load_func and called by |
| 628 | * subscriptions_mail(). |
| 629 | * |
| 630 | * @param $nid |
| 631 | * Node ID. |
| 632 | * @param $sqid |
| 633 | * Subscriptions queue ID. |
| 634 | * @param $is_new |
| 635 | * TRUE if this is a new-node notification. |
| 636 | * |
| 637 | * @return node as array(). |
| 638 | */ |
| 639 | function subscriptions_content_node_load($nid, $sqid, $is_new) { |
| 640 | // Do not cache because for different users the node can be different, |
| 641 | // subscriptions_mail_cron caches per uid. |
| 642 | $node = _subscriptions_content_load($nid, 0); |
| 643 | if (empty($node)) { |
| 644 | return; |
| 645 | } |
| 646 | if ($is_new) { |
| 647 | $node->_subscriptions_is_new = TRUE; |
| 648 | } |
| 649 | else { |
| 650 | $node->_subscriptions_is_updated = TRUE; |
| 651 | } |
| 652 | return $node; |
| 653 | } |
| 654 | |
| 655 | /** |
| 656 | * Custom function for loading comments. |
| 657 | * |
| 658 | * Function name stored in {subscriptions_queue}.load_func and called by |
| 659 | * subscriptions_mail(). |
| 660 | * |
| 661 | * @param $cid |
| 662 | * Comment ID. |
| 663 | * @param $sqid |
| 664 | * Subscriptions queue ID. |
| 665 | * |
| 666 | * @return node as array(). |
| 667 | */ |
| 668 | function subscriptions_content_comment_load($cid, $sqid) { |
| 669 | $nid = db_result(db_query('SELECT nid FROM {comments} WHERE cid = %d', $cid)); |
| 670 | if (empty($nid)) { |
| 671 | return; |
| 672 | } |
| 673 | $item = db_fetch_array(db_query('SELECT * FROM {subscriptions_queue} WHERE sqid = %d', $sqid)); |
| 674 | if ($item['module'] != 'node' || $item['field'] != 'nid') { |
| 675 | // Only if we're processing a node/nid queue item should we cut off the comments at an update item, otherwise not: |
| 676 | $sqid = NULL; |
| 677 | } |
| 678 | $node = _subscriptions_content_load($nid, $sqid); |
| 679 | if (empty($node->_subscriptions_comments)) { |
| 680 | return; |
| 681 | } |
| 682 | return $node; |
| 683 | } |
| 684 | |
| 685 | /** |
| 686 | * Returns a node if published, including any comments that are still queued, but |
| 687 | * limited by the given subscriptions queue ID. |
| 688 | */ |
| 689 | function _subscriptions_content_load($nid, $comment_load_sqid) { |
| 690 | global $user; |
| 691 | |
| 692 | $node = node_load($nid, NULL, TRUE); |
| 693 | // Note: we must not cache across users (access checking), and we take care |
| 694 | // not to process the same node more than once (except for multiple batches |
| 695 | // of comments), so we don't gain from caching nodes; on the contrary: we |
| 696 | // might run out of memory! |
| 697 | |
| 698 | if (!empty($node) && module_exists('comment')) { |
| 699 | $published_comments_only = $limit_sqids = ''; |
| 700 | if (!user_access('administer comments')) { |
| 701 | $published_comments_only = 'AND c.status = '. COMMENT_PUBLISHED; |
| 702 | } |
| 703 | if (!empty($comment_load_sqid)) { |
| 704 | // check for a later queued update notification (don't send comments past that one because it will go out as node/type with its own comments later!) |
| 705 | if ($cutoff_sqid = db_result(db_query_range("SELECT sqid FROM {subscriptions_queue} WHERE module = 'node' AND field = 'nid' AND value = '%s' AND uid = %d AND load_function = 'subscriptions_content_node_load' AND sqid > %d", array($nid, $user->uid, $comment_load_sqid), 0, 1))) { |
| 706 | $limit_sqids = 'AND q.sqid < '. (integer) $cutoff_sqid; |
| 707 | } |
| 708 | } |
| 709 | $sql = " |
| 710 | SELECT q.sqid AS _subscriptions_sqid, q.is_new AS _subscriptions_is_new, c.* |
| 711 | FROM {comments} c |
| 712 | INNER JOIN {subscriptions_queue} q ON ". ($GLOBALS['db_type'] == 'pgsql' ? 'CAST(' : '') |
| 713 | ."c.cid". ($GLOBALS['db_type'] == 'pgsql' ? ' AS VARCHAR)' : '') |
| 714 | ." = q.load_args AND q.uid = %d AND q.load_function = '%s' |
| 715 | WHERE c.nid = %d ". $published_comments_only .' '. $limit_sqids; |
| 716 | $sql = db_rewrite_sql($sql, 'c', 'cid'); |
| 717 | $result = db_query($sql, $user->uid, 'subscriptions_content_comment_load', $nid); |
| 718 | $sqids = array(); |
| 719 | while ($comment = db_fetch_object($result)) { |
| 720 | comment_invoke_comment($comment, 'view'); |
| 721 | if ($comment && user_access('access comments') && !isset($node->_subscriptions_comments[$comment->cid])) { |
| 722 | $node->_subscriptions_comments[$comment->cid] = $comment; |
| 723 | } |
| 724 | $sqids[] = $comment->_subscriptions_sqid; |
| 725 | } |
| 726 | if ($sqids) { |
| 727 | db_query('DELETE FROM {subscriptions_queue} WHERE sqid IN ('. db_placeholders($sqids) .')', $sqids); |
| 728 | } |
| 729 | } |
| 730 | return (empty($node) ? NULL : $node); |
| 731 | } |
| 732 | |
| 733 | /** |
| 734 | * Subscriptions page callback: List thread subscriptions. |
| 735 | */ |
| 736 | function subscriptions_content_page_node($account, $form) { |
| 737 | return drupal_get_form('subscriptions_content_node_form', $account, $form); |
| 738 | } |
| 739 | |
| 740 | /** |
| 741 | * Build the Thread subscriptions form at user/UID/subscriptions/node. |
| 742 | * |
| 743 | * @ingroup form |
| 744 | */ |
| 745 | function subscriptions_content_node_form(&$form_state, $account, $form) { |
| 746 | $uid = $account->uid; |
| 747 | $tr = 't'; |
| 748 | $subscriptions = array(); |
| 749 | $sql = db_rewrite_sql(" |
| 750 | SELECT n.nid, n.uid, s.send_interval, s.author_uid, s.send_comments, s.send_updates, n.title, n.status, n.changed, n.comment AS comment_count, ncs.last_comment_timestamp, |
| 751 | IF(s.send_comments + s.send_updates = 0, n.created, IF(s.send_comments + s.send_updates = 2, IF(n.changed > ncs.last_comment_timestamp, n.changed, ncs.last_comment_timestamp), IF(s.send_comments = 1, ncs.last_comment_timestamp, n.changed))) AS latest_activity |
| 752 | FROM {node} n |
| 753 | INNER JOIN {subscriptions} s ON ". ($GLOBALS['db_type'] == 'pgsql' ? 'CAST(' : '') |
| 754 | ."n.nid". ($GLOBALS['db_type'] == 'pgsql' ? ' AS VARCHAR)' : '') |
| 755 | ." = s.value |
| 756 | LEFT JOIN {node_comment_statistics} ncs ON n.nid = ncs.nid |
| 757 | WHERE s.module = 'node' AND s.field = 'nid' AND s.recipient_uid = %d |
| 758 | ORDER BY latest_activity DESC"); |
| 759 | $sql_count = db_rewrite_sql(" |
| 760 | SELECT COUNT(n.nid) |
| 761 | FROM {node} n |
| 762 | INNER JOIN {subscriptions} s ON ". ($GLOBALS['db_type'] == 'pgsql' ? 'CAST(' : '') |
| 763 | ."n.nid". ($GLOBALS['db_type'] == 'pgsql' ? ' AS VARCHAR)' : '') |
| 764 | ." = s.value |
| 765 | WHERE s.module = 'node' AND s.field = 'nid' AND s.recipient_uid = %d"); |
| 766 | $result = pager_query($sql, 50, 0, $sql_count, $uid); |
| 767 | while ($s = db_fetch_array($result)) { |
| 768 | $subscriptions[$s['nid']][$s['author_uid']] = $s; |
| 769 | } |
| 770 | |
| 771 | // check whether we've commented: |
| 772 | $nids = array_keys($subscriptions); |
| 773 | $result = db_query(" |
| 774 | SELECT nid FROM {comments} |
| 775 | WHERE |
| 776 | nid IN ( |
| 777 | SELECT ". ($GLOBALS['db_type'] == 'pgsql' ? 'CAST(' : '') |
| 778 | ."value". ($GLOBALS['db_type'] == 'pgsql' ? ' AS INTEGER)' : '') |
| 779 | ." FROM {subscriptions} WHERE module = 'node' AND field = 'nid' AND recipient_uid = %d |
| 780 | ) |
| 781 | AND uid = %d GROUP BY nid", $uid, $uid); |
| 782 | while ($c = db_fetch_array($result)) { |
| 783 | if (isset($subscriptions[$c['nid']])) { |
| 784 | foreach ($subscriptions[$c['nid']] as $author_uid => $subscription) { |
| 785 | $subscriptions[$c['nid']][$author_uid]['commented'] = TRUE; |
| 786 | } |
| 787 | } |
| 788 | } |
| 789 | |
| 790 | $form[0] = array( |
| 791 | '#type' => 'item', |
| 792 | '#title' => '', |
| 793 | '#tree' => TRUE, |
| 794 | '#theme' => 'subscriptions_form_table', |
| 795 | ); |
| 796 | $defaults = array(); |
| 797 | foreach ($subscriptions as $nid => $bundle) { |
| 798 | foreach ($bundle as $author_uid => $subscription) { |
| 799 | $title = truncate_utf8($subscription['title'], 40); |
| 800 | if ($title != $subscription['title']) { |
| 801 | $title .= '...'; |
| 802 | } |
| 803 | $title = l($title, 'node/'. $subscription['nid']); |
| 804 | if (!$subscription['status']) { |
| 805 | if (user_access('administer nodes')) { |
| 806 | $title = SUBSCRIPTIONS_UNAVAILABLE .' '. $title; |
| 807 | } |
| 808 | else { |
| 809 | continue; |
| 810 | } |
| 811 | } |
| 812 | $subscription['extra_info'] = t('@latest_activity, @authored, @commented', array( |
| 813 | '@latest_activity' => format_interval(time() - $subscription['latest_activity']), |
| 814 | '@authored' => ($subscription['uid'] == $uid ? $tr('Yes') : $tr('No')), |
| 815 | '@commented' => (!empty($subscription['commented']) ? $tr('Yes') : $tr('No')), |
| 816 | )); |
| 817 | subscriptions_form_helper($form[0], $defaults, $author_uid, $subscription['nid'], $title, $subscription); |
| 818 | } |
| 819 | } |
| 820 | unset($form[0]['author']); |
| 821 | |
| 822 | if (count(element_children($form[0]))) { |
| 823 | $form[0]['extra_info']['#title'] = t('Latest activity, authored, commented'); |
| 824 | $form[0]['defaults'] = array( |
| 825 | '#type' => 'value', |
| 826 | '#value' => $defaults, |
| 827 | ); |
| 828 | subscriptions_form_column_filter($form[0], $uid); |
| 829 | $form['#tree'] = TRUE; |
| 830 | $form['uid'] = array('#type' => 'value', '#value' => $uid); |
| 831 | $form['access_key'] = array('#type' => 'value', '#value' => 'node'); |
| 832 | $form['module'] = array('#type' => 'value', '#value' => 'node'); |
| 833 | $form['field'] = array('#type' => 'value', '#value' => 'nid'); |
| 834 | $form['submit'] = array('#type' => 'submit', '#value' => t('Save'), '#weight' => 10); |
| 835 | $form['#submit'][] = 'subscriptions_page_form_submit'; |
| 836 | $form['note'] = array('#type' => 'item', '#description' => '<div>'. t('Note: Deactivated subscriptions will be removed from the list.') .'</div>' ); |
| 837 | $form['pager'] = array('#value' => theme('pager', NULL, 50, 0)); |
| 838 | } |
| 839 | else { |
| 840 | $form = array( |
| 841 | array( |
| 842 | '#type' => 'item', |
| 843 | '#value' => t('There are no subscribed pages.'), |
| 844 | ), |
| 845 | ); |
| 846 | } |
| 847 | return $form; |
| 848 | } |
| 849 | |
| 850 | /** |
| 851 | * Subscriptions page callback: List content types subscriptions. |
| 852 | */ |
| 853 | function subscriptions_content_page_type($account, $form) { |
| 854 | return drupal_get_form('subscriptions_content_type_form', $account, $form); |
| 855 | } |
| 856 | |
| 857 | /** |
| 858 | * Build the Content Types subscriptions form at user/UID/subscriptions/type. |
| 859 | * |
| 860 | * @ingroup form |
| 861 | */ |
| 862 | function subscriptions_content_type_form(&$form_state, $account, $form) { |
| 863 | $uid = (isset($account) ? $account->uid : (is_numeric(arg(5)) ? -arg(5) : -DRUPAL_AUTHENTICATED_RID)); |
| 864 | $unlisteds = variable_get('subscriptions_unlisted_content_types', array()); |
| 865 | $blockeds = variable_get('subscriptions_blocked_content_types', array()); |
| 866 | $omits = array_merge($unlisteds, $blockeds); |
| 867 | $result = db_query(db_rewrite_sql(" |
| 868 | SELECT s.value, s.send_interval, s.author_uid, s.send_comments, s.send_updates, nt.type, nt.name |
| 869 | FROM {subscriptions} s |
| 870 | INNER JOIN {node_type} nt ON s.value = nt.type |
| 871 | WHERE s.module = 'node' AND s.field = 'type' AND s.recipient_uid = %d |
| 872 | ORDER BY s.author_uid", 'nt', 'type'), $uid); |
| 873 | while ($s = db_fetch_array($result)) { |
| 874 | $subscriptions[$s['value']][$s['author_uid']] = $s; |
| 875 | } |
| 876 | $form[0] = array( |
| 877 | '#type' => 'item', |
| 878 | '#title' => '', |
| 879 | '#tree' => TRUE, |
| 880 | '#theme' => 'subscriptions_form_table', |
| 881 | ); |
| 882 | $intervals = _subscriptions_send_intervals(); |
| 883 | foreach (node_get_types() as $type) { |
| 884 | // add the active subscriptions |
| 885 | $type_name = check_plain($type->name); |
| 886 | if (in_array($type->type, $omits)) { |
| 887 | if (user_access('subscribe to all content types') || user_access('administer site configuration')) { |
| 888 | if (in_array($type->type, $blockeds)) { |
| 889 | $type_name = '<span class="error" title="'. t('This !content_type is blocked.', array('!content_type' => t('content type'))) .'">'. $type_name .'</span> '. SUBSCRIPTIONS_UNAVAILABLE; |
| 890 | } |
| 891 | else { |
| 892 | $type_name = $type_name .' '. SUBSCRIPTIONS_UNAVAILABLE; |
| 893 | } |
| 894 | } |
| 895 | else { |
| 896 | continue; |
| 897 | } |
| 898 | } |
| 899 | if (!isset($subscriptions[$type->type][-1])) { |
| 900 | // author-less item is missing -- add it here: |
| 901 | $subscriptions[$type->type][-1] = array( |
| 902 | 'send_interval' => _subscriptions_get_setting('send_interval', ($uid < 0 ? $uid : $account)), |
| 903 | 'send_comments' => _subscriptions_get_setting('send_comments', ($uid < 0 ? $uid : $account)), |
| 904 | 'send_updates' => _subscriptions_get_setting('send_updates', ($uid < 0 ? $uid : $account)), |
| 905 | 'author_uid' => FALSE, |
| 906 | ); |
| 907 | } |
| 908 | foreach ($subscriptions[$type->type] as $author_uid => $subscription) { |
| 909 | subscriptions_form_helper($form[0], $defaults, $author_uid, $type->type, $type_name, $subscription); |
| 910 | } |
| 911 | } |
| 912 | |
| 913 | if (isset($form[0]['checkboxes'])) { |
| 914 | $form[0]['defaults'] = array( |
| 915 | '#type' => 'value', |
| 916 | '#value' => $defaults, |
| 917 | ); |
| 918 | subscriptions_form_column_filter($form[0], $uid); |
| 919 | $form['#tree'] = TRUE; |
| 920 | $form['uid'] = array('#type' => 'value', '#value' => $uid); |
| 921 | $form['access_key'] = array('#type' => 'value', '#value' => 'type'); |
| 922 | $form['module'] = array('#type' => 'value', '#value' => 'node'); |
| 923 | $form['field'] = array('#type' => 'value', '#value' => 'type'); |
| 924 | $form['submit'] = array('#type' => 'submit', '#value' => t('Save'), '#weight' => 10); |
| 925 | $form['#submit'][] = 'subscriptions_page_form_submit'; |
| 926 | } |
| 927 | else { |
| 928 | $form['header']['#value'] = t('There are no available !subs_types.', array('!subs_types' => t('content types'))); |
| 929 | unset($form['footer']); |
| 930 | } |
| 931 | return $form; |
| 932 | } |
| 933 | |
| 934 | /** |
| 935 | * Implementation of hook_mailkeys(). |
| 936 | * |
| 937 | * Provide mailkeys for mail_edit. |
| 938 | * |
| 939 | * @ingroup hooks |
| 940 | */ |
| 941 | function subscriptions_content_mailkeys() { |
| 942 | $mailkeys['node-nid'] = t('Notifications for %Pages (update/comment) subscriptions', array('%Pages' => t('Pages/Threads'))); |
| 943 | foreach (array_keys(node_get_types()) as $type) { |
| 944 | $mailkeys['node-type-'. $type] = t('Notifications for %type !content_type subscriptions', array('%type' => $type, '!content_type' => t('content type'))); |
| 945 | } |
| 946 | return $mailkeys; |
| 947 | } |
| 948 | |
| 949 | /** |
| 950 | * Implementation of hook_mail_edit_tokens_list(). |
| 951 | * |
| 952 | * Provide replacable tokens for mail_edit. |
| 953 | * |
| 954 | * @ingroup hooks |
| 955 | */ |
| 956 | function subscriptions_content_mail_edit_tokens_list($mailkey, $options = array()) { |
| 957 | $tr = 't'; |
| 958 | $tokens = array(); |
| 959 | switch ($mailkey) { |
| 960 | case 'comments': |
| 961 | $tokens += array( |
| 962 | '!comment_name' => t('The name of the comment author.'), |
| 963 | '!comment_title' => t('The title of the comment.'), |
| 964 | '!comment_text' => t('The body text of the comment.'), |
| 965 | '!comment_url' => t('The direct URL of the comment.'), |
| 966 | '!comment_is_new' => t('The type of comment notification: 1 = new comment, 0 = updated comment.'), |
| 967 | '!comment_is_published' => t('The comment publication state: 1 = published, 0 = unpublished.<br />(Unpublished comments are sent to users with the %administer_comments permission only.)', array('%administer_comments' => $tr('administer comments'))), |
| 968 | ); |
| 969 | return $tokens; |
| 970 | |
| 971 | default: |
| 972 | $tokens += array( |
| 973 | '!unsubscribe_url' => t('The user can unsubscribe by clicking this link.'), |
| 974 | '!sender_name' => t('The name of the sender (if the sender is visible).'), |
| 975 | '!sender_page' => t('The user page of the sender (if the sender is visible).'), |
| 976 | '!sender_has_contact_page' => t("The sender's contact setting: 1 = contact form enabled, 0 = disabled."), |
| 977 | '!sender_contact_page' => t('The contact page of the sender.'), |
| 978 | '!subs_type' => t("The type of the subscription, like '!thread' or '!category'.", array('!thread' => t('thread'), '!category' => $tr('category'))), |
| 979 | '!node_type' => t("The type of the node, like '!forum' or '!story'.", array('!forum' => 'forum', '!story' => 'story')), |
| 980 | '!title' => t('The title of the subscriptions item.'), |
| 981 | '!teaser' => t('An excerpt of the subscriptions item.'), |
| 982 | '!body' => t('The body of the subscriptions item.'), |
| 983 | ); |
| 984 | if (isset($options['tokens'])) { |
| 985 | $tokens += $options['tokens']; |
| 986 | } |
| 987 | |
| 988 | $tokens += module_invoke_all('subscriptions_tokens_list', $mailkey, array('tokens' => $tokens)); |
| 989 | |
| 990 | if ($mailkey != 'digest') { |
| 991 | $tokens['!full_node'] = t('The full node as it appears on the website (must be specifically enabled !here).', array('!here' => l(t('here'), 'admin/settings/subscriptions', array('fragment' => 'edit-subscriptions-generate-full-node')))); |
| 992 | } |
| 993 | $tokens += array( |
| 994 | '!url' => t('The URL of the item.'), |
| 995 | '!is_new' => t('The type of notification: 1 = new item, 0 = otherwise.'), |
| 996 | '!is_updated' => t('The type of notification: 1 = updated (possibly new and already updated) item, 0 = otherwise.'), |
| 997 | '!is_old' => t('The type of notification: 1 = neither new nor updated item, 0 = otherwise.'), |
| 998 | '!is_published' => t('The publication state: 1 = published, 0 = unpublished.<br />(Unpublished nodes are sent to users with the %administer_nodes permission only.)', array('%administer_nodes' => $tr('administer nodes'))), |
| 999 | '!has_files' => t('The presence of attached files or img_assist images: 1 = files are available in !files, 0 = no files.'), |
| 1000 | '!files' => t('The list of attached files, one per line, if any, otherwise empty.'), |
| 1001 | '!has_new_comments' => t('The comments state: 1 = comments are available in !comments, 0 = no comments.'), |
| 1002 | '!comments' => t('One or more comments if available, otherwise empty.') .'<br />', |
| 1003 | ); |
| 1004 | if ($mailkey == 'node-nid' || $mailkey == 'digest') { |
| 1005 | $tokens['!comments'] = $tokens['!comments'] . t('The rendering of the comments is defined by the template below.'); |
| 1006 | } |
| 1007 | else { |
| 1008 | $tokens['!comments'] = $tokens['!comments'] . t('The rendering of the comments is defined by the !link.', array( |
| 1009 | '!link' => '<a href="../subscriptions_content_node-nid/'. check_plain(arg(4)) .'#edit-comment-body">'. t('comment templates') .'</a>')); |
| 1010 | } |
| 1011 | } |
| 1012 | return $tokens; |
| 1013 | } |
| 1014 | |
| 1015 | /** |
| 1016 | * Implementation of hook_mail_edit_text(). |
| 1017 | * |
| 1018 | * Provide default template strings for mail_edit. |
| 1019 | * |
| 1020 | * @ingroup hooks |
| 1021 | */ |
| 1022 | function subscriptions_content_mail_edit_text($mailkey, $language) { |
| 1023 | if (!($return = module_invoke('subscriptions_mail', 'subscriptions_mail_text', $mailkey, $language))) { |
| 1024 | $return = module_invoke_all('subscriptions_mail_text', $mailkey, $language); |
| 1025 | } |
| 1026 | return $return; |
| 1027 | } |
| 1028 | |
| 1029 | /** |
| 1030 | * Implementation of hook_form_alter(). |
| 1031 | * |
| 1032 | * Add the comment parts to the subscriptions_content_node-nid mail_edit page. |
| 1033 | * |
| 1034 | * @ingroup hooks |
| 1035 | * @ingroup form |
| 1036 | */ |
| 1037 | function subscriptions_content_form_mail_edit_trans_alter(&$form, &$form_state) { |
| 1038 | $mailkey = 'subscriptions_content_node-nid'; |
| 1039 | if ($form['id']['#value'] == $mailkey) { |
| 1040 | $tr = 't'; |
| 1041 | $langcode = $form['language']['#value']; |
| 1042 | |
| 1043 | $form['mail']['note'] = array( |
| 1044 | '#value' => '<div>'. t("Note: 'new' and 'update' notifications for %Pages subscriptions use the matching !content_type subscriptions template rather than this one, if allowed; this does not apply to 'comment'-only notifications.", array('%Pages' => t('Pages/Threads'), '!content_type' => t('content type'))) .'</div>', |
| 1045 | '#weight' => -1, |
| 1046 | ); |
| 1047 | |
| 1048 | $comment_body = subscriptions_mail_template_load |