Symfony $this->>createFormBuilder throws notice from controller - symfony

I am doing a small project in Symfony to gain some experience with this framework. At the moment I am just following tutorials while making my own tool which is a GUI to make my resume.
In my controller I am calling $this->createFormBuilder($cvBase) which is throwing an "Undefined property" notice which I think is strange because I am calling a method.
Does anyone know what is causing this?
<?php
// My php code
namespace NuiCart\CvToolBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use NuiCart\CvToolBundle\Entity\CvBase;
use Symfony\Component\HttpFoundation\Request;
class DefaultController extends Controller{
public function formAction(Request $request){
$cvBase = new CvBase();
$form = new $this->createFormBuilder($cvBase);
The notice:
Notice: Undefined property:
NuiCart\CvToolBundle\Controller\DefaultController::$createFormBuilder
in
/var/www/devel/cv/public_html/src/NuiCart/CvToolBundle/Controller/DefaultController.php
line 19 500 Internal Server Error - ContextErrorException

createFormBuilder() already returns a newly created FormBuilder object and you therefore don't need to create a new Object. By attempting to use new, it is trying to create a new DefaultController and access a function that is private to the internals of the Controller (or something like that - don't sue me for correctness on this one as it is just an attempt to explain why using new $this is wrong.)
Your solution is to remove the new in $this->createFormBuilder():
$form = $this->createFormBuilder($cvBase);

Related

Annotation for Symfony validator returns "annotation was never imported exception"

I am trying to use the validator service on a Symfony controller, particularly the uniqueEntity constraint to check if an object with a same id is already on the database. I have successfully used de UUID constraint of the validator on the same project before, using annotations as well. For this reason it seems strange that using the same method wouldn't work.
My annotated entity looks like this:
<?php
//src/Entity/Usuarios.php
namespace App\Entity;
use App\Repository\UsuariosRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity(repositoryClass=UsuariosRepository::class)
* #UniqueEntity("idUsuario")
*/
class Usuarios
{
/**
* #ORM\Id() #ORM\Column(name="idUsuario",type="integer", unique=true)
* #Assert\IdUsuario
*/
private $idUsuario;
\** etc.**\
?>
My controller looks like this:
//src/Entity/Usuarios.php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpClient\HttpClient;
use Doctrine\ORM\EntityManagerInterface;
use App\Entity\Empleados;
use App\Entity\Productos;
use App\Entity\ProductoOrden;
use App\Entity\Ordenes;
use App\Entity\Usuarios;
use App\Entity\Ventas;
use App\Entity\Periodos;
require_once('/Users/jaumaf/clases/2020-1/incentivos/src/testData.php');
use const testData\USUARIOS_T;
use const testData\EMPLEADOS_T;
use const testData\PRODUCTOS_T;
use const testData\ORDENES_T;
use const testData\PERIODOS_T;
use const testData\VENTAS_T;
use Psr\Log\LoggerInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;
class LoadDataController extends AbstractController
{
/**
* #Route("/load/data", name="load_data")
*/
public function index(LoggerInterface $logger, ValidatorInterface $validator) {
//los json estan en testData.php
$usuariosArray = json_decode(USUARIOS_T, TRUE);
$empleadosArray = json_decode(EMPLEADOS_T,TRUE);
$productosArray = json_decode(PRODUCTOS_T,TRUE);
$ordenesPorEmpleadoArray = json_decode(ORDENES_T,TRUE);
$periodosArray = json_decode(PERIODOS_T, TRUE);
$ventasPorVendedorArray= json_decode(VENTAS_T, TRUE);
$logger->info('Test constants loaded');
$entities = $this -> mapArraysToObjects($usuariosArray, $empleadosArray, $productosArray, $ordenesPorEmpleadoArray,$ventasPorVendedorArray,$periodosArray);
$logger->info('Entities loaded to memory');
$cont = 0;
$logtable = $this -> logLoadedEntities($cont, $entities);
// Persistencia
$entityManager = $this->getDoctrine()->getManager();
$logger->info('ORM loaded');
// Validator test
$usuario = $entities[0];
$validation = $validator -> validate($usuario);
// this should make the validator throw a uniqueEntity exception, but it throws an annotation exception.
The exception I am getting is:
[Semantical Error] The annotation "#Symfony\Component\Validator\Constraints\IdUsuario" in property App\Entity\Usuarios::$idUsuario was never imported. Did you maybe forget to add a "use" statement for this annotation?
I have tried adding a use statement for Symfony\Component\Validator\Constraints\IdUsuario on my controller as the exception message seems to imply (however, the Symfony guide doesn't mention this step so it should be unneccesary). But it shows exactly the same error.
I also tried making a doctrine migration hoping that the metadata the annotations use somehow updates itself, but It throws the same exception in the command line.
bash-3.2$ php bin/console make:migration
In AnnotationException.php line 54:
[Semantical Error] The annotation "#Symfony\Component\Validator\Constraints\IdUsu
ario" in property App\Entity\Usuarios::$idUsuario was never imported. Did you may
be forget to add a "use" statement for this annotation?
I am new to php and I don't really understand how annotations work. But I've followed the guide in https://symfony.com/doc/current/reference/constraints/UniqueEntity.html. I'm pretty sure I've gone over the syntax thoroughly and as I said it worked before with a different constraint. In addition, the exception is thrown from within the the controller when I make a call to the validate() function. Maybe there is something I'm missing in the controller side or something on the Symfony framework system that I don't know about that might affect the behavior of the validation service?
I would appreciate any guidance. I will be trying to wrap my head over annotations on the meantime.
Thanks
Remove annotation #Assert\IdUsuario from class Usuarios
You copy-pasted it from https://symfony.com/doc/current/reference/constraints/UniqueEntity.html
It's not related to UniqueEntity validation. It's just checking that field is a valid email.

Fixture DOCTRINE2

When I use:
php app/console doctrine:fixtures:load --fixtures=/var/www/Symfony/src/BISSAP/ForumBundle/DataFixtures/ORM**
I get the following error:
PHP Catchable fatal error: Argument 1 passed to
BISSAP\ForumBundle\Entity\Forum::setCategory() must be an instance of
BISSAP\ForumBundle\Entity\Category, null given, called in
/var/www/Symfony/src/BISSAP/ForumBundle/DataFixtures/ORM/LoadForum.php
on line 40 and defined in
/var/www/Symfony/src/BISSAP/ForumBundle/Entity/Forum.php on line 184
My Fixture - LoadForum.php:
<?php
namespace BISSAP\ForumBundle\DataFixtures\ORM;
use Doctrine\Common\DataFixtures\FixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use BISSAP\ForumBundle\Entity\Forum;
use BISSAP\ForumBundle\Entity\Category;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class LoadForum extends Controller implements FixtureInterface
{
public function load(ObjectManager $manager)
{
$data=array(array('NAME','DESCRTIPTION','60',$manager->getRepository('BISSAPForumBundle:Category')->find('1')),
array('NAME2','DESCRTIPTION2','60',$manager->getRepository('BISSAPForumBundle:Category')->find('2')));
foreach ($data as $for) {
$forum = new Forum();
$forum->setName($for[0]);
$forum->setDescription($for[1]);
$forum->setOrdre($for[2]);
$forum->setCategory($for[3]);
$manager->persist($forum);
}
$manager->flush();
}
}
doctrine:fixtures:load erases all data from DB and loads new set of fixtures
I believe your problem is
$manager->getRepository('BISSAPForumBundle:Category')->find('1')
that return empty result instead of Category object
And it looks like either you loads Forum fixtures before Category or you didn't considered that DB was erased and you don't have any records for Category.
for case 1 you should change order of fixtures loading - change the function "getOrder" for Category fixtures and set returned number lower then number at Forum
for case 2 you should also create fixtures for some categories
BTW you should use a reference to the object, instead of picking up from the repository, so common way is:
Create new reference for the Category fixture
$category = new \MyApp\CategoryBundle\Entity\Category();
$category->setName();
$this->addReference('MyApp\CategoryBundle\Entity\Category-1',$category);
Call created reference to fill Forum
$forum->setCategory($this->getReference('MyApp\CategoryBundle\Entity\Category-1'));

KnpMenuBundle, extend Builder by ContainerAware and Controller

I m using KNPMenuBuilder to create a menu. I would like to add query in my Builder.php but I need to extend Builder class by Controller. By default it`s extends by "ContainerAware".
I would like to ask how to extends Builder class by two elements- "ContainerAware" and "Controller"?
Or how can I create a DQL query without extending of Controller?
The Controller class is just a "tool" to easily use controllers (some people even say it's a bad thing to use, as it's somewhat advocating a service locator pattern).
You shouldn't extend Controller in any class other than a controller.
To get access to doctrine (like the Controller#getDoctrine() method), you should request for the doctrine service. Then you just have the same as you have when using the getDoctrine() method.
Since the builder extends ContainerAware, you have access to a $container property and you can get() the doctrine service from it:
$doctrine = $this->container->get('doctrine');
$em = $doctrine->getManager();
$query = $em->createQuery(...);

Access database in BeforeFeature

How do I access my database via doctrine in a BeforeFeature? I am unable to get my entity manager because my kernel is null...this is what I am trying:
/**
* #BeforeFeature
*/
public static function cleanDatabase(FeatureEvent $event)
{
$context = new FeatureContext(array());
$context->thereAreNoUsersInTheDatabase();
}
It tells me that I cannot get container from a non-object (the kernel). Why isn't KernelAwareInterface assigning the kernel when I manually create that FeatureContext?
KernelAwareInterface just provides a method "setKernel" method, you still have to call manually if you instantiate a new FeatureContext object
You can use FriendlyContext that provide you a "#reset-schema" annotation. See https://github.com/KnpLabs/FriendlyContexts/blob/master/doc/context-entity.md#reset-schema .
Do not hesitate to read the full documentation and the code that doesn't uses the SymfonyExtension.

Set a variable in Symfony2 to be used for all Doctrine calls

Okay, so I'm not even sure how to ask this question (much less search for it). But in my system, I have a variable that forms a relationship for nearly every row. The user does not know it and it is set as a session variable each time a user logs in.
I need this variable to be available to Doctrine. It's not a default or static, so setting it in the class property isn't an option. Having it as a hidden form poses a security risk. I'm honestly at a loss. I've avoided the problem until I can't avoid it no more...
It'd accept a workaround for the time being. I really need to get this project launched as soon as humanly possible.
Any help would be greatly appreciated. Even help explaining what I'm trying to accomplish would be appreciated!
While this doesn't resolve my issue entirely, this particular solution may help someone else in a similar predicament...
In order to inject (I use the term loosely) an object into my form data using a form extension and an event listener.
Extension:
<?php
namespace Acme\DemoBundle\Form\Extension;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormEvents;
use Acme\DemoBundle\Form\EventListener\MyListener;
class FormTypeMyExtension extends AbstractTypeExtension
{
public function getExtendedType()
{
return 'form'; // because we're extending the base form, not a specific one
}
public function buildForm(FormBuilder $builder, array $options)
{
$listener = new MyListener($this->security, $this->em);
$builder->addEventListener(FormEvents::SET_DATA, array($listener, 'onSetData'));
}
}
Listener:
<?php
namespace Acme\DemoBundle\Form\EventListener;
use Symfony\Component\Form\Event\FilterDataEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Security\Core\SecurityContext;
use Doctrine\ORM\EntityManager;
class MyListener
{
public function onSetData(FilterDataEvent $event)
{
// I use form.set_data because it has a method to set data to the form.
$form = $event->getForm();
$data = $event->getData();
// do things to the form or the data.
}
}
(Had some help from this site.)
That allows you to do anything to the form or form data to every form. Which is how I injected the object initially. My problem is the embedded forms apparently don't call setData() (presumably because the first object already has the other objects).
I've worked on this all day, so, if my answer is badly worded, complain and I'll fix it in the morning!

Resources