16

After we upgraded to PHP 5.5, we get the following error when adding a Website, Store or Store View. This bug is still present in Magento 1.9.0.1

Exception message: Deprecated functionality: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in app/code/core/Mage/Core/Helper/Abstract.php on line 238
Trace: #0 [internal function]: mageCoreErrorHandler(8192, 'preg_replace():...', 'app...', 238, Array)
#1 app/code/core/Mage/Core/Helper/Abstract.php(238): preg_replace('# <(?![/a-z]) |...', 'htmlentities('$...', 'New Store Name')
#2 app/code/core/Mage/Adminhtml/controllers/System/StoreController.php(175): Mage_Core_Helper_Abstract->removeTags('New Store Name')
#3 app/code/core/Mage/Core/Controller/Varien/Action.php(418): Mage_Adminhtml_System_StoreController->saveAction()
#4 app/code/core/Mage/Core/Controller/Varien/Router/Standard.php(250): Mage_Core_Controller_Varien_Action->dispatch('save')
#5 app/code/core/Mage/Core/Controller/Varien/Front.php(172): Mage_Core_Controller_Varien_Router_Standard->match(Object(Mage_Core_Controller_Request_Http))
#6 app/code/core/Mage/Core/Model/App.php(354): Mage_Core_Controller_Varien_Front->dispatch()
#7 app/Mage.php(686): Mage_Core_Model_App->run(Array)
#8 index.php(87): Mage::run('', 'store')
#9 {main}

This is the code which produces the error

The code can be found in Mage_Core_Helper_Abstract

/**
 * Remove html tags, but leave "<" and ">" signs
 *
 * @param   string $html
 * @return  string
 */
public function removeTags($html)
{
    $html = preg_replace("# <(?![/a-z]) | (?<=\s)>(?![a-z]) #exi", "htmlentities('$0')", $html);
    $html =  strip_tags($html);
    return htmlspecialchars_decode($html);
}

This is, in my opinion, the easiest patch for the method:

/**
 * Remove html tags, but leave "<" and ">" signs
 *
 * @param   string $html
 * @return  string
 */
public function removeTags($html)
{
    $html = preg_replace_callback("# <(?![/a-z]) | (?<=\s)>(?![a-z]) #xi",
        create_function('$matches', 'return htmlentities($matches);'),
        $html
    );
    $html =  strip_tags($html);
    return htmlspecialchars_decode($html);
}

The method is only used by the Mage_Adminhtml_System_StoreController::storeAction().

There are three possible places to fix it:

  1. Mage_Core_Helper_Abstract => that is where the method is located, but it sucks because it touches a core file.
  2. Rewrite Mage_Core_Helper_Abstract => it is an abstract class, so it shouldn't/cant't be rewritten.
  3. Rewrite Mage_Adminhtml_Helper_Data and add the method there. => I think this is the way to go.

What do you guys think?

  1. Is option #3 the correct way to fix the issue.
  2. Is the code in my patch correct?
  • Issue still exists in 1.9.1 CE and 1.14.1 EE – user20422 Jan 16 '15 at 19:55
13

Yes, you are right. Fix the adminhtml helper. This is the diff for the fix I use:

--- app/code/core/Mage/Core/Helper/Abstract.php.orig 2014-09-25 15:32:56.000000000 +0200
+++ app/code/core/Mage/Core/Helper/Abstract.php 2014-09-25 15:34:42.000000000 +0200
@@ -235,7 +235,9 @@
  */
 public function removeTags($html)
 {
-        $html = preg_replace("# <(?![/a-z]) | (?<=\s)>(?![a-z]) #exi", "htmlentities('$0')", $html);
+        $html = preg_replace_callback("# <(?![/a-z]) | (?<=\s)>(?![a-z]) #xi", function($matches) {
+            return htmlentities($matches[0]);
+        }, $html);
         $html =  strip_tags($html);
         return htmlspecialchars_decode($html);
 }

This is a test to confirm the behavior is the same as with php 5.4:

<?php

namespace Vinai\Kopp\Magento\Tests;

class MageAdminhtmlHelperDataTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @var \Mage_Adminhtml_Helper_Data
     */
    private $helper;

    static public function setUpBeforeClass()
    {
        ini_set('display_errors', 1);
        umask(0);
        error_reporting(E_ALL);
        require_once 'app/Mage.php';
        \Mage::setIsDeveloperMode(true);
    }

    public function setUp()
    {
        $this->helper = new \Mage_Adminhtml_Helper_Data();
    }

    /**
     * @covers \Mage_Core_Helper_Abstract::removeTags
     * @dataProvider removeTagsDataProvider
     */
    public function testRemoveTags($inputHtml, $expected)
    {
        $result = $this->helper->removeTags($inputHtml);
        $this->assertEquals($expected, $result);
    }

    public function removeTagsDataProvider()
    {
        return array(
            array('<b>', ''),
            array('<b> >', ' >'),
            array('<b> <', ' <'),
            array('<b/> </', ' '),
            array('< <b/>', '< '),
            array('> <b/>', '> '),
            array('</ <b/>', ''),
            array('x />', 'x />'),
            array('> <', '> <'),
            array('>>', '>>'),
            array('<<', '<<'),
            array('<>', '<>'),
        );
    }
} 
4

This is now fixed in Magento EE 1.14.1 and 1.9.1. Additional incompatibility is pack()/unpack() changes which affects Backup/Rollback and some extensions during installation - anything that touches tar files. I assume anyone who is running Magento in production is not using those.

3

Short answer: Magento is not PHP 5.5 compatible, don't update your webserver to 5.5.

Longer answer: I would assume, Magento fixes this bug with the next version, so I would just make a core hack and hope the best. I don't know whether the code is correct, sorry.

  • Hi Fabian, we run all our servers on PHP 5.5 for quite some time now. This is the first problem I ever encountered. Which other known incompatibilities exist or where does this information come from? – RobM84 Oct 13 '14 at 19:40
  • 1
    tbh I have no idea. You can just check the changelog php.net/manual/en/migration54.php and grep for the methods and ini settings – Fabian Blechschmidt Oct 13 '14 at 21:33
  • 1
    actually this is the only PHP 5.5 problem in magento CE, we did not hit another in the last half year running on it – Flyingmana Oct 14 '14 at 18:23
  • 2
    also thats a really bad advice, as 5.3 is way outdated, php 5.4 never hit a real stable state as most people use it with APC, 5.5 is currently the only minimum stable supported PHP version availabil, not mentioning all the security fixes which are not included in older PHP versions – Flyingmana Oct 14 '14 at 18:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.