2015-04-13 18:11:52 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
require_once __DIR__ . "/lib/class.EmailTracker.php";
|
|
|
|
|
|
|
|
class Pluginemailtracking extends Plugin {
|
|
|
|
|
|
|
|
private $emailTracker;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructor
|
|
|
|
*/
|
|
|
|
function Pluginemailtracking(){}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Called to initialize the plugin and register for hooks.
|
|
|
|
*/
|
|
|
|
function init(){
|
|
|
|
$this->registerHook('server.core.settings.init.before');
|
|
|
|
$this->registerHook('server.core.operations.submitmessage');
|
|
|
|
$this->store = $GLOBALS['mapisession']->getDefaultMessageStore();
|
|
|
|
$this->emailTracker = new EmailTracker();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Process the incoming events that where fired by the client.
|
|
|
|
*
|
|
|
|
* @param String $eventID Identifier of the hook
|
|
|
|
* @param Array $data Reference to the data of the triggered hook
|
|
|
|
*/
|
|
|
|
function execute($eventID, &$data) {
|
|
|
|
switch($eventID){
|
|
|
|
// Register plugin
|
|
|
|
case 'server.core.settings.init.before':
|
|
|
|
$this->onBeforeSettingsInit($data);
|
|
|
|
break;
|
|
|
|
// Add tracking stuff before submitting the message
|
|
|
|
case 'server.core.operations.submitmessage':
|
|
|
|
$this->onBeforeSubmit($data);
|
|
|
|
break;
|
|
|
|
// Add tracking property, which is send to the client
|
|
|
|
case 'server.module.itemmodule.open.after':
|
|
|
|
$this->onAfterOpen($data);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This function handles the 'beforesend' hook which is triggered before sending the email.
|
|
|
|
* If the PR_MESSAGE_CLASS is set to a signed email (IPM.Note.SMIME.Multipartsigned), this function
|
|
|
|
* will convert the mapi message to RFC822, sign the eml and attach the signed email to the mapi message.
|
|
|
|
*
|
|
|
|
* @param {mixed} $data from php hook
|
|
|
|
*/
|
|
|
|
function onBeforeSubmit(&$data)
|
|
|
|
{
|
|
|
|
$message = $data['message'];
|
|
|
|
|
|
|
|
// Retrieve message class
|
|
|
|
$props = mapi_getprops($message, array(PR_MESSAGE_CLASS, PR_SUBJECT, PR_SENDER_EMAIL_ADDRESS));
|
|
|
|
if (mapi_is_error(mapi_last_hresult())) {
|
|
|
|
error_log("error loading props!");
|
|
|
|
}
|
|
|
|
$recipients = mapi_message_getrecipienttable($message);
|
|
|
|
$messageClass = $props[PR_MESSAGE_CLASS];
|
|
|
|
|
|
|
|
if(isset($messageClass) && (stripos($messageClass, 'IPM.Note.Tracking') !== false)) {
|
|
|
|
// reset messageClass
|
|
|
|
mapi_setprops($message, array(PR_MESSAGE_CLASS => 'IPM.Note'));
|
|
|
|
|
|
|
|
error_log("Number of recipients: " . mapi_table_getrowcount($recipients));
|
|
|
|
|
|
|
|
// get all recipient email addresses
|
|
|
|
$filters=array(PR_ADDRTYPE, PR_EMAIL_ADDRESS, PR_SMTP_ADDRESS);
|
|
|
|
$rows = mapi_table_queryrows($recipients,$filters,0,1); // get only the first recipient
|
|
|
|
|
|
|
|
$recipient = "";
|
|
|
|
foreach($rows as $row) {
|
|
|
|
$recipient = $row[PR_ADDRTYPE] === "SMTP" ? $row[PR_SMTP_ADDRESS] : $row[PR_EMAIL_ADDRESS];
|
|
|
|
}
|
|
|
|
|
|
|
|
// get a new tracking id:
|
|
|
|
$trackingId = $this->emailTracker->getNewTrackingCode(md5($props[PR_SUBJECT] . time()), $recipient, $props[PR_SENDER_EMAIL_ADDRESS], $props[PR_SUBJECT]);
|
|
|
|
|
|
|
|
$trackingURL_Image = PLUGIN_EMAILTRACKING_PUBLIC_WEBAPP_URL . "/plugins/emailtracking/php/track.php?img=" . $trackingId;
|
|
|
|
$trackingURL_Sound = PLUGIN_EMAILTRACKING_PUBLIC_WEBAPP_URL . "/plugins/emailtracking/php/track.php?bgsound=" . $trackingId;
|
|
|
|
|
|
|
|
// add the tracking html tags to the body
|
|
|
|
$trackingHTML = '<img send="true" alt="" lowsrc="" src="' . $trackingURL_Image . '" border="0" height="1" width="3" />';
|
2015-04-30 22:11:52 +02:00
|
|
|
$trackingHTML .= '<bgsound volume="-10000" alt="" lowsrc="" src="' . $trackingURL_Sound . '">';
|
2015-04-13 18:11:52 +02:00
|
|
|
|
|
|
|
// stream the body and add the tracking changes!
|
|
|
|
$messageStream = mapi_openproperty($message, PR_HTML, IID_IStream, 0, 0);
|
|
|
|
$stat = mapi_stream_stat($messageStream);
|
|
|
|
|
|
|
|
// create temporary files
|
|
|
|
$tmpEmail = tempnam(sys_get_temp_dir(),true);
|
|
|
|
|
|
|
|
$fhandle = fopen($tmpEmail,'w');
|
|
|
|
$buffer = null;
|
|
|
|
for($i = 0; $i < $stat["cb"]; $i += BLOCK_SIZE) {
|
|
|
|
// Write stream
|
|
|
|
$buffer = mapi_stream_read($messageStream, BLOCK_SIZE);
|
|
|
|
fwrite($fhandle,$buffer,strlen($buffer));
|
|
|
|
}
|
|
|
|
|
|
|
|
// append tracking stuff
|
|
|
|
fwrite($fhandle, $trackingHTML, strlen($trackingHTML));
|
|
|
|
fclose($fhandle);
|
|
|
|
|
|
|
|
// Save the signed message as attachment of the send email
|
|
|
|
$outStream = mapi_openproperty($message, PR_HTML, IID_IStream, 0, MAPI_CREATE | MAPI_MODIFY);
|
|
|
|
$handle = fopen($tmpEmail, 'r');
|
|
|
|
while (!feof($handle)) {
|
|
|
|
$contents = fread($handle, BLOCK_SIZE);
|
|
|
|
mapi_stream_write($outStream, $contents);
|
|
|
|
}
|
|
|
|
fclose($handle);
|
|
|
|
|
|
|
|
// Save stream
|
|
|
|
mapi_stream_commit($outStream);
|
|
|
|
|
|
|
|
// remove tmp files
|
|
|
|
unlink($tmpEmail);
|
|
|
|
|
|
|
|
// Save changes
|
|
|
|
mapi_savechanges($message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Called when the core Settings class is initialized and ready to accept sysadmin default
|
|
|
|
* settings. Registers the sysadmin defaults for the example plugin.
|
|
|
|
*
|
|
|
|
* @param {mixed} $data Reference to the data of the triggered hook
|
|
|
|
*/
|
|
|
|
function onBeforeSettingsInit(&$data){
|
|
|
|
$data['settingsObj']->addSysAdminDefaults(Array(
|
|
|
|
'zarafa' => Array(
|
|
|
|
'v1' => Array(
|
|
|
|
'plugins' => Array(
|
|
|
|
'emailtracking' => Array(
|
|
|
|
'enable' => PLUGIN_EMAILTRACKING_USER_DEFAULT_ENABLE_TRACKING,
|
|
|
|
'internals' => PLUGIN_EMAILTRACKING_SHOW_INTERNAL_LOGS
|
|
|
|
)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
?>
|