The SymfonyFrameworkBundle in Fork CMS

In our latest release: 3.7.2, the SymfonyFrameworkBundle has been added. This means a big step towards the Symfony2 full stack integration. But what does this change for Fork CMS?

Most developers will never notice the difference. The change is fully backwards compatible and only touches parts of the code you'll never use when developing modules.

The main change that is introduced is the handling of routing between our applications. A routing.yml file has been added to the /app/config folder. This is read by the frameworkbundle and maps certain url's to controllers. We now have one controller for each application. These are responsible for executing the needed action and return the response.

How does it work?

In our config.yml file (app/config/config.yml), the frameworkbundle has been added. We specified that the routing should be handled by the framework.

# app/config/config.yml
framework:
    router:
        resource: "%kernel.root_dir%/config/routing.yml"
        strict_requirements: ~

When a request comes in, it first passes through the index.php file in the root of your Fork CMS directory. A request object is made based on the global PHP variables ($_SERVER, $_POST, $_GET, ...). This request object is sent to the Kernel which tries to get a response relevant for this request.

Our Kernel is some kind of wrapper around our application. In our kernel, the needed services like the database are added to our container, the wanted bundles are initialized, configuration is read,...

When you ask the Kernel to handle a request, it makes sure everything is initialized and then throws an event using the Eventdispatcher component.

// request
$event = new GetResponseEvent($this, $request, $type);
$this->dispatcher->dispatch(KernelEvents::REQUEST, $event);

Code from: Symfony/Component/HttpKernel/HttpKernel.php

The FramworkBundle registers a lot of services in the Symfony dependency injection container. One of these services is the "router_listener". This service is a listener to the "KernelEvents::REQUEST" event. When the event is dispatched, it gets all the needed information from the event, reads the routing.yml file and returns the corresponding controller and action back to the event.

The returned action will be executed and we expect it to return a Response object (Symfony\Component\HttpFoundation\Response). This response object is bubbled up to our index.php file and is sent from there.

What does this mean for Fork CMS?

Bundles

Since we needed to integrate the full Symfony Kernel to be able to use the FrameworkBundle, we're now able to add more bundles to our system. This will make it easier to implement stuff like the WebProfilerBundle, DoctrineBundle, TwigBundle,... A part of this integration has already begun! (https://github.com/forkcms/forkcms/pull/815)

Routing

We now use a routing.yml file wich maps routes to controllers. We can easily add an extra route that maps to a controller that doesn't have the default Fork structure. It can even contain controllers that are not part of Fork. This way, we'll be able to transform modules to the Symfony Bundle system without the need to rewrite everything at once.

Structure

The framework bundle brings our structure closer to the Symfony full stack framework. We're now able to refactor some more code to get closer and closer to a full integration.

Conclusion

This integration doesn't include a lot of changes for most of our users, but it's a big step forward for futher Symfony integration. This means a win for both users and developers!

More info about the integration can be found in the corresponding pull request: https://github.com/forkcms/forkcms/pull/800.