Hi, der Titel verrät schon worum es geht. Ich möchte gern eine Action meines eigenen Controllers über die CLI-Tools aufrufen. Ist das Möglich? Die Dokumentation zu den CLI-Tools ist ja noch etwas dünn. Das CLI-Framework von shredding kann das offensichtlich aber das ist glaube ich nicht mehr so aktuell… Hat jemand einen Tipp für mich wie man die cli-tools von Shopware dahingehend erweitern/nutzen kann? Viele Grüße,
ich habe jetzt versucht erst einmal einen eigenen Befehl, wie hier beschrieben zu registrieren. Leider scheitere ich schon an dieser Stelle. In meiner Plugin-Bootstrap habe ich /\*\* \* Registers all necessary events, hooks and controllers. \*/ private function subscribeEvents() { $this-\>registerController('Backend', 'Test'); $this-\>subscribeEvent( 'Shopware\_Console\_Add\_Command', 'onAddConsoleCommand' ); } public function onAddConsoleCommand(Enlight\_Event\_EventArgs $args) { require\_once \_\_DIR\_\_ . '/Commands/TestCommand.php'; return new \Shopware\Commands\TestCommand(); }
Meine TestCommand.php sieht wie folgt aus: [code]<?php namespace Shopware\Commands;
use Shopware\Components\Model\ModelManager;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class TestCommand extends ShopwareCommand
{
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName(‘maxout:test’) ->setDescription(‘Dies ist ein Test’) ->addArgument( ‘test’, InputArgument::REQUIRED, ‘test arg’ ) ->setHelp(<<%command.name% is just a test.
EOF
);
;
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$test = $input->getArgument('test');
// get some service from container (formerly Shopware()->Bootstrap()->getResource())
$em = $this->container->get('front');
$output->writeln('<info>'.sprintf("Got test: %s.", $test).'</info>');
}
}
[/code]
Das Plugin lässt sich ohne Fehler installieren. In der Konsole wird der Aufruf bin/console maxout:test wie folgt quittiert:
[InvalidArgumentException]
There are no commands defined in the "maxout" namespace.
Was mache ich falsch?
Kannst Du mir das Plugin Vollständig als zip schicken? Dann schaue ich mir das gerne an. Gruß
[quote=„tonne“]Kannst Du mir das Plugin Vollständig als zip schicken? Dann schaue ich mir das gerne an. Gruß[/quote] Klar, wo soll’s hingehen? Vielen Dank.
Hi, ich würde prüfen, ob deine Callback-Funktion überhaupt aufgerufen wird. Häufig wird bspw. vergessen, das Plugin nach Hinzufügen eines neuen Events neu zu installieren. Was die Frage generell angeht: Zwar mag es über Umwege möglich sein, Controller-Actions bspw. Konsolen-Commandos heraus auszulösen - gerade wenn es aber dein eigener Controller ist, solltest du das niemals machen. Da würde ich die fragliche Logik eher in eine Service-Klasse packen, die du dann aus dem Controller und dem Command heraus nutzt. lG Daniel
Hallo Daniel, vielen Dank für deine Antwort. Das Plugin habe ich bereits mehrmals neu installiert. Jetzt habe ich aber mal ein Shopware()->Pluginlogger()->info(‘onAddConsoleCommand’); in den Callback gepackt, leider wird nichts in die logs geschrieben – danke für den Hinweis Was mache ich falsch? Warum wird die Fallback-Funktion nicht aufgerufen? Hier noch mal meine gesamte Bootstrap: [code]<?php /**
- @copyright Copyright © 2015, Heiko Bee
- @author Heiko bee hb@maxout.de * @package Shopware * @subpackage Plugins * @creation_date 09.01.15 */ /** * User: hbee * Date: 09.01.15 * Time: 17:45 */ class Shopware_Plugins_Backend_TestPlugin_Bootstrap extends Shopware_Components_Plugin_Bootstrap { /** * GetVersion plugin method * * @return String */ public function getVersion() { return ‘1.0.0’; } /** * GetLabel plugin method * * @return String */ public function getLabel() { return ‘TEST::TEST’; } /** * getDescription plugin method * * @return String */ public function getDescription(){ return “Just for testing”; } /** * GetInfo plugin method * * @return Array */ public function getInfo() { return array( ‘version’ => $this->getVersion(), ‘label’ => $this->getLabel(), ‘author’=> ‘Heiko Bee’, ‘license’ => ‘proprietary’, ‘copyright’ => ‘Copyright © 2014, Heiko Bee’, ‘support’ => ‘plugins@maxout.de’, ‘link’ => ‘http://plugins.maxout.de’, ‘description’ => $this->getDescription() ); } /** * Enable plugin method * * @return bool */ public function enable() { return true; } /** * Disable plugin method * * @return bool */ public function disable() { return true; } /** * /** * Install plugin method * this method is called automatically each time the plugin will be installed * @return bool * @throws Enlight_Exception */ public function install() { $this->subscribeEvents(); return true; } /** * Registers all necessary events, hooks and controllers. */ private function subscribeEvents() { $this->registerController(‘Backend’, ‘Test’); $this->subscribeEvent( ‘Shopware_Console_Add_Command’, ‘onAddConsoleCommand’ ); } public function onAddConsoleCommand(Enlight_Event_EventArgs $args) { Shopware()->Pluginlogger()->info(‘onAddConsoleCommand’); require_once __DIR__ . ‘/Commands/TestCommand.php’; return new Shopware\Plugins\Backend\TestPlugin\Commands\TestCommand(); } } [/code] Das mit der Service-Klasse habe ich auch schon überlegt. Erst einmal müsste ich aber die Registrierung des Commands hinbekommen. Vielen Dank.
[quote=“hbee”] <?php public function onAddConsoleCommand(Enlight_Event_EventArgs $args)
{
Shopware()->Pluginlogger()-\>info('onAddConsoleCommand'); require\_once \_\_DIR\_\_ . '/Commands/TestCommand.php'; return new Shopware\Plugins\Backend\TestPlugin\Commands\TestCommand(); } }
[/quote] bitte: return new Shopware\Plugins\Backend\TestPlugin\Commands\TestCommand();
durch: return new \Shopware\Commands\TestCommand();
ersetzen. Des Weiteren hab ich bei mir öfters das Problem gehabt wenn der Benutzer der die Konsole verwendet nicht genügend Berechtigungen hatte das mir meine eigenen CLI Erweiterungen nicht angezeigt wurden. Zum testen ob Du dieses Problem hast einfach ./console sw:plugin:list ausführen. Wenn dort eine Fehlermeldung wie “is not writable” kommt passen die Berechtigungen nicht Gruß, Thomas
… noch mal zum Hintergrund: ich habe ein Plugin welches Artikeldaten in Shopware importiert. Aktuell mache ich das in einem Controller über die lokale API. Das funktioniert alles wunderbar, bis auf dem Bildimport. Da wir sehr viele und grosse Bilder haben laufen wir früher oder später auf das execution_limit von PHP. Auch wenn wir das beliebig raufsetzen könnten müsste das Browserfenster dazu ja geöffnet bleiben. Nun wollte ich die entsprechende Action des Controllers einfach über die CLI-Tools aufrufen und das am Ende möglichst über einen Cronjob. Vielleicht hat ja einer eine bessere Vorgehensweise wie große Datenmengen bzw. lang laufende Skripte in Shopware behandelt werden können. Vielen Dank.
[quote=„tonne“][quote=„hbee“] <?php public function onAddConsoleCommand(Enlight_Event_EventArgs $args)
{
Shopware()->Pluginlogger()-\>info('onAddConsoleCommand'); require\_once \_\_DIR\_\_ . '/Commands/TestCommand.php'; return new Shopware\Plugins\Backend\TestPlugin\Commands\TestCommand(); } }
[/quote] bitte: return new Shopware\Plugins\Backend\TestPlugin\Commands\TestCommand();
durch: return new \Shopware\Commands\TestCommand();
ersetzen. Des Weiteren hab ich bei mir öfters das Problem gehabt wenn der Benutzer der die Konsole verwendet nicht genügend Berechtigungen hatte das mir meine eigenen CLI Erweiterungen nicht angezeigt wurden. Zum testen ob Du dieses Problem hast einfach ./console sw:plugin:list ausführen. Wenn dort eine Fehlermeldung wie „is not writable“ kommt passen die Berechtigungen nicht Gruß, Thomas[/quote] Hallo Thomas, vielen Dank. Es gab tatsächlich noch ein Rechtsproblem. Jetzt bekomme ich folgende Meldung: [quote] PHP Fatal error: Class ‚Shopware\Plugins\Backend\TestPlugin\Commands\ShopwareCommand‘ not found in /var/www/shopware/engine/Shopware/Plugins/Community/Backend/TestPlugin/Commands/TestCommand.php on line 10 Fatal error: Class ‚Shopware\Plugins\Backend\TestPlugin\Commands\ShopwareCommand‘ not found in /var/www/shopware/engine/Shopware/Plugins/Community/Backend/TestPlugin/Commands/TestCommand.php on line 10 [/quote] den return habe ich wie von dir beschrieben geändert.
[quote=„hbee“]Vielleicht hat ja einer eine bessere Vorgehensweise wie große Datenmengen bzw. lang laufende Skripte in Shopware behandelt werden können.[/quote] Auf jeden Fall die Logik aus der Controller Action in eine oder mehrere Klassen auslagern. Ich bin mir nicht sicher ob die Rest API im CLI Kontext zur Verfügung steht. Das müsstest Du beim Klassen erstellen berücksichtigen. Ansonsten bieten sich die CLI Commands super für solche Aufgaben an. Gruß
Poste bitte deine Bootstrap.php und TestCommand.php vollständig. Gruß
Bootstrap.php [code]<?php /**
- @copyright Copyright © 2015, Heiko Bee
- @author Heiko bee hb@maxout.de * @package Shopware * @subpackage Plugins * @creation_date 09.01.15 */ /** * User: hbee * Date: 09.01.15 * Time: 17:45 */ class Shopware_Plugins_Backend_TestPlugin_Bootstrap extends Shopware_Components_Plugin_Bootstrap { /** * GetVersion plugin method * * @return String */ public function getVersion() { return ‚1.0.0‘; } /** * GetLabel plugin method * * @return String */ public function getLabel() { return ‚TEST::TEST‘; } /** * getDescription plugin method * * @return String */ public function getDescription(){ return „Just for testing“; } /** * GetInfo plugin method * * @return Array */ public function getInfo() { return array( ‚version‘ => $this->getVersion(), ‚label‘ => $this->getLabel(), ‚author‘=> ‚Heiko Bee‘, ‚license‘ => ‚proprietary‘, ‚copyright‘ => ‚Copyright © 2014, Heiko Bee‘, ‚support‘ => ‚plugins@maxout.de‘, ‚link‘ => ‚http://plugins.maxout.de‘, ‚description‘ => $this->getDescription() ); } /** * Enable plugin method * * @return bool */ public function enable() { return true; } /** * Disable plugin method * * @return bool */ public function disable() { return true; } /** * /** * Install plugin method * this method is called automatically each time the plugin will be installed * @return bool * @throws Enlight_Exception */ public function install() { $this->subscribeEvents(); return true; } /** * Registers all necessary events, hooks and controllers. */ private function subscribeEvents() { $this->registerController(‚Backend‘, ‚Test‘); $this->subscribeEvent( ‚Shopware_Console_Add_Command‘, ‚onAddConsoleCommand‘ ); } public function afterInit(){ $this->Application()->Loader()->registerNamespace( ‚Shopware\TestPlugin‘, $this->Path() . „Components/“ ); return true; } public function onAddConsoleCommand(Enlight_Event_EventArgs $args) { Shopware()->Pluginlogger()->info(‚onAddConsoleCommand‘); require_once __DIR__ . ‚/Commands/TestCommand.php‘; return new \Shopware\Commands\TestCommand(); } } [/code] Commands/TestCommand.php [code]<?php namespace Shopware\Plugins\Backend\TestPlugin\Commands;
use Shopware\Components\Model\ModelManager;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class TestCommand extends ShopwareCommand
{
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName(‚TestPlugin:test‘) ->setDescription(‚Dies ist ein Test‘) ->addArgument( ‚test‘, InputArgument::REQUIRED, ‚test arg‘ ) ->setHelp(<<%command.name% is just a test.
EOF
);
;
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$test = $input->getArgument('test');
// get some service from container (formerly Shopware()->Bootstrap()->getResource())
$em = $this->container->get('front');
$output->writeln('<info>'.sprintf("Got test: %s.", $test).'</info>');
}
}
[/code]
Verzeichnisstruktur:
TestPlugin
->Commands
->TestCommand.php
->Components
->Test.php
->Controller
->Backend
->Test.php
Bootstrap.php
Danke.
ah, ich habe den Fehler gerade selbst entdeckt. Der namespace in der TestCommand.php muss Showware\Commands lauten. Jetzt lässt sich das Kommando aufrufen. Danke. Bleibt die Frage wie ich die Controller-Action ansprechen kann…
Du kannst controller actions ohne das entspreche routing des Systems nicht einfach direkt aufrufen. Du könntest höchstens mal versuchen direkt eine Instanz des controllers zu erzeugen und schauen was passiert. $obj = new \Shopware\_Controllers\_Frontend\_xxx(); $obj-\>machwas();
Einfach mal testen. Ich glaube aber dass der router bei der Instanziierung noch weitere Attribute, Objekte etc injiziert. Viele Grüße
Ach du willst an -deinen- controller kommen?! Warum das denn? Das macht ja überhaupt keinen Sinn?! Viele Grüße
[quote=„Aquatuning GmbH“]Ach du willst an -deinen- controller kommen?! Warum das denn? Das macht ja überhaupt keinen Sinn?! [/quote] Richtig, ich möchte an meinen eigenen Controller. Das macht in so fern Sinn, dass dort schon meine ganze Logik steht. Ich muss ja zb. auch auf meine Komponenten und auch die API zugreifen können. Wie geht man da am besten vor? Vielen Dank.
so, auf meine Komponente kann ich aber zugreifen $obj = new \Shopware\TestPlugin\Test(); $test = $obj-\>test();
Jetzt müsste ich noch mal testen ob mir dann auch die Api-Resourcen zur Verfügung stehen.
[quote=„hbee“]dass dort schon meine ganze Logik steht[/quote] Und genau das macht keinen Sinn Die CLI tools haben nichts mit controllern aus dem frontend oder backend zu tun. Controller werden ausschließlich durch das Shopware routing instanziert und gefüttert. Mehrfach genutzte Logik solltest du in externe Komponenten, helper Klassen etc packen. Viele Grüße
[quote=“hbee”]Jetzt müsste ich noch mal testen ob mir dann auch die Api-Resourcen zur Verfügung stehen.[/quote] An die API kommst du entweder über die Shopware singletons oder über dependency injections. Viele Grüße