Category Archives: CakePHP

CakePHP headaches at a glance

@jose_zap has replied to me regarding a tweet of mine comparing CodeIgniter and CakePHP and the different aspects of both technologies.

Since Twitter itself is way restricted into the 140 chars (which I like most usually - less offtopic and media) I will better blog this off here as a couple of things I don't like in Cake.

First of all, I've been doing Cake for a year and a half and have several projects up and running with different web services, sync mechanisms and so on. It's usually one of my preferred platforms (right after WP and Croogo which is actually Cake based) but it doesn't mean that I adore all of the features in it.

Auto recursive models 

By default linking the models in Cake sets a recursive level of 1 - so you get a direct access to level 1 of all corelated models. it is usually nice as you don't have to join or bind models every few requests. The bad part however is that every serious project (and even non-serious ones with more than 10 tables!) gets bloated with so much insignificant data not being used anywhere in the site. When we have a product which has categories and part of an order, which has a user and so on there are lots of queries back there and tons of useless data which leads to reduced performance and page load time. 

Yet again - very useful, especially for non-technicians who have hard time joining and so, but I get different requests from oDesk or local clients with old Cake sites that need optimization and fine tuning cause the site used to work at the beginning but the previous developer uses the standard recursive=1 settings and therefore the more the database records, the more hardcore the end results.

ACL

ACL is... well, it sucks big time in my opinion. It has a wrong concepts at the beginning, it is also hard to implement (lots of years technical background and lots of hours, if not days, trying to setup something that needs to be in the core). @jose_zap - I like Croogo's way of setting the jquery matrix of roles and controller actions and predefining the actions for each role. The UI plugin for the standard ACL is too complex in a usability manner and doesn't do the work.

Another thing is the role based auth. Cake does a pretty good job restricting different roles, but the autogeneration of MVC implies that no user-based authentication would be done or so. Another few projects of mine used to fix actions accessible via URL (no controller backend checks) and protecting every single add/edit and listing as index/view from unauthorized data listing. Or in other words - user number 2 is usually able to change the URL and see the listings of user number 3 or click the edit/5 link and edit the records of another user. It is not hard to implement it manually, but it takes time and having the logic predefined and working and generating tens of MVCs from tables opens lots of vulnerabilities out there.

i18n

What I don't like here is basically using one table for all translations by default. Once I tried setting different tables for i18n for the different DB tables but it was kinda tough for me to set up the models. Also the multilingual content with the localized data (so to speak i18n with the l10n together) had to be implemented by some third party tutorials with lots of app_controller magic in between.

---------

I had been able to fix all of the concerns above back then. It just happened for them not to be straight forward or workarounds are painful which leads to discomfort while coding or revamping an application.

These are my top concerns for Cake so far. Pretty sure I've had many more back there, but now as I do explore a framework, I usually look for several things first:

  • multilingual support
  • user management
  • security
  • design adaptiveness and plugins capabilities

I think I have some hard time with AJAX as well, but can't recall the specific projects with it. 

del.icio.us Digg DZone Facebook Google Google Reader Magnolia reddit SlashDot Technorati ReadMe.ru Dobavi.com Dao.bg Lubimi.com Ping.bg Pipe.bg Svejo.net Web-bg.com

Some hate over Cake’s i18n

I'm really fond of CakePHP's principles, but I'm too tired of its i18n features. For some reason internationalization, although one of the really major requirements for every framework or CMS, is implemented poorly in most of the systems I've worked with. Django had few disadvantages (but few strong points as well) with its django-multilingual, and here it comes Cake with its toolkit for multilingual applications.

Comparing with few Java frameworks + CodeIgniter, I'm pretty aware of using locale-based apps with few languages for dynamic content. It's ugly as hell most of the times.

The beauty of Cake is mostly its 'convention over configuration' and dynamic admin panel generation. Admin panel is pretty neat, although there is no CMS-alike functionality and one should translate/adapt the admin for a project every single time. This is a problem that savant is taking care of, creating a multi-functional and reusable administrative panel. However, nobody has ever thought about creating something advanced like in Django's admin - data filters, field hiding, form populating module etc. Everything is hardcoded (actually spitted from the code generator, which is fine, automagic should be based on something and code must be there at some point) but not flexible at all except if you don't rewrite your admin generator.

The other thing is the multilingual content.

Designing i18n stuff in CakePHP is done by Translate behavior. You define your languages in the core file (or bootstrap in older versions) and you use it for localization. Also, your models actAs Translate behavior and you need to define the fields to be translated.

What is missing here is that because of the database normalization, these fields in question are not in the model table, but in the translation one. For that matter you cannot create a multilingual views for add/edit/view/index, because you miss some of the important fields (usually such as name/content that need to be translated in other languages as well). Also, relations in the previous abstraction level with translate tables are done transparently and using find() with translated fields is pretty hardcore. 

Croogo is a pretty neat CMS based on Cake. Translation there is modified by Fahad and he had done few changes in the main mechanism. Also, in order to add some translation, you do the following:

  • enter the base material and submit
  • view the material
  • click on a 'translate' button
  • select a language to translate in
  • fill data for the language in question

This one ain't bad, but it requires 5 steps for adding one translation. What if we have 5 languages?

Django's multilingual module is better in my opinion. It iterates over the languages and it outputs all translatable fields for every language in one page. When you add content, you could insert the whole data in one window or skip the unnecessary details at first. That's a better one. However, Django has a different approach (the one that jose is taking into consideration - actually creating database over the models and not MVC over a database). This way connection between fields for translation could be predefined in a smarter way. 

Why should all of that be so hard? Cake needs to be rapid and DRY and KISS, but admin needs to be changed every time, translation is tough to configure, administration is not straight-forward with its acl (and tens of auth modules). Croogo does a good job with putting all of that in one package, but it's too heavy sometimes (Cake is not the fastest framework after all). I really need there is a place left for a good i18n module, some killing-auth lib and a better convention definition for even more rapid dev.

del.icio.us Digg DZone Facebook Google Google Reader Magnolia reddit SlashDot Technorati ReadMe.ru Dobavi.com Dao.bg Lubimi.com Ping.bg Pipe.bg Svejo.net Web-bg.com

First week with Croogo

 

It's been my first week using Croogo - a CMS platform based on CakePHP and created by the Bangladesh developer Fahad Heylaal. Recently I've been looking for a next level platform in order to decrease development time and reduce wasting time for writing standard things from scratch such as menus, user controls (Auth+ACL), multilingual options etc. What Croogo does is delivering all this in a way upper lever. 

Croogo itself works out some general concepts in a way that we know from other popular systems. Overall look & feel in admin panel seems like the one that we've seen in WordPress. The node-based content (with ability to create new types from the admin) is a well known practice in Drupal - CCK. The core is, of course, CakePHP. I'm quite sure I could find more similar characteristics but the point is that the system is stable enough and flexible as well for other people to develop beyond and contribute as well.

I'll share some notes and issues from my first steps. Wiki is the first place to stop by. 

Theming - themes could easily apply to a Croogo website because there are no special functions needed here. Of course you could (and probably should) use helpers in views to build a better and well structured website. Adding blocks/menus via helpers is also 'a must'. The point is that you could easily take a free html template (or a sliced PSD design) and adapt it in Croogo in no time. 

Themes are installed in app/views/themed - theme name, layout, css/img etc and yml file for configuration.

i18n - multilingual websites are what's worth to me. I had to release a website in 2 languages, 4 types of users, contact (registration) form, dynamic menu. Everything is already here if you know how to use it. I still do translate the Bulgarian version of Croogo (admin panel, static messages etc). The Translate plugin allows you to add different languages and translate every node/menu/link or a custom type of yours. That frees a room for your powerful multilingual website. Just enable the translate plugin and you'll see the correct button. Note: please use version 1.3.2 and above because of crucial bugs in 1.3.1 translations.

User management - Auth + ACL. Each controller+action has a granular permission to access from every role you have specified. Fair enough.

Custom stuff - There are helpers, behaviors and components meant to be reused and inherited. Just have a look at what Croogo gives you (the additional config stuff, the new helpers/plugins etc) and you could easily attach your custom code here. If you add actions to your existing controllers (or add controllers) be sure you've refreshed your permissions table in order to give rights to certain roles here.

Hacky: reset admin password

I've migrated 1.3.1 db in a 1.3.2 website and I misgenerated my admin password. I tried the forgotten password feature which doesn't work on local accounts. However, the activation key is in the database. Suppose we're on a local server, you could copy activation key and visit:

 localhost/yourcroogosite/users/reset/admin/youractivationkey

and then your password is free for you to reset. 

del.icio.us Digg DZone Facebook Google Google Reader Magnolia reddit SlashDot Technorati ReadMe.ru Dobavi.com Dao.bg Lubimi.com Ping.bg Pipe.bg Svejo.net Web-bg.com

Access beforeFilter set variable in controller (CakePHP)

In a CakePHP application we could define an intermediate abstraction of a controller called AppController. The concept is having a Controller class defined by Cake core, writing controllers for our project and defining app_controller.php file for our common functions repeated in every controller.

In this case we usually use beforeFilter or beforeRender method in AppController in order to define some data to be transferred automatically in every controller. More about app_controller and callback functions.

When a variable is set in beforeFilter, it could be used with it's name later in CakePHP views. For example:

 

  1.  
  2. $this->set('products', array('P1' => 'Pizza', 'P2' => 'Water'));

 

Any view later:

 

  1.  
  2. <?php echo $products['P1']; ?>
  3.  

But that variable could not be accessed directly in a controller function. In this case we could use viewVars array in order to access beforeFilter set variable in other controller method, which solves our problem: 

 

  1.  
  2. function test() {
  3. $products = $this->viewVars['products'];
  4. $product_1 = $products['P1'];
  5. }
  6.  

 

 

del.icio.us Digg DZone Facebook Google Google Reader Magnolia reddit SlashDot Technorati ReadMe.ru Dobavi.com Dao.bg Lubimi.com Ping.bg Pipe.bg Svejo.net Web-bg.com

Easy AJAX calls in CakePHP

 CakePHP is a great framework for rapid development of web based applications that serves well the principles of DRY (Do not Repeat Yourself). However unlike other web frameworks, CakePHP is not (and probably will not) fully AJAX based (for instance, you could check the list of PHP Ajax frameworks or try some Java/Python implementations such as Google Web Toolkit and Pyjamas). 

In no way the statement above means that you cannot do some flexible and dynamic client-side calls into your CakePHP site. You could freely use plain Javascript in your views, use the JS helper of CakePHP or add some prototype/jQuery library and take advantage of its features. Beyond all that possibilities you could use one more helper of Cake - the AJAX helper. The AJAX helper provides an intuitive interface for maintaining some standard task with only few lines of code.

Some of the methods that you can use with the Ajax helper:

  • link
  • remoteFunction
  • form
  • observeField
  • autoComplete
  • drag & drop

and few more that you could find in the link above. 

The standard 1.2 implementation expects prototype and scriptaculous in order to run properly. However you could easily replace them with jQuery (and jQuery UI) libraries. Some examples on that: http://www.cakephp.bee.pl/

 

del.icio.us Digg DZone Facebook Google Google Reader Magnolia reddit SlashDot Technorati ReadMe.ru Dobavi.com Dao.bg Lubimi.com Ping.bg Pipe.bg Svejo.net Web-bg.com

How to hide load time comment for AJAX calls in CakePHP

 CakePHP puts some debug info after page load including the load time of the page. Even though it is an HTML comment line, it does affect returned data for AJAX calls (and not only). 

If we do return JSON, we could set the returned type for json-like and then json_encode the data using the $this->autoRender = false; clause. However, if we expect some specific data (like a boolean yes/no result), we would have problems with the debug feature of CakePHP.

So we could disable the debugging feature of Cake only for AJAX calls adding this statement to the beforeFIlter() action of the app_controller.php:

 

  1. if ( $this->RequestHandler->isAjax() ) {
  2. Configure::write('debug',0);
  3. }

del.icio.us Digg DZone Facebook Google Google Reader Magnolia reddit SlashDot Technorati ReadMe.ru Dobavi.com Dao.bg Lubimi.com Ping.bg Pipe.bg Svejo.net Web-bg.com

Motoclub.BG – our new moto project

 

We delivered Motoclub.BG and now it's available and accessible. The web portal is an online version of a magazine for motorcycle sports and vehicles, ATVs and others. As the bikers' favourite music is rock/metal, breaking news on concerts and live events in clubs are posted there as well.

The portal has few interesting sections for magazine online overview. You could find news and specialised articles, moto calendar with coming events, catalogue with specifications for different brands and so on. Filters and archives provide searching via keywords or month/year ranges. RSS feed on latest news is staying in the left column, next to the invitation to the Facebook group of the website.

The project is CakePHP based with MySQL database behind. I've implemented a few custom solutions on user management and RSS aggregation which I'm going to describe later.

del.icio.us Digg DZone Facebook Google Google Reader Magnolia reddit SlashDot Technorati ReadMe.ru Dobavi.com Dao.bg Lubimi.com Ping.bg Pipe.bg Svejo.net Web-bg.com