hevertonfreitas/filter_results

从搜索表单生成查找 CakePHP 2.3+ 中方法的条件

安装: 77

依赖项: 0

建议者: 0

安全: 0

星级: 0

关注者: 2

分支: 16

类型:cakephp-plugin

v1.0.0 2016-11-10 18:43 UTC

This package is auto-updated.

Last update: 2024-09-12 07:01:54 UTC


README

从搜索表单生成 conditions 以在 CakePHP 2.3+ 中查找方法。

兼容性

与 CakePHP 2.3 + Paginate (组件) 兼容

2.3 版本中的更改

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

安装

下载插件并将其内容放置在 /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,Paginate 将自动配置。
  • 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));

准备好了!我们有一个可以根据名称筛选用户并兼容 Paginate 的字段。

而且更多,筛选结果自动分解筛选值以获得更好的结果。例如:如果我们通过 'Pedro Elsner' 进行筛选,条件将是:WHERE ((User.name LIKE '%Pedro%') AND (User.name LIKE '%Elsner%'))

分解设置

对于 LIKENOT LIKE 操作符的 explode 选项始终在筛选结果设置中启用。但您如何知道,您可以在控制器声明中禁用它。如果您这样做,则可以仅针对指定的筛选器启用 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中包含'informe' '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));

现在,您首先可以选择字段(过滤器结果表将自动列出字段),然后通知运算符和过滤器所需的价值。

将会有需要自定义字段和运算符进行选择的情况。例如,让我们只保留字段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/)

感谢