В OpenCart, можно получить доступ ко всем основным объектам из любой точки приложения (из любого другого объекта). Для этого используется класс-регистратор Registry (файл system\engine\registry.php).
Экземпляр данного класса создается первым, еще на этапе загрузки приложения, перед созданием остальных служебных объектов, в файле system\framework.php
$registry = new Registry();

Далее, все создаваемые объекты библиотек регистрируют свой экземпляр класса в регистраторе. Например объект класса Event (для работы с событиями):
$event = new Event($registry);
$registry->set('event', $event);

Таким образом, позже, обратившись к регистратору из другого класса, можно получить любой объект, который был зарегистрирован. Для этого, только, нужно не терять связь с самим регистратором. Для этого, при создании служебных объектов, в метод конструктора передается объект класса регистратора:
class Event {
    protected $registry;

    public function __construct($registry) {
        $this->registry = $registry;
    }
…

Только на словах понять новичку будет трудно, поэтому я написал УПРОЩЕННЫЙ пример. Доступ к другим служебным объектам в OpenCart часто используется в работе контроллеров. Поэтому в примере я использовал принцип работы модели MVC, примерно как это делается в данном фреймворке.

Можно скачать небольшой архив с файлами для тестирования, чтобы не набирать указанный ниже код вручную.

Файл index.php
/*
 * Класс-регистратор, который сохраняет в свойстве $data
 * экземпляры других служебных классов для доступа к любому из них
 * из любой точки приложения.
 * 
 * Для доступа к регистру, такие классы, при создании объекта,
 * получают аргументом для метода-конструктора экземпляр данного класса:
 * protected $registry;
    function __construct($registry) {    
        $this->registry = $registry;
    }
 */
class Registry{
    private $data = array();
    function set($key,$obj){
        if (!$this->has($key)){
            $this->data[$key] = $obj;
        }
    }
    function get($key){
        return $this->data[$key];
    }
    public function has($key) {
        return isset($this->data[$key]);
    }
}
$registry = new Registry();

/*
 * Тестовый класс для демонстрации доступа к его свойствам/методам 
 */
class Request{
    public $language = 'ru';
    function get(){
        return $this->language;
    }
}
$request = new Request();
/*
 * Все объекты, к которым нужен доступ из других классов, передаем в регистратор
 * в формате ключ/экземпляр класса
 */
$registry->set('request', $request);


/*
 * Класс для удобного доступа к элементам MVC (модель/вид/контроллер)
 */
class Loader{
    protected $registry;
    function __construct($registry) {
        $this->registry = $registry;
    }
    function controller($name, $action='index'){
        $file  = './controllers/' . $name . '.php';
        if (is_file($file)){
            require_once $file;
            $controller = new $name($this->registry);
            return $controller->$action();
        }
    }    
    function model($name){
        $file  = './models/' . $name . '.php';
        if (is_file($file)){
            require_once $file;
            return new $name($this->registry);
        }
    }
    function view($name, $date){
        $file  = './views/' . $name . '.php';
        if (is_file($file)){
            ob_start();
            require_once $file;
            return ob_get_clean();
        }
    }
    /*
     * Метод, подключающий языковой файл в зависимости от текущего языка
     * Для примера, текущий язык берем из объекта Request
     */
    function language($name){
        /*
         * Таким образом можем получить данные из любого объекта, который внесен
         * в регистратор. Просто передаем ключ нужного объекта.
         */
        $request = $this->registry->get('request');
        $default = $request->get();
        $file  = './language/' . $default . '/' . $name . '.php';
        if (is_file($file)){
            require_once $file;
            return isset($_) ? $_: null;
        }    
    }    
}
$loader = new Loader($registry);
$registry->set('loader',$loader); //так же передаем в регистратор

/*
 * В реальном приложении вызов определенного контроллера происходит после 
 * разбора текущего URL. Для упрощения - вызовем сразу FunController.
 */
$output = $loader->controller('FunController');
echo $output;

В данном файле у нас упрощенная реализация того, что происходит в файле framework.php OpenCart.
Классы (для простоты примера) я не стал разбивать на отдельные файлы. То есть – первым создаем экземпляр класса регистратора, а далее передаем ему каждый из служебных классов, доступ к которому нам понадобится в дальнейшем. Соответственно, чтобы из других объектов была возможность обратиться к одному и тому же объекту класса регистратора, при создании этих объектов – передаем методу конструктору этих классов, объект- регистратор.
Так же, тут приведена работа загрузчика реализованная в OpenCart (класс Loader), который активно применяется в контроллерах для получения доступа к основным компонентам MVC – моделям, видам ну и языковым файлам.
Загрузчик позволяет динамически создавать экземпляры классов, которые нужно вызвать, одновременно передавая в их метод-конструктор объект-регистратор. С помощью загрузчика, так же, легче/нагляднее получить доступ к другому служебному объекту, с которыми он работает (методы загрузчика соответствуют классам, объекты которых создаются в этих методах).



Например получаем класс нужной модели:
$model = $this->loader->model('FunModel');

Без использования загрузчика, из контроллера или модели, обратиться к другому объекту можно так, как продемонстрировано в методе language() класса Loader:
- получаем объект нужного класса (например 'request')
$request = $this->registry->get('request');
- далее вызываем нужный метод или свойство
$default = $request->get();

В конце, для тестирования, вызван контроллер 'FunController' который, в своих методах, использует работу с объектом-регистратором.
Результат работы выводим на экран, должно отобразиться:
Fun
русский

Первое значение получено с использованием модели, второе – языкового файла.
Далее привожу код остальных файлов с комментариями. Разместить их следует в указанных папках. Будут вопросы – задавайте.


Файл controllers\FunController.php
<?php
class Controller{
    protected $registry;
    function __construct($registry) {
        $this->registry = $registry;
    }
    /*
     * Используем "магический" метод __get для перенаправления к методу get()
     * класса регистратора (Registry)
     */
    function __get($name) {
        return $this->registry->get($name);
    }
}

class FunController extends Controller {
    function index(){
        /*
         * Формируем общий массив для данных, которые будут передаваться в
         * файл-представление для использования
         */
        $date = [];
        /*
         * Т.к. у класса FunController нет свойства loader, будет вызван
         * метод __get() родительского класса Controller, который строкой
         * $this->registry получает объект регистратор, сохраненный в свойстве
         * $registry при создании объекта FunController. А уже регистратор, используя
         * метод get() возвращает объект класса Loader, у которого вызывается 
         * запрашиваемый метод model('FunModel').
         */
        $model = $this->loader->model('FunModel');
        $date['text'] = $model->index();

        $language = $this->loader->language('lang');
        $date['lang']  = $language['title'];
    
        $view = $this->loader->view('FunView',$date);
        return $view;
    }
}

Файл models\FunModel.php
<?php
class Model{
    protected $registry;
    function __construct($registry) {
        $this->registry = $registry;
    }    
    function __get($name) {
        return $this->registry->get($name);
    }
}

class FunModel extends Model{
    function index(){
    //Допустим модель обработала данные и должна вернуть в качестве рез-та "Fun"
    return "Fun";
    }
}

Файл language\ru\lang.php
<?php
$_['title'] = 'русский';

Файл language\en\lang.php
<?php
$_['title'] = 'english';

Файл views\FunView.php
<h2><?=$date['text']?></h2>
<h3><?=$date['lang']?></h3>