These are chat archives for symfony2admingenerator/GeneratorBundle

22nd
Jul 2015
@bobvandevijver Part of my config: https://gist.github.com/ksn135/edbfeb69217ad8131734
Stéphane
@sescandell
Jul 22 2015 05:36
I imagine you do, but do you have the form_script call in your template?
Any chance to have access to a sample demo easy to run and not working? (to dive into the issue)
Serg N. Kalachev
@ksn135
Jul 22 2015 09:42
Well, no, I don't have a call to form_script. And I don't see any doc about it.
But I do have an the following call form_js(form) in twig template.
Bob van de Vijver
@bobvandevijver
Jul 22 2015 11:35
Well, I guess that the datetimepicker call is still being generated by the form_js call. But van you check in your <head> part the seperate generated JS scripts? You only posted a part of your head tag (or you do not have the form_js call in your head)
Bob van de Vijver
@bobvandevijver
Jul 22 2015 11:47
Lorenzo Sanzari
@ulisse73
Jul 22 2015 12:43
Hi there, everyone!
I've a problem with SF2admin generator bundle when I use related entities
This method in DoctrineORMFieldGuesser() fails:
'''protected function getMetadatas($class)
{
// Cache is implemented by Doctrine itself
return $this->doctrine->getManagerForClass($class)->getClassMetadata($class);
}'''
'''
protected function getMetadatas($class)
{
// Cache is implemented by Doctrine itself
return $this->doctrine->getManagerForClass($class)->getClassMetadata($class);
}
'''
Lorenzo Sanzari
@ulisse73
Jul 22 2015 12:48
The system display this error message:
Call to undefined method getClassMetadata($class) on an object
Lorenzo Sanzari
@ulisse73
Jul 22 2015 13:14
'''
test
'''
Bob van de Vijver
@bobvandevijver
Jul 22 2015 14:45
@ulisse73 For code, you will need to use backticks (`)
You could try to find out what the getManagerForClass returns for you specific class?
Karel Sommer
@calvera
Jul 22 2015 15:01
Hi all, has anybody example of batch action with intermediate screen? for example: list of users, select several of them and use assign to group with screen to allow you to select group name somehow... thanks!
Lorenzo Sanzari
@ulisse73
Jul 22 2015 15:08

HELP ME!!! :-)

@bobvandevijver It returns null value

Bob van de Vijver
@bobvandevijver
Jul 22 2015 15:09
Okay, than probably you have a typo in your class name, as it is not known by Doctrine
Lorenzo Sanzari
@ulisse73
Jul 22 2015 15:10
In class name or in class file (entity)?
Bob van de Vijver
@bobvandevijver
Jul 22 2015 15:10
So, are you sure that the entity you're trying to build an admingenerator for is managed?
In the generator file, you might have a typo in the model
For example, I have the following
generator: admingenerator.generator.doctrine
params:
  model: Idb\EventBundle\Entity\Activity
Lorenzo Sanzari
@ulisse73
Jul 22 2015 15:15
<?php

namespace ENet\CRMBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Libri
 *
 * @ORM\Table(name="libri")
 * @ORM\Entity
 */
class Libri
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="titolo", type="string", length=300, nullable=false)
     */
    private $titolo;

    /**
     * @var string
     *
     * @ORM\Column(name="descrizione", type="text", nullable=false)
     */
    private $descrizione;

    /**
     * @var string
     *
     * @ORM\Column(name="prezzo", type="decimal", precision=10, scale=2, nullable=false)
     */
    private $prezzo;


}
My Entity class
generator: admingenerator.generator.doctrine
params:
    model: ENet\CRMBundle\Entity\Libri
Note that I'm using GeneratorBundle v2!
Bob van de Vijver
@bobvandevijver
Jul 22 2015 15:18
Okay, so that looks fine
Can you create and save an Libri entity in another controller (not an admingenerator controller)?
Lorenzo Sanzari
@ulisse73
Jul 22 2015 15:19
At moment, I have only admin controller
Bob van de Vijver
@bobvandevijver
Jul 22 2015 15:20
Are you using automatic mapping of all bundles, or do you define the mapping yourself in the config.yml like this?
doctrine: 
  orm:
    auto_generate_proxy_classes: %kernel.debug%
    default_entity_manager: default
    entity_managers:
      default:
        connection: default
        mappings:
          IdbEventBundle: ~
It is most certain a problem with your Doctrine configuration, and not with the admingenerator
Lorenzo Sanzari
@ulisse73
Jul 22 2015 15:41

I've noted that:
in \vendor\doctrine\common\lib\Doctrine\Common\Persistence\AbstractManagerRegistry.php, I introduced the modification below (row 202)

foreach ($this->managers as $id) {
            $manager = $this->getService($id);

            if (!$manager->getMetadataFactory()->isTransient($class)) {
                return $manager;
            }else{
                echo 'MY DEBUG: Transient!';exit;
            }
        }

and it prints "Transient" message. (A transient class seems to have not metadata). Why?

(Sorry for my english :-) )
Bob van de Vijver
@bobvandevijver
Jul 22 2015 15:42
Okay, this indicates a problem with your annotations
Lorenzo Sanzari
@ulisse73
Jul 22 2015 15:43
Ah, ok! Annotations in my entity class?
Bob van de Vijver
@bobvandevijver
Jul 22 2015 15:44
Or that the annotations are not parsed
According to Doctrine, a class is transient when: "This is only the case if it is either mapped as an Entity or a MappedSuperclass"
Lorenzo Sanzari
@ulisse73
Jul 22 2015 15:45
The entity was generated with command:
php app/console doctrine:generate:entities ENetCRMBundle annotation
Bob van de Vijver
@bobvandevijver
Jul 22 2015 15:46
That command does not ensure it is managed ;)
Lorenzo Sanzari
@ulisse73
Jul 22 2015 15:46
And what command is correct?
Bob van de Vijver
@bobvandevijver
Jul 22 2015 15:46
Can you try running php app/console doctrine:mapping:info?
Lorenzo Sanzari
@ulisse73
Jul 22 2015 15:47
I start the process from existance of db tables
Bob van de Vijver
@bobvandevijver
Jul 22 2015 15:47
If your entity is missing, it is not managed, so you should fix that
Lorenzo Sanzari
@ulisse73
Jul 22 2015 15:47
c:\wamp\www\sfbase>php app/console doctrine:mapping:info
Found 3 mapped entities:
[OK]   ENet\CRMBundle\Entity\User
[OK]   FOS\UserBundle\Model\Group
[OK]   FOS\UserBundle\Model\User
Bob van de Vijver
@bobvandevijver
Jul 22 2015 15:48
So, it is indeed missing
Lorenzo Sanzari
@ulisse73
Jul 22 2015 15:48
It's ok?
Bob van de Vijver
@bobvandevijver
Jul 22 2015 15:49
Well, we now know for sure that it is indeed the Doctrine configuration, as your entity is missing
That's why the getManagerForClass fails
Lorenzo Sanzari
@ulisse73
Jul 22 2015 15:49
Why is missing? Info say me "OK" ?!?!?
Bob van de Vijver
@bobvandevijver
Jul 22 2015 15:50
The entity you are trying to use: ENet\CRMBundle\Entity\Libri
It is not mentioned, therefor not managed
Lorenzo Sanzari
@ulisse73
Jul 22 2015 15:50
Ohhhh, it's true!!!! Sorry
Ok, you are right! :-)
Bob van de Vijver
@bobvandevijver
Jul 22 2015 15:52
So, when you've fixed that, the admingenerator should work fine ;)
Lorenzo Sanzari
@ulisse73
Jul 22 2015 15:52
ok,thanks, I try to resolve
What command use you to generate correct entity class from database?
I use:
php app/console doctrine:mapping:import
and then
php app/console doctrine:generate:entities NameOfBundle annotation
It's right?
Bob van de Vijver
@bobvandevijver
Jul 22 2015 15:56
I've never imported an entity class from a database actually
So I wouldn't know
Lorenzo Sanzari
@ulisse73
Jul 22 2015 15:56
ok
Bob van de Vijver
@bobvandevijver
Jul 22 2015 15:57
You can look at the second answer here: http://stackoverflow.com/questions/20179438/doctrine-does-not-map-its-own-generated-entity (I already mentioned this to you earlier)
I now have to go, so good luck figuring this out!
Lorenzo Sanzari
@ulisse73
Jul 22 2015 16:01
Very thanks for your time! ;-)
Stéphane
@sescandell
Jul 22 2015 16:39

@calvera : the bundle doesn't manage this for you by default. But you can easily make it.
Here is a proposition on how to do it (assuming your custom action is called "generate" and all your generator file is okay):
1- Create a form for your batch action with two fields: Group selector and ids selected (as an hidden field)
2- In your ActionController override the executeBatchGenerate method
3- Instanciate your Form with default values coming from the $selected parameter from the method
4- bind the request to your form
5- if your form is valid $form->isValid() that means the user posted it from your intermediate page and everything is good => you can process data
6- if your form is invalid that migh means two things: the user has not yet even the intermediate page (because so group is not submitted) OR user has seen the page but group is invalid. In both cases : throw an exception
7- Override the errorBatchGenerate method
8- Test if the form has been submitted $form->isSubmitted(). If yes: that means the user has seen the intermediate page but didn't filled it correctly. Return your intermediate page with error message. If not, that simply means the user just click the button from the list, so let's simply show him the intermediate page with form from a renderView call.

That should work.

If $form->isSubmitted() is not working, you can still test if the $form->getName() is in the request parameters.

Hopping that helps

Stéphane
@sescandell
Jul 22 2015 16:47
Here is an almost equivalent solution I'm using for Object action with AJAX to do exactly what you want (showing a form to select a group or category or hatever you want before validate the action). You can make exactly the samething with batch action:
    /**
     * (non-PHPdoc)
     * @see \Admingenerated\AppBundle\BaseModuleController\ActionsController::executeObjectCopyTo()
     */
    protected function executeObjectCopyTo(\Sescandell\AppBundle\Entity\Module $module)
    {
        $contextManager = $this->get('context_restrictor.manager');
        $disabled = $contextManager->disable();

        $this->form = $this->createForm(
            new ModuleCopyType($this->get('security.context'), $this->get('translator')),
            $module->copy()/* clone $module */,
            array('action' => $this->getRequest()->getRequestUri())
        );

        $this->form->handleRequest($this->getRequest());

        if ($this->form->isValid()) {
            $copy = $this->form->getData();
            $copy->setFromAdmin(true);
            $copy->setAuthor($this->getUser());
            if ($copy->getCustodyAccount()) {
                $copy->setCompany(null);
            }

            $this->getDoctrine()->getManager()->persist($copy);
            $this->getDoctrine()->getManager()->flush();
        } elseif ($this->form->isSubmitted()) {
            if ($disabled) {
                $contextManager->enable();
            }
            throw new \InvalidArgumentException('Form is not valid');
        }

        if ($disabled) {
            $contextManager->enable();
        }
    }

    /**
     * (non-PHPdoc)
     * @see \Admingenerated\AppBundle\BaseModuleController\ActionsController::successObjectCopyTo()
     */
    protected function successObjectCopyTo(\Sescandell\AppBundle\Entity\Module $module)
    {
        if ($this->form->isSubmitted() && $this->form->isValid()) {
            $this->get('session')->getFlashBag()->set('from_copy', true);
            return new JsonResponse(array(
                'success' => true,
                'type' => 'redirect',
                'content' => $this->generateUrl("Sescandell_AppBundle_Module_edit", array('pk' => $this->form->getData()->getId())),
            ));
        }

        // Get
        return $this->render(
            'SescandellAppBundle:ModuleActions:copy.html.twig',
            array('form' => $this->form->createView())
        );
    }

    /**
     * (non-PHPdoc)
     * @see \Admingenerated\AppBundle\BaseModuleController\ActionsController::errorObjectCopyTo()
     */
    protected function errorObjectCopyTo(\Exception $e, \Sescandell\AppBundle\Entity\Module $module = null)
    {
        if (is_null($module)) {
            return parent::errorObjectCopyTo($e, $module);
        }

        if (!is_null($this->form) && $this->form->isSubmitted()) {
            $this->get('session')->getFlashBag()->add(
                    'error',
                    $this->get('translator')->trans("admin.module.object_actions.copy.error", array('%name%' => $module->getName()), 'app')
            );

            return new JsonResponse(array(
                    'success' => false,
                    'type'    => 'html',
                    'content' => $this->renderView(
                            'SescandellAppBundle:ModuleActions:copy.html.twig',
                            array('form' => $this->form->createView())
                    )
            ));
        }
    }
The only thing you need to take care with batch action is $selected values sent by your user. Check he is authorized to make your request on all these ids (but this is valuable on all batch actions, not only customized ones like here)
Better than playing with isSubmitted and protected member of the controller, you can also throw dedicated Exception injecting the form you created and manage your error method depending on the exception instance
Karel Sommer
@calvera
Jul 22 2015 19:25
@sescandell Thanks, this is what I wanted...