Free Symfony 2.3 Tutorial Videos

If you are thinking of making the switch from Functional to Object Oriented PHP development, or have already ventured down the OOP route and tried a framework (Laravel, Cake, Yii, or similar), chances are you will have hit a few stumbling blocks or worse, given up in despair.

I remember being there.

I also remember wishing someone had come up with some video tutorials which I could watch rather than having to slog through the manuals.

Now, don’t get me wrong – you are still going to need the manual, but hopefully these videos will explain the concepts visually, which you can then use as a base of reference when you start reading further.

There are six videos up in total at the moment with more on the way. If there is a specific topic you have in mind or aren’t sure of, I would be happy to make a video for it. Just leave a comment either here, or on youtube.

Full video list

VichUploaderBundle – How to Fix: Cannot Overwrite / Update Uploaded File

this picture of george osbourne has no relevance to this post. i hope it cheered you up.This one stumped me a few days back, and I have had the Chrome tab open ever since to remind myself of how to fix this in future.

The problem: VichUploaderBundle will let you upload a file, but when you go back to the form to edit / update / over-write that file by uploading a new one, it doesn’t upload the new file.

The solution: I cannot take credit for this, as the solution was found by digging around in the github closed issues list for the project, where JMather had posted his working fix.

For those who cannot be bothered to click any of the links I have so helpfully provided, read on.

Make sure you have something like this in your config.yml:

vich_uploader:
    db_driver: orm
    gaufrette: false
    storage: vich_uploader.storage.file_system
    twig: true
    mappings:
        users_uploaded_file:
            delete_on_remove: true
            delete_on_update: true
            inject_on_load: true
            upload_destination: /some/path/to/uploads
            namer: vich_user_upload_file_naming_service

I’m not using Gaufrette for a couple of reasons I won’t go in too. And also, I’m saving the given uploads outside of my Symfony install for security.

The key line is: delete_on_update: true

The other important thing here is you have to have some way of telling your ORM that the file has been updated. This is not immediately obvious, and isn’t documented at all.

So the solution seems to be:

1. Make sure you have at least an updatedAt field in the entity you are uploading too. I would normally have a createdAt and updatedAt field, and use LifecycleCallbacks to update these fields for me on prePersist and preUpdate. This isn’t well documented either in my opinion, so if you are unsure how to use them, please read my post on Lifecycle Callbacks.

2. Then update the method you are using to save the uploaded file to include an updating of the updatedAt property inside your entity. Sounds confusing, so it’s better to explain it with a code snippet:

    public function setUploadedFile($uploadedFile)
    {
        $this->uploadedFile = $uploadedFile;

        if ($uploadedFile instanceof UploadedFile) {
            $this->setUpdatedAt(new \DateTime());
        }
    }

All we are saying here is to set the updatedAt time to now if this is an uploaded file.

This then tells your ORM that the file is new – in a very round the houses kind of way – and correctly uploads the new file. And because we used delete_on_update: true, the old file is deleted so no need to worry about that.

Again, check out the github link if this still doesn’t make sense.

Thanks to Chrysweel for raising this issue, and to JMather for solving it.

Using LifecycleCallbacks for CreatedAt and UpdatedAt in Symfony 2

It's a life cycle. *Tumbleweed*

[Update: May 2015 – This post has been updated with videos]

Lifecycle Callbacks are a super helpful bit of code that I use in a good number of my entities.

They are scary sounding and the documentation on the Symfony 2 official docs doesn’t give a detailed enough demonstration (in my opinion) to explain to the new Symfony user how useful they are.

So, rather than waffle on, I will give a bit of handy code that you can steal and re-use.

namespace MCM\MyExampleBundle\Entity;

// some use statements here

/**
 * MyPretendEntity
 *
 * @ORM\Table(name="my_table_name")
 * @ORM\Entity(repositoryClass="\MCM\MyExampleBundle\Repository\MyPretendRepository")
 * @ORM\HasLifecycleCallbacks()
 */
class MyPretendEntity
{
    // snip snip snip

    /**
     * created Time/Date
     *
     * @var \DateTime
     *
     * @ORM\Column(name="created_at", type="datetime", nullable=false)
     */
    protected $createdAt;

    /**
     * updated Time/Date
     *
     * @var \DateTime
     *
     * @ORM\Column(name="updated_at", type="datetime", nullable=false)
     */
    protected $updatedAt;

    // snip snip snip

    /**
     * Set createdAt
     *
     * @ORM\PrePersist
     */
    public function setCreatedAt()
    {
        $this->createdAt = new \DateTime();
        $this->updatedAt = new \DateTime();
    }

    /**
     * Get createdAt
     *
     * @return \DateTime
     */
    public function getCreatedAt()
    {
        return $this->createdAt;
    }

    /**
     * Set updatedAt
     *
     * @ORM\PreUpdate
     */
    public function setUpdatedAt()
    {
        $this->updatedAt = new \DateTime();
    }

    /**
     * Get updatedAt
     *
     * @return \DateTime
     */
    public function getUpdatedAt()
    {
        return $this->updatedAt;
    }
}

I have seen this done other ways – some people use only one method for both.

The implementation is up to you – but do remember to use the correct annotations – @ORM\HasLifecycleCallbacks() , @ORM\PrePersist , and @ORM\PreUpdate.

There are some other events you can interact with, so be sure to check out the official docs – they become much more useful now that you understand how they work.