Inject databazy do filtra
- aRagornol
- Člen | 17
Ako injectnut instanciu databazy do Filters triedy ?
Podla navodu som spravil generic filter loader
class Filters
{
public static function common($filter, $value)
{
if (method_exists(__CLASS__, $filter)) {
$args = func_get_args();
array_shift($args);
return call_user_func_array(array(__CLASS__, $filter), $args);
}
}
}
a teraz by som potreboval vytvorit filter ktory bude pouzivat databazu a takisto objekt aplikacie pre vytvaranie liniek.
V 2.0.nieco som to mal spravene v Helpery takto ale teraz uz pouzivam 2.3.0
class Helper extends Nette\Object
{
/** @var Nette\Application\Application */
protected $application;
/** @var App\Repository */
protected $repository;
public function __construct(Nette\Application\Application $application)
{
$this->application = $application;
$this->repository = $this->application->getPresenter()->getContext()->repository;
}
public function linkifyDog($text)
{
$pattern = "/(\[dog\])(\w+)(\[\/dog\])/";
$application = $this->application;
$repository = $this->repository;
return preg_replace_callback($pattern, function ($text) use ($application, $repository) {
$dog = $repository->getTable('dogs')->select('fullName AS name')->where('nickname', $text[2]);
if(count($dog) > 0)
{
return '<a href="' . $application->getPresenter()->link('Page:dog', $text[2]) . '">' . $dog[0]->name . '</a>';
} else {
return 'unknown dog';
}
}, $text);
}
}
Dakujem.
Editoval aRagornol (26. 3. 2015 10:46)
- aRagornol
- Člen | 17
nie chcem vytvorit filter ktory po aplikovani na text vytvori zo stringov
linky. teda ak budem mat text
„Vystava 10.3.2015. [dog]random[/dog] obhajil prvenstvo.“, filter podla
nicku random vytiahne z databazy full name a zaroven vytvori na psa linku.
usage {text|linkifyDog} v sablone
Editoval aRagornol (26. 3. 2015 10:32)
- Filip Klimeš
- Nette Blogger | 156
Netuším jak to udělat, snad odpoví někdo jiný. Mám ale tušení, že to jde těžko, protože se to tak dělat nemá.
Jaký benefit těžíš z toho, že se budeš dotazovat do DB až při vykreslování šablony? Je případná změna modelu dostatečně dobrým důvodem pro změnu helperu v šabloně? Data o pejscích znáš určitě dříve než v šabloně, proto s nimi také můžeš pracovat dříve. Osobně bych doporučoval nějakou metodu v repozitáři nebo service. Poté předáš do šablony již připravená data a v šabloně z nich jen vytvoříš odkaz.
Btw lepší by bylo
class Helper extends Nette\Object
{
/** @var Nette\Application\Application */
protected $application;
/** @var App\Repository */
protected $repository;
public function __construct(Nette\Application\Application $application, App\Repository $repository)
{
$this->application = $application;
$this->repository = $repository;
}
...
Editoval Filip Klimeš (26. 3. 2015 10:36)
- aRagornol
- Člen | 17
ano upravit model je jedno z rieseni na ktore som myslel. cisto z teoretickeho hladiska ma zaujimalo ci by to bolo mozne spravit aj inak. samozrejme nie je problem v modely spravit replace pred poslanim dat do sablony. – btw pouzivam uz 2.3.0 takze ten Helper som musel vymazat / uviedol som ho len na ukazku.
- greeny
- Člen | 405
Vyrob si službu, nějak takhle:
class TextParser
{
private $linkGenerator;
private $dogRepository;
public function __construct(LinkGenerator $linkGenerator, DogRepository $dogRepository) {
$this->linkGenerator = $linkGenerator;
$this->dogRepository = $dogRepository;
}
public function parse($text) {
$dogRepository = $this->dogRepository;
$linkGenerator = $this->linkGenerator;
Strings::replace('~\[dog\](\w+?)\[\\dog\]~', function ($matches) use ($dogRepository, $linkGenerator) {
$dog = $dogRepository->find($matches[1]);
if (!$dog) {
return 'Unknown dog ' . $matches[1];
} else {
return Html::el('a', [
'href' => $linkGenerator->link(':Dog:detail', ['id' => $dog->id]),
])->setText($matches[1]);
}
}
}
}
Tu si zaregistruj do config.neon pod services.
Potom tím protáhni ten text ještě před předáním do šablony.
Editoval greeny (26. 3. 2015 10:42)
- Filip Klimeš
- Nette Blogger | 156
Doporučuju jít cestou modelu. Je to čistější a z dlouhodobého hlediska udržitelnější.
Jasně, jen jsem chtěl demonstrovat, že bys neměl přistupovat přes aplikaci na presenter, pak přes presenter na context a přes context až k repozitáři (porušuješ Dependency inversion principle). Raději si o služby řekni napřímo v konstruktoru. (a jestli už jsi na 2.3, můžeš používat LinkGenerator místo Application).