#6078: Can't sort by translated field when using PaginatorHelper::sort() and
TranslateBehavior
---------------------------+------------------------------------------------
Reporter: sebby | Type: Bug
Status: new | Priority: High
Milestone: 1.2.x.x | Component: Controller
Version: 1.2 Final | Severity: Normal
Keywords: | Php_version: n/a
Cake_version: 1.2.1.8004 |
---------------------------+------------------------------------------------
== What I did: ==
I'm using a model that uses TranslateBehavior to translate the `title`
field. When I need to get the result sorted by `title`, usually I use the
following code inside the Controller:
{{{
$this->Post->find('all', array(
'order' => array(
'I18n__title.content' => 'ASC'
)
));
}}}
and everything works as expected.
[[BR]]
[[BR]]
When I use the pagination system, and making a link to sort by `title`
using [http://api.cakephp.org/view_source/paginator-helper/#line-215
PaginatorHelper::sort()] inside the View like this:
{{{
echo $paginator->sort('Post Title', 'I18n__title.content');
}}}
there is a problem. And the same problem is with:
{{{
echo $paginator->sort('Post Title', 'title');
}}}
== What I expected to happen: ==
I expected the Paginator to sort the paginated results by `title` field.
== Why it didn't meet my expectations: ==
The [http://api.cakephp.org/view_source/paginator-helper/#line-215
PaginatorHelper::sort()] passes the correct parameters to controller but
inside the [http://api.cakephp.org/view_source/controller/#line-904
Controller::paginate()] there is a check on line
[http://api.cakephp.org/view_source/controller/#line-982 982] to see if
the sort field exists in the model. As the `title` field is a virtual
field and does not exist in the model, this test fails and the field is
not added to the order options.
== Possible Fix: ==
Expand the `if/else` structure found on line
[http://api.cakephp.org/view_source/controller/#line-982 982] inside
[http://api.cakephp.org/view_source/controller/#line-904
Controller::paginate()] to also check if the specified field is a
translated one, like this:
{{{
if (isset($object->{$alias}) &&
$object->{$alias}->hasField($field)) {
$options['order'][$alias . '.' . $field] = $value;
} elseif ($object->hasField($field)) {
$options['order'][$alias . '.' . $field] = $value;
} elseif (in_array('Translate',
$object->Behaviors->_attached)) {
$isTranslatedField = (
in_array($field,
$object->Behaviors->Translate->runtime[$object->alias]['fields']) ||
in_array($field,
$object->Behaviors->Translate->settings[$object->alias])
);
if ($isTranslatedField) {
$options['order']['I18n__' . $field . '.content'] =
$value;
}
}
}}}
Then refactorize [http://api.cakephp.org/view_source/paginator-
helper/#line-135 PaginatorHelper::sortKey()] to support I18n model:
{{{
function sortKey($model = null, $options = array()) {
if (empty($options)) {
$params = $this->params($model);
$options = array_merge($params['defaults'],
$params['options']);
}
if (isset($options['sort']) && !empty($options['sort'])) {
if (preg_match('/(?:\w+\.)?(\w+)/', $options['sort'], $result)
&& isset($result[1])) {
return $result[1];
}
return $options['sort'];
} elseif (isset($options['order']) && is_array($options['order']))
{
$key = key($options['order']);
if (preg_match('/I18n__(\w+)\.content/', $key, $result) &&
isset($result[1])) {
return $result[1];
}
return preg_replace('/.*\./', '', $key);
} elseif (isset($options['order']) &&
is_string($options['order'])) {
if (preg_match('/(?:\w+\.)?(\w+)/', $options['order'],
$result) && isset($result[1])) {
return $result[1];
}
}
return null;
}
}}}
Now the pagination system works as expected when trying to sort by a
translated field:
{{{
echo $paginator->sort('Post Title', 'title');
}}}
== Note ==
The ticket [https://trac.cakephp.org/ticket/5220 #5220] describes a
similar problem.
--
Ticket URL: <https://trac.cakephp.org/ticket/6078>
CakePHP : The Rapid Development Framework for PHP <https://trac.cakephp.org/>
Cake is a rapid development framework for PHP which uses commonly known design
patterns like ActiveRecord, Association Data Mapping, Front Controller and MVC.
Our primary goal is to provide a structured framework that enables PHP users at
all levels to rapidly develop robust web applications, without any loss to
flexibility.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"tickets cakephp" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/tickets-cakephp?hl=en
-~----------~----~----~----~------~----~------~--~---