MailMimeParser 3.0

CommentConsumerService extends GenericConsumerService
in package

Consumes all tokens within parentheses as comments.

Parenthetical comments in mime-headers can be nested within one another. The outer-level continues after an inner-comment ends. Additionally, quoted-literals may exist with comments as well meaning a parenthesis inside a quoted string would not begin or end a comment section.

In order to satisfy these specifications, CommentConsumerService inherits from GenericConsumerService which defines CommentConsumerService and QuotedStringConsumerService as sub-consumers.

Examples: X-Mime-Header: Some value (comment) X-Mime-Header: Some value (comment (nested comment) still in comment) X-Mime-Header: Some value (comment "and part of original ) comment" - still a comment)

Tags
author

Zaahid Bateson

Table of Contents

$logger  : LoggerInterface
$maxHeaderTokenCount  : int
$partFactory  : HeaderPartFactory
$subConsumers  : array<string|int, mixed>
$depth  : int
$maxCommentDepth  : int
$tokenSplitPattern  : string|null
__construct()  : mixed
__invoke()  : array<string|int, IHeaderPart>
Invokes parsing of a header's value into header parts.
advanceToNextToken()  : static
Calls $tokens->next() and returns.
getAllConsumers()  : array<string|int, AbstractConsumerService>
Returns this consumer and all unique sub consumers.
getAllTokenSeparators()  : array<string|int, string>
Returns a list of regular expression markers for this consumer and all sub-consumers by calling getTokenSeparators().
getConsumerTokenParts()  : array<string|int, IHeaderPart>
Iterates through this consumer's sub-consumers checking if the current token triggers a sub-consumer's start token and passes control onto that sub-consumer's parseTokenIntoParts().
getPartForToken()  : IHeaderPart|null
Instantiates and returns Part\Token objects.
getTokenParts()  : array<string|int, IHeaderPart>
Returns an array of IHeaderPart for the current token on the iterator.
getTokenSeparators()  : array<string|int, string>
Returns patterns matching open and close parenthesis characters as separators.
getTokenSplitPattern()  : string
Returns a regex pattern used to split the input header string.
isEndToken()  : bool
Returns true if the token is a close parenthesis character, ')'.
isStartToken()  : bool
Returns true if the token is an open parenthesis character, '('.
parseTokensIntoParts()  : array<string|int, IHeaderPart>
Overridden to keep track of the current comment nesting depth.
processParts()  : array<string|int, IHeaderPart>
Post processing involves creating a single Part\CommentPart out of generated parts from tokens. The Part\CommentPart is returned in an array.
splitRawValue()  : array<string|int, string>
Returns an array of split tokens from the input string.
discardNestedComment()  : array<string|int, IHeaderPart>
Consumes tokens to the end of the current comment without recursing into it or constructing any parts for it.
parseRawValue()  : array<string|int, IHeaderPart>
Parses the raw header value into header parts.

Properties

$maxHeaderTokenCount

protected int $maxHeaderTokenCount

Maximum number of tokens parsed from a single header value.

$subConsumers

protected array<string|int, mixed> $subConsumers = []

array of sub-consumers used by this consumer if any, or an empty array if none exist.

$depth

private int $depth = 0

the nesting level currently being parsed. Comments nest by re-entering this same consumer, so an instance counter tracks the real nesting depth.

$maxCommentDepth

private int $maxCommentDepth

Maximum nesting depth of comments in a header value.

$tokenSplitPattern

private string|null $tokenSplitPattern = null

the generated token split pattern on first run, so it doesn't need to be regenerated every time.

Methods

__invoke()

Invokes parsing of a header's value into header parts.

public __invoke(string $value) : array<string|int, IHeaderPart>
Parameters
$value : string

the raw header value

Return values
array<string|int, IHeaderPart>

the array of parsed parts

advanceToNextToken()

Calls $tokens->next() and returns.

protected advanceToNextToken(Iterator $tokens, bool $isStartToken) : static

The default implementation checks if the current token is an end token, and will not advance past it. Because a comment part of a header can be nested, its implementation must advance past its own 'end' token.

Parameters
$tokens : Iterator
$isStartToken : bool
Return values
static

getAllConsumers()

Returns this consumer and all unique sub consumers.

protected getAllConsumers() : array<string|int, AbstractConsumerService>

Loops into the sub-consumers (and their sub-consumers, etc...) finding all unique consumers, and returns them in an array.

Return values
array<string|int, AbstractConsumerService>

Array of unique consumers.

getAllTokenSeparators()

Returns a list of regular expression markers for this consumer and all sub-consumers by calling getTokenSeparators().

protected getAllTokenSeparators() : array<string|int, string>
Return values
array<string|int, string>

Array of regular expression markers.

getConsumerTokenParts()

Iterates through this consumer's sub-consumers checking if the current token triggers a sub-consumer's start token and passes control onto that sub-consumer's parseTokenIntoParts().

protected getConsumerTokenParts(Iterator<string|int, string> $tokens) : array<string|int, IHeaderPart>

If no sub-consumer is responsible for the current token, calls AbstractConsumerService::getPartForToken() and returns it in an array.

Parameters
$tokens : Iterator<string|int, string>
Return values
array<string|int, IHeaderPart>

getPartForToken()

Instantiates and returns Part\Token objects.

protected getPartForToken(string $token, bool $isLiteral) : IHeaderPart|null

Tokens from this and sub-consumers are combined into a Part\CommentPart in processParts.

Parameters
$token : string
$isLiteral : bool
Return values
IHeaderPart|null

getTokenParts()

Returns an array of IHeaderPart for the current token on the iterator.

protected getTokenParts(Iterator<string|int, string> $tokens) : array<string|int, IHeaderPart>

If the current token is a start token from a sub-consumer, the sub- consumer's AbstractConsumerService::parseTokensIntoParts() method is called.

Parameters
$tokens : Iterator<string|int, string>

The token iterator.

Return values
array<string|int, IHeaderPart>

getTokenSeparators()

Returns patterns matching open and close parenthesis characters as separators.

protected getTokenSeparators() : array<string|int, string>
Return values
array<string|int, string>

the patterns

isEndToken()

Returns true if the token is a close parenthesis character, ')'.

protected isEndToken(string $token) : bool
Parameters
$token : string
Return values
bool

isStartToken()

Returns true if the token is an open parenthesis character, '('.

protected isStartToken(string $token) : bool
Parameters
$token : string
Return values
bool

parseTokensIntoParts()

Overridden to keep track of the current comment nesting depth.

protected parseTokensIntoParts(Iterator<string|int, string> $tokens) : array<string|int, IHeaderPart>
Parameters
$tokens : Iterator<string|int, string>
Return values
array<string|int, IHeaderPart>

processParts()

Post processing involves creating a single Part\CommentPart out of generated parts from tokens. The Part\CommentPart is returned in an array.

protected processParts(array<string|int, IHeaderPart$parts) : array<string|int, IHeaderPart>
Parameters
$parts : array<string|int, IHeaderPart>
Return values
array<string|int, IHeaderPart>

splitRawValue()

Returns an array of split tokens from the input string.

protected splitRawValue(string $rawValue) : array<string|int, string>

The method calls preg_split using AbstractConsumerService::getTokenSplitPattern(). The split array will not contain any empty parts and will contain the markers.

Parameters
$rawValue : string

the raw string

Return values
array<string|int, string>

the array of tokens

discardNestedComment()

Consumes tokens to the end of the current comment without recursing into it or constructing any parts for it.

private discardNestedComment(Iterator<string|int, string> $tokens) : array<string|int, IHeaderPart>

A CommentPart holds the full text of everything nested below it, and each level of recursion costs a stack frame, so an absurdly nested comment is expensive in both memory and depth. Past $maxCommentDepth the tokens are still consumed so the rest of the header parses normally, but nothing is built from them.

Parentheses inside a quoted string don't open or close a comment, and escaped characters arrive as two-character tokens, so neither is mistaken for a delimiter here.

Parameters
$tokens : Iterator<string|int, string>
Return values
array<string|int, IHeaderPart>

an empty array

parseRawValue()

Parses the raw header value into header parts.

private parseRawValue(string $value) : array<string|int, IHeaderPart>

Calls splitTokens to split the value into token part strings, then calls parseParts to parse the returned array.

Parameters
$value : string
Return values
array<string|int, IHeaderPart>

the array of parsed parts

Search results