Showing posts with label Symfony2. Show all posts
Showing posts with label Symfony2. Show all posts

Saturday, April 5, 2014

Symfony2.3 form, grandchildren forms are not validated

Recently I had some issues with Symfony2.3 grandchildren forms not being validated even if I used as default option 'cascade_validation' => true. After doing some research I found other people having same issue and I found out that the solution is that besides putting 'cascade_validation' to true as default option to the form I also had to 'cascade_validation' => true in the collection of children and grandchildren forms I added.

Check the code sample below
Father form
class FatherType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add(
            'children',
            'collection',
            array(
                'type' => new ChildFormType(),
                'allow_add' => true,
                'allow_delete' => true,
                'by_reference' => false,
                'required' => false,
                'cascade_validation' => true //important to be added
            )
        );
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(
            array(
                'data_class' => 'Company/SomeBundle/Form/Entity/FatherFormEntity',
                'cascade_validation' => true, //important to be added
            )
        );
    }

    public function getName()
    {
        return 'father';
    }
}
Child form
class ChildType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add(
            'grandchildren',
            'collection',
            array(
                'type' => new GrandchildFormType(),
                'allow_add' => true,
                'allow_delete' => true,
                'by_reference' => false,
                'required' => false,
                'cascade_validation' => true //important to be added
            )
        );
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(
            array(
                'data_class' => 'Company/SomeBundle/Form/Entity/ChildFormEntity',
                'cascade_validation' => true, //important to be added
            )
        );
    }

    public function getName()
    {
        return 'child';
    }
}
Grandchild form
class GrandchildType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add(
            'attribute',
            'text'
        );
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(
            array(
                'data_class' => 'Company/SomeBundle/Form/Entity/GrandchildFormEntity',
                'cascade_validation' => true, 
            )
        );
    }

    public function getName()
    {
        return 'grandchild';
    }
}

References: https://github.com/symfony/symfony/issues/5204


I hope it helped you!
Robert Rusu

Monday, January 27, 2014

SymfonyLive Portland 2013 - Alexander Mols - Taking caching to the next ...



I recommend you to watch the video because Alexander presented a lot of tips and explained a lot of things regarding caching.
Topics discussed:

  1. Caching for Routing, Container component of Symfony2
  2. Caching in Twig
  3. Doctrine Caching
  4. Varnish
  5. Tricks to prevent making a request to the Symfony2app for misc stuff like showing an html edit anchor

Saturday, August 24, 2013

Symfony2 routing tip

Symfony2 routing tip

Did you ever needed to make the default value to NULL of a routing parameter when using XML for symfony2?
Here is a sample configuration
<route id="acme_user_show" pattern="/{id}">
    <default key="_controller">AcmeUserBundle:User:show</default>
    <default key="id" xsi:nil="true" />
</route>

Friday, June 22, 2012

Why use a PHP framework?

There are several reasons to use a framework instead not using one. The framework that you are using can be one that is open source or your company/team developed for future projects. Learning how to use a PHP framework(or any other framework developed for other languages) can take time depending on multiple factors like documentation, community, practices and patterns that it uses. But it will worth your time because when developing web applications using that framework it will be faster than not using one. 

For example Codeigniter is a lightweight framework that it is easily to use and learn, I mean really easy to learn it. You can start developing a website after a few hours you have downloaded it. But if you have to work on a large project then you should use for example Zend or Symfony2 because these frameworks have more components available to help you with different tasks.

Easier to understand someone else code

 Firstly if you using a framework then other developers who uses it will understand better your code. If developers understand better the code then they will easily extend, fix bugs or use what you wrote. Let's say that you work at a small company in a team of web developers and one of your team member gets married then he has no time to finish the project on which he was working on. Another team member will easily continue his work if he uses the same framework and if the team has a certain coding standards.

If you have some experience with a framework then you will get a job easier because a lot of companies use at least one framework. The most popular frameworks are Symfony2, Zend, Codeigniter, CakePHP. Here is a comparison.

Built in classes that help you

The second advantage of a framework is that you can reuse classes that helps you to get your job done faster. For example the framework can have a database layer that is easier to use for connecting to a database, maybe the framework has a class that helps you to write queries without writing any sql. Of course that in larger projects you must know how to write complicated queries.

Another example is Zend, this framework has a lot of modules that help you to work with different APIs. Zend has a module that helps you to work with Amazon Service. Here is a piece of code example:

$amazon = new Zend_Service_Amazon('AMAZON_API_KEY', 'US',  
'AMAZON_SECRET_KEY');
$results = $amazon->itemSearch(array(
    'SearchIndex' => 'Books',
    'Keywords' => 'php',
    'AssociateTag' => 'yourtaghere'
));

Your web application would be more secure

Another advantage is that a lot of PHP frameworks have built-in security. I am not saying that you should leave the framework to take care of all the ways that someone could break your website but your web application would be more secure if you are using a framework.

Build in caching

Most frameworks have build in caching components that will make your web application faster. This components give you the power to control caching in different ways like timing and other things. Here is an article about Symfony2 caching component.

Separating your logic in your web application

For example if you are using a MVC framework and you are separating the logic of application in the three major parts: views, controllers and models then it will be faster to develop, test it, refactor it and understand it. The views should not contain any logic, it should only present data to the user. The controller must receive a request and return an response. And most importantly the models should contain your logic of the application and your database queries. If do not organize your files and your code properly then your project will become a mess and it will be hard to debug it, to extend it and to reuse that code. It will become a spaghetti code!

Conclusion

Learning a php framework can take time depending on which you are learning but the productivity will grow. Frameworks have a lot of components that will ease your work. Inevitably you will learn to separate your files and code in a way that makes sense to you and the others who use the same framework. Almost all PHP frameworks are Object oriented so all of them use the best OOP Patterns to solve common problems. If you want to start building your own MVC framework then you should follow this tutorials.


Sunday, June 10, 2012

Sonata Admin Bundle error:configureShowFields

If you get this two errors:
[2/2] FileLoaderLoadException: Cannot import resource "C:\wamp\www\project\app/config\." from "C:\wamp\www\project\app/config\routing.yml".  -+

[1/2] ErrorException: Runtime Notice: Declaration of Company\NameBundle\Admin\EntityAdmin::configureShowFields() should be compatible with that of Sonata\AdminBundle\Admin\Admin::configureShowFields() in C:\wamp\www\havefun\src\Company\NameBundle\Admin\EntityAdmin.php line 84  -

Check if you included the ShowMapper class like this:
use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Show\ShowMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Validator\ErrorElement;
use Sonata\AdminBundle\Form\FormMapper;

protected function configureShowFields(ShowMapper $showMapper)
    {
        $showMapper
            ->add('name')
            ->add('email')
        ;
    }

Saturday, June 9, 2012

SonataAdminBundle weird breadcrumbs

If you installed SonataAdminBundle and your breadcrumbs look like this 0/1/ then the solution to this problem is to reinstall the KnpMenuBundle, but the 1.1.0 version, you can find it on git . Add this to your deps file:
[MenuBundle]
git=https://github.com/KnpLabs/KnpMenuBundle.git
target=/bundles/Knp/Bundle/MenuBundle
version=v1.1.0

[KnpMenu]
git=https://github.com/KnpLabs/KnpMenu.git
target=/knp/menu
version=v1.1.1
  
But before running the command  php bin/vendors install --reinstall  make sure you comment the
'Knp\Menu'   => __DIR__.'/../vendor/knp/menu/src',
    'Knp\Bundle' => __DIR__.'/../vendor/bundles',

in the app/autoload.php file

and comment  the
new Knp\Bundle\MenuBundle\KnpMenuBundle(),

line in the app/AppKernel.php file

Also you might have to comment the:
   lines of code in app/config
      sonata_admin:
    title:      HungryCoders
    title_logo: bundles/sonataadmin/logo_title.png
    templates:
        # default global templates
        layout:  SonataAdminBundle::standard_layout.html.twig
        ajax:    SonataAdminBundle::ajax_layout.html.twig

        # default actions templates, should extend a global templates
        list:    SonataAdminBundle:CRUD:list.html.twig
        show:    SonataAdminBundle:CRUD:show.html.twig
        edit:    SonataAdminBundle:CRUD:edit.html.twig
    dashboard:
        blocks:
            # display a dashboard block
            - { position: left, type: sonata.admin.block.admin_list }

...


services:           
    sonata.admin.product:
        class: Demo\TestBundle\Admin\ProductAdmin
        tags:
            - { name: sonata.admin, manager_type: orm, group: demo, label: Products }
        arguments: [null, Demo\TestBundle\Entity\Product, DemoTestBundle:ProductAdmin]

Now you can run the command to install the vendors, and UnComment the code in app/autoload.php, app/AppKernel.php and app/config/config.yml. Now your breadcrumb should look good.

Monday, June 4, 2012

Event Listener Example

Here is an event listener example. I made a little game using Symfony2 framework and I needed to check if the user chose a hero(character) to play before trying to make some actions like view inventory etc.
src/HungryCoders/HeroGameBundle/EventListener/BeforeControllerListener.php:
<?php
namespace HungryCoders\HeroGameBundle\EventListener;

use Symfony\Component\HttpKernel\Event\FilterControllerEvent;

class BeforeControllerListener
{
  
    protected $session;
    protected $resolver;
  
  
    public function __construct($session, $resolver)
    {
        $this->session = $session;
        $this->resolver = $resolver;
    }
  
    /**
     * This is used to check if the user that wants to access some hero game controller
     * chose a hero to play with
     */
    public function onKernelController(FilterControllerEvent $event)
    {
        $controller = $event->getController();
      

        if (!is_array($controller)) {
            // not a object but a different kind of callable. Do nothing
            return;
        }
        $controller = $event->getController();
        $controllerObject = $controller[0];
      
     
        if ($controllerObject instanceOf \HungryCoders\HeroGameBundle\Controller\BattleController
        ||  $controllerObject instanceOf \HungryCoders\HeroGameBundle\Controller\HeroController
        ||  $controllerObject instanceOf \HungryCoders\HeroGameBundle\Controller\InventoryController
        ||  $controllerObject instanceOf \HungryCoders\HeroGameBundle\Controller\TownController
        )
        {
            if ($this->session->get('heroGameHeroId') === null) {
              
                $this->session->setFlash('heroGame.mustChooseAHero', 'You must choose a hero to play');
              
                //a way to create a new response without any redirect just create a response using a controller action
                $request = new \Symfony\Component\HttpFoundation\Request();
                $request->attributes->set('_controller', 'HungryCodersHeroGameBundle:HeroAccess:dashboard');
                $event->setController($this->resolver->getController($request));
            }
        }
    }
}


src/HungryCoders/HeroGameBundle/Resources/config/services.yml
parameters:
    heroGame.battle.maxRounds: 5
    heroGame.attack.rangeLevels: 5

services:
    beforeController.listener:
        class: HungryCoders\HeroGameBundle\EventListener\BeforeControllerListener
        arguments: [ @session, @controller_resolver]
        tags:
            - { name: kernel.event_listener, event: kernel.controller, method: onKernelController }

What is Symfony2?

I found a great article wrote by Fabien Potencier on his website the topics that he reached are:
  1. What is Symfony2?
  2. Is Symfony2 an MVC framework?
  3. Why does it matter?
  4. Why Symfony2
  5. The Symfony2 Components
I really encourage you to read his post! Thank you Fabien Potencier!

Monday, May 21, 2012

Installing Sonata Bundle Error

If you get the next error when using Sonata Admin Bundle you should use the Sonata Admin Bundle 2.0 branch.

Fatal error: Declaration of Sonata\AdminBundle\Form\Extension\Field\Type\FormTypeFieldExtension::getDefaultOptions() must be compatible with that of Symfony\Component\Form\FormTypeExtensionInterface::getDefaultOptions() in /var/www/pulpower.spotymedia.com/vendor/bundles/Sonata/AdminBundle/Form/Extension/Field/Type/FormTypeFieldExtension.php on line 186

 Clear the deps file and copy the next code

[SonataAdminBundle]
    git=git://github.com/sonata-project/SonataAdminBundle.git
    target=/bundles/Sonata/AdminBundle
    version=origin/2.0

run the command php bin/vendors install -reinstall

Now everything should work.

https://github.com/sonata-project/SonataAdminBundle/issues/679

Sunday, May 20, 2012

Symfony2 assets:install error

If you get the next error when running php app/console assets:install --symlink ./web:

  Warning: unlink(./web/bundles/framework): Permission denied in C:\wamp\www\project
\vendor\symfony\src\Symfony\Component\HttpKernel\Util\Filesystem.php line 100

Then delete folders in project/web/bundles/ then run the command and it should work.

Installing SonataAdminBundle Error

If you get the next error when installing SonataAlbumBundle:
The child node "default_contexts" at path "sonata_block" must be configured.

Then you should include this code in your app/config/config.yml file
 # app/config/config.yml
sonata_block:
    default_contexts: [cms]
    blocks:
        sonata.admin.block.admin_list:
            contexts:   [admin]

        #sonata.admin_doctrine_orm.block.audit:
        #    contexts:   [admin]

        sonata.block.service.text:
        sonata.block.service.action:
        sonata.block.service.rss:

        # Some specific block from the SonataMediaBundle
        #sonata.media.block.media:
        #sonata.media.block.gallery:
        #sonata.media.block.feature_media:

Wednesday, May 16, 2012

Start learning Symfony2 help

You want to learn Symfony2? Here check the next list of websites that I found and learned from:
  1. http://tutorial.symblog.co.uk/  Darren Rees wrote a great tutorial for creating a blog in Symfony2. This tutorial helped me to get started with Symfony2, I hope it will help you too.
  2. You should read all you can from the official website http://symfony.com/ because the documentation is great and there is a lot of stuff that will help you get started. Also there are some very interesting videos about Symfony2 at http://symfony.com/videos
  3.  This presentation http://www.youtube.com/watch?v=VuNFof59A7M made by Fabien Potencier helped me a lot, because he explains in detail how some of the components work.
  4. Symfony2 the maturity of PHP frameworks in this video Stefan Koopmanschap is explaining a lot of interesting stuff about Symfony2 that will help you understand about the framework. 
  5. http://www.ens.ro/2012/03/21/jobeet-tutorial-with-symfony2/ A kind sir made a Jobeet tutorial with Symfony2

I hope this will help you! If you know other good learning resources please post them here. Thank you!

Monday, May 7, 2012

How to check if Entity is in an array collection of another Entity

 Check if $friend is in the friends array collection of the user
$user->getFriends()->contains($friend); 

if $friend is in the array collection  method returns true otherwise it returns false

Sunday, May 6, 2012

Symfony2 Security component. How to get the user who is logged-in?

If you are using Symfony2(version 2.0.12 2012-03-19 ) and using Security component then you can get the logged in user like this:


$user = $this->container->get('security.context')->getToken()->getUser();

Symfony2 many-to-many self referencing relation using Doctrine2

Symfony2 many-to-many self referencing relation using Doctrine2

 Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken::serialize() must return a string or NULL

I created this blog because I wanted to help others who are self learners like me. I spent few hours to figure out why I was getting the next error when playing with Symfony2.
Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken::serialize() must return a string or NULL

I had an User entity a many to many self referencing relation. I still did not find out why I was getting the error but I found out here a way to get rid of the error. I just had to add the __sleep method for the user entity like this:

/**
 * @ORM\Entity(repositoryClass="Acme\DemoBundle\Repository\UserRepository")
 * @ORM\Table(name="users")
 * @ORM\HasLifecycleCallbacks()
 */

 class User
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;
    ..................
    public function __sleep()
    {
        return array('id');
    }
}

I hope this helped someone who got the same error as I did. If you have a better solution please post it here.