Tag Archives: CakePhp

Troubleshooting your cakePhp installation

If your a first timer installing cakePhp, it's quite annoying if your not getting it to work. Really, I've seen people take up to 3 days just installing it because they don't know what the problem is. The common problem I've seen is usually a mod_rewrite issue. If your installing an application made in cakePhp and can't make it work, I suggest the ffg:
1. Get the most recent stable version from cakephp.org and follow the instructions from the Manual Section 3. Install it in a subfolder. You can always move it somewhere else after the installation. Let's say the subfolder name is /mycake. Also make sure to change the permission to /app/tmp
2. After running it, see if the page is a bit colorful. If yes, then go to the next step. If not, check the src of the <link> tag. The link tag should most likely look like this
<link src="/mycake/css/style.css">
If the src is only "/css/style.css", then I bet you have a mod_rewrite problem. Check your apache configuration. For windows, I believe it is named httpd.conf and most likely it was just commented out in the list of modules so look for the word mod_rewrite. In ubuntu, most likely it is in the /ect/apache2/, I don't know in other distros. I can't give much info in troubleshooting it in ubuntu or linux, there could be a couple of ways. After successfully doing so, remember to restart your apache and check again. Don't stop until you see those colors. Go to the next step afterwards.
3. You can stop right here. The ffg step is just for me to verify that no doubt the installation works. Proceed if you like.
Create a simple controller with the ffg content:

PHP:
  1. var $uses = null // so you dont have to use a model
  2. function index() {}

Then create your view named index.thtml (im using the 1.1 version). If that successfully loaded, congratulations! You have verified your installation successful. If not, then tell me about it.

Another problem I experienced before when installing this in a server is the "new installation of cake: open_basedir restriction error". Basically, here are the solutions:
1. Hack the core. Change the fileExistsInPath (located in /cake/basics.php) function to:

PHP:
  1. function fileExistsInPath($file) {
  2. $paths = explode(PATH_SEPARATOR, ini_get(’include_path’));
  3. // removing /usr/share/pear from the list of includes_path
  4. array_shift($paths); //added
  5. array_shift($paths); //added
  6. // the rest goes here
  7. }

2. .htaccess config. Add the ffg lines to your .htaccess so that the php include_path doesn’t have all the extra stuff you don’t need:

PHP:
  1. php_value include_path

Read more info here.
For IIS installation, I just found this help . If you have other experience, write about it or add a comment and let us all know.

How to change your DEBUG level on the fly

The debugging features of cakePhp is very very helpful to me specially the full debug with sql. Sometimes it's a bit irritating if your dealing with ajax calls. In looking at the cheesecake source code, I found this hack to change it to 0, 1, 2 or 3 on the fly:

PHP:
  1. Configure::write('debug',0);

Here is the complete code on how they handle ajax calls:

PHP:
  1. // Hack to prevent wierd output with AJAX
  2. if ($this-&gt;RequestHandler-&gt;isAjax()) {
  3. $db =&amp; ConnectionManager::getDataSource('default');
  4. $db-&gt;fullDebug = false;
  5.  
  6. }

cakePhp $html->checkbox htmlattributes issues

It's not obvious but certainly I was caught offguard for a certainly small issue that made me use the old habit of doing the checkbox thingy.

When I explicitly tell the html helper to check a certain checkbox, I always do array('checked'=>'checked'); to add the checked attribute but I am left wondrin why it does not do what I want. I really can't remember what I did to make others work but certainly it was such a headache that I opted to use the old <input type='checkbox' /> tags. After looking at the html helper, I found out the ffg comments

* + 'compact'
* + 'checked'
* + 'declare'
* + 'readonly'
* + 'disabled'
* + 'selected'
* + 'defer'
* + 'ismap'
* + 'nohref'
* + 'noshade'
* + 'nowrap'
* + 'multiple'
* + 'noresize'
*
* And its value is one of:
* + 1
* + true
* + 'true'
*
* Then the value will be reset to be identical with key's name.
* If the value is not one of these 3, the parameter is not output.

This does not only involve the checkbox but all the input tags because they pass this step first before outputting any parameter. I wish I explored on this much earlier, it would have saved me a lot of energy. Oh well, atleast I learned something new for the day :)

You may also want to check the function yourself. It is the function _parseAttributes($options, $exclude = null, $insertBefore = ' ', $insertAfter = null) in the html helper. You can see the $insertBefore = ' ', $insertAfter = null, this is useful for checkboxes to add labels but currently, that option is not available in the 1.1 version. Someone already asked this enhancement in trac so I am not reporting it again. I hope that saves some of your time :)

Validate radio buttons in cakePhp’s ajax->form

It took me a while to learn how to add validation using the $ajax->form() of cakePhp. I think the ajax helper simplifies your work for ajax calls but you should first understand how to use it. The manual isn't that helpful in explaining the deatails of this helper. Here is one example that I used in an application I am involve with and this hopefully could brighten someone's day.

In my view.thtml, I have this form

<?php
// !important: name your form
$form_options['id'] = 'myform';
$form_options['update'] = 'my-results';
// this is where you'll call the validation function
$form_options['before'] = 'if (!validate()) return false;';
echo $ajax->form('/controller/action', null, $form_options)
?>
<div id="errMsg"></div>
<table>
<tr valign="top">
<td nowrap><span class="required">*</span> Subscription type </td>
<td><div id="ModelType"><?php echo $html->radio('Model/type', $my_type, '<br />') ?></div></td>
</tr>
<tr valign="top">
<td nowrap><span class="required">*</span> Receive updates </td>
<td><div id="ModelRange"><?php echo $html->radio('Model/range', $my_range, ' ') ?></div></td>
</tr>
</table>
</form><div id="my-results"></div>

The validation looks like this

function validate() {
var validation_cnt = 0;
// you must delete the previous message
removeMsg(['err1', 'err2', 'err3']);

// begin the validation
if (isRadioEmpty("myform", "data[Rss][type]")) {
insertMsg('RssType', 1, 'This is required.');
validation_cnt++;
}

if (isRadioEmpty("myform", "data[Rss][range]")) {
insertMsg('RssRange', 2, 'This is required.');
validation_cnt++;
}

if (validation_cnt > 0) {
var req_msg = '';
if (validation_cnt == 1) {
req_msg = 'Found '+ validation_cnt +' error. Please double check your answers. Some fields are required.'
} else {
req_msg = 'Found '+ validation_cnt +' errors. Please double check your answers. Some fields are required.'
}
insertMsg('errMsg', 3, req_msg);
validation_cnt = 0;
return false;
}

return true;
}

One problem I had with this one is that I need to validate radio buttons. But since cakePhp uses illegal characters in its name, you cannot just use the normal call for it. I found an explanation of how to do this here. Here is the function that validates the radiobuttons:

/**
* Returns true if any of radio boxes with the NAMEs of elementName contained in the FORM named formName is checked
*
* @param formName - ID of the FORM
* @param elementName - NAME of the radio boxes
* @author: Rachel
*/
function isRadioEmpty(formName, elementName) {
var empty = true;
for (i=0; i<=document.forms[formName].elements[elementName].length - 1; i++) {
if (document.forms[formName].elements[elementName][i].checked) empty = false;
}

if (empty) return true;
return false;
}

I am also using some prototype methods to insert the error messages at the bottom of the fields and count the errors. Here is the function for that

/**
* Insert error message after the element containerID
* Add style to class errFld to add style to the error message
* You can delete the previous message created by using @link removeID('err'+errID)
*
* @param containerID - ID of an element preceeding the error message
* @param errID - any unique ID that you can give to the error message to uniquely identify it
* @param msg - message
* @param containerType - default value is DIV tag
* @author: rage
*/
function insertMsg(containerID, errID, msg, containerType) {
if (!containerType) containerType = 'div';
new Insertion.After(containerID, '<'+containerType+' id="err'+errID+'" class="errFld">'+msg+'</'+containerType+'>');
}

/**
* Delete the element if it exist. Do nothing if it doesnt exist
*
* @param id - element IDs
* @author: rage
*/
function removeMsg(ids) {
for (x=0; x<=ids.length - 1; x++) {
try { Element.remove(ids[x]); } catch (err) {} // do nothing
}
}

You can check the whole code for simplicity here.