Search code examples
shopwareshopware6

How to decorate the final class DocumentGenerator


I am having problems to decorate the final class "DocumentGenerator" (in vendor/shopware/core/Checkout/Document/Service/DocumentGenerator.php) and overwrite the "generate" function inside of it. I tried to decorate it the usual way, but an error is thrown because the "DocumentController" class excepts the original class and not my decorated one?

Argument 2 passed to Shopware\Core\Checkout\Document\DocumentGeneratorController::__construct() must be an instance of Shopware\Core\Checkout\Document\Service\DocumentGenerator

Its also not possible to extend from the class in my decorated class, because the "DocumentGenerator" is a final class.

My goal is to execute additional code, after an order document is generated. Previously I successfully used to decorate the "DocumentService" Class, but its marked as deprecated and shouldnt be used anymore. Also the "DocumentGenerator" class is used for the new "bulkedit" function for documents as of Version 6.4.14.0

I'm grateful for every tip.


Solution

  • As @j_elfering already wrote it's by design that you should not extend that class and therefore also shouldn't decorate it.

    To offer a potential alternative:

    Depending on what you want to do after a document has been generated it might be enough to add a subscriber to listen to document.written, check if it was a new document created and then work with the data from the payload for fetching/persisting data depending on that.

    public static function getSubscribedEvents()
    {
        return [
            'document.written' => 'onDocumentWritten',
        ];
    }
    
    public function onDocumentWritten(EntityWrittenEvent $event): void
    {
        foreach ($event->getWriteResults() as $result) {
            if ($result->getOperation() !== EntityWriteResult::OPERATION_INSERT) {
                // skip if the it's not a new document created
                continue;
            }
            
            $payload = $result->getPayload();
            // do something with the payload
        }
    }