View source
<?php
require_once 'auto_expire.inc';
function auto_expire_perm() {
return array(
ADMINISTER_AUTO_EXPIRE,
EXTEND_AUTO_EXPIRE_OWN,
EXTEND_AUTO_EXPIRE_ALL,
);
}
function auto_expire_help($section) {
switch ($section) {
case 'admin/help#auto_expire':
case 'admin/modules#description':
return t('Expires nodes automatically.');
break;
}
}
function auto_expire_menu($may_cache) {
$items = array();
if ($may_cache) {
}
else {
$items[] = array(
'path' => 'admin/settings/auto_expire',
'title' => t('Auto Expire'),
'description' => t('Set node types that auto expire.'),
'callback' => 'drupal_get_form',
'callback arguments' => '_auto_expire_admin_settings',
'access' => user_access(ADMINISTER_AUTO_EXPIRE),
'type' => MENU_NORMAL_ITEM,
);
if (arg(0) == 'node' && is_numeric(arg(1))) {
$node = node_load(arg(1));
if (_auto_expire_is_expiring_node($node)) {
$items[] = array(
'path' => 'node/' . $node->nid . '/expiry',
'title' => t('Extend'),
'description' => t('See and extend the expiry period.'),
'callback' => 'drupal_get_form',
'callback arguments' => array(
'_auto_expire_expiry',
$node->nid,
),
'access' => _auto_expire_can_user_extend($node),
'type' => MENU_LOCAL_TASK,
'weight' => 10,
);
}
}
}
return $items;
}
function _auto_expire_is_expiring_node($node) {
return variable_get(AUTO_EXPIRE_NODE_TYPE . $node->type . '_e', 0);
}
function _auto_expire_can_user_extend($node) {
global $user;
return user_access(EXTEND_AUTO_EXPIRE_ALL) || user_access(EXTEND_AUTO_EXPIRE_OWN) && $user->uid > 0 && $node->uid == $user->uid;
}
function _auto_expire_expiry($nid) {
$node = node_load($nid);
drupal_set_title(check_plain($node->title));
$expire = _auto_expire_get_expire($node->nid);
$code = AUTO_EXPIRE_NODE_TYPE . $node->type;
$warn = variable_get($code . '_w', AUTO_EXPIRE_WARN);
$form['nid'] = array(
'#type' => 'value',
'#value' => $nid,
);
$form['expireson'] = array(
'#value' => '<p>' . t('!title will expire on !date<br />that is in !interval.', array(
'!title' => $node->title,
'!date' => format_date($expire),
'!interval' => format_interval($expire - time()),
)) . '</p>',
);
if (time() > $expire - $warn * 24 * 60 * 60) {
$days = variable_get($code . '_d', AUTO_EXPIRE_DAYS);
$form['extendby'] = array(
'#value' => '<p>' . format_plural($days, 'You can extend it with 1 day.', 'You can extend it with @count days.') . '</p>',
);
$form['extend'] = array(
'#type' => 'submit',
'#value' => t('Extend'),
);
}
else {
$form['extendwhen'] = array(
'#value' => '<p>' . format_plural($warn, 'You will be able to extend this 24 hours before the expiry time.', 'You will be able to extend this @count days before the expiry time.') . ' ' . t('You will receive an email notification at that time.') . '</p>',
);
}
return $form;
}
function _auto_expire_expiry_submit($form_id, $form_values) {
$op = $form_values['op'];
$node = node_load($form_values['nid']);
switch ($op) {
case t('Extend'):
$days = variable_get(AUTO_EXPIRE_NODE_TYPE . $node->type . '_d', AUTO_EXPIRE_DAYS);
db_query('UPDATE {auto_expire} SET expire = %d, extended = extended + 1, warned = 0 WHERE nid = %d', time() + $days * 24 * 60 * 60, $node->nid);
db_query('UPDATE {node} SET status = 1 WHERE nid = %d', $node->nid);
watchdog('auto_expire', "Extended node {$node->nid} by {$days} days", WATCHDOG_NOTICE);
drupal_set_message(t('Extended for !days more days', array(
'!days' => $days,
)));
break;
}
return "node/{$node->nid}/expiry";
}
function _auto_expire_admin_settings() {
$form = array();
foreach (node_get_types() as $type => $name) {
$code = AUTO_EXPIRE_NODE_TYPE . $type;
$form['nodetypes'][$type] = array(
'#type' => 'fieldset',
'#title' => $name->name,
'#collapsible' => TRUE,
'#collapsed' => !variable_get($code . '_e', 0),
);
$form['nodetypes'][$type][$code . '_e'] = array(
'#type' => 'checkbox',
'#title' => t('Expire'),
'#return_value' => 1,
'#default_value' => variable_get($code . '_e', 0),
);
$form['nodetypes'][$type][$code . '_d'] = array(
'#type' => 'textfield',
'#title' => t('Days'),
'#field_suffix' => t('days'),
'#return_value' => 1,
'#default_value' => variable_get($code . '_d', AUTO_EXPIRE_DAYS),
'#description' => t('Number of days after an item was created when it will be automatically expired.'),
);
$form['nodetypes'][$type][$code . '_w'] = array(
'#type' => 'textfield',
'#title' => t('Warn'),
'#field_suffix' => t('days'),
'#return_value' => 1,
'#default_value' => variable_get($code . '_w', AUTO_EXPIRE_WARN),
'#description' => t('Number of days before the items expiration when a warning message is sent to the user. Set to 0 (zero) for no warnings.'),
);
$form['nodetypes'][$type][$code . '_p'] = array(
'#type' => 'textfield',
'#title' => t('Purge'),
'#field_suffix' => t('days'),
'#return_value' => 1,
'#default_value' => variable_get($code . '_p', AUTO_EXPIRE_PURGE),
'#description' => t('Number of days after an item has expired when it will be purged from the database. Set to 0 (zero) for no purge.'),
);
}
$form['email']['warn'] = array(
'#type' => 'fieldset',
'#title' => t('Expiration Warning Notification Email'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
'#description' => t("Template of email sent when content is about to expire. You can use the following variables:!type - content type, !title - title of content, !url - URL of content, !days - number of days before it expired, !site - site name, !siteurl - site URL"),
);
$form['email']['warn'][AUTO_EXPIRE_EMAIL . 'warn_subject'] = array(
'#type' => 'textfield',
'#title' => t('Email Subject'),
'#description' => t('Leave empty to disable Expiration Warning Notifications.'),
'#return_value' => 1,
'#default_value' => variable_get(AUTO_EXPIRE_EMAIL . 'warn_subject', t('!type about to expire')),
);
$form['email']['warn'][AUTO_EXPIRE_EMAIL . 'warn_body'] = array(
'#type' => 'textarea',
'#title' => t('Email Body'),
'#return_value' => 1,
'#default_value' => variable_get(AUTO_EXPIRE_EMAIL . 'warn_body', t("Your !type listing '!title' will expire in !days days.\n\nPlease visit !site if you want to renew:\n!url")),
);
$form['email']['expired'] = array(
'#type' => 'fieldset',
'#title' => t('Expired Notification Email'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
'#description' => t("Template of email sent right after the content has expired. You can use the following variables:!type - content type, !title - title of content, !site - site name, !siteurl - site URL"),
);
$form['email']['expired'][AUTO_EXPIRE_EMAIL . 'expired_subject'] = array(
'#type' => 'textfield',
'#title' => t('Email Subject'),
'#description' => t('Leave empty to disable Expired Notifications.'),
'#return_value' => 1,
'#default_value' => variable_get(AUTO_EXPIRE_EMAIL . 'expired_subject', t('!type has expired')),
);
$form['email']['expired'][AUTO_EXPIRE_EMAIL . 'expired_body'] = array(
'#type' => 'textarea',
'#title' => t('Email Body'),
'#return_value' => 1,
'#default_value' => variable_get(AUTO_EXPIRE_EMAIL . 'expired_body', t("Your !type listing '!title' has expired.\n\nPlease visit !site to add new content:\n!siteurl")),
);
$form['email']['cc'][AUTO_EXPIRE_EMAIL . 'bcc'] = array(
'#type' => 'textfield',
'#title' => t('BCC Address'),
'#description' => t('An e-mail address to blind carbon copy notifications.'),
'#return_value' => 1,
'#default_value' => variable_get(AUTO_EXPIRE_EMAIL . 'bcc', ''),
);
return system_settings_form($form);
}
function auto_expire_cron() {
foreach (node_get_types() as $type => $name) {
$code = AUTO_EXPIRE_NODE_TYPE . $type;
if (variable_get($code . '_e', 0)) {
$days = variable_get($code . '_d', AUTO_EXPIRE_DAYS);
$warn = variable_get($code . '_w', AUTO_EXPIRE_WARN);
$purge = variable_get($code . '_p', AUTO_EXPIRE_PURGE);
if ($warn > 0) {
$subject = variable_get(AUTO_EXPIRE_EMAIL . 'warn_subject', '');
$body = variable_get(AUTO_EXPIRE_EMAIL . 'warn_body', '');
switch ($GLOBALS['db_type']) {
case 'mysql':
case 'mysqli':
$result = db_query('SELECT n.nid, n.title FROM {auto_expire} e, {node} n WHERE n.nid = e.nid AND n.status = 1 AND e.warned = 0 AND (FROM_UNIXTIME(e.expire) - INTERVAL %d DAY) <= NOW()', $warn);
break;
case 'pgsql':
$result = db_query('SELECT n.nid, n.title FROM {auto_expire} e, {node} n WHERE n.nid = e.nid AND n.status = 1 AND e.warned = 0 AND ((e.expire::ABSTIME::TIMESTAMP) - INTERVAL \'%d DAYS\') <= NOW()', $warn);
break;
}
while ($node = db_fetch_object($result)) {
_auto_expire_notify_warning($node->nid, $node->title, $name->name, $days, $subject, $body);
db_query('UPDATE {auto_expire} SET warned = 1 WHERE nid = %d', $node->nid);
watchdog('auto_expire', 'Auto expire warning for node ' . $node->nid, WATCHDOG_NOTICE);
}
}
$subject = variable_get(AUTO_EXPIRE_EMAIL . 'expired_subject', '');
$body = variable_get(AUTO_EXPIRE_EMAIL . 'expired_body', '');
switch ($GLOBALS['db_type']) {
case 'mysql':
case 'mysqli':
$result = db_query('SELECT n.nid, n.title FROM {auto_expire} e, {node} n WHERE n.nid = e.nid AND n.status = 1 AND FROM_UNIXTIME(e.expire) <= NOW()');
break;
case 'pgsql':
$result = db_query('SELECT n.nid, n.title FROM {auto_expire} e, {node} n WHERE n.nid = e.nid AND n.status = 1 AND (e.expire::ABSTIME::TIMESTAMP) <= NOW()');
break;
}
while ($node = db_fetch_object($result)) {
db_query('UPDATE {node} SET status = 0 WHERE nid = %d', $node->nid);
_auto_expire_notify_expired($node->nid, $node->title, $name->name, $subject, $body);
watchdog('auto_expire', 'Unpublishing node ' . $node->nid, WATCHDOG_NOTICE);
}
if ($purge > 0) {
switch ($GLOBALS['db_type']) {
case 'mysql':
case 'mysqli':
$result = db_query('SELECT e.nid FROM {auto_expire} e, {node} n WHERE n.nid = e.nid AND n.status = 0 AND (FROM_UNIXTIME(e.expire) + INTERVAL %d DAY) <= NOW()', $purge);
break;
case 'pgsql':
$result = db_query('SELECT e.nid FROM {auto_expire} e, {node} n WHERE n.nid = e.nid AND n.status = 0 AND ((e.expire::ABSTIME::TIMESTAMP) + INTERVAL \'%d DAYS\') <= NOW()', $purge);
break;
}
$cntPurged = 0;
while ($nid = db_result($result)) {
$node = node_load($nid);
db_query('DELETE FROM {node} WHERE nid = %d', $nid);
db_query('DELETE FROM {node_revisions} WHERE nid = %d', $nid);
node_invoke($node, 'delete');
node_invoke_nodeapi($node, 'delete');
if (function_exists('search_wipe')) {
search_wipe($nid, 'node');
}
watchdog('auto_expire', "Auto expire purged node: {$nid}", WATCHDOG_NOTICE);
$cntPurged++;
}
if ($cntPurged > 0) {
cache_clear_all();
watchdog('auto_expire', "Auto expire purged {$cntPurged} node(s).", WATCHDOG_NOTICE);
}
}
}
}
}
function auto_expire_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
$code = AUTO_EXPIRE_NODE_TYPE . $node->type;
if (variable_get($code . '_e', 0)) {
switch ($op) {
case 'insert':
$days = variable_get($code . '_d', 0);
db_query('INSERT INTO {auto_expire} (nid, expire) VALUES (%d, %d)', $node->nid, $node->created + $days * 24 * 60 * 60);
drupal_set_message(t('This %type will autoexpire in %days days.', array(
'%type' => node_get_types('name', $node),
'%days' => $days,
)));
break;
case 'delete':
db_query('DELETE FROM {auto_expire} WHERE nid = %d', $node->nid);
break;
}
}
}
function auto_expire_node_type($op, $info) {
switch ($op) {
case 'delete':
$code = AUTO_EXPIRE_NODE_TYPE . $info->type;
variable_del($code . '_e');
variable_del($code . '_d');
variable_del($code . '_w');
variable_del($code . '_p');
break;
case 'update':
if (!empty($info->old_type) && $info->old_type != $info->type) {
$code_old = AUTO_EXPIRE_NODE_TYPE . $info->old_type;
$code_new = AUTO_EXPIRE_NODE_TYPE . $info->type;
$expire = variable_get($code_old . '_e', 0);
$days = variable_get($code_old . '_d', AUTO_EXPIRE_DAYS);
$warn = variable_get($code_old . '_w', AUTO_EXPIRE_WARN);
$purge = variable_get($code_old . '_p', AUTO_EXPIRE_PURGE);
variable_set($code_new . '_e', $expire);
variable_set($code_new . '_d', $days);
variable_set($code_new . '_w', $warn);
variable_set($code_new . '_p', $purge);
variable_del($code_old . '_e');
variable_del($code_old . '_d');
variable_del($code_old . '_w');
variable_del($code_old . '_p');
}
break;
}
}
function _auto_expire_notify_warning($nid, $title, $type, $days, $subject, $body) {
$args = array(
'!type' => $type,
'!title' => $title,
'!url' => url('node/' . $nid, NULL, NULL, TRUE),
'!days' => $days,
'!site' => variable_get('site_name', ''),
'!siteurl' => url('<front>', NULL, NULL, TRUE),
);
_auto_expire_notify($nid, 'auto_expire_warning', $subject, $body, $args);
}
function _auto_expire_notify_expired($nid, $title, $type, $subject, $body) {
$args = array(
'!type' => $type,
'!title' => $title,
'!site' => variable_get('site_name', ''),
'!siteurl' => url('<front>', NULL, NULL, TRUE),
);
_auto_expire_notify($nid, 'auto_expire_expired', $subject, $body, $args);
}
function _auto_expire_notify($nid, $mailkey, $subject, $body, $args) {
if (!empty($subject)) {
$result = db_query('SELECT u.mail FROM {users} u, {node} n WHERE n.nid = %d AND n.uid = u.uid AND u.status=1 AND u.uid>0', $nid);
if ($result) {
$userEmail = db_result($result);
if ($userEmail) {
$subject = t($subject, $args);
$body = t($body, $args);
$bcc = trim(variable_get(AUTO_EXPIRE_EMAIL . 'bcc', ''));
if ($bcc == '') {
$sent = drupal_mail($mailkey, $userEmail, $subject, $body);
}
else {
$headers['Bcc'] = $bcc;
$sent = drupal_mail($mailkey, $userEmail, $subject, $body, NULL, $headers);
}
if (!$sent) {
watchdog('auto_expire', 'Could not send notification email to: ' . $userEmail, WATCHDOG_ERROR);
}
}
}
}
}
function _auto_expire_get_expire($nid) {
return db_result(db_query('SELECT expire FROM {auto_expire} WHERE nid = %d', $nid));
}
function auto_expire_views_tables() {
$tables['auto_expire'] = array(
'name' => 'auto_expire',
'join' => array(
'left' => array(
'table' => 'node',
'field' => 'nid',
),
'right' => array(
'field' => 'nid',
),
),
'fields' => array(
'expire' => array(
'name' => t('Auto Expire: Expiration Date'),
'sortable' => TRUE,
'handler' => views_handler_field_dates(),
'help' => t('Date the node will expire'),
'option' => 'integer',
),
'warned' => array(
'name' => t('Auto Expire: Warning Sent?'),
'help' => t('Has the warning already been sent?'),
'field' => 'warned',
'option' => 'integer',
),
),
'filters' => array(
'expire' => array(
'field' => 'expire',
'name' => t('Auto Expire: Expiration Date'),
'help' => t('Date the node will expire. This filter allows nodes to be filtered by their expiration date. The "Value" can either be a date in the format: CCYY-MM-DD HH:MM:SS or the word "now" to use the current time. You may enter a positive or negative number in the "Option" field that will represent the amount of seconds that will be added or substracted to the time; this is most useful when combined with "now". If you have the jscalendar module from jstools installed, you can use a popup date picker here.'),
'operator' => 'views_handler_operator_gtlt',
'value' => views_handler_filter_date_value_form(),
'option' => 'string',
'handler' => 'views_handler_filter_timestamp',
),
'warned' => array(
'name' => t('Auto Expire: Warning Sent?'),
'help' => t('Has the warning already been sent?'),
'field' => 'warned',
'operator' => 'views_handler_operator_eqneq',
),
),
'sorts' => array(
'expire' => array(
'name' => t('Auto Expire: Date'),
'help' => t('Sort by date'),
'handler' => 'views_handler_sort_date',
'option' => views_handler_sort_date_options(),
),
),
);
return $tables;
}