A Guide to Evernote Trunk

I mentioned Evernote in my post on tools for productive online writing and I am sure almost all of you have heard about it – if not used it. It is probably the best note-taking software out there.

Just a few days back, Evernote announced a new section on their site called ‘The Trunk’. Being a long time user of the tool, I was immediately interested in knowing what it was all about and hence decided to check it out. This article sums up what I’ve discovered about this new offering from the folks at Evernote.

What is Evernote Trunk?

Evernote Trunk is basically a neatly organized collection of apps and tools built by third-party developers using Evernote’s API. It’s like Apple’s App Store or like the collection of Facebook apps built using Facebook’s API.

There’s one unique thing about Evernote Trunk though. The product range showcased includes hardware stuff too. There are sections called ‘Hardware’ and ‘Gear’ that talk about physical tools cameras and printers that work with Evernote.

App Categories

Now, lets see what are the categories under which Evernote has organized all these apps and tools. There are almost 100 items, mind you. It’s a very comprehensive collection for Evernote enthusiasts.

Mobile

Evernote works on all kinds of cellphones. It has apps for iPhone, Android, iPad and other smartphones. Hence, there’s bound to be a section dedicated to mobile users in the trunk. It features all kinds of different mobile apps and add-ons.

You’ll find apps like iNews that can quickly send an item from your mobile RSS feed reader to Evernote, Seesmic to save items from Twitter and Facebook to Evernote, and many more.

Desktop & Web

The Desktop & Web section, as the name suggests, features various Evernote related desktop tools and web applications.

And there are some pretty interesting apps here too. Like Scandrop that can scan documents and transfer them directly to your Evernote account, Nitro PDF Reader for saving PDF documents to Evernote, and many such nifty tools.

Hardware

Now we come to Hardware. As I mentioned earlier, the Hardware section showcases some of the physical tools like printers, scanners etc that could make the job of importing notes directly into Evernote easier.

This section lists Evernote compatible hardware from major vendors like Canon, Fujitsu, Nokia and Sony. One very interesting tool in this category I came across lets you wirelessly send pictures from your digicam to Evernote. It’s known as Eye-Fi.

Gear

If you are big fan of Evernote then you’d love the Gear section. It features all kinds of Evernote branded accessories and tools you could make use of.

There’s the Evernote starter pack, Evernote essentials guide, stickers, all kinds of t-shirts, wallpapaer pack, premium notepad, a podcast to listen and much more.

Notebooks

Finally, we’ve got a section named Notebooks. It’s an interesting category to say the least. You’ll find some familiar names in this section, like Make magazine and Cool Hunting.

What Evernote has done is that it has partnered with some of these publications to create customized content for Evernote users. So, basically, you can import these notebooks to your account and get customized content delivered right inside your Evernote. And they include some really cool stuff. Like, the Make: Projects Home and Garden notebook adds a bunch of DIY projects to your account. On the other hand, the Cool Hunting Travel Notebook comes with a number of essential travel tips.

How to Get Them Into Your Evernote?

Right, so now that you are tempted to try out some of these cool apps in the Trunk, you’d be wondering how to access them. Well it’s pretty simple actually. If you are using the latest version of Evernote on Windows or Mac, you should be prompted to update and once you do, you will see a ‘Trunk’ on the toolbar from where you can get direct access to the all those applications.

For those who prefer to use Evernote on the web, well, just sign in to your account and you’ll see the Trunk link present already, right on top. Click on it and start trying the apps, especially from the ‘Notebooks’ section.

As you can see, this new suite of tools from Evernote has to offer augments an already great note taking solution. If you are an Evernote user, I’d love to hear what you have to say about it.

Learn How to Build a Successful Blog Business

Envato is one of a small number of companies that has learned how to make money from blogs. Today, we gross well over seven figures a year from our blogs.

So it’s no small announcement that CEO Collis Ta’eed has released a book packed with the company’s secrets, detailing a road map you can use to navigate your blog business to success.

How to Build a Successful Blog Business is a straight forward guide to building a publishing business online that covers everything from choosing a niche to hiring staff, registering a business to selling it, finding traffic to monetizing it.

Whether you are interested in creating an additional income stream or building a fully-fledged business, this is an essential read for web entrepreneurs and online publishers.

Quick Tip: 5 Easy Ways to Stay on Track With Your Project 365

The first time I tried to complete a Project365 I failed, badly. In less than two weeks I was cheating, uploading photos from multiple days to try to keep up. Shortly after that I just gave up altogether. A month and a half ago I started all over again and this time I’m not struggling at all thanks to a couple of handy strategies I’ve been using, which is exactly what I’m going to share with you today!


Step 1. Do it With Friends

The most tricky part about a Project365 is often just remembering to do it, having a group of friends who are in the same boat helps a huge amount. Having people to talk to about your photos will keep them at the front of your mind, and you’ll have the added benefit that they’ll remind you get that image uploaded.

If you don’t know anyone who is doing a Project365 then all you have to do is join the Flickr Project365 Group – there are thousands of people there, all doing it me included! So go and find some photos which you like, and then leave some comments! Chances are that at least some people will reciprocate, and you’ll start building up your network.


Step 2. Find Inspiration

During my first attempt at a 365 it would get to the latter part of the evening and I would start looking around the room for something (anything) to photograph. This almost always resulted in boring mediocre photos of stuff on my desk.

If you’re short on ideas for the day then one of the best strategies I’ve found is to look through some of the best photos of the day on Flickr and try to replicate one of them in some way. You can easily find the top photos of the day on Flickr by clicking on the “Last 7 Days Interesting” link under “Explore” in the main navigation. This should keep you challenging yourself to produce high quality images without having to spend ages deciding what to photograph when you’re having a mental block.

Finally – subscribe to the PhotoJojo Newsletter, you can’t beat having great photography project ideas emailed straight to your inbox every so often!


Step 3. Get Some New Equipment

It’s amazing how a new bit of gear can breathe new life into your motivation for photography. Picking up a 50mm lens and a really cheap lighting kit helped me in a big way. You don’t have to spend a lot of money, if you’re interested in off-camera flash then you can pick up a cheap umbrella, stand, and flash for less than $100. Playing with studio lighting is a lot of fun, and it opens up so many more possibilities for Project365 shots, especially when you’ve left it till the last-minute and it’s dark outside again.


Step 4. Get A Flickr Pro Account

It’s not impossible to do a Project365 without a Flickr Pro account… but having one makes things much easier. Upgrading (just $24.95 for an entire year) means your monthly bandwidth limits are removed, you can access your original files at full size, and most importantly: you get full statistics on all of your photos.

The first two are handy, but the stats are really useful. In particular, stats let you gauge your own success rate without anyone else needing to tell you. You can see which of your shots got a lot of attention and which got none at all. This might be overly simple but it’s really useful for progressing as a photographer.


Step 5. Don’t Kill Yourself With Rules

Everyone is different and imposing a such a long-term project on yourself is a big deal. If you want to see it through to the end then the best thing to do is to make sure that the project suits you. I work for myself from home and I pretty much never get to bed before 2am. For that reason I now do my 365 according to my sleep cycle, not to the clock. As long as I’m awake – then it still counts.

Don’t be afraid to make small changes to fit the project better to you.

Credits: Hand-holding photo by Ashley Baxter and Rick Nunn for their Project50, Car lighting photo by Ricky Flores, self-beating photo by me, John O’Nolan.

Friday Photo Critique #43

Friday Photo Critique is our weekly community project, where we publish a photograph submitted by one of our wonderful readers, then ask you all to offer constructive feedback on the image. It’s a great way to learn more about photography, express your viewpoint, and have your own image critiqued!


Quick Ground Rules

  1. Play nice! We’ve deliberately chosen photographs that aren’t perfect, so please be constructive with any criticism.
  2. Feel free to offer any type of advice – composition, lighting, post-processing etc.
  3. You can also link to photographs that you feel offer a great example of this type of image shot exceptionally well.

Without further ado, here is this week’s candidate for Friday Photo Critique!


The Photograph

Photo Critique

Photographer: Ryan Szepan

Please let us know what you think in the comments – how would you have approached the scene or taken the photo differently? A massive thank you to everyone who commented last week.

The most constructive and helpful comments will be featured on the site. Interested in submitting your own photo? You can do so here!

Hints & Tips for Composing a Perfect Photo

Composition can simply be defined as how elements are arranged in a photo. You can choose to stand far away or move close up. You decide what type of lens to use. The basic skills of composition can be learned and practiced, and this tutorial is meant to add some tools to your arsenal, because compositional elements are just that, tools. Each one of these sections is a little trick that can apply to different situations. So let’s get started!


Rule of Thirds

The phrase “rule of thirds” is thrown around a lot in photography, and I have heard at least five different versions of the rule. Here are two interpretations.

One, make a tic-tac-toe board over your photo. Your main subject or an important feature of the subject should be at one of the intersections of two of the lines.

Two, divide your photo into thirds horizontally and vertically (same as above), your subject should be in 1/3 of the frame either horizontally or vertically, not both.

So basically, it’s generally a good idea to keep your subject out of the middle of the frame. Now that wasn’t so hard was it? As you can see in the photo below, the subject lands at an intersection of the lines. This lets your eye flow back into the frame to reveal the environment where the child is playing.


Repetition of Form

When shooting photos, it is often like being on a treasure hunt. You look for compositional elements. You seek them out. While the rule of thirds is a compositional tool that you control by framing up an image, the concept of repetition of form is something you look for and find. You can apply the rule of thirds in almost any situation, but repetition of form will not always be available.

That being said, repetition of form is basically just that, repeating shapes. Think of things that you see everyday; a row of flags or boxes, a line of children, a bunch of balloons. When you encounter these things, shoot the photo to emphasize the repetition. The photo below shows two sets of hand folded in prayer. I think the symmetry of the image shows unity and balance.


Leading Lines

Using leading lines is like repetition of form in that it is a compositional tool you have to seek out and look for, you cannot just apply it at will. Any strong lines that are in your images will lead the viewer’s eye from one end to the other.

The eye naturally follows lines. Imagine railroad tracks with a person walking toward you along them. The lines of the tracks will lead your eye to the person. Look for the edges of shelves, stripes on the road, even telephone wires or a fence. Arrange the lines so the go to your subject.

Usually getting physically closer to the lines helps. If the lines are on the ground, get close to the ground. If the lines are on a wall, get closer to the wall. But even if you’re not going to use lines, be conscious of them. Lines can just as easily lead your viewer away from a subject as toward them.

As in the example, the photo below uses railroad tracks to bring your eye from the railroad worker to the train wreck behind him:


Framing

People frame and mat photos to emphasize them, to draw attention to them. You can use this same technique within photographs. It’s sometimes easier to think about this technique in a different way. Think about it as shooting through objects – look for things to shoot through.

Look for windows, slats or holes in a fence, even the shapes that people can make with their arms or legs. When utilizing the framing technique, the smallest movements can make all the difference. A few inches, or even millimeters, can have a profound impact.

As with all of these techniques, and really all of photography, be deliberate in your image making. Think about what you’re trying to say and use the tools at your disposal that are most appropriate.

In the next photo, the child is framed between the lines of the abacus. In this instance, I think the framing creates a tension that we all remember from our days of doing math homework.


Layering

Photography as an art form has some limitations. At reproducing reality, photography can for the most part not show you time. Video can show time, but neither video or photography can show depth (unless you want to get technical and bring up 3D technology). But there are ways around this.

Layering can make your photos seem more three-dimensional. By having something in the foreground, something in the background, and something in the middle, you can create depth to your image. Your subject can be in any of these positions. Having each of the individual layers add information to the story of the photo can really take your work to the next level.

In the following image, the child drawing on the ground is the foreground element, but the children behind him add an additional layer. It shows that he is participating in an activity with others and isn’t just by himself.


Bright Spots

Like the technique of leading lines, the idea of bright spots (sorry it doesn’t have a more official-sounding name) describes the natural behavior of human vision. People’s eyes are naturally drawn to the brightest part of the image.

This can be good, such as having a light face on a dark background. But this can also cause problems, such having a bright lamp in the background when your subject isn’t lit as well. You can use this knowledge as part of your compositional technique, but it is also just a good idea to keep this in mind while your shooting to avoid a distracting problem in your image.

In the photo below, this technique is exaggerated because the subject in very bright light wearing colorful clothes while the rest of the image is very dark.


Negative Space

The term negative space refers to large areas of blank, empty space, usually contrasting in color, tone, or brightness to your subject. This technique creates a dynamic separation. Depending on how negative space is used, it can create tension or unity in an image.

There are several famous pieces of art and photographs that utilize this technique, but again, it’s usually something that has to be found or created in a studio.

In the next photo, the sky acts as the negative space and balances the buildings in the frame. But toward the left and the right the buildings seem to be reaching up and pushing against the negative space.


Selective Focus

While our eyes do have to focus on things at different distances, they do it very quickly and we normally don’t notice that things closer or farther away from what we’re looking at are not as sharp.

A camera operates differently. A good photo can be many things, but often it is a photo that shows the subject to the viewer in a way that the viewer doesn’t typically see it. We don’t notice what our eyes are focused on in our daily lives, so appropriately choosing and emphasizing focus can work to your advantage.

Selective focus is usually achieved by using a shallow depth-of-field. Depth-of-field is determined by your aperture. For a shallow depth-of-field, you want your aperture as wide open as possible, in other words, you want the lowest number f/stop possible.

If you’re unfamiliar with the term “depth-of-field,” it is a little hard to define, so I won’t go into it here, but it is not hard to find information about it. In the photo below, I used a shallow depth-of-field, selectively focusing on the girl to draw attention to her and separate her from the environment.


Camera Height or Angle

Continuing on with the idea that good photos show things to the viewer in a different way, people are used to seeing things from standing eye-level. So it would stand to reason that simply changing the height or angle of view would give your photos an interesting look. Get on a chair and show the scene from above. Lay down on the floor and look up at everything.

There are also some principles you should remember while changing your height or angle. People shot from a low angle will seem taller and perhaps stronger or more dominating, while people shot from a high angle will seem small and possibly weak or vulnerable.

This is something people perceive on an almost subconscious level. Adults literally look down on children, and when we were children we literally looked up to adults. Use this to your advantage. You could use it to contrast the obvious, or use it to add another dimension to the story your image is telling.


Lensing

Beginning photographers will typical choose the focal length (how “zoomed” in or out they are) of their lens based on their distance to the subject. If close to something, they zoom out. If far from something they zoom in.

For the purposes of this tutorial, let’s pretend we only have two lenses: a wide angle lens and a “longer” telephoto lens. These lenses have unique characteristics other than how close they make things appear. As I mentioned earlier, a telephoto lens has a more shallow depth-of-field than a wide angle lens when they are both set to the same f/stop and focused at the same distance.

Telephoto lenses also achieve a characteristic called compression. Compression makes near and far objects appear closer together and also closer to the same size. Wide angle lenses allow the viewer to feel closer to the subject (but only if you get in close).

Wide angle lenses can also be used to include a lot of the background, while telephoto lenses can be used to eliminate distracting backgrounds.

In the photo below, I shot the same scene using a telephoto and a wide angle lens. As you can see by the lines, in both photos, the top of the frame is the girl’s head and the bottom is the edge of the logo. For the telephoto image, I moved farther away, and for the wide angle image I moved in very close.

You can see the differences in how the images look, like the relative size of the logo to the girl in the frame and how much of the background you can see. Sometimes it is good to “zoom” with your feet. It can be a good exercise to zoom your lens all the way in and then physically back way up until you have what you want in your frame. On the other hand, you can set you lens very wide and then move in close.


Conclusion

This tutorial probably doesn’t cover every element of composition, and it can probably be argued that camera height and lensing aren’t strictly used for compositional purposes. That said, I think that with all of these tools at your disposal, you’ll have a good foundation to starting making and understanding great photos.

Just remember that rules are made to be broken, not every image has to follow the rule of thirds. But remember to look for those compositional elements that naturally occur in our world, like leading lines and repetition of form. Also remember to show your viewers things in a way that they haven’t seen them before.

Now get out there are start composing!

How to Use CakePHP’s Access Control Lists


If you’re building a CMS, you’ll probably need different user roles—superusers, admins, users—with different permission levels. Too complicated to code? Enter CakePHP’s ACL (Access Control Lists). With the right setup, you’ll be checking user permissions with just one line.

Introduction: What Are Access Control Lists?

The ACL lets you create a hierarchy of users with their respective roles. Here’s a quick example.

  • Super Users
    • User #1
  • Admins
    • User #2
    • User #3
  • Users
    • User #4
    • User #5
    • User #6
    • ….

In this tutorial, we will be setting up an ACL for a simple blog. If you haven’t yet checked out Getting Started With CakePHP (and Part 2) here on Nettuts+, please do so and then return, as we will be taking for granted the framework basics.

With this hierarchy, we can assign several permissions for each role:

  • The Super Users can create, read, update and delete Posts and Users.
  • The Admins can create, read, update and delete Posts.
  • The Users can create and read Posts.
  • Everyone else can just read Posts.

Each permission will be given to the group, not to the user; so if user #6 is promoted to Admin, he will be checked against the group permission –not his. These roles and child nodes (users) are called Access Requests Objects, or AROs.

Now, on the other side, we have the Access Control Objects, or ACOs. These are the objects to be controlled. Above I mentioned Posts and Users. Normally, these objects are directly linked with the models, so if we have a Post model, we will need an ACO for this model.

Each ACO has four basic permissions: create, read, update and delete. You can remember them with the keyword CRUD. There’s a fifth permission, the asterisk, that is a shortcut for full access.

We will be using just two ACOs for this tutorial: Post and User, but you can create as many as you need.

The ACL Tables

Let’s proceed to create the database tables. You can find this code in db_acl.sql inside your app’s config/sql directory.

CREATE TABLE acos (
  id INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  parent_id INTEGER(10) DEFAULT NULL,
  model VARCHAR(255) DEFAULT '',
  foreign_key INTEGER(10) UNSIGNED DEFAULT NULL,
  alias VARCHAR(255) DEFAULT '',
  lft INTEGER(10) DEFAULT NULL,
  rght INTEGER(10) DEFAULT NULL,
  PRIMARY KEY  (id)
); 

CREATE TABLE aros_acos (
  id INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  aro_id INTEGER(10) UNSIGNED NOT NULL,
  aco_id INTEGER(10) UNSIGNED NOT NULL,
  _create CHAR(2) NOT NULL DEFAULT 0,
  _read CHAR(2) NOT NULL DEFAULT 0,
  _update CHAR(2) NOT NULL DEFAULT 0,
  _delete CHAR(2) NOT NULL DEFAULT 0,
  PRIMARY KEY(id)
); 

CREATE TABLE aros (
  id INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  parent_id INTEGER(10) DEFAULT NULL,
  model VARCHAR(255) DEFAULT '',
  foreign_key INTEGER(10) UNSIGNED DEFAULT NULL,
  alias VARCHAR(255) DEFAULT '',
  lft INTEGER(10) DEFAULT NULL,
  rght INTEGER(10) DEFAULT NULL,
  PRIMARY KEY  (id)
);

We can begin now creating ARO and ACO nodes, but hey, we don’t have users! We’ll have to create a basic authentication system.


Step 1: A Basic Authentication System

As this tutorial is intended for CakePHP developers with a basic to moderate knowledge of the framework, I will be supplying the code and a brief explanation. However, the authentication system is not the goal of this tutorial.

The MySQL table:

CREATE TABLE users (
  id INTEGER(10) UNSIGNED AUTO_INCREMENT KEY,
  username TEXT,
  password TEXT
);

The User model (models/user.php)

<?php
class User extends AppModel {
    var $name = 'User';
}
?>

The Users controller (controllers/users_controller.php)

<?php
class UsersController extends AppController {
    var $name = 'Users';
    var $components = array('Auth'); 

    function beforeFilter(){
        $this->Auth->userModel = 'User';
        $this->Auth->allow('*');
    } 

    function register(){
        if(!empty($this->data)){
            // Here you should validate the username (min length, max length, to not include special chars, not existing already, etc)
            // As well as the password
            if($this->User->validates()){
                $this->User->save($this->data);
                // Let's read the data we just inserted
                $data = $this->User->read();
                // Use it to authenticate the user
                $this->Auth->login($data);
                // Then redirect
                $this->redirect('/');
            }
        }
    } 

    function login(){
        if(!empty($this->data)){
            // If the username/password match
            if($this->Auth->login($this->data)){
                $this->redirect('/');
            } else {
                $this->User->invalidate('username', 'Username and password combination is incorrect!');
            }
        }
    } 

    function logout(){
        $this->Auth->logout();
        $this->redirect('/');
    }
}
?> 

Since we have new elements, let’s review them. First, we are setting a $components variable. This variable includes all the components in the array. We will be needing the Auth component, which is a core component, as are HTML and Form helpers, but since it isn’t included by default by Cake, we will have to include it manually.

The Auth component handles some basic authentication mechanics: it helps us to login a user and it handles an authenticated user’s session for us, as well as handling the log out and basic authorization for guests. Also, it hashes the password automatically. I’ll be explaining how to call each function in the following paragraphs.

Next, we are creating a function called beforeFilter. This is a callback function and it lets us set some actions before all the controller logic is processed. The Auth component requires us to specify a model to be used, in this case the User. Then, by default, it will deny all the access to users not logged in. We’ll have to overwrite this behaviour with allow() which requires one parameter. That parameter can be an asterisk, specifying that all methods inside said controller can be accessed by unauthenticated users. Or, it can be passed an array with the functions that can be accessed by unauthenticated users. In this case, since we have just three functions, the following lines are the same thing.

$this->Auth->allow('*');
$this->Auth->allow(array('register', 'login', 'logout'));

For the login() function, the Auth component will handle all the login mechanics for us. We will just have to supply the function with an array with two keys: the username and the password. These keys can be changed, but by default, both username and password fields will be matched against the database and will return true if the user has been authenticated.

Finally, the controller’s login function will try to match a username/password combination against the database.

Please note that this code is very basic. You’ll need to validate the username characters, if the username exists, the minimum length for the password, and so on.

The Register view (views/users/register.ctp)

<h2>Register your account</h2> 

<form method="POST" action="<?=$this->here; ?>"> 

<p>
    Username
    <?=$form->text('User.username'); ?>
</p>
<p>
    Password
    <?=$form->password('User.password'); ?>
</p> 

<?=$form->submit('Register'); ?>
</form>

The Login view (views/users/login.ctp)

<h2>Log in to your account</h2> 

<form method="POST" action="<?=$this->here; ?>"> 

<?=$form->error('User.username'); ?>
<p>
    Username
    <?=$form->text('User.username'); ?>
</p>
<p>
    Password
    <?=$form->password('User.password'); ?> 

</p>
<?=$form->submit('Log in'); ?>
</form>

Open /users/register in your web browser and register a new account. I suggest admin as username and 123 as password and if your session expires just go to /users/login and enter the correct username/password combination you just created.


Step 2: Denying Access To Unauthenticated Users

We’re not even working with ACL, but we already can deny posting, editing and deleting posts. Open your Posts controller and add the Auth component.

var $components = array('Auth');

Now go to /posts in your web browser. If you’re logged in, you should see the posts, but if you’re not, you will be redirected to /users/login. By simply including the Auth component, all the actions are by default, denied for guests. We need to deny three actions for unauthorized users: create, edit and delete. In other terms, we’ll have to allow index and view.

function beforeFilter(){
    $this->Auth->userModel = 'User';
    $this->Auth->allow(array('index', 'view'));
}

Go to edit or create a post; if you’re not logged in, you should be redirected to /users/login. Everything seems to be working quite good, but what about the views? The edit and delete links are being shown to everybody. We should make a conditional.

But before going into that, let’s see how Auth’s user() function works. Copy and paste these lines into the index function.

$user = $this->Auth->user();
pr($user); 

Open your /posts in your browser and, if logged in, the pr() will throw something like this.

Array
(
    [User] => Array
        (
            [id] => 1
            [username] => admin
        )
) 

The user() function returns an array just as a model would do. If we had more than three fields (password is not included), they will be shown in the array. If you’re not logged in, the array will be empty, so you can know a user is logged in if Auth’s user() array is not empty.

Now, Auth is a component, meant to be used in a controller. We need to know from a view if a user is logged in, preferably via a helper. How can we use a component inside a helper? CakePHP is so awesome and flexible that it is possible.

<?
class AccessHelper extends Helper{
    var $helpers = array("Session"); 

    function isLoggedin(){
        App::import('Component', 'Auth');
        $auth = new AuthComponent();
        $auth->Session = $this->Session;
        $user = $auth->user();
        return !empty($user);
    }
?> 

Save this snippet in views/helpers as access.php. Now let’s see the code, line by line. First, we are setting up a $helpers var. Helpers can include other helpers, just like $components can. The Session component is required for the Auth component, but we have no access to this component inside a helper. Fortunately we have a Session helper, that will help us.

Next, we create a function and use App::import which will let us import an element that normally we wouldn’t have access to. The next line creates the Auth component in a $auth variable, and now a little dirty hack; since the Auth component reads the session to know if we are logged or not, it requires the Session component, but as we are importing it from a place it shouldn’t belong to, we’ll have to give it a new Session object. Finally, we are using user() and setting it to $user and returning true if the variable is not empty, otherwise false.

Let’s get back to the posts controller and proceed to add the helper.

var $helpers = array('Access');

The access helper is now accessible from the view. Open index.ctp in views/posts and replace this line.

<small><a href="/posts/edit/<? echo $post['Post']['id'] ?>">edit</a> | <? echo $html->link('delete', '/posts/delete/'.$post['Post']['id'], NULL, 'Are you sure?'); ?></small> 

With this one.

<? if($access->isLoggedin()): ?><small><a href="/posts/edit/<? echo $post['Post']['id'] ?>">edit</a> | <? echo $html->link('delete', '/posts/delete/'.$post['Post']['id'], NULL, 'Are you sure?'); ?></small><? endif; ?> 

Go back to your web browser, reload the index page and if you’re logged in, you’ll see the edit and delete links for each post. Otherwise, you’ll see nothing.

While this would be enough if you have an app with one or two users, it is not enough if you have registrations open.


Step 3: Installing ACL

Open the Users controller and add the ACL component.

var $components = array('Auth', 'Acl'); 

Next, let’s create a function to install the ACOs and AROs nodes.

function install(){
    if($this->Acl->Aro->findByAlias("Admin")){
        $this->redirect('/');
    }
    $aro = new aro(); 

    $aro->create();
    $aro->save(array(
        'model' => 'User',
        'foreign_key' => null,
        'parent_id' => null,
        'alias' => 'Super'
    )); 

    $aro->create();
    $aro->save(array(
        'model' => 'User',
        'foreign_key' => null,
        'parent_id' => null,
        'alias' => 'Admin'
    )); 

    $aro->create();
    $aro->save(array(
        'model' => 'User',
        'foreign_key' => null,
        'parent_id' => null,
        'alias' => 'User'
    )); 

    $aro->create();
    $aro->save(array(
        'model' => 'User',
        'foreign_key' => null,
        'parent_id' => null,
        'alias' => 'Suspended'
    )); 

    $aco = new Aco();
    $aco->create();
    $aco->save(array(
        'model' => 'User',
        'foreign_key' => null,
        'parent_id' => null,
        'alias' => 'User'
    )); 

    $aco->create();
    $aco->save(array(
       'model' => 'Post',
       'foreign_key' => null,
       'parent_id' => null,
       'alias' => 'Post'
    )); 

    $this->Acl->allow('Super', 'Post', '*');
    $this->Acl->allow('Super', 'User', '*');
    $this->Acl->allow('Admin', 'Post', '*');
    $this->Acl->allow('User', 'Post', array('create'));
} 

By importing the ACL component, we can access the ACOs and AROs model. We begin by creating an ARO, which is the requester for the objects; in other words, who will be accessing the objects. That would be the user (hence the User string in model). We are creating different roles; Super, Admin, User and Suspended.

Next, we do the same with ACOs, since we just have two objects to manage (Posts and Users), we’ll create two, one for each.

Now, a quick note. The array that we are saving for both ACOs and AROs have four fields: the model name, foreign key (which is useful if you want to give access to one ARO, like a post he created), parent id (which will be used later and is the basic parent-child nodes relationship; we will be creating users below these roles), and the alias (which is a quick form to find the objects).

Finally, we are using ACL’s allow() function. The first parameter is the ACO alias; second, the ARO alias, and third, the permissions given to said ARO. A Superuser has full access to the Post and User models, an Admin has full access to the Post model, and a User can just create posts.

At the function’s beginning, I declared a conditional to check if the Admin role exists in ACOs. You don’t want to install the same thing more than once, do you? It would mess up the database quite badly.

Open /users/install in your web browser, and, since we don’t have a view, CakePHP will throw an error, but just check the MySQL dump. All the relationships have been successfully created, it’s time to work with the child nodes.

Setting users to roles

Let’s clean the users table. Open phpMyAdmin, select your database, the users table and click empty. We’ll get back to the register() function on the Users Controller. Just below this line:

 $this->Auth->login($data);

Paste this code:

// Set the user roles
$aro = new Aro();
$parent = $aro->findByAlias($this->User->find('count') > 1 ? 'User' : 'Super'); 

$aro->create();
$aro->save(array(
     'model'        => 'User',
     'foreign_key'    => $this->User->id,
     'parent_id'    => $parent['Aro']['id'],
     'alias'        => 'User::'.$this->User->id
)); 

In the first line we create a new ARO object. Then we’ll get the parent node in which the user will be created. If there’s a record in the database, we’ll set it to the User ARO, else, the first user should be the Super.

Then we’ll save a new ARO; the model is the one we are working currently on, User, the foreign_key is the last record’s id we just created. The parent_id is the node we began with; we’ll just pass it the id and finally the alias. It is a good idea to call it Model_name, then a separator ::, and then the identifier. It will be much easier to find it.

Now we’re done. Create four users: superuser, adminuser, normaluser and suspendeduser. I suggest the same username and password for testing purposes. Don’t forget that, until this point, only the superuser has a role of Super; all the remaining will be Users!


Step 4: Reading Permissions

Because ACL is a component, it is accessible only within the controller. Later, it will be also in the view; but first things first. Include the ACL component in the Posts controller, as we did in the Users controller. Now you can begin checking permissions. Let’s go to the edit function and do a quick test. In the first line of said method, add this.

$user = $this->Auth->user();
if(!$this->Acl->check('User::'.$user['User']['id'], 'Post', 'update')) die('you are not authorized'); 

ACL’s check() function needs three parameters: the ARO, the ACO and the action. Go and edit a post, and, if you’re not logged in as the super user, the script will die. Go to /users/login and access as the Super user and go back to editing. You should be able to edit the post. Check below the MySQL dump to see the magic. Four database queries: that sure isn’t scalable.

We have two issues. First, two lines for the permissions check. Second, the ACLs aren’t being cached. And don’t forget all the logged users can see the edit link, even if just the Super user can use it.

Let’s create a new component. Let’s call it Access.

<?php
class AccessComponent extends Object{
    var $components = array('Acl', 'Auth');
    var $user; 

    function startup(){
        $this->user = $this->Auth->user();
    }
}
?>

Save it in controllers/components as access.php. The class’s $user var will be initiated as the component is loaded, and startup() is a callback function, so it’s now set in the class. Now let’s create our check() function.

function check($aco, $action='*'){
    if(!empty($this->user) && $this->Acl->check('User::'.$this->user['User']['id'], $aco, $action)){
        return true;
    } else {
        return false;
    }
}

Our check() method will need just two parameters: the ACO and the action (which is optional). The ARO will be the current user for each session. The action parameter will default to *, which is full access for the ARO. The function begins by checking if the $this->user is not empty (which really tells us if a user is logged in) and then we go to ACL. We have already covered this.

We can now include the Access component in our Posts controller and check the permissions with just one line.

if(!$this->Access->check('Post', 'update')) die('you are not authorized');

The same result is achieved with less code, but the error message is ugly. You’d better replace the die() with the CakePHP error handler:

$this->cakeError('error404');

Permissions in views

This might be ugly, but it works. We’ll have to create a helper that loads a component with a custom method for use in the helper.

Add this function in the Access component (controllers/components/access.php).

function checkHelper($aro, $aco, $action = "*"){
    App::import('Component', 'Acl');
    $acl = new AclComponent();
    return $acl->check($aro, $aco, $action);
} 

Now,let’s rewrite the access helper (views/helpers/access.php).

<?php
class AccessHelper extends Helper{
    var $helpers = array("Session");
    var $Access;
    var $Auth;
    var $user; 

    function beforeRender(){
        App::import('Component', 'Access');
        $this->Access = new AccessComponent(); 

        App::import('Component', 'Auth');
        $this->Auth = new AuthComponent();
        $this->Auth->Session = $this->Session; 

        $this->user = $this->Auth->user();
    } 

    function check($aco, $action='*'){
        if(empty($this->user)) return false;
        return $this->Access->checkHelper('User::'.$this->user['User']['id'], $aco, $action);
    } 

    function isLoggedin(){
        return !empty($this->user);
    }
}
?> 

The beforeRender() method is a callback, similar to the component’s startup(). We are loading two components and since these will be used in most functions, it’s a good idea to start all at once, than to manually start them each time the method is called.

Now on your index.ctp view in views/posts you can replace this line.

<small><a href="/posts/edit/<? echo $post['Post']['id'] ?>">edit</a> | <? echo $html->link('delete', '/posts/delete/'.$post['Post']['id'], NULL, 'Are you sure?'); ?></small>

With this one.

<? if($access->check('Post')): ?><small><a href="/posts/edit/<? echo $post['Post']['id'] ?>">edit</a> | <? echo $html->link('delete', '/posts/delete/'.$post['Post']['id'], NULL, 'Are you sure?'); ?></small><? endif; ?>

Just don’t forget to check permissions, both in the views and the controllers!

User data

You can access the user data for a logged user with the user() method in the Auth component. Then you can access the array and get the info you want. But there must be a better way. Let’s add the following function in the Access component.

function getmy($what){
    return !empty($this->user) && isset($this->user['User'][$what]) ? $this->user['User'][$what] : false;
} 

This is quite useful when you need to save a Post with a user_id relationship.

$this->data['Post']['user_id'] = $this->Access->getmy('id');

And in the view, we can do something similar with the helper.

function getmy($what){
    return !empty($this->user) && isset($this->user['User'][$what]) ? $this->user['User'][$what] : false;
}

In your template file you can do something like below to greet a user by his username.

Welcome <?=$access->isLoggedIn() ? $access->getmy('username') : 'Guest'; ?>

Step 5: Modifying Permissions

Let’s say we need to switch roles for the user #4: he needs to be a Super User. So, User’s id is 4 and Aro’s id is 1.

$user_id = 4;
$user_new_group = 1;

Now we need to find the User’s Aro in order to modify its parent Aro.

$aro_user =  $this->Acl->Aro->find('first',
    array(
        'conditions' => array(
            'Aro.parent_id !=' => NULL,
            'Aro.model' => 'User',
            'Aro.foreign_key' => $user_id
        )
    )
); 

Finally, if the $aro_user variable is not empty, let’s update the Aro.parent_id field.

if(!empty($aro_user)){
    $data['id'] = $aro_user['Aro']['id'];
    $data['parent_id'] = $user_new_group;
    $this->Acl->Aro->save($data);
}

Please note that you have to validate both the user’s id and the new aro’s id. If one of these do not exist, it will create a mess in your ACL tables.


Step 6: Optimization

Although the component we just created are both simple and useful, the database is queried with each and every check. It is not ready for production yet. First, the database should be queried as little as possible. To optimize this, we should take advantage of CakePHP’s Cache.

Using Cache will reduce the load quite a bit, but if we have ten posts showing up in the index, and, for each one, we are checking if the user has update permissions for the Post Aco, the framework will be reading and parsing a file to return the same result…ten times for each page load.

That’s the second point: a variable inside the class and some conditionals will make the work lighter, so that a repeated request will be checking against Cache just once.

Both these changes are reflected in access_cache.php, inside the controllers/components directory. So make sure you download the source!


Conclusions

Access Control Lists are a basic features that most apps need. CakePHP has a nice implementation, but lacks in both good documentation and examples. I hope that, with this tutorial, these two issues will now be covered. Thanks for reading!