diff --git a/ChangeLog b/ChangeLog
index aa17400d..e688d379 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+1.10.0 - [RELEASEDATE]
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+- Fixed #96: Add new option 'parseMultipartMixedTextAttachmentsAsFiles' to
+ ezcMailParserOptions to retrieve only text attachments, that are sub-parts of
+ multipart/mixed parts an ezcMailFile object, instead of the default ezcMailText
+ object.
+
1.9.7 - Tuesday 20 August 2024
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/options/parser_options.php b/src/options/parser_options.php
index ac0b6816..3d0de157 100644
--- a/src/options/parser_options.php
+++ b/src/options/parser_options.php
@@ -33,6 +33,7 @@
* $options->mailClass = 'myCustomMailClass'; // extends ezcMail
* $options->fileClass = 'myCustomFileClass'; // extends ezcMailFile
* $options->parseTextAttachmentsAsFiles = true; // to get the text attachments in ezcMailFile objects
+ * $options->parseMultipartMixedTextAttachmentsAsFiles = true; // to get all text attachments that are sub-parts of multipart/mixed parts as ezcMailFile objects
*
* $parser = new ezcMailParser( $options );
*
@@ -43,6 +44,7 @@
* $parser->options->mailClass = 'myCustomMailClass'; // extends ezcMail
* $parser->options->fileClass = 'myCustomFileClass'; // extends ezcMailFile
* $parser->options->parseTextAttachmentsAsFiles = true;
+ * $parser->options->parseMultipartMixedTextAttachmentsAsFiles = true;
*
*
* @property string $mailClass
@@ -54,7 +56,11 @@
* by the parser to handle file attachments. The default value is
* ezcMailFile.
* @property string $parseTextAttachmentsAsFiles
- * Specifies whether to parse the text attachments in an ezcMailTextPart
+ * Specifies whether to parse the text attachments in an ezcMailText part
+ * (default) or in an ezcMailFile (by setting the option to true).
+ * @property string $parseMultipartMixedTextAttachmentsAsFiles
+ * Specifies whether to parse the text attachments that are sub-parts
+ * of a multipart/mixed part as an ezcMailText part
* (default) or in an ezcMailFile (by setting the option to true).
* @package Mail
* @version //autogen//
@@ -74,7 +80,8 @@ public function __construct( array $options = array() )
{
$this->mailClass = 'ezcMail'; // default value for mail class is 'ezcMail'
$this->fileClass = 'ezcMailFile'; // default value for file attachment class is 'ezcMailFile'
- $this->parseTextAttachmentsAsFiles = false; // default is to parse text attachments in ezcMailTextPart objects
+ $this->parseTextAttachmentsAsFiles = false; // default is to parse text attachments in ezcMailText objects
+ $this->parseMultipartMixedTextAttachmentsAsFiles = false; // default is to parse multiple/mixed text attachments in ezcMailText objects
parent::__construct( $options );
}
@@ -140,6 +147,16 @@ public function __set( $propertyName, $propertyValue )
ezcMailPartParser::$parseTextAttachmentsAsFiles = $propertyValue;
break;
+
+ case 'parseMultipartMixedTextAttachmentsAsFiles':
+ if ( !is_bool( $propertyValue ) )
+ {
+ throw new ezcBaseValueException( $propertyName, $propertyValue, 'bool' );
+ }
+ $this->properties[$propertyName] = $propertyValue;
+ ezcMailPartParser::$parseMultipartMixedTextAttachmentsAsFiles = $propertyValue;
+ break;
+
default:
throw new ezcBasePropertyNotFoundException( $propertyName );
}
diff --git a/src/parser/interfaces/part_parser.php b/src/parser/interfaces/part_parser.php
index a81378b3..89fd4e96 100644
--- a/src/parser/interfaces/part_parser.php
+++ b/src/parser/interfaces/part_parser.php
@@ -66,7 +66,7 @@ abstract class ezcMailPartParser
'sender', 'subject', 'sender', 'to' );
/**
- * The default is to parse text attachments into ezcMailTextPart objects.
+ * The default is to parse text attachments into ezcMailText objects.
*
* Setting this to true before calling the parser will parse text attachments
* into ezcMailFile objects. Use the parser options for this:
@@ -81,6 +81,23 @@ abstract class ezcMailPartParser
*/
public static $parseTextAttachmentsAsFiles = false;
+ /**
+ * The default is to parse text attachments into ezcMailText objects.
+ *
+ * Setting this to true before calling the parser will parse text attachments
+ * that are sub-parts of Multipart/Mixed parts into ezcMailFail objects.
+ * Use the parser options for this:
+ *
+ *
+ * $parser = new ezcMailParser();
+ * $parser->options->parseMultipartMixedTextAttachmentsAsFiles = true;
+ * // call $parser->parseMail( $set );
+ *
+ *
+ * @var bool
+ */
+ public static $parseMultipartMixedTextAttachmentsAsFiles = false;
+
/**
* The name of the last header parsed.
*
@@ -118,7 +135,7 @@ abstract public function finish();
* @param ezcMailHeadersHolder $headers
* @return ezcMailPartParser
*/
- static public function createPartParserForHeaders( ezcMailHeadersHolder $headers )
+ static public function createPartParserForHeaders( ezcMailHeadersHolder $headers, ?ezcMailPartParser $parentParser = null )
{
// default as specified by RFC2045 - #5.2
$mainType = 'text';
@@ -168,7 +185,18 @@ static public function createPartParserForHeaders( ezcMailHeadersHolder $headers
break;
case 'text':
- if ( ezcMailPartParser::$parseTextAttachmentsAsFiles === true )
+ if ( ezcMailPartParser::$parseMultipartMixedTextAttachmentsAsFiles === true )
+ {
+ if ( $parentParser instanceof ezcMailMultipartMixedParser )
+ {
+ $bodyParser = new ezcMailFileParser( $mainType, $subType, $headers );
+ }
+ else
+ {
+ $bodyParser = new ezcMailTextParser( $subType, $headers );
+ }
+ }
+ else if ( ezcMailPartParser::$parseTextAttachmentsAsFiles === true )
{
$bodyParser = new ezcMailFileParser( $mainType, $subType, $headers );
}
diff --git a/src/parser/parser.php b/src/parser/parser.php
index fef2a83e..1604d5de 100644
--- a/src/parser/parser.php
+++ b/src/parser/parser.php
@@ -83,6 +83,15 @@
* $parser->options->parseTextAttachmentsAsFiles = true;
*
*
+ * In some cases, you might only want to create {@link ezcMailFile} objects
+ * for text attachments that are sub-parts of multipart/mixed parts.
+ * In that case, you can use the parseMultipartMixedTextAttachmentsAsFiles
+ * option. Example:
+ *
+ * $parser = new ezcMailParser();
+ * $parser->options->parseMultipartMixedTextAttachmentsAsFiles = true;
+ *
+ *
* @property ezcMailParserOptions $options
* Holds the options you can set to the mail parser.
*
diff --git a/src/parser/parts/multipart_parser.php b/src/parser/parts/multipart_parser.php
index d31fb802..52ecbd50 100644
--- a/src/parser/parts/multipart_parser.php
+++ b/src/parser/parts/multipart_parser.php
@@ -181,7 +181,7 @@ public function parseBody( $origLine )
{
if ( $this->parserState == self::PARSE_STATE_HEADERS && $line == '' )
{
- $this->currentPartParser = self::createPartParserForHeaders( $this->currentPartHeaders );
+ $this->currentPartParser = self::createPartParserForHeaders( $this->currentPartHeaders, $this );
$this->parserState = self::PARSE_STATE_BODY;
}
else if ( $this->parserState == self::PARSE_STATE_HEADERS )
diff --git a/src/parser/parts/rfc822_parser.php b/src/parser/parts/rfc822_parser.php
index eed7c413..0a74c30d 100644
--- a/src/parser/parts/rfc822_parser.php
+++ b/src/parser/parts/rfc822_parser.php
@@ -107,7 +107,7 @@ public function parseBody( $origLine )
}
// get the correct body type
- $this->bodyParser = self::createPartParserForHeaders( $headers );
+ $this->bodyParser = self::createPartParserForHeaders( $headers, $this );
}
else if ( $this->parserState == self::PARSE_STATE_HEADERS )
{
diff --git a/tests/parser/parser_test.php b/tests/parser/parser_test.php
index 77365add..8c324fae 100644
--- a/tests/parser/parser_test.php
+++ b/tests/parser/parser_test.php
@@ -1937,5 +1937,43 @@ public function testVarious14b()
$this->assertEquals( 'application', $alternativeParts[1]->contentType );
$this->assertEquals( 'html', $alternativeParts[1]->mimeType );
}
+
+
+ public function testVarious14c()
+ {
+ $parser = new ezcMailParser();
+ $parser->options->parseMultipartMixedTextAttachmentsAsFiles = true;
+
+ $set = new SingleFileSet( 'various/test-html-text-and-text-attachment' );
+ $mail = $parser->parseMail( $set );
+ $this->assertEquals( 1, count( $mail ) );
+ $mail = $mail[0];
+ $parts = $mail->body->getParts();
+
+ $this->assertEquals( 4, count( $parts ) );
+ $this->assertEquals( 'ezcMailMultipartAlternative', get_class( $parts[0] ) );
+
+ $this->assertEquals( 'ezcMailFile', get_class( $parts[1] ) );
+ $this->assertEquals( '2_load_xss.html.txt', basename( $parts[1]->fileName ) );
+ $this->assertEquals( 'text', $parts[1]->contentType );
+ $this->assertEquals( 'plain', $parts[1]->mimeType );
+
+ $this->assertEquals( 'ezcMailFile', get_class( $parts[2] ) );
+ $this->assertEquals( 'form_03.doc', basename( $parts[2]->fileName ) );
+ $this->assertEquals( 'application', $parts[2]->contentType );
+ $this->assertEquals( 'msword', $parts[2]->mimeType );
+
+ $this->assertEquals( 'ezcMailFile', get_class( $parts[3] ) );
+ $this->assertEquals( '2932_1 Ward Grouped Mayor-Lismore.pdf', basename( $parts[3]->fileName ) );
+ $this->assertEquals( 'application', $parts[3]->contentType );
+ $this->assertEquals( 'pdf', $parts[3]->mimeType );
+
+ $alternativeParts = $parts[0]->getParts();
+ $this->assertEquals( 2, count( $alternativeParts ) );
+ $this->assertEquals( 'ezcMailText', get_class( $alternativeParts[0] ) );
+ $this->assertEquals( 'plain', $alternativeParts[0]->subType );
+ $this->assertEquals( 'ezcMailText', get_class( $alternativeParts[1] ) );
+ $this->assertEquals( 'html', $alternativeParts[1]->subType );
+ }
}
?>