I'm trying to programmatically add an entity-manager, with reference to this documentation:
https://symfony.com/doc/6.0/doctrine/multiple_entity_managers.html
However, it needs to be created dynamically, so I'm triggering it by a controller. Unfortunately Symfony does not find the DoctrineConfig class ... although specified as in the docs.
namespace App\Controller;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Config\DoctrineConfig;
class AdministrationController extends AbstractController
{
#[Route('/api/create-org', methods:['POST'])]
public function setUpNewOrg(DoctrineConfig $doctrine)
{
$doctrine->dbal()
->connection('test')
->url('postgresql://Test:test1234127.0.0.1:5432/testDB')
->serverVersion('13')
->charset('utf8');
$emNew = $doctrine->orm()->entityManager('test');
$emNew->mapping('test')
->isBundle(false)
->type('annotation')
->dir('%kernel.project_dir%/src/Entity')
->prefix('App\Entity')
->alias('App');
return $this->json([ 'message' => 'configured' ]);
}
}
However, this leads to following error message:
Cannot resolve argument $doctrine of
"App\Controller\AdministrationController::setUpNewOrg()": Cannot
determine controller argument for
"App\Controller\AdministrationController::setUpNewOrg()": the
$doctrine argument is type-hinted with the non-existent class or
interface: "Symfony\Config\DoctrineConfig".
Does this just not work within a Controller?
Symfony version: 6.0.7
PHP version: 8.1.6
Related
When I inject the Request class of Simfony it works well for me, but I just created a class called FormRequest that "extends" from Request, I thought this would work, since it is still a Request instance, but it is not, I get an error.
Type error: Argument 1 passed to AppBundle\Http\Controllers\BlogController::validateAction() must be an instance of AppBundle\Http\FormRequest, instance of Symfony\Component\HttpFoundation\Request given, called in /var/www/html/api-erp/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php on line 151
Exception
My class FormRequest.php:
namespace AppBundle\Http;
use Symfony\Component\HttpFoundation\{JsonResponse, Request, Response};
class FormRequest extends Request
{
}
Controller BlogController.php is:
<?php
namespace AppBundle\Http\Controllers;
use AppBundle\Http\FormRequest;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\{Request, JsonResponse};
use Symfony\Component\Routing\Annotation\Route;
class BlogController extends Controller
{
/**
* #Route("/blog", name="blog_index")
*/
public function validateAction(FormRequest $request)
{
return new JsonResponse(['success' => true]);
}
}
Simfony versiĆ³n: 3.4.*
You missing something.
Symfony use the ParamConverter feature to inject the request in your action. If you want to override it you also have to create a custom converter and use the correct priority in the service to avoid the error.
More explanation in symfony documentation
I created src/Controller file named as sampleController.php:
<?php
namespace App\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class sampleController extends Controller
{
/**
* #Route("/hello")
*/
public function number()
{
$number = mt_rand(0, 100);
return $this->render('sample/number.html.twig', array(
'number' => $number,
));
}
}
My twig file is this:
<h1>Number is: {{ number }}</h1>
And routes.yaml is this:
sample_asd:
path: /hello
controller: App\Controller\sampleController::number
I've installed annotations and --dev profiler. But when I navigate to http://localhost:8000/hello it gives:
HTTP 500 Internal Server Error
[Semantical Error] The annotation "#Route" in method App\Controller\sampleController::number() was never imported. Did you maybe forget to add a "use" statement for this annotation? in C:\xampp\htdocs\Projects\symfony_learning\config/routes../../src/Controller/ (which is being imported from "C:\xampp\htdocs\Projects\symfony_learning\config/routes/annotations.yaml"). Make sure annotations are installed and enabled.
I didn't understand what is the problem.
Thanks
You did forget to include annotation class. Try to add this.
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
Update
For symfony 4 you should use this path.
use Symfony\Component\Routing\Annotation\Route;
I've recently updated my MAMP server to PHP 7.1 and build a project with Cakephp 3.x. But I get a strange 500 (Internal Server Error) error when I use the afterSave() callback.
The documentation lifecycle-callbacks describes the following:
public function afterSave(Event $event, EntityInterface $entity, ArrayObject $options) {
// some action
}
When I use PHP 7.1 it will give's me a 500 error, but if I use PHP 5.6 it will work for me.
Now I've fixed this 500 error on PHP 7.1 by no longer defining the types inside the function. But is this the correct way to do this?
public function afterSave($event, $entity, $options) {
// some action
}
Update:
My error log says:
2017-05-06 13:38:09 Error: [TypeError] Argument 1 passed to
Storages\Model\Table\StoragecontainerBlockElementsTable::afterSave()
must be an instance of Storages\Model\Table\Event, instance of
Cake\Event\Event given, called in
/Applications/MAMP/htdocs/safebend-community-data-center/community/vendor/cakephp/cakephp/src/Event/EventManager.php
on line 414 Request URL: /storages/blocks/dsdsdsd/ajaxAddElement
Referer URL:
http://localhost:8888/safebend-community-data-center/community/storages/blocks/dsdsdsd
My Table with namespace:
namespace Storages\Model\Table;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
use Cake\ORM\TableRegistry;
class StoragecontainerBlockElementsTable extends Table {
public function afterSave(Event $event, EntityInterface $entity, ArrayObject $options) {
// some action
}
}
My Controller with Namespace:
namespace Storages\Controller;
use App\Controller\AppController;
use Cake\Log\Log;
use Cake\ORM\TableRegistry;
class StoragecontainerBlocksController extends AppController { }
You haven't import the used names, hence Event will refer to the current namespace, ie the argument will be typed as \Storages\Model\Table\Event instead of the expected \Cake\Event\Event. The same problem exists for the two other arguments.
Import the class names and you should be good:
use ArrayObject;
use Cake\Datasource\EntityInterface;
use Cake\Event\Event;
Failing to do so should cause an error in any PHP version though (given that the method is being invoked).
I am using the FOS Message Bundle, but it looks like it doesn't recognize the following method:
$threads = $this->getProvider()->getInboxThreads();
I get this errormessage:
Attempted to call an undefined method named "getProvider" of class "AppBundle\Controller\MessageController"
Here is the code for the controller:
namespace AppBundle\Controller;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\DependencyInjection\ContainerAware;
use Symfony\Component\HttpFoundation\RedirectResponse;
use FOS\MessageBundle\Provider\ProviderInterface;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
class MessageController extends ContainerAware
{
/**
* #Route("/messages/", name="messages_home")
*/
public function inboxAction()
{
$threads = $this->getProvider()->getInboxThreads();
return $this->container->get('templating')->renderResponse('inbox/inbox.html.twig', array(
'threads' => $threads
));
}
}
I suspected it had something to do with my usings, but I changed it and that didn't seem to help me...
You just trying to use method getProvider() from current object. $this is pointer current object of MessageController what extends ContainerAware. If these both classes (and their parents) do not has getProvider() method, throwing is an error.
I see you just imported use FOS\MessageBundle\Provider\ProviderInterface; instance. Reading the FOSMessageBundle documentation:
Get the threads in the inbox of the authenticated user::
$provider = $container->get('fos_message.provider');
$threads = $provider->getInboxThreads();
Also you need to register provider in container earlier (read more on Setting up FOSMessageBundle and Basic Usage of FOSMessageBundle).
According to Symfony2 Cookbook I'm trying to secure controller via dependecy injection, but I'm getting error Catchable Fatal Error: Argument 1 passed to Acme\ExampleBundle\Controller\DefaultController::__construct() must implement interface Symfony\Component\Security\Core\SecurityContextInterface, none given, called in /var/www/example/app/cache/dev/classes.php on line 4706 and defined in /var/www/example/src/Acme/ExampleBundle/Controller/DefaultController.php line 13
Here is my services.yml
parameters:
acme_example.default.class: Acme\ExampleBundle\Controller\DefaultController
services:
acme_example.default:
class: %acme_example.default.class%
arguments: [#security.context]
and controller:
namespace Acme\ExampleBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
class DefaultController extends Controller {
public function __construct(SecurityContextInterface $securityContext)
{
if(false === $securityContext->isGranted('IS_AUTHENTICATED_FULLY'))
{
throw new AccessDeniedException();
}
}
public function indexAction()
{
return new Response('OK');
}
}
If you configure your controllers as services you need to use a slightly different syntax when referencing them in your routes. Instead of AcmeExampleBundle:Default:index you should use acme_example.default:indexAction.
Make sure you use Symfony\Component\Security\Core\SecurityContextInterface; in your controller. Without it, the SecurityContextInterface type hint in the constructor won't resolve.
Also, make sure your controller is actually being called as a service. The error you posted is complaining that nothing was sent to the constructor, which sounds to me like you're using your controller the 'default' way. See this cookbook page on how to setup a controller as a service.
The class Symfony\Bundle\FrameworkBundle\Controller\Controller extends ContainerAware base class. This class ha whole the container accessible via $container local property, so you should not inject any services to a controller service, because you can access SecurityContext via $this->container->get('security.context').