Modifiers

For arlanix/product-feed 1.0.0

Modifiers

This page is for the PHP developer who needs a change to a value that the store can put on any mapping row, the way it puts truncate:150 or strip_tags. A modifier is one such step. Once registered, it is listed in the menu of the Modifiers column, behind the + of every row, and it works everywhere a modifier does:

  • as a chip on a mapping row, after the row's source and dictionary;
  • in a template placeholder, after a pipe: {name|words:12};
  • in a field catalog's default_modifiers; see Field catalogs.

The module registers trim, lower, upper, ucfirst, strip_tags, truncate, replace, default, prefix, suffix, number and date; the manual's Modifiers section says what each does. An item under one of those names replaces the module's modifier.

Write a modifier

The following modifier keeps the first words of a text, words:12 keeping twelve:

<?php
declare(strict_types=1);

namespace Vendor\Module\Model\Modifier;

use Arlanix\Core\Model\Template\Modifier\Description;
use Arlanix\Core\Model\Template\Modifier\StringModifier;

class Words extends StringModifier
{
    protected function transform(string $value, array $arguments): string
    {
        $limit = max(1, (int)($arguments[0] ?? 20));
        $words = preg_split('/\s+/u', trim($value), -1, PREG_SPLIT_NO_EMPTY) ?: [];

        return implode(' ', array_slice($words, 0, $limit));
    }

    public function describe(): Description
    {
        return new Description('words:20', __('Keep the first words'), 'words:12');
    }
}

Arlanix\Core\Model\Template\Modifier\StringModifier is the base of the module's own text modifiers. It calls transform() with each text of the value: once for a single value, once for each member of a list, such as the labels of a multiselect attribute. A value that is not text, a number or a list, null included, passes through untouched.

A modifier of something other than text implements Arlanix\Core\Model\Template\ModifierInterface itself:

Method Does
apply(mixed $value, array $arguments = []): mixed Returns the changed value. $value is whatever the previous step gave: text, a number, a list or null. Pass on untouched what the modifier has no meaning for, so that one step never breaks a row.

An exception from a modifier stops the whole run, so return the value unchanged rather than throw.

How arguments arrive

$arguments holds the arguments as they are written after the name, as strings, in order: words:12 gives ['12'], replace:a:b gives ['a', 'b']. A missing argument is absent from the array, so give each one a default. An argument holding a : or a |, or starting or ending with a space, is written in quotes, suffix:' | ', and arrives without them.

Nothing checks the arguments when the feed is saved: only the modifier's name is. Read them leniently, as max(1, (int)…) does in the example.

Describe it

describe(), from Arlanix\Core\Model\Template\Modifier\DescribesItselfInterface, which StringModifier implements, gives the modifier menu its line:

Description argument Shown
signature How it is written, arguments included: words:20. The menu lists modifiers by it.
summary One line, in the imperative: Keep the first words. The menu shows it beside the signature, and a chip shows it when pointed at.
example A step that works as it is, words:12, which the menu inserts when it is chosen.

A modifier that does not describe itself is listed by its name alone, and choosing it inserts the bare name.

Register it

In your module's etc/di.xml, add the modifier to ModifierPool under its name:

<type name="Arlanix\Core\Model\Template\ModifierPool">
    <arguments>
        <argument name="modifiers" xsi:type="array">
            <item name="words" xsi:type="object">Vendor\Module\Model\Modifier\Words</item>
        </argument>
    </arguments>
</type>

The name is what a mapping row stores. Use lower-case letters, digits and underscores: a name ends at the first :, |, { or }.

Then run bin/magento setup:upgrade and bin/magento cache:clean config. Open a feed, press + in the Modifiers column of a row, choose words:20, save, and check the value with Preview. A mapping that names a modifier no installed module registers is refused when the feed is saved, naming the row.