Použití translatoru ve filtru

Vojtha
Člen | 36
+
0
-

Zdravím,

potřeboval bych poradit. Rád bych definoval filtry v konfiguraci v common.neon (abych je nemusel definovat v BasePresenteru), nějak takto:

latte.latteFactory:
		setup:
			- addFilter('userRole', [App\Component\Filter, 'userRole'])

Narazil jsem ale na problém, že filtr musí být statická funkce, ale zároveň bych v něm chtěl použít translator (převádím číslo reprezentující roli z databáze na text). Tudíž mi injection na translator nefunguje ($this->translator nejde použít).

Má to nějaké řešení? Díky za odpovědi.

Marek Bartoš
Nette Blogger | 1216
+
+1
-

V extension běžně používám službu, imho by to neměl být problém https://github.com/…xtension.php#…

Zkus něco takového

- App\Component\Filter
latte.latteFactory:
		setup:
			- addFilter('userRole', [@App\Component\Filter, 'userRole'])

Zaregistrování filtru jako služby a odkázání na službu v callbacku

Editoval Marek Bartoš (2. 2. 2023 13:20)

dakur
Člen | 493
+
+2
-

Třídu lze volat jako funkci pomocí magické metody __invoke():

final class Filter
{
	public function __construct(
		private Translator $translator,
	) {}

	public function __invoke($cokoliv): string
	{
		return $this->translator->translate($cokoliv);
	}
}

Registrace:

- App\Component\Filter

latte.latteFactory:
		setup:
			- addFilter(userRole, @App\Component\Filter)

Editoval dakur (2. 2. 2023 13:42)

Vojtha
Člen | 36
+
0
-

Díky, pořád ale nevidím, jak ve filtru volat překlad. V konfiguraci teď mám

services:
	- App\Component\Filter
	latte.latteFactory:
		setup:
			- addFilter('userRole', [@App\Component\Filter, 'userRole'])

ale pokud ve Filtru

<?php

declare(strict_types=1);

namespace App\Component;

use Nette;
use Nette\Localization\ITranslator;


class Filter
{
    /**
     * @var ITranslator
     * @inject
     */
    public $translator;

    public function userRole($roles) {
        $toBereturned = [];
        foreach ($roles as $role) {
          $toBereturned[] = $this->translateRole($role);
        }
        return implode(", ", $toBereturned);
    }

    protected function translateRole($role) {
        switch ($role) {
          case 0:
            return $this->translator->translate('ui.roles.anonymous');
          case 1:
            return $this->translator->translate('ui.roles.registered');
          case 7:
            return $this->translator->translate('ui.roles.administrator');
        }
    }

zavolám translator, dostanu

Error: Call to a member function translate() on null
dakur
Člen | 493
+
+1
-

Pokud vím, anotace @inject funguje jen v presenterech. Použij běžný constructor injection:

public function __construct(
	private ITranslator $translator,
) {}

Editoval dakur (2. 2. 2023 14:48)

nightfish
Člen | 483
+
0
-

Vojtha napsal(a):

zavolám translator, dostanu

Error: Call to a member function translate() on null

Počti si o předávání závislostí.

Vojtha
Člen | 36
+
0
-

Super, díky @dakur.

@nightfish o předávání závislostí jsem samozřejmě četl, jen ten článek je dost jednoduchý, a například neříká nic o tom, že v presenteru inject nefunguje :-)

nightfish
Člen | 483
+
+1
-

Vojtha napsal(a):
@nightfish o předávání závislostí jsem samozřejmě četl, jen ten článek je dost jednoduchý, a například neříká nic o tom, že v presenteru inject nefunguje :-)

…čtvrtý („metodou, anotací či atributem inject“) je specifický pro presentery v Nette, takže o něm pojednává samostatná kapitola.

Vojtha
Člen | 36
+
+1
-

ok, vyhrál jsi … to jsem přehlédl

dakur
Člen | 493
+
+2
-

Jako je to trochu ukecaný, takže to člověk nevidí na první dobrou. Možná by to bylo lepší takto..

David Grudl
Nette Core | 8183
+
0
-

Klidně pošli PR (nejlépe i v jazykových mutacích 😅)