function _subscriptions_mail_cron in Subscriptions 2.0.x
Same name and namespace in other branches
- 6 subscriptions_mail.cron.inc \_subscriptions_mail_cron()
- 7 subscriptions_mail.cron.inc \_subscriptions_mail_cron()
Implementation of hook_cron().
Takes items from {subscriptions_queue} and generates notification emails.
1 call to _subscriptions_mail_cron()
- subscriptions_mail_cron in subscriptions_mail/
subscriptions_mail.module - Implements hook_cron().
File
- subscriptions_mail/
subscriptions_mail.cron.inc, line 13 - Subscriptions module mail gateway (cron functions).
Code
function _subscriptions_mail_cron() {
global $user, $language;
_subscriptions_mail_module_load_include('templates.inc');
$mails_allowed = variable_get('subscriptions_number_of_mails', 0);
$from = _subscriptions_mail_site_mail();
$single_count = $single_failed = $digest_count = $digest_failed = 0;
$loaded_objects = array();
$fields = array();
// Strategy for cron:
// Use a defined percentage of the total cron time (default: 50%), but leave at least 5s.
$total_seconds = ini_get('max_execution_time');
$total_seconds = empty($total_seconds) ? 240 : $total_seconds;
$lost_seconds = timer_read('page') / 1000;
$available_seconds = $total_seconds - $lost_seconds;
$usable_seconds = min(array(
$available_seconds - 5,
$total_seconds * subscriptions_mail_get_cron_percentage() / 100,
));
$watchdog = 'watchdog';
// disable automatic translation
$watchdog_variables = array(
'@Subscriptions' => 'Subscriptions',
);
//TEST: watchdog('cron', "Subscriptions has $available_seconds of $total_seconds seconds available.");
if ($usable_seconds <= 0) {
$watchdog_variables += array(
'@link' => url(SUBSCRIPTIONS_CONFIG_PATH, array(
'fragment' => 'edit-subscriptions-cron-percent',
)),
);
if ($usable_seconds == 0) {
$watchdog('cron', t('@Subscriptions cannot send any notifications because its <a href="@link">cron job time</a> is 0!', $watchdog_variables), NULL, WATCHDOG_WARNING);
}
else {
$watchdog('cron', t('@Subscriptions cannot send any notifications because the cron run has less than 5 available seconds left!', $watchdog_variables), NULL, WATCHDOG_WARNING);
}
}
while ((empty($mails_allowed) || $single_count + $digest_count < $mails_allowed) && timer_read('page') / 1000 < $lost_seconds + $usable_seconds) {
$result = db_query_range("SELECT * FROM {subscriptions_queue} WHERE suspended = 0 AND last_sent + send_interval < :time ORDER BY sqid", 0, 1, array(
':time' => time(),
));
if (!($queue_item = $result
->fetchAssoc())) {
break;
// No more ready queue items, terminate loop.
}
if (!($subscriber = user_load($queue_item['uid']))) {
$watchdog('subscriptions', t('Subscriber %uid not found.', array(
'%uid' => $queue_item['uid'],
)), NULL, WATCHDOG_WARNING);
continue;
}
$saved_user = $user;
$saved_language = $language;
drupal_save_session(FALSE);
// Clear the term cache to avoid getting a different user's set of terms.
entity_load('taxonomy_term', array(), array(), TRUE);
$lang_code = $language->language;
$user = $subscriber;
$digest_data = array(
'subs' => array(
'type' => 'digest',
),
);
$watchdog_variables['%user_name'] = $user->name;
do {
// once and repeat while adding to a digest
$watchall = variable_get('subscriptions_watchall', 0);
if (!$user->status) {
if ($watchall) {
$watchdog('subscriptions', t('Subscription of blocked user %user_name ignored.', $watchdog_variables), NULL, WATCHDOG_DEBUG);
}
}
elseif (!$user->access && !variable_get('subscriptions_mail_unaccessed_users', FALSE)) {
if ($watchall) {
$watchdog('subscriptions', t('Subscription of never-logged-in user %user_name ignored.', $watchdog_variables), NULL, WATCHDOG_DEBUG);
}
}
else {
$queue_item['mail'] = $user->mail;
/** @var $load_function string */
$load_function = $queue_item['load_function'];
$load_args = $queue_item['load_args'];
if (!isset($loaded_objects[$user->uid][$load_function][$load_args]) && $load_function($queue_item)) {
$object = $queue_item['object'];
$access = module_invoke_all('subscriptions', 'access', $load_function, $load_args, $object);
// Allow other modules to alter the data.
drupal_alter('subscriptions_access', $access);
// One FALSE vote is enough to deny. Also, we need a non-empty array.
$allow = !empty($access) && array_search(FALSE, $access) === FALSE;
if (!$allow && $watchall) {
$watchdog('subscriptions', t("User %user_name was denied access to %load(!args).", $watchdog_variables + array(
'%load' => $load_function,
'!args' => filter_xss(serialize($load_args)),
)), NULL, WATCHDOG_DEBUG);
$watchall = FALSE;
}
$loaded_objects[$user->uid][$load_function][$load_args] = $allow ? $object : FALSE;
}
if (empty($loaded_objects[$user->uid][$load_function][$load_args])) {
if ($watchall) {
$watchdog('subscriptions', t('User %user_name was unable or not allowed to %load(!args).', $watchdog_variables + array(
'%load' => $load_function,
'!args' => filter_xss(serialize($load_args)),
)), NULL, WATCHDOG_DEBUG);
}
}
else {
$object = $loaded_objects[$user->uid][$load_function][$load_args];
$module = $queue_item['module'];
$ori_field = $field = $queue_item['field'];
$ori_value = $value = $queue_item['value'];
if (!isset($fields[$lang_code][$module])) {
$fields[$lang_code][$module] = module_invoke_all('subscriptions', 'fields', $module);
}
$data_function = $fields[$lang_code][$module][$field]['data_function'];
$mailmod = empty($fields[$lang_code][$module][$field]['mail_module']) ? 'subscriptions_mail' : $fields[$lang_code][$module][$field]['mail_module'];
$mailkey = $fields[$lang_code][$module][$field]['mailkey'];
if ($mailkey_altered = module_invoke_all('subscriptions', 'mailkey_alter', $mailkey, $object, $queue_item)) {
$mailkey = $mailkey_altered[0];
}
$digest = $queue_item['digest'] > 0 || $queue_item['digest'] == -1 && _subscriptions_get_setting('digest', 0) > 0;
//$show_node_info = (isset($object->type) ? variable_get('node_submitted_' . $object->type, TRUE) : TRUE);
$data = array(
'subs' => array(
'type' => $fields[$lang_code][$module][$field]['subs_type'],
'unsubscribe_path' => "s/del/{$module}/{$ori_field}/{$ori_value}/" . $queue_item['author_uid'] . '/' . $queue_item['uid'] . '/' . md5(drupal_get_private_key() . $module . $ori_field . $ori_value . $queue_item['author_uid'] . $queue_item['uid']),
),
'user' => user_load(!empty($object->revision_uid) ? $object->revision_uid : $object->uid),
);
$data_function($data, $object, $queue_item);
drupal_alter('subscriptions_data', $data, $object, $queue_item);
//mail_edit_format($values['subscriptions_comment_body'], $data + array('comment' => $comment), array('language' => $language));
if ($digest) {
$digest_data = subscriptions_mail_digest_add_item($digest_data, $mailmod, $mailkey, $data, $user);
$digest_data['subs']['send_intervals'][$queue_item['send_interval']] = $queue_item['send_interval'];
}
else {
_subscriptions_mail_send($mailmod, $mailkey, $queue_item['name'], $queue_item['mail'], $from, $queue_item['uid'], array(
$queue_item['send_interval'],
), $data) ? ++$single_count : ++$single_failed;
}
}
}
db_delete('subscriptions_queue')
->condition('load_function', $queue_item['load_function'])
->condition('load_args', $queue_item['load_args'])
->condition('uid', $queue_item['uid'])
->execute();
if (!empty($digest)) {
// Get next ready queue item for this user.
$result = db_query_range('SELECT * FROM {subscriptions_queue} WHERE uid = :uid AND last_sent + send_interval < :send_interval ORDER BY sqid', 0, 1, array(
':uid' => $user->uid,
':send_interval' => time(),
));
if (!($queue_item = $result
->fetchAssoc())) {
_subscriptions_mail_send($mailmod, SUBSCRIPTIONS_DIGEST_MAILKEY, $digest_data['subs']['name'], $digest_data['subs']['mail'], $from, $digest_data['subs']['uid'], $digest_data['subs']['send_intervals'], $digest_data) ? ++$digest_count : ++$digest_failed;
$digest = FALSE;
$digest_data = array(
'subs' => array(
'type' => 'digest',
),
);
}
}
} while (!empty($digest));
$user = $saved_user;
$language = $saved_language;
drupal_save_session(TRUE);
}
if (module_exists('taxonomy')) {
// Clear the term cache again for the next cron client.
entity_load('taxonomy_term', array(), array(), TRUE);
}
if ($single_count + $digest_count + $single_failed + $digest_failed > 0) {
$current_seconds = timer_read('page') / 1000;
$variables = $watchdog_variables + array(
'!single_count' => $single_count,
'!digest_count' => $digest_count,
'!single_failed' => $single_failed,
'!digest_failed' => $digest_failed,
'!used_seconds' => round($current_seconds - $lost_seconds),
'!total_seconds' => $total_seconds,
'!remaining_items' => db_query("SELECT COUNT(*) FROM {subscriptions_queue} WHERE last_sent + send_interval < :send_interval AND suspended = 0", array(
':send_interval' => REQUEST_TIME,
))
->fetchField(),
'!suspended_items' => db_query("SELECT COUNT(*) FROM {subscriptions_queue} WHERE last_sent + send_interval < :send_interval AND suspended <> 0", array(
':send_interval' => REQUEST_TIME,
))
->fetchField(),
'!remaining_seconds' => round($total_seconds - $current_seconds),
'%varname' => 'subscriptions_mail_trash_silently',
'!cron' => 'cron',
);
if (variable_get('subscriptions_mail_trash_silently', 0)) {
$message = t('@Subscriptions DISCARDED !single_count single and !digest_count digest notifications in !used_seconds of !total_seconds seconds, due to the %varname variable being set.', $variables);
}
elseif ($single_failed > 0 || $digest_failed > 0) {
$message = t('@Subscriptions FAILED !single_failed single and !digest_failed digest notifications, sent !single_count single and !digest_count digest notifications in !used_seconds of !total_seconds seconds.', $variables);
}
else {
$message = t('@Subscriptions sent !single_count single and !digest_count digest notifications in !used_seconds of !total_seconds seconds.', $variables);
}
$message .= ' ' . t('!remaining_items queue items remaining (plus !suspended_items suspended), !remaining_seconds seconds left for other !cron client modules.', $variables);
$watchdog('cron', $message, NULL);
_subscriptions_mail_check_baseurl(FALSE);
}
}