In response of Karim's request...

The standard way of implementing translations in the default cake core
is, to my opinion, very resource intensive. It uses a lot of sub-
queries when a lot of fields in a table need translations.

At this stage I'm using the following setup in my solutions:

Example: A content table where title,introduction & content should be
available in more than one language.

id -> int(11)
uid -> int(11)
language -> char(3)
title -> varchar(150)
introduction -> text
content -> text

- uid represents a  shared id among all translations for a give page
- language represents the language of this translated page record, for
example: dut,eng,ger etc... It is unique for a given uid


In the model for Page the following association is made:
var $hasMany = array(
   'Translation' => array(
       'className' => 'Page',
       'foreignKey' => 'uid',

       .. other keys
   )
)

For every language one record is made per page, all sharing the same
uid

Using the following actions in the Page model class will;
a.) Add the translation language to each query, and all queries using
Id will be rewriten to be using Uid
b.) Converts the numeric keys in the Translation array found in
resultsets to the language keys. (0=>...,1=>... would become for
example 'dut'=>..., 'eng'=>...)

--------------------
        function beforeFind($queryData)
        {
                $lang = Configure::read('lang');

                if(array_key_exists('conditions',$queryData))
                {

                        // replace id key to uid if present
                        if(array_key_exists('Page.id',$queryData['conditions']))
                        {
                                $queryData['conditions']['Page.uid'] = 
$queryData['conditions']
['Page.id'];
                                unset($queryData['conditions']['Page.id']);
                        }

                        //add language key to query
                        $queryData['conditions'] = 
array_merge($queryData['conditions'],
array('Page.language'=>$lang));
                }
                else
                {
                        $queryData['conditions'] = 
array('Page.language'=>$lang);
                }
                return $queryData;
        }


        function afterFind($results)
        {
                //check if we are in the last loop, just before returning all 
data
                if(count($results) > 0 && array_key_exists('Page',$results[0]))
                {
                        //assign all Translation results to named keys
                        foreach($results as $key => $page)
                        {
                                $translations = array();
                                foreach($page['Translation'] as $trans)
                                {
                                        $translations[$trans['language']] = 
$trans;

                                }
                                $results[$key]['Translation'] = $translations;
                        }
                }

                return $results;
        }
--------------------

In add & edit forms the result should be converted to the following
form before setting it to the form view

Example edit page id 3
-------
a.) Result from $page = $this->Page->findById(3); would be something
like

[Page]
    [id] => 3
    [uid] => 3
    [language] => 'dut'
    [title] => '....

[Translation]

   [dut]
     [id] => 3
     [uid] => 3
     [language] => 'dut'
     [title] => '....

   [eng]
     [id] => 4
     [uid] => 3
     [language] => 'eng'
     [title] => '....

b.) before setting it to the view this gets rewriten as

[Page]

   [0]
     [id] => 3
     [uid] => 3
     [language] => 'dut'
     [title] => '....

   [1]
     [id] => 4
     [uid] => 3
     [language] => 'eng'
     [title] => '....


c.) In your form view the fields can be addressed as Page.0.title (for
dutch), Page.1.title (for english), etc... Don't forget the hidden uid
& language field values.

d.) In your controller, in the edit -> save function you can use $this-
>Page->saveAll($this->data['Page']) to save all records back to the
db.

Add a new page involves one extra step:
a.) Save the first translation and get it's auto increment id
b.) Set the uid key for all translations to this value of this id
c.) Use saveAll ... again to save all records

Maybe someday I will create a behaviour for this kind of functionality

Succes Karim!

P.s. Open for comments!

Regards,

Olav





--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"CakePHP" group.
To post to this group, send email to cake-php@googlegroups.com
To unsubscribe from this group, send email to 
cake-php+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/cake-php?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to