#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
-~----------~----~----~----~------~----~------~--~---

  • [CakePHP : The Rapid Dev... CakePHP : The Rapid Development Framework for PHP

Reply via email to