I'm a beginner in using symfony and i'm having trouble to test a function I just built, i have this error when I run php bin/phpunit tests/controller :
App\Tests\Controller\MailControllerTest::testMailIsSentAndContentIsOk
Symfony\Component\Config\Exception\LoaderLoadException: Expected to find class "App\Controller\MailController" in file "C:\wamp64\www\Marketplace\src/Controller\MailController.php" while importing services from resource "../src/*", but it was not found! Check the namespace prefix used with the resource in C:\wamp64\www\Marketplace\config/services.yaml (which is loaded in resource "C:\wamp64\www\Marketplace\config/services.yaml").
I tried fixing it and looking for a fix but it didn't help at all.
I have the class MailController which I want to test
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class MailController extends AbstractController
{
public function mail_inscription($destination, $name, \Swift_Mailer $mailer){
//etc etc
the class MailControllerTest.php which is testing the mailing function
<?php
//tests/controller/MailControllerTest.php
namespace App\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class MailControllerTest extends WebTestCase
{
public function testMailIsSentAndContentIsOk(): void
{
$client = static::createClient();
//etc etc
and here is the services.yaml which it's telling me to look at
parameters:
services:
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
App\:
resource: '../src/*'
exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
App\Controller\:
resource: '../src/Controller'
tags: ['controller.service_arguments']
I don't know what to do, if anyone got any leads, thanks a lot.
structure of my project
nevermind it was just because I had return $this->render(...); at the end xD sorry for bothering you
Related
I am encountering some weir behaviour with Symfony listener. I have a working configuration, but when I change or add something to the controller, Expected to find class "App\EventListener\AuthenticationSuccessListener" shows up. The change could be only something inside route path string. All code is here.
Remove cache and server restart doesn't help.
Listener
namespace AppBundle\EventListener;
use Lexik\Bundle\JWTAuthenticationBundle\Event\AuthenticationSuccessEvent;
use Lexik\Bundle\JWTAuthenticationBundle\Event\AuthenticationFailureEvent;
use Lexik\Bundle\JWTAuthenticationBundle\Response\JWTAuthenticationFailureResponse;
use Symfony\Component\Serializer\SerializerInterface;
class AuthenticationListener
{
/**
* #var SerializerInterface
*/
private $serializer;
public function __construct(SerializerInterface $serializer)
{
$this->serializer = $serializer;
}
/**
* #param AuthenticationSuccessEvent $event
*/
public function onAuthenticationSuccessResponse(AuthenticationSuccessEvent $event)
{
$event->setData([
'user' => $this->serializer->normalize($event->getUser(), null, ['groups' => ['basic']]),
'token' => $event->getData()['token'],
]);
}
}
services.yaml
# This file is the entry point to configure your own services.
# Files in the packages/ subdirectory configure your dependencies.
# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:
services:
app.event.authentication_success_response:
class: AppBundle\EventListener\AuthenticationListener
tags:
- { name: kernel.event_listener, event: lexik_jwt_authentication.on_authentication_success, method: onAuthenticationSuccessResponse }
# 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,Entity,Migrations,Tests,Kernel.php}'
# controllers are imported separately to make sure services can be injected
# as action arguments even if you don't extend any base controller class
App\Controller\:
resource: '../src/Controller'
tags: ['controller.service_arguments']
Controller
<?php
namespace App\Controller;
use App\Entity\User;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Serializer\SerializerInterface;
class ApiUserController extends AbstractController
{
/**
* #Route("/api/verify_token", methods="POST", name="api_verify_token")
* #IsGranted("ROLE_USER")
*/
public function verifyToken(User $user = null){
return new JsonResponse([], 200);
}
}
Solved by #Jakumi answer. The error was caused by namespace AppBundle\EventListener. After the change to App\EventListener error disappear.
I'm trying to refactor some controllers in Symfony 5 server, but suddenly I'm unable to change or create controllers because of the following error:
'App\Controller{{ControllerName}}' has no container set, did you forget to define it as a service subscriber?
This is the controller:
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Request;
use App\Entity\Shiftsummary;
use App\Entity\Station;
use App\Entity\Shift;
use App\Entity\Line;
use \Datetime;
class StartStationController extends AbstractController {
/**
* #Route("/start", name="StartStation")
*/
public function route(Request $request)
{
...
} }
This is the content of service.yaml
services:
_defaults:
autowire: true
autoconfigure: true
App\:
resource: '../src/*'
exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
App\Controller\:
resource: '../src/Controller'
tags: ['controller.service_arguments']
The controllers are inside the src/controller/ folder
The issue had to do with the cached files, deleting /var/cache made the error not occur.
Thanks go to Cerad for point this out.
I have to add that if you set the wrong namespace, you get this error too:
// src/Controller/Api/ProductController.php
namespace App\Controller;
class ProductController extends AbstractController {}
namespace must follow folders structure.
namespace App\Controller\Api;
this is just it, your controller did not have container injected. However, framework expects it to be done if your controller inherits from AbstractController.
in ControllerResolver.php:
TLDR; What you need is to inject it.
In your services.yaml, add the following setter call
In my case, the class had just a different name than the file.
You have to change:
namespace App\Controller;
with:
namespace App\Controller\Api;
None of above helped in my case.
I solved my case by:
calls:
- [setContainer, ["#service_container"]]
https://symfony.com/doc/5.4/service_container/calls.html
In my case it was an error in the controller name when I used the bin/console command :
bin/console make:controller APIController this command add automatically suffix -Controller to the file.
Then the controller created is called APIControllerController.
Next I made a copy/paste of Auth0 guide to create API nammed APIController.
In the end the file had the name APIControllerController.php and the class APIController: you just had to change the filename and remove the duplicate -Controller suffix.
Or - in general - verify the name of file controller and the class name ;)
(Another possibility, even more basic than the other suggestions:)
I had a simple controller that was requiring another PHP file, but in the course of some changes that required file couldn't even be compiled. Fixing that required file resolved the somewhat misleading "has no container set..." message.
I have just resolved this issue.
Turned out for me - I had miss typed __construct() as a private function, should be public
I was following Symfony docs and wanted to use ServiceEntityRepository (link).
I created entity:
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass="App\Repository\BetRepository")
*/
class Bet
{
....
Repository was automatically created:
namespace App\Repository;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Symfony\Bridge\Doctrine\RegistryInterface;
use App\Entity\Bet;
class BetRepository extends ServiceEntityRepository
{
public function __construct(RegistryInterface $registry)
{
parent::__construct($registry, Bet::class);
}
}
I wanted to create BetService which uses BetRepository:
namespace App\Service;
use App\Repository\BetRepository;
final class BetService
{
private $betRepository;
public function __construct(BetRepository $betRepository)
{
$this->betRepository = $betRepository;
}
finally I created a controller and wanted to inject BetService into it:
namespace App\Controller;
use App\Service\BetService;
final class BetController extends AbstractController
{
private $betService;
public function __construct(BetService $betService)
{
$this->betService = $betService;
}
}
Problem is I keep getting error:
Cannot autowire service "App\Repository\BetRepository": argument
"$registry" of method "__construct()" references interface
"Symfony\Bridge\Doctrine\RegistryInterface" but no such service
exists. Did you create a class that implements this interface?
my services.yaml is default one from installation:
parameters:
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.
public: false
# 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,Entity,Migrations,Tests,Kernel.php}'
# controllers are imported separately to make sure services can be injected
# as action arguments even if you don't extend any base controller class
App\Controller\:
resource: '../src/Controller'
tags: ['controller.service_arguments']
I am using Symfony 4.2
I tried autowiring EntityManager to BetRepository however I get error that EntityManager constructor is not public and tbh I feel this is not the right approach as docs say it should work out of box.
I can provide composer.json (didn't initially as already question is quite long)
Thanks everyone in advance!
I am having trouble accessing an injected service in the constructor of one of my controllers.
Per http://symfony.com/doc/current/service_container/injection_types.html I believe I have done the injection correctly, however when I try to load a view from the controller, I get the following error:
Argument 1 passed to Regions\AnalyticsBundle\Controller\PatternsController::__construct()
must be an instance of Regions\AnalyticsBundle\Controller\PatternCacheService, instance of
Regions\AnalyticsBundle\Service\PatternCacheService given, called
in /var/tmp/symfony/cache/dev/ContainerLoHUcSH/getPatternsControllerService.php on line 9
It seems like the error indicates that the type hinting in the constructor is trying making it look for an instance in the *\Controller\* namespace instead of the *\Services\* namespace - what am I doing wrong or not seeing here?
Details of my setup are as follows...
Symfony 4.1.0, PHP 7.2.5
services.yaml
services:
...
pattern_cache_service:
class: Regions\AnalyticsBundle\Service\PatternCacheService
public: true
Regions\AnalyticsBundle\Controller\PatternsController:
arguments: ['#pattern_cache_service']
Controller:
namespace Regions\AnalyticsBundle\Controller;
class PatternsController extends BaseController
{
private $pcs;
public function __construct(PatternCacheService $pcs)
{
$this->pcs = $pcs;
}
}
You forgot a use in your Controller, making PHP think that your service is in the same namespace as your controller.
<?php
namespace Regions\AnalyticsBundle\Controller;
use Regions\AnalyticsBundle\Service\PatternCacheService;
class PatternsController extends BaseController
{
private $pcs;
public function __construct(PatternCacheService $pcs)
{
$this->pcs = $pcs;
}
}
This was actually raised as part of your error message
Argument 1 passed to Regions\AnalyticsBundle\Controller\PatternsController::__construct()
must be an instance of Regions\AnalyticsBundle\Controller\PatternCacheService
When what you expected was your controller to need an instance of Regions\AnalyticsBundle\Service\PatternCacheService
The class PatternCacheService cannot be found in the namespace Regions\AnalyticsBundle\Controller.
Add an import:
<?php
namespace Regions\AnalyticsBundle\Controller;
use Regions\AnalyticsBundle\Service\PatternCacheService;
class PatternsController extends BaseController
{
private $pcs;
public function __construct(PatternCacheService $pcs)
{
$this->pcs = $pcs;
}
}
For reference, see
http://php.net/manual/en/language.namespaces.importing.php
You don't need a service definition for pattern_cache_service. It should autowire your service if autowire: true is set.
PatternCacheService should be private as you don't want to access it from within container. Suggested practise!
You don't need a service definition for PatternsController either.
Note: You should not use "bundles" anymore in Symfony 4 so I would get rid of AnalyticsBundle.
Note: Better organise your configuration files as show here: Organising route, service and parameter configuration files in symfony 4 applications.
This should suffice:
services.yaml
services:
_defaults:
autowire: true
autoconfigure: true
public: false
App\:
resource: '../src/*'
exclude: '../src/{Entity,....so on .....,Kernel.php}'
App\Controller\:
resource: '../../src/Regions/AnalyticsBundle/Controller'
tags: ['controller.service_arguments']
PatternsController
namespace Regions\AnalyticsBundle\Controller;
use Regions\AnalyticsBundle\Service\PatternCacheService;
class PatternsController
{
private $pcs;
public function __construct(PatternCacheService $pcs)
{
$this->pcs = $pcs;
}
}
I'm trying to access TokenStorageInterface inside a Utils Class, since I need to reuse code and I don't want to mess with internal logic inside the controllers.
But I get the following error when accessing the TokenStorage Interface from my class.
Type error: Too few arguments to function App\Utils\Ability::__construct(), 0 passed
Here is my class (I'll post just the __construct since that's the relevant part) :
<?php
namespace App\Utils;
use Doctrine\ORM\EntityManagerInterface;
class Ability
{
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
}
}
Any clues?
PS: Autowiring is enabled
Adding config\services.yaml :
parameters:
locale: 'en'
services:
_defaults:
autowire: true
autoconfigure: true
public: false
App\:
resource: '../src/*'
exclude: '../src/{Entity,Migrations,Tests,Kernel.php}'
App\Controller\:
resource: '../src/Controller'
tags: ['controller.service_arguments']