By running this command on console in symfony/pimcore
i'm getting this error:
There are no commands defined in the "branch" namespace.
This is the code:
namespace App\Command;
use Pimcore\Console\AbstractCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Pimcore\Model\DataObject;
use Symfony\Component\Console\Helper\ProgressBar;
/**
* #method getContainer()
* #property $em
*/
class Branch extends AbstractCommand
{
protected function configure(): void
{
$this
->setName('branch:import')
->setDescription('Branch cagai');
}
and this is the command:
php bin/console branch:import
What i'm doing wrong here?
The class, should be in src path and not in bin path
Related
What would be a proper way to have a Service (that will be used by a Command) write information to the terminal? I like the same functionality to parse thousands of records to be able to be called from both a Controller and a Command. When it's called from the Command, I like to write a status to the terminal for every parsed record.
I've tried autowiring InputInterface $input, OutputInterface $output into the service but that gives me the following error:
Cannot autowire service "App\Service\Command\TestIoService": argument
"$input" of method "__construct()" references interface
"Symfony\Component\Console\Input\InputInterface" but no such service
exists. Did you create a class that implements this interface?
I could pass the input and output to the service but I was wondering if there is a better way to do this
I know this is over a year old, but I just stumbled upon the same requirement for my project. It's a bad idea to be passing around the Input/Output Interfaces.
Since Symfony 2.4 you've been able to use the Monolog component to log to the console. (https://symfony.com/doc/current/logging/monolog_console.html). It's already all wired-up for you. DI The LoggerInterface (use Psr\Log\LoggerInterface) in your constructor. Then use it like you normally would. $this->logger->debug('Hello World'). Your output is dependent on the verbosity level set via the CLI -v, -vv, -vvv options as described in the link above.
// src/Command/YourCommand.php
namespace App\Command;
use App\Service\AwesomeService;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class YourCommand extends Command
{
public function __construct(AwesomeService $service)
{
$this->service = $service;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->service->doMethod();
}
}
// src/Service/AwesomeService.php
namespace App\Service;
use Psr\Log\LoggerInterface;
class AwesomeService
{
private $logger;
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}
protected function doMethod()
{
$this->logger->debug('Some info');
$this->logger->notice('Some more info');
}
}
I am using Symfony 4.2.1 and I cannot somehow not use the generate() Method of router:
<?php
namespace App\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Routing\RouterInterface;
class NewAcceptedOrderCommand extends Command
{
/**
* #var RouterInterface $router
*/
private $router;
public function __construct(
RouterInterface $router
) {
$this->router = $router;
parent::__construct();
}
protected function configure()
{
$this
->setName('address:new')
->setDescription('Get adresses by Status ID')
->setHelp('Get adresses by Status ID')
->addArgument('id', InputArgument::REQUIRED, 'Status ID');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$url = $this->router->generate('adresses_index');
// SOME more Code
}
}
I injected all sorts of other services and interfaces before (EntityManagerInterface, my Logservice etc.)
But I am always getting
Unable to generate a URL for the named route "adresses_index" as such
route does not exist.
But this route exists for sure I checked with php bin/console debug:router and also using it in other places. I am using the global approach from here: https://symfony.com/doc/current/console/request_context.html#configuring-the-request-context-globally
I was thinking to secure at the beginning and added the annotation "method" to every action - it has to be unset (ANY). It works fine afterwards.
Dont forget to configure your router
$context = $this->router->getContext();
$context->setHost($this->container->getParameter('router_host'));
$context->setScheme($this->container->getParameter('router_scheme'));
Impossible to load Stripe classe in my Symfony controller see :
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Stripe\Stripe;
class PointsController extends Controller
{
/**
*
* #Route("/points/buy", name="points_buy")
*/
public function buyAction(Request $request)
{
\Stripe\Stripe::setApiKey('sk_test_');
return $this->render('points/buy.html.twig', [
]);
}
}
Stripe added with composer in vendor directory
I tried Stripe::setApiKey('sk_test_') but same error ...
Any idea?
If you're importing Stripe\Stripe in your use statement then I don't think you need the fully qualified class name.
use Stripe\Stripe;
//// etc.
/**
*
* #Route("/points/buy", name="points_buy")
*/
public function buyAction(Request $request)
{
Stripe::setApiKey($secretKey);
}
Here's a Stripe service I created for one of my projects.
I'm trying to getDoctrine() outside of the controller.
I've created this service:
config/services.yml
services:
update_command:
class: project\projBundle\Command\Update
arguments: ['#doctrine.orm.entity_manager']
and in my app/config/config.yml
imports:
- { resource: "#projectprojBundle/Resources/config/services.yml" }
so and the class that I want to use:
namespace project\projBundle\Command;
use Doctrine\ORM\EntityManager;
class Update {
protected $em;
public function __construct(EntityManager $em) {
$this->em = $em;
}
but every time I want to do this: (I'm doing this right?)
$up = new Update();
i got this error:
Catchable Fatal Error: Argument 1 passed to ...\Update::__construct() must be an instance of Doctrine\ORM\EntityManager, none given, called in .../Update.php line 7
Simple solution
If you're implementing a Symfony command (that can be executed in a cron tab), you can access the service container from the command.
<?php
namespace MyProject\MyBundle\Command;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Doctrine\ORM\EntityManager;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class UpdateCommand extends ContainerAwareCommand
{
protected $em;
protected function configure()
{
$this->setName('myproject:mybundle:update') ;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->em = $this->getContainer()->get('doctrine.orm.entity_manager');
}
}
That way, you get the entity manager from a command and don't need to declare this class as a service. You can therefore remove the configuration you added in the services.yml file.
An other solution (cleaner)
This solution allows better separation of concerns and can therefore be easily unit tested and reused in other parts of your Symfony application (not only as a command).
Move all the logic part of your "update" command to a dedicated class that you will declare as a service:
<?php
namespace MyProject\MyBundle\Service;
use Doctrine\ORM\EntityManager;
class MyUpdater
{
protected $em;
public function __construct($em)
{
$this->em = $em;
}
public function runUpdate()
{
// All your logic code here
}
}
Declare it as a service in your services.yml file:
services:
myproject.mybundle.myupdater:
class: MyProject\MyBundle\Service\MyUpdater
arguments: ['#doctrine.orm.entity_manager']
Simply call your service from your command :
<?php
namespace MyProject\MyBundle\Command;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class UpdateCommand extends ContainerAwareCommand
{
protected function configure()
{
$this->setName('myproject:mybundle:update') ;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$myUpdater = $this->getContainer()->get('myproject.mybundle.myupdater');
$myUpdater->runUpdate();
}
}
You have to either inject your newly created #update_command service or get it from the container in order to have the #doctrine.orm.entity_manager service injected automatically.
You're just creating the object with no argument, not a service. Update expects to retrieve an entity manager instance but you don't provide it.
$up = new Update();
In a ContainerAware class like a controller get your service like this:
$up = $this->container->get('update_command');
Otherwise turn the class where you want to use the update_command into a service aswell and inject #update_command as you did with the entity manager in the service itself.
remove below codes in app/config/config.yml, your services.yml will be autoload...
imports:
- { resource: "#projectprojBundle/Resources/config/services.yml" }
in a Action new a instance you can do:
$up = $this->get('update_command');
I am struggling with the combination of a Controller, an EntityRepository, and my Doctrine Fixtures in Symfony2.
My ImageParts Entity are pieces of images. I want to randomly generate images, using random pieces.
So, I have an entity called ImagePart, and an EntityRepository with the name 'ImagePartRepository'.
Within that EntityRepository, I created a function called 'getRandomImagePart()', which is working fine when testing it using a route.
But I cannot figure out how I can use this function within my fixtures. I THINK I have to declare a service, but even then I cannot get it to work. The type of error messages I get tells me that I'm clearly doing something structurally wrong.
Furthermore, I am wondering if I use the Symfony2 framework the correct way, functional. Eg: Should I be able to use an EntityRepository within my fixtures.
Controller:
<?php
namespace AMM\AMMBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\Finder\Finder;
use AMM\AMMBundle\Entity\ImagePart;
use Doctrine\ORM\Mapping as ORM;
class ImagePartController extends Controller implements ContainerAwareInterface
{
/**
* #var ContainerInterface
*/
protected $container;
/**
* {#inheritDoc}
*/
public function setContainer(ContainerInterface $container = null)
{
$this->container = $container;
}
public function getRandomImagePartAction($type)
{
/*
$sql = "
SELECT a.imagePartBase64 FROM imageparts a
WHERE a.imagePartCategory = '".$type."'
ORDER BY RAND()
LIMIT 1
";
*/
$em = $this->getDoctrine()
->getManager();
$imagePart = $em->createQueryBuilder()
->select('g')
->from('AMMBundle:ImagePart', 'i')
->addOrderBy('i.id', 'ASC')
->getQuery()
->getSingleResult();
// $conn = $this->get('database_connection');
//$randomimagepart = $conn->fetchAll($sql);
// return $randomimagepart[0]['imagePartBase64'];
return $imagePart;
}
// ..
public function generateRandomImage()
{
$object->getRandomImagePartAction('BACKGROUND');
}
Fixture file ImageFixtures.php
<?php
namespace AMM\AMMBundle\DataFixtures\ORM;
use Doctrine\Common\DataFixtures\FixtureInterface;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use AMM\AMMBundle\Entity\ImagePart;
class GenerateImages implements FixtureInterface, ContainerAwareInterface, OrderedFixtureInterface
{
private $container;
public function load(Objectmanager $manager)
{
$image= new Image();
$imageGenerator = $this->container
->get('imageGenerator')
->GenerateRandomImage();
$manager->persist($image);
$manager->flush();
}
My services.yml:
services:
imageGenerator:
class: AMM\AMMBundle\Controller\ImagePartController
So, basically what I do is call a function from a function in the same controller. This works fine when testing it, for example, in a view.
But when trying to load doctrine fixtures, the following error occurs:
Fatal error: Call to a member function has() on a non-object in C:\wamp\www\amm\vendor\symfony\symfony\src\Symfony\Bundle\FrameworkBundle\Controller\Controller.php on line 198
The end of the stack trace:
5.7077 41983128 15. AMM\AMMBundle\Controller\ImagePartController->getRandomImagePartAction() C:\wamp\www\amm\src\AMM\AMMBundle\Controller\ImagePartController.php:119
5.7077 41983128 16. Symfony\Bundle\FrameworkBundle\Controller\Controller->getDoctrine() C:\wamp\www\amm\src\AMM\AMMBundle\Controller\ImagePartController.php:44
Ok, I found the problem.
I had to add this to my services.yml:
calls: - [setContainer, [#service_container]] –