gildonei/filter_results

CakePHP 插件,用于向控制器和视图添加 PRG 过滤器

安装: 133

依赖者: 0

建议者: 0

安全: 0

星标: 3

关注者: 1

分支: 16

类型:cakephp-plugin

1.0 2020-07-28 16:58 UTC

This package is auto-updated.

Last update: 2024-09-08 01:29:05 UTC


README

从搜索表单生成 CakePHP 2.3+ 的 conditions 以供 find 方法使用。

兼容性

兼容 CakePHP 2.3 + Paginate (组件)

2.3 版本变更

  • FilterResultsComponent 已更改为 FilterComponent;
  • FilterFormHelper 已更改为 SearchHelper;
  • 重构所有结构方法;

安装

Composer

composer require gildonei/filter_results:"2.3.x-dev"

手动下载

下载插件并将其内容放置在 /app/Plugin/FilterResults 或其他 CakePHP 插件目录中。

激活

通过添加文件 /app/Config/bootstrap.php 来激活插件

CakePlugin::load('FilterResults');

配置

编辑文件 /app/AppController.php

var $components = array(
    'FilterResults.Filter' => array(
        'auto' => array(
            'paginate' => false,
            'explode'  => true,  // recommended
        ),
        'explode' => array(
            'character'   => ' ',
            'concatenate' => 'AND',
        )
    )
);

var $helpers = array(
    'FilterResults.Search' => array(
        'operators' => array(
            'LIKE'       => 'containing',
            'NOT LIKE'   => 'not containing',
            'LIKE BEGIN' => 'starting with',
            'LIKE END'   => 'ending with',
            '='  => 'equal to',
            '!=' => 'different',
            '>'  => 'greater than',
            '>=' => 'greater or equal to',
            '<'  => 'less than',
            '<=' => 'less or equal to'
        )
    )
);

设置参数

  • auto->paginate: 如果设置为 TRUE,将自动配置分页。
  • auto->explode: 如果设置为 TRUE,则将过滤值通过 explode->character 分解,并通过 explode->concatenate 连接。

使用组件

以下示例将基于以下数据库构建

CREATE TABLE groups (
    id INT UNSIGNED NOT NULL AUTO_INCREMENT,
    name VARCHAR(200) NOT NULL,
    PRIMARY KEY(id),
    UNIQUE(name)
) ENGINE=INNODB;

CREATE TABLE users (
    id INT UNSIGNED NOT NULL AUTO_INCREMENT,
    group_id INT UNSIGNED NOT NULL,
    name VARCHAR(200) NOT NULL,
    username VARCHAR(20) NOT NULL,
    active TINYINT(1) NOT NULL DEFAULT 1,
    PRIMARY KEY(id),
    FOREIGN KEY(group_id) REFERENCES groups(id),
    UNIQUE(username)
) ENGINE=INNODB;

INSERT INTO groups(name) VALUES('Admin');
INSERT INTO groups(name) VALUES('Guest');

INSERT INTO users(group_id, name, username) VALUES(1, 'Pedro Elsner', 'pelsner');
INSERT INTO users(group_id, name, username) VALUES(1, 'Petter Morato', 'pmorato');
INSERT INTO users(group_id, name, username, active) VALUES(2, 'Lucas Pedro Mariano Elsner', 'lpmelsner', 0);
INSERT INTO users(group_id, name, username, active) VALUES(2, 'Rebeca Moraes Silva', 'rebeca_moraes', 0);
INSERT INTO users(group_id, name, username, active) VALUES(2, 'Silvia Morato Moraes', 'silvia22', 0);

简单过滤

在生成 Bake 界面后,我们在网格(表格)上放置一个过滤器,通过姓名(User.name)搜索用户。所以让我们设置控制器和视图,如下所示

文件 /app/Controller/UsersController.php

function index() {
    
    // Add filter
    $this->Filter->addFilters(
        array(
            'filter1' => array(
                'User.name' => array(
                    'operator' => 'LIKE',
                    'value' => array(
                        'before' => '%', // optional
                        'after'  => '%'  // optional
                    )
                )
            )
        )
    );

    $this->Filter->setPaginate('order', 'User.name ASC'); // optional
    $this->Filter->setPaginate('limit', 10);              // optional

    // Define conditions
    $this->Filter->setPaginate('conditions', $this->Filter->getConditions());

    $this->User->recursive = 0;
    $this->set('users', $this->paginate());
}

这里的设置很简单:我们创建了一个名为 filter1 的过滤器,它将使用字段 User.name。此过滤器使用 LIKE 操作符,并在要过滤的内容前后添加 %

现在我们只需在表格顶部创建表单。

文件 /app/View/Users/index.ctp

echo $this->Search->create();
echo $this->Search->input('filter1');
echo $this->Search->end(__('Filter', true));

准备好了!我们有一个可以按姓名过滤用户并兼容分页的字段。

还有更多,过滤结果会自动分解过滤值以获得更好的结果。例如:如果我们通过 'Pedro Elsner' 过滤,条件将是:WHERE ((User.name LIKE '%Pedro%') AND (User.name LIKE '%Elsner%'))

分解设置

对于操作符 LIKENOT LIKEexplode 选项始终在过滤结果设置中启用。但您知道,您可以在控制器中声明组件时禁用它。如果这样做,您可以只为指定的过滤器启用 explode 函数。

$this->Filter->addFilter(
    array(
        'filter1' => array(
            'User.name' => array(
                'operator' => 'LIKE',
                'explode'  => true
            )
        )
    )
);

也可以为每个过滤器更改分解参数。

$this->Filter->addFilter(
    array(
        'filter1' => array(
            'User.name' => array(
                'operator' => 'LIKE',
                'explode' => array(
                    'character'   = '-',
                    'concatenate' = 'OR'
                )
            )
        )
    )
);

您还可以使用分解函数与任何操作符(如 =)一起使用。请参见

$this->Filter->addFilter(
    array(
        'filter1' => array(
            'User.name' => array(
                'operator' => '=',
                'explode'  => true
            )
        )
    )
);

简单过滤 + 组合规则

现在让我们在过滤器 filter1 中创建另一个规则。我们想要通过名称(User.name)或用户名(User.username)过滤。

然后只需更改我们的控制器

文件 /app/Controller/UsersController.php

$this->Filter->addFilters(
    array(
        'filter1' => array(
            'OR' => array(
                'User.name'     => array('operator' => 'LIKE'),
                'User.username' => array('operator' => 'LIKE')
            )
        )
    )
);

OR 规则也可以是 ANDNOT

注意:如果您定义了多个条件而没有具体的规则,插件将自动理解它们之间的关系为 AND

简单过滤 + 固定规则

假设现在我们的过滤器 filter1 在被通知的情况下,应该根据名称(User.name并且仅过滤活动用户。

文件 /app/Controller/UsersController.php

$this->Filter->addFilters(
    array(
        'filter1' => array(
            'User.name'   => array('operator' => 'LIKE'),
            'User.active' => array('value'    => '1')
        )
    )
);

过滤聚合

过滤结果会自动按 AND 规则连接所有过滤条件。请看下面的示例,如果在 filter1 中输入 'Pedro',在 filter2 中输入 'elsner',我们将得到以下条件:WHERE (User.name LIKE '%Pedro%') AND (User.usernname LIKE '%elsner%')

$this->Filter->addFilters(
    array(
        'filter1' => array(
            'User.name' => array('operator' => 'LIKE')
        )
        'filter2' => array(
            'User.username' => array('operator' => 'LIKE')
        )
    )
);

注意:我们也可以通过 ORNOT 规则连接过滤条件。

现在,我们将改变示例,通过 OR 规则连接 filter1filter2,并且如果 filter1 不为空,则仅过滤活动用户。因此,我们将得到以下条件:WHERE ((User.name LIKE '%Pedro%') AND (User.active = 1)) OR (User.usernname LIKE '%elsner%')

$this->Filter->addFilters(
    array(
        'OR' => array(
            'filter1' => array(
                'User.name'   => array('operator' => 'LIKE'),
                'User.active' => array('value'    => '1')
            )
            'filter2' => array(
                'User.username' => array('operator' => 'LIKE')
            )
        )
    )
);

选择过滤器

让我们改变我们的过滤器。除了按名称过滤外,我们还可以通过一个期望的选择字段按用户组(Group.name)过滤。

文件 /app/Controller/UsersController.php

function index() {
    
    // Add filter
    $this->Filter->addFilters(
        array(
            'filter1' => array(
                'User.name' => array('operator' => 'LIKE')
            ),
            'filter2' => array(
                'User.group_id' => array(
                    'select' => $this->Filter->select('Grupo', $this->User->Group->find('list'))
                )
            )
        )
    );
    
    // Define conditions
    $this->Filter->setPaginate('conditions', $this->Filter->getConditions());

    $this->User->recursive = 0;
    $this->set('users', $this->paginate());
}

文件 /app/View/Users/index.ctp

echo $this->Search->create();
echo $this->Search->input('filter2', array('class' => 'select-box'));
echo $this->Search->input('filter1');
echo $this->Search->end(__('Filter', true));

准备好了!使用和滥用您想要的过滤器。

为了明确起见,请看这张图片。这里是我们产品的查看界面,您可以根据颜色、尺寸、重量、材料和产品名称进行过滤。

高级过滤器

在某些情况下,我们可能想要不同的东西,例如,我们想要用户选择字段和执行过滤操作的运算符。

文件 /app/Controller/UsersController.php

function index() {
    
    // Add filter
    $this->Filter->addFilters('filter1');
    
    // Define conditions
    $this->Filter->setPaginate('conditions', $this->Filter->getConditions());

    $this->User->recursive = 0;
    $this->set('users', $this->paginate());
}

注意:请注意,这次我们过滤 filter1 没有任何参数。这是因为规则是在视图中选择的。

文件 /app/View/Users/index.ctp

echo $this->Search->create();
echo $this->Search->selectFields('filter1', null, array('class' => 'select-box'));
echo $this->Search->selectOperators('filter1');
echo $this->Search->input('filter1');
echo $this->Search->end(__('Filter', true));

现在,您可以首先选择字段(Filter Results 表格会自动列出字段),然后输入运算符和过滤条件的期望值。

在某些情况下,您可能需要自定义选择字段和运算符。例如,我们可以只留下 User.idUser.nameUser.username 字段用于选择,以及 LIKE= 运算符。

为此,我们只需更改视图。

文件 /app/View/Users/index.ctp

echo $this->Search->create();

echo $this->Search->selectFields('filter1',
        array(
            'User.id'       => __('ID', true),
            'User.name'     => __('Name', true),
            'User.username' => __('Username', true),
        ),
        array(
            'class' => 'select-box'
        )
    );

echo $this->Search->selectOperators('filter1',
        array(
            'LIKE' => __('containing', true),
            '='    => __('equal to', true)
        )
    );

echo $this->Search->input('filter1');
echo $this->Search->end(__('Filter', true));

运算符

过滤结果具有预定义的运算符,以下列出您可以在高级过滤器中使用的所有选项。

array(
    'LIKE'       => __('containing', true),
    'NOT LIKE'   => __('not containing', true),
    'LIKE BEGIN' => __('starting with', true),
    'LIKE END'   => __('ending with', true),
    '='  => __('equal to', true),
    '!=' => __('different', true),
    '>'  => __('greater than', true),
    '>=' => __('greater or equal to', true),
    '<'  => __('less than', true),
    '<=' => __('less or equal to', true)
);

介于

要使用运算符 BETWEEN

$this->Filter->addFilters(
    array(
        'filter1' => array(
            'User.id' => array(
                'operator'    => 'BETWEEN',
                'between' => array(
                    'text' => __(' and ', true)
                )
            )
        )
    )
);

HABTM 关系

默认情况下,CakePHP HABTM 关系会进行多个查询然后合并结果到一个 array 中。您可能已经注意到这一点,但如果没有,请在 HABTM 关系中的 find() 时检查调试窗口。

要过滤这些关系,我们需要创建一些“黑客”来生成单个 CakePHP select,这样插件就可以使用简单的 where 命令过滤结果。

有关创建“黑客”的所有必要信息和说明,您可以在这篇葡萄牙语教程中找到:http://pedroelsner.com/2012/09/pesquisando-em-associacoes-habtm-no-cakephp/

或者用谷歌翻译英文:http://translate.google.com.br/translate?sl=pt&tl=en&js=n&prev=_t&hl=pt-BR&ie=UTF-8&layout=2&eotf=1&u=http%3A%2F%2Fpedroelsner.com%2F2012%2F09%2Fpesquisando-em-associacoes-habtm-no-cakephp%2F

版权和许可证

版权 2012,Pedro Elsner (http://pedroelsner.com/)

在 Creative Commons 3.0 许可下 (http://creativecommons.org/licenses/by/3.0/)

感谢