News:

Bored?  Looking to kill some time?  Want to chat with other SMF users?  Join us in IRC chat or Discord

Main Menu

Daily digest emails?

Started by paramudduck, December 23, 2010, 08:33:32 PM

Previous topic - Next topic

paramudduck

The notifications are being sent but they just show topic name and number of posts.

Is there a setting where I can have it add a clickable url link to the topic its self?

I haven't been able to find any settings for these notifications  and forum and manual searches came up blank.

Edit forgot to add: 2 RC3 


hadesflames

There's no particular setting for this, but you can go into ./Sources/ScheduledTasks.php and search for this:

// Send out a daily email of all subscribed topics.
function scheduled_daily_digest()
{
global $is_weekly, $txt, $mbname, $scripturl, $sourcedir, $smcFunc, $context, $modSettings;

// We'll want this...
require_once($sourcedir . '/Subs-Post.php');
loadEssentialThemeData();

$is_weekly = !empty($is_weekly) ? 1 : 0;

// Right - get all the notification data FIRST.
$request = $smcFunc['db_query']('', '
SELECT ln.id_topic, COALESCE(t.id_board, ln.id_board) AS id_board, mem.email_address, mem.member_name, mem.notify_types,
mem.lngfile, mem.id_member
FROM {db_prefix}log_notify AS ln
INNER JOIN {db_prefix}members AS mem ON (mem.id_member = ln.id_member)
LEFT JOIN {db_prefix}topics AS t ON (ln.id_topic != {int:empty_topic} AND t.id_topic = ln.id_topic)
WHERE mem.notify_regularity = {int:notify_regularity}
AND mem.is_activated = {int:is_activated}',
array(
'empty_topic' => 0,
'notify_regularity' => $is_weekly ? '3' : '2',
'is_activated' => 1,
)
);
$members = array();
$langs = array();
$notify = array();
while ($row = $smcFunc['db_fetch_assoc']($request))
{
if (!isset($members[$row['id_member']]))
{
$members[$row['id_member']] = array(
'email' => $row['email_address'],
'name' => $row['member_name'],
'id' => $row['id_member'],
'notifyMod' => $row['notify_types'] < 3 ? true : false,
'lang' => $row['lngfile'],
);
$langs[$row['lngfile']] = $row['lngfile'];
}

// Store this useful data!
$boards[$row['id_board']] = $row['id_board'];
if ($row['id_topic'])
$notify['topics'][$row['id_topic']][] = $row['id_member'];
else
$notify['boards'][$row['id_board']][] = $row['id_member'];
}
$smcFunc['db_free_result']($request);

if (empty($boards))
return true;

// Just get the board names.
$request = $smcFunc['db_query']('', '
SELECT id_board, name
FROM {db_prefix}boards
WHERE id_board IN ({array_int:board_list})',
array(
'board_list' => $boards,
)
);
$boards = array();
while ($row = $smcFunc['db_fetch_assoc']($request))
$boards[$row['id_board']] = $row['name'];
$smcFunc['db_free_result']($request);

if (empty($boards))
return true;

// Get the actual topics...
$request = $smcFunc['db_query']('', '
SELECT ld.note_type, t.id_topic, t.id_board, t.id_member_started, m.id_msg, m.subject,
b.name AS board_name
FROM {db_prefix}log_digest AS ld
INNER JOIN {db_prefix}topics AS t ON (t.id_topic = ld.id_topic
AND t.id_board IN ({array_int:board_list}))
INNER JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_first_msg)
INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board)
WHERE ' . ($is_weekly ? 'ld.daily != {int:daily_value}' : 'ld.daily IN (0, 2)'),
array(
'board_list' => array_keys($boards),
'daily_value' => 2,
)
);
$types = array();
while ($row = $smcFunc['db_fetch_assoc']($request))
{
if (!isset($types[$row['note_type']][$row['id_board']]))
$types[$row['note_type']][$row['id_board']] = array(
'lines' => array(),
'name' => $row['board_name'],
'id' => $row['id_board'],
);

if ($row['note_type'] == 'reply')
{
if (isset($types[$row['note_type']][$row['id_board']]['lines'][$row['id_topic']]))
$types[$row['note_type']][$row['id_board']]['lines'][$row['id_topic']]['count']++;
else
$types[$row['note_type']][$row['id_board']]['lines'][$row['id_topic']] = array(
'id' => $row['id_topic'],
'subject' => un_htmlspecialchars($row['subject']),
'count' => 1,
);
}
elseif ($row['note_type'] == 'topic')
{
if (!isset($types[$row['note_type']][$row['id_board']]['lines'][$row['id_topic']]))
$types[$row['note_type']][$row['id_board']]['lines'][$row['id_topic']] = array(
'id' => $row['id_topic'],
'subject' => un_htmlspecialchars($row['subject']),
);
}
else
{
if (!isset($types[$row['note_type']][$row['id_board']]['lines'][$row['id_topic']]))
$types[$row['note_type']][$row['id_board']]['lines'][$row['id_topic']] = array(
'id' => $row['id_topic'],
'subject' => un_htmlspecialchars($row['subject']),
'starter' => $row['id_member_started'],
);
}

$types[$row['note_type']][$row['id_board']]['lines'][$row['id_topic']]['members'] = array();
if (!empty($notify['topics'][$row['id_topic']]))
$types[$row['note_type']][$row['id_board']]['lines'][$row['id_topic']]['members'] = array_merge($types[$row['note_type']][$row['id_board']]['lines'][$row['id_topic']]['members'], $notify['topics'][$row['id_topic']]);
if (!empty($notify['boards'][$row['id_board']]))
$types[$row['note_type']][$row['id_board']]['lines'][$row['id_topic']]['members'] = array_merge($types[$row['note_type']][$row['id_board']]['lines'][$row['id_topic']]['members'], $notify['boards'][$row['id_board']]);
}
$smcFunc['db_free_result']($request);

if (empty($types))
return true;

// Let's load all the languages into a cache thingy.
$langtxt = array();
foreach ($langs as $lang)
{
loadLanguage('Post', $lang);
loadLanguage('index', $lang);
loadLanguage('EmailTemplates', $lang);
$langtxt[$lang] = array(
'subject' => $txt['digest_subject_' . ($is_weekly ? 'weekly' : 'daily')],
'char_set' => $txt['lang_character_set'],
'intro' => sprintf($txt['digest_intro_' . ($is_weekly ? 'weekly' : 'daily')], $mbname),
'new_topics' => $txt['digest_new_topics'],
'topic_lines' => $txt['digest_new_topics_line'],
'new_replies' => $txt['digest_new_replies'],
'mod_actions' => $txt['digest_mod_actions'],
'replies_one' => $txt['digest_new_replies_one'],
'replies_many' => $txt['digest_new_replies_many'],
'sticky' => $txt['digest_mod_act_sticky'],
'lock' => $txt['digest_mod_act_lock'],
'unlock' => $txt['digest_mod_act_unlock'],
'remove' => $txt['digest_mod_act_remove'],
'move' => $txt['digest_mod_act_move'],
'merge' => $txt['digest_mod_act_merge'],
'split' => $txt['digest_mod_act_split'],
'bye' => $txt['regards_team'],
);
}

// Right - send out the silly things - this will take quite some space!
$emails = array();
foreach ($members as $mid => $member)
{
// Right character set!
$context['character_set'] = empty($modSettings['global_character_set']) ? $langtxt[$lang]['char_set'] : $modSettings['global_character_set'];

// Do the start stuff!
$email = array(
'subject' => $mbname . ' - ' . $langtxt[$lang]['subject'],
'body' => $member['name'] . ',' . "\n\n" . $langtxt[$lang]['intro'] . "\n" . $scripturl . '?action=profile;area=notification;u=' . $member['id'] . "\n",
'email' => $member['email'],
);

// All new topics?
if (isset($types['topic']))
{
$titled = false;
foreach ($types['topic'] as $id => $board)
foreach ($board['lines'] as $topic)
if (in_array($mid, $topic['members']))
{
if (!$titled)
{
$email['body'] .= "\n" . $langtxt[$lang]['new_topics'] . ':' . "\n" . '-----------------------------------------------';
$titled = true;
}
$email['body'] .= "\n" . sprintf($langtxt[$lang]['topic_lines'], $topic['subject'], $board['name']);
}
if ($titled)
$email['body'] .= "\n";
}

// What about replies?
if (isset($types['reply']))
{
$titled = false;
foreach ($types['reply'] as $id => $board)
foreach ($board['lines'] as $topic)
if (in_array($mid, $topic['members']))
{
if (!$titled)
{
$email['body'] .= "\n" . $langtxt[$lang]['new_replies'] . ':' . "\n" . '-----------------------------------------------';
$titled = true;
}
$email['body'] .= "\n" . ($topic['count'] == 1 ? sprintf($langtxt[$lang]['replies_one'], $topic['subject']) : sprintf($langtxt[$lang]['replies_many'], $topic['count'], $topic['subject']));
}

if ($titled)
$email['body'] .= "\n";
}

// Finally, moderation actions!
$titled = false;
foreach ($types as $note_type => $type)
{
if ($note_type == 'topic' || $note_type == 'reply')
continue;

foreach ($type as $id => $board)
foreach ($board['lines'] as $topic)
if (in_array($mid, $topic['members']))
{
if (!$titled)
{
$email['body'] .= "\n" . $langtxt[$lang]['mod_actions'] . ':' . "\n" . '-----------------------------------------------';
$titled = true;
}
$email['body'] .= "\n" . sprintf($langtxt[$lang][$note_type], $topic['subject']);
}

}
if ($titled)
$email['body'] .= "\n";

// Then just say our goodbyes!
$email['body'] .= "\n\n" . $txt['regards_team'];

// Send it - low priority!
sendmail($email['email'], $email['subject'], $email['body'], null, null, false, 4);
}

// Clean up...
if ($is_weekly)
{
$smcFunc['db_query']('', '
DELETE FROM {db_prefix}log_digest
WHERE daily != {int:not_daily}',
array(
'not_daily' => 0,
)
);
$smcFunc['db_query']('', '
UPDATE {db_prefix}log_digest
SET daily = {int:daily_value}
WHERE daily = {int:not_daily}',
array(
'daily_value' => 2,
'not_daily' => 0,
)
);
}
else
{
// Clear any only weekly ones, and stop us from sending daily again.
$smcFunc['db_query']('', '
DELETE FROM {db_prefix}log_digest
WHERE daily = {int:daily_value}',
array(
'daily_value' => 2,
)
);
$smcFunc['db_query']('', '
UPDATE {db_prefix}log_digest
SET daily = {int:both_value}
WHERE daily = {int:no_value}',
array(
'both_value' => 1,
'no_value' => 0,
)
);
}

// Just in case the member changes their settings mark this as sent.
$members = array_keys($members);
$smcFunc['db_query']('', '
UPDATE {db_prefix}log_notify
SET sent = {int:is_sent}
WHERE id_member IN ({array_int:member_list})',
array(
'member_list' => $members,
'is_sent' => 1,
)
);

// Log we've done it...
return true;
}


replace with this:

// Send out a daily email of all subscribed topics.
function scheduled_daily_digest()
{
global $is_weekly, $txt, $mbname, $scripturl, $sourcedir, $smcFunc, $context, $modSettings;

// We'll want this...
require_once($sourcedir . '/Subs-Post.php');
loadEssentialThemeData();

$is_weekly = !empty($is_weekly) ? 1 : 0;

// Right - get all the notification data FIRST.
$request = $smcFunc['db_query']('', '
SELECT ln.id_topic, COALESCE(t.id_board, ln.id_board) AS id_board, mem.email_address, mem.member_name, mem.notify_types,
mem.lngfile, mem.id_member
FROM {db_prefix}log_notify AS ln
INNER JOIN {db_prefix}members AS mem ON (mem.id_member = ln.id_member)
LEFT JOIN {db_prefix}topics AS t ON (ln.id_topic != {int:empty_topic} AND t.id_topic = ln.id_topic)
WHERE mem.notify_regularity = {int:notify_regularity}
AND mem.is_activated = {int:is_activated}',
array(
'empty_topic' => 0,
'notify_regularity' => $is_weekly ? '3' : '2',
'is_activated' => 1,
)
);
$members = array();
$langs = array();
$notify = array();
while ($row = $smcFunc['db_fetch_assoc']($request))
{
if (!isset($members[$row['id_member']]))
{
$members[$row['id_member']] = array(
'email' => $row['email_address'],
'name' => $row['member_name'],
'id' => $row['id_member'],
'notifyMod' => $row['notify_types'] < 3 ? true : false,
'lang' => $row['lngfile'],
);
$langs[$row['lngfile']] = $row['lngfile'];
}

// Store this useful data!
$boards[$row['id_board']] = $row['id_board'];
if ($row['id_topic'])
$notify['topics'][$row['id_topic']][] = $row['id_member'];
else
$notify['boards'][$row['id_board']][] = $row['id_member'];
}
$smcFunc['db_free_result']($request);

if (empty($boards))
return true;

// Just get the board names.
$request = $smcFunc['db_query']('', '
SELECT id_board, name
FROM {db_prefix}boards
WHERE id_board IN ({array_int:board_list})',
array(
'board_list' => $boards,
)
);
$boards = array();
while ($row = $smcFunc['db_fetch_assoc']($request))
$boards[$row['id_board']] = $row['name'];
$smcFunc['db_free_result']($request);

if (empty($boards))
return true;

// Get the actual topics...
$request = $smcFunc['db_query']('', '
SELECT ld.note_type, t.id_topic, t.id_board, t.id_member_started, m.id_msg, m.subject,
b.name AS board_name
FROM {db_prefix}log_digest AS ld
INNER JOIN {db_prefix}topics AS t ON (t.id_topic = ld.id_topic
AND t.id_board IN ({array_int:board_list}))
INNER JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_first_msg)
INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board)
WHERE ' . ($is_weekly ? 'ld.daily != {int:daily_value}' : 'ld.daily IN (0, 2)'),
array(
'board_list' => array_keys($boards),
'daily_value' => 2,
)
);
$types = array();
while ($row = $smcFunc['db_fetch_assoc']($request))
{
if (!isset($types[$row['note_type']][$row['id_board']]))
$types[$row['note_type']][$row['id_board']] = array(
'lines' => array(),
'name' => $row['board_name'],
'id' => $row['id_board'],
);

if ($row['note_type'] == 'reply')
{
if (isset($types[$row['note_type']][$row['id_board']]['lines'][$row['id_topic']]))
$types[$row['note_type']][$row['id_board']]['lines'][$row['id_topic']]['count']++;
else
$types[$row['note_type']][$row['id_board']]['lines'][$row['id_topic']] = array(
'id' => $row['id_topic'],
'subject' => un_htmlspecialchars($row['subject']),
'count' => 1,
);
}
elseif ($row['note_type'] == 'topic')
{
if (!isset($types[$row['note_type']][$row['id_board']]['lines'][$row['id_topic']]))
$types[$row['note_type']][$row['id_board']]['lines'][$row['id_topic']] = array(
'id' => $row['id_topic'],
'subject' => un_htmlspecialchars($row['subject']),
);
}
else
{
if (!isset($types[$row['note_type']][$row['id_board']]['lines'][$row['id_topic']]))
$types[$row['note_type']][$row['id_board']]['lines'][$row['id_topic']] = array(
'id' => $row['id_topic'],
'subject' => un_htmlspecialchars($row['subject']),
'starter' => $row['id_member_started'],
);
}

$types[$row['note_type']][$row['id_board']]['lines'][$row['id_topic']]['members'] = array();
if (!empty($notify['topics'][$row['id_topic']]))
$types[$row['note_type']][$row['id_board']]['lines'][$row['id_topic']]['members'] = array_merge($types[$row['note_type']][$row['id_board']]['lines'][$row['id_topic']]['members'], $notify['topics'][$row['id_topic']]);
if (!empty($notify['boards'][$row['id_board']]))
$types[$row['note_type']][$row['id_board']]['lines'][$row['id_topic']]['members'] = array_merge($types[$row['note_type']][$row['id_board']]['lines'][$row['id_topic']]['members'], $notify['boards'][$row['id_board']]);
}
$smcFunc['db_free_result']($request);

if (empty($types))
return true;

// Let's load all the languages into a cache thingy.
$langtxt = array();
foreach ($langs as $lang)
{
loadLanguage('Post', $lang);
loadLanguage('index', $lang);
loadLanguage('EmailTemplates', $lang);
$langtxt[$lang] = array(
'subject' => $txt['digest_subject_' . ($is_weekly ? 'weekly' : 'daily')],
'char_set' => $txt['lang_character_set'],
'intro' => sprintf($txt['digest_intro_' . ($is_weekly ? 'weekly' : 'daily')], $mbname),
'new_topics' => $txt['digest_new_topics'],
'topic_lines' => $txt['digest_new_topics_line'],
'new_replies' => $txt['digest_new_replies'],
'mod_actions' => $txt['digest_mod_actions'],
'replies_one' => $txt['digest_new_replies_one'],
'replies_many' => $txt['digest_new_replies_many'],
'sticky' => $txt['digest_mod_act_sticky'],
'lock' => $txt['digest_mod_act_lock'],
'unlock' => $txt['digest_mod_act_unlock'],
'remove' => $txt['digest_mod_act_remove'],
'move' => $txt['digest_mod_act_move'],
'merge' => $txt['digest_mod_act_merge'],
'split' => $txt['digest_mod_act_split'],
'bye' => $txt['regards_team'],
);
}

// Right - send out the silly things - this will take quite some space!
$emails = array();
foreach ($members as $mid => $member)
{
// Right character set!
$context['character_set'] = empty($modSettings['global_character_set']) ? $langtxt[$lang]['char_set'] : $modSettings['global_character_set'];

// Do the start stuff!
$email = array(
'subject' => $mbname . ' - ' . $langtxt[$lang]['subject'],
'body' => $member['name'] . ',' . "\n\n" . $langtxt[$lang]['intro'] . "\n" . $scripturl . '?action=profile;area=notification;u=' . $member['id'] . "\n",
'email' => $member['email'],
);

// All new topics?
if (isset($types['topic']))
{
$titled = false;
foreach ($types['topic'] as $id => $board)
foreach ($board['lines'] as $topic)
if (in_array($mid, $topic['members']))
{
if (!$titled)
{
$email['body'] .= "\n" . $langtxt[$lang]['new_topics'] . ':' . "\n" . '-----------------------------------------------';
$titled = true;
}
$email['body'] .= "\n" . sprintf($langtxt[$lang]['topic_lines'], ('<a href="' . $scripturl . '?topic=' . $topic['id'] . '">' . $topic['subject'] . '</a>'), ('<a href="' . $scripturl . '?board=' . $board['id'] . '">' . $board['name'] . '</a>'));
}
if ($titled)
$email['body'] .= "\n";
}

// What about replies?
if (isset($types['reply']))
{
$titled = false;
foreach ($types['reply'] as $id => $board)
foreach ($board['lines'] as $topic)
if (in_array($mid, $topic['members']))
{
if (!$titled)
{
$email['body'] .= "\n" . $langtxt[$lang]['new_replies'] . ':' . "\n" . '-----------------------------------------------';
$titled = true;
}
$email['body'] .= "\n" . ($topic['count'] == 1 ? sprintf($langtxt[$lang]['replies_one'], ('<a href="' . $scripturl . '?topic=' . $topic['id'] . '">' . $topic['subject'] . '</a>')) : sprintf($langtxt[$lang]['replies_many'], $topic['count'], ('<a href="' . $scripturl . '?topic=' . $topic['id'] . '">' . $topic['subject'] . '</a>')));
}

if ($titled)
$email['body'] .= "\n";
}

// Finally, moderation actions!
$titled = false;
foreach ($types as $note_type => $type)
{
if ($note_type == 'topic' || $note_type == 'reply')
continue;

foreach ($type as $id => $board)
foreach ($board['lines'] as $topic)
if (in_array($mid, $topic['members']))
{
if (!$titled)
{
$email['body'] .= "\n" . $langtxt[$lang]['mod_actions'] . ':' . "\n" . '-----------------------------------------------';
$titled = true;
}
$email['body'] .= "\n" . sprintf($langtxt[$lang][$note_type], ('<a href="' . $scripturl . '?topic=' . $topic['id'] . '">' . $topic['subject'] . '</a>'));
}

}
if ($titled)
$email['body'] .= "\n";

// Then just say our goodbyes!
$email['body'] .= "\n\n" . $txt['regards_team'];

// Send it - low priority!
sendmail($email['email'], $email['subject'], $email['body'], null, null, false, 4);
}

// Clean up...
if ($is_weekly)
{
$smcFunc['db_query']('', '
DELETE FROM {db_prefix}log_digest
WHERE daily != {int:not_daily}',
array(
'not_daily' => 0,
)
);
$smcFunc['db_query']('', '
UPDATE {db_prefix}log_digest
SET daily = {int:daily_value}
WHERE daily = {int:not_daily}',
array(
'daily_value' => 2,
'not_daily' => 0,
)
);
}
else
{
// Clear any only weekly ones, and stop us from sending daily again.
$smcFunc['db_query']('', '
DELETE FROM {db_prefix}log_digest
WHERE daily = {int:daily_value}',
array(
'daily_value' => 2,
)
);
$smcFunc['db_query']('', '
UPDATE {db_prefix}log_digest
SET daily = {int:both_value}
WHERE daily = {int:no_value}',
array(
'both_value' => 1,
'no_value' => 0,
)
);
}

// Just in case the member changes their settings mark this as sent.
$members = array_keys($members);
$smcFunc['db_query']('', '
UPDATE {db_prefix}log_notify
SET sent = {int:is_sent}
WHERE id_member IN ({array_int:member_list})',
array(
'member_list' => $members,
'is_sent' => 1,
)
);

// Log we've done it...
return true;
}

Illori

this should not require code changes, the email template is in a template file which just would need to be edited to contain what the user wants.

hadesflames

Really? So how exactly are you going to add in the specific topic id's in the language files?

Arantor

Yup, there's absolutely no replacement space in the email templates to handle this, since there's not a per-post container - if you look, it's the physical body that is updated, which is built in exactly the same way as it was before, which also doesn't fit into a neat little template on its own, it requires pre-processing.

Sadly, template edits are not the answer to most problems.
Holder of controversial views, all of which my own.


SportPistol

I've implemented the code change provided by hadesflames above with success but having problems with the formatting.

Example of a daily digest using this code:
The following topics have been started:
-----------------------------------------------
"<a href="hxxp://www.mywebsite.org/forums/index.php?topic=1513">Whats New Automations - Admin Test Message II</a>" in "<a href="hxxp://www.mywebsite.org/forums/index.php?board=32">Sandbox</a>"

The code in hadesflames post to produce the URL link in the daily digest is:
$email['body'] .= "\n" . sprintf($langtxt[$lang]['topic_lines'], ('<a href="' . $scripturl . '?topic=' . $topic['id'] . '">' . $topic['subject'] . '</a>'), ('<a href="' . $scripturl . '?board=' . $board['id'] . '">' . $board['name'] . '</a>'));

What do I change in this line of code to produce a cleanly formatted daily digest (one that does not contain the HTML code "<a href=" and </a> and quotes around "in"... etc.)

SportPistol

Received help from several sources to resolve the format question.
First, install the original code changes to ScheduledTasks.php as submitted in this topic by hadesflames .
Problem I was experiencing with the e-mail format was because it was being sent as plain text.
Change the Sendmail() command to "true" so the message is sent as HTML.
sendmail($email['email'], $email['subject'], $email['body'], null, null, true, 4);
After making the change to HTML, the message was one run on sentence.
Adjust line spacing with line breaks <br> as you see fit.  Here is one example of the change I made.
  $email['body'] .= "\n" . $langtxt[$lang]['new_replies'] . ':' . "\n" . '--'.'<br><br>';
Here is the post where I got the answer on changing the email to HTML.  topic
Hopefully a MOD will be made available to make this functionality outside of editing the scheduledtasks.php file.  Here is the discussion on that topic
Problem closed. 

Advertisement: