Skip to content

Commit

Permalink
Merge branch '6.6.3' into stable
Browse files Browse the repository at this point in the history
  • Loading branch information
jstanden committed Feb 21, 2014
2 parents 31b7613 + b407c3b commit ed8145f
Show file tree
Hide file tree
Showing 24 changed files with 700 additions and 135 deletions.
193 changes: 107 additions & 86 deletions api/Application.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@
\* - Jeff Standen, Darren Sugita, Dan Hildebrandt
* Webgroup Media LLC - Developers of Cerb
*/
define("APP_BUILD", 2014021402);
define("APP_VERSION", '6.6.2');
define("APP_BUILD", 2014022001);
define("APP_VERSION", '6.6.3');

define("APP_MAIL_PATH", APP_STORAGE_PATH . '/mail/');

Expand Down Expand Up @@ -1273,7 +1273,7 @@ static public function setActivityDefaultActor($context, $context_id=null) {
}
}

static public function logActivity($activity_point, $target_context, $target_context_id, $entry_array, $actor_context=null, $actor_context_id=null, $also_notify_worker_ids=array()) {
static public function logActivity($activity_point, $target_context, $target_context_id, &$entry_array, $actor_context=null, $actor_context_id=null, $also_notify_worker_ids=array()) {
// Target meta
if(!isset($target_meta)) {
if(null != ($target_ctx = DevblocksPlatform::getExtension($target_context, true))
Expand Down Expand Up @@ -1351,7 +1351,7 @@ static public function logActivity($activity_point, $target_context, $target_con
$entry_array['urls']['actor'] = $actor_url;

// Activity Log
DAO_ContextActivityLog::create(array(
$activity_entry_id = DAO_ContextActivityLog::create(array(
DAO_ContextActivityLog::ACTIVITY_POINT => $activity_point,
DAO_ContextActivityLog::CREATED => time(),
DAO_ContextActivityLog::ACTOR_CONTEXT => $actor_context,
Expand All @@ -1363,108 +1363,129 @@ static public function logActivity($activity_point, $target_context, $target_con

// Tell target watchers about the activity

$watchers = array();
$do_notifications = true;

// Merge in the record owner if defined
if(isset($target_meta) && isset($target_meta['owner_id']) && !empty($target_meta['owner_id'])) {
$watchers = array_merge(
$watchers,
array($target_meta['owner_id'])
);
}
// Only fire notifications if supported by the activity options (!no_notifications)

// Merge in watchers of the actor (if not a worker)
if(CerberusContexts::CONTEXT_WORKER != $actor_context) {
$watchers = array_merge(
$watchers,
array_keys(CerberusContexts::getWatchers($actor_context, $actor_context_id))
);
}
$activity_points = DevblocksPlatform::getActivityPointRegistry();

// And watchers of the target (if not a worker)
if(CerberusContexts::CONTEXT_WORKER != $target_context) {
$watchers = array_merge(
$watchers,
array_keys(CerberusContexts::getWatchers($target_context, $target_context_id))
);
if(isset($activity_points[$activity_point])) {
$activity_mft = $activity_points[$activity_point];
if(
isset($activity_mft['params'])
&& isset($activity_mft['params']['options'])
&& in_array('no_notifications', DevblocksPlatform::parseCsvString($activity_mft['params']['options']))
)
$do_notifications = false;
}

// Include the 'also notify' list
if(!is_array($also_notify_worker_ids))
$also_notify_worker_ids = array();
// Send notifications

$watchers = array_merge(
$watchers,
$also_notify_worker_ids
);

// And include any worker-based custom fields with the 'send watcher notifications' option
$target_custom_fields = DAO_CustomField::getByContext($target_context, true);

if(is_array($target_custom_fields))
foreach($target_custom_fields as $target_custom_field_id => $target_custom_field) {
if($target_custom_field->type != Model_CustomField::TYPE_WORKER)
continue;
if($do_notifications) {
$watchers = array();

if(!isset($target_custom_field->params['send_notifications']) || empty($target_custom_field->params['send_notifications']))
continue;
// Merge in the record owner if defined
if(isset($target_meta) && isset($target_meta['owner_id']) && !empty($target_meta['owner_id'])) {
$watchers = array_merge(
$watchers,
array($target_meta['owner_id'])
);
}

$values = DAO_CustomFieldValue::getValuesByContextIds($target_context, $target_context_id);
// Merge in watchers of the actor (if not a worker)
if(CerberusContexts::CONTEXT_WORKER != $actor_context) {
$watchers = array_merge(
$watchers,
array_keys(CerberusContexts::getWatchers($actor_context, $actor_context_id))
);
}

if(isset($values[$target_context_id]) && isset($values[$target_context_id][$target_custom_field_id]))
// And watchers of the target (if not a worker)
if(CerberusContexts::CONTEXT_WORKER != $target_context) {
$watchers = array_merge(
$watchers,
array($values[$target_context_id][$target_custom_field_id])
array_keys(CerberusContexts::getWatchers($target_context, $target_context_id))
);
}

// Remove dupe watchers
$watcher_ids = array_unique($watchers);

$url_writer = DevblocksPlatform::getUrlService();

// Fire off notifications
if(is_array($watcher_ids)) {
$message = CerberusContexts::formatActivityLogEntry($entry_array, 'plaintext');
@$url = reset($entry_array['urls']);
}

// Include the 'also notify' list
if(!is_array($also_notify_worker_ids))
$also_notify_worker_ids = array();

$watchers = array_merge(
$watchers,
$also_notify_worker_ids
);

// And include any worker-based custom fields with the 'send watcher notifications' option
$target_custom_fields = DAO_CustomField::getByContext($target_context, true);

if(0 == strcasecmp('ctx://',substr($url,0,6))) {
$url = self::parseContextUrl($url);
} elseif(0 != strcasecmp('http',substr($url,0,4))) {
$url = $url_writer->writeNoProxy($url, true);
if(is_array($target_custom_fields))
foreach($target_custom_fields as $target_custom_field_id => $target_custom_field) {
if($target_custom_field->type != Model_CustomField::TYPE_WORKER)
continue;

if(!isset($target_custom_field->params['send_notifications']) || empty($target_custom_field->params['send_notifications']))
continue;

$values = DAO_CustomFieldValue::getValuesByContextIds($target_context, $target_context_id);

if(isset($values[$target_context_id]) && isset($values[$target_context_id][$target_custom_field_id]))
$watchers = array_merge(
$watchers,
array($values[$target_context_id][$target_custom_field_id])
);
}

foreach($watcher_ids as $watcher_id) {
// If not inside a VA
if(0 == EventListener_Triggers::getDepth()) {
// Skip a watcher if they are the actor
if($actor_context == CerberusContexts::CONTEXT_WORKER
&& $actor_context_id == $watcher_id) {
// If they explicitly added themselves to the notify, allow it.
// Otherwise, don't tell them what they just did.
if(!in_array($watcher_id, $also_notify_worker_ids))
continue;
}
// Remove dupe watchers
$watcher_ids = array_unique($watchers);

$url_writer = DevblocksPlatform::getUrlService();

// Fire off notifications
if(is_array($watcher_ids)) {
$message = CerberusContexts::formatActivityLogEntry($entry_array, 'plaintext');
@$url = reset($entry_array['urls']);

if(0 == strcasecmp('ctx://',substr($url,0,6))) {
$url = self::parseContextUrl($url);
} elseif(0 != strcasecmp('http',substr($url,0,4))) {
$url = $url_writer->writeNoProxy($url, true);
}

// Does the worker want this kind of notification?
$dont_notify_on_activities = WorkerPrefs::getDontNotifyOnActivities($watcher_id);
if(in_array($activity_point, $dont_notify_on_activities))
continue;
foreach($watcher_ids as $watcher_id) {
// If not inside a VA
if(0 == EventListener_Triggers::getDepth()) {
// Skip a watcher if they are the actor
if($actor_context == CerberusContexts::CONTEXT_WORKER
&& $actor_context_id == $watcher_id) {
// If they explicitly added themselves to the notify, allow it.
// Otherwise, don't tell them what they just did.
if(!in_array($watcher_id, $also_notify_worker_ids))
continue;
}
}

// If yes, send it
DAO_Notification::create(array(
DAO_Notification::CONTEXT => $target_context,
DAO_Notification::CONTEXT_ID => $target_context_id,
DAO_Notification::CREATED_DATE => time(),
DAO_Notification::IS_READ => 0,
DAO_Notification::WORKER_ID => $watcher_id,
DAO_Notification::MESSAGE => $message,
DAO_Notification::URL => $url,
));
// Does the worker want this kind of notification?
$dont_notify_on_activities = WorkerPrefs::getDontNotifyOnActivities($watcher_id);
if(in_array($activity_point, $dont_notify_on_activities))
continue;

// If yes, send it
DAO_Notification::create(array(
DAO_Notification::CONTEXT => $target_context,
DAO_Notification::CONTEXT_ID => $target_context_id,
DAO_Notification::CREATED_DATE => time(),
DAO_Notification::IS_READ => 0,
DAO_Notification::WORKER_ID => $watcher_id,
DAO_Notification::MESSAGE => $message,
DAO_Notification::URL => $url,
));
}
}
}
} // end if($do_notifications)

return $activity_entry_id;
}

private static function _getAttachmentContext($attachment, &$token_labels, &$token_values, $prefix=null) {
Expand Down
10 changes: 8 additions & 2 deletions api/app/Mail.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ static function getMailerDefaults() {
static function parseRfcAddresses($string) {
$results = array();
$string = rtrim(str_replace(';',',',$string),' ,');
$parsed = imap_rfc822_parse_adrlist($string, 'localhost');
@$parsed = imap_rfc822_parse_adrlist($string, 'localhost');

if(is_array($parsed))
foreach($parsed as $parsed_addy) {
Expand All @@ -76,7 +76,11 @@ static function parseRfcAddresses($string) {

if(empty($mailbox) || empty($host))
continue;
if($mailbox == 'INVALID_ADDRESS')

if(0 == strcasecmp($mailbox, 'invalid_address'))
continue;

if(0 == strcasecmp($host, '.syntax-error.'))
continue;

$results[$mailbox . '@' . $host] = array(
Expand All @@ -88,6 +92,8 @@ static function parseRfcAddresses($string) {
);
}

@imap_errors();

return $results;
}

Expand Down
14 changes: 8 additions & 6 deletions api/app/Parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -114,13 +114,14 @@ private function _parseHeadersFrom() {

$from = array();

if(!empty($sReplyTo)) {
if(empty($from) && !empty($sReplyTo))
$from = CerberusParser::parseRfcAddress($sReplyTo);
} elseif(!empty($sFrom)) {

if(empty($from) && !empty($sFrom))
$from = CerberusParser::parseRfcAddress($sFrom);
} elseif(!empty($sReturnPath)) {

if(empty($from) && !empty($sReturnPath))
$from = CerberusParser::parseRfcAddress($sReturnPath);
}

if(empty($from) || !is_array($from))
throw new Exception('No sender headers found.');
Expand Down Expand Up @@ -673,7 +674,7 @@ static public function parseMime($mime, $full_filename) {

$bounce_token = '------ This is a copy of the message, including all the headers. ------';

if(false !== ($bounce_pos = mb_strpos($text, $bounce_token, 0, $info['charset']))) {
if(false !== ($bounce_pos = @mb_strpos($text, $bounce_token, 0, $info['charset']))) {
$bounce_text = mb_substr($text, $bounce_pos + strlen($bounce_token), strlen($text), $info['charset']);
$text = mb_substr($text, 0, $bounce_pos, $info['charset']);

Expand Down Expand Up @@ -1017,6 +1018,7 @@ static public function parseMessage(CerberusParserMessage $message, $options=arr
if(is_array($lines))
foreach($lines as $line) {

// Ignore quoted relay comments
if(preg_match('/[\s\>]*\s*##/', $line))
continue;

Expand Down Expand Up @@ -1114,7 +1116,7 @@ static public function parseMessage(CerberusParserMessage $message, $options=arr
));
}

$properties['content'] = $body;
$properties['content'] = ltrim($body);

CerberusMail::sendTicketMessage($properties);
return $proxy_ticket->id;
Expand Down
53 changes: 39 additions & 14 deletions api/app/Utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,27 +60,52 @@ static function parseRfcAddressList($input) {
$input = array($input);

foreach($input as $string) {
@$addy_rows = imap_rfc822_parse_adrlist($string, '');
$addy_rows = self::_parseRfcAddress($string);

if(is_array($addy_rows))
foreach($addy_rows as $idx => $addy_row) {
if(empty($addy_row->host))
continue;

if(strlen($addy_row->mailbox) == 1 && preg_match('/[^a-zA-Z0-9]/', $addy_row->mailbox))
continue;

if($addy_row->host == '.SYNTAX-ERROR.')
continue;

$addys[] = $addy_row;
if(!empty($addy_rows))
$addys = array_merge($addys, $addy_rows);
}

// If we failed to find any content, try a regexp parse
if(empty($addys)) {
foreach($input as $string) {
if(preg_match('/[\\w\\.\\-+=*_]*@[\\w\\.\\-+=*_]*/', $string, $matches)) {
if(is_array($matches))
foreach($matches as $match) {
$addy_rows = self::_parseRfcAddress($match);

if(!empty($addy_rows))
$addys = array_merge($addys, $addy_rows);

}
}
}

}

@imap_errors();

return $addys;
}

static private function _parseRfcAddress($string) {
@$addy_rows = imap_rfc822_parse_adrlist($string, '');
$results = array();

if(is_array($addy_rows))
foreach($addy_rows as $idx => $addy_row) {
if(empty($addy_row->host))
continue;

if($addy_row->host == '.SYNTAX-ERROR.')
continue;

if(strlen($addy_row->mailbox) == 1 && preg_match('/[^a-zA-Z0-9]/', $addy_row->mailbox))
continue;

$results[] = $addy_row;
}

return $results;
}

}
Loading

0 comments on commit ed8145f

Please sign in to comment.