pmPrefs;
}
/**
* Constructor
*
* @param array $prefs - pref settings for PM plugin
* @return none
*/
public function __construct($prefs=null)
{
$this->e107 = e107::getInstance();
$this->pmPrefs = e107::pref('pm');
}
/**
* Mark a PM as read
* If flag set, send read receipt to sender
*
* @param int $pm_id - ID of PM
* @param array $pm_info - PM details
*
* @return none
*
* @todo - 'read_delete' pref doesn't exist - remove code? Or support?
*/
function pm_mark_read($pm_id, $pm_info)
{
$now = time();
if($this->pmPrefs['read_delete'])
{
$this->del($pm_id);
}
else
{
e107::getDb()->gen("UPDATE `#private_msg` SET `pm_read` = {$now} WHERE `pm_id`=".intval($pm_id)); // TODO does this work properly?
if(strpos($pm_info['pm_option'], '+rr') !== FALSE)
{
$this->pm_send_receipt($pm_info);
}
e107::getEvent()->trigger('user_pm_read', $pm_id);
}
}
/*
* Get an existing PM
*
* @param int $pmid - ID of PM in DB
*
* @return boolean|array - FALSE on error, array of PM info on success
*/
function pm_get($pmid)
{
$qry = "
SELECT pm.*, ut.user_image AS sent_image, ut.user_name AS sent_name, uf.user_image AS from_image, uf.user_name AS from_name, uf.user_email as from_email, ut.user_email as to_email FROM #private_msg AS pm
LEFT JOIN #user AS ut ON ut.user_id = pm.pm_to
LEFT JOIN #user AS uf ON uf.user_id = pm.pm_from
WHERE pm.pm_id='".intval($pmid)."'
";
if (e107::getDb()->gen($qry))
{
$row = e107::getDb()->fetch();
return $row;
}
return FALSE;
}
/*
* Send a PM
*
* @param array $vars - PM information
* ['receipt'] - set TRUE if read receipt required
* ['uploaded'] - list of attachments (if any) - each is an array('size', 'name')
* ['to_userclass'] - set TRUE if sending to a user class
* ['to_array'] = array of recipients
* ['pm_userclass'] = target user class
* ['to_info'] = recipients array of array('user_id', 'user_class')
*
* May also be an array as received from the generic table, if sending via a cron job
* identified by the existence of $vars['pm_from']
*
* @return string - text detailing result
*/
function add($vars)
{
$tp = e107::getParser();
$sql = e107::getDb();
$pmsize = 0;
$attachlist = '';
$pm_options = '';
$ret = '';
$addOutbox = TRUE;
$timestamp = time();
$maxSendNow = varset($this->pmPrefs['pm_max_send'],100); // Maximum number of PMs to send without queueing them
if (isset($vars['pm_from']))
{ // Doing bulk send off cron task
$info = array();
foreach ($vars as $k => $v)
{
if (strpos($k, 'pm_') === 0)
{
$info[$k] = $v;
unset($vars[$k]);
}
}
$addOutbox = FALSE; // Don't add to outbox - was done earlier
}
else
{ // Send triggered by user - may be immediate or bulk dependent on number of recipients
$vars['options'] = '';
if(isset($vars['receipt']) && $vars['receipt']) {$pm_options .= '+rr+'; }
if(isset($vars['uploaded']))
{
foreach($vars['uploaded'] as $u)
{
if (!isset($u['error']) || !$u['error'])
{
$pmsize += $u['size'];
$a_list[] = $u['name'];
}
}
$attachlist = implode(chr(0), $a_list);
}
$pmsize += strlen($vars['pm_message']);
$pm_subject = trim($tp->toDB($vars['pm_subject']));
$pm_message = trim($tp->toDB($vars['pm_message']));
if (!$pm_subject && !$pm_message && !$attachlist)
{ // Error - no subject, no message body and no uploaded files
return LAN_PM_65;
}
// Most of the pm info is fixed - just need to set the 'to' user on each send
$info = array(
'pm_from' => $vars['from_id'],
'pm_sent' => $timestamp, /* Date sent */
'pm_read' => 0, /* Date read */
'pm_subject' => $pm_subject,
'pm_text' => $pm_message,
'pm_sent_del' => 0, /* Set when can delete */
'pm_read_del' => 0, /* set when can delete */
'pm_attachments' => $attachlist,
'pm_option' => $pm_options, /* Options associated with PM - '+rr' for read receipt */
'pm_size' => $pmsize
);
// print_a($info);
// print_a($vars);
}
if(!empty($vars['pm_userclass']) || isset($vars['to_array']))
{
if(!empty($vars['pm_userclass']))
{
$toclass = e107::getUserClass()->uc_get_classname($vars['pm_userclass']);
$tolist = $this->get_users_inclass($vars['pm_userclass']);
$ret .= LAN_PM_38.": {$toclass}
";
$class = TRUE;
$info['pm_sent_del'] = 1; // keep the outbox clean and limited to 1 entry when sending to an entire class.
}
else
{
$tolist = $vars['to_array'];
$class = FALSE;
}
// Sending multiple PMs here. If more than some number ($maxSendNow), need to split into blocks.
if (count($tolist) > $maxSendNow)
{
$totalSend = count($tolist);
$targets = array_chunk($tolist, $maxSendNow); // Split into a number of lists, each with the maximum number of elements (apart from the last block, of course)
unset($tolist);
$array = new ArrayData;
$pmInfo = $info;
$genInfo = array(
'gen_type' => 'pm_bulk',
'gen_datestamp' => time(),
'gen_user_id' => USERID,
'gen_ip' => ''
);
for ($i = 0; $i < count($targets) - 1; $i++)
{ // Save the list in the 'generic' table
$pmInfo['to_array'] = $targets[$i]; // Should be in exactly the right format
$genInfo['gen_intdata'] = count($targets[$i]);
$genInfo['gen_chardata'] = $array->WriteArray($pmInfo,TRUE);
$sql->insert('generic', array('data' => $genInfo, '_FIELD_TYPES' => array('gen_chardata' => 'string'))); // Don't want any of the clever sanitising now
}
$toclass .= ' ['.$totalSend.']';
$tolist = $targets[count($targets) - 1]; // Send the residue now (means user probably isn't kept hanging around too long if sending lots)
unset($targets);
}
foreach($tolist as $u)
{
set_time_limit(30);
$info['pm_to'] = intval($u['user_id']); // Sending to a single user now
if($pmid = $sql->insert('private_msg', $info))
{
$info['pm_id'] = $pmid;
e107::getEvent()->trigger('user_pm_sent', $info);
unset($info['pm_id']); // prevent it from being used on the next record.
if($class == FALSE)
{
$toclass .= $u['user_name'].', ';
}
if(check_class($this->pmPrefs['notify_class'], null, $u['user_id']))
{
$vars['to_info'] = $u;
$vars['pm_sent'] = $timestamp;
$this->pm_send_notify($u['user_id'], $vars, $pmid, count($a_list));
}
}
else
{
$ret .= LAN_PM_39.": {$u['user_name']}
";
e107::getMessage()->addDebug($sql->getLastErrorText());
}
}
if ($addOutbox)
{
$info['pm_to'] = $toclass; // Class info to put into outbox
$info['pm_sent_del'] = 0;
$info['pm_read_del'] = 1;
if(!$pmid = $sql->insert('private_msg', $info))
{
$ret .= LAN_PM_41.'
';
}
}
}
else
{ // Sending to a single person
$info['pm_to'] = intval($vars['to_info']['user_id']); // Sending to a single user now
if($pmid = $sql->insert('private_msg', $info))
{
$info['pm_id'] = $pmid;
$info['pm_sent'] = $timestamp;
e107::getEvent()->trigger('user_pm_sent', $info);
if(check_class($this->pmPrefs['notify_class'], null, $vars['to_info']['user_id']))
{
set_time_limit(20);
$vars['pm_sent'] = $timestamp;
$this->pm_send_notify($vars['to_info']['user_id'], $vars, $pmid, count($a_list));
}
$ret .= LAN_PM_40.": {$vars['to_info']['user_name']}
";
}
}
return $ret;
}
/**
* Delete a PM from a user's inbox/outbox.
* PM is only actually deleted from DB once both sender and recipient have marked it as deleted
* When physically deleted, any attachments are deleted as well
*
* @param integer $pmid - ID of the PM
* @param boolean $force - set to TRUE to force deletion of unread PMs
* @return boolean|string - FALSE if PM not found, or other DB error. String if successful
*/
function del($pmid, $force = FALSE)
{
$sql = e107::getDb();
$pmid = (int)$pmid;
$ret = '';
$newvals = '';
if($sql->select('private_msg', '*', 'pm_id = '.$pmid.' AND (pm_from = '.USERID.' OR pm_to = '.USERID.')'))
{
$row = $sql->fetch();
// if user is the receiver of the PM
if (!$force && ($row['pm_to'] == USERID))
{
$newvals = 'pm_read_del = 1';
$ret .= LAN_PM_42.'
';
if($row['pm_sent_del'] == 1) { $force = TRUE; } // sender has deleted as well, set force to true so the DB record can be deleted
}
// if user is the sender of the PM
if (!$force && ($row['pm_from'] == USERID))
{
if($newvals != '') { $force = TRUE; }
$newvals = 'pm_sent_del = 1';
$ret .= LAN_PM_43."
";
if($row['pm_read_del'] == 1) { $force = TRUE; } // receiver has deleted as well, set force to true so the DB record can be deleted
}
if($force == TRUE)
{
// Delete any attachments and remove PM from db
$attachments = explode(chr(0), $row['pm_attachments']);
$aCount = array(0,0);
foreach($attachments as $a)
{
$a = trim($a);
if ($a)
{
$filename = e_PLUGIN.'pm/attachments/'.$a;
if (unlink($filename)) $aCount[0]++; else $aCount[1]++;
}
}
if ($aCount[0] || $aCount[1])
{
// $ret .= str_replace(array('--GOOD--', '--FAIL--'), $aCount, LAN_PM_71).'
';
$ret .= e107::getParser()->lanVars(LAN_PM_71, $aCount);
}
$sql->delete('private_msg', 'pm_id = '.$pmid);
}
else
{
$sql->update('private_msg', $newvals.' WHERE pm_id = '.$pmid);
}
return $ret;
}
return FALSE;
}
/**
* Convinient url assembling shortcut
*//*
public function url($action, $params = array(), $options = array())
{
if(strpos($action, '/') === false) $action = 'view/'.$action;
e107::getUrl()->create('pm/'.$action, $params, $options);
}*/
/**
* Send an email to notify of a PM
*
* @param int $uid - not used
* @param array $pmInfo - PM details
* @param int $pmid - ID of PM in database
* @param int $attach_count - number of attachments
*
* @return none
*/
function pm_send_notify($uid, $pmInfo, $pmid, $attach_count = 0)
{
// require_once(e_HANDLER.'mail.php');
$tpl_file = THEME.'pm_template.php';
$PM_NOTIFY = null; // loaded in template below.
include(is_readable($tpl_file) ? $tpl_file : e_PLUGIN.'pm/pm_template.php');
$template = $PM_NOTIFY;
if(empty($template)) // BC Fallback.
{
$template =
"
".LAN_PM_102." | {USERNAME} |
".LAN_PM_103." | {PM_SUBJECT} |
".LAN_PM_108." | {PM_DATE} |
".LAN_PM_104." | {PM_ATTACHMENTS} |