Appite – je možné volať controllery z console?
- Čamo
- Člen | 798
Potreboval by som spustiť nejaký kód v Appite projekte cez konzolu ako cron, ale zdá sa že to nieje úplne jednoduché. Je to možné či nie? skúšal som
php index.php Filters:index
ale toto mi neprejde. Pričom Filters je controller a index je metoda. Píše mi „No matched route by given URL“.
Díky za radu.
Editoval Čamo (1. 2. 2022 16:50)
- dakur
- Člen | 493
Apitte neznám, na to odpovědět neumím. Zavání mi to ale anti-patternem. Pokud ten presenter obsahuje nějakou logiku, kterou potřebuješ provést, pak by ta logika neměla být v presenteru, ale v modelu, ne? Potom bys nemusel volat presenter, ale přímo service z modelu, s čímž není problém.
Editoval dakur (15. 12. 2021 16:47)
- Pavel Janda
- Člen | 977
Můžeš to zkusit přes CURL :)
Ale jinak souhlasím s @Felix a @dakur
Co přesně chceš, aby se stalo po tom, co zavoláš tu routu?
Editoval Pavel Janda (31. 1. 2022 12:30)
- dakur
- Člen | 493
@Čamo Řekněme, že chceš přidávat uživatele, a to dvojím
způsobem – jednak normálně v UI na adrese /users/add
, anebo
zavoláním php skript.php users:add username
Presentery, resp. celé nette/application, pokrývají ten první přístup. Zjednodušeně řečeno to funguje takto:
- vezmi request (tj.
/users/add
) - najdi, jestli k tomu v routeru něco sedí
- pokud ano, přelož to na název presenter a metodu (např.
Users:add
) - spusť tuto action v daném presenteru
- presenter pak zavolá něco v modelu, co reálně toho uživatele vytvoří
(např. nějakou metodu
UsersModel#add($username)
Při spuštění přes command line chceš z tohoto seznamu zachovat jen tu
poslední odrážku, všeho ostatní je zbytečné, protože nemáme žádný
request. Zato máme vstupní parametery – users:add
a username
Tam tedy bude probíhat něco podobného:
- najdi obsluhu pro
users:add
- spusť ji s danými parametry (username)
- obsluha pak opět zavolá
UsersModel#create($username)
Obsluze se říká command a s jejich registrací ti pomůže např. https://componette.org/…tte/console/
Je to takové nette/application pro CLI. Takže v execute()
metodě
daného commandu (viz
docs) můžeš volat svůj model, který si předtím normálně vytáhneš
z DI.
Editoval dakur (1. 2. 2022 11:04)
- jiri.pudil
- Nette Blogger | 1029
(…) tak asi nemôžem čakať že mi to nainjektuje závislosti z configu že?
Ale ano, zaregistruj si command jako kteroukoliv jinou službu, pak si všechny závislosti můžeš vyžádat standardně v konstruktoru.
- dakur
- Člen | 493
Čiže budem musieť vytvoriť špeciálne model pre túto consolovú akciu ano?
@Čamo Ne, modelovou třídu máš jen jednu a používáš ji na více místech (presenter, command). Příkladná modelová třída:
namespace MyApp;
class UsersModel
{
private DbHandler $db;
public function __construct(DbHandler $db) // může být Nette\Database, Dibi, EntityManager, cokoliv
{
$this->db = $db;
}
public function add(string $username): void
{
// samotná logika přidávání, práce s DB, např.:
$this->db->insert(...);
}
}
Tu máš zaregistrovanou v services
:
services:
- MyApp\UsersModel
Potom máš místa, kde tu modelovou třídu používáš. Presenter a command:
namespace MyApp;
use Nette\Application\UI\Form;
use Nette\Application\UI\Presenter;
class UserPresenter extends Presenter
{
private UsersModel $model;
public function __construct(UsersModel $model)
{
$this->model = $model;
}
public function actionDefault(): void
{}
public function createComponentAddUserForm(): Form
{
$form = new Form();
$form->addText('username');
$form->onSuccess[] = function ($values) {
$this->model->add($values['username']); // voláme model
};
}
}
class AddUserCommand extends Command
{
private UsersModel $model;
public function __construct(UsersModel $model)
{
$this->model = $model;
}
public function configure()
{
// ...
}
public function execute($input, $output): void
{
$username = $input->getArgument('username');
$this->model->add($username); // voláme model
}
}
Opět musíš mít obě zaregistrované v DI, jak píše Jirka. Ale presentery jsou (zjednodušeně) registrované automaticky, takže stačí registrovat command:
services:
- MyApp\AddUserCommand
O předání UsersModel
už se postará DI container.
Editoval dakur (3. 2. 2022 9:11)