Fork CMS 3.5 - major milestone

  • Written by Dieter Vanden Eynde on Wednesday 13 March 2013

Today, we released Fork CMS 3.5. This release is a major step towards the Symfony integration. You can read about all major changes in this blogpost.

Minimum requirements

First of all, we needed to update the minimum-requirements. Not that much has changed: most importantly the PHP version, which has to be at least 5.3.3. The other extra requirements are the JSON-extension and PCRE-extension - these were required already, even though it was not being checked if they were actually available.


Second, we cleaned up the code. A lot of the dependencies were removed from the repository. This allows us to concentrate on the Fork CMS specific code instead of syncing code from other repositories. For people who like to work with Git, there's a drawback: you will have to install the dependencies. The dependencies are handled by Composer. After you cloned the repo, you should run:

php composer.phar install

This command will install all the dependencies in a folder called: vendor.

MIT license

With the 3.5 release, Fork CMS will be available under the MIT-license, for more details see the dedicated blogpost.


Probably the most anticipated change is the integration of Symfony. As we stated in a previous blogpost we decided to move to Symfony. We started looking at the available components to see which ones would be suitable for initial implementation. Finally, we decided on HTTPKernel, HTTPFoundation, Dependency Injection (DI) and its related components.

Front controller and AppKernel

In the Symfony framework the DI-container gets passed to each bundle from its Kernel class. It processes an incoming request, loads any relevant config files, initiates a DI-container and processes the bundles. Afterwards, the front controller sends a response back to the browser.

So we built a Kernel of our own, relying a lot on the implementation in Symfony's framework. You will find most new files in the app folder in Fork's webroot. Let's take a closer look at them:

  • app/AppKernel.php
    This extension of the Kernel class contains a method registerServices() where the database service gets registered. Custom services can be registered here, to make them available throughout Fork's DI-container.

  • app/ApplicationInterface.php
    Every Fork application (frontend, backend, api,...) should have, at the very least, two methods; initialize() and display().
    If you're looking to expand Fork with an additional application, you'd do well to implement this interface.

  • app/BaseModel.php
    FrontendModel and BackendModel extend from this class. Its purpose is to provide a getContainer() method in the models, which in turn provides a way to access the database object. To facilitate this, BackendModel::getDB() and FrontendModel::getDB() have been removed in favour of the following:


  • app/KernelLoader.php
    You can extend from this class to pass Fork's Kernel object. See the Frontend class for an example on usage.

  • app/Kernel.php
    This class loads our configuration files, along with the service container.

  • app/routing.php
    This class gets called in app/AppKernel.php in Symfony's handle() method. By intercepting the Request object at this point, we can load all Fork functionality inbetween, and make it return a Response object. All of Fork's old "init" classes (API, installer and cronjobs included) get instantiated through this class.

  • app/config/config.yml
    Loads app/config/parameters.yml. This is the file that gets loaded in the Kernel.
    This is a YAML file, and gets loaded through Symfony's YAML-component. For more information, read the Symfony documentation on YAML.

  • app/config/parameters.yml
    The library/globals.php file is replaced with app/config/parameters.yml. In time, all constants in Fork will be replaced by kernel parameters.

The new Kernel class can be accessed throughout fork actions in backend/frontend, cronjobs and the API:

$kernel = $this->getKernel();

globals.php -> parameters.yml

As previously stated above, the old globals.php file(s) are gone. The installer now generates an app/config/parameters.yml file with all relevant data that was previously in the globals. This paves the way to implement environment configuration and service registration through YAML-files in a later stage, all of this taking place in the aforementioned Kernel class.

Service container

The new DI-container can be used throughout Fork actions in backend/frontend, cronjobs and the API:

$container = $this->getContainer();

For more information on the usage of the DI-container object, read up on the Symfony documentation.



  • Core: Upgraded to CKEditor 3.6.6
  • Core: Upgraded to CKFinder 2.3.1
  • Core: added utils.string.sprintf to backend and frontend. Thx to Jeroen Desloovere.
  • With the 3.5.0 release, Fork CMS will be available under the MIT-license.
  • Core: allow people to define their own errorhandler.
  • Core: switched to the official Facebook SDK, inspired on the pull request of Jeroen.
  • Start using Composer to handle dependencies. See more info in the
  • Core: Akismet and CssToinlineStyles are now installed with Composer.
  • Core: Upgraded Highcharts to 2.3.3
  • Core: Upgraded to jQuery UI 1.8.24
  • FormBuilder: do not prefix the site URL to the form action to prevent submitting to another domain.
  • Core: starting to use namespaces for the external classes that use namespaces.
  • Core: upgraded Spoon
  • Core: new CKFinder license, see:
  • Core: merged all autoloaders in to one autoload.php.
  • Core: added the Symfony HttpFoundation and HttpKernel components via an AppKernel.
  • Core: added the Symfony DependencyInjection component to handle our services and config.
  • Core: the AppKernel is passed to all actions/models which contains the DI container.
  • Core: one frontcontroller which routes all requests (actions, ajax, cronjobs, ...)
  • Core: replaced globals*.php config files with app/config/config.yml.
  • Core: removed js.php
  • Spoon: Spoon dependency is now handled via composer.
  • Core: Include a non-official patch for CKeditor to fix an issue with the stylesheetparser on FF/Safari on Macs.
  • Blog: enabled Flip ahead for blogposts.
  • Core: enabled Flip ahead for paginated pages.
  • Core: Pagination can now use an anchor, thx to Jeroen Desloovere.
  • Core: Added validation for module and action in the frontend ajax.
  • Core: added $action to BackendModel::getExtrasForData + deleteExtrasForData.
  • Core: getUTCTimestamp() added in FrontendModel. Thx to Jeroen Desloovere.
  • Core: Replace getDB() in the models with getContainer()->get('database')
  • Core: Pagination can now use an anchor. Thx to Jeroen Desloovere.
  • Core: added $action to BackendModel::getExtrasForData + deleteExtrasForData.
  • Core: Added validation for module and action in the frontend ajax.
  • Core: getUTCTimestamp() added in FrontendModel. Thx to Jeroen Desloovere.
  • Tags: FrontendTagsModel::get() should use FRONTEND_LANGUAGE. Thx to Jeroen Desloovere.
  • Pages: Widget had invalid parent url
  • Blog: Show always Open Graph Tags
  • Pages: BackendPagesModel::copy() added, so it can be called from elsewhere. Thx to Jeroen Desloovere.


  • Users: Added fix so users can't edit other profiles.
  • SpoonDate: only replace full matches of date abbreviations, otherwise Montag becomes Mo.tag. Thx to Jan Moesen.
  • DataGrid: do not overwrite existing row attributes when greying out a row.
  • Form: encode html entities in hidden field values to prevent XSS.
  • Mailmotor: add jsData to iframe template.
  • Location: Google Maps JS needs to be loaded before location.js, thx to siesqo.
  • Core: when fetching parameters take the index in account when computing the differences.
  • Blog: Use full links for the navigation below the blogposts.
  • FormBuilder: validation (email, numeric) was inherited from previously added fields causing errors on checkboxes.
  • Blog: Use full links for the navigation below the blogposts.
  • Blog: Ticket 294: Next and previous don't work when blog-items has same publish_on date
  • TagBox: Ticket 333: Tags should be handled as strings
  • Extensions: Ticket 316: Link to default action
  • API: Fix bug in form_builder.entriesGet where limit/offset would be applied to fields instead of the form submissions.
  • Locale: Fix jsBackend.locale.get() so the {$loc...} labels get fetched correctly.
  • Core: A search term should only be saved when it's not empty
  • Core: BackendModel::invalidateFrontendCache() should listen to the given language. Thx to Jeroen Desloovere.


Bauffman wrote 7 years ago

Congratz to the team responsible for this release!

Peter Muusers-Meeuwsen

Peter Muusers-Meeuwsen wrote 7 years ago

Thanks! I'll be jumping to 3.5 soon!

Is there a recommended upgrade path for 3.4.4 -> 3.5? I guess with so many changes, it won't be simply a case of copying the new files over and run with it...?

Louis wrote 7 years ago

Can't wait for the full transition!

Fork would then be by my cms of choice.

Jeroen Desloovere wrote 7 years ago

Glad to see lots of changes. Big things are yet to come.

Dieter W

Dieter W wrote 7 years ago

Hi Peter, I'm writing an article about how to update your modules. I think that will make it clear how to upgrade.

Stay tuned!

John Poelman wrote 7 years ago

That should come in handy, soon I will be modifying the links module to work for this release. Way to go Forkdevs!

Kevin Van Den Haute wrote 7 years ago

I'm struggling with my Nginx config to get 3.5 running like it should. Redirection to the installer fails. Do you guys have an example config for Nginx (the one from 2011 is not working with 3.5)?

Kevin Van Den Haute wrote 7 years ago

No one? That's a bummer .. :(

Wouter Sioen wrote 7 years ago

@Kevin: you should change your nginx config so all requests go through the front controller (the index.php in the root), also the requests for the installer, backend or api.

Kevin Van Den Haute wrote 7 years ago

I tried, I'm not able to get it working. I really want to go forward with Fork, but the lack of help from the Fork team is really disappointing. They do a big change, but they don't help the users with a valid config for a popular web server since the old config is not valid anymore. And I'm not switching to Apache. Lost enough time already, I will look for another CMS. Sad but true :(


Flip wrote 7 years ago

@Dieter W: Did you managed to finish the article? I will be updating to 3.5 (well, actually 3.5.1) soon, so a good upgrade-manual would come in handy.

Dieter W

Dieter W wrote 7 years ago

Kevin, I'm very sad to hear that. I couldn't and still can't help you with Nginx problem, but Fork is a community project so ask around and I'm sure someone can help you with that! (Forum, IRC, ...) Hope to see you back!

Flip, the article that I was talking about is published on Let me know if your have anymore questions!