Upgrading Nouchi.Mobi from 1.3 to 2.0, i got this error on my page and spent quite a few moments trying to debug. I narrowed it down to this call I was making:
$this->helpers[‘Paginator’] = array(‘ajax’ => ‘Ajax’);
This sets up Ajax pagination in CakePHP 1.3 by using the AjaxHelper class but in 2.0, this functionality has been delegated to the JsHelper. I removed that line from the code and was on my way from then on. Refer to this link in the official documentation to properly set up Ajax Pagination in CakePHP 2.0; all that is needed is the RequestHandler component, and the Js Helper.
I run both CakePHP 1.3 and 2.0 for my side projects and wanted to be able to use both console executables in my Ubuntu 11.10 dev box; I set up my aliases in my .bashrc file to point for:
Cake 1.3: alias cake=”<CAKE_FOLDER>/cake/console/cake”
Cake 2.1: alias cake2=”<CAKE_2_1_FOLDER>/app/Console/cake2″
and added the paths to the console folders where the scripts actually reside to my global PATH variable:
Since both Cake 1.3 and 2.1 console commands are called cake, i renamed the Cake 2 version to cake2 and gave it executable permissions:
mv cake cake2
chmod 755 cake2
So i tried running both command but kept getting a: “Permission Denied” error. I googled around and everybody else got their problem solved by either chmoding the cake script to either 755 or 777, or any of the containing folders in the script path. If you are running into this issue, first ensure that any folder in the path to the cake script has 755 permissions and that the cake script itself is 755. Mine was all halal but it was still no dice! I couldn’t execute and was still getting this permission denied issue. So i went back to Google and expanded my search outside the CakePHP fold and into permissions error in general when executing scripts and bang! I encountered a question on SO related to a similar issue that put me on the right track. My code resides on an extended partition that i mounted using the “users,user” option, and apparently doing it that way sets the “noexec” option as well which prevents the execution of binaries on the mounted partition. That was the source of my error, I edited my /etc/fstab file and added the “exec” option to the mount options. unmounted and remounted and bingo! I was in business. If you have exhausted all other possibilities, I bet this is what your issue is related to so give it a shot and make sure to comment for others if you come up with another solutions.
You will sometimes run into this issue when using CakePHP, I did a few times, and randomly or so it seemed and the reason is in my case, and I want to bet in most cases, is that you are using the Auth Component, and added a new action to your controller, and simply forgot to add it to the allowed functions in the Auth Component. Make sure you add the action name that you want to be made available to anyone to the Auth.allow() call in your beforeFilter() function body in the controller where the action is defined.
In anticipation of heavier traffic and also just for performance reasons, I’ve started looking into ways of caching data for Nouchi.Mobi. Since this is a CakePHP application, I naturally looked into PHP cache based solutions and you’d be hard pressed not be recommended Memcached(Used by Facebook, Twitter, Youtube, Flicker amongst others). Why would you want database caching? If you’re using a framework to build your application or just from building any type of decently functional custom coded dynamic application nowadays, chances are you will make numerous calls to retrieve the data you want to display (the average Drupal site issues 300/400 queries!). Some pages do actually make more SQL queries than others and caching the result of these queries would give your application a significant performance boost. Memcached is a high performance in-memory data caching system that works by storing data as key-value pairs, meaning :
- Store the value V with the key K
- Retrieve the Value V identified by the key K
In the context of CakePHP, follow these instructions to get Memcached up and running in your local development environment. The trickiest steps in this set up will probably enabling the memcache support in your PHP configuration (getting and enabling the php_memcache.so extension in Linux). Keep in mind that for your production environment, unless you have your own Virtual Private Server, you’d be hard pressed to find any host that will let you run Memcached in a shared hosting environment, but this is a scaling issue, and a problem you want to have, meaning your application is getting popular. Next you’d need to enable it in CakePHP in your app/core.php
Cache::config('default', array('engine' => 'Memcache'));
Once it’s up and running what you have to remember about using caching is that it is not magic. You have to code with caching in mind, and caching works best for queries that return the same data or that don’t change often. Teknoid has a good article on explaining what I mean by that with an example. Hope that’s enough to get you started and you can also take a look at this excellent Nettuts tutorial on the matter.
It turns out localization is not such an obvious task. I am currently trying to localize my Nouchi.Mobi app built with CakePHP and although CakePHP i18n console shell is helpful in created POT files, there still remains the question of translating time strings in French when using for example the CakePHP timeAgoInWords() or the PHP strftime() functions . I found a good tutorial on getting it set up in your environment here. Luckily I develop on Linux so i was able to find the LC_TIME files and import them in my application. Another tip i found out was also running the i18n shell task on your CAKE_CORE folder. It will create a POT file for your views, and your helpers as well which will give you access to some of the hard coded strings like month and day of the week values.
During the development of Nouchi.Mobi where i use this quite useful Facebook plugin (get it, it’s the best!), i ran into an issue trying to authenticate my localhost server against my Facebook app settings. I’vre created a virtual host entry in Apache pointing to my local project folder, edited my /etc/hosts file with a new “indexdot.dev” entry but i could not add that url to the Facebook app App Domain settings. The qualified domain name for my app in the Facebook settings was nouchi.mobi, and trying to login from my local app I would get this message;
API Error Code: 191
API Error Description: The specified URL is not owned by the application.
Error Message: redirect_uri is not owned by the application.
The solution was quite simple actually, thanks to this post, I added local.nouchi.mobi to my /etc/hosts file, created a virtual host entry in Apache pointing to my application folder and finally, added local.nouchi.mobi as a additional domain entry in my App Domain settings in Facebook and voila!
Working on setting up the Rest Plugin for CakePHP helped me realize that i wanted to set up JSON output for some of my actions. This way, if you request for example “www.yourapp.com/app/post/view/1.json” in the url, you will be returned the JSON post data. This excellent tutorial here will help you achieve it. The steps are simple:
Enabling JSON parsing in your app/config/routes.php: Router::parseExtensions('json');
Enable the RequestHandler component in your app_controller.php:
//Only enabling json response parsing for url requested with the .json extension
if ($this->RequestHandler->ext === 'json')
//Prevent debug output that'll corrupt your json data
In your app/layouts folder, create a json folder with the default.ctp (so the file path should be app/layout/json/default.ctp) file with the following content:
header("Cache-Control: no-store, no-cache, max-age=0, must-revalidate");
Now for all controller actions that you want the json output enabled for, set the variable in the viewVars for examples in my PostsController view action, i return the post data I want to view as:
$this->set('post', $this->Post->read(null, $id));
Now second, we need to create the json view for this data. I created a "json" folder in my "views/posts" folder and created a "view.ctp" file (views/posts/json/view.ctp) with this content:
//Some old posts you will find have this as
- And that’s it you are home free, json output a go go for your action. Access http://www.yourapp.com/view/1 and you will get your regular html output, access http://www.yourapp.com/view/1.json and you will be returned your Json output, to view the Json file in Firefox install the JsonView extension.
Now you will notice that for all json views, we will be re-using the same code, basically just changing the name of the variable to output. This call for a JsonView, and I will post aboutit once i get it implemented correctly.