# Component filters

**Whenever a value is saved to a Component Repository and whenever a value is retrieved via the `getValue()` method of the Component View Model, the value is automatically filtered. Filters are added to the component entry in `etc/loki_components.xml` and are fully extensible.**

## Adding a filter to a component
To add a filter to an component - either a new component or an existing component - create a file `etc/loki_components.xml`, find or add an entry for the component in question and then add a new `<filter/>` tag to it.

```xml
<?xml version="1.0" encoding="UTF-8" ?>
<components xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Loki_Components:etc/loki_components.xsd">
    <component name="loki-components.example">
        <filter name="uppercase" />
    </component>
</components>
```

Let's say that the component value is a string `foobar`, then the string `FOOBAR` will be saved to the repository. Let's say that the string `foobar` has been saved before, then the value will be retrieved via the `ComponentViewModel::getValue()` method as `FOOBAR` again.

If the component value is an array, each entry in the array is filtered as well. 

## Existing filters
Filters are identified in the `etc/loki_components.xml` file by their name. This name is declared together with a corresponding filter class via the constructor of the class `Loki\Components\Filter\FilterRegistry`.

The following filters exist by default:

- `trim`
- `capitalize`
- `lowercase`
- `number`
- `positive_number`
- `uppercase`
- `security`

The `security` filter removes HTML tags from a value and decodes HTML entities. This filter is automatically added to any component.

Other modules, like `LokiCheckout_Core`, can add additional filters as well. And you can add your own custom filters.

## Declaring a new custom filter
To add a new filter, an `di.xml` entry is needed:
```xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Loki\Components\Filter\FilterRegistry">
        <arguments>
            <argument name="filters" xsi:type="array">
                <item name="speling" xsi:type="object">YireoTraining\ExampleComponent\Filter\Speling</item>
            </argument>
        </arguments>
    </type>
</config>
```

Next, the PHP class `YireoTraining\ExampleComponent\Filter\Speling` needs to be implementing the `Loki\Components\Filter\FilterInterface` interface. This could a bit like the following:

```php
<?php declare(strict_types=1);

namespace YireoTraining\ExampleComponent\Filter;

use Loki\Components\Filter\FilterInterface;

class Speling implements FilterInterface
{
    public function filter(mixed $data): mixed
    {
        $value = str_replace('Holland', 'The Netherlands', $value);
    }
}
```

And now the filter can be applied:

```xml
<?xml version="1.0" encoding="UTF-8" ?>
<components xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Loki_Components:etc/loki_components.xsd">
    <component name="loki-components.example">
        <filter name="speling" />
    </component>
</components>
```

## Client-side filtering
Currently there is no filtering done client-side.
