Understanding the boot loader

Introduction

OpenCart has became a very useful eCommerce framework for small to medium level online stores. Although it provides comprehensive features in its stack, it maintains a simple framework, with a nice modular architecture that can be extended. In this article, we'll focus on certain elements of the bootstrapping process.

Although there are lots of components which are involved in the typical bootstrapping process, we'll focus on the Registry and Loader objects for the course of this tutorial. The code snippets explained in this article belong to OpenCart version 2.0.x. Although the Registry class code is the same in versions 1.5.x and 2.0.x, the Loader class code has changed a lot. So we'll focus on the 2.0.x version of OpenCart.

The Registry Object

As the name suggests, the Registry object is used to store elements, from simple variables to complex objects, when the set method is called. It stores all the elements using key, so later on they can be accessed easily when the get method is called.

Let's have a closer look at the class file itself. Open the file located at system/engine/registry.php in your favorite text editor!

<?php
final class Registry {
  private $data = array();

  public function get($key) {
    return (isset($this->data[$key]) ? $this->data[$key] : null);
  }

  public function set($key, $value) {
    $this->data[$key] = $value;
  }

  public function has($key) {
    return isset($this->data[$key]);
  }
}

As you can see, the class definition is fairly simple to understand. It stores everything in the data property of the object, which is declared as an array, and the scope is private. In the get method, it checks whether value is available for the desired key, and it returns the value if it's available, and null otherwise. In the set method, it inserts the new element into the data array using the arguments passed to the method. Finally, it provides the has method to check if a certain key is already set into the data array.

Now, let's see how the OpenCart framework uses the registry object during the initial phase of the page execution. Open the index.php file in the document root of OpenCart. You'll see the $registry object is created very early in the script execution.

// Registry
$registry = new Registry();

After the creation of the $registry object, it stores several other objects using the set method. Let's see a couple of examples.

<?php
// Loader
$loader = new Loader($registry);
$registry-­>set('load', $loader);

// Config
$config = new Config();
$registry-­>set('config', $config);

// Database
$db = new DB(DB_DRIVER, DB_HOSTNAME, DB_USERNAME, DB_PASSWORD, DB_DATABASE);
$registry-­>set('db', $db);

// Request
$request = new Request();
$registry-­>set('request', $request);

// Session
$session = new Session();
$registry-­>set('session', $session);

I've listed here some example usages of the $registry object. As you may have noticed, frequently used objects are created and stored in the registry. The reason is that you don't have to instantiate common class objects multiple times, so you could simply call the get method of the $registry object to use the desired object. The approach is somewhat similar to the Singleton Pattern, in which you're forced to keep a single instance of the class.

Now, the $registry object is populated with useful stuff, but how is it used? Let's see how the $db object stored in the $registry is used in the Activity model of the Account module. Open the file located at catalog/model/account/activity.php. You can see that in the addActivity method, an insert query is fired.

$sql = sprintf("
    INSERT INTO %s
    SET `customer_id` = '%s', 
        `key` = '%s', 
        `data` = '%s',
        `ip` = '%s', 
        `date_added`= %s
    ", 
    DB_PREFIX . 'customer_activity', 
    (int) $customer_id,
    this->db->escape($key),
    $this->db->escape(serialize($data)),
    $this->db->escape($this->request->server['REMOTE_ADDR']),
    NOW()
);

$this->db->query($sql);

You may wonder about the way it's called, as there is no db method or property defined in the ModelAccountActivity class. You can go to the parent model class Model to see if it's defined there or not. Yeah, you won't find a db method or property in that class either. But if you look closely at the Model class, you'll see that it implements the magic methods, specifically the __get method in this case.

public function __get($key) {
  return $this->registry->get($key);
}

For now, let's assume that the $registry object is stored in the protected registry property of the Model class. We'll see how it's stored when Model is instantiated in the Loader class.

The __get method is called when you call any method which is not defined in the class. In this method, db is passed as an argument as we are trying to call $this-­>db in the activity.php file. And as discussed earlier, $registry has all the utility objects already stored during the bootstrapping process. So we just need to fetch the db object using the key by calling the get method of the Registry object!

In the same way, $this­->load works from the controller files as well. So overall, Registry is a really useful component of the OpenCart framework which stores commonly used variables and objects, which are used throughout the script execution.

The Loader Object

The Loader object is used to load the different components of OpenCart as required, like model, controller, language, view, library, etc. It's important to note here that when the Loader object is created, it is stored in the $registry object with load as an array key. So you can access the $loader object by using a $this­->load call as explained in the above section.

// Loader instantiation
$loader = new Loader($registry);
$registry-­>set('load', $loader);

Now, let's see how different components are loaded using the Loader. Open system/engine/loader.php to see the definition of a Loader class. We'll start with the controller method to understand how it works.

// load controller
$this->load->controller('common/column_left');

It's a code snippet which loads the common/column_left.php controller and calls the index method as well. We make this call to get the XHTML output of the Left Column of the OpenCart page. The $this­->load part works similar to the $this­->db example which I explained earlier! Thus, it returns the $loader object stored in the $registry, and finally it'll call the controller method of the Loader class!

In the same way, the following snippets work to load different components.

// load Model
$this-­>load-­>model('catalog/category');

// load View
$this­->load-­>view('default/template/product/category.tpl', $data);

// load Library
$this­->load-­>library('user');

// load Helper
$this­->load-­>helper('json');

// load Language
$this­->load-­>language('product/category');

Looking at the method definitions in the Loader class, you'll see that it's not that complicated to understand exactly how it works. First, it prepares the file path for the corresponding component, and it's included using the include_once function.

Overall, Registry and Loader are two very important components in the OpenCart framework which make things a lot easier for module developers.

Conclusion

So today, we looked at the Loader and Registry components of the OpenCart framework. I hope you've learned something useful in this tutorial. And hopefully, I'll come up with something more on the same topic! Submit your queries and suggestions using the feed below!

Original article: link by Salja Soni

Last update: August 27th at 10:58am