views:

130

answers:

4

I want to extend Zend_Controller_Action so I can have messaging be universal. Right now in the preDispatch() I am setting all the error and warning messages. How can I make the AddMessage (see code) and preDispatch functions be universal throughout all controllers?

<?php

class PlaygroundController extends Zend_Controller_Action {

public function init()
{
    /* Initialize action controller here */
}

public function preDispatch()
{
    $flashMessenger = $this->_helper->FlashMessenger;

    $flashMessenger->setNamespace('Errors');
    $this->view->Errors = $flashMessenger->getMessages();

    $flashMessenger->setNamespace('Warnings');
    $this->view->Warnings = $flashMessenger->getMessages();

    $flashMessenger->setNamespace('Messages');
    $this->view->Messages = $flashMessenger->getMessages();

    $flashMessenger->setNamespace('Success');
    $this->view->Success = $flashMessenger->getMessages();

}

protected function AddMessage($message,$type='Errors') {
    $flashMessenger = $this->_helper->FlashMessenger;
    $flashMessenger->setNamespace($type);
    $flashMessenger->addMessage($message);
}

public function flashAction()
{
    $this->AddMessage('This is an error message');
    $this->AddMessage('This is another error message');
    $this->AddMessage('This is a warning message','Warnings');
    $this->AddMessage('This is message','Messages');
    $this->AddMessage('This is another success message','Success');
}

}

+2  A: 

I don't really have any ZF experience, but I can't imagine why the following wouldn't work:

abstract class Zend_Controller_MyAction extends Zend_Controller_Action
{
  public function preDispatch()
  {
  ...
  }

  protected function addMessage ($message, $type='Errors')
  {
    ....
  }
  //... other common methods
}

Then your PlaygroundController will extend Zend_Controller_MyAction instead of Zend_Controller_Action.

grossvogel
I think that would work, but I'm trying to figure out where it should go haha. That is usually the issue with ZF haha
Brendan
Yeah, I was thinking back and realized you probably have to be really careful with naming and directories to get the autoloading and everything to work correctly... sorry if this is no help.
grossvogel
+1  A: 

See my related question: Correct Location for Custom Zend_Action_Controller

I've just ended up putting it under library/APPNAMESAPCE/Action/Contoller and throw this in application.ini:

autoloadernamespaces.APPNAMESPACE = "APPNAMESPACE_"
appnamespace = "APPNAMESPACE_"

Obviously, APPNAMESPACE should be replaced my the namespace of your application. You should already have the second line to autoload the models/forms/etc.

I also use the library/APPNAMESPACE/ for any other application specific subclasses of standard Zend Framework classes.

Update: Using a plug is has been suggested, and certainly seems like a good idea for this use case. Guess where I keep my application specific plugins?

library/APPNAMESPACE/Action/Contoller/Plugin

Of course if this is a plugin you'll be using for more than one application, it would make sense to put that in a common library.

Tim Lytle
It should probably go under /application/models.... and "APPNAMESPACE" should not be capitalized. According to Zend guidelines, only the first letter of a namespace qualifier is capitalized, even for initialisms and acronyms (i.e. HTML or REST)
Billy ONeal
`APPNAMESPACE` was simply a placeholder, in all caps so it wouldn't be mistaken for a real 'namespace'. And I really don't get putting subclasses in the models directory, that just seems to be the place for *data* models. But that's just me. I also like being able to just replace `Zend` with the application name I'm using: `Zend_Controller_Action` becomes `APPNAMESPACE_Controller_Action` (again with the placeholder there).
Tim Lytle
@Iznogood Thanks for the edits - was a bleary eyed copy and paste.
Tim Lytle
@Tim Lytle no problems! I do that ALL THE TIME (typo`s).
Iznogood
+2  A: 

You could move those two into a model, and inject the PreDispatch event using a Zend_Controller_Front plugin.

Billy ONeal
+1 For this case a plugin certainly seems the way to go, but why not just a `Zend_Controller_Plugin`?
Tim Lytle
@Tim: AFAIK, you can't hang a random method off a plugin and make it available to action controllers. But I'm not positive.
Billy ONeal
Ah, yes, wasn't fully tracking what he is doing. Yeah, no way to add a function to the action controller.
Tim Lytle
@Billy ONeal - then again, we can rely on controller helpers, for injecting custom functionality to our controllers.
Victor Farazdagi
@Victor: I don't believe I said anything against helpers...
Billy ONeal
@Billy ONeal Sorry, used wrong name :) was referring to @Tim's second comment actually. Meaning there IS a way to inject custom functionality into controllers.
Victor Farazdagi
A: 

You have to subclass Zend_Controller_Action:

//library/My/Controller/Action.php
class My_Controller_Action extends Zend_Controller_Action
{
...
}

then

class IndexController extends My_Controller_Action
{
...
}

Alternatively, you may put Zend Framework in somewhere outside the project, and then overload Zend_Controller_Action class putting it in /library dir, which will be read before the Zend library.

Having answered your question, my advice is, you should avoid doing this.

In this case the best solution seems to be writing custom flashMessenger. E.g. Take a look at this one:

Zend Framework: View Helper Priority Messenger | emanaton

takeshin