[Kdyby\Console] Ukazatel průběhu uvnitř modelu
Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
- Petr Hudík
- Člen | 49
Ahoj,
v modelové vrstvě mám poměrně rozsáhlou logiku, některé části mohou být výpočetně náročné a jejich provedení může trvat déle. Část této logiky je možné (/vhodné) vyvolat normálně z presenteru. Nyní přidávám do aplikace Kdyby\Console a chtěl bych, aby se ukazoval průběh zpracování.
Hlavní problém je v podstatě v tom, že když napíšu vlastní command,
tak FooCoomand::execute()
obsahuje vlastně jen jeden
řádek – např.
<?php
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->collection->updateAll();
$output->writeln('update done');
}
?>
Dle mého názoru daná logika do modelové vrstvy patří.
Zároveň se však domnívám, že do modelové vrstvy zápisy typu
$output->writeln()
nepatří a třída z modelové vrstvy by
neměla mít závislost na outputu. Jak tuto situaci řešit?
- David Matějka
- Moderator | 6445
Pouzij eventy
class FooModel extends Nette\Object
{
public $onProgress = [];
public function updateAll()
{
foreach (.... as $item) {
...
$this->onProgress($item);
}
}
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->collection->onProgress[] = function ($item) use ($output) {
$output->writeln(...);
};
$this->collection->updateAll();
$output->writeln('update done');
}
- Filip Procházka
- Moderator | 4668
Přesně jak píše @DavidMatějka, použíj eventy. Ale taky progressbar ze symfony je fajn :)
protected function execute(InputInterface $input, OutputInterface $output)
{
$progress = new \Symfony\Component\Console\Helper\ProgressBar($output);
$progress->setFormat($progress::getFormatDefinition('debug'));
$this->collection->onUpdateStart[] = function ($itemsCount) use ($progress) {
$progress->start($itemsCount);
};
$this->collection->onProgress[] = function ($item) use ($progress) {
$progress->advance();
};
$this->collection->updateAll();
$progress->finish();
$output->writeln('');
$output->writeln('Update done');
}