I'm using FOSUserbunble, how can access the user object from another controller/form in another bunble?
for example I have a BlogBundle and when I create a new post I need to save the userId in the post table.
for the form I'm using buildForm extending AbstractType.
thanks
Try $user = $this->getUser();
You can do it via SecurityContext.
let's a example ..
namespace YourPackage\UserBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use FOS\UserBundle\Model\UserInterface;
class YourController extends Controller{
/**
* Fetch a user object.
*
* #Route("/yourRoute", name="your_route")
* #Method()
* #Template()
*/
public function yourAction(Request $request)
{
$user = $this->container->get('security.context')->getToken()->getUser();
return $this->redirect($this->generateUrl('your_route'));
}}
Related
Maybe im just missing it, I would like to hide some rest methods from controllers that do not implement them like options , delete, head
Is there an annotation for this? I could not find it in the documentation
using https://github.com/nelmio/NelmioApiDocBundle v3
currently when i view /api/doc any controllers I add list all rest methods even if I only have a GET method implemented.
<?php
namespace ApiBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\JsonResponse;
use Swagger\Annotations as SWG;
class UserController extends Controller
{
/**
* #Security("is_granted('IS_AUTHENTICATED_FULLY')")
* #Route("/api/users", name="get_users", methods={"GET"})
*
* #SWG\Response(
* response=200,
* description="Returns all users"
* )
* #SWG\Tag(name="users")
*
*
* #return \Symfony\Component\HttpFoundation\JsonResponse
*/
public function getUsersAction()
{
$repo = $this->getDoctrine()
->getRepository('AccountBundle:User');
$users = $repo->createQueryBuilder('q')
->getQuery()
->getArrayResult();
return new JsonResponse($users);
}
}
Just figured it out if you do not specify the methods in the controller in the #Route() annotation then it will show all of them but if you add methods={} to the Route annotation then it will only list the defined methods
* #Route("/api/users", name="get_users", methods={"GET"})
Specify #Value and #method type in the #RequestMapping
#RequestMapping(value="/instances/all",method=RequestMethod.GET)
#JsonFormat
public String showInstances(){
return "instances";
}
I'm trying to work with Entity Repository to write my custom functions.
I have an Entity and his Repository generated from yaml file
Yaml file
Bluesys\WeekupBundle\Entity\Event:
type: entity
repositoryClass: Bluesys\WeekupBundle\Repository\Event
fields:
id:
id: true
type: integer
generator:
strategy: AUTO
...
Entity code automatically generated
namespace Bluesys\WeekupBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Event
*/
class Event
{
/**
* #var integer
*/
private $id;
...
}
Repository code automatically generated
I juste wrote the function isHidden
namespace Bluesys\WeekupBundle\Repository;
use Doctrine\ORM\EntityRepository;
/**
* Event
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class Event extends EntityRepository
{
/**
* isHidden
*
* #return bool
*/
public function isHidden()
{
return true;
}
}
The Controller code
namespace Bluesys\WeekupBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Bluesys\WeekupBundle\Event\Event;
...
class TimelineController extends Controller
{
public function testAction(){
$repository = $this->getDoctrine()->getManager()->getRepository('BluesysWeekupBundle:Event');
$event = $repository->findOneById( 73 );
return $this->render('BluesysWeekupBundle::test.html.twig', array( 'event' => $event ));
}
...
And the view code
{{ event.isHidden }}
I get this error :
Method "isHidden" for object "Bluesys\WeekupBundle\Entity\Event" does not exist in BluesysWeekupBundle::test.html.twig at line 1
Can somebody help me by telling me what is missing ?
Repository classes are used only for selecting/fetching data. They are not the part of entity/object.
If you really want to call isHidden method by repository you can acheive this by passing the whole repository to template (return $this->render('BluesysWeekupBundle::test.html.twig', array( 'event' => $repository ));), but this is very bad idea.
Instead you can put isHidden() method into your entity class and call it as event.isHidden..
Am using symfony framework for my application. And to save records in database I want call the $this->getDoctrine()->getManager(); method in my entity class. But when I did that it gave me the error:
Call to undefined method getDoctrine(),
Can some one tell me what is the right way to do this.
My entity class is like:
namespace Acme\SuperbAppBundle\Entity;
use Symfony\Component\DependencyInjection\Container;
use Doctrine\ORM\Mapping as ORM;
class Users
{
/**
* #var integer
*/
private $id;
/**
* #var string
*/
private $firstName;
/**
* #var string
*/
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set firstName
*
* #param string $firstName
* #return Users
*/
public function setFirstName($firstName)
{
$this->firstName = $firstName;
return $this;
}
/**
* Get firstName
*
* #return string
*/
public function getFirstName()
{
return $this->firstName;
}
function __construct($firstName){
$this->setFirstName($firstName);
}
function save(){
$em = $this->getDoctrine()->getManager();
$em->persist($create);
$em->flush();
}
}
And my controller method is like:
public function test(){
$create = new Users('Rajat');
$create->save();
}
Your save method is attempting to call
$this->getDoctrine();
Whereby $this is the current Class, and any other Class it inherits. As it stands, your current Class, User, is standalone, and does not have a getDoctrine() method. If your Class were to extend the Controller Class, it would have access to that method:
class User extends Controller
I believe this simple fix will work, although it probably doesn't make real sense for it to extend Controller, as it is a User Entity, and unrelated to a Controller. A preferred, more advanced method, would be to inject the Doctrine service into the User class.
Ok, first of all Doctrine Entities :
Handle the entity generation and configuration
Declare the operations on the setters and getters.
If you wana save an object into your entity there it's your User, you have two way to store this user:
One:
You can use entity manager to store a user and the entity will help you to create the right object using the seters and getters:
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use PATH\TO\Users;
class ExampleController extends Controller
{
public function examplefunction()
{
$em = $this->getDoctrine()->getManager();
$entity = new Users();
$entity->setFirstName('Rajat');
$em->persist($entity);
$em->flush();
}
}
The other way is to create this entry using QueryBuilder but it's a bad way in your case.
Oh, i forgot please delete the save method in your entity Doctrine manager allready implement it.
Your controller probably doesnt extends Symfony\Bundle\FrameworkBundle\Controller\Controller ...
You should have controller defined like this example:
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class DefaultController extends Controller
{
}
Entity class does not extends ContainerAware / Controller, so you can't call $this->getDoctrine()->getManager(). I don't think your Entity class should extend to a Controller. Because your entity class will become a controller instance just because you want to access the doctrine manager. That's a not good practice. What you can do is inject doctrine manager to your Entity class through services.
I wrote a blog few weeks ago regarding injecting services container and accessing through constructor. You can inject doctrine entity manager in the same way you inject services container. You can take a look at that if you like :- http://anjanasilva.com/blog/injecting-services-in-symfony-2/
Here's a nice question regarding injecting doctrine manager. Make sure you read the answer as well. :- Symfony 2 EntityManager injection in service
And another nice tutorial on injecting custom repository manager instead of injecting the whole entity manager. Which I believe even a good solution. :- http://php-and-symfony.matthiasnoback.nl/2014/05/inject-a-repository-instead-of-an-entity-manager/
Hope this helps to increase your understanding about Symfony 2.
Cheers!
I am using FOSUserBundle in Symfony 2.3, I created an additional table for store the user profile, at some point, I need to access to the entity manager to persist and flush the data coming from the profile form to the profile table, but I am having problems trying to get an instance of the entity manager.
Any idea?
Thanks!
To edit profiles of users using the FOSUserBundle, you have to create a new ProfileController which extends the ProfileController of FOSUserBundle.
Here you can now override methods of the FOSUserBundle.
An exemple of start :
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Acme\UserBundle\Controller;
use FOS\UserBundle\Model\UserInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use FOS\UserBundle\Controller\ProfileController as BaseController;
/**
* Controller managing the user profile
*
* #author Christophe Coevoet <stof#notk.org>
*/
class ProfileController extends BaseController
{
public function editAction()
{
$em = $this->container->get('doctrine')->getManager();
// your code here
}
}
You can access to the Doctrine service this way :
$em = $this->container->get('doctrine')->getManager();
The controllers of the FOSUserBundle extend from Symfony\Component\DependencyInjection\ContainerAware. So you have access to the Symfony\Component\DependencyInjection\ContainerInterface through $this->container. With this container you can access doctrine and subequently the EntityManager:
$doctrine = $this->container->get('doctrine');
$em = $doctrine->getManager();
I'd like to use, something like:
$em = $this->getEntityManager();
Inside a Entity.
I understand I should do this as a service but for some testing purposes, I want to access it from an Entity.
Is it possible to achieve that?
I've tried to:
$em = $this->getEntityManager();
$profile_avatar = $em->getRepository('bundle:Perfils')->findOneByUser($this-getId());
But isn't working.
Fatal error: Call to undefined method
Proxies\webBundleEntityUserProxy::getEntityManager() in
/opt/lampp/htdocs/web/src/Pct/bundle/Entity/User.php on line
449
Why am I trying to do it this way?
I've 3 kinds of users: Facebook, Twitter and MyOwnWebsite users. Each of them have differents avatar which links facebook's profile, twitter's or otherwise, if its myownwebsite user, I retrieve the avatar from a URL in a database. For now, I don't want to create a service, because I'm just trying to make it working, to test it, not to create a final deployment. So this is why I'm trying to call Entity manager from an Entity. I don't want, by now, to modify configuration files, just this entity.
As pointed out (again) by a commenter, an entity manager inside an entity is a code smell. For the OP's specific situation where he wished to acquire the entity manager, with the least bother, a simple setter injection would be most reliable (contrary to my original example injecting via constructor).
For anyone else ending up here looking for a superior solution to the same problem, there are 2 ways to achieve this:
Implementing the ObjectManagerAware interface as suggested by https://stackoverflow.com/a/24766285/1349295
use Doctrine\Common\Persistence\ObjectManagerAware;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
*/
class Entity implements ObjectManagerAware
{
public function injectObjectManager(
ObjectManager $objectManager,
ClassMetadata $classMetadata
) {
$this->em = $objectManager;
}
}
Or, using the #postLoad/#postPersist life cycle callbacks and acquiring the entity manager using the LifecycleEventArgs argument as suggested by https://stackoverflow.com/a/23793897/1349295
use Doctrine\Common\Persistence\Event\LifecycleEventArgs;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\HasLifecycleCallbacks()
*/
class Entity
{
/**
* #ORM\PostLoad
* #ORM\PostPersist
*/
public function fetchEntityManager(LifecycleEventArgs $args)
{
$this->setEntityManager($args->getEntityManager());
}
}
Original answer
Using an EntityManager from within an Entity is VERY BAD PRACTICE. Doing so defeats the purpose of decoupling query and persist operations from the entity itself.
But, if you really, really, really need an entity manager in an entity and cannot do otherwise then inject it into the entity.
class Entity
{
private $em;
public function __contruct($em)
{
$this->em = $em;
}
}
Then invoke as new Entity($em).
Best way is to use Life Cycle: #ORM\HasLifecycleCallbacks
And you can use the appropriate Event as you want to get result:
#postLoad
#postPersist
...
Calling the Entity Manager from inside an Entity is a bad practice! You should keep your entities as simple as possible.
For what purpose do you need to call the Entity Manager from an Entity?
What I think you should do is, instead of using the Entity Manager inside your entity, is to create a custom repository for your entity.
In your entity ORM file, add an entry as follows (or in your entity class annotations if not using YML):
App\Bundle\Profils:
# Replace the above as appropiate
type: entity
table: (your table)
....
repositoryClass: App\Bundle\CustomRepos\ProfilsRepository
# Replace the above as appropiate.
# I always put my custom repos in a common folder,
# such as CustomRepos
Now, create a new PHP class that has the namespace above:
//Your ProfilsRepository.php
<?php
namespace App\Bundle\CustomRepos;
use Doctrine\ORM\EntityRepository;
class ProfilsRepository extends EntityRepository
{
/**
* Will return the user url avatar given the user ID
* #param integer $userID The user id.
#return string The avatar url
*/
public function getUserProfile($userId)
{
$em = $this->getEntityManager();
$qb = $em->createQueryBuilder();
$qb->select... (your logic to retrieve the profil object);
$query = $qb->getQuery();
$result = $query->getResult();
return $result;
}
}
Finally, in your Controller:
// Your controller
<?php
namespace <class namespace>;
...
use App\Bundle\CustomRepos\ProfilsRepository;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
...
class YourClassNameController extends Controller
{
public function yourAction()
{
$userId = <get the user ID>;
// Pass the name of your entity manager to the
// getManager function if you have more than one and
// didn't define any default
$em = $this->getDoctrine()->getManager();
$repo = $em->getRepository('Profils');
$avatar = $repo->getUserProfile($userId);
...
}
}
You need to set the services.yml with:
services:
your_service_name:
class: AppBundle\Controller\ServiceController
arguments: [ #doctrine.orm.entity_manager ]
You need to set also the Controller with the following constructor:
public function __construct(\Doctrine\ORM\EntityManager $em)
{
$this->em = $em;
}
and use $this->em in the controller
(for example $connection = $this->em->getConnection();)