CakePHP3: When to use Elements, Helpers or View Cells?

This has been asked on Stackoverflow and I decided to turn my long answer in a Blog post as well. This article will explain when to use the different parts of views the best. This might be opinionated but it is based on writing clean and re-usable code.

Elements

Use it when you need to repeat presentation related stuff, usually HTML, a lot. For example I have a project in which three tables use records of an addresses table. The form part of all of these three that contains the address data is an element. There is no logic at all in this and I think if it is just a very simply if that wraps an element call or something similar you don’t need to come up with a helper for that, it’s just to basic. Elements are basically “dumb” snippets that repeat through the site.

Helpers

Use it to encapsulate view logik, don’t put HTML in it if possible or other presentation related things. For example let it do something and depending on the result you can use an element of that result type to render the data: `return $this->_view->render(‘items/’ . $type . ‘_item’);`

You might say now “But the Form- and HtmlHelper contain HTML…” well, they do but look at their code how they deal with it. If you look a the HtmlHelper for example you’ll see a property $_defaultConfig[1]:

These are the template strings that are used to generate the HTML output. This separtes the markup pretty nice from the actual code that generates the final output. Take a look at the FormHelper as well, it’s using widgets to render more complex output. See this section “Adding Custom Widgets“[3] of the official documentation.

So this works fine with element like pieces of markup. By a rule of thumb I would say if your markup is longer than what you see there make it an element and call it from within the helper or make it a widget.

View Cells

Think of view cells as “Mini MVC” stacks that have a view and can load multiple models. They’re IMHO similar to AngularJS directives if you’re familiar with them. See this article for an example [2]. I really suggest you to read it, it explains them and their use cases in detail.

I haven’t done much with them yet but they can be used to replace requestAction() calls for example. You won’t “pollute” your controller with methods that are not intended to be access by a request. Taken from the linked article above:

One of the most ill-used features of CakePHP is View::requestAction(). Developers frequently use this all over their applications, causing convoluted cases where you need to figure out if you are within a web request or an internal action request, cluttering controllers. You also need to invoke a new CakePHP request, which can add some unneeded overhead.

Disclaimer

The above reflects my personal view on these things, there is no ultimate and final rule how you have to use these three things. The goal is always clean and re-useable code and proper separation of concerns. How you archive that is up to you, you’ve got the tools.

[1]: http://api.cakephp.org/3.0/source-class-Cake.View.Helper.HtmlHelper.html#54
[2]: http://josediazgonzalez.com/2014/03/20/view-cells/
[3]: http://book.cakephp.org/3.0/en/views/helpers/form.html#adding-custom-widgets

Simple links and routes with CakePHP 2.x

I’ve recently read this article about entity based routing in CakePHP 3 and thought that this, somehow, could be done for CakePHP 2.0 as well. So I wrote the LinkHelper for CakePHP 2.0 which is now part of my BzUtils plugin.

The biggest difference here is that CakePHP 2 doesn’t use entity objects, instead we have to deal with an array. The downside of the solution for CakePHP 2 is, that it doesn’t work fully automated but you’ll have to write a config for each kind of URL but this gives you as well more control over the URL but still decreases the amount of code you have to write for all your links on your page. You won’t have to do more than just passing the array data to a helper method and provide and identifier. An advantage of my solution is that it can deal with associated data as well. This could be added to the entity route class for 3.0 as well.

So the ideal case would be just something like this:

The result of that call will be:

If you only want to generate the URL, you can do this as well:

How does that work?

First you’ll need your route, as usual:

Now the link building magic: You’ll have to provide a config for each data structure you want to turn into a link. You can put this into bootstrap.php or put it in a separate config file and load it in bootstrap.php. A full featured example might look this:

The title and alias are optional. But you’ll require the title if you want to use that feature and you’ll have to use the alias if your primary models name in the array structure changes for whatever reason. The preset is the URL you want to use, the fieldMap is a mapping of URL params to the array data you pass to the helper that will be turned into the link.

Wherever you now need that link you can simply use the LinkHelper to generate that link. When you need to change the URL some day you’ll just have to change a single place – the config for the URL. This might not sound that great if you have a small application but if you have a large site with many places using the same links this is something really nice to have.

 

CakePHP and token based auth (with Angular JS)

This article will show you how to set up a Json Web Token with CakePHP and Angular. This blog post is not a complete step by step tutorial but shows you the concept of the JWT Token and a high-level implementation. To follow the instructions in this article it is assumed that you know how to work with REST and JSON Views in CakePHP and Composer.

This is actually pretty easy by using php-jwt and modifying Ceerams TokenAuthenticate adapter for CakePHP. I’ve modified the nice working TokenAuthenticate adapter to work with JWT. You’ll need to add firebase/php-jwt to your composer.json or add the library otherwise to your application. You can find the JwtTokenAuthenticate for CakePHP 2.x on Github, it is part of my BzUtils plugin.

So what is the important difference between JWT and a regular Token?

The JWT token is encrypted and contains the actual user data. Usually a token is stateless and you would have to look up the user based on the token generated after login in your database. That’s what the original component did until I’ve modified it to work with JWT. The JWT token eliminates that need because it contains the actual user data, or whatever else data you want to add to it, and encrypts it. Decrypting the token every request is more efficient than querying the DB every request to lookup the user based on the token.

Pay attention to no bloating the token with unnecessary data, just store what you really need, usually the users id, username and maybe email and some authorization specific things like a role. The issue with bloating the token is that your server might not respond properly or won’t respond at all. This is because HTTP does not define any header size limit but most web servers limit the size of headers they accept. For example in Nginx it is 8KB, Apache default limit is 8KB, in IIS it’s 16K. The server will return a 413 Entity Too Large error if the headers size exceeds that limit.

To use the component add this to your AppController::beforeFilter(), you’ll still need the Form Authenticate to do the login.

Your login function has to make use of the JWT lib as well to encode the token, remember, we’re dong RESTful calls and return JSON and don’t access this via the browser directly!

This is the AngularJS component that deals with the token data. Please note that the second request right after the login is just for demonstration purpose to demonstrate that the token works by making an immediate request to a protected action.