Using CakePHP behaviors

Let me assume: your Cake app has users and these users have something in hasOne or hasMany relationships. If there are more than one user you probably want to allow most of CRUD actions only to the owner.

How do you do that? And how to do it right?

In my early years I would have done something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php
class PostsController extends AppController
{
    public function edit($id = null)
    {
        // ... some logic
 
        $user_id = $this->Auth->user('id');
        if (0 != $this->Post->find(
                'count',
                array(
                    'conditions' => array(
                        'Post.user_id' => $user_id,
                        'Post.id' => $id
                    )
                )
            )
        ) {
            $this->Post->save();
            // more logic
        } else {
            // error:403 logic
        }
    }
}

And that’s just not a DRY KISS. Today, while coding a project, I have came up with a better idea for this: writing a behavior.

Here’s the code I’ll be using in my projects::

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?php
/**
 * Belonging to user behavior.
 * Models acting as belinging to user are able to perform common tasks
 * (check if the entry belongs to user, etc.)
 *
 * @author Steponas Dauginis <stepas@itworks.lt>
 */
class BelongingToUserBehavior extends ModelBehavior
{
 
    /**
     * Checks if the given Model.id belongs to the given user.
     *
     * @param AppModel $Model The model who is acting as belonging to user.
     * @param int $id [optional] Model's row id. It can be set as $model->id.
     * @param int $user_id [optional] The user in question.
     *
     * @return bool
     */
    public function belongsToUser($model, $id = null, $user_id)
    {
        if (!isset($id) && isset($model->id)) {
            $id = $model->id;
        } else if(!isset($id)) {
            return false;
        }
 
        return 0 < $model->find(
            'count',
            array(
                'conditions' => array(
                    $model->alias . '.id'      => $id,
                    $model->alias . '.user_id' => $user_id,
                ),
                'recursive' => -1
            )
        );
    }
}

So the example Post model should have a new line:

public $actsAs = array('BelongingToUser');

And the controller logic should be rewritten into this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
class PostsController extends AppController
{
    public function edit($id = null)
    {
        // ... some logic
 
        $user_id = $this->Auth->user('id');
        if ($this->Post->belongsToUser($id, $user_id)) {
            $this->Post->save();
            // more logic
        } else {
            // error:403 logic
        }
    }
}

That’s a lot better!

Other thoughts:

  • I didn’t put this into AppModel because not every model belongsTo user.
  • I didn’t put this only into Post model because more models can belongTo user.

I would recommend using all reusable things like Behaviors, Components and Helpers. Five minutes more of coding today will save you a day tomorrow.

Happy coding!

Posted in CakePHP | Tagged , | Leave a comment

Project JavaScript string localisation

JavaScript in english, russian, lithuanian and (probably) italian

If you ever worked on a project which involved JavaScript text, you surely have had some thoughts on how to pass localized or server-side processed strings to JavaScript.

One good way is JavaScript templates (Mozilla has some links, I use jQuery templates). But depending on the situation this sometimes is out of the question.

The other way – JavaScript localization (l10n). My new project will be using the JavaScript layout I proposed in my last post. It’s being written on top of CakePHP. So how will I deal with localization? Quite simply.

First, I have built a small object for handling language strings:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/**
 * JS localisation.
 * @author Steponas Dauginis <stepas@itworks.lt>
 */
System.Lang = {
    strings: {},
 
    /**
     * Add one localisation string.
     * @param string id
     * @param string str
     */
    add: function(id, str) {
        this.strings[id] = str;
    },
 
    /**
     * Add many localised strings.
     * @param Object list
     */
    addMany: function(list) {
        $.extend(this.strings, list);
    },
 
    /**
     * Returns the localised string or empty string if not found.
     * @return string
     */
    get: function(id) {
        if (typeof this.strings[id] == 'undefined') {
            if (console && console.warn) {
                console.warn('String ' + id + ' is undefined.');
            }
            return id;
        } else {
            return this.strings[id];
        }
    }
};
 
/**
 * Function imitating Gettext.
 * @param string id
 * @return string
 */
function __(id) {
    return System.Lang.get(id);
}

Next, I needed to somehow get the strings from CakePHP localization database into JavaScript. For this job I created a CakePHP Shell script that puts all strings into per-language javascript files.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?php
uses('File');
 
/**
 * JavaScript localisation generator for CakePHP 1.3.
 * @author Steponas Dauginis <stepas@itworks.lt>
 */
class JsLangGenShell extends Shell
{
    function main()
    {
        /**
         * Languages list.
         */
        $langs = array('lit', 'eng',);
 
        foreach ($langs as $lang) {
            Configure::write('Config.language', $lang);
 
            $this->out('Generating JS language file for ' . $lang . '...');
 
            /**
             * The strings.
             */
            $list = array(
                'user.login.loginDialogTitle' => __('Prisijunkite', true),
                'user.login.loginFailed'      => __('Jums nepavyko prisijungti. Patikrinkite prisijungimo duomenis ir bandykite dar kartą.', true),
                'form.pleaseInputValue'       => __('Prašome užpildyti šį lauką', true),
            );
 
            $script = 'System.Lang.strings = ' . json_encode($list) . ';' . PHP_EOL;
 
            $file = new File(APP . DS . WEBROOT_DIR . DS . 'js' . DS . 'lang' . DS . $lang . '.js', true);
            $file->lock = true;
            $file->write($script);
            $file->close();
        }
 
        $this->out('Done. Files refreshed.');
    }
}

PS> I’ve created a test case to check if JSON or index-access is faster in JavaScript. My guess was right – that’s why I encode the strings into JSON.

Now updating the files is easy as this:

% cake\console\cake jslanggen
Welcome to CakePHP v1.3.6 Console
---------------------------------------------------------------
App : app
Path: $path
---------------------------------------------------------------
Generating JS language file for lit...
Generating JS language file for eng...
Done. Files refreshed.

A quick FAQ:

  • Why did I choose this implementation?
    I think all the code must be as clear as possible. Everywhere. So using the same localization syntax in PHP and JS is great!
  • Why not to generate the strings per-request?
    I’m cautios for performance. The language strings don’t change that offten and I don’t find it hard to regenerate the files when needed. It’s even possible to initiate that through administration interfase (e.g. after some string update).
  • If there are a lot of string in the file it will be hard to maintain.
    That’s true. My toughts on that is to create a directory with .php files especially for JS localisation strings. The shell would include every file from that dir and do all the required stuff. But for now there is no such problem.
    This is why I love code – there is more than one problem for every situation, and more than one solution for each problem!
  • Other JS localisation methods?
    Lot’s of them. One interesting way is to add to String.prototype function called, for example, translate. More on this here. Be careful: the first comment IMO not light-weight. Next comments there are worth gold.
    Other resource is here. It is also a gettext-like implementation like mine but with more features. Which I don’t see I will be needing.
Posted in Code, JavaScript, PHP, Theory | Tagged , , | Leave a comment

Project Javascript layout

For some time I’ve been finding myself coding more JavaScript instead of server-side code. And I like it! But that aside, I want to ask you: do you have a file and object-wise layout for your JS code?

I’ve got my hands on a bigger project. And I thought: what path will I choose for name spaces of the objects and directory structure?

The layout

This time I will go with something Java-like. For example, my system error message handler would be System.ErrorMessage, so to show an error I would need to call

System.ErrorMessage.show('This is an error');

The folder structure will be only one directory deep – the first name space being the directory. This differs from the Java approach because in Java there would be a N deep directory tree, N being name spaces of the class (System – 1, ErrorMessage – 2). All other classes will be there as files separated with a dot. Some examples:

  • System would lie in JS_DIR/system/system.js
  • System.ErrorMessage » JS_DIR/system/system.errormessage.js
  • Form.Upload.Ajax » JS_DIR/form/form.upload.ajax.js
  • And the list goes on…

Why this one?

I find this clear, simple and attractive. For huge and JS-intensive projects I guess that multi-directory structure is the better way to go because you – the programmer – are more happy to look at more directories with fewer files than vice versa. But for small to almost-big this is a good way of keeping files ordered.

“Why not place the error messenger in a directory called “messages” instead?”, you may ask. I recommend staying focused without trying to reinvent the wheel :) The naming should come directly from the class names so that:

  1. You (or anyone else) can find the files later easy.
  2. It would be much easier to write code that does class name to file name conversions (for example, caching all required JS files into one or auto-loading missing JS files).
  3. Everybody does it this way. Well, the smarter ones do. This alone isn’t a good statement, but then look at #1.
Posted in Code, Ideas, Theory | Tagged , | 1 Comment

CakePHP vs. Zend framework? The answer is one question.

CakePHP or Zend framework – this question arises quite often. In my opinion, the answer to it is the answer to this question:

Are you (your team) skilled enough to define your own application structure and keep all code in it?

If yes – you can try Zend. It’s great because of it’s “I have it all” attitude. It gives you full freedom of choice how you want to have your application logic. I love it’s autoloading magic! Yet… Are these the features you really need?

Ir no (or “I don’t know…”) – I would recommend Cake. It has it’s own way of doing things – Convention over configuration, it’s called. I would choose Cake. It’s not because I’m not brave enough to choose my own path. It just that my experience with both frameworks shows that Cake helps you bake apps faster than Zend.

CakePHP forces you to keep in tact with the Cake conventions. This makes some devs call it “hard to adapt” but I would call it “do it the Cake way”. Sure, Zend has it’s own recommendations to the structure of your app. But it is so easy go get past recommendations and open… Coding hell. Or whatever you would like to call it. Of course, you can always do this. Even in Cake. But if you do some RTFM, Cake docs will try to guide you the right path.

One other great thing – Zend’s power can be used in Cake as vendors. So no “Zend is more powerfull than Cake”, please.

Keep in mind that this is only a short review-like opinion of mine. Both frameworks have strong and weak sides but IMO most devs would find Cake as the faster alternative to build web apps.

Posted in Theory | Tagged , , | 4 Comments

Fixing code or writing code – what`s better?

Error in code. Happens a lot to us!

This is a long write-up. If you get bored at some point, I recommend going to the conslusion.

Writing new code. Fixing old code (that’s like archaeology, right?). But which one of those does help you become better faster?

More than two and a half years I’ve been fixing code that has been written by all sorts of programmers. The code ranges from PHP3 and IE6-only to PHP5 OO. I’ve been deploying these apps to all sorts of servers and have seen a lot of compatibility problems between OSes, PHP versions and web server configurations. So I think I have something to say about this.

My other one and a half years I’ve been writing apps in teams or alone. Doing freelance jobs. This time I could choose myself which patterns to use, OOP or functional programming to focus on, and so on.

Debugging, fixing, enhancing

Bad code – this one you can not evade. At some point we all did code worse than we do now, and this probably will have to be fixed by someone. What’s good about bad code is that you can identify it and think of how to make it better. But if you are not experienced enough this can be a pitfall and  you would “learn” from it. Bad habits are hard to loose…

Debugging – finding that one buggy line in a mist of files, functions and classes. Maybe the culprit is a misused function? For example:

1
2
3
4
5
6
7
8
<?php
// Let's say the outputted email list is not unique. The code is this:
$list = get_email_list($params);
array_unique($list);
output($list);
// If you're not familiar with array_unique(), this can be hard.
// Line 4 is buggy and should be like this:
$list = array_unique($list);

The good thing about debugging is that you get good at finding problems. You learn to follow the traces, use xdebug. You are angry at bad coders – there is a chance that you will have to fix their code! You get sharp at giving suggestions how to find problems. If you are working on well written projects, debugging can be a good source for looking at how things should be done.
But in reality, debugging good code is rare. If you’re at it – be happy.
The drawback of debugging is that you seem slow. And you think this too. It is hard to read other programmer’s code, even more if it’s crappy and standard-avoiding. Or you are debugging a software that is buggy not in code, but in logic. And you don’t understand how to synthesize these atoms, even when you have a 600-page long manual to help you…

Other good things I’ve learned when debugging:

  • Code quality matters. Choose a coding standard and stick to it. You’ll say thanks to yourself later – and others will see that you have quality.
  • At some point you quickly can say what code is good and what – bad. Why isi t bad? This requires more experience, but you are on the right track!
  • When facing problems you have good examples of BAD code to support your position.

etc.

Optimizing – this is one of the key parts in real-life application work. Optimizing databases, code, UI (usability or JavaScript speed), etc. But be careful -Optimization is root of all evil. This is often learned the hard way. On the other hand, if you like programming, you will like writing the best code there can be. Remember – this is probably impossible (Cite: “If you look at your code a year later and won’t find anything to rewrite, you are not evolving”) so take the time needed to finish your job in consideration.
I like optimizing! Next week I’ll have a jQuery optimization study on one of my work’s projects – I’m looking forward to that!

Writing new code

This part is more interesting for every programmer. This is the one and only way you can be the God of Dev, Michael Jordan of your keyboard.

When writing new code, you are swallowing information faster. You are forced to find solutions to problems you’ve never faced before. You can choose the best pattern that you know of – or learn a new better one. The choice is yours.

But at the same time writing new this requires more skill and experience. Most programmers have their own vision of “the best path to glory”. And this can be wrong. Very wrong.

Speed

When programming your own brand new shiny stuff, you can measure your programming speed, e.g.

$speed_factor = ($job_done_hours + $error_fixing_hours) / $estimated_hours;
if ($speed_factor < 1)
    $manager->kickAss($you);
else
    $manager->makeWorkMore($you);

Compared to debugging, this time you can measure your speed. You can get faster by analyzing the parts you’ve got stuck and finding on how to not get stuck again.

After a year of write-everything-yourself you are starting to realize that using third-parity libs is a time-saver. And a life-saver in terms of open-source (or paid software) support and bug fixing.

Experience

When working on something, you are gaining experience. Once you use a wrong pattern, next time you will try to use a better one. You are learning hands-on new techniques, writing all sorts of tests, mock-objects, and so forth.

In some time you start understanding that hacking the core of the framework you use was a bad idea. And why.

After writing a million or two lines of code you will start getting good at defining the time needed to complete a task. This, of course, will be quite theoretical, but still in the range of “good”.

In the time you code new stuff, you will learn frameworks (server- and client-side), patterns, libraries. You will do more debugging and fixing but this time of your own code.

Conclusion

In my opinion, you need the experience of fixing and writing code. Yes, writing new and fresh code does let you evolve faster, so you should write new stuff more. But it teaches you some good practices “the hard way” – by making and fixing errors. Sometimes it is better to get familiar with bad code of others so you can learn what’s bad. But you have to have a good eye for that.

What’s the most important is the people you work with. If their level of experience is lower then yours, you will have to push them and this will slow you down. But if your co-workers are brilliant people, real problem-solvers and deep into programming, no matter what you do – debug, code or just listen when they talk – you will go up.

I haven’t mentioned this in my article but it is the truth. This truth can be sad because if you’re working hard all alone, you’re doing great as a programmer, but in team of great people you would be moving a lot faster. So go and find a job that does not only offer a good pay for your skills but also has great people that you can learn from.

I wish you that you would one day be a programmer that others look up to. I am striving to be one like that.

Posted in Theory | Tagged , , , | Leave a comment

Why it is more fun to code in a team?

Because you can smile by looking at other guy’s code:

Some debug "Cheezburger code" left by my co-worker

Posted in Fun, Short | Tagged , , | Leave a comment

jQuery selectors on IE 6 and 7 don’t always work as expected on repeating IDs

IE & jQuery. Do work well.

Today I’ve had a small freelance job on fixing a bug in a e-shop. To summarize, the task was like this:

IE 6 and 7 don’t behave as other browsers, including IE8, do. Fix this!

Despite the fact that I, as a WebDev, would recommend all users to kill IE versions less than 8 and adapt a fresh and new one, I know that all user are valuable. But this time I find that this “problem” of IE6 is more like a feature that I would prefer having in all other major browsers.

A quick code for you:

<table>
    <tr id="row">
        <td id="col">A</td>
        <td id="col">B</td>
        <td id="col">C</td>
    </tr>
</table>
<script type="text/javascript">
// jQuery is included somewhere up there. Tested with 1.4.2.
// What will this print?
document.write( jQuery('#col').length );
</script>

Whats bad on this code snipped? There are more than one ID of value “col” in the code. An ID attribute must identify UNIQUELY one element in one document. At least that’s in the bible I’m reading before going to bed.

Guess what? IE6 and 7 are returning “1″ as the selector’s length. All other browsers would return “3″.

I find this odd. And disrespectful to the standards. Don’t know if this is a feature of jQuery, or a feature of the browsers. But be warned: IE6 and 7 behave quite well on this topic.

How to fix this?

If you have lots of time – rewrite the code. The “col” IDs should originally have gone to the CLASS attribute, IMO.

If you want it fast, change the selector to something like:

jQuery( '$(tr#row td)' );
Posted in bugs | Tagged , , , , | Leave a comment

Interruptable file download

Have you ever been to a website that offers downloads of stuff? And while you are waiting for the download, there are lots of ads around? Sure you have. I have too.

The last day I was downloading stuff. An idea came to my head. Was there a site which required to stay and watch the ads while you are downloading? Didn’t see one. Is that technically possible? Sure. I wanted to show how. So I made a small web app for that.

You can see the or the full source.

How does this app work?

  1. The user visits the download page.
  2. He gets through the bushes of ads and clicks on “Download”.
  3. The javascript call makes a request to the server and gets the download URL.
    In the background, PHP script creates a “download is active” file with the
    current modification time.
  4. The download is made through a PHP script. The script checks if the “download
    is active” file has modification time of allowed age. If the file gets older
    than allowed, the download is canceled server-side.
  5. While on this page, after clicking “Download”, there is a invisible counter
    started which calls a “download still active” URL that updates the modification
    time of the “download is active” file. Thus, if the user doesn’t leave the page,
    the download is not canceled.

Do I recommend this or tactics of this like? No. Why?

  1. It is dirty.
  2. Other services exist that offer much better alternatives.
  3. Having the window open doesn’t mean any of the ads will be seen. Better use other tactics.
  4. Only few users will read the “YOU MUST LEAVE THE WINDOW OPEN” notice, files will get corrupted, etc.

All comments and thoughts welcome.

Posted in Code, Ideas | Tagged , , , | 5 Comments

WhoAmI

Hello, my dear code friends! I want to start my blog with introducing myself.

My name is Steponas Kazakevičius. I was born and am still living in the center of Europe – Lithuania, in its beautiful capital city Vilnius.

4 years ago I was invited to join a web development company. And I did. Since then, by walking over lots of code ranging from broken, ugly, irrational to great, inspiring and must-learn – yet such code was rare to see – I have been falling in love with programming. Oh come on, not literally “in love”!

That's (almost) me. Img found @ devtopics.com

What’s programming to me? The power to create, the freedom to choose a path that will eventually lead you to your destination. Mostly to years of debugging and support. A job that lets me buy perfume for my wife, gives me lots ideas and lets me meet great people. And not so great.

All sarcasm aside – programming is great. I started with PHP 4, plain-JavaScript. Currently I’m into PHP 5.3, JavaScript + jQuery + DOM, MySQL. Doing some digging in HTML5 and other stuff. Working in my third job so far. Doing freelance @ ItWorks!. Zend framework at hands. But CakePHP is my fav for now. Ehh, I’ll talk about this later.

Why this blog? After reading a great post with the thought that English is the language of programming, I finally got myself together, installed WordPress and voila – I’m currently in the middle of writing this post and I don’t know how it’s gonna end. I hope well.

I always wanted to write in English about programming. I have my personal blog in Lithuanian but it does not reach as much as this blog can and hopefully will. Why writing to some thousand Lithuanian programmers when I can join an army of million blogs and be the million first?

What will be here? Thoughts, code, examples and discussion. That is what I want my blog to be. I hope my posts will be interesting to middle-to-high experience level web devs. But of course novices can learn something too.

Hope read me soon!

Posted in Uncategorized | Tagged , , | Leave a comment

Hello world!

Hello!

This is my first blog post. So I won’t be writing anything more than I (and probably lots of others programmers too) have started their journey of DEV:

1
2
<?php
echo "Hello world!";

More coming shortly.

Posted in Uncategorized | Leave a comment