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
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
$logger
protected
LoggerInterface
$logger
$maxHeaderTokenCount
protected
int
$maxHeaderTokenCount
Maximum number of tokens parsed from a single header value.
$partFactory
protected
HeaderPartFactory
$partFactory
used to construct IHeaderPart objects
$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
__construct()
public
__construct(LoggerInterface $logger, MimeTokenPartFactory $partFactory, QuotedStringConsumerService $quotedStringConsumerService[, int $maxCommentDepth = 32 ]) : mixed
Parameters
- $logger : LoggerInterface
- $partFactory : MimeTokenPartFactory
- $quotedStringConsumerService : QuotedStringConsumerService
- $maxCommentDepth : int = 32
Return values
mixed —__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
getTokenSplitPattern()
Returns a regex pattern used to split the input header string.
protected
getTokenSplitPattern() : string
The default implementation calls AbstractConsumerService::getAllTokenSeparators() and implodes the returned array with the regex OR '|' character as its glue.
Return values
string —the regex pattern
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