I changed directory structure in Symfony and I want it to work without success.
Autoload:
"autoload": {
"psr-4": {
"D2D\\": "src/"
}
},
Front controller (public\index.php):
<?php
declare(strict_types=1);
use D2D\Shared\Infrastructure\SymfonyKernel;
use Symfony\Component\HttpFoundation\Request;
require dirname(__DIR__).'/vendor/autoload.php';
$kernel = new SymfonyKernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']);
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);
Kernel (src\Shared\Infrastructure\SymfonyKernel.php):
<?php
namespace D2D\Shared\Infrastructure;
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;
class SymfonyKernel extends BaseKernel
{
use MicroKernelTrait;
... everything else as default
}
Error I get:
Attempted to load class "Kernel" from namespace "App". Did you forget
a "use" statement for "Symfony\Component\HttpKernel\Kernel"?
I forgot that cli commands are going through bin/console so I had to change namespace for SymfonyKernel there because it's separate environment that creates kernel.
Related
I'm making simple "MyCoreBundle" (MystertyCoreBundle) using symfony6.1 how to make bundle's doc.
I defined my bundle class vendor/mysterty/core-bundle/CoreBundle.class
<?php
namespace Mysterty\CoreBundle;
use Symfony\Component\HttpKernel\Bundle\AbstractBundle;
class MystertyCoreBundle extends AbstractBundle
{
}
I defined some parameters and configuration in vendor/mysterty/core-bundle/config/services.yaml as defaults :
services:
Mysterty\CoreBundle\Controller\CoreController:
public: true
calls:
- method: setContainer
arguments: ["#service_container"]
parameters:
app.admin_email: "mymailATserver.com"
Then I made simple controller in vendor/mysterty/core-bundle/src/Controller/CoreController.php:
<?php
namespace Mysterty\CoreBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Contracts\Translation\TranslatorInterface;
class CoreController extends AbstractController
{
#[Route('/', name: 'mty_default')]
public function indexNoLocale(): Response
{
$lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
$supportedLangs = explode('|', $this->getParameter('app.supported_locales'));
$lang = in_array($lang, $supportedLangs) ? $lang : $supportedLangs[0];
return $this->redirectToRoute('mty_home', ['_locale' => $lang]);
}
Finally, i added the bundle's routes to \config\routes.yaml
mysterty_core:
resource: "../vendor/mysterty/core-bundle/src/Controller/CoreController.php"
type: annotation
prefix: /
Here is the error i have on http://127.0.0.1:8000/ :
"Mysterty\CoreBundle\Controller\CoreController" has no container set, did you forget to define it as a service subscriber?
I try to make a shared bundle with default actions and components for all my symfony projects.
Solution (thx to helpers)
define loadExtension function in MyOwnBundle.php :
<?php
namespace MyOwn\MyOwnBundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Symfony\Component\HttpKernel\Bundle\AbstractBundle;
class MyOwnBundle extends AbstractBundle
{
public function loadExtension(array $config, ContainerConfigurator $container, ContainerBuilder $builder): void
{
// load an XML, PHP or Yaml file
$container->import('../config/services.yaml');
}
}
It looks like Symfiony could not autoconfigure your controller. Try adding the #[AsController] attribute to your controller classes or add autoconfigure: true to your controller service definition in your services.yaml
I am porting a custom bundle that was created originally for symfony 2 to Symfony 5.
Inside the bundle there is a listener with this function:
public function onEarlyKernelRequest(RequestEvent $event)
{
if (!$tenant = $this->tenantStrategy->getTenant()) {
$this->dispatcher->dispatch($tEvent = new TenantEvent(null, $event), TenantEvents::TENANT_NOT_FOUND);
if (!$tEvent->getTenant()) {
return;
}
}
$this->dispatcher->dispatch(new TenantEvent($tenant, $event), TenantEvents::TENANT_FOUND);
//$this->container->set('synd_multitenant.tenant', $tenant);
}
When I remove the comment from the last line I get this error:
The "synd_multitenant.tenant" service is already initialized, you cannot replace it.
With that line commented out, When I try to get the service from the controller I get this message:
Service "synd_multitenant.tenant" not found: even though it exists in the app's container, the container inside "App\Controller\DefaultController" is a smaller service locator that only knows about the "doctrine", "form.factory", "http_kernel", "parameter_bag", "request_stack", "router", "security.authorization_checker", "security.csrf.token_manager", "security.token_storage", "serializer", "session" and "twig" services. Try using dependency injection instead.
And in case it is relevant, I had to change to RequestEvent from GetResponseEvent because GetResponseEvent is not supported anymore.
Here is the controller where I am trying to use the service:
<?php
namespace App\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use App\Repository\ClientRepository;
class DefaultController extends AbstractController {
function index() {
//$entityManager = $this->getDoctrine()->getManager();
//$clientRepository = $entityManager->getRepository('App\Entity\Client');
//$client = $clientRepository->findOneBy(array('domain' => 'someclient.mysymfony.local'));
$client = $this->get('synd_multitenant.tenant');
return new Response(
'<html><body>Welcome to My Symfony 5 demo!'.
'<br>Client: ' . $client->getDomain() .
'</body></html>'
);
}
}
Here is the output of console debug:
$ php bin/console debug:container synd_multitenant.tenant
Information for Service "synd_multitenant.tenant"
=================================================
---------------- -----------------------------------------------
Option Value
---------------- -----------------------------------------------
Service ID synd_multitenant.tenant
Class Synd\MultiTenantBundle\Entity\TenantInterface
Tags -
Public yes
Synthetic no
Lazy no
Shared yes
Abstract no
Autowired yes
Autoconfigured yes
---------------- -----------------------------------------------
The complete code is available at this github repository: https://github.com/karimmtl/Mysymfony5
Thanks
found out that the tentant service class name is
\Synd\MultiTenantBundle\Entity\TenantInterface
in the bundles service.yaml file.
Try to change your controller so that you inject the service:
namespace App\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use App\Repository\ClientRepository;
use Synd\MultiTenantBundle\Entity\TenantInterface;
class DefaultController extends AbstractController
{
function index(TenantInterface $client)
{
return new Response(
'<html><body>Welcome to My Symfony 5 demo!'.
'<br>Client: ' . $client->getDomain() .
'</body></html>'
);
}
}
I am new with symfony i am trying to use the constructor but it doesn't work and i don't understand why
error:
Cannot autowire service \App\Controller\OutputController argument $product of method &__construct() references class App\Entity\Product but no such service exists.
<?php
namespace App\Controller;
use App\Entity\Product;
class OutputController {
private $product;
public function __construct(Product $product)
{
$this->product = $product;
}
public function jsonFormat() {
return json_encode($this->product->toArray());
}
}
?>
thanks
You use autowiring and you try to autowire a entity. By default they are not exposed as services by this config line from the default app/config/services.yml:
App\:
resource: '../src/*'
exclude: '../src/{Entity,Migrations,Tests,Kernel.php}'
As you can see, symfony exposes all files from src/* except from:
Entity,Migrations,Tests,Kernel.php
You should not expose entities as services and you should not rely on entities in your controller, Use services for that
Working on Symfony 2.7 -
I created a new service (ipad.registerchecksum) in a custom bundle and now I try to use it as an argument in another service (ipad.download_history) in another custom bundle but I get the following error :
The service "ipad.download_history" has a dependency on a non-existent
service "ipad.registerchecksum".
Creation of my service :
<?php
namespace MyCompany\MyBundle2\Services;
class Registerchecksum
{
public function sayHello()
{
return "Hello";
}
}
?>
Register my class as Service :
#MyCompany\MyBundle2\Resources\Config\services.yml
services:
ipad.registerchecksum:
class: MyCompany\MyBundle2\Services\Registerchecksum
Load my services.yml :
<?php
namespace MyCompany\MyBundle2\DependencyInjection;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader;
class MyBundle2Extension extends Extension
{
public function load(array $configs, ContainerBuilder $container)
{
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('datagrid/datagrids.yml');
$loader->load('navigation.yml');
$loader->load('services.yml');
}
// Please note : navigation.yml and datagrid/datagrids.yml are well loaded and work perfectly
}
?>
.. the service seems not to be registered.
If I test "/app/console container:debug", it doesn't appear.
I already clean caches (dev & prod), warmup caches too.
$ rm -rf app/cache/*
#MyCompany\MyBundle2\Resources\Config\services.yml
services:
ipad.registerchecksum:
class: MyCompany\MyBundle2\Services\Registerchecksum
ipad.download_history:
class: Your Service
arguments: ["#ipad.registerchecksum"]
I am using Symfony 3.4.0, I try to load fixtures with:
php bin/console doctrine:fixtures:load
An error occurred while creating the data, what's wrong?
This command looks for all services tagged with doctrine.fixture.orm.
There is two ways to fix this problem.
First one: any class that implements ORMFixtureInterface will automatically be registered with this tag.
<?php
namespace AppBundle\DataFixtures\ORM;
use Doctrine\Bundle\FixturesBundle\ORMFixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
class LoadFixtures implements ORMFixtureInterface
{
public function load(ObjectManager $manager)
{
#your code
}
}
Second one: You need manually tag doctrine.fixture.orm to DataFixtures in sevice.yml configuration.
services:
...
# makes classes in src/AppBundle/DataFixtures available to be used as services
# and have a tag that allows actions to type-hint services
AppBundle\DataFixtures\:
resource: '../../src/AppBundle/DataFixtures'
tags: ['doctrine.fixture.orm']
I tried #Alexander's solution but it's doesn't work for me.
I had resolved the same problem by adding the tag service to the class, Symfony doc on the services.yml file bundle:
BlogBundle/Resources/config/services.yml
Services:
...
# Fixtures services
BlogBundle\DataFixtures\ORM\PostFixture:
tags: [doctrine.fixture.orm]
...
My BlogBundle/DataFixtures/ORM/PostFixture.php class :
...
use Doctrine\Common\DataFixtures\FixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
...
class PostFixture implements FixtureInterface
{
public function load(ObjectManager $manager)
{
...
}
}
Source Inspiration : Synfony doc -> Service container -> The autoconfigure Option
Hope it'll an alternative solution
Example for reusable bundle.
src/Acme/Bundle/UserBundle/DataFixtures/ORM/DataFixtures.php
<?php
namespace Acme\Bundle\UserBundle\DataFixtures\ORM;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\Persistence\ObjectManager;
class DataFixtures extends Fixture
{
/**
* Load data fixtures with the passed EntityManager
*
* #param ObjectManager $manager
*/
public function load(ObjectManager $manager)
{
#your code
}
}
in app/config/services.yml
Acme\Bundle\UserBundle\DataFixtures\:
resource: '../../src/Acme/Bundle/UserBundle/DataFixtures/'
append your fixtures data:
php bin/console doctrine:fixtures:load --append
In 4.0.1 I have to implement service configuration to show Symfony my DataFixtures folder:
in config/services.yaml
services:
...
App\DataFixtures\:
resource: '%kernel.project_dir%/src/DataFixtures'
tags: [doctrine.fixture.orm]
if my class IMPLEMENTS FixtureInterface and without this config if it is EXTENDS Fixture
~/dev/domain.lan/src/ProductBundle/DataFixtures/ORM/ProductFixture.php
<?php
namespace ProductBundle\DataFixtures\ORM;
use Doctrine\Bundle\FixturesBundle\FixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use ProductBundle\Entity\Product;
class ProductFixture implements FixtureInterface
{
public function load(ObjectManager $manager)
{
// create 20 products! Bam!
for ($i = 0; $i < 20; $i++) {
$product = new Product();
$product->setName('Product name' . $i);
$manager->persist($product);
}
$manager->flush();
}
}
The problem is solved it was necessary to add a service: (app/config/services.yml)
services:
# Product service
ProductBundle\:
resource: '../../src/ProductBundle/*'
exclude: '../../src/ProductBundle/{Entity,Repository,Tests}'
use Doctrine\Bundle\FixturesBundle\Fixture
class ProductFixture extends Fixture implements FixtureInterface
see documentation: http://symfony.com/doc/current/bundles/DoctrineFixturesBundle/index.html
After long research, found a solution.
This work with :
doctrine/doctrine-fixtures-bundle: ^3.0,
Symfony ^3.3
First
Define your Fixture.
<?php
namespace Where\MyFixtureBundle\FileFolder\IsLocated;
use Doctrine\Common\DataFixtures\FixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use Nao\UserBundle\Entity\User;
class LoadData implements FixtureInterface
{
/**
* Load data fixtures with the passed EntityManager
*
* #param ObjectManager $manager
*/
public function load(ObjectManager $manager){
$object = new Entity();
$object->setFoo(bar)
...
$manager->persist($object);
$manager->flush();
}
}
Next, define a service in the bundle's service.yml file or directly in
"app/config/service.yml" (not recommanded)
# Fixtures service
your_service.name:
class: Full\Namespce\With\TheClassFixtureName
tags: [doctrine.fixture.orm] <-- important
Don't forget, just to be sure the following
composer du -o or composer dump-autoload -o
Try to execute your command now for load your data fixtures.
I also had to update the app/AppKernel.php and added the following the the bundles array:
new Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle()
After read above comment, i found solution inside #GuRu answer's :
"Second one: You need manually tag doctrine.fixture.orm to DataFixtures in sevice.yml configuration".
Then implements ORMFixtureInterface in your fixtures class.
. in fact, we have to add additionnal configuration inside services.yml to solve it.
Important to know, i notice this issue in version ~3.4 of symfony.
Best regard
I'm jumping here after several years just to document for myself the mixed of solution that I found in this thread.
I experienced the same issue and find the solution by using multiple answers and I hope it will help.
This were my code:
namespace App\DataFixtures;
use App\Entity\Book;
use App\Factory\{BookFactory, UserFactory};
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;
class AppFixtures extends Fixture
{
public function load(ObjectManager $manager): void
{
UserFactory::new()->createOne([
'email' => 'user2#user.hr',
'roles' => ['ROLE_ADMIN']
]);
UserFactory::new()->createOne([
'email' => 'user3#user.hr',
'roles' => ['ROLE_USER']
]);
BookFactory::new()->createMany(25);
$manager->flush();
}
}
so I changed replaced extends Fixture ORMFixtureInterface. So new code looks like this:
namespace App\DataFixtures;
use App\Entity\Book;
use App\Factory\{BookFactory, UserFactory};
use Doctrine\Bundle\FixturesBundle\ORMFixtureInterface;
use Doctrine\Persistence\ObjectManager;
class AppFixtures implements ORMFixtureInterface
{
public function load(ObjectManager $manager): void
{
UserFactory::new()->createOne([
'email' => 'user2#user.hr',
'roles' => ['ROLE_ADMIN']
]);
UserFactory::new()->createOne([
'email' => 'user3#user.hr',
'roles' => ['ROLE_USER']
]);
BookFactory::new()->createMany(25);
$manager->flush();
}
}
then I went to services.yml and the I inserted this:
App\DataFixtures\:
resource: '%kernel.project_dir%/src/DataFixtures'
tags: ['doctrine.fixture.orm']
so services.yml file looks like this:
services:
# default configuration for services in *this* file
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\:
resource: '../src/'
exclude:
- '../src/DependencyInjection/'
- '../src/Entity/'
- '../src/Kernel.php'
App\DataFixtures\:
resource: '%kernel.project_dir%/src/DataFixtures'
tags: ['doctrine.fixture.orm']
# add more service definitions when explicit configuration is needed
# please note that last definitions always *replace* previous ones
and then, like #Spartacvs1 suggested, in your terminal execute this
composer dump-autoload -o