24 Oct

10 Best CakePHP snippets for Web2.0 development

CakePHP

I’ve compiled a list of all code snippets in CakePHP which help me doing things faster in Cake. I hope this will be helpful for you too.

1. Tag Cloud: Web2.0 way of showing tags.. This customizable snippet will allow you to add tag cloud easily.

2. AJAX Auctocomplete: Another basic requirement of the latest web technologies. Also check out the Autocomplete article to implement the same.

3. AJAX Star Rating: This is a great one, lets you implement the rating system with your Cake application very fast and without any pain.

4. AJAX Chat Plugin: This is my favorite one, lets you implement AJAX chat easily - this can serve so many purposes in an application.

5. Flickr Gallery: This is a great article by Jonathan Snook. Lets you create a flexible attractive gallery with your own application.

6. GeoCoding: Good for mashup applications which uses Google Maps or Yahoo maps.

7. Ajax Validation Component: This component adds a few validation options to CakePHP validations. And yes, its more web2-ish.

8. Lightbox Effect Helper: Easily implement lightbox effect to your links and images.

9. Google Map Helper: Lets you add Google Map to any application in no-time, lacks flexibility, but speeds up the implementation process. This was developed by me.

10. jQuery Helper: jQuery is designed to change the way that you write JavaScript.

Please feel free to add up more to the list.

Additional Stuff:

1. Submit forms with AJAX in CakePHP
2. Enable SOAP Services in Cake
3. RESTful Web Services With CakePHP

13 Feb

Finally a practical solution: Joomla with CakePHP together - JAKE

Articles, CakePHP, Latest Developments

For all those who liked my previous post where we integrated Joomla and CakePHP together, will surely love this one. There were some problems and limitations with the previous system, the major one was - The users who are already running Joomla couldn't take advantage of Cake as the setup involved in changing paths and all. Thanks to Dr. Tarique Sani for suggesting me that.

Ok, so lets start with the setup. Here the concept is, to install CakePHP as any other Joomla component and lets not modify anything with the present setup of Joomla. This is how we will start writing our component, com_cake [You can skip this part if you are interested in getting ready to use component] :

1. Lets install CakePHP in '\components\com_cake' of Joomla directory.

2. As we did before, lets create triggers for Cake... which are actual part of the components too: cake.php and cake.html.php

Here is cake.php

PHP:
  1. <?php
  2. defined( '_VALID_MOS' ) or die( 'Restricted access' );
  3.  
  4. require_once($mainframe->getPath('front_html'));
  5. $mainframe->setPageTitle("com_cake: Ultimate Joomla Component");
  6.  
  7. $joomla_path=dirname(dirname(dirname(__FILE__)));
  8.  
  9. // As this component (cakephp) will need database access, lets include Joomla's config file
  10. require_once($joomla_path.'/configuration.php');
  11.  
  12. // Constants to be used later in com_cake
  13. define(JOOMLA_PATH,$mosConfig_live_site);
  14. define(DB_SERVER,$mosConfig_host);
  15. define(DB_USER,$mosConfig_user);
  16. define(DB_PASSWORD,$mosConfig_password);
  17. define(DB_NAME,$mosConfig_db);
  18.  
  19. $controller=mosGetParam( $_REQUEST ,'module'); //option passed is treated as a controller in cake
  20. $action=mosGetParam( $_REQUEST ,'task'); //task passed is treated as a controller in cake
  21. $param=mosGetParam( $_REQUEST ,'id');
  22.  
  23. HTML_cake::requestCakePHP('/'.$controller.'/'.$action.'/'.$param);
  24.  
  25. ?>

cake.html.php

PHP:
  1. <?php
  2. defined( '_VALID_MOS' ) or die( 'Restricted access' );
  3.  
  4. class HTML_cake {
  5.  
  6. function requestCakePHP($url)
  7. {
  8.     $_GET['url']=$url;
  9.     require_once 'app\webroot\index.php';
  10. }
  11.  
  12. }
  13. ?>

Edit Cake's database.php

PHP:
  1. <?php
  2.  
  3. class DATABASE_CONFIG
  4. {
  5.     var $default = array(
  6.         'driver' => 'mysql',
  7.         'connect' => 'mysql_connect',
  8.         'host' => DB_SERVER,
  9.         'login' => DB_USER,
  10.         'password' => DB_PASSWORD,
  11.         'database' => DB_NAME
  12.     );
  13. }
  14. ?>

Ok, now we can see that URL like:
http://localhost/joomla/index.php?option=com_cake
will open Cake's homepage in Joomla layout. Make sure you have edited your default.thtml file so that CSS and HTML tags do not mess up.

http://localhost/joomla/index.php?option=com_cake&module=names&task=add
will call CakePHP's 'names' controller and 'add' function.
(Please dont confuse 'module' variable in URL with Joomla's module !!)
It will work great but we need even more. We also need scafollding/bake and more things which Cake can give... In my case, I loved baking than any other thing, so as to support bake process. Lets do next step.

3. Since Cake baked code uses helpers to output links, images or any other URL. So, lets hack Cake helper to output Joomla's URL in this formats:

index.php?option=com_cake&module=names&task=add
index.php?option=com_cake&module=names&task=index
index.php?option=com_cake&module=names&task=view&id=12

So, I wrote a small function for this, as we all love our HTML helper in Cake:
Write this function on bootstrap.php

PHP:
  1. <?php
  2.   function reform_url($url)
  3.     {
  4.         $temp=explode('/',$url);
  5.         $controller=$temp[1];
  6.         $action=$temp[2];
  7.         $param=$temp[3];
  8.         $url=JOOMLA_PATH.'/index.php?option=com_cake&module='.$controller.'&task='.$action;
  9.         if($param)
  10.             $url=$url.'&id='.$param;
  11.         return $url;
  12.     }
  13. ?>

Now we need to integrate this function with the helper functions so that it takes input in same format but output Joomla URL.

Copy HTML Helper (html.php) to your views/helpers folder and edit the following functions:

PHP:
  1. function url($url = null, $return = false) {
  2.  
  3.         if (isset($this->plugin)) {
  4.             $base = strip_plugin($this->base, $this->plugin);
  5.         } else {
  6.             $base = $this->base;
  7.         }
  8.  
  9.         if (empty($url)) {
  10.             return $this->here;
  11.         } elseif($url{0} == '/') {
  12.             $url=reform_url($url)//Lets change the URL
  13.             $output = $base . $url;
  14.         } else {
  15.             $url=reform_url($url)//Lets change the URL
  16.             $output = $base . '/' . strtolower($this->params['controller']) . '/' . $url;
  17.         }
  18.  
  19.         return $this->output($output, $return);
  20.     }

Similar changes were done in HTML::link(), HTML::image() and Controller:flash()

PHP:
  1. function flash($message, $url, $pause = 1) {
  2.         $this->autoRender = false;
  3.         $this->autoLayout = false;
  4.         $this->set('url', reform_url($this->base . $url));
  5.         $this->set('message', $message);
  6.         $this->set('pause', $pause);
  7.         $this->set('page_title', $message);
  8.  
  9.         if (file_exists(VIEWS . 'layouts' . DS . 'flash.thtml')) {
  10.             $flash = VIEWS . 'layouts' . DS . 'flash.thtml';
  11.         } elseif ($flash = fileExistsInPath(LIBS . 'view' . DS . 'templates' . DS . "layouts" . DS . 'flash.thtml')) {
  12.         }
  13.         $this->render(null, false, $flash);
  14. }

4. We are all done, and our Cake is waiting for us....!!!
I did one more mod so that you people can still bake on using bake.php... Edit com_cake\cake\scripts\bake.php and on starting lines add this:

PHP:
  1. $joomla_path=dirname(dirname(dirname(dirname(dirname(__FILE__)))));
  2. require_once($joomla_path.'/configuration.php');

Most of your small applications developed with Cake will still work with Joomla using this component, as we have modified the helpers too. You dont even have to change Cake's conding conventions to use this plus you can still use bake.php anytime.

You can download the component here.

See it in action:
CakePHP Homepage in Joomla
Names::index()
Names::add()

Please post your feedback if you like this, good feedback on my previous article inspired me to do this.. I will post more interesting stuff soon.

UPDATE - 16, Feburary: Mariano Iglesias is extending this project further. Here's the Jake Homepage

Thanks
- Max

28 Jan

Joining powers of two great systems: Joomla and CakePHP

Articles, CakePHP, Latest Developments

The day I learned CakePHP, it started inspiring me for getting more and more out of it. Its custom hacks are pretty cool, and CakePHP is a complete framework in itself. However, like all other frameworks, it creates too much of work when we have to code some features again and again, like User-registration, a link manager, gallery and all.... Joomla does handle all this pretty well. So, after I saw Drake, I decided to write my same thing with Joomla as I like it as a CMS and it is used by us everyday.

I would like to thank Felix from ThinkingPHP the most, his research helped me a lot to do this.

Let's start with a nice fresh setup.

1) Download Fresh versions of Cake and Joomla
and install Cake first (for me its joomla_cake), Rename cakephp's /app/webroot/index.php to cakephp.php then install Joomla inside 'webroot' of Cake's directory.

So your directory structure will be like:

/app
---------/webroot
-----------------/joomla's index.php with other files
-----------------/cakephp.php (we will use this to triger Cake)
/cake
/vendors

Edit cakephp.php

PHP:
  1. if(isset($_GET['url']) && $_GET['url'] === 'favicon.ico')
  2. {
  3. }
  4. else
  5. {
  6. /*    $Dispatcher= new Dispatcher ();
  7.     $Dispatcher->dispatch($url);*/
  8. }

Now we have disabled page rendering if we include this 'cakephp.php' in any external application.

2) Lets Create Joomla Component which will trigger Cake. : Lets call it 'com_cake'. This will be our master component in Joomla which will be triggered in case of when any unidentified Joomla's component is called... Lets add this functionality first.. Edit Joomla's index.php:

PHP:
  1. //Before Joomla initialize its mainframe, lets play...
  2. // check missing component -- added before $mainframe is being initialized
  3. //##########################
  4. if (!file_exists( $mosConfig_absolute_path .'/components/'.$option ) )
  5.     $option='com_cake'//set component to com_cake if a controller is not found.
  6. //##########################
  7. $mainframe = new mosMainFrame( $database, $option, '.' );

Lets get back to create the component:


/app
---------/webroot
-----------------/components (Joomla's component dir)
------------------------/com_cake
----------------------------------/cake.html.php (trigger to cakephp)
----------------------------------/cake.php (calls trigger with required options)
/cake
/vendors

We have to follow Joomla conventions for this module...
Lets create these 2 files, cake.php and cake.html.php:

cake.html.php:

PHP:
  1. defined( '_VALID_MOS' ) or die( 'Restricted access' );
  2. class HTML_cake {
  3. function requestCakePHP($url)
  4. {
  5.     $_GET['url']=$url;
  6.     require_once 'cakephp.php';
  7.     ob_start();
  8.     $Dispatcher= new Dispatcher ();
  9.     $Dispatcher->dispatch($url);
  10. }
  11. }

cake.php: This file will judge which controller/action to pass in cakephp.

PHP:
  1. defined( '_VALID_MOS' ) or die( 'Restricted access' );
  2. require_once($mainframe->getPath('front_html'));
  3. $mainframe->setPageTitle("Check this out");
  4. global $database;
  5. $controller=mosGetParam( $_REQUEST ,'option'); //option passed is treated as a controller in cake
  6. $action=mosGetParam( $_REQUEST ,'task'); //task passed is treated as a controller in cake
  7. HTML_cake::requestCakePHP('/'.$controller.'/'.$action);

3) Time to check its functioning:

www.myserver.com/joomla/index.php?option=names&task=add

1. $_GET['option'] is passed to Joomla's index.php. There it concluded that component called 'names' is not found, so lets pass it to 'com_cake'

2. Now we are in cake.php (com_cake), we will check what controller and action it is requesting, and trigger the 'requestCakePHP' function.

This will make Joomla to assume that component being called is 'com_cake', and task is 'names/add'. This task will be then passed to Cake as $_GET['url'].

And we're done...

I see baked code of Cake's model 'name' inside Joomla.

Joomla and Cake together

Currently, I have not created it to handle the function arguments... but if I found this to be more useful... I will continue the project. The next updates will be:

1. Better handling of function arguments.
2. Customization of CakePHP's helpers to make use of right path and more.
3. Utilization of some plugins

Thanks
-- Max aka Abhimanyu Grover