Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Magento default controller action

How to create a function for every action? for example I have function:

 public function indexAction()
    {

        $this->loadLayout();     
        $this->renderLayout();
    }

but this is for action index, but what when I don't know action, or its created dynamiclly, so for example action could be controller/someaction, controller/someaction2 I would like to create default function which will handle this

like image 275
user2746186 Avatar asked Mar 07 '14 13:03

user2746186


2 Answers

I personally would do something like this:
1 - I would create an abstract class inheriting from Zend_Controller_Action like this:

<?php
abstract Class Yourlibrary_Controller_ControllerAbstract extends Zend_Controller_Action
{

    public function preDispatch()
    {
        $this->loadLayout();     
        $this->renderLayout();
    }

2 - My Controllers inherit Yourlibrary_Controller_ControllerAbstract not Zend_Controller_Action

I did in the preDispatch() but you can also do it in the postDispatch
You can also add variables and controllers use these variables execute the code or not

like image 150
doydoy44 Avatar answered Sep 28 '22 05:09

doydoy44


[EDIT]
This works for magento versions up to CE 1.7 and EE 1.12 (including these ones).
For later version you cannot use __call in controllers anymore.

[ORIGINAL ANSWER]

This is a very interesting question.
Here is a solution that works, but I don't know the full implications of it.
In php if you implement the __call method in a class, this one will be called when the method does not exist.

Here is an example:

class SomeClass {
    public function doSomething() {
        return "Doing something"; 
    }
    public function __call($function, $args){
         return "Still doing something even if you said ".$function;
    }
}

Based on the class above:...

$obj = new SomeClass();
echo $obj->doSomething(); //will output "Doing something" - because the method exists
echo $obj->doNothing(); //will output "Still doing something even if you said doNothing". 

Based on this, you can implement in your controller the method __call(), but you have to be careful. This will be called for everything that does not exist.
So you can try to filter the requested method to only those that end with Action.

Here is an example.

public function __call($function, $args){
    if (substr($function, -6) == 'Action') {
         $this->loadLayout('some_default_layout_handle');
         $this->renderLayout();
    }
    else {//otherwise throw an exeption
        throw new Exception ("Method {$function} cannot be called in ". __CLASS__);
    }
}

Now some explanations I used $this->loadLayout('some_default_layout_handle'); with a parameter because when calling just loadLayout Magento will load the <default> layout handle and the handle that corresponds to the action. But since your action can be almost anything, you cannot create a layout handle for each possible action.
This way you always load the same handle.

You can also change that to

$this->loadLayout(array('default','some_default_layout_handle'));

to load the <default> AND you custom layout handle.

Like I said, this seams to work but I don't know all it's implications.
I think you can get some errors if you have 2 extensions that rewrite (not extend!) the same controller, but not sure about it.

like image 21
Marius Avatar answered Sep 28 '22 05:09

Marius