containerAware and Controller in symfony2 - symfony

FOSUserBundle profile controller
use Symfony\Component\DependencyInjection\ContainerAware;
class ProfileController extends ContainerAware
some functions ok ... but when i try then creat form
$form = $this->createForm
This error appear: Call to undefined method ProfileController::createForm()
BUT when i change it to this:
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class ProfileController extends Controller
The form is rendered... so ... i dont know how can i add this controller to my class and dont remove the ContainerAware ? :/
//
MY solution ?
instead of containeraware i use
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
And then
class ProfileController extends Controller implements ContainerAwareInterface
But i dont know i cant see a different i am noob now so... is it good solution or i will broke something?

To answer your original question,
Replace:
$form = $this->createForm
With:
$form = $this->container->get('form.factory')->create($type, $data, $options);
The createForm method is just a convenience method defined in Symfony\Bundle\FrameworkBundle\Controller\Controller. For various reasons, 3rd party libraries tend not to extend the Controller class. Hence createForm is not available.
The real question is: why are you trying to extend the Profile controller? In most cases it is not necessary. It's better to do your customization by listening to events. That of course assumes you are using the development version of FOSUserBundle.

Controller is already ContainerAware - from Controller declaration:
class Controller extends ContainerAware

Have a look at this blog Symfony2: Moving Away From the Base Controller by Richard Miller

Related

How to change Symfony Sonata's flash message

The default flash message in Sonata admin bundle adds the key and value to the message:
Item "AppBundle\Entity\Users:00000000342d9b58000000004a2ab3f9" has been successfully created.
Could someone tell me how to get rid of the key and just have the value displayed?
Thank you.
I believe there is an answer to this question on sonata project github.
Try to add __toString($object) method to your Sonata Admin class:
namespace App\Admin;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use App\Entity\Category;
class CategoryAdmin extends AbstractAdmin
{
public function toString($object)
{
return $object instanceof Category
? $object->getName()
: 'Category'; // shown in the breadcrumb on the create view
}
}
For example override flash_create_success -> (Item "%name%" has been successfully created.), you need to create SonataAdminBundle.en.xliff file in your SonataAdminBundle's child and after that insert into file:
<trans-unit id="flash_create_success">
<source>flash_create_success</source>
<target>WHAT DO YOU WANT TO SHOW.</target>
</trans-unit>
Clear cache and test :)

override parameter of anohter bundle

I'm building a bundle, which depends on another bundle. The parent bundle loads a services.yml file, which defines some parameters:
parameters:
xbundle.doctrine.factory: Doctrine\ORM\Repository\DefaultRepositoryFactory
services:
....
I know the xbundle.doctrine.factory parameter can be changed from app/config/config.yml, but I want to change its value the from within my custom child bundle. I read the docs, and also the suggested stackoverflow questions, but still can't figure how to achieve it.
You must write a CompilerPass in your child Bundle, and change the value:
// src/Acme/DemoBundle/DependencyInjection/Compiler/OverrideServiceCompilerPass.php
namespace Acme\DemoBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class OverrideServiceCompilerPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$container->setParameter('xbundle.doctrine.factory', '..New Value ...');
}
}
Some documentation here.

Symfony: Getting basic routing to work

this maybe due to my stupidity, but I could really use a hint here.
I have not done much with php so far, been mostly working with javascript, and now trying to get a grasp on Symfony. I'm working with vagrant and the great scotch-box, so I installed Symfony on this vm and created a new app. I tried creating a route that just returns "Hello world!", but i can't get it to work.
The route defined in the DefaultController is working. I created a new controller via the console command
$ php bin/console generate:controller
and called it TestController. This is it:
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class TestController extends Controller
{
/**
* #Route("/test")
*/
public function testAction()
{
return new Response( "Hello World!" );
}
}
When navigating to [scotch-box address]/my_project/web I get the default route, but [scotch-box address]/my_project/web/test gives me a 404.
Maybe it has to do with the configuration of the vm, but this is not my expertise, so any nudge in the right direction will be appreciated. Thank you!
Edit: After I managed to destroy my vm yesterday, I set up a clean scotch-box and installed symfony's demo-app, which is running just fine. I also have setup a clean Symfony project and changed only the DefaultController's route to "/home":
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
class DefaultController extends Controller
{
/**
* #Route("/home", name="homepage")
*/
public function indexAction(Request $request)
{
// replace this example code with whatever you need
return $this->render('default/index.html.twig', [
'base_dir' => realpath($this->container->getParameter('kernel.root_dir').'/..'),
]);
}
}
my routing.yml reads:
app:
resource: "#AppBundle/Controller/"
type: annotation
As I understand it, Symfony's welcome page should now be reachable via [scotch-box address]/my_project/web/home, but it isn't. Instead I can still reach it via [scotch-box address]/my_project/web, while /home throws a 404 page.
Maybe I'm wearing the idiot hat here, but I could not find anything in the documentation that would shed a light on this.
I may be wrong, but I'm pretty sure that it's because your routing.yml file is incomplete. Check if you have this in routing.yml:
app:
resource: "#AppBundle/Controller/"
type: annotation
If not, add it. This will "plug in" the annotation routing of your AppBundle into the routing of the whole project.

Why symfony can't find template it rendered in other function

I have a function in my controller like this:
<?php
namespace GradeBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\Session;
use GradeBundle\Entity\User;
use GradeBundle\Entity\SchoolClass;
class MainController extends Controller
{
/**
* #Route("/", name="index_page")
*/
public function index()
{
return $this->render('GradeBundle:Default:index.html.twig');
}
It renders the twig template correctly. However when I use other function:
/**
* #Route("/adminNew", name="add_admin")
*/
public function addAdmin()
{
$session = new Session();
if($session->get('loggedIn') == null)
return $this->redirect($this->generateUrl('index_page'));
else
return $this->render('GradeBundle:Add:newAdmin.html.twig');
}
I have the following error:
Unable to find template "GradeBundle:Default:index.twig.html".
Does anybody have any idea what might be wrong?
It's a typo somewhere you call template:
GradeBundle:Default:index.twig.html
But you have only GradeBundle:Default:index.html.twig template.
Note the difference: html.twig twig.html
I suspect that you extend it in GradeBundle:Add:newAdmin.html.twig by:
{% extends 'GradeBundle:Default:index.twig.html' %}
but should be:
{% extends 'GradeBundle:Default:index.html.twig' %}
Have you made sure to use the correct namespace for the Controller you're using? And are you including the correct files? Also I'm not sure I understand the question correctly - are you saying if you add another function with a different twig file render, the first one no longer renders? Could I see your class names and the namespaces / use statements?
Usually in these instances, it's that the templates are in the wrong place or the correct file is not included in order to find it.
Michael

symfony 2.6 buildForm versus createFormBuilder

someone can explain me the difference between buildForm and CreateFormBuilder?
what is the best way to create forms? I'm reading symblog and it uses:
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class EnquiryType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('name');
$builder->add('email', 'email');
$builder->add('subject');
$builder->add('body', 'textarea');
but in documentation symfony i find use of "createFormBuilder"
// src/Acme/TaskBundle/Controller/DefaultController.php
namespace Acme\TaskBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
class DefaultController extends Controller
{
public function newAction(Request $request)
{
// createFormBuilder is a shortcut to get the "form factory"
// and then call "createBuilder()" on it
$form = $this->createFormBuilder()
->add('task', 'text')
->add('dueDate', 'date')
->getForm();
return $this->render('AcmeTaskBundle:Default:new.html.twig', array(
'form' => $form->createView(),
The first example you've shown is the right way to do it. Why?
Best practices. A form type should live in its own namespace - BundleName\Form\Type for instance. It's a better practice to do it that way, because you're free to re-use the form type anywhere you want in your application. Everything your form needs is placed in one file, easier to understand, not just by you, also by someone who can work on your project in future. That would be the first place every developer should look for, if something needs to be changed/added. Once you start adding event listeners, custom validators and more into your forms, you will understand that a controller is not a suitable place for a form to be defined.
DRY - every developer is aiming to write better code everyday. One of the most important concepts regarding controllers is - keep it as thin as possible. Let the controller action do only what it's supposed to do, nothing more - nothing less. Once your form types are defined, then its only a matter of few lines to create and render your form.
To answer your first questions - no, there is not much of a difference, whether you create your form in separate class or not. There is a lot more to discuss on this matter, but I believe this would be enough for you to understand the idea behind form type as a class. My suggestion to you, is to keep your forms in their own namespace.
Hope this can clarify things for you.

Resources