Skip to content

Commit

Permalink
Fixed #96: Add new option 'parseMultipartMixedTextAttachmentsAsFiles'…
Browse files Browse the repository at this point in the history
… to ezcMailParserOptions

By setting this option like:

  $parser = new ezcMailParser();
  $parser->options->parseMultipartMixedTextAttachmentsAsFiles = true;

The parser returns text parts as attachments, but only if they are sub-parts of
multipart/mixed parts.

This is distinct from the 'parseTextAttachmentsAsFiles' option, which does it
for *all* text parts.
  • Loading branch information
derickr committed Nov 6, 2024
1 parent fc981b4 commit bebae73
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 7 deletions.
8 changes: 8 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -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
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Expand Down
21 changes: 19 additions & 2 deletions src/options/parser_options.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
* </code>
Expand All @@ -43,6 +44,7 @@
* $parser->options->mailClass = 'myCustomMailClass'; // extends ezcMail
* $parser->options->fileClass = 'myCustomFileClass'; // extends ezcMailFile
* $parser->options->parseTextAttachmentsAsFiles = true;
* $parser->options->parseMultipartMixedTextAttachmentsAsFiles = true;
* </code>
*
* @property string $mailClass
Expand All @@ -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//
Expand All @@ -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 );
}
Expand Down Expand Up @@ -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 );
}
Expand Down
34 changes: 31 additions & 3 deletions src/parser/interfaces/part_parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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:
*
* <code>
* $parser = new ezcMailParser();
* $parser->options->parseMultipartMixedTextAttachmentsAsFiles = true;
* // call $parser->parseMail( $set );
* </code>
*
* @var bool
*/
public static $parseMultipartMixedTextAttachmentsAsFiles = false;

/**
* The name of the last header parsed.
*
Expand Down Expand Up @@ -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';
Expand Down Expand Up @@ -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 );
}
Expand Down
9 changes: 9 additions & 0 deletions src/parser/parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,15 @@
* $parser->options->parseTextAttachmentsAsFiles = true;
* </code>
*
* 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:
* <code>
* $parser = new ezcMailParser();
* $parser->options->parseMultipartMixedTextAttachmentsAsFiles = true;
* </code>
*
* @property ezcMailParserOptions $options
* Holds the options you can set to the mail parser.
*
Expand Down
2 changes: 1 addition & 1 deletion src/parser/parts/multipart_parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 )
Expand Down
2 changes: 1 addition & 1 deletion src/parser/parts/rfc822_parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 )
{
Expand Down
38 changes: 38 additions & 0 deletions tests/parser/parser_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
}
}
?>

0 comments on commit bebae73

Please sign in to comment.