天狼座/suggest-bundle

symfony2 suggest (自动完成) 扩展包

v3.0.2 2023-05-02 10:18 UTC

README

关于

这是一个用于使流行的Select2组件作为标准实体文档选择字段在Symfony表单上的直接替换的Symfony扩展包。

此扩展包的主要功能是,选择列表通过远程ajax调用检索。

1. 安装

sirian/suggest-bundle包添加到composer.json文件的require部分。

$ composer require sirian/suggest-bundle

将SuggestBundle添加到应用程序的核心

<?php
public function registerBundles()
{
    $bundles = array(
        // ...
        new Sirian\SuggestBundle\SirianSuggestBundle(),
        // ...
    );
    ...
}

2. 配置

安装扩展包后,确保您将此路由添加到路由中

# app/config/routing.yml

_sirian_suggest:
    resource: "@SirianSuggestBundle/Resources/config/routing.yml"
    prefix:   /suggest

并为表单选择默认小部件(取决于您使用的select2版本)。可以是select2_v3select2_v4。您还可以为SuggestType::class指定其他默认表单选项

# app/config/config.yml

...
sirian_suggest:
    form_options:
        widget: select2_v4
        attr:
            placeholder: "Search..."

3. 配置建议者

3.1. Doctrine ODM 文档建议者

# app/config/config.yml

...
sirian_suggest:
    odm:
        category:
            class: "MainBundle:Category"
            property: name
        
        user:
            class: "MainBundle:User"
            property: username
            search:
                email: ~
                username: ~

3.2. Doctrine ORM 实体建议者

# app/config/config.yml

...
sirian_suggest:
    orm:
        category:
            class: "MainBundle:Category"
            property: name
        
        user:
            class: "MainBundle:User"
            property: username
            search:
                email: ~
                username: ~

3.3. 自定义建议者

当您需要一些额外的逻辑时,您可以创建自己的建议者。例如,让我们创建AdminSuggester,它只为具有ROLE_ADMIN角色的用户提供建议。

<?php

namespace App\MainBundle\Suggest;

use App\MainBundle\Document\User;
use Doctrine\Common\Persistence\ManagerRegistry;
use Sirian\SuggestBundle\Suggest\DocumentSuggester;
use Sirian\SuggestBundle\Suggest\Item;
use Sirian\SuggestBundle\Suggest\SuggestQuery;

class AdminSuggester extends DocumentSuggester
{
    public function __construct(ManagerRegistry $registry)
    {
        $options = [
            'class' => User::class,
            'id_property' => 'id',
            'property' => 'username',
            'search' => [
                'name' => DocumentSuggester::SEARCH_MIDDLE,
                'username' => DocumentSuggester::SEARCH_MIDDLE,
                'email' => DocumentSuggester::SEARCH_MIDDLE
            ]
        ];

        parent::__construct($registry, $options);
    }

    protected function createSuggestQueryBuilder(SuggestQuery $query)
    {
        $qb = parent::createSuggestQueryBuilder($query);
        
        $qb->field('roles')->equals('ROLE_ADMIN');
        
        return $qb;
    }

    protected function transformObject($user)
    {
        $item = new Item();
        $item->id = $user->getId();
        $item->text = $user->getName() . ' ( ' . $user->getUsername() . ', ' . $user->getEmail() . ')';

        return $item;
    }
}

使用services.yml定义带有sirian_suggest.suggester标记的服务

    app.suggester.admin:
        class: App\MainBundle\Suggest\AdminSuggester
        arguments: ["@doctrine_mongodb"]
        tags: 
            - {name: 'sirian_suggest.suggester', alias: 'admin'}

别名admin将在SuggestType::classsuggester选项和/suggest/admin URL模式中使用。

4. 使用

现在您可以在表单中使用配置好的建议者

$formBuilder->add('category', SuggestType::class, [
    'suggester' => 'category'
])

5. 安全

您可以通过保护URL模式来限制对建议者的访问

security:
   ...
   access_control:
        ...
        - { path: ^/suggest/category, roles: ROLE_USER }
        - { path: ^/suggest, roles: ROLE_ADMIN }

6. 向建议者传递额外选项

有时您需要向Suggester传递额外的参数。

6.1. 静态额外选项

让我们从简单的例子开始。您有brandsmodels,您只想显示一个特定品牌的模型。创建类ModelSuggester

<?php

namespace App\MainBundle\Suggest;

use App\MainBundle\Document\Model;
use Doctrine\Common\Persistence\ManagerRegistry;
use Sirian\SuggestBundle\Suggest\DocumentSuggester;
use Sirian\SuggestBundle\Suggest\SuggestQuery;

class ModelSuggester extends DocumentSuggester
{
    public function __construct(ManagerRegistry $registry)
    {
        $options = [
            'class' => Model::class,
            'id_property' => 'id',
            'property' => 'name',
        ];

        parent::__construct($registry, $options);
    }

    protected function createSuggestQueryBuilder(SuggestQuery $query)
    {
        $qb = parent::createSuggestQueryBuilder($query);
        
        $brandId = $query->extra['brand_id'];
        
        $qb->field('brand')->equals($brandId);
        
        return $qb;
    }
}

定义服务

    app.suggester.model:
        class: App\MainBundle\Suggest\ModelSuggester
        arguments: ["@doctrine_mongodb"]
        tags: 
            - {name: 'sirian_suggest.suggester', alias: 'model'}

并将extra选项添加到表单选项中

$formBuilder->add('model', SuggestType::class, [
    'suggester' => 'model',
    'extra' => [
        'brand_id' => 123
    ]
])

6.2. 动态额外选项

现在让我们看一个例子,您有两个建议字段brandmodel,在第二个选择框中,您想显示所选品牌的模型。

您需要创建ModelSuggester并定义建议者服务(如前所述)。

然后自定义表单小部件,将brand_id额外选项传递给建议者

{% block _form_model_widget %}
    {{ form_widget(form) }}
    
    <script>
        (function () {
            // get prepared options for select2
            var options = $('#{{ id }}').data('suggest-options');
            
            // update ajax.data option 
            options.ajax.data = function (term, page) {
                return {
                    q: term,
                    page: page,
                    extra: {
                        brand_id: $('#form_brand').val() // get brand_id from another select 
                    }
                }
            }
        }());
    </script>
{% endblock %}