[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
+
0
-

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
+
+7
-

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
+
+1
-

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');
}