cancel
Showing results for 
Search instead for 
Did you mean: 

JsFooterPlugin.php Error

SOLVED
Highlighted

JsFooterPlugin.php Error

We're running into an issue with JsFooterPlugin.php, which moves the site JS to the footer.

 

The error is: 

Uncaught TypeError: strpos() expects parameter 1 to be string, null given in /var/www/gl/magento/releases/20191107051759/vendor/magento/module-theme/Controller/Result/JsFooterPlugin.php:44

 

Looking at the source for JsFooterPlugin.php, it appears that $content should have the page source, but instead is null.

 

This happens sporadically when the Auctane ShipStation module is contacted through the Magento API (screenshot with the full stack trace) and during Amazon logout (screenshot). It doesn't happen during normal browsing of the site.

 

The obvious solution is to turn off dev/js/move_script_to_bottom; however, I'm thinking this is a symptom of a larger issue.

 

We're running Magento 2.3.3 Community Edition on PHP 7.3 / nginx / varnish.

 

A Google search for JsFooterPlugin.php came up with nothing, so I'm at a loss.

 

Any ideas would be greatly appreciated.

1 ACCEPTED SOLUTION

Accepted Solutions
Highlighted

Re: JsFooterPlugin.php Error

I've had a couple of people PM me with solutions to this issue. One was a patch that modifies 

vendor/magento/module-banner/view/frontend/web/js/model/banner.js

I'm not posting the patch, because I haven't tested it.

 

The other solution, which is what I went with, is to modify 

vendor/magento/module-theme/Controller/Result/JsFooterPlugin.php

and comment out the code that produces the error:

    public function beforeSendResponse(Http $subject)
    {
        // $content = $subject->getContent();
        // $script = [];
        // if (strpos($content, '</body') !== false) {
        //     if ($this->scopeConfig->isSetFlag(
        //         self::XML_PATH_DEV_MOVE_JS_TO_BOTTOM,
        //         ScopeInterface::SCOPE_STORE
        //     )
        //     ) {
        //         $pattern = '#<script[^>]*+(?<!text/x-magento-template.)>.*?</script>#is';
        //         $content = preg_replace_callback(
        //             $pattern,
        //             function ($matchPart) use (&$script) {
        //                 $script[] = $matchPart[0];
        //                 return '';
        //             },
        //             $content
        //         );
        //         $subject->setContent(
        //             str_replace('</body', implode("\n", $script) . "\n</body", $content)
        //         );
        //     }
        // }
    }
}

If you're getting frequent Marketplace Notification Failed (Server 500 Error) messages from your ShipStation integration, this may mitigate the issue until there is an official fix from Magento.

 

It worked for me.

View solution in original post

8 REPLIES 8
Highlighted

Re: JsFooterPlugin.php Error

Any success resolving this? Encountering it as well. And to my surprise, Moving JS to footer is already disabled, but it's still happening.

Highlighted

Re: JsFooterPlugin.php Error

Unfortunately, we haven't identified a solution yet. We also found that
disabling moving JS to the footer doesn't solve the issue.

I've had one other person PM me with the same problem.

When we do find a solution, I'll post it.

Highlighted

Re: JsFooterPlugin.php Error

I've had a couple of people PM me with solutions to this issue. One was a patch that modifies 

vendor/magento/module-banner/view/frontend/web/js/model/banner.js

I'm not posting the patch, because I haven't tested it.

 

The other solution, which is what I went with, is to modify 

vendor/magento/module-theme/Controller/Result/JsFooterPlugin.php

and comment out the code that produces the error:

    public function beforeSendResponse(Http $subject)
    {
        // $content = $subject->getContent();
        // $script = [];
        // if (strpos($content, '</body') !== false) {
        //     if ($this->scopeConfig->isSetFlag(
        //         self::XML_PATH_DEV_MOVE_JS_TO_BOTTOM,
        //         ScopeInterface::SCOPE_STORE
        //     )
        //     ) {
        //         $pattern = '#<script[^>]*+(?<!text/x-magento-template.)>.*?</script>#is';
        //         $content = preg_replace_callback(
        //             $pattern,
        //             function ($matchPart) use (&$script) {
        //                 $script[] = $matchPart[0];
        //                 return '';
        //             },
        //             $content
        //         );
        //         $subject->setContent(
        //             str_replace('</body', implode("\n", $script) . "\n</body", $content)
        //         );
        //     }
        // }
    }
}

If you're getting frequent Marketplace Notification Failed (Server 500 Error) messages from your ShipStation integration, this may mitigate the issue until there is an official fix from Magento.

 

It worked for me.

View solution in original post

Highlighted

Re: JsFooterPlugin.php Error

Commenting out the entire function seems a bit heavy handed. The issue here is that

 $subject->getContent() is returning "null" and the strpos function can only work with strings. I think a simpler solution (and one that should allow the functionality to work if you activate it) is to change line 42 from:

$content = $subject->getContent();

to

$content = $subject->getContent() ?: '';

So that if the function call returns null, it will get converted to an empty string and prevent the fatal error.

Highlighted

Re: JsFooterPlugin.php Error

I solved the issue just embedding $content in double quotes:

if (strpos($content, '</body') !== false) {

became

if (strpos("$content", '</body') !== false) {
Highlighted

Re: JsFooterPlugin.php Error

I can confirm the simple patch to core code of enclosing the $content in double quotes resolved the issue on my install of M2.3.4 in production.

 

Highlighted

Re: JsFooterPlugin.php Error

Highlighted

Re: JsFooterPlugin.php Error

This issue is already solved in the Magento 2.3.5 by replacing below line in the JsFooterPlugin.php file

 

From

if (strpos($content, '</body') !== false) {

To

if (is_string($content) && strpos($content, '</body') !== false) {