CakePHP:complexe分页查询不对列进行排序

时间:2013-06-12 09:04:00

标签: cakephp join paginate

我想使用paginate()的复杂查询。这是我的代码:

// PhasesController.php
public function manage($id = null) {
    $this->loadModel('ProjectDomainPhasesUser');
    $this->ProjectDomainPhasesUser->recursive = 0;
    $this->paginate = array(
      'ProjectDomainPhasesUser' => array(
      'order' => array('Phase.label_'.$_SESSION['lang']),
      'joins' => array(
         array(
            'table' => 'users',
            'alias' => 'User',
            'type' => 'INNER',
            'foreignKey' => false,
            'conditions'=> array(
             'ProjectDomainPhasesUser.user_id = User.id AND User.id = '.$this->Auth->User('id')
            )
         ),
         array(
            'table' => 'project_domains_phases',
            'alias' => 'ProjectDomainsPhase',
            'type' => 'INNER',
            'foreignKey' => false,
            'conditions'=> array(
             'ProjectDomainsPhase.id = ProjectDomainPhasesUser.project_domain_phase_id'
            )
         ),
         array(
            'table' => 'processes_phases',
            'alias' => 'ProcessesPhase',
            'type' => 'LEFT',
            'foreignKey' => false,
            'conditions'=> array(
             'ProjectDomainsPhase.process_phase_id = ProcessesPhase.id'
            )
         ),
         array(
            'table' => 'phases',
            'alias' => 'Phase',
            'type' => 'LEFT',
            'foreignKey' => false,
            'conditions'=> array(
             'ProcessesPhase.phase_id = Phase.id'
            )
         ),
         array(
            'table' => 'projects_domains',
            'alias' => 'ProjectsDomain',
            'type' => 'LEFT',
            'foreignKey' => false,
            'conditions'=> array(
             'ProjectDomainsPhase.project_domain_id = ProjectsDomain.id'
            )
         ),
         array(
            'table' => 'domains',
            'alias' => 'Domain',
            'type' => 'LEFT',
            'foreignKey' => false,
            'conditions'=> array(
             'ProjectsDomain.domain_id = Domain.id'
            )
         ),
         array(
            'table' => 'projects',
            'alias' => 'Project',
            'type' => 'LEFT',
            'foreignKey' => false,
            'conditions'=> array(
             'ProjectsDomain.project_id = Project.id'
            )
         )
      ),
      'fields' => array('Project.title', 'Project.date_target', 'ProcessesPhase.step_number', 'Domain.label_fr AS domain_fr', 'Domain.label_es AS domain_es', 'Phase.label_fr AS phase_fr', 'Phase.label_es AS phase_es', 'ProjectDomainsPhase.date_notification', 'ProjectDomainsPhase.done', 'ProjectDomainsPhase.date_finished', 'ProjectDomainsPhase.id')
      )
    );
    $this->set('taches', $this->paginate());

我是通过关注cakephp: using a join for search results

来实现的

我的观点:

// manage.ctp
<table cellpadding="8" cellspacing="0">
<tr>
    <th><?php echo $this->Paginator->sort('Project.title','Projet'); ?></th>
    <th><?php echo $this->Paginator->sort('Project.date_target','Date cible du projet'); ?></th>
    <th><?php echo $this->Paginator->sort('ProcessesPhase.step_number','Etape'); ?></th>
    <th><?php echo $this->Paginator->sort('Domain.domain_'.$_SESSION['lang'],'Domaine'); ?></th>
    <th><?php echo $this->Paginator->sort('Phase.phase_'.$_SESSION['lang'],'Tâche'); ?></th>
    <th><?php echo $this->Paginator->sort('ProjectDomainsPhase.date_notification','Date notification'); ?></th>
    <th><?php echo __('Statut'); ?></th>
    <th><?php echo $this->Paginator->sort('ProjectDomainsPhase.date_finished','Date fin tâche'); ?></th>
</tr>
<?php
foreach ($taches as $key => $tache){ ?>
<tr>
    <td><?php echo $tache['Project']['title']; ?>&nbsp;</td>
    <td><?php echo $this->Date->date_inv($tache['Project']['date_target']); ?>&nbsp;</td>
    <td><?php echo $tache['ProcessesPhase']['step_number']; ?>&nbsp;</td>
    <td><?php echo $tache['Domain']['domain_'.$_SESSION['lang']]; ?>&nbsp;</td>
    <td><?php echo $tache['Phase']['phase_'.$_SESSION['lang']]; ?>&nbsp;</td>
    <td><?php echo $this->Date->date_inv($tache['ProjectDomainsPhase']['date_notification']); ?>&nbsp;</td>
    <td><?php 
    echo '<input type="hidden" name="data['.$key.'][ProjectDomainsPhase][done]" value=0 />';
    echo '<input type="checkbox" name="data['.$key.'][ProjectDomainsPhase][done]" value="1"';
    if ($tache['ProjectDomainsPhase']['done']==1)
    echo ' checked';
    echo ' />';
    echo '<input type="hidden" name="data['.$key.'][ProjectDomainsPhase][id]" value='.$tache['ProjectDomainsPhase']['id'].' />';
    ?>&nbsp;</td>
    <td><?php echo $this->Date->date_inv($tache['ProjectDomainsPhase']['date_finished']); ?>&nbsp;</td>
</tr>
<?php };
?>
</table>

我的问题是,在我看来,所有数据都很棒但是当我尝试排序时,通过点击一列,页面重新加载但没有任何变化。

1 个答案:

答案 0 :(得分:0)

我为此获得了一个新的解决方案..

实际上我也遇到了同样的问题,并最终得到了一个诀窍......

这是我的联接查询和功能..

        $fields = array('SubjectCategory.name,Subject.name');
        $joins = array();
        $joins[] = array(
            'table' => 'subject_category_link',
            'foreignKey' => false,
            'conditions' => array('SubjectCategoryLink.subject_id = Subject.subject_id'
            ),
            'type' => 'INNER',
            'alias' => 'SubjectCategoryLink',
        );
        $joins[] = array(
            'table' => 'subject_category',
            'foreignKey' => false,
            'conditions' => 'SubjectCategory.subject_category_id = SubjectCategoryLink.subject_category_id',
            'type' => 'INNER',
            'alias' => 'SubjectCategory',
        );
        $conditions = array('SubjectCategory.parent_category_id' => NULL);
        $limit = 10;
        $group = 'Subject.name';
        $this->paginate = array('Subject' => compact('conditions', 'fields', 'order', 'limit', 'joins', 'group'));
        $order='';
       /* Here you should solution code provided bellow */

        $this->paginate('Subject');

当我在视图文件中调用波纹管代码时,cakephp paginator组件仅对上述记录进行排序..

echo $this->Paginator->sort('Subject.name');

我遇到的问题我无法通过单击视图文件中生成的链接按SubjectCategory.name对记录进行排序。

echo $this->Paginator->sort('SubjectCategory.name');

但它只能在初始加载时通过在控制器中定义$ order来实现。

$order = 'SubjectCategory.name asc';

所以我在cakephp中分析了paginator组件(位于app / Cake / Controller / Component / PaginatorComponent.php中)并获得了对记录进行排序的技巧..

1.在您的分页符调用($ this-&gt; paginate('Subject'))之前在控制器中添加此部分..

    if (array_key_exists('sort', $this->params['named'])) {
        $order = $this->params['named']['sort'] . ' ' . $this->params['named']['direction'];
    } else {
        $order = 'Subject.name asc';
    }
    $this->Session->write('paginate_custom',1);
    $this->paginate = array('Subject' => compact('conditions', 'fields', 'order', 'limit', 'joins', 'group'));

    $this->set(compact('order'));// Dont forget to set this order variable to view
  1. 去编辑cakephp paginator组件。(app / Cake / Controller / Component / PaginatorComponent.php)
  2. 在第141行,您可以在paginate()函数中看到波纹管代码。

     $options = $this->mergeOptions($object->alias);
    

    在此行之后添加波纹管逻辑。

        if ($this->Controller->Session->read('paginate_custom')) {
            unset($options['sort']);
            unset($options['direction']);
            $this->Controller->Session->delete('paginate_custom');
        }
    

    3.在您的视图中,在每次排序调用时替换波纹管代码($ this-&gt; Paginator-&gt; sort('SubjectCategory.name'))

        <td><?php
             $col_string = explode(' ', $order);
             $col = $col_string[0];
             if ($col == 'SubjectCategory.name') {
                 $dir = ($col_string[1] == 'asc') ? 'desc' : 'asc';
             } else {
                 $dir = 'asc';
             }
             echo $this->Paginator->sort('SubjectCategory.name', 'Name', array('direction' => $dir));?>
        </td>
    

    我认为这可能对你有帮助..

    一切顺利......

    快乐的节目......