Skip to content

M2.1.2 : Impossible to create an after interceptor when files are being downloaded by controllers #7356

@kanduvisla

Description

@kanduvisla

Preconditions

Magento - develop branch
Take the \Magento\Sales\Controller\Adminhtml\Shipment\PrintAction controller for example. This has an execute()-method which triggers a downloading to the browser.

Now if you want to do something after this event with a plugin, you're out of luck. Since this controller uses \Magento\Framework\App\Response\Http\FileFactory::create() to print the PDF.

And if you look closer in this code, you'll notice the following:

if ($content !== null) {
    $this->_response->sendHeaders();
    if ($isFile) {
        $stream = $dir->openFile($file, 'r');
        while (!$stream->eof()) {
            echo $stream->read(1024);
        }
    } else {
        $dir->writeFile($fileName, $content);
        $stream = $dir->openFile($fileName, 'r');
        while (!$stream->eof()) {
            echo $stream->read(1024);
        }
    }
    $stream->close();
    flush();
    if (!empty($content['rm'])) {
        $dir->delete($file);
    }
    $this->callExit();
}

This piece if code (especially the $this->callExit()) makes it impossible to use a plugin with after (or around partially), since it hard sends an exit code. That's right: $this->callExit() is equivalent for exit(0).

I suggest that this get handles differently because exiting the code in the middle of the Magento lifecycle doesn't seems right to me. Especially if it breaks functionality like this.

Steps to reproduce

Create a plugin that executes code after \Magento\Sales\Controller\Adminhtml\Shipment\AbstractShipment\PrintAction::execute(). For example:

<type name="Magento\Sales\Controller\Adminhtml\Shipment\PrintAction">
    <plugin name="after_print_shipment"
            type="VendorModule\Plugin\Magento\Sales\Controller\Adminhtml\Shipment\PrintAction"/>
</type>

code:

function afterExecute(\Magento\Sales\Controller\Adminhtml\Shipment\PrintAction $subject, $result) {
    echo 'x';
    die;
}

Expected result

See the 'x' in the browser

Actual result

It just starts downloading; Magento ignores the plugin.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Fixed in 2.2.xThe issue has been fixed in 2.2 release lineIssue: Clear DescriptionGate 2 Passed. Manual verification of the issue description passedIssue: Format is validGate 1 Passed. Automatic verification of issue format passedbug report

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions