inject Latte\Engine v konzolové aplikaci

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
supex
Člen | 2
+
0
-

Ahoj,
dělám teď na konzolové php aplikaci. Zatím umí jenom to, že z konzole (Kdyby\Console) přebere parametry a vyflusne mi přes Latte vygenerovanou šablonu, kterou pak použiju pro poslání mailu z powershellu.

<?php
protected function execute(InputInterface $input, OutputInterface $output) {
        $template=new Latte\Engine
		$params = [
            'from' => $input->getArgument('from'),
            'accounts' => $input->getArgument('accounts')
        ];
        $output->writeLn($template->renderToString(__DIR__ . '/templates/generatecreatemail/generatecreatemail.latte', $params));
    }
?>

Takhle mi to bez problému funguje.
Říkal jsem si, ale že zkusím dodržet DI „vstříkni to tam“. Udělal jsem si abstraktní třídu MailCommand, která má přes @inject anotaci vstříknuté Latte\Engine a tu pak chci dědit v Command třídách, které budou mít za úkol generovat rozdílné maily

<?php
class MailCommand extends Command {

    /** @var \Latte\Engine @inject */
    public $template;
}
?>

Nicméně při spuštění mi nette, resp tracy, vyhodí následující exception
`[Nette\InvalidStateException]
Service of type Latte\Engine used in @var annotation at App\Console\MailCommand::$template not found. Did you register it in configuration file?`

composer.json vypadá následovně

<script>
{
    "require": {
        "latte/latte": "^2.4",
        "kdyby/console": "^2.6",
        "nette/di": "^2.4",
        "nette/neon": "^2.4",
        "nette/bootstrap": "^2.4",
        "tracy/tracy": "^2.4"
    },
    "autoload": {
        "psr-4": {
            "App\\": [
                "app/"
            ]
        }
    }
}
</script>

Pokud jsem dobře pochopil bootstrap.php, tak Latte jako service nemusím uvádět v config.neon, protože už je načtené přes autoload.php z vendor složky. Navíc se nic nezmění když ho v neonu zaregistruju :/

Cache jsem mazal. Nic se nezměnilo.

Můžete poradit co dělám blbě? Případně trochu nasměrovat?
Appka bude čistě konzolová, takže nechci tahat celé nette.

David Matějka
Moderator | 6445
+
+1
-

latte engine neni registrovan jako sluzba. Je zde ale create: https://api.nette.org/…Factory.html, kterou si muzes predat.

Jan Mikeš
Člen | 771
+
+1
-

Latte\Engine totiž není služba, je vytvářena pomocí LatteFactory

edit: @DavidMatějka byl rychlejší :-)

Editoval Jan Mikeš (24. 10. 2016 12:34)

supex
Člen | 2
+
0
-

Takže buď potřebuju závislost na Nette\Application, což je něco co v konzolové appce nepotřebuju.
A nebo si na sprosťáka vykopíruju jenom ten bridge, vložím někam do app složky a zaregistruju jako službu. Je tak?

Jan Mikeš
Člen | 771
+
+1
-

@supex to vůbec ne, můžeš si vytvořit svou vlastní factory ;)

Ještě stojí za povšimnutí, jak latte extension lattefactory generuje automaticky:

public function loadConfiguration()
	{
		if (!class_exists(Latte\Engine::class)) {
			return;
		}

		$config = $this->validateConfig($this->defaults);
		$builder = $this->getContainerBuilder();

		$builder->addDefinition($this->prefix('latteFactory'))
			->setClass(Latte\Engine::class)
			->addSetup('setTempDirectory', [$this->tempDir])
			->addSetup('setAutoRefresh', [$this->debugMode])
			->addSetup('setContentType', [$config['xhtml'] ? Latte\Compiler::CONTENT_XHTML : Latte\Compiler::CONTENT_HTML])
			->addSetup('Nette\Utils\Html::$xhtml = ?', [(bool) $config['xhtml']])
			->setImplement(Nette\Bridges\ApplicationLatte\ILatteFactory::class);

		$builder->addDefinition($this->prefix('templateFactory'))
			->setClass(Nette\Application\UI\ITemplateFactory::class)
			->setFactory(Nette\Bridges\ApplicationLatte\TemplateFactory::class);

		foreach ($config['macros'] as $macro) {
			if (strpos($macro, '::') === FALSE && class_exists($macro)) {
				$macro .= '::install';
			}
			$this->addMacro($macro);
		}

		if ($this->name === 'latte') {
			$builder->addAlias('nette.latteFactory', $this->prefix('latteFactory'));
			$builder->addAlias('nette.templateFactory', $this->prefix('templateFactory'));
		}
	}

Editoval Jan Mikeš (24. 10. 2016 12:50)