cakephp:扩展模型类以覆盖分页方法

发布于 2024-11-29 02:10:48 字数 7596 浏览 1 评论 0原文

我花了 2 天的时间寻找 cakephp 分页问题的解决方案。

简而言之,我需要针对同一模型使用不同的分页方法。索引操作将使用默认方法,视图操作将使用带有自定义查询的方法。

基于OOP的继承概念,我认为解决方案是扩展我的模型并覆盖扩展模型上的分页方法。因此,我可以从控制器调用索引操作的默认分页方法和视图操作的自定义方法。

问题是:我如何扩展我的模型类?这个想法行得通吗?

这是我的模型:

<?php
class Communication extends AppModel {

var $name = 'Communication';
var $displayField = 'title';

//The Associations below have been created with all possible keys, those that are not needed can be removed

var $hasMany = array(
    'Interaction' => array(
        'className' => 'Interaction',
        'foreignKey' => 'communication_id',
        'dependent' => false,
        'conditions' => '',
        'fields' => '',
        'order' => '',
        'limit' => '',
        'offset' => '',
        'exclusive' => '',
        'finderQuery' => '',
        'counterQuery' => ''
    ),
    'Star' => array(
        'className' => 'Star',
        'foreignKey' => 'communication_id',
        'dependent' => false,
        'conditions' => '',
        'fields' => '',
        'order' => '',
        'limit' => '',
        'offset' => '',
        'exclusive' => '',
        'finderQuery' => '',
        'counterQuery' => ''
    )
);

var $hasAndBelongsToMany = array(
    'Document' => array(
        'className' => 'Document',
        'joinTable' => 'communications_documents',
        'foreignKey' => 'communication_id',
        'associationForeignKey' => 'document_id',
        'unique' => true,
        'conditions' => '',
        'fields' => '',
        'order' => '',
        'limit' => '',
        'offset' => '',
        'finderQuery' => '',
        'deleteQuery' => '',
        'insertQuery' => ''
    ),
    'Event' => array(
        'className' => 'Event',
        'joinTable' => 'communications_events',
        'foreignKey' => 'communication_id',
        'associationForeignKey' => 'event_id',
        'unique' => true,
        'conditions' => '',
        'fields' => '',
        'order' => '',
        'limit' => '',
        'offset' => '',
        'finderQuery' => '',
        'deleteQuery' => '',
        'insertQuery' => ''
    ),
    'Meeting' => array(
        'className' => 'Meeting',
        'joinTable' => 'communications_meetings',
        'foreignKey' => 'communication_id',
        'associationForeignKey' => 'meeting_id',
        'unique' => true,
        'conditions' => '',
        'fields' => '',
        'order' => 'date_create DESC',
        'limit' => '',
        'offset' => '',
        'finderQuery' => '',
        'deleteQuery' => '',
        'insertQuery' => ''
    ),
    'User' => array(
        'className' => 'User',
        'joinTable' => 'communications_users',
        'foreignKey' => 'communication_id',
        'associationForeignKey' => 'user_id',
        'unique' => true,
        'conditions' => '',
        'fields' => '',
        'order' => 'name',
        'limit' => '',
        'offset' => '',
        'finderQuery' => '',
        'deleteQuery' => '',
        'insertQuery' => ''
    )
);

function getComInfos($id) {

    $this->unbindModel(array('hasAndBelongsToMany'=>array('Document','Event','Meeting')));
    $this->unbindModel(array('hasMany'=>array('Star','Interaction')));
    $communication_infos = $this->read(null, $id);

    //debug($communication_infos);

    return $communication_infos;

}

function getComLinks($id) {

    $communication_links = $this->query("
    SELECT 'documents' AS 'type', 'D' AS 'marker', d.id AS id, d.date_create AS date, du.user_id AS info_aux, d.title AS title, d.desc AS content 
    FROM communications_documents AS cd
    JOIN documents AS d ON d.id = cd.document_id
    JOIN documents_users AS du ON du.document_id = d.id
    WHERE cd.communication_id = ".$id."

    UNION

    SELECT 'events' AS 'type', 'E' AS 'marker', e.id AS id, e.date_create AS date, e.institution AS info_aux, e.title AS title, e.desc AS content
    FROM communications_events AS ce
    JOIN events AS e ON e.id = ce.event_id
    WHERE ce.communication_id =".$id."

    UNION

    SELECT 'meetings' AS 'type', 'R' AS 'marker', m.id AS id, m.date_create AS date, m.site AS info_aux, m.title AS title, m.desc AS content
    FROM communications_meetings AS cm
    JOIN meetings AS m ON m.id = cm.meeting_id
    WHERE cm.communication_id =".$id."

    UNION

    SELECT 'interactions' AS 'type', 'C' AS 'marker', i.id AS id, i.date_create AS date, i.user_id AS info_aux, i.title AS title, i.content AS content
    FROM interactions AS i
    WHERE i.communication_id =".$id."

    ORDER BY date DESC
    ");

    //debug($communication_links);

    return $communication_links;

}

}

这是我的两个自定义分页方法,我只需将其用于视图操作:

function paginate($conditions, $fields, $order, $limit, $page = 1, $recursive = null, $extra = array()) {

    $recursive = -1;
    return $this->query("
    SELECT 'documents' AS 'type', 'D' AS 'marker', d.id AS id, d.date_create AS date, du.user_id AS info_aux, d.title AS title, d.desc AS content 
    FROM communications_documents AS cd
    JOIN documents AS d ON d.id = cd.document_id
    JOIN documents_users AS du ON du.document_id = d.id
    WHERE cd.communication_id = 137

    UNION

    SELECT 'events' AS 'type', 'E' AS 'marker', e.id AS id, e.date_create AS date, e.institution AS info_aux, e.title AS title, e.desc AS content
    FROM communications_events AS ce
    JOIN events AS e ON e.id = ce.event_id
    WHERE ce.communication_id =137

    UNION

    SELECT 'meetings' AS 'type', 'R' AS 'marker', m.id AS id, m.date_create AS date, m.site AS info_aux, m.title AS title, m.desc AS content
    FROM communications_meetings AS cm
    JOIN meetings AS m ON m.id = cm.meeting_id
    WHERE cm.communication_id = 137

    UNION

    SELECT 'interactions' AS 'type', 'C' AS 'marker', i.id AS id, i.date_create AS date, i.user_id AS info_aux, i.title AS title, i.content AS content
    FROM interactions AS i
    WHERE i.communication_id = 137

    ORDER BY date DESC
    LIMIT ".(($page-1)*$limit).", ".$limit);

}

function paginateCount($conditions = null, $recursive = 0, $extra = array()) {
    $sql = "
    SELECT 'documents' AS 'type', 'D' AS 'marker', d.id AS id, d.date_create AS date, du.user_id AS info_aux, d.title AS title, d.desc AS content 
    FROM communications_documents AS cd
    JOIN documents AS d ON d.id = cd.document_id
    JOIN documents_users AS du ON du.document_id = d.id
    WHERE cd.communication_id = 137

    UNION

    SELECT 'events' AS 'type', 'E' AS 'marker', e.id AS id, e.date_create AS date, e.institution AS info_aux, e.title AS title, e.desc AS content
    FROM communications_events AS ce
    JOIN events AS e ON e.id = ce.event_id
    WHERE ce.communication_id = 137

    UNION

    SELECT 'meetings' AS 'type', 'R' AS 'marker', m.id AS id, m.date_create AS date, m.site AS info_aux, m.title AS title, m.desc AS content
    FROM communications_meetings AS cm
    JOIN meetings AS m ON m.id = cm.meeting_id
    WHERE cm.communication_id = 137

    UNION

    SELECT 'interactions' AS 'type', 'C' AS 'marker', i.id AS id, i.date_create AS date, i.user_id AS info_aux, i.title AS title, i.content AS content
    FROM interactions AS i
    WHERE i.communication_id = 137

    ORDER BY date DESC
    ";
    $this->recursive = $recursive;
    $results = $this->query($sql);
    return count($results);
}`

i spent the last 2 days looking for a solution for a problem with pagination in cakephp.

In short, i need diferent pagination methods for the same model. The index action will use the default method and the view action will use the method with a custom query.

Based on the OOP's inheritance concept, i thought that the solution was to extend my model and override the pagination method on the extended model. So, i can call from the controller the default pagination method for the index action and the custom methods for the view action.

The question is: how can i extend my model class? Will work this ideia?

this is my model:

<?php
class Communication extends AppModel {

var $name = 'Communication';
var $displayField = 'title';

//The Associations below have been created with all possible keys, those that are not needed can be removed

var $hasMany = array(
    'Interaction' => array(
        'className' => 'Interaction',
        'foreignKey' => 'communication_id',
        'dependent' => false,
        'conditions' => '',
        'fields' => '',
        'order' => '',
        'limit' => '',
        'offset' => '',
        'exclusive' => '',
        'finderQuery' => '',
        'counterQuery' => ''
    ),
    'Star' => array(
        'className' => 'Star',
        'foreignKey' => 'communication_id',
        'dependent' => false,
        'conditions' => '',
        'fields' => '',
        'order' => '',
        'limit' => '',
        'offset' => '',
        'exclusive' => '',
        'finderQuery' => '',
        'counterQuery' => ''
    )
);

var $hasAndBelongsToMany = array(
    'Document' => array(
        'className' => 'Document',
        'joinTable' => 'communications_documents',
        'foreignKey' => 'communication_id',
        'associationForeignKey' => 'document_id',
        'unique' => true,
        'conditions' => '',
        'fields' => '',
        'order' => '',
        'limit' => '',
        'offset' => '',
        'finderQuery' => '',
        'deleteQuery' => '',
        'insertQuery' => ''
    ),
    'Event' => array(
        'className' => 'Event',
        'joinTable' => 'communications_events',
        'foreignKey' => 'communication_id',
        'associationForeignKey' => 'event_id',
        'unique' => true,
        'conditions' => '',
        'fields' => '',
        'order' => '',
        'limit' => '',
        'offset' => '',
        'finderQuery' => '',
        'deleteQuery' => '',
        'insertQuery' => ''
    ),
    'Meeting' => array(
        'className' => 'Meeting',
        'joinTable' => 'communications_meetings',
        'foreignKey' => 'communication_id',
        'associationForeignKey' => 'meeting_id',
        'unique' => true,
        'conditions' => '',
        'fields' => '',
        'order' => 'date_create DESC',
        'limit' => '',
        'offset' => '',
        'finderQuery' => '',
        'deleteQuery' => '',
        'insertQuery' => ''
    ),
    'User' => array(
        'className' => 'User',
        'joinTable' => 'communications_users',
        'foreignKey' => 'communication_id',
        'associationForeignKey' => 'user_id',
        'unique' => true,
        'conditions' => '',
        'fields' => '',
        'order' => 'name',
        'limit' => '',
        'offset' => '',
        'finderQuery' => '',
        'deleteQuery' => '',
        'insertQuery' => ''
    )
);

function getComInfos($id) {

    $this->unbindModel(array('hasAndBelongsToMany'=>array('Document','Event','Meeting')));
    $this->unbindModel(array('hasMany'=>array('Star','Interaction')));
    $communication_infos = $this->read(null, $id);

    //debug($communication_infos);

    return $communication_infos;

}

function getComLinks($id) {

    $communication_links = $this->query("
    SELECT 'documents' AS 'type', 'D' AS 'marker', d.id AS id, d.date_create AS date, du.user_id AS info_aux, d.title AS title, d.desc AS content 
    FROM communications_documents AS cd
    JOIN documents AS d ON d.id = cd.document_id
    JOIN documents_users AS du ON du.document_id = d.id
    WHERE cd.communication_id = ".$id."

    UNION

    SELECT 'events' AS 'type', 'E' AS 'marker', e.id AS id, e.date_create AS date, e.institution AS info_aux, e.title AS title, e.desc AS content
    FROM communications_events AS ce
    JOIN events AS e ON e.id = ce.event_id
    WHERE ce.communication_id =".$id."

    UNION

    SELECT 'meetings' AS 'type', 'R' AS 'marker', m.id AS id, m.date_create AS date, m.site AS info_aux, m.title AS title, m.desc AS content
    FROM communications_meetings AS cm
    JOIN meetings AS m ON m.id = cm.meeting_id
    WHERE cm.communication_id =".$id."

    UNION

    SELECT 'interactions' AS 'type', 'C' AS 'marker', i.id AS id, i.date_create AS date, i.user_id AS info_aux, i.title AS title, i.content AS content
    FROM interactions AS i
    WHERE i.communication_id =".$id."

    ORDER BY date DESC
    ");

    //debug($communication_links);

    return $communication_links;

}

}

And this is my two custom pagination method, that i need to use just to the view action:

function paginate($conditions, $fields, $order, $limit, $page = 1, $recursive = null, $extra = array()) {

    $recursive = -1;
    return $this->query("
    SELECT 'documents' AS 'type', 'D' AS 'marker', d.id AS id, d.date_create AS date, du.user_id AS info_aux, d.title AS title, d.desc AS content 
    FROM communications_documents AS cd
    JOIN documents AS d ON d.id = cd.document_id
    JOIN documents_users AS du ON du.document_id = d.id
    WHERE cd.communication_id = 137

    UNION

    SELECT 'events' AS 'type', 'E' AS 'marker', e.id AS id, e.date_create AS date, e.institution AS info_aux, e.title AS title, e.desc AS content
    FROM communications_events AS ce
    JOIN events AS e ON e.id = ce.event_id
    WHERE ce.communication_id =137

    UNION

    SELECT 'meetings' AS 'type', 'R' AS 'marker', m.id AS id, m.date_create AS date, m.site AS info_aux, m.title AS title, m.desc AS content
    FROM communications_meetings AS cm
    JOIN meetings AS m ON m.id = cm.meeting_id
    WHERE cm.communication_id = 137

    UNION

    SELECT 'interactions' AS 'type', 'C' AS 'marker', i.id AS id, i.date_create AS date, i.user_id AS info_aux, i.title AS title, i.content AS content
    FROM interactions AS i
    WHERE i.communication_id = 137

    ORDER BY date DESC
    LIMIT ".(($page-1)*$limit).", ".$limit);

}

function paginateCount($conditions = null, $recursive = 0, $extra = array()) {
    $sql = "
    SELECT 'documents' AS 'type', 'D' AS 'marker', d.id AS id, d.date_create AS date, du.user_id AS info_aux, d.title AS title, d.desc AS content 
    FROM communications_documents AS cd
    JOIN documents AS d ON d.id = cd.document_id
    JOIN documents_users AS du ON du.document_id = d.id
    WHERE cd.communication_id = 137

    UNION

    SELECT 'events' AS 'type', 'E' AS 'marker', e.id AS id, e.date_create AS date, e.institution AS info_aux, e.title AS title, e.desc AS content
    FROM communications_events AS ce
    JOIN events AS e ON e.id = ce.event_id
    WHERE ce.communication_id = 137

    UNION

    SELECT 'meetings' AS 'type', 'R' AS 'marker', m.id AS id, m.date_create AS date, m.site AS info_aux, m.title AS title, m.desc AS content
    FROM communications_meetings AS cm
    JOIN meetings AS m ON m.id = cm.meeting_id
    WHERE cm.communication_id = 137

    UNION

    SELECT 'interactions' AS 'type', 'C' AS 'marker', i.id AS id, i.date_create AS date, i.user_id AS info_aux, i.title AS title, i.content AS content
    FROM interactions AS i
    WHERE i.communication_id = 137

    ORDER BY date DESC
    ";
    $this->recursive = $recursive;
    $results = $this->query($sql);
    return count($results);
}`

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

帥小哥 2024-12-06 02:10:48

在控制器中,我将为每个模型设置一些非常通用的选项,如下所示:

    class SampleController extends AppController {
        ...
        var $paginate = array(
            'ModelName' => array( ...general options... )
        );
        ...
    }

然后在每个操作中,您可以对其进行自定义:

    ...
    function index(){
        $this->paginate = array(
            ... specific pagination options for index action ...
        );
        $this->paginate('ModelName');
    }
    ...
    function view(){
        $this->paginate = array(
            ... specific pagination options for view action ...
        );
        $this->paginate('ModelName');
    }

这样您就可以为每个操作提供自定义分页结果。

希望有帮助。

In the controller, I would set some very general options for each model, like so:

    class SampleController extends AppController {
        ...
        var $paginate = array(
            'ModelName' => array( ...general options... )
        );
        ...
    }

And then inside each action, you can customize it:

    ...
    function index(){
        $this->paginate = array(
            ... specific pagination options for index action ...
        );
        $this->paginate('ModelName');
    }
    ...
    function view(){
        $this->paginate = array(
            ... specific pagination options for view action ...
        );
        $this->paginate('ModelName');
    }

This way you can have custom pagination results for each action.

Hope that helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文