News:

Wondering if this will always be free?  See why free is better.

Main Menu

[2.1] Any bits on how to use the Alerts

Started by Diego Andrés, July 14, 2019, 12:30:49 AM

Previous topic - Next topic

Diego Andrés

Is there any information available about adding custom alerts?
Nothing fancy just the basics  ;D

SMF Tricks - Free & Premium Responsive Themes for SMF.

SychO

Well, for starters if you're gonna be adding a custom alert, you should add an option for users to be able to disable/enable it in the profile notifications area, you can do that with the integrate_alert_types hook which is called from Profile-Modify.php line 2080

As for sending out the alert, the proper way of doing it is to create a background task like so

<?php
// Prepare to send out notifications
$smcFunc['db_insert']('insert',
'{db_prefix}background_tasks',
array('task_file' => 'string''task_class' => 'string''task_data' => 'string''claimed_time' => 'int'),
array('$sourcedir/tasks/BackgroundTaskName-Notify.php''BackgroundTaskName_Notify_Background'$smcFunc['json_encode'](array(
'sender_id' => $context['user']['id'],
'sender_name' => $context['user']['name'],
'time' => time(),
...
)), 0),
array('id_task')
);


After that you go ahead and create your class located under $sourcedir/tasks, this is where the alerts and/or emails will be sent/inserted.
Note that you will be able to access the json formatted array through the background tasks's $_details attribute.

The class has an execute() method where all the work will be done.


<?php

class BackgroundTaskName_Notify_Background extends SMF_BackgroundTask
{
/**
 * This executes the task - loads up the information, puts the email in the queue and inserts alerts as needed.
 * @return bool Always returns true.
 */
public function execute()
{
...

return true;
}
}


You will have to query/get all the members that are supposed to receive this alert, and then you will want to check their preferences and if they want to receive an alert/email


<?php

class BackgroundTaskName_Notify_Background extends SMF_BackgroundTask
{
/**
 * This executes the task - loads up the information, puts the email in the queue and inserts alerts as needed.
 * @return bool Always returns true.
 */
public function execute()
{
// Query/get members here
$members = ...

// Result is an array of member ids in $members (as an example)
// You probably want to remove the sender from the array
$members array_diff($members, array($this->_details['sender_id']));

// Preferences
require_once($sourcedir '/Subs-Notify.php');
$prefs getNotifyPrefs($members'YOUR_ALERT_CUSTOM_NAME'true);

$alert_bits = array(
'alert' => self::RECEIVE_NOTIFY_ALERT,
'email' => self::RECEIVE_NOTIFY_EMAIL,
);
$notifies = array();

foreach ($prefs as $member => $pref_option)
{
foreach ($alert_bits as $type => $bitvalue)
if ($pref_option['msg_report'] & $bitvalue)
$notifies[$type][] = $member;
}

// Those receiving alerts
if (!empty($notifies['alert']))
{
// Alerts are relatively easy.
$insert_rows = array();
foreach ($notifies['alert'] as $member)
{
$insert_rows[] = array(
...
);
}

$smcFunc['db_insert']('insert',
'{db_prefix}user_alerts',
array('alert_time' => 'int''id_member' => 'int''id_member_started' => 'int',
'member_name' => 'string''content_type' => 'string''content_id' => 'int',
'content_action' => 'string''is_read' => 'int''extra' => 'string'),
$insert_rows,
array('id_alert')
);

// Update their alert count
updateMemberData($notifies['alert'], array('alerts' => '+'));
}

// Those receiving emails
if (!empty($notifies['email']))
{
...
}

return true;
}
}


Note that updateMemberData() has got to be called after inserting the new alerts, it MUST NOT be before.

You should take a look at any of the tasks located under $sourcedir/tasks they are great examples :), I've taken some of the code above from MsgReport-Notify.php
Checkout My Themes:
-

Potato  •  Ackerman  •  SunRise  •  NightBreeze

Diego Andrés


SMF Tricks - Free & Premium Responsive Themes for SMF.

vbgamer45

Community Suite for SMF - Take your forum to the next level built for SMF, Gallery,Store,Classifieds,Downloads,more!

SMFHacks.com -  Paid Modifications for SMF

Mods:
EzPortal - Portal System for SMF
SMF Gallery Pro
SMF Store SMF Classifieds Ad Seller Pro

Diego Andrés

Having a look at that MsgReport-Notify.php as you mentioned.
I've got my alert working. However, for that particular alert (MsgReport-Notify) you guys seem to be cheating as the txt string has a different text on 2 different language files.

Is there a parameter we could use to set a different language string so I can have both strings on the same language file?
I'm referring to the setting txt string for enabling/disabling the alert in profile and the one that actually appears in the alert.

SMF Tricks - Free & Premium Responsive Themes for SMF.

Diego Andrés

So I can use content_type for the actual alert. I got that working.
Thanks

SMF Tricks - Free & Premium Responsive Themes for SMF.

Arantor

You don't technically *need* a background task. If you're doing something where you're not checking the user's preference and realistically only sending one at a time, just insert into the alerts table and call updateMemberData to bump the alerts count.

The background task is only to push it outside of the code where you're doing the work so it can return to the user faster - in 2.0 if people have notifications set up on a topic "instantly", that gets done immediately on posting which is why on some sites it can take a while to return to topic once done. In 2.1 this whole thing can be safely punted out to the background tasks and the main process can return to the user immediately.

Diego Andrés

So if it's a 1v1 alert I could skip the background task?

SMF Tricks - Free & Premium Responsive Themes for SMF.

Arantor

You could, provided you're willing to accept the hit of working out if the user should get an alert in the same page load. The whole deal of background tasks is to move the processing to where the normal users won't see it so it won't slow down page loads for them.

vbgamer45

Adding some more information.
integrate_fetch_alerts you can set a custom icon via
$alert['icon'] = '<img class="alert_icon" src="https://site.com/icon.png">';

To have an alert enabled by default you need to insert into the user_alerts_prefs table and set id_member to 0 and  alert_value = 1 along with your alert_pref name.

Community Suite for SMF - Take your forum to the next level built for SMF, Gallery,Store,Classifieds,Downloads,more!

SMFHacks.com -  Paid Modifications for SMF

Mods:
EzPortal - Portal System for SMF
SMF Gallery Pro
SMF Store SMF Classifieds Ad Seller Pro

Diego Andrés

Yes, I recommend using <span class="main_icons icon"></span> instead of a plain image, in case a theme replaces the icons with others or similar, AND specially if you didn't add a new custom icon for that alert.

SMF Tricks - Free & Premium Responsive Themes for SMF.


vbgamer45

Does content_id need to be unique? In the following code below. If multiple of same type of alert for a msg. Using the message id as the content id.

$smcFunc['db_insert']('insert',
'{db_prefix}user_alerts',
array('alert_time' => 'int', 'id_member' => 'int', 'id_member_started' => 'int',
'member_name' => 'string', 'content_type' => 'string', 'content_id' => 'int',
'content_action' => 'string', 'is_read' => 'int', 'extra' => 'string'),
$insert_rows,
array('id_alert')
);

Community Suite for SMF - Take your forum to the next level built for SMF, Gallery,Store,Classifieds,Downloads,more!

SMFHacks.com -  Paid Modifications for SMF

Mods:
EzPortal - Portal System for SMF
SMF Gallery Pro
SMF Store SMF Classifieds Ad Seller Pro

Diego Andrés

I believe they don't need to be unique, but you can't have multiple rows of say
content_id = 1, id_member = 1, content_action = msg. One of the columns would have to be different for each row.

content_id could be a gallery item, or a comment in a gallery item which could coincidentally have the same id as some msg in the forum, but that's when content_action matters, they won't match. One would be content_action = msg, other would be content_action = gallery_item, and content_action = gallery_comment and so on. And of course, id_member is the user liking which shouldn't repeat per content_action and content_id

Idk if my explanation is good enough but I think that's how it works

SMF Tricks - Free & Premium Responsive Themes for SMF.

Arantor

Sure you can have multiple instances of things.

content_type = what type of thing the alert is about, e.g. msg
content_id = which one of the type of thing the alert is about, e.g. for a message, its id_msg
content_action = what you are doing with the content, e.g. like

This produces the compound msg_like which is how you find the language string for it.

Pretty sure without checking that id_member is the person who should get the alert and id_member_started is the person whose action triggered it.

Advertisement: