Have You Ever Used A Symfony Compiler Pass?

It’s been JavaScript, JavaScript, JavaScript for the past few weeks, so this week I thought I’d vary things up a little and, heck, cover a little Symfony ūüôā

Yes, two new Рdare I say Рuseful videos were added to CodeReviewVideos this week.

Lets go ahead and jump right into it.

First up we venture into the wonderful – and scary sounding – world of Compiler Passes. Now, this is one of those Symfony things that is really useful, but also something you’re unlikely to try until you’ve seen it working before. Ahh, the old catch 22. Not so bad if you work in a huge team of devs who all share knowledge (or you are particularly good at reverse engineering), but if you’re a lone wolf, or part of a smaller, less experienced team, things like this may completely pass you by.

To begin with, we start with a code smell that I saw recently when working with a client. This problematic code is fairly common, and isn’t specific to Symfony projects. You may even have it in your own projects:

Controller bloat.

This particularly issue starts off with an if¬† / else¬†, which turns into an if¬† / elseif¬† / else¬†, and within a few further iterations you’ve got this nasty conditional dominating the method. Actually in the code I was looking at, this was a common theme throughout multiple controllers, and multiple actions in each controller. It’s things like this that make people believe Symfony is hard, when in reality, this problem would follow you if you switched to Laravel, or Zend, or Slim, or any other.

We’ll use an example of having to convert an array of data into a variety of formats – CSV, XML, YAML, and so on.

To begin with, these various conversion strategies live inside our controller action.

In the first video we cover a simple way to start refactoring this code:

https://codereviewvideos.com/course/symfony-compiler-pass-example/video/extract-extract-extract

At this stage all we are doing is extracting the problem code from the controller. This is really easy to do, and can immediately start to reduce duplication, and increase code re-use.

Unfortunately this doesn’t actually solve the tight coupling problem. But sometimes, you know what? You don’t need too. Over engineered code can be just as painful to work with as sloppy code. It’s just a different kind of pain.

Anyway, on larger systems simply extracting code out like this may not give you the flexibility you need. For that we can use a technique that third party bundles use:

https://codereviewvideos.com/course/symfony-compiler-pass-example/video/introducing-the-compiler-pass

In this video we cover how to use a Symfony Compiler Pass to decouple the Conversion service we’ve created from the various conversion strategies (e.g. convert to YAML, convert to JSON, and so on).

Let’s imagine that you wanted to create a Symfony Bundle that you could then share with the world in order to help others who might need to convert arrays in the future. Whilst you might provide a variety of implementations out of the box – ConvertToJSON, ConvertToXML, and so on – you don’t want to be solely responsible for adding every possible implementation in the future.

Instead, you could allow users of your library to implement the expected interface, and then use a Symfony service Tag that tells your Conversion service to also include this custom converter that your library user has created.

There’s loads of uses for this approach, and honestly it’s easier to do than you might think. Much like a lot of Symfony concepts, actually ūüôā

All of this weeks videos are free to watch, though I will be making the Compiler Pass video a Members Only video at the end of this month.

Until next week, take care and happy coding

Chris

How I Fixed: CSRF Token Is Invalid

There’s an obvious fix, and a not so obvious fix to this problem – The CSRF Token Is Invalid. Please try to resubmit the form:

The CSRF Token Is Invalid. Please try to resubmit the form.
pesky.

The ‘obvious’ fix is that you may very well have forgotten to add in:

{{ form_end(yourFormNameHere) }}

To your twig form template file.

It’s easy to do, and we’ve all done it.

You may see this as:

{{ form_rest(yourFormName) }}
{{ form_end(yourFormName) }}

Also, but as of Symfony 3 at least,¬†form_rest¬†is now added in to¬†form_end¬†for free. It may have arrived earlier, but it’s late now, and I’m too tired to check.

Anyway, if that all works then perfect, and off you go.

However, the less obvious problem might be that your session directory is not writable by the web server user.

This just caught me out when setting up a new server.

I’d used Ansible to build my dev server, and then I’d also deployed a variant of my dev script to production.

However, somewhere along the way I’d boobed and created myself a¬†var/sessions¬†directory, and also a¬†shared/var/sessions¬†directory, and whilst the permissions where correct on one, they weren’t correct on the right one :/

Why might this be the case? Well, I deploy using Deployer, but I’d only just set that up to deploy to prod. During dev I simply work on the local VM – no deploy script needed. And at this stage I don’t have a staging box for ¬†this project.

So yeah, make sure that whatever user your web server is running as –¬†www-data¬†in this case – also has permissions to write to whichever directory you are storing your session data in.

You can find this directory by looking in config.yml :

framework:
    # snip
    session:
        # http://symfony.com/doc/current/reference/configuration/framework.html#handler-id
        handler_id:  session.handler.native_file
        save_path:   "%kernel.root_dir%/../var/sessions/%kernel.environment%"

 

Gotcha: Upgrading To FOSRestBundle 2.0

This is not a huge issue, and likely quite easy to identify and fix. But I’m the kind of person who hits Google before engaging brain, and I didn’t find a direct answer (boo, wake up brain!).

I have, this very evening, decided to try FOSRestBundle 2.0. It’s currently still in development, so isn’t available without a little naughty composer tagging:

    "require": {
        "friendsofsymfony/rest-bundle": "^2.0@dev"
    },

A little tip there – if you use the¬†@dev¬†after your requested version number, you can force through development packages without globally changing your project’s¬†minimum-stability¬† setting.

Anyway, being that I’ve been coding for the last 12.5 hours, I went with the lazy man’s option of copy / pasting my config from a FOSRestBundle 1.7 installation I happened to have laying around.

fos_rest:
    view:
        exception_wrapper_handler:  null
        mime_types:
            json: ['application/json', 'application/x-json']
            jpg: 'image/jpeg'
            png: 'image/png'

Firstly, I got this:

InvalidConfigurationException in ArrayNode.php line 317:
Unrecognized option "exception_wrapper_handler" under "fos_rest.view"

Which confuses me, as this seems to be the same as what’s in the configuration reference.

Anyway, simply removing that line makes the error go away.

The next error I got was this:

Warning: array_merge(): Argument #1 is not an array
500 Internal Server Error - ContextErrorException

And what this turns out to be is that the mime_types must now all be arrays:

fos_rest:
    view:
        mime_types:
            json: ['application/json', 'application/x-json']
            jpg: ['image/jpeg']
            png: ['image/png']

So there you go ūüôā

Symfony 3 Tutorials List

I’ve been asked a few times now if there is a Symfony 3 track available yet at Code Review Videos?

The answer is: yes!

It’s a work-in-progress,¬†but there are already plenty of videos available.

Did you know? There are over 250 videos over 38 courses available right now.

I have been meaning to put together a more formally structured list, so here we go:

Symfony 3 Tutorials List

I’ll keep this list updated as new courses become available.

1. Introduction to Symfony 3

This is a beginner friendly Symfony 3 tutorial series.

I figured the best way to learn a new topic – something which can be quite boring and dry if you just learn the theory stuff – would be to immediately build something cool.

This course covers a lot of the fundamentals by building a reproduction of your GitHub profile.

By the end of this series you will have hands-on experience with:

  • Symfony 3
  • Routing
  • Twig Templates
  • Bootstrap 3
  • Symfony Services
  • Guzzle / RESTful API interactivity with GitHub

You don’t need a GitHub profile to take part in this course. You can use anyone’s profile. No excuses! Get learning, and welcome to Symfony 3 ūüôā

https://www.codereviewvideos.com/course/beginner-friendly-hands-on-symfony-3-tutorial

2. Doctrine

Doctrine allows you to create, read, update, and delete records from your database.

This is pretty much essential knowledge for any developer who needs to get things done.

Doctrine has a ton of unusual terms like hydration, persistence, fixtures, migrations, annotations… and without much context, it can be really confusing at first to figure out what they all mean.

We’ll go through an example of scraping Reddit’s PHP subreddit to explain a large number of these terms, and also in the process start relating entities together, and optimising our queries.

We also cover Doctrine’s Query Builder, and Doctrine Query Language (DQL), and discuss when might be appropriate to use one or the other.

This beginner friendly short course is all about demystifying Doctrine, and getting your started Рquickly Рwith some hands on exercises to cover the basics of working with your database in Symfony 3.

https://www.codereviewvideos.com/course/doctrine-databasics

3. Forms

Symfony’s form component is incredibly versatile.

However, initially it can be a source of confusion.

In this course we cover the fundamentals of using the form – concepts which if you do not know or understand will make life much more difficult for you when you get to the more complex form types that Symfony can offer.

We start with a basic contact form, and then move on to adding and editing records in our database using Doctrine entities.

From there we will cover:

  • form styling – particularly integration with Bootstrap 3
  • form customisation
  • form fragments
  • data validation

And then on to a selection of examples which cover how to use Symfony’s form in a number of more realistic / real world ways.

https://codereviewvideos.com/course/beginner-s-guide-to-symfony-3-forms

Symfony 3 Intermediate Tutorials List

These tutorials are aimed at Symfony developers who are comfortable with the basics of a Symfony project.

It doesn’t matter whether that is Symfony 2, or Symfony 3. The syntax differences between Symfony2 and Symfony3 are not too difficult to figure out¬†for any developer with a project or two under their belt.

If you are new to Symfony, I’d advise not starting with projects in this list to begin with. Make a simpler site, get a feel for the framework, then tackle these bigger projects without losing all your hair in the process.

Symfony 3 RESTful API

Probably the most important topic currently facing back-end Symfony developers is – how do I present my code via a RESTful API?

In Symfony there are a number of ways to solve this problem. In this series I show you one way using:

  • FOSRESTBundle
  • Testing using Behat 3 and PHPSpec 2
  • File Uploading using Flysystem
  • User management with FOSUserBundle
  • Handling login with LexikJWTBundle

This allows your front end developer(s) to interact with your Symfony 3 application using React, Ember, AngularJS, or any other technology your project needs.

https://codereviewvideos.com/course/symfony-3-rest-tutorial

New Courses

I have a long list of forthcoming courses, plenty to keep me going for the foreseeable future.

As a site member, you are more than welcome to submit course ideas and suggestions, and ask questions about video content.

What might not be immediately obvious is that all the previous courses on Symfony 2 topics here at Code Review Videos are in the most part, directly transferable to Symfony 3. There really wasn’t that huge of a change between Symfony 2 and Symfony 3. Not like when we went from Symfony 1 to Symfony 2 anyway.

I really hope you find these courses, and the rest of the content here to be extremely useful.

Don’t struggle learning all this stuff on your own. Let me help you learn Symfony faster and easier.

Site membership is $24.97 a month, or $49.97 a month for a team.