Something on Everything

IE8, is it really kicking?

March 20, 2009 · Leave a Comment

I’ve been playing with IE8 since Microsoft made it available on its website.

Yes, I still try Microsoft: it’s what I’ve been using for almost three months now at the big D, and it’s ruled by Steve Ballmer – and he kicks asses up there.

Ok, so, what is it, why am I taking my precious time to talk about this release?
Well, guys over Microsoft labs seem to have been pushing hard to make this version of IE at least user friendly – let’s not expect it’s developers friendly, never forget it still is IE – but, HEY, haven’t already tested it in this field.

Tiered with file system (?)

First downside we have. I want a web browser, not a file browser. Please do not include network files in the auto-completion, I haven’t even used the browser to access them!

Overall UI

Tabs have suffered a drastic size reduction, they are clean and well tailored. They don’t even remember those ugly giants we had on the previous version.
Actually, all UI components were reduced, they don’t have that 800×600 Win98 look anymore.

Still on tabs, there’s a cool feature that colors them by group – once you open a tab from within another one, they get colored with a new color, so that you can keep track on what contents are related. Hot.
Also, you can now undo closed tabs, just like on Firefox.

The address bar is entirely revamped.
Auto-suggestion is fast, but may slow you down if you have already got used to use this Firefox feature that allows you to use page titles for search - IE8 only use the URL itself.
Domain highlighter – just like Chrome – and improved handling of selection in the URL string, have made it really sexy. Also the capability to delete stored entries with just one click, right there, is really interesting.

Developers gift

Web Developer Toolbar have been updated, and it really have become useful.
Sure it’s not Firebug. But we have web profilers, CSS controller, JS console and a lot of new features… and guess what: they work, and work pretty well and fast!
A downside we have here is that it’s not integrated on browser’s window. It really looks like WebKit Web Developers Tools.

Speed

It’s faster and lighter. You might even get surprised. They were able to cut down bootstrapping time, and page loadings – everything is running smoother. Google Chrome still’s faster, but they did a great job on optimizations.

Accelerators

The hot feature. Talking about it quick and dirty is easy: it’s a Ubiquity, but with the mouse.
Access web services within pages’ content to translate, google, mail and such… Cool.

So, maybe it’s just  a quick overview, and we might have tons of new features to discover.
Anyway, IE8 is worth it. He might not be kicking @sses but he definitely is replacing IE7 for good.

Kudos for IE devs. Yes, I said it.

See you.

→ Leave a CommentCategories: My Opinion
Tagged: , , ,

Update to the new version!

March 6, 2009 · 8 Comments

Hey folks, just a quick walk back… I want to warn you that version 1.9 of this software is no longer supported and has been tagged as deprecated.

Version 2.0 was released today, full of bugs and inconsistency, but was considered pretty stable. Congrats to my mum that did this great job while coding the codebase, and to Nina by having constantly upgraded and updated the Moral, Happines and WillPower modules with uncountable patches using the “Kiss and Hugs” approach.

Also I would like to thank everyone who contributed for this new release, I’m very proud of having you guys around.

By the way, although the source code is currently being held by the big D, it shall go back to Foss world sooner.

So, feel free to congrat me for this new release, and be in peace.
- I won’t promise anything this time… as you know, I’m not very trusty when it comes to personal projects.

- it means I’m 20 years old now. Happy Birthday, me.

→ 8 CommentsCategories: Uncategorized
Tagged:

2008 +1 Stuffs

January 9, 2009 · Leave a Comment

2008 was the best thing that could ever happen to me. Here are listed all those things that earned a “+1″ from me on last year:

- Creating a strong relation between me and my older cousins and sisters

- Discovering the joys of being a a single father and a single man with no chains

- Leaving the advertising marketing to develop corporative softwares

- Moving from Prototype.js to jQuery, and then rediscovering the power of plain JS

- Start studying about leadership, management and entrepreneurship

- Start blogging and therefore find out I can contribute with other people work

- Rediscovering my capabilities as a designer

- Focusing on a specific knowledge time enough to be a professional, but not enough to get the wrong idea that I’ve mastered it

- Receiving up to 4 personal contacts for job proposals per week for two months, and feeling good about that

- Learning that no job worth more than my life and values

- Learning that no money worth more than knowledge and experience. Great monthly revenues are nothing if you feel like haven’t earned nothing but money

- Receiving an e-mail with a big “Welcome to Dell” at the top

- Entering on forced vacation because of the last item

- Helping Santa to get a pool for Nina

- Running the last podcast of the year on TheShow with Nate Abele, announcing CakePHP 1.2

- Traveling to the beach on 31/12, and having a good night.

And for you people? What are those special things and moments that made 2008 a great year?

ps.: I have only one more post about “Real Life” stuffs – the “My Seven Things” meme, cuz I liked it… and then I’ll start to show some 2008 work that I left undone for 2009…

→ Leave a CommentCategories: Real Life

Will you continue to make the same mistakes in 2009?

January 7, 2009 · 2 Comments

A new year is rising…. ah, actually it is already here, and I’m late! Anyway, when a year is ending and a new one is starting, it’s time to think about what went wrong and what was successful, what should never happen again, and what should be taken as lesson. So lets talk about those things that should be taken in consideration for this new year. The things you might have being doing but definitely shouldn’t: in this 2009 will you continue to the same old mistakes? Like…

start coding without planning

Sharpening the saw time enough to clarify the steps needed to accomplish a task, sowing your thoughts deep enough to define details and caring about design principles are certainly required steps for every project startup. There are lots of ways to setup and to accomplish a task, and ten times more for a project. Defining a start point, a north, guide lines, and the expected end makes  it easier to know how far you should go, and how long it shall take.

So, before sitting in your chair and launching your dev set, take your time, open the white board, take two color pens, and draw about “What is it that I’m going to do?”, “How, when and where is it going to be useful?”, and finally, “How can I do it?”.

If programming was a religion, planning would be praying.

using no SCM

Version management is free and easy. Now with git, it got a lot easier to have your own setup to manage the source code of your projects, there’s no need for remote hosts, repos can be created everywhere – even in your pen-drive, easy branching and ease work flow, and, if you ever feel the need, github.com private accounts worth every cent, providing more than just a remote host with all it’s functionalities and reports.

But if you still don’t feel like using git, you can create an account on code.google.com and store your projects there, playing a little with admin settings and making it a “private” project.

Ok, but what is it all about? Managing source code allows you to revert changes without messing with your project, tag releases for easy access of production ready versions, make changes to the project without hurting what’s already there, work with other developers without collision of code changes.

If programming was a religion, scm would be the confessional, commit would be the confession and revert would be the forgiveness.

reinventing the wheel

Creating your own solutions for already solved problems is tempting: your way, your rules. When solving problems on your own, there’s almost no need for reading and learning, and getting used to someone else’s ideas, implementations and styles.

But let the truth be told, everything is already done when talking about programming – well it may not be open source, but it was done.

In the long run, using supported, tested and maintained code is always the better choice. The time spent reading documentation, api, examples, digging someone else’s work and investigating adds to you in experience, knowledge and ideas.

When common problems end up solved with almost no expense on time, you are free to think about the project’s domain problem, that peculiar part that makes the whole project value/price.

If programming was a religion, reinventing the wheel would be a sacrilege.

defining no code standards

Code standards are the guidelines that rule implementation’s styles. Having fixed code standards will help any project to remain consistent all over it’s implementation, with defined ways to write, name and format snippets, classify and solve problems, create and iterate through arrays, and so on.

Standards are the key for integration and maintenance of a project when it’s run by a team, but it’s also a time saver on small and personal projects, assuring you won’t need to bash your head every time you want to implement a new feature or read the code two months after having written it.

If programming was a religion, Code Standards would be the “Ten Commandments”.

commenting the source code

There are no worse code than the unreadable one. It can be tricky, magical, voodoo based, or anything else… but it must be readable and maintainable by anyone whose skill level is the same as the one that coded it. The code should talk by itself – with the api, variable names, iteration purposes and architectural principles.

Commented code is insulting for both the coder , and the reader. The first is showing how unreadable it’s code is – and turning it even more unreadable, and how illogical its structures might be. The second gets annoying lines in the middle of the code, making it really hard and lengthy to read, and is somewhat humiliated by obvious statements.

When feeling the need to guide the code reader through your work, think that, just as the one who coded something should care about its code readability, the one who is reading the code should care about its own knowledge.

If programming was a religion, comments in the source code would be heresy.

leaving code with no documentation

Documentation is the key to unlock any issue in a project, be it a personal project that no one else will ever read, be it a small project with only one person assigned, be it a large project with many contributors.

During the development, documentation will help tracking what is done, show how it was done, and will be a reminder on how to use implemented features. After the development process, documentation will help to track bugs, maintainability of the code and ease the investigation when reopening the project.

Documentation must be used as the code manual, it must be as explicitly as possible, and regard every aspect of the documented process.

If programming was a religion, documentation would be the Bible.

asking and not trying to learn

Well, probably the most dangerous and committed mistake I’ll forever and ever see: people don’t like to fish and cook, they like to eat sushi. I won’t talk too much about this, because I know people won’t change.

Think about the time you spend asking for solutions and you’ll see that there’s something really wrong down there. The current workflow used by new developers to solve problems is scary, they tend to never get conclusions by themselves, never getting their hands dirty by digging on the source of a problem and start asking for help at the first error message.

Every problem solved by an unlearned solution, leads to another n problems that you will never be able to solve.

When learning you can be assured you’ll only have headaches once, and then, every time you get in touch with the problem, you’ll know how to solve it. Learning processes are usually seen as painful and boring, but they can be really fun if used properly: make a dynamic process, where you’ll need to read, write and act, always having in mind short steps with visible improvements, and always put the learned lessons in practice as soon as possible.

When thinking about learning, think wide and abstract, think about concepts as much as possible. When you know a concept, you master the implementation, in any language, tool and rule set. The more abstract is the lesson, the more concrete is the knowledge.

When facing a problem, dig it, look for its reasons and sources, that’s for what we developers are paid for.

If programming was a religion, the askers would be atheists. And all the radicals would burn them for this.

not following this blog

Well, 2009 is a promising year preceded by a successful period of personal and professional achievements. I’ve gained a bunch of experience in everything I’ve done, I pushed myself to the edge of productivity and learning, I’ve never felt better about my thoughts, feelings and wishes. Everything is on it’s way.

One remarkable thing about 2008, that will leave a rich legacy for this new year, is this blog and what I’ve learned with it. Things shown here allow me to say that I’ve earned an interesting amount of recognition, even from people I follow and have as “guru”. It’s good and fun for a narcissist like me – after all I wasn’t that wrong about my value.

Said that, you can bet I’ll be a more active blogger, with more respect for my personal projects – the ones that I should be launching by now, and far more dedicated to knowledge and concepts on programming and leading. What are you waiting for subscribe?

If programming was a religion, I would be a priest.

… as it isn’t, I’m an atheist. Thanks and a happy, wealthy and productive 2009 for everyone.

ps.: I’ll leave a note as soon as I move to the new domain.

→ 2 CommentsCategories: My Opinion · Programming · Real Life

CakePHP 1.2 RC4 – The most important thing

December 21, 2008 · 5 Comments

CakePHP 1.2 RC4 is out, we all know.
Chris, Joel, Mark, and, of course, Daniel – who also did an overview about what changed since RC3, posted about it, but everyone missed the most important change on the new release: the bombs!

Cake Bombs

Cake Bombs

oh yeah baby, now Cake is bombing buggy code! Watch out and think twice before coding, or… BOOOM!

→ 5 CommentsCategories: Uncategorized

How is it going so far?

December 11, 2008 · Leave a Comment

Almost a month now since I started publishing some code and, well, everything is going just fine.
I’m deep involved on my company’s projects and having little to no time at all to contribute with some enhancements I planned for projects I like to support.
So, let’s review how things are going and talk about upcoming plans.

Some refactoring and fixing were made on LazyLoaderBehavior, thanks to some troubles Nachopitt pointed out that he was having. Also thanks to ‘lorenzo’, that suggested support for additional query parameters – allowing more control over n:1 and n:n relations

$this->Post->getCommenters('active', array('email LIKE' => '%gmail%'))

Also, support for a more readable usage of the ‘load instance’ feature on 1:1 relations was implemented

$this->Post->getAuthor('instance')

backwards compatibility was maintained and all tests still pass.
LazyLoader is also about to receive one more – and probably last – feature, anytime soon it’s going to be pushed, so keep tunned.

LinkableBehavior had a “major” fix for HABTM associations, so make sure you grab the new version. I’m still trying to put a test case for LinkableBehavior, in the mean time just know that it is tested, but with specific models from the app where it borne, so have no fear.
I’m writing about HABTM pagination with Linkable and how it kicks ContainableBehavior *ss, along with an article about paginating different find types, It shall be done till the end of the year – erhm… gotta run to achieve it!

Mark Story has just pushed FireCake, the CakePHP’s firebug interface, to DebugKit. Haven’t tested it yet, but I’m sure he did a great job. In the mean time… I’m working on IE6 compliances – because I need debug on IError – and lacking of ideas on panels control over the rendering process, it’s needed to resolve the issue where when sqlLog panel is disabled you won’t have the bottom table with the log, which, sometimes, is better.

About all other projects, I’m now focused on the blog release. Yes, I said I wouldn’t, but the high traffic I’m having here needs to be exploited. So as soon as I solve my problems with domain registration I’ll start to use a SCRUM like approach to release it – and we might all see the kid growing.

→ Leave a CommentCategories: CakePhp · Real Life

Handling Multiple Environments on (Cake)PHP

December 5, 2008 · 9 Comments

This week Chris Hartjes published his approach on how to handle different environments on a PHP application.
Although a nice approach, it demands different versions of a file in all environments, what,
correct me if I’m wrong, may lead to serious headaches with version control when server has to be tweaked.
Then Neil Crookes published his own, straight forward, but not very extensible.
Now it’s my turn. Got this shiny piece of code from an old cd-rw that I used to store some ideas – well I
didn’t born knowing about SCM – and then refactored it to look prettier.

So, the code is the following:

/**
 * Singleton class to handle environment specific configurations.
 *
 * Auto-detect environment based on specific configured params and
 * allow per environment configuration and environment emulation.
 *
 * Environment. Smart Environment Handling.
 * Copyright 2008 Rafael Bandeira - rafaelbandeira3
 *
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 */
class Environment {

	public $environments = array();

	protected $_configMap = array(
		'security' => 'Security.level'
	);

	protected $_paramMap = array(
		'server' => 'SERVER_NAME'
	);

	static function &getInstance() {
		static $instance = array();
		if (!isset($instance[0])) {
			$Environment = 'Environment';
			if (config('app_environment')) {
				$Environment = 'App' . $Environment;
			}
			$instance[0] = new $Environment();
			Configure::write('Environment.initialized', true);
		}
		return $instance[0];
	}

	static function configure($name, $params, $config = null) {
		$_this = Environment::getInstance();
		$_this->environments[$name] = compact('name', 'params', 'config');
	}

	static function start($environment = null) {
		$_this =& Environment::getInstance();
		$_this->setup($environment);
	}

	static function is($environment) {
		$_this =& Environment::getInstance();
		return ($_this->name === $environment);
	}

	public function __construct() {
		if (Configure::read('Environment.initialized')) {
			throw new Exception('Environment can only be initialized once');
			return false;
		}
	}

	public function setup($environment = null) {
		if (empty($environment)) {
			foreach ($this->environments as $environment => $config) {
				if ($this->_match($config['params'])) {
					break;
				}
			}
		}
		$config = array_merge(
			$this->environments[$environment]['config'],
			array('Environment.name' => $environment)
		);
		foreach ($config as $param => $value) {
			if (isset($this->_configMap[$param])) {
				$param = $this->_configMap[$param];
			}
			Configure::write($param, $value);
		}
	}

	protected function _match($params) {
		if ($params === true) {
			return true;
		}
		foreach ($params as $param => $value) {
			if (isset($this->_paramMap[$param])) {
				$param = $this->_paramMap[$param];
			}
			if (function_exists($param)) {
				$match = call_user_func($param, $value);
			} else {
				$match = (env($param) === $value);
			}
			if (!$match) {
				return false;
			}
		}
		return true;
	}
}

The cool is that, placing it inside APP/config folder,
it can be loaded like

config('environment');

Wow, and even a dog would know what it does.

The usage is simple, as you might guess, to configure enviroments

Environment::configure(
	'my_environment',
	array('server' => 'sandbox.localhost'),
	array('debug' => 3)
);
Environment::configure(
	'mama\'s pc',
	array('DOCUMENT_ROOT' => 'C:\\Workspace\\my_proj\\webroot'),
	array('debug' => 1, 'Email.server' => false)
);

And then to start

Environment::start();

start it anywhere, when you want.

You can also emulate an environment configuration

Environment::start('staging');

useful on tests

Environment::start('linux_development');
$this->assertFalse($obj->doIt(), 'works fine on dev');

Environment::start('linux_staging');
$this->assertFalse($obj->doIt(), 'breaks with some staging configs');

and

$this->skipIf(Environment::is('cli'));
$this->assertEqual('mamma', $variable);

You can easily configure all your environments

Environment::configure(
	'cli'
	,array('defined' => 'CAKEPHP_SHELL')
	,array('debug' => 1)
);
Enviroment::configure(
	'development'
	,array('server' => 'localhost')
	,array('debug' => 2, 'security' => 'low')
);
Environment::configure(
	'staging'
	,array('server' => 'staging.localhost')
	,array('debug' => 2, 'security' => 'medium')
);
Environment::configure(
	'production'
	,true
	,array('debug' => 1, 'security' => 'high')
);

notice that the “true” param on ‘production’ says that it will match always, so,
if it’s not ‘dev’, nor ’staging’, nor ‘cli’, Environment will, by default, assume it’s ‘production’,
but you could do the same with the ‘dev’ set.

You can create ‘app_environment.php’ on APP/config containing the AppEnvironment class,
that should extend Environment, and then specify different config key aliases and
match params. So, to mix Hartjes’ approach, you can create the AppEnvironment

class AppEnvironment extends Environment {
	protected $_paramMap = array('env' => 'APP_ENV');
}

set APP_ENV in the .htaccess

SetEnv APP_ENV "littlehart.net"

and configure needed enviroments

Environment::configure(
	'production'
	,array('env' => 'littlehart')
	,array('debug' => 1, 'Session.cookie' => 'attthekeyboard')
);
Environment::configure(
	'development'
	,array('env' => 'sandbox')
	,array('debug' => 1, 'Session.timeout' => '1500')
);

To get rid of the ‘Session.cookie’, you can map ‘cookie’ to it, doing

class AppEnvironment extends Environment {
	protected $_paramMap = array('env' => 'APP_ENV');
	protected $_configMap = array('cookie' => 'Session.cookie');
}

and then configuring

Environment::configure(
	'production'
	,array('env' => 'littlehart')
	,array('debug' => 1, 'cookie' => 'attthekeyboard')
);
Environment::configure(
	'development'
	,array('env' => 'sandbox')
	,array('debug' => 1, 'Session.timeout' => '1500')
);

Although the implementation is CakePHP specific, it’s really easy to adapt – actually replace two or three lines
and you are done… ok, here is the tip: get rid of all Configure::write() and Configure::read(), config() and env()…
ok… maybe it’s 4 or 5 lines, but you got the picture.

What do you think? I think it’s just fine!

→ 9 CommentsCategories: CakePhp · My Opinion · Programming
Tagged: , , , , ,

Pretty, Painless and Productive debug with DebugKit

November 23, 2008 · 2 Comments

CakePHP DebugKit has been released some time ago now, you know.

Since the release some things have changed: it’s no longer dependent of it’s own view – actually it is, but DebugView will now be hackilly automagically declared as a subclass of the view class being used in the request, it is much more extensible and is planned to be useful on non-html outputs, and it’s no longer dependent of javascripts libraries. Next major change will be the integration with firebug to allow ajax debugging and maybe some other goodies. Aren’t you just excited about that?

For TDD lovers like me it isn’t much impactant at a glance, but take a closer look, after all, even enjoying writing test cases – peehh… liar. No one likes to write test cases, ok? Test Engineers maybe, but it’s just so boring – from time to time you’ll face a simple case or project, or just one with an extremely short deadline, and find yourself debugging all the inside outs of the app. And that happened to me in the past few weeks.

So, I saw myself cutting down debug time and pain with the interface designed by Mark Story , and decided to share a word about how to take some more out of it.

First things first

Of course I won’t talk about the “installation” process. If you want to get started with the kit, check clone it out from github, refer to the wiki, ‘install’ and get the feeling of how it works. Of course it’s easy.

Customized panels

Although the kit comes packed with almost everything you need to debug the heart of your buggy app – ;-) – you may want to cover, control and debug other aspects and processes in your project.
To create a customized panel at least two things are needed: a subclass of DebugPanel placed on vendors folder and named as <Name>Panel, the file has to have the same name but underscored, and an element named just like the panel, but with the ‘.ctp’ extension, that will be the content of the tab on the panel.

Did someone shout: “Hello World example!”? I hope not (don’t you dare asking this…). So…

DebugPanel class interface gives you 4 gifts:
- you can specify a plugin to which your panel belongs to, so that the element can be searched in it’s right place;


var $plugin = 'Shooter';

- you can specify a custom name for the element to be rendered;


var $elementName = 'triggers/analysis';

- you can access the Controller in it’s startup with the ’startup’ callback;


function startup(&$Controller) {
	$this->params['modelClass'] = $Controller->modelClass;
}

- and you can access the Controller before the rendering process, and return data to be passed to the panel’s element with the ‘beforeRender’ callback.


function beforeRender($&Controller) {
	return $this->params;
}

Playing with the element is easy. The data returned by the panel on ‘beforeRender’ callback will be available on $content var, and to make all those pretty lists that are pimped by the javascript controller you can use the HtmlToolbarHelper::makeNeatArray() method:


<h2>Debug the bug</h2>
<?php echo $htmlToolbar->makeNeatArray($content) ?>

…a piece of cake isn’t it? Now let’s debug the vars being passed to the view:

in the APP/vendors folder, create a file and name it ‘view_vars_panel.php’, and write:


class ViewVarsPanel extends DebugPanel {
	function beforeRender(&$Controller) {
		return $Controller->viewVars;
	}
}

now, in the APP/views/elements folder, create a file and name it ‘view_vars_panel.ctp’, and write:


<h2>Vars set by the Controller</h2>
<?php echo $htmlToolbar->makeNeatArray($content) ?>

and finally, in the AppController, or wherever you have set the DebugKit.ToolbarComponent, change the declaration to:


var $components = array(
	'DebugKit.Toolbar' => array('panels' => array('viewVars'))
	//sure, you can add the rest of your components here
);

Ctrl + Tab, choose your browser, F5
… wait a little… and… here it is:
Your brand new customized debug panel!
Oh come on! that was too easy and quick!

Now, wait, where are all the other panels? “oh you little bastard…”… when specifying panels to be loaded, make sure you specify all panels you want to be used:


var $components = array(
	'DebugKit.Toolbar' => array(
		'panels' => array('viewVars', 'session', 'request', 'sqlLog', 'timer', 'log', 'memory')
	)
	//sure, you can still add the rest of your components here
);

Ufff… and there are them again… – that was close…

Benchmarking

Well, it’s not all about debugging sire. DebugKit is packed with it’s own debugger class which holds some functionalities that are planned to integrate the core in the near future, and it happens to be that some of the features are timer handlers for benchmarking purposes. Cool!

When benchmarking you won’t need a custom panel, although you could write one to fit your needs, all timers are shown on “Timer” panel.
Timers are initialized and finalized by static methods of DebugKitDebugger class, and they can have an ID and a message:


DebugKitDebugger::startTimer('timer_id', 'My timer message, describing what is it');
[... your complex code goes here ..]
DebugKitDebugger::stopTimer('timer_id');

Now a merchand a use case of the [7640] changes a real world example:


class Schedule extends AppModel {
	function _findAgenda($state, $query, $results = array()) {
                if ($state === 'before') {
                        $default = array(
				// Uses LinkableBehavior to bash out all the data I need!
                                'link' => array('Employee' => 'Person', 'Task' => array('Project' => 'Company'))
                                ,'order' => array('Schedule.check_in' => 'DESC')
                                ,'fields' => array(
                                        'Schedule.employee_id', 'Schedule.task_id'
                                        ,'Employee.position', 'Person.name'
                                        ,'Task.title', 'Task.project_id', 'Project.title'
                                        ,'Project.company_id', 'Company.trade_name'
                                )
                        );
                        $mandatory = array(
                                'fields' => array($this->getVirtualField('date'), $this->getVirtualField('day_part'))
                                ,'group' => null
                        );
                        $query = $this->_mergeQueryParams(compact('default', 'query', 'mandatory'));
                        return $query;
                } elseif (empty($results)) {
                        return null;
                }
		
		DebugKitDebugger::startTimer(
			'agenda_structure_generation',
			'handling the data to generate the agenda structure'
		);
		
                foreach($results as $key => $record) {
                        unset($results[$key]);
                        $keyName = $record['Schedule']['date'];
                        $groupKey = $record['Schedule']['day_part'];
                        if (!isset($results[$keyName])) {
                                $results[$keyName] = array();
                        }
                        if (!isset($results[$keyName][$groupKey])) {
                                $results[$keyName][$groupKey] = array();
                        }
                        $results[$keyName][$groupKey][] = $record;
        	}
		
		DebugKitDebugger::stopTimer('agenda_structure_generation');
		
                return $results;
	}
}

And – I wish I could put a picture here showing the result… – erhm? can I? really!? … don’t tell them, please – you’ll see the results by opening the “Timer” panel on the toolbar.

Closing

Now along with all the mentioned super cool features, the most impressive and useful functionality is the “disable toolbar” feature: click on the cake icon and it’s done! Now, click it again and it’s back! It’s just too much magic for a single tool, isn’t it??

Oh ok, I’m out of here.
Hope you learned something.
Is it too painfull to give some feedback?
Make sure you catch on my typos, there might be tons of it, it’s past 4am here.
And yes, I wrote the plain js debug kit javascript controller… I tried man, but I can’t help it, I’m just too narcisist! – Will talk about it in an upcoming post… no, not about my narcisism, doh… about contributing and giving a hand to open source projects that make your monthly revenue bigger and easier.

→ 2 CommentsCategories: CakePhp
Tagged: , , , , , ,

Lazy Loader Behavior. What you need, When you need, The way you want.

November 21, 2008 · 22 Comments

More on my github’s brute code.

Lazy Load is a simple design pattern that basically consists in making related data to be easily fetched by the domain model.

The implementation of the pattern happened through a behavior that will allow you to get related data with simple, readable and beauty method calls:

$this->User->getProfile();

and the User’s Profile data you shall have.

$this->User->getComments();

and the User’s Comments list will be returned.
“But I want the whole data man” – i hear you shout:

$this->User->getComments('all');

“Nope, I want it to use my custom method as you and Daniel shown” – ok:

$this->User->getEvents('expecteds');

All relationships are supported:

$this->Project->getMilestones();
$this->Project->getOwner();
$this->Child->getFriends();
$this->Post->getTags();
$this->Tag->get_posts(); // if you like this style, enjoy then

But be semantic, it can’t getTask if it actually hasMany Task:

$this->Project->getTask(); // Exception thrown here
$this->Project->getTasks(); // yes sir, here they are.

Default behavior is to return a find(’first’) for belongsTo and hasOne associations, and a find(’list’) for hasMany and hasAndBelongsToMany, but you can override it, as shown above, and here again:

$this->Node->getComments(); // find('list') returned
$this->Node->getComments('threaded'); // find('threaded') will be returned
$this->Comment->getAuthor(); // find('first')

And you can even get the related model instance for belongsTo and hasOne associations, just pass a boolean true as param:

// get a Baker instance already setted with the related model data
$Baker =& $this->Cake->getBaker(true);
$cakes = $Baker->getCakes();

About the beauty mentioned, we can use controller’s actions as examples:

class ProjectsController extends AppController {
    function view($id = null) {
        if ($this->Project->exists()) {
            $data = $this->Project->read();
            $assignedUsers = $this->Project->getAssignedUsers();
            $hotTickets = $this->Project->getTasks('hots');
            $this->set(compact('data', 'assignedUsers', 'hotTickets'));
        }
    }
}

Pretty RAD prone in my opinion.
No configuration needed, it’s just plug and play.
Be sure to get the tests too, so you can assure it works well.
Thanks and “good night ladies, good night…”

→ 22 CommentsCategories: CakePhp · Code Release · Programming
Tagged: , , , ,

Linkable Behavior. Taking it easy in your DB

November 16, 2008 · 25 Comments

LinkableBehavior is the implementation to solve ContainableBehavior’s inextensibility, complexity, “featurity” and – mainly – it’s db usage.
Working on db normalization on one of my ongoing projects, I found myself killing app’s performance when trying to push deep related data from tables. Some simple functionality had a processing time addition of more than 5 seconds while Containable was doing it’s dirty job assembling my wanted dataset with 300+ db hits. 300+ for datasets that could be easily fetched with few joins in a single SQL query, using not more than some miliseconds on a production-all-filled-with-data database.

The solution implemented to fetch deep relation data, with no performance hit on app side and no complex model binding hack, is to work right into the query data passed to Model::find, ordering sql JOINs generation using the ‘joins’ for the query data. That’s why the class will only act on beforeFind callback looking for the ‘link’ param to map relations and add needed joins. Usage is simple:


$Schedule->find('all', array(
    'link' => array('Task' => array('Project' => 'Company')),
    'fields' => array('Schedule.check_in', 'Task.title', 'Project.title', 'Company.cod'),
    'conditions' => array('Company.name' => '3Solutions')
));

you can use ‘field’ param inside links specification


$Schedule->find('all', array(
    'link' => array('Task' => array(
        'fields' => array('title', 'progress', 'priority', 'severity'),
        'Project' => array(
            'fields' => array('title', 'created', 'status'),
            'Company' => array(
                'fields' => array('trade_name', 'cod')
            )
        )
    ),
    'fields' => array('Schedule.check_in'),
    'conditions' => array('Company.name' => '3Solutions')
));

and you can also define joins specifications


$db =& $this->getDataSource();
$isAssigned = $db->expression(sprintf(
    '(SUM(IF(project_id = %s, 1, 0)) > 1) as %s',
    $db->value($project_id),
    $db->name('is_assigned')
));
$this->find('assignments', array(
    'link' => array('User' => array('Person', 'type' => 'RIGHT')),
    'fields' => array($isAssigned, 'User.id', 'Person.name'),
    'conditions' => array($this->escapeField('project_id') => 1),
    'group' => $this->escapeField('user_id')
));

Notice that relation mapping is implemented in Containable’s fashion, with enclosing arrays making a kind of path, so if you want to fetch or query data about the Company related to a scheduled task, you have to specify where this relation comes from, by enclosing relations by reference, in this particular example, the ‘link’ param could be supplied like this:


$Schedule->find('all', array(
    'link' => array('Task' => array('Project' => 'Company'))
));

Every relation type is supported, but notice that hasMany and hasAndBelongsToMany, that can potentially associate more than one record to the main – right most – table record, won’t reproduce ContainableBehavior’s behavior, fetching all related data and binding it to the resultset following Cake’s data format. When fetching data use the right most model to perform the find operation:


$Tag->find('all', array(
    'link' => 'Post',
    'conditions' => array('Post.title LIKE' => 'the pipettes rock')
));

Notice that returned data will be just like directly related – recursive 0 – data. Only one record per model, all models in the same dimension:


[0] => Array(
    [Schedule] => [...],
    [Task] => [...],
    [Project] => [...],
    [Company] => [...]
),
[1] => Array(
    [Schedule] => [...],
    [Task] => [...],
    [Project] => [...],
    [Company] => [...]
)

Further more, notice that only models with fields being fetched will appear on the resultset, which means that even if you link a model it won’t necessarily appear on the resultset.

Try yourself. Change a ‘contain’ key for ‘link’ and make friends with your db again.

PS. Don’t you forget to catch on my typos!!!

→ 25 CommentsCategories: CakePhp · Code Release
Tagged: , , , , ,