streams/Zotlabs/Lib/Enotify.php

799 lines
27 KiB
PHP
Raw Normal View History

<?php
2016-05-24 08:25:13 +00:00
namespace Zotlabs\Lib;
/**
2016-05-24 08:25:13 +00:00
* @brief File with functions and a class for generating system and email notifications.
*/
2011-12-08 09:28:27 +00:00
2016-05-24 08:25:13 +00:00
class Enotify {
2016-05-24 08:25:13 +00:00
/**
* @brief
*
* @param array $params an assoziative array with:
* * \e string \b from_xchan sender xchan hash
* * \e string \b to_xchan recipient xchan hash
* * \e array \b item an assoziative array
* * \e int \b type one of the NOTIFY_* constants from boot.php
* * \e string \b link
* * \e string \b parent_mid
* * \e string \b otype
* * \e string \b verb
* * \e string \b activity
*/
2012-03-26 08:43:26 +00:00
2016-05-24 08:25:13 +00:00
static public function submit($params) {
2016-05-24 08:25:13 +00:00
logger('notification: entry', LOGGER_DEBUG);
2012-03-26 08:43:26 +00:00
2016-05-24 08:25:13 +00:00
// throw a small amount of entropy into the system to breakup duplicates arriving at the same precise instant.
usleep(mt_rand(0, 10000));
2012-03-26 08:43:26 +00:00
2016-05-24 08:25:13 +00:00
if ($params['from_xchan']) {
$x = q("select * from xchan where xchan_hash = '%s' limit 1",
dbesc($params['from_xchan'])
);
}
if ($params['to_xchan']) {
$y = q("select channel.*, account.* from channel left join account on channel_account_id = account_id
where channel_hash = '%s' and channel_removed = 0 limit 1",
dbesc($params['to_xchan'])
);
}
if ($x & $y) {
$sender = $x[0];
$recip = $y[0];
} else {
logger('notification: no sender or recipient.');
logger('sender: ' . $params['from_xchan']);
logger('recip: ' . $params['to_xchan']);
return;
}
2011-12-08 09:28:27 +00:00
2016-05-24 08:25:13 +00:00
// from here on everything is in the recipients language
2016-05-24 08:25:13 +00:00
push_lang($recip['account_language']); // should probably have a channel language
2016-05-24 08:25:13 +00:00
$banner = t('$Projectname Notification');
$product = t('$projectname'); // PLATFORM_NAME;
$siteurl = z_root();
$thanks = t('Thank You,');
$sitename = get_config('system','sitename');
$site_admin = sprintf( t('%s Administrator'), $sitename);
2011-12-08 09:28:27 +00:00
2016-05-24 08:25:13 +00:00
$sender_name = $product;
$hostname = \App::get_hostname();
if(strpos($hostname,':'))
$hostname = substr($hostname,0,strpos($hostname,':'));
2016-05-24 08:25:13 +00:00
// Do not translate 'noreply' as it must be a legal 7-bit email address
2016-09-30 00:54:11 +00:00
$reply_email = get_config('system','reply_address');
if(! $reply_email)
$reply_email = 'noreply' . '@' . $hostname;
$sender_email = get_config('system','from_email');
2016-09-30 00:54:11 +00:00
if(! $sender_email)
$sender_email = 'Administrator' . '@' . $hostname;
$sender_name = get_config('system','from_email_name');
if(! $sender_name)
2016-10-02 08:47:25 +00:00
$sender_name = \Zotlabs\Lib\System::get_site_name();
2016-05-24 08:25:13 +00:00
$additional_mail_header = "";
if(array_key_exists('item', $params)) {
require_once('include/conversation.php');
// if it's a normal item...
if (array_key_exists('verb', $params['item'])) {
// localize_item() alters the original item so make a copy first
$i = $params['item'];
logger('calling localize');
localize_item($i);
$title = $i['title'];
$body = $i['body'];
$private = (($i['item_private']) || intval($i['item_obscured']));
}
else {
$title = $params['item']['title'];
$body = $params['item']['body'];
}
2016-11-22 22:24:38 +00:00
if($params['item']['created'] < datetime_convert('UTC','UTC','now - 1 month')) {
logger('notification invoked for an old item which may have been refetched.',LOGGER_DEBUG,LOG_INFO);
return;
}
2016-05-24 08:25:13 +00:00
}
else {
2016-05-24 08:25:13 +00:00
$title = $body = '';
}
2011-12-24 07:07:05 +00:00
2012-03-01 03:23:01 +00:00
// e.g. "your post", "David's photo", etc.
$possess_desc = t('%s <!item_type!>');
2012-03-01 02:19:08 +00:00
if ($params['type'] == NOTIFY_MAIL) {
2013-01-06 07:24:15 +00:00
logger('notification: mail');
2016-09-30 02:33:08 +00:00
$subject = sprintf( t('[$Projectname:Notify] New mail received at %s'),$sitename);
2011-12-24 07:07:05 +00:00
$preamble = sprintf( t('%1$s, %2$s sent you a new private message at %3$s.'),$recip['channel_name'], $sender['xchan_name'],$sitename);
$epreamble = sprintf( t('%1$s sent you %2$s.'),'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]', '[zrl=$itemlink]' . t('a private message') . '[/zrl]');
$sitelink = t('Please visit %s to view and/or reply to your private messages.');
$tsitelink = sprintf( $sitelink, $siteurl . '/mail/' . $params['item']['id'] );
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '/mail/' . $params['item']['id'] . '">' . $sitename . '</a>');
2014-03-17 03:49:29 +00:00
$itemlink = $siteurl . '/mail/' . $params['item']['id'];
2011-12-26 22:16:25 +00:00
}
if ($params['type'] == NOTIFY_COMMENT) {
2012-02-28 01:18:19 +00:00
// logger("notification: params = " . print_r($params, true), LOGGER_DEBUG);
2011-12-26 22:16:25 +00:00
2014-01-10 00:23:58 +00:00
$itemlink = $params['link'];
// ignore like/unlike activity on posts - they probably require a separate notification preference
if (array_key_exists('item',$params) && (! visible_activity($params['item']))) {
logger('notification: not a visible activity. Ignoring.');
pop_lang();
return;
}
$parent_mid = $params['parent_mid'];
2012-03-01 02:19:08 +00:00
2013-02-07 05:21:50 +00:00
// Check to see if there was already a notify for this post.
2012-07-04 04:40:13 +00:00
// If so don't create a second notification
2012-07-04 04:40:13 +00:00
$p = null;
2013-02-07 05:21:50 +00:00
$p = q("select id from notify where link = '%s' and uid = %d limit 1",
2012-07-04 04:40:13 +00:00
dbesc($params['link']),
2013-02-07 05:21:50 +00:00
intval($recip['channel_id'])
2012-07-04 04:40:13 +00:00
);
if ($p) {
2013-07-31 09:32:41 +00:00
logger('notification: comment already notified');
2012-07-04 04:40:13 +00:00
pop_lang();
return;
}
2012-03-01 02:19:08 +00:00
// if it's a post figure out who's post it is.
$p = null;
if($params['otype'] === 'item' && $parent_mid) {
$p = q("select * from item where mid = '%s' and uid = %d limit 1",
dbesc($parent_mid),
2013-02-07 05:21:50 +00:00
intval($recip['channel_id'])
2012-03-01 02:19:08 +00:00
);
}
2013-02-07 05:21:50 +00:00
xchan_query($p);
$item_post_type = item_post_type($p[0]);
2014-08-10 00:20:30 +00:00
// $private = $p[0]['item_private'];
$parent_id = $p[0]['id'];
2015-11-13 23:28:34 +00:00
$parent_item = $p[0];
//$possess_desc = str_replace('<!item_type!>',$possess_desc);
2012-03-01 03:23:01 +00:00
// "a post"
$dest_str = sprintf(t('%1$s, %2$s commented on [zrl=%3$s]a %4$s[/zrl]'),
$recip['channel_name'],
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
$itemlink,
$item_post_type);
2012-03-01 03:23:01 +00:00
// "George Bull's post"
2012-03-01 02:19:08 +00:00
if($p)
$dest_str = sprintf(t('%1$s, %2$s commented on [zrl=%3$s]%4$s\'s %5$s[/zrl]'),
$recip['channel_name'],
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
$itemlink,
$p[0]['author']['xchan_name'],
$item_post_type);
2012-03-01 03:23:01 +00:00
// "your post"
if($p[0]['owner']['xchan_name'] == $p[0]['author']['xchan_name'] && intval($p[0]['item_wall']))
$dest_str = sprintf(t('%1$s, %2$s commented on [zrl=%3$s]your %4$s[/zrl]'),
$recip['channel_name'],
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
$itemlink,
$item_post_type);
2012-03-01 02:19:08 +00:00
// Some mail softwares relies on subject field for threading.
// So, we cannot have different subjects for notifications of the same thread.
// Before this we have the name of the replier on the subject rendering
// differents subjects for messages on the same thread.
2012-02-28 01:18:19 +00:00
2016-09-30 02:33:08 +00:00
$subject = sprintf( t('[$Projectname:Notify] Comment to conversation #%1$d by %2$s'), $parent_id, $sender['xchan_name']);
$preamble = sprintf( t('%1$s, %2$s commented on an item/conversation you have been following.'), $recip['channel_name'], $sender['xchan_name']);
$epreamble = $dest_str;
2012-02-18 11:18:20 +00:00
2011-12-26 22:16:25 +00:00
$sitelink = t('Please visit %s to view and/or reply to the conversation.');
$tsitelink = sprintf( $sitelink, $siteurl );
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
}
if ($params['type'] == NOTIFY_LIKE) {
// logger("notification: params = " . print_r($params, true), LOGGER_DEBUG);
$itemlink = $params['link'];
// ignore like/unlike activity on posts - they probably require a separate notification preference
if (array_key_exists('item',$params) && (! activity_match($params['item']['verb'],ACTIVITY_LIKE))) {
logger('notification: not a like activity. Ignoring.');
pop_lang();
return;
}
$parent_mid = $params['parent_mid'];
// Check to see if there was already a notify for this post.
// If so don't create a second notification
$p = null;
$p = q("select id from notify where link = '%s' and uid = %d limit 1",
dbesc($params['link']),
intval($recip['channel_id'])
);
if ($p) {
logger('notification: like already notified');
pop_lang();
return;
}
// if it's a post figure out who's post it is.
$p = null;
if($params['otype'] === 'item' && $parent_mid) {
$p = q("select * from item where mid = '%s' and uid = %d limit 1",
dbesc($parent_mid),
intval($recip['channel_id'])
);
}
xchan_query($p);
$item_post_type = item_post_type($p[0]);
// $private = $p[0]['item_private'];
$parent_id = $p[0]['id'];
$parent_item = $p[0];
// "your post"
if($p[0]['owner']['xchan_name'] == $p[0]['author']['xchan_name'] && intval($p[0]['item_wall']))
$dest_str = sprintf(t('%1$s, %2$s liked [zrl=%3$s]your %4$s[/zrl]'),
$recip['channel_name'],
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
$itemlink,
$item_post_type);
else {
pop_lang();
return;
}
// Some mail softwares relies on subject field for threading.
// So, we cannot have different subjects for notifications of the same thread.
// Before this we have the name of the replier on the subject rendering
// differents subjects for messages on the same thread.
$subject = sprintf( t('[$Projectname:Notify] Like received to conversation #%1$d by %2$s'), $parent_id, $sender['xchan_name']);
$preamble = sprintf( t('%1$s, %2$s liked an item/conversation you created.'), $recip['channel_name'], $sender['xchan_name']);
$epreamble = $dest_str;
$sitelink = t('Please visit %s to view and/or reply to the conversation.');
$tsitelink = sprintf( $sitelink, $siteurl );
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
}
2011-12-26 22:16:25 +00:00
if($params['type'] == NOTIFY_WALL) {
2016-09-30 02:33:08 +00:00
$subject = sprintf( t('[$Projectname:Notify] %s posted to your profile wall') , $sender['xchan_name']);
2012-02-28 01:18:19 +00:00
$preamble = sprintf( t('%1$s, %2$s posted to your profile wall at %3$s') , $recip['channel_name'], $sender['xchan_name'], $sitename);
$epreamble = sprintf( t('%1$s, %2$s posted to [zrl=%3$s]your wall[/zrl]') ,
$recip['channel_name'],
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
$params['link']);
2011-12-26 22:16:25 +00:00
$sitelink = t('Please visit %s to view and/or reply to the conversation.');
$tsitelink = sprintf( $sitelink, $siteurl );
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
$itemlink = $params['link'];
2011-12-08 09:28:27 +00:00
}
if ($params['type'] == NOTIFY_TAGSELF) {
2013-07-31 09:32:41 +00:00
$p = null;
$p = q("select id from notify where link = '%s' and uid = %d limit 1",
dbesc($params['link']),
intval($recip['channel_id'])
);
if ($p) {
2013-07-31 09:32:41 +00:00
logger('enotify: tag: already notified about this post');
pop_lang();
return;
}
2016-09-30 02:33:08 +00:00
$subject = sprintf( t('[$Projectname:Notify] %s tagged you') , $sender['xchan_name']);
$preamble = sprintf( t('%1$s, %2$s tagged you at %3$s') , $recip['channel_name'], $sender['xchan_name'], $sitename);
$epreamble = sprintf( t('%1$s, %2$s [zrl=%3$s]tagged you[/zrl].') ,
$recip['channel_name'],
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
$params['link']);
2012-02-09 22:06:17 +00:00
$sitelink = t('Please visit %s to view and/or reply to the conversation.');
2012-07-20 04:09:40 +00:00
$tsitelink = sprintf( $sitelink, $siteurl );
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
$itemlink = $params['link'];
}
if ($params['type'] == NOTIFY_POKE) {
2016-09-30 02:33:08 +00:00
$subject = sprintf( t('[$Projectname:Notify] %1$s poked you') , $sender['xchan_name']);
$preamble = sprintf( t('%1$s, %2$s poked you at %3$s') , $recip['channel_name'], $sender['xchan_name'], $sitename);
$epreamble = sprintf( t('%1$s, %2$s [zrl=%2$s]poked you[/zrl].') ,
$recip['channel_name'],
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
$params['link']);
2012-07-20 04:09:40 +00:00
$subject = str_replace('poked', t($params['activity']), $subject);
$preamble = str_replace('poked', t($params['activity']), $preamble);
$epreamble = str_replace('poked', t($params['activity']), $epreamble);
$sitelink = t('Please visit %s to view and/or reply to the conversation.');
2012-02-09 22:06:17 +00:00
$tsitelink = sprintf( $sitelink, $siteurl );
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
$itemlink = $params['link'];
}
if ($params['type'] == NOTIFY_TAGSHARE) {
2016-09-30 02:33:08 +00:00
$subject = sprintf( t('[$Projectname:Notify] %s tagged your post') , $sender['xchan_name']);
$preamble = sprintf( t('%1$s, %2$s tagged your post at %3$s') , $recip['channel_name'],$sender['xchan_name'], $sitename);
$epreamble = sprintf( t('%1$s, %2$s tagged [zrl=%3$s]your post[/zrl]') ,
$recip['channel_name'],
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]',
$itemlink);
2012-02-09 22:06:17 +00:00
$sitelink = t('Please visit %s to view and/or reply to the conversation.');
$tsitelink = sprintf( $sitelink, $siteurl );
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
$itemlink = $params['link'];
}
if ($params['type'] == NOTIFY_INTRO) {
2016-09-30 02:33:08 +00:00
$subject = sprintf( t('[$Projectname:Notify] Introduction received'));
2014-03-28 01:03:19 +00:00
$preamble = sprintf( t('%1$s, you\'ve received an new connection request from \'%2$s\' at %3$s'), $recip['channel_name'], $sender['xchan_name'], $sitename);
$epreamble = sprintf( t('%1$s, you\'ve received [zrl=%2$s]a new connection request[/zrl] from %3$s.'),
$recip['channel_name'],
$siteurl . '/connections/ifpending',
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]');
2013-02-07 05:21:50 +00:00
$body = sprintf( t('You may visit their profile at %s'),$sender['xchan_url']);
2011-12-26 23:47:40 +00:00
2014-03-28 01:03:19 +00:00
$sitelink = t('Please visit %s to approve or reject the connection request.');
$tsitelink = sprintf( $sitelink, $siteurl . '/connections/ifpending');
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '/connections/ifpending">' . $sitename . '</a>');
$itemlink = $params['link'];
2011-12-26 23:47:40 +00:00
}
if ($params['type'] == NOTIFY_SUGGEST) {
2016-09-30 02:33:08 +00:00
$subject = sprintf( t('[$Projectname:Notify] Friend suggestion received'));
$preamble = sprintf( t('%1$s, you\'ve received a friend suggestion from \'%2$s\' at %3$s'), $recip['channel_name'], $sender['xchan_name'], $sitename);
$epreamble = sprintf( t('%1$s, you\'ve received [zrl=%2$s]a friend suggestion[/zrl] for %3$s from %4$s.'),
$recip['channel_name'],
$itemlink,
'[zrl=' . $params['item']['url'] . ']' . $params['item']['name'] . '[/zrl]',
'[zrl=' . $sender['xchan_url'] . ']' . $sender['xchan_name'] . '[/zrl]');
2012-01-04 01:29:07 +00:00
$body = t('Name:') . ' ' . $params['item']['name'] . "\n";
$body .= t('Photo:') . ' ' . $params['item']['photo'] . "\n";
$body .= sprintf( t('You may visit their profile at %s'),$params['item']['url']);
$sitelink = t('Please visit %s to approve or reject the suggestion.');
$tsitelink = sprintf( $sitelink, $siteurl );
$hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>');
$itemlink = $params['link'];
}
if ($params['type'] == NOTIFY_CONFIRM) {
// ?
2012-03-25 11:37:09 +00:00
}
if ($params['type'] == NOTIFY_SYSTEM) {
// ?
2011-12-26 23:47:40 +00:00
}
2012-03-25 12:06:11 +00:00
$h = array(
'params' => $params,
2012-03-25 12:06:11 +00:00
'subject' => $subject,
'preamble' => $preamble,
'epreamble' => $epreamble,
'body' => $body,
2012-03-25 12:06:11 +00:00
'sitelink' => $sitelink,
2015-10-02 02:54:28 +00:00
'sitename' => $sitename,
2012-03-25 12:06:11 +00:00
'tsitelink' => $tsitelink,
'hsitelink' => $hsitelink,
'itemlink' => $itemlink,
'sender' => $sender,
'recipient' => $recip
2012-03-25 12:06:11 +00:00
);
call_hooks('enotify', $h);
2012-03-25 12:06:11 +00:00
$subject = $h['subject'];
$preamble = $h['preamble'];
$epreamble = $h['epreamble'];
$body = $h['body'];
$sitelink = $h['sitelink'];
$tsitelink = $h['tsitelink'];
$hsitelink = $h['hsitelink'];
$itemlink = $h['itemlink'];
2011-12-26 23:47:40 +00:00
require_once('include/html2bbcode.php');
2012-02-18 10:57:42 +00:00
do {
$dups = false;
$hash = random_string();
2016-10-04 02:47:36 +00:00
$r = q("SELECT id FROM notify WHERE hash = '%s' LIMIT 1",
dbesc($hash));
if ($r)
$dups = true;
} while ($dups === true);
2012-02-27 07:54:04 +00:00
$datarray = array();
$datarray['hash'] = $hash;
2015-01-27 04:47:53 +00:00
$datarray['sender_hash'] = $sender['xchan_hash'];
$datarray['xname'] = $sender['xchan_name'];
$datarray['url'] = $sender['xchan_url'];
$datarray['photo'] = $sender['xchan_photo_s'];
$datarray['created'] = datetime_convert();
$datarray['aid'] = $recip['channel_account_id'];
$datarray['uid'] = $recip['channel_id'];
$datarray['link'] = $itemlink;
$datarray['parent'] = $parent_mid;
2015-11-13 23:28:34 +00:00
$datarray['parent_item'] = $parent_item;
$datarray['ntype'] = $params['type'];
$datarray['verb'] = $params['verb'];
$datarray['otype'] = $params['otype'];
$datarray['abort'] = false;
2014-06-10 02:07:15 +00:00
$datarray['item'] = $params['item'];
2012-02-27 07:54:04 +00:00
call_hooks('enotify_store', $datarray);
if ($datarray['abort']) {
pop_lang();
return;
}
2012-02-18 10:57:42 +00:00
// create notification entry in DB
$seen = 0;
// Mark some notifications as seen right away
// Note! The notification have to be created, because they are used to send emails
// So easiest solution to hide them from Notices is to mark them as seen right away.
// Another option would be to not add them to the DB, and change how emails are handled
// (probably would be better that way)
$always_show_in_notices = get_pconfig($recip['channel_id'],'system','always_show_in_notices');
if (!$always_show_in_notices) {
if (($params['type'] == NOTIFY_WALL) || ($params['type'] == NOTIFY_MAIL) || ($params['type'] == NOTIFY_INTRO)) {
$seen = 1;
}
}
2012-02-18 10:57:42 +00:00
$r = q("insert into notify (hash,xname,url,photo,created,msg,aid,uid,link,parent,seen,ntype,verb,otype)
values('%s','%s','%s','%s','%s','%s',%d,%d,'%s','%s',%d,%d,'%s','%s')",
2012-02-27 07:54:04 +00:00
dbesc($datarray['hash']),
dbesc($datarray['xname']),
2012-02-27 07:54:04 +00:00
dbesc($datarray['url']),
dbesc($datarray['photo']),
dbesc($datarray['created']),
dbesc(''), // will fill this in below after the record is created
intval($datarray['aid']),
2012-02-27 07:54:04 +00:00
intval($datarray['uid']),
dbesc($datarray['link']),
dbesc($datarray['parent']),
intval($seen),
intval($datarray['ntype']),
2012-02-27 07:54:04 +00:00
dbesc($datarray['verb']),
dbesc($datarray['otype'])
2012-02-18 10:57:42 +00:00
);
2011-12-08 09:28:27 +00:00
$r = q("select id from notify where hash = '%s' and uid = %d limit 1",
dbesc($hash),
2013-01-06 07:24:15 +00:00
intval($recip['channel_id'])
);
if ($r) {
$notify_id = $r[0]['id'];
} else {
2013-01-06 07:24:15 +00:00
logger('notification not found.');
2012-03-26 08:43:26 +00:00
pop_lang();
return;
2012-03-26 08:43:26 +00:00
}
2016-03-31 05:13:24 +00:00
$itemlink = z_root() . '/notify/view/' . $notify_id;
2013-01-08 10:49:08 +00:00
$msg = str_replace('$itemlink',$itemlink,$epreamble);
2014-02-26 04:36:56 +00:00
// wretched hack, but we don't want to duplicate all the preamble variations and we also don't want to screw up a translation
2016-05-24 08:25:13 +00:00
if ((\App::$language === 'en' || (! \App::$language)) && strpos($msg,', '))
2014-02-26 04:36:56 +00:00
$msg = substr($msg,strpos($msg,', ')+1);
PostgreSQL support initial commit There were 11 main types of changes: - UPDATE's and DELETE's sometimes had LIMIT 1 at the end of them. This is not only non-compliant but it would certainly not do what whoever wrote it thought it would. It is likely this mistake was just copied from Friendica. All of these instances, the LIMIT 1 was simply removed. - Bitwise operations (and even some non-zero int checks) erroneously rely on MySQL implicit integer-boolean conversion in the WHERE clauses. This is non-compliant (and bad programming practice to boot). Proper explicit boolean conversions were added. New queries should use proper conventions. - MySQL has a different operator for bitwise XOR than postgres. Rather than add yet another dba_ func, I converted them to "& ~" ("AND NOT") when turning off, and "|" ("OR") when turning on. There were no true toggles (XOR). New queries should refrain from using XOR when not necessary. - There are several fields which the schema has marked as NOT NULL, but the inserts don't specify them. The reason this works is because mysql totally ignores the constraint and adds an empty text default automatically. Again, non-compliant, obviously. In these cases a default of empty text was added. - Several statements rely on a non-standard MySQL feature (http://dev.mysql.com/doc/refman/5.5/en/group-by-handling.html). These queries can all be rewritten to be standards compliant. Interestingly enough, the newly rewritten standards compliant queries run a zillion times faster, even on MySQL. - A couple of function/operator name translations were needed (RAND/RANDOM, GROUP_CONCAT/STRING_AGG, UTC_NOW, REGEXP/~, ^/#) -- assist functions added in the dba_ - INTERVALs: postgres requires quotes around the value, mysql requires that there are not quotes around the value -- assist functions added in the dba_ - NULL_DATE's -- Postgres does not allow the invalid date '0000-00-00 00:00:00' (there is no such thing as year 0 or month 0 or day 0). We use '0001-01-01 00:00:00' for postgres. Conversions are handled in Zot/item packets automagically by quoting all dates with dbescdate(). - char(##) specifications in the schema creates fields with blank spaces that aren't trimmed in the code. MySQL apparently treats char(##) as varchar(##), again, non-compliant. Since postgres works better with text fields anyway, this ball of bugs was simply side-stepped by using 'text' datatype for all text fields in the postgres schema. varchar was used in a couple of places where it actually seemed appropriate (size constraint), but without rigorously vetting that all of the PHP code actually validates data, new bugs might come out from under the rug. - postgres doesn't store nul bytes and a few other non-printables in text fields, even when quoted. bytea fields were used when storing binary data (photo.data, attach.data). A new dbescbin() function was added to handle this transparently. - postgres does not support LIMIT #,# syntax. All databases support LIMIT # OFFSET # syntax. Statements were updated to be standard. These changes require corresponding changes in the coding standards. Please review those before adding any code going forward. Still on my TODO list: - remove quotes from non-reserved identifiers and make reserved identifiers use dba func for quoting - Rewrite search queries for better results (both MySQL and Postgres)
2014-11-13 20:21:58 +00:00
$r = q("update notify set msg = '%s' where id = %d and uid = %d",
dbesc($msg),
intval($notify_id),
2013-01-08 10:49:08 +00:00
intval($datarray['uid'])
);
2011-12-24 07:07:05 +00:00
// send email notification if notification preferences permit
require_once('bbcode.php');
if ((intval($recip['channel_notifyflags']) & intval($params['type'])) || $params['type'] == NOTIFY_SYSTEM) {
2011-12-24 07:07:05 +00:00
2011-12-27 22:26:44 +00:00
logger('notification: sending notification email');
2011-12-24 07:07:05 +00:00
2015-01-15 22:40:00 +00:00
$hn = get_pconfig($recip['channel_id'],'system','email_notify_host');
2016-05-24 08:25:13 +00:00
if($hn && (! stristr(\App::get_hostname(),$hn))) {
2015-01-15 22:40:00 +00:00
// this isn't the email notification host
pop_lang();
return;
}
$textversion = strip_tags(html_entity_decode(bbcode(stripslashes(str_replace(array("\\r", "\\n"), array( "", "\n"), $body))),ENT_QUOTES,'UTF-8'));
2013-06-17 23:21:03 +00:00
$htmlversion = bbcode(stripslashes(str_replace(array("\\r","\\n"), array("","<br />\n"),$body)));
2013-06-17 23:21:03 +00:00
// use $_SESSION['zid_override'] to force zid() to use
// the recipient address instead of the current observer
$_SESSION['zid_override'] = channel_reddress($recip);
$_SESSION['zrl_override'] = z_root() . '/channel/' . $recip['channel_address'];
2013-06-17 23:21:03 +00:00
$textversion = zidify_links($textversion);
$htmlversion = zidify_links($htmlversion);
// unset when done to revert to normal behaviour
unset($_SESSION['zid_override']);
unset($_SESSION['zrl_override']);
2011-12-24 07:07:05 +00:00
2012-02-27 07:54:04 +00:00
$datarray = array();
$datarray['banner'] = $banner;
$datarray['product'] = $product;
$datarray['preamble'] = $preamble;
$datarray['sitename'] = $sitename;
$datarray['siteurl'] = $siteurl;
$datarray['type'] = $params['type'];
$datarray['parent'] = $params['parent_mid'];
$datarray['source_name'] = $sender['xchan_name'];
$datarray['source_link'] = $sender['xchan_url'];
$datarray['source_photo'] = $sender['xchan_photo_s'];
$datarray['uid'] = $recip['channel_id'];
$datarray['username'] = $recip['channel_name'];
$datarray['hsitelink'] = $hsitelink;
$datarray['tsitelink'] = $tsitelink;
$datarray['hitemlink'] = '<a href="' . $itemlink . '">' . $itemlink . '</a>';
$datarray['titemlink'] = $itemlink;
$datarray['thanks'] = $thanks;
$datarray['site_admin'] = $site_admin;
$datarray['title'] = stripslashes($title);
$datarray['htmlversion'] = $htmlversion;
$datarray['textversion'] = $textversion;
$datarray['subject'] = $subject;
$datarray['headers'] = $additional_mail_header;
$datarray['email_secure'] = false;
2012-02-27 07:54:04 +00:00
call_hooks('enotify_mail', $datarray);
// Default to private - don't disclose message contents over insecure channels (such as email)
// Might be interesting to use GPG,PGP,S/MIME encryption instead
// but we'll save that for a clever plugin developer to implement
$private_activity = false;
if (! $datarray['email_secure']) {
switch ($params['type']) {
case NOTIFY_WALL:
case NOTIFY_TAGSELF:
case NOTIFY_POKE:
case NOTIFY_COMMENT:
if (! $private)
break;
$private_activity = true;
case NOTIFY_MAIL:
$datarray['textversion'] = $datarray['htmlversion'] = $datarray['title'] = '';
2016-09-30 02:33:08 +00:00
$datarray['subject'] = preg_replace('/' . preg_quote(t('[$Projectname:Notify]')) . '/','$0*',$datarray['subject']);
break;
default:
break;
}
}
if ($private_activity
&& intval(get_pconfig($datarray['uid'], 'system', 'ignore_private_notifications'))) {
pop_lang();
return;
}
2011-12-24 07:07:05 +00:00
// load the template for private message notifications
$tpl = get_markup_template('email_notify_html.tpl');
$email_html_body = replace_macros($tpl,array(
2012-02-27 07:54:04 +00:00
'$banner' => $datarray['banner'],
2016-05-24 08:25:13 +00:00
'$notify_icon' => \Zotlabs\Lib\System::get_notify_icon(),
2012-02-27 07:54:04 +00:00
'$product' => $datarray['product'],
'$preamble' => $datarray['preamble'],
'$sitename' => $datarray['sitename'],
'$siteurl' => $datarray['siteurl'],
'$source_name' => $datarray['source_name'],
'$source_link' => $datarray['source_link'],
'$source_photo' => $datarray['source_photo'],
'$username' => $datarray['to_name'],
'$hsitelink' => $datarray['hsitelink'],
'$hitemlink' => $datarray['hitemlink'],
'$thanks' => $datarray['thanks'],
'$site_admin' => $datarray['site_admin'],
'$title' => $datarray['title'],
'$htmlversion' => $datarray['htmlversion'],
2011-12-24 07:07:05 +00:00
));
2011-12-24 07:07:05 +00:00
// load the template for private message notifications
$tpl = get_markup_template('email_notify_text.tpl');
$email_text_body = replace_macros($tpl, array(
2012-02-27 07:54:04 +00:00
'$banner' => $datarray['banner'],
'$product' => $datarray['product'],
'$preamble' => $datarray['preamble'],
'$sitename' => $datarray['sitename'],
'$siteurl' => $datarray['siteurl'],
'$source_name' => $datarray['source_name'],
'$source_link' => $datarray['source_link'],
'$source_photo' => $datarray['source_photo'],
'$username' => $datarray['to_name'],
'$tsitelink' => $datarray['tsitelink'],
'$titemlink' => $datarray['titemlink'],
'$thanks' => $datarray['thanks'],
'$site_admin' => $datarray['site_admin'],
'$title' => $datarray['title'],
'$textversion' => $datarray['textversion'],
2011-12-24 07:07:05 +00:00
));
2011-12-27 22:26:44 +00:00
// logger('text: ' . $email_text_body);
2011-12-24 07:07:05 +00:00
// use the EmailNotification library to send the message
2016-05-24 08:25:13 +00:00
self::send(array(
'fromName' => $sender_name,
'fromEmail' => $sender_email,
'replyTo' => $reply_email,
'toEmail' => $recip['account_email'],
'messageSubject' => $datarray['subject'],
'htmlVersion' => $email_html_body,
'textVersion' => $email_text_body,
2012-02-27 07:54:04 +00:00
'additionalMailHeader' => $datarray['headers'],
));
2011-12-24 07:07:05 +00:00
}
2012-02-18 10:57:42 +00:00
pop_lang();
2011-12-24 07:07:05 +00:00
}
2011-12-08 09:28:27 +00:00
/**
* @brief Send a multipart/alternative message with Text and HTML versions.
2011-12-08 09:28:27 +00:00
*
* @param array $params an assoziative array with:
* * \e string \b fromName name of the sender
* * \e string \b fromEmail email of the sender
* * \e string \b replyTo replyTo address to direct responses
* * \e string \b toEmail destination email address
* * \e string \b messageSubject subject of the message
* * \e string \b htmlVersion html version of the message
* * \e string \b textVersion text only version of the message
* * \e string \b additionalMailHeader additions to the smtp mail header
2011-12-08 09:28:27 +00:00
*/
static public function send($params) {
2016-09-30 05:28:23 +00:00
$params['sent'] = false;
$params['result'] = false;
2016-10-01 22:15:14 +00:00
call_hooks('email_send', $params);
2016-09-30 05:28:23 +00:00
if($params['sent']) {
logger("notification: enotify::send (addon) returns " . (($params['result']) ? 'success' : 'failure'), LOGGER_DEBUG);
2016-10-03 22:58:54 +00:00
return $params['result'];
2016-09-30 05:28:23 +00:00
}
$fromName = email_header_encode(html_entity_decode($params['fromName'],ENT_QUOTES,'UTF-8'),'UTF-8');
$messageSubject = email_header_encode(html_entity_decode($params['messageSubject'],ENT_QUOTES,'UTF-8'),'UTF-8');
2011-12-08 09:28:27 +00:00
// generate a mime boundary
$mimeBoundary = rand(0, 9) . "-"
.rand(10000000000, 9999999999) . "-"
.rand(10000000000, 9999999999) . "=:"
.rand(10000, 99999);
2011-12-08 09:28:27 +00:00
// generate a multipart/alternative message header
$messageHeader =
$params['additionalMailHeader'] .
"From: $fromName <{$params['fromEmail']}>\n" .
2013-01-03 21:50:23 +00:00
"Reply-To: $fromName <{$params['replyTo']}>\n" .
2011-12-08 09:28:27 +00:00
"MIME-Version: 1.0\n" .
"Content-Type: multipart/alternative; boundary=\"{$mimeBoundary}\"";
// assemble the final multipart message body with the text and html types included
$textBody = chunk_split(base64_encode($params['textVersion']));
$htmlBody = chunk_split(base64_encode($params['htmlVersion']));
2011-12-08 09:28:27 +00:00
$multipartMessageBody =
"--" . $mimeBoundary . "\n" . // plain text section
"Content-Type: text/plain; charset=UTF-8\n" .
"Content-Transfer-Encoding: base64\n\n" .
$textBody . "\n" .
"--" . $mimeBoundary . "\n" . // text/html section
"Content-Type: text/html; charset=UTF-8\n" .
"Content-Transfer-Encoding: base64\n\n" .
$htmlBody . "\n" .
"--" . $mimeBoundary . "--\n"; // message ending
// send the message
$res = mail(
$params['toEmail'], // send to address
2013-01-03 21:50:23 +00:00
$messageSubject, // subject
$multipartMessageBody, // message body
2011-12-08 09:28:27 +00:00
$messageHeader // message headers
);
logger("notification: enotify::send returns " . (($res) ? 'success' : 'failure'), LOGGER_DEBUG);
2016-09-30 05:28:23 +00:00
return $res;
2011-12-08 09:28:27 +00:00
}
2016-05-24 08:25:13 +00:00
2016-05-26 12:37:30 +00:00
static public function format($item) {
2016-05-24 08:25:13 +00:00
$ret = '';
require_once('include/conversation.php');
// Call localize_item to get a one line status for activities.
2016-05-24 08:25:13 +00:00
// This should set $item['localized'] to indicate we have a brief summary.
localize_item($item);
if($item['localize']) {
2016-05-24 08:25:13 +00:00
$itemem_text = $item['localize'];
}
else {
$itemem_text = (($item['item_thread_top'])
? t('created a new post')
: sprintf( t('commented on %s\'s post'), $item['owner']['xchan_name']));
}
// convert this logic into a json array just like the system notifications
return array(
'notify_link' => $item['llink'],
2016-05-24 08:25:13 +00:00
'name' => $item['author']['xchan_name'],
'url' => $item['author']['xchan_url'],
'photo' => $item['author']['xchan_photo_s'],
'when' => relative_date($item['created']),
'class' => (intval($item['item_unseen']) ? 'notify-unseen' : 'notify-seen'),
'message' => strip_tags(bbcode($itemem_text))
);
}
2011-12-08 09:28:27 +00:00
}