Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Events: changing data, output and arguments

A handler does not only observe: it receives the values of the original call by reference and can change them. This is how an extension adds a block to someone else's page or corrects data before it is saved — without touching the core file.

What the handler receives

Trigger kindbeforeafter
controller, model&$route, &$args&$route, &$args, &$output
view&$route, &$data&$route, &$data, &$output

$args is the array of arguments of the original method, $data is the data array of the template, $output is the result: the return value of a model method or ready HTML. The ampersand means the value is passed by reference — a change made in the handler is seen by the engine.

All handlers of this lesson are methods of extension/acme_hello/catalog/controller/module/acme_hello.php. Each is registered in install() with its own code and trigger, as in the previous lesson.

Changing template data

// trigger: catalog/view/product/product/before
public function productData(string &$route, array &$data): void
{
    $data['heading_title'] .= ' — ' . $this->config->get('module_acme_hello_text');
}

Open a product page — the heading of the product is followed by the greeting text from the module settings. The handler changed a variable before the template was rendered.

Changing the output

A new variable is useless if the core template does not print it. Then the ready HTML is changed:

// trigger: catalog/view/product/product/after
public function productOutput(string &$route, array &$data, string &$output): void
{
    $note = '<p class="acme-note">' . $this->config->get('module_acme_hello_text') . '</p>';
 
    $output = str_replace('</h1>', '</h1>' . $note, $output);
}

On the product page a paragraph with the text appears right under the heading.

Changing arguments

// trigger: admin/model/catalog/product.addProduct/before
public function normalizeSku(string &$route, array &$args): void
{
    $args[0]['sku'] = strtoupper(trim($args[0]['sku'] ?? ''));
}

$args[0] is the first argument of addProduct() — the array with the product form. Add a product in the admin panel with the SKU mug-001 — it is saved as MUG-001. This trigger belongs to the admin application, so the handler must be in an admin controller of the extension.

Changing the result

In an after handler of a model $output is what the method returned:

// trigger: catalog/model/catalog/product.getProduct/after
public function productResult(string &$route, array &$args, mixed &$output): void
{
    if ($output) {
        $output['name'] = trim($output['name']);
    }
}

Cancelling the original call

If a before handler returns a value, the original method is not executed and the returned value becomes the result. This replaces a core method completely — and breaks other extensions subscribed to the same call, so it is a last resort.

Common mistake

Insertion through str_replace() depends on the markup of the theme. The shop switches to another theme where the heading is written differently — and the block silently disappears. Search for stable fragments, and after the replacement compare the string with the original: if nothing changed, write a line to the log.

Thanks for reading!

Donate to the site — we work hard for you.