If you've come across module development in OpenCart, you may have faced the situation in which you've declared a couple of common elements in each and every controller. Don't you think that it would be nice if you could declare the common code somewhere and it's picked up as needed! So in this article, we're going to discuss how to set up common controller code and use that across the modules.
For those who are familiar with module development in OpenCart, it's a routine to set up the common elements like header, footer and sidebar columns in the index method of the controller class. Although there are different ways to centralize the common code, we'll look at an OpenCart way to accomplish this!
I assume that you're using the latest version of OpenCart and are familiar with the module development process, as we'll concentrate more on the concept rather than discussing the basic code.
Set Up the Common Controller Code
Go ahead and create the catalog/controller/preactiondemo
directory. Create a file common.php
under that directory with the following contents.
<?php class ControllerPreactiondemoCommon extends Controller { public function setup($args) { // do the pre-processing here $data['header'] = $this->load->controller('common/header'); $data['footer'] = $this->load->controller('common/footer'); $data['preaction_text'] = "I've been set by the 'setup' method from 'common' controller file."; $args['controller']->$args['method']($data, FALSE); } }
Fairly easy and straightforward to understand! It just initializes a couple of variables in the $data
array, except the last line of the setup
method. We'll get back to that later, as it will reveal the secret of the $args
array.
Understand the Dispatch Process
Before we create any further code, I'll give you a quick explanation of how dispatching works in OpenCart.
Whenever the user accesses any URL in OpenCart, the corresponding action object is instantiated based on the route query string variable. Here's the snippet from index.php
.
// Router if (isset($request->get['route'])) { $action = new Action($request->get['route']); } else { $action = new Action('common/home'); }
And following that, the dispatch
method is called.
$controller->dispatch($action, new Action('error/not_found'));
It’ll call the dispatch
method defined in the file located at system/engine/front.php
. In that method, you’ll find a snippet which executes the while loop until it gets the $action
value set to false.
while ($action) { $action = $this->execute($action); }
As you can see, it’ll call the execute method defined in the same file until $action
evaluates to false. This means that if the method of the controller returns an action object, OpenCart will execute that action before proceeding further. We could take advantage of this and call the other action from within the action itself. Let’s see how to accomplish that!
Call the Common Controller and View Setup
Now, let's create a preaction_demo.php
file under the preactiondemo
directory with the following contents.
<?php class ControllerPreactiondemoPreactionDemo extends Controller { public function index($data=array(), $flag=TRUE) { if ($flag) { return new Action('preactiondemo/common/setup', array('controller' => $this, 'method'=>'index')); } if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/preactiondemo/preaction_demo.tpl')) { $this->response->setOutput($this->load->view($this->config->get('config_template') . '/template/preactiondemo/preaction_demo.tpl', $data)); } else { $this->response->setOutput($this->load->view('default/template/preactiondemo/preaction_demo.tpl', $data)); } } }
If $flag
is true, we’ll return the instance of the action class, and as we’ve just seen, if the dispatch process receives an action object, it’ll continue with that action. So in this case, it will call the setup
method of the common
controller. Recall the common.php
file which we created in the earlier section.
The important thing to note is that we’re passing array('controller' => $this, 'method'=>'index')
as an argument, which will be eventually passed to the first argument of the setup
method in the common
controller. It’ll help us to get back to the index
method of the preaction_demo
controller after initialization of variables.
Further, in the setup
method we’ve defined a few common variables like header, footer, etc. And finally, we’re transferring control back to the original controller from where the setup
method was called using the following statement.
$args['controller']->$args['method']($data, FALSE);
Of course, we need to pass the variables initialized in the setup
method via $data
to the original controller so that it can be utilized there, which is the main purpose of this article. It’s passed as the first argument of the above method call. The second argument is very important as it’ll be initialized to the $flag
variable. We’re deliberately doing this to avoid infinite looping.
Finally, let’s go ahead and set up our view file at catalog/view/theme/default/template/preactiondemo/preaction_demo.tpl
with the following code.
<?php echo $header; ?> <div class="container"> <div class="row"> <?php echo $preaction_text; ?> </div> </div> <?php echo $footer; ?>
Now that we've finished with the setup, go ahead and open the URL http://youropencartstoreurl/index.php?route=preactiondemo/preaction_demo in your browser. You should see the message "I've been set by the 'setup' method from the 'common' controller file." in that page!
So, in this way you could set up the common code in one place, and call that action from the other controllers. Certainly, it’ll avoid code duplication, and it’s easier to change the code which is common across the modules.
Conclusion
Today, you’ve learned a cool trick in OpenCart: how to call an action from within the action! Of course, there are other ways to achieve that, but it’s something I’ve got in my mind lately and thought I should share it with you and get your feedback!
Comments