ZF-7544: Fatal Error when setting same FilterRule more than one time in script call

Description

  • multiple views via action helper and they ahve a context called dashboard, when I set the rule each call the Iflecetor throws an Fatal Error the second time I trya to set the same Rule

{color:red} "Fatal error: [] operator not supported for strings in[...]/library/Zend/Filter/Inflector.php on line 381"{color}

==================

 
$this->_helper->getHelper('viewRenderer')->getInflector()
                ->addFilterRule(':context' ,array('Word_CamelCaseToDash', 'StringToLower'))
                ->setStaticRuleReference('suffix'  , $this->_viewSuffix)
                ->setStaticRuleReference('context' , $this->_context)
                ->setTargetReference($this->_inflectorTarget)
            ;

Comments

Could solve that by checking if the Rule is set already, but solves not the problem, that "$this->_rules[$spec]" is a string not an array, second time.

 
if ($inflector->getRules('context') == false) {
            $inflector
                ->addFilterRule(':context' ,array('Word_CamelCaseToDash', 'StringToLower'));
        }
            $inflector
                ->setStaticRuleReference('suffix'  , $this->_viewSuffix)
                ->setStaticRuleReference('context' , $this->_context)
                ->setTargetReference($this->_inflectorTarget)
            ;

Set component and auto reassign

I'm unable to verify this issue with the given description. Using your description the following testcode makes no problems:


        $rules = $this->inflector->getRules();
        $this->assertEquals(0, count($rules));
        $this->inflector->setFilterRule('controller', 'PregReplace');
        $rules = $this->inflector->getRules('controller');
        $this->assertEquals(1, count($rules));
        $this->inflector->addFilterRule('controller', array('Alpha', 'StringToLower'));
        $rules = $this->inflector->getRules('controller');
        $this->assertEquals(3, count($rules));
        $this->inflector->setStaticRuleReference('context' , $this->_context);
        $this->inflector->addFilterRule('controller', array('Alpha', 'StringToLower'));
        $rules = $this->inflector->getRules('controller');
        $this->assertEquals(5, count($rules));

Could it be that you are using setStaticRule anywhere else in your code ? In this case I can verify the issue.

Fixed with r17697

In meantime I updated my wc to 1.9.1. I'll check if the problem still exist and if so I'll explain it more accurate.

ok ... it still exists. And it's not that easy to test.

Exlpaination:

Almost all of my action have multiple contexts belonging to what the user want to do with the 'data'. I have e.g. html, json, xml, pdf and one for another 'normal' view: dashboard, so that I can react on the context in dthe controller and use different views to present the data. Now I use the inflector in my extend of the Zend_Controller_Action to inflect the viewScrtipt target to organize my view files in subfolders.

The problem now is exactly the dashboard. In this view multiple actions will be processed by the action helper with the context dashboard, so the function will called each time a action helper runs and one time for the dashboard view itself. 1. call is ok (context == '') 2. call is ok (context == 'dashboard' ) 3. call is not ok (context == 'dashboard' ) => FATAL

this is my work around:


[...]
  /**
     * Inflector target
     * @var string
     */
    protected $_inflectorTarget = ':controller/:context:action.:suffix';
[...]

/**
     * sets the inflector for the viewRenderer in context mode
     * and give the view the context
     * @return void
     */
    protected function setContextInflector() {
        $currentContext = $this->getContext();
        $inflector = $this->_helper->getHelper('viewRenderer')->getInflector();
        $this->_context = ( $currentContext == '' || $currentContext == 'html' ) ? '' : $this->getContext(). '/';

        if ($inflector->getRules('context') == false) {
            $inflector
                ->addFilterRule(':context' ,array('Word_CamelCaseToDash', 'StringToLower'));
        }
            $inflector
                ->setStaticRuleReference('suffix'  , $this->_viewSuffix)
                ->setStaticRuleReference('context' , $this->_context)
                ->setTargetReference($this->_inflectorTarget)
            ;
        $this->view->currentContext = $currentContext;
    }
[...]

and so it does not work:


[...]
  /**
     * Inflector target
     * @var string
     */
    protected $_inflectorTarget = ':controller/:context:action.:suffix';
[...]

/**
     * sets the inflector for the viewRenderer in context mode
     * and give the view the context
     * @return void
     */
    protected function setContextInflector() {
        $currentContext = $this->getContext();
        $inflector = $this->_helper->getHelper('viewRenderer')->getInflector();
        $this->_context = ( $currentContext == '' || $currentContext == 'html' ) ? '' : $this->getContext(). '/';

        if ($inflector->getRules('context') == false) {
            $inflector
                ;
        }
        $inflector
            ->addFilterRule(':context' ,array('Word_CamelCaseToDash', 'StringToLower'))
            ->setStaticRuleReference('suffix'  , $this->_viewSuffix)
            ->setStaticRuleReference('context' , $this->_context)
            ->setTargetReference($this->_inflectorTarget)
        ;
        $this->view->currentContext = $currentContext;
    }
[...]

Dont hesitate to contact me if you need more informations.

without that part



 if ($inflector->getRules('context') == false) {
            $inflector
                ;
        }

How should that issue be fixed in ZF 1.9.1 when ZF 1.9.1 was build 1 week ago and I fixed that issue yesterday for 1.9.2 ?

Seems to be impossible in my eyes. :-)

Next MiniRelase means that the next upcomming Release will solve that problem. Fix is until then in core and not in downloadable release. And the next release will be ZF 1.9.2 in about 1-2 weeks.

One thing to note: When you add the same rules again to the inflector then they will be added as is. There is no way for the inflector to check if you want that filter to be executed 2 times or if you want to have it only one time.

This means that you will then have StringToLower and Word_CamelCaseToDash 2 times, in sum 4 filters and they will all be executed.

Ok, I'm sorry for the version thing, but ... I checked my problem against the trunk (with your changes) and ... :D ... it still exists. I'll attach a test package, so you can see, what's the problem. Ok?

without the lib ;)

It's still fixed for the next MiniRelease :D Update your trunk release ;-)

I checked out the whole trunk a hour ago ... so?

Must be a problem on your side.

I tested with your example code. I verified once again with r17716 (which is actual trunk). Your example produces something like #1 to #10 but does not fail with an exception like before.

Yes you'r right ... NOW it works. Interesting Diff ... (the second) ;)