Wednesday, February 17, 2010

Ajax charset issue in CakePHP

I was facing a typical issue in the internationalisation with cakephp.

My requirement was to render french characters in the normal flow.

My form fields were accepting the french characters in the normal flow. They were stored and retrieved normally.

But, in the Ajax flow, for eg in comments section, the french characters didnt reach the backend in the normal charset. I was breakinig my head very badly.

I found the solution in one of the forums. The problem was with the prototype.js file, where the character set was set as default to UTF-8. But the french characters need ISO-8859-1.

There are two solutions.

First Solution :

I could have updated to the latest version of the prototype.js and then try to send the encoding as a option in the ajax form field. That would have solved the problem. But I couldnt update to the latest file since I had so many stuff dependent on the existing version. I dont want to take any risk.

Second Solution:

The other option was really cool one.

$name = iconv("UTF-8", "windows-1256", $_POST['name']);

That is PHP gives you a method to convert the charset from any given charset to any required charset.

I simply used the iconv to fix the issue.


Tuesday, January 19, 2010

failed to open stream: Permission denied [CORE/cake/libs/file.php, line 146]

Warning (2): fopen(cakephp/app/tmp/cache/persistent/cake_core_dir_map) [function.fopen]: failed to open stream: Permission denied [CORE/cake/libs/file.php, line 146]

The main problem could be the access permission of the cache folder or the files within.

first try to set 777 permission to the app/tmp folder.

try clearing the cache.

If any of the persistent cache files have a different user say webadmin instead of apache, then that could result in these kind of issues

Monday, January 11, 2010

Common file extensions

Text Files


.doc

Microsoft Word Document

.docx

Microsoft Word Open XML Document

.log

Log File

.msg

Outlook Mail Message

.pages

Pages Document

.rtf

Rich Text Format File

.txt

Plain Text File

.wpd

WordPerfect Document

.wps

Microsoft Works Word Processor Document


Data Files


.123

Lotus 1-2-3 Spreadsheet

.accdb

Access 2007 Database File

.csv

Comma Separated Values File

.dat

Data File

.db

Database File

.dll

Dynamic Link Library

.efx

eFax Document

.mdb

Microsoft Access Database

.pps

PowerPoint Slide Show

.ppt

PowerPoint Presentation

.pptx

Microsoft PowerPoint Open XML Document

.sdb

OpenOffice.org Base Database File

.sdf

Standard Data File

.sql

Structured Query Language Data

.uccapilog

Microsoft UCC API Log File

.vcf

vCard File

.wks

Microsoft Works Spreadsheet

.xls

Microsoft Excel Spreadsheet

.xlsx

Microsoft Excel Open XML Document

.xml

XML File


Image Files



.pct

Picture File

Raster Image Files



.bmp

Bitmap Image File

.gif

Graphical Interchange Format File

.jpg

JPEG Image File

.png

Portable Network Graphic

.psd

Photoshop Document

.psp

Paint Shop Pro Image File

.thm

Thumbnail Image File

.tif

Tagged Image File


Vector Image Files



.ai

Adobe Illustrator File

.drw

Drawing File

.eps

Encapsulated PostScript File

.ps

PostScript File

.svg

Scalable Vector Graphics File


3D Image Files



.3dm

Rhino 3D Model

.dwg

AutoCAD Drawing Database File

.dxf

Drawing Exchange Format File

.pln

ArchiCAD Project File


Page Layout Files


.indd

Adobe InDesign File

.pdf

Portable Document Format File

.qxd

QuarkXPress Document

.qxp

QuarkXPress Project File

.rels

Open Office XML Relationships File


Audio Files

.aac

Advanced Audio Coding File

.aif

Audio Interchange File Format

.iff

Interchange File Format

.m3u

Media Playlist File

.mid

MIDI File

.midi

MIDI File

.mp3

MP3 Audio File

.mpa

MPEG-2 Audio File

.ra

Real Audio File

.wav

WAVE Audio File

.wma

Windows Media Audio File


Video Files



.3g2

3GPP2 Multimedia File

.3gp

3GPP Multimedia File

.asf

Advanced Systems Format File

.asx

Microsoft ASF Redirector File

.avi

Audio Video Interleave File

.flv

Flash Video File

.mov

Apple QuickTime Movie

.mp4

MPEG-4 Video File

.mpg

MPEG Video File

.rm

Real Media File

.swf

Flash Movie

.vob

DVD Video Object File

.wmv

Windows Media Video File


Web Files

.asp

Active Server Page

.css

Cascading Style Sheet

.htm

Hypertext Markup Language File

.html

Hypertext Markup Language File

.js

JavaScript File

.jsp

Java Server Page

.php

Hypertext Preprocessor File

.rss

Rich Site Summary

.tvpi

TitanTV Television Listing File

.tvvi

TitanTV Television Listing File

.xhtml

Extensible Hypertext Markup Language File



Font Files



.fnt

Windows Font File

.fon

Generic Font File

.otf

OpenType Font

.ttf

TrueType Font



Plugin Files



.8bi

Photoshop Plug-in

.plugin

Mac OS X Plug-in

.xll

Excel Add-In File



System Files


.cab

Windows Cabinet File

.cpl

Windows Control Panel

.cur

Windows Cursor

.dmp

Windows Memory Dump

.drv

Device Driver

.key

Security Key

.lnk

File Shortcut

.sys

Windows System File



Settings Files


.cfg

Configuration File

.ini

Windows Initialization File

.prf

Outlook Profile File


Executable Files


.app

Mac OS X Application

.bat

DOS Batch File

.cgi

Common Gateway Interface Script

.com

DOS Command File

.exe

Windows Executable File

.pif

Program Information File

.vb

VBScript File

.ws

Windows Script



Compressed Files

.7z

7-Zip Compressed File

.deb

Debian Software Package

.gz

Gnu Zipped File

.pkg

Mac OS X Installer Package

.rar

WinRAR Compressed Archive

.sit

Stuffit Archive

.sitx

Stuffit X Archive

.zip

Zipped File

.zipx

Extended Zip File


Encoded Files


.bin

Macbinary II Encoded File

.hqx

BinHex 4.0 Encoded File

.mim

Multi-Purpose Internet Mail Message

.uue

Uuencoded File



Developer Files



.c

C/C++ Source Code File

.cpp

C++ Source Code File

.java

Java Source Code File

.pl

Perl Script



Backup Files


.asd

Microsoft Word AutoSave File

.bak

Backup File

.bup

Backup File

.gho

Norton Ghost Backup File

.ori

Original File

.tmp

Temporary File



Disk Files


.dmg

Mac OS X Disk Image

.iso

Disc Image File

.toast

Toast Disc Image

.vcd

Virtual CD


Game Files


.gam

Saved Game File

.nes

Nintendo (NES) ROM File

.rom

N64 Game ROM File

.sav

Saved Game



Misc Files


.msi

Windows Installer Package

.part

Partially Downloaded File

.torrent

BitTorrent File

.yps

Yahoo! Messenger Data File



Tuesday, January 5, 2010

Internationalisation and Localisation in CakePHP

CakePHP tutorial on this http://book.cakephp.org/complete/161/Internationalization-Localization should be enough.

I should preface this post by saying that it does not cover the basics of i18n and l10n so, please, first take a look at the manual on how to get the basics going.

To better understand the goal and why some things were done the way they were, I’ll summarize the requirements:

The app has to support two languages or more (in this case English and Russian)
Default language is English
The language switching is based on a URL param
The URL format should be: example.com/eng/controller/action
Language choice should persist in the session and a cookie
Just a note here… there are other ways to determine the language requested by the user, for example it could come from a domain name like eng.example.com or rus.example.com. Hopefully the approach outlined here will also be helpful if other methods of language switching are used in your app…

Also, worth while to mention, that having language name in the URL (as opposed to just reading it from the session or cookie) helps with SEO… I won’t bore you here with details, but basically it helps to ensure that a variation of each page, based on the language param in the URL, is properly indexed by the search engines. Thus, each indexed page can be found later in the native language of the user.

Last, but not least, CakePHP uses three letter language name abbreviation, based on this, so I figure, should be fine to use the same in the URL’s.

Alright, so looking at the URL format, instantly raises a question… how do we tack on the language name to the “front” of each URL?

Thankfully the Router accomplishes that pretty easily (in app/config/routes.php):

Router::connect('/:language/:controller/:action/*',
array(),
array('language' => '[a-z]{3}'));

It takes a ‘language’ parameter and throws it to the front of the URL, just as we need it.

Now, we need to specify a default language to use, I just add this to my app/config/core.php


Configure::write('Config.language', 'eng');

So, when someone comes to the http://example.com/users/home, the site is displayed in English by default. Then we usually see a link somewhere (with a little flag next to it :)), to switch to another language.

In cake we can make those language-switching links like this:


$html->link('Русский', array('language'=>'rus'));

Notice that we set the language param, which we’ll rely on to do our switching. Providing no other params, will simply reload the current page (in the new language) with the param tacked to the front of the URL (more about this later).

Side note, it’s not a good idea to use the __() translation function on language-switching links… If I get to the site and it’s displayed in the language I can’t understand even remotely, the only savior would be a link in my native language, which indicates that i can switch to it (and well, a little flag would help too :))

So now we actually need the code to switch the language, when a user clicks on the link, like above.

It’s best done in the App Controller, kinda like here:


var $components = array('Session', 'Cookie');

function beforeFilter() {
$this->_setLanguage();
}

function _setLanguage() {

if ($this->Cookie->read('lang') && !$this->Session->check('Config.language')) {
$this->Session->write('Config.language', $this->Cookie->read('lang'));
}
else if (isset($this->params['language']) && ($this->params['language']
!= $this->Session->read('Config.language'))) {

$this->Session->write('Config.language', $this->params['language']);
$this->Cookie->write('lang', $this->params['language'], null, '20 days');
}
}


Let’s take a look at the code quickly and consider some scenarios…

I created a separate method _setLanguage();, the reason I like doing this is that it keeps the beforeFilter() cleaner, which already has enough crap in there usually.
Secondly, it can be overridden in the child controllers, if required.

So let’s consider some user-case scenarios:

The user comes to the site for the very first time

In this case the default language is read from the core.php file, so the site is set to English

The user starts clicking around the site for the very first time in his native English

Nothing really needs to be done, so we can happily skip that part

The user comes to the site and has to switch the language to Russian

Thankfully he sees a link to do so, and clicks on it. Now we check our else if, since no cookie or session with configured language exist yet. We see that the link has a /rus/ param in the URL and it is not yet stored in the session, therefore we write the new value of the default language to the session and the cookie.

The above user browses around the site, leaves, and then comes back

The session value is still present and therefore the site is automagically translated to Russian. This is good if the user forgot or doesn’t care to use links like example.com/rus/controller/action, because even plain links like example.com/controller/action will display the site in the right language because of the session value.

The above user closes the browser, goes out hunting for wild boars, and comes to the site on some other day

Now we rely on our previously stored cookie to read in the language and ensure we don’t override anything that might be in the session already. (the first if )

Now if the user decides to read the site in English

We pretty much follow through the same steps as above.

Now the last thing we need to do is to ensure that a URL param gets automatically added to all the links on the site, if a given language is chosen. Remember, that this is important to have such links for SEO as well.

Well, we’re sure as hell not going to supply the ‘language’ param manually to each link, so let’s override the cake’s default url() method to ensure the language param is now added to all links.

We create app_helper.php in /app/ (same place for app_controller.php and app_model.php), something like this:


class AppHelper extends Helper {
function url($url = null, $full = false) {
if(!isset($url['language']) && isset($this->params['language'])) {
$url['language'] = $this->params['language'];
}
return parent::url($url, $full);
}
}

Basically we check if ‘language’ param is already in the URL if it is, we don’t need to worry about it.
If not, and $this->params['language'] is available we pre-pend the required language to the URL.
The rest of the site, and all standard links will now include that ‘language’ param at the front of the URL (again, good for SEO).

And that’s pretty much it, even though the post was a bit long-winded (and beer to you, if you’ve made through the whole thing) it is quite nice to be able to do i18n & l10n in just about 15 lines of code.

A little disclaimer: even though the code seems to work fine, it is still experimental… so if you find some problems I haven’t yet encountered, please be sure to let me know.

P.S. Here’s a sampe test view, from which you can generate your .po files (easily done with cake i18n console command, but this is a topic for another tutorial and there are plenty of them “out there”).




Source :

http://teknoid.wordpress.com/2008/11/28/cakephp-url-based-language-switching-for-i18n-and-l10n-internationalization-and-localization/

Once this is done, we need to make sure the character set is proper.

We need to find the corresponding characterset of every language that we are going to translate and use the charsets accordingly.

The bootstrap file can detect the language or condition and then set the character set like this.

Configure::write('App.encoding', 'ISO-8859-1');


The database setting in the database.php in app/config should have the config element
encoding with proper character set.

'encoding' => "UTF-8"

If all of the above steps are followed, hopefully the internationalization should work.

Clear SVN Lock error

When we have a script in place to run the SVN update commands and they give a svn lock error, then the issue could be mainly because of the directory permissions.

When some one ssh to the server box and edit something over there directly, the file permission get changed from apache to root. So when we execute the SVN update command through the script, the svn shows a lock error.

If the lock error specifies a folder then we can ssh to the server and then browse to the corresponding directory and then change the file user to apache again.

For eg cd /var/www/html

chown -R apache:apache app/

This should work.