Version 4.5.0
This commit is contained in:
1 parent
1a0c7fd3c2
commit
f79dcf067a
3791 files changed
+248032
-76372
No files matched your search
@@ -11,7 +11,7 @@
|
||||
namespace IPS\Email\Incoming;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
@@ -57,6 +57,11 @@ class _Email
|
||||
* @brief Attachments
|
||||
*/
|
||||
public $attachments = array();
|
||||
|
||||
/**
|
||||
* @brief Existing attachments to store a map for
|
||||
*/
|
||||
public $mappedAttachments = array();
|
||||
|
||||
/**
|
||||
* @brief Raw email headers
|
||||
@@ -121,7 +126,7 @@ class _Email
|
||||
/* Save */
|
||||
if ( isset( $headers[ $headerName ] ) )
|
||||
{
|
||||
if ( is_array( $headers[ $headerName ] ) )
|
||||
if ( \is_array( $headers[ $headerName ] ) )
|
||||
{
|
||||
$headers[ $headerName ][] = $headerValue;
|
||||
}
|
||||
@@ -137,7 +142,7 @@ class _Email
|
||||
}
|
||||
|
||||
/* Work out the content type */
|
||||
if ( isset( $headers['content-type'] ) and is_string( $headers['content-type'] ) )
|
||||
if ( isset( $headers['content-type'] ) and \is_string( $headers['content-type'] ) )
|
||||
{
|
||||
$contentType = $this->_parseStructuredHeader( $headers['content-type'] );
|
||||
}
|
||||
@@ -147,7 +152,7 @@ class _Email
|
||||
}
|
||||
|
||||
/* Parse body: Multipart */
|
||||
if ( in_array( $contentType['value'], array( 'multipart/parallel', 'multipart/appledouble', 'multipart/report', 'multipart/signed', 'multipart/digest', 'multipart/alternative', 'multipart/related', 'multipart/mixed', 'application/vnd.wap.multipart.related' ) ) and isset( $contentType['extra']['boundary'] ) )
|
||||
if ( \in_array( $contentType['value'], array( 'multipart/parallel', 'multipart/appledouble', 'multipart/report', 'multipart/signed', 'multipart/digest', 'multipart/alternative', 'multipart/related', 'multipart/mixed', 'application/vnd.wap.multipart.related' ) ) and isset( $contentType['extra']['boundary'] ) )
|
||||
{
|
||||
$parts = array();
|
||||
|
||||
@@ -192,7 +197,7 @@ class _Email
|
||||
|
||||
$body = preg_replace_callback( '/=([a-f0-9]{2})/i', function( $matches )
|
||||
{
|
||||
return chr( hexdec( $matches[1] ) );
|
||||
return \chr( hexdec( $matches[1] ) );
|
||||
}, $body );
|
||||
}
|
||||
elseif( $encoding == 'base64' )
|
||||
@@ -232,7 +237,7 @@ class _Email
|
||||
preg_match_all( '/=([a-f0-9]{2})/i', $text, $matches );
|
||||
foreach( $matches[1] as $value )
|
||||
{
|
||||
$text = str_replace( '=' . $value, chr( hexdec( $value ) ), $text );
|
||||
$text = str_replace( '=' . $value, \chr( hexdec( $value ) ), $text );
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -279,7 +284,7 @@ class _Email
|
||||
* Parse basic headers (to, from, subject, cc)
|
||||
*
|
||||
* @param array $headers Raw headers
|
||||
* @retrun void
|
||||
* @return void
|
||||
*/
|
||||
protected function _parseBasicHeaders( $headers )
|
||||
{
|
||||
@@ -313,7 +318,7 @@ class _Email
|
||||
/* CC */
|
||||
if( isset( $headers['cc'] ) )
|
||||
{
|
||||
if( is_array( $headers['cc'] ) )
|
||||
if( \is_array( $headers['cc'] ) )
|
||||
{
|
||||
$this->cc = $headers['cc'];
|
||||
}
|
||||
@@ -405,17 +410,17 @@ class _Email
|
||||
{
|
||||
if ( isset( $data['headers']['content-id'] ) and $contentId = trim( $data['headers']['content-id'], '<>' ) and isset( $this->imagePlaceholders[ $contentId ] ) )
|
||||
{
|
||||
$imageTag = "<img src='<fileStore.core_Attachment>/{$file}' class='ipsImage ipsImage_thumbnailed'>";
|
||||
$imageTag = "<img src='<fileStore.core_Attachment>/{$file}' class='ipsImage ipsImage_thumbnailed'> ";
|
||||
$this->message = preg_replace( "/<a href=\"#image-placeholder={$this->imagePlaceholders[ $contentId ]}\" rel=\"[^\"]*\"><\/a>/", $imageTag, $this->message );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->message .= "<img src='<fileStore.core_Attachment>/{$file}' class='ipsImage ipsImage_thumbnailed'>";
|
||||
$this->message .= "<img src='<fileStore.core_Attachment>/{$file}' class='ipsImage ipsImage_thumbnailed'> ";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->message .= "<a class='ipsAttachLink' href='<fileStore.core_Attachment>/{$file}'>{$file->originalFilename}</a>";
|
||||
$this->message .= "<a class='ipsAttachLink' href='<fileStore.core_Attachment>/{$file}'>{$file->originalFilename}</a><br><br>";
|
||||
}
|
||||
|
||||
/* Save to the $attachments array and exit */
|
||||
@@ -489,7 +494,7 @@ class _Email
|
||||
*
|
||||
* @param string $body Email body
|
||||
* @param array $contentType Content-Type data (as returned by _parseStructuredHeader)
|
||||
* @retrun void
|
||||
* @return void
|
||||
*/
|
||||
protected function _parseBodyAsHtml( $body, $contentType )
|
||||
{
|
||||
@@ -502,7 +507,7 @@ class _Email
|
||||
/* Convert to UTF-8 if possible */
|
||||
if ( isset( $contentType['extra']['charset'] ) and mb_strtolower( $contentType['extra']['charset'] ) != 'utf-8' )
|
||||
{
|
||||
if( in_array( mb_strtolower( $contentType['extra']['charset'] ), array_map( 'mb_strtolower', mb_list_encodings() ) ) )
|
||||
if( \in_array( mb_strtolower( $contentType['extra']['charset'] ), array_map( 'mb_strtolower', mb_list_encodings() ) ) )
|
||||
{
|
||||
$body = mb_convert_encoding( $body, 'UTF-8', $contentType['extra']['charset'] );
|
||||
}
|
||||
@@ -512,13 +517,14 @@ class _Email
|
||||
$body = preg_replace_callback( '/<img[^>]*src=[\'"]cid:(.+?)[\'"][^>]*>/', array( $this, '_replaceImageWithPlaceholder' ), $body );
|
||||
|
||||
/* Clean */
|
||||
$body = \IPS\Text\Parser::parseStatic( $body, FALSE, NULL, \IPS\Member::load( $this->from, 'email' ), TRUE, TRUE, TRUE, function( $config ) {
|
||||
$parser = new \IPS\Text\Parser( FALSE, NULL, \IPS\Member::load( $this->from, 'email' ), TRUE, TRUE, TRUE, function( $config ) {
|
||||
$config->set( 'HTML.TargetBlank', TRUE );
|
||||
$config->set( 'URI.Munge', urldecode( (string) \IPS\Http\Url::internal( 'app=core&module=system&controller=redirect&url=%s&key=%t&resource=%r', 'front' ) ) );
|
||||
$config->set( 'URI.MungeResources', TRUE );
|
||||
$config->set( 'URI.MungeSecretKey', \IPS\Settings::i()->site_secret_key );
|
||||
});
|
||||
|
||||
} );
|
||||
$body = $parser->parse( $body );
|
||||
|
||||
/* Store any mapped attachments that will need a mapping stored in the individual incoming email handlers */
|
||||
$this->mappedAttachments = array_merge( $this->mappedAttachments, $parser->mappedAttachments );
|
||||
|
||||
/* Return */
|
||||
return $body;
|
||||
}
|
||||
@@ -540,7 +546,7 @@ class _Email
|
||||
* Extract quote from message body
|
||||
*
|
||||
* @param string $body Email body (the quote will be removed from it and returned)
|
||||
* @retrun string
|
||||
* @return string
|
||||
*/
|
||||
protected function _extractQuoteFromBody( &$body )
|
||||
{
|
||||
@@ -549,20 +555,20 @@ class _Email
|
||||
$_body = array();
|
||||
$_seen = FALSE;
|
||||
$inQuote = FALSE;
|
||||
$exploded = explode( "<br />", $body );
|
||||
if ( count( $exploded ) === 1 )
|
||||
{
|
||||
$exploded = explode( '<br>', $body );
|
||||
}
|
||||
|
||||
/* It is possible the email is formatted with <p></p> and not <br> which can confuse the quote selection */
|
||||
/* Split into lines - It is possible the email is formatted with <p></p> and not <br> which can confuse the quote selection */
|
||||
if ( mb_stristr( $body, '</p>' ) or mb_stristr( $body, '</div>' ) )
|
||||
{
|
||||
{
|
||||
$body = preg_replace( '#<(p|div)[^>]*?>#', '', $body );
|
||||
$body = preg_replace( '#</(p|div)>#', '<br>', $body );
|
||||
}
|
||||
$exploded = explode( "<br />", $body );
|
||||
if ( \count( $exploded ) === 1 )
|
||||
{
|
||||
$exploded = explode( '<br>', $body );
|
||||
}
|
||||
|
||||
/* Loop over each line */
|
||||
foreach ( $exploded as $k => $line )
|
||||
{
|
||||
$line = trim( $line );
|
||||
@@ -634,7 +640,7 @@ class _Email
|
||||
{
|
||||
/* Check for common "on x so and so wrote:" type lines preceeding this position */
|
||||
preg_match_all( '/<div([^>]+?)?>((?!<div).)*:(<br(>| \/>))*\s*<\/div>/sU', $message, $possibleHeaders, PREG_OFFSET_CAPTURE );
|
||||
if ( count( $possibleHeaders ) )
|
||||
if ( \count( $possibleHeaders ) )
|
||||
{
|
||||
foreach ( array_reverse( $possibleHeaders[0] ) as $header )
|
||||
{
|
||||
@@ -733,7 +739,7 @@ class _Email
|
||||
case 'eqls':
|
||||
if ( mb_strpos( $analyse, ',' ) !== FALSE )
|
||||
{
|
||||
$match = (bool) in_array( $analyse, explode( ',', $analyse ) );
|
||||
$match = (bool) \in_array( $analyse, explode( ',', $analyse ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -763,7 +769,7 @@ class _Email
|
||||
/* Get all IncomingEmail extension classes for the app */
|
||||
$extensions = $app->extensions( 'core', 'IncomingEmail' );
|
||||
|
||||
if( count( $extensions ) )
|
||||
if( \count( $extensions ) )
|
||||
{
|
||||
/* Loop over the extensions */
|
||||
foreach( $extensions as $_instance )
|
||||
@@ -792,7 +798,7 @@ class _Email
|
||||
* Is this an auto-reply? Try to detect to prevent auto-reply loops.
|
||||
*
|
||||
* @return bool
|
||||
* @link https://github.com/opennorth/multi_mail/wiki/Detecting-autoresponders
|
||||
* @see https://github.com/opennorth/multi_mail/wiki/Detecting-autoresponders
|
||||
*/
|
||||
protected function isAutoreply()
|
||||
{
|
||||
@@ -820,17 +826,17 @@ class _Email
|
||||
}
|
||||
|
||||
/* Now check for specific headers with specific values */
|
||||
if( !empty( $this->headers['x-autogenerated'] ) AND in_array( mb_strtolower( $this->headers['x-autogenerated'] ), array( 'forward', 'group', 'letter', 'mirror', 'redirect', 'reply' ) ) )
|
||||
if( !empty( $this->headers['x-autogenerated'] ) AND \in_array( mb_strtolower( $this->headers['x-autogenerated'] ), array( 'forward', 'group', 'letter', 'mirror', 'redirect', 'reply' ) ) )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if( !empty( $this->headers['precedence'] ) AND in_array( mb_strtolower( $this->headers['precedence'] ), array( 'auto_reply', 'list', 'bulk' ) ) )
|
||||
if( !empty( $this->headers['precedence'] ) AND \in_array( mb_strtolower( $this->headers['precedence'] ), array( 'auto_reply', 'list', 'bulk' ) ) )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if( !empty( $this->headers['x-precedence'] ) AND in_array( mb_strtolower( $this->headers['x-precedence'] ), array( 'auto_reply', 'list', 'bulk' ) ) )
|
||||
if( !empty( $this->headers['x-precedence'] ) AND \in_array( mb_strtolower( $this->headers['x-precedence'] ), array( 'auto_reply', 'list', 'bulk' ) ) )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
@@ -845,7 +851,7 @@ class _Email
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ( !empty( $this->headers['delivered-to'] ) AND is_array( $this->headers['delivered-to'] ) )
|
||||
if ( !empty( $this->headers['delivered-to'] ) AND \is_array( $this->headers['delivered-to'] ) )
|
||||
{
|
||||
foreach( $this->headers['delivered-to'] AS $deliveredTo )
|
||||
{
|
||||
@@ -856,7 +862,7 @@ class _Email
|
||||
}
|
||||
}
|
||||
|
||||
if( !empty( $this->headers['delivered-to'] ) AND is_string( $this->headers['delivered-to'] ) AND mb_strtolower( $this->headers['delivered-to'] ) == 'autoresponder' )
|
||||
if( !empty( $this->headers['delivered-to'] ) AND \is_string( $this->headers['delivered-to'] ) AND mb_strtolower( $this->headers['delivered-to'] ) == 'autoresponder' )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user