Reputation: 181
I have a tabbed form and in each tab, a set of identical fields that differ in language only. For example, I have a name and description field in each tab, and I would create each input using CakePHP's form helper in the following fashion:
English Tab
$this->Form->input("Service.en.name");
$this->Form->input("Service.en.description");
French Tab
$this->Form->input("Service.fr.name");
$this->Form->input("Service.fr.description");
After which (this may be wrong but it worked) I would set the value of a particular field to be an array containing the values keyed by the various locales.
I'm using the TranslateBehavior and all has been well until I upgraded to the most recent of CakePHP (2.4.3 from 2.3). Now whenever I try to save I get an error saying: Unknown column "Array"
I can't find anything on saving multiple languages at once. Any ideas would be greatly appreciated!!
Update 1
I have also tried moving the locale to the end like so:
$this->Form->input("Service.name.en")
With same results
Update 2
According to xdebug, this is the SQL:
UPDATE `cc_dev`.`services` SET `name` = Array, `description` = Array, `duration` = 60, `category_id` = 1, `backend_only` = "0", `id` = 1, `vendor_id` = 116, `updated` = "2013-11-26 18:46:11" WHERE `cc_dev`.`services`.`id` = "1"
And it occurs during save. I simply check to ensure that the request data isn't empty first, and nothing more.
if (!empty($this->request->data)) {
$this->Service->save($this->request->data);
}
Update 3
Content of the submitted request data, currently in the format specified in Update 1
<pre>Array (
[Service] => Array
(
[name] => Array
(
[en] => One-to-One Session
[fr] => Séance individuelle
)
[description] => Array
(
[en] => Choose a personalized training session of 45 minutes.
[fr] => Choisissez une séance de formation individuelle de 45 minutes.
)
[duration] => 60
[category_id] => 1
)
)
</pre>
Upvotes: 1
Views: 1762
Reputation: 290
The locale is not required to be in ISO 639-2, by default, Cake2 uses it, but in my case, Configure:write('Config.language') = 'en'
and so my forms were:
$this->Form->input("Service.name.en");
$this->Form->input("Service.description.en");
It is working great, the only problem i encountered was gathering data from db in the correct format to fit this form automatically. Before the find function, i used bindTranslation() as stated in CakePhp docs:
$this->Service->bindTranslation(array('name'=>'nameTranslation'));
Removing or adjusting the contain or adding recursive = 1, it gets the translations, but finally, the nameTranslations must be moved to the Service Index in the array to be in the correct format so the CakeMagic Forms works.
'Service' => array(
'id' => '108',
'name' => 'Hugs',
'created' => '1391082480',
'locale' => 'en'
),
'nameTranslation' => array(
(int) 0 => array(
'content' => 'Hugs',
'locale' => 'en',
'foreign_key' => '108'
),
(int) 1 => array(
'content' => 'Abrazos',
'locale' => 'es',
'foreign_key' => '108'
)
)
)
As you see, that array format is clear but definitely it is not valid, so i had to add the following foreach to move values and clean it up.
$this->request->data['Service']['name'] = array();
foreach($this->request->data['nameTranslation'] as $translation)
$this->request->data['Service']['name'][$translation['locale']] = $translation['content'];
unset($this->request->data['nameTranslation'],$this->request->data['Service']['locale']);
The result was exactly what I was looking for:
'Service' => array(
'id' => '108',
'name' => array(
'en' => 'Hugs',
'es' => 'Abrazos'
),
'created' => '1391082480'
)
It is done and online, but there must be a better way to do it.
Upvotes: 0
Reputation: 181
Ok, I finally got it working.
The new preferred locale format for CakePHP is based on ISO 639-2, so I updated all current locale records to match. This is especially important when using gettext in Cake as the folder for your *.po files changes (not entirely relevant, but good to know).
After that I changed the structure of my forms to be:
$this->Form->input("Service.name.eng");
$this->Form->input("Service.description.eng");
Finally, I had to now call saveMany, as opposed to simply calling save being mindful that saveMany expects an array of records.
if (!empty($this->request->data)) {
$this->Service->saveMany(array($this->request->data));
}
So now I can save numerous translations at once again.
Upvotes: 2