Wednesday, May 4, 2011

[CakePHP 1.3.8, TranslateBehavior, DboPostgres] Invalid result set

Hello,
I just have moved my project on CakePHP 1.3.8 from MySQL to PostgreSQL
8.3 and then Translate stopped working correctly.

Instead of:

[0] => Array
(
[Category] => Array
(
[id] => 3
[parent_id] =>
[lft] => 1
[rght] => 2
[locale] => pol
[name] => Start
[description] => Tutaj opis
)
...

I have received:

[0] => Array
(
[Category] => Array
(
[id] => 3
[parent_id] =>
[lft] => 1
[rght] => 2
[locale] => pol
[name] =>
[description] =>
)

[I18n] => Array
(
[name] => Start
[description] => Tutaj opis
)
...

SQL code generated by Cake:

SELECT
"Category"."id" AS "Category__id",
"Category"."parent_id" AS "Category__parent_id",
"Category"."lft" AS "Category__lft",
"Category"."rght" AS "Category__rght",
"I18n__name"."content" AS "I18n__name__content",
"I18n__description"."content" AS "I18n__description__content"
FROM "cms_categories" AS "Category"
LEFT JOIN "i18n" AS "I18n__name"
ON ("Category"."id" = "I18n__name"."foreign_key"
AND "I18n__name"."model" = 'Category'
AND "I18n__name"."field" = 'name')
LEFT JOIN "i18n" AS "I18n__description"
ON ("Category"."id" = "I18n__description"."foreign_key"
AND "I18n__description"."model" = 'Category'
AND "I18n__description"."field" = 'description')
WHERE "I18n__name"."locale" = 'pol'
AND "I18n__description"."locale" = 'pol'
ORDER BY "Category"."lft" ASC

After some debug work I found reason in method
DboPostgres::resultSet(). Name of the column for "description" field
translation is "I18n__description__content". DboPostgres::resultSet()
method incorrectly parses table name and field name from this string
as "I18n" and "description" instead of "I18n__description" and
"content". In the end, method creates invalid result array and
TranslateBehavior does not detect the translation.

Code:
...
if (strpos($columnName, '__')) {
$parts = explode('__', $columnName);
$this->map[$index++] = array($parts[0], $parts[1]);
} ...

I propose the following solution:
...
$pos = strrpos($columnName, '__');
if ($pos !== false) {
$table_name = substr($columnName, 0, $pos);
$column_name = substr($columnName, $pos+2, strlen($columnName));
$this->map[$index++] = array($table_name, $column_name);
} ...

Solution is to split $columnName at the last occurrence of __
separator, not every like in original code.

--
Our newest site for the community: CakePHP Video Tutorials http://tv.cakephp.org
Check out the new CakePHP Questions site http://ask.cakephp.org and help others with their CakePHP related questions.


To unsubscribe from this group, send email to
cake-php+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/cake-php

No comments: