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.
Solved! Go to Solution.
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.
Any success resolving this? Encountering it as well. And to my surprise, Moving JS to footer is already disabled, but it's still happening.
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.
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.
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.
I solved the issue just embedding $content in double quotes:
if (strpos($content, '</body') !== false) {
became
if (strpos("$content", '</body') !== false) {
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.
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) {