diff --git a/index.md b/index.md index d87478c3..9942a245 100644 --- a/index.md +++ b/index.md @@ -49,7 +49,7 @@ manipulation routines. use ZBateson\MailMimeParser\Message; $message = Message::from($handleOrStreamOrString, true); -$subject = $message->getHeaderValue('Subject'); +$subject = $message->getSubject(); $text = $message->getTextContent(); $html = $message->getHtmlContent(); $from = $message->getHeader('From'); @@ -108,7 +108,7 @@ There are numerous advantages over other libraries: * PSR-compliant, unit and functionally tested. -## Usage Guide +## Previous Versions > For the 0.4 usage guide, [click here](usage-guide-0.4.html) > For the 1.0 usage guide, [click here](usage-guide-1.0.html) @@ -264,6 +264,41 @@ echo $htmlStream->getContents(); echo $message->getHtmlContent(); ``` +### Error reporting and logging + +Some basic logging has been added, and a logger can be provided either globally +or to an instance of MailMimeParser. + +```php +use ZBateson\MailMimeParser\MailMimeParser; +use ZBateson\MailMimeParser\IMessage; +use Monolog\Logger; +use Monolog\Handler\StreamHandler; + +$logger = new Logger('mail-parser'); +$logger->pushHandler(new StreamHandler(__DIR__ . '/mmp.log', 'debug')); + +// set it globally, calling new Message() would use the 'globally-provided' +// LoggerInterface +MailMimeParser::setGlobalLogger($logger); + +// or set it on an instance, any instances created through this via parsing, +// etc... would use the provided logger, but calling 'new Message()' yourself +// would require passing it manually +$parser = new MailMimeParser($logger); + +$message = Message::from($string, false); +``` + +[IMessagePart](api/3.0/classes/ZBateson-MailMimeParser-Message-IMessagePart.htmlIMessagePart) (and therefore all interfaces that inherit from it, IMimePart IMessage), +[IHeader](api/3.0/classes/ZBateson-MailMimeParser-Header-IHeader.html), and +[IHeaderPart](api/3.0/classes/ZBateson-MailMimeParser-Header-IHeaderPart.html) all inherit from +[IErrorBag](api/3.0/classes/ZBateson-MailMimeParser-IErrorBag.html). Errors that occur on any child can be inspected at the top-level IMessage with a call to +[IErrorBag::getAllErrors()](api/3.0/classes/ZBateson-MailMimeParser-IErrorBag.html#method_getAllErrors) which will return all +[Error](3.0/classes/ZBateson-MailMimeParser-Error.html) objects that have occurred. Optionally passing 'true' to validate getAllErrors may perform additional +validation on objects, and a PSR level can be provided to retrieve objects logged at different levels. The Error class has a 'getObject()' method to retrieve the +object the error occurred on (helpful if calling getAllErrors at a top-level, and you want to know which object it actually occurred on). + ## API Documentation * [Current (3.0)](api/3.0) * [2.4](api/2.4) diff --git a/upgrade-3.0.md b/upgrade-3.0.md index 6a07e783..70698550 100644 --- a/upgrade-3.0.md +++ b/upgrade-3.0.md @@ -1,6 +1,101 @@ -[Home](/) - [Sponsors](/#sponsors) - [API Documentation](api/3.0) - [Contributors](/#contributors) +[Home](/) - [Sponsors](/#sponsors) - [API Documentation](api/3.0) - [Upgrading to 3.0](upgrade-3.0) - [Contributors](/#contributors) # Upgrading to 3.0 -Coming soon. +Changes in 3.0 concentrate mostly on additions to error reporting, logging, +updating the dependency injection library used, and migrating to php8+. Basic +usage hasn't changed, but more advanced header inspection has: specifically +changes to HeaderPart classes, GenericHeader::getValue has changed to return the +concatenated value of all child parts, rather than the value of the first part +(this applies to any header that doesn't have a more specialized header type -- +not an address, date, id, parameter, received or subject header). +For header parts, please inspect the documentation for that when upgrading, +there are many changes there, mostly structurally to support error reporting: + +* Creating a HeaderPart out of tokens is now done in header parts so errors can + be kept against the specific parts. +* There is no longer a LiteralPart, instead there is a ContainerPart which + serves as a container for other parts, allowing a full introspection of errors + that occur on it or any child parts. +* There is no longer a MimeLiteralPart, instead there is a MimeToken which + represents a single mime header token. +* Comments are generally parsed into a HeaderPart, so for instance in a + parameter header, Content-Type: text/html; (a comment)name=value, the comment + is part of the "name=value" parameter part, and further part of the "name" + part. +* Created IHeader::getAllParts which returns all parts and which may include + comment parts (although in most cases those comment parts are part of other + ContainerParts as mentioned). IHeader::getParts stays the same although the + number and types of parts returned may be different. + +Here's a detailed list of changes: + +* Logging support, pass in a LoggerInterface to the constructor or call + MailMimeParser::setGlobalLogger. Not much is actually logged at this point + (please submit pull requests to add useful log messages) + +* ErrorBag class -- most user classes extend ErrorBag which allows classes to + keep track of errors by calling addError, and users to call getErrors or + getAllErrors (to include errors in child classes). + + Additional validation on objects is not performed, but can be done by passing + 'true' as the validate parameter on getErrors/getAllErrors. By default only + errors encountered without additional validation are added. + + See IErrorBag class for documentation. + +* Added an AbstractHeader::from which returns IHeader objects from a passed + header line, or header name/value pair. Static method can be called on a + sub class which returns its type, for example AddressHeader::from would return + an AddressHeader regardless of the name parameter or name of header in the + passed line. + +* If ParserManagerService can't find a parser for a PartBuilder, + CompatibleParserNotFoundException will be thrown. This would only happen if + customizing the used parsers passed on to ParserManagerService since the + default set includes a 'catch-all' with NonMimeParserService. + +* protected AbstractHeader::setParseHeaderValue renamed to parseHeaderValue, and + signature changed. + +* Can look up comment parts in headers -- use IHeader::getAllParts to return all + parsed parts including comment parts, or + +* GenericHeader getValue returns a string value of the combination of all its + non-comment parts. This applies to any header that doesn't have a more + specialized header type (not an address, date, id, parameter, received or + subject header), see HeaderFactory docs for specifics. + +* IHeader now has a getComments() method that returns a string array of + comments. ReceivedHeader no longer has protected members $comments and + $date ($date is now private -- still has AbstractHeader::getComments(), and + ReceivedHeader::getDateTime()), and added getAllParts which includes comments. + +* Switched to PHP-DI, users can provide a array|string|DefinitionSource to + override definitions + - Renamed service classes to clarify: + o AbstractParser -> AbstractParserService + o HeaderParser -> HeaderParserService + o IParser -> IParserService + o MessageParser -> MessageParserService + o MimeParser -> MimeParserService + o NonMimeParser -> NonMimeParserService + o ParserManager -> ParserManagerService + o All consumer classes, e.g. AbstractConsumer -> AbstractConsumerService + +* Refactored Header classes to depend on their respective IConsumerService + classes they need + +* Refactored ConsumerService classes to define which sub-ConsumerService classes + they depend on. Removed ConsumerService. + +* Refactored HeaderPart classes with the following goals: + - Token classes to be used by Consumers to convert from a string to a "part". + - When processing a part, consumer may combine them into a 'ContainerPart' + array to return to a header. + - Non-Token classes are "ContainerParts" and contain other HeaderParts. + - When constructing a ContainerPart, other HeaderParts can become children of + it. + - HeaderPart is an ErrorBag, so it and all its children can report errors up + the chain all the way to Message.