krzysztof-gzocha / searcher-bundle
搜索器和 Symfony2 框架之间的桥梁
Requires
- php: >=5.5.9
- krzysztof-gzocha/searcher: ~4.0.0
- symfony/framework-bundle: >=2.3
Requires (Dev)
- knplabs/knp-components: >=1.2.4
- knplabs/knp-paginator-bundle: ^2.2.0
- phpdocumentor/reflection-docblock: 2.0.4
- phpunit/phpunit: ^4.8
Suggests
- doctrine/mongodb-odm: to use with Doctrine's ODM
- doctrine/orm: to use with Doctrine's ORM
- knplabs/knp-paginator-bundle: to use with Knp Paginator bundle
- symfony/form: to use with Symfony Form component
README
SearcherBundle

此组件提供了 Symfony 和 Searcher 之间的集成
什么是 Searcher?
Searcher 是一个完全解耦于任何框架的库,旨在简化基于传递的条件的复杂搜索查询的构建。它的基本思想是将每个搜索 过滤器 分割成单独的类。无论您要搜索什么:MySQL 中的实体、MongoDB 或只是文件。支持的 PHP 版本:>=5.5、7 和 HHVM。
完整文档
完整文档可在 http://searcher.rtfd.io/ 找到
安装
您可以通过 composer 安装此组件
composer require krzysztof-gzocha/searcher-bundle
并别忘了在您的 AppKernel 中注册它
public function registerBundles() { $bundles = array( /** Your bundles **/ new KGzocha\Bundle\SearcherBundle\KGzochaSearcherBundle(), ); /** rest of the code **/ }
示例用法
配置
在配置文件中,我们将指定 people
上下文的最小配置。
您可以在 此处 找到配置引用的完整示例
k_gzocha_searcher: contexts: people: context: service: your_searching_context_service_id criteria: - { class: \AgeRangeCriteria, name: age_range} - { service: some_service_id, name: other_criteria } builders: - { class: \AgeRangeCriteriaBuilder, name: age_range } - { service: other_service_id, name: my_criteria_builder }
如您所见,您可以将一切指定为简单的类或您自己的服务。此配置将创建我们的 people
上下文并创建所有必需的服务(构建集合、标准集合、搜索器和上下文),因此您可以访问它们并使用它们。例如,要从控制器访问 Searcher 实例,您只需
$this->get('k_gzocha_searcher.people.searcher');
或访问 age_range
标准
$this->get('k_gzocha_searcher.people.criteria.age_range');
或访问 my_criteria_builder
$this->get('k_gzocha_searcher.people.builder.my_criteria_builder');
我认为命名约定很容易理解。在此示例中,您只需定义一个自己的服务 - 搜索上下文服务,其 ID 在配置中指定(your_searching_context_service_id
)。您可以这样做
your_searching_context_service_id: class: KGzocha\Searcher\Context\QueryBuilderSearchingContext arguments: - @my_search.query_builder # Or any QueryBuilder service
代码
对于此示例,我们将使用简单的 AgeRangeCriteria(在 此处 描述),但当然您可以使用您自己的类或服务。
class AgeRangeCriteria implements CriteriaInterface { private $minimalAge; private $maximalAge; /** * Only required method. */ public function shouldBeApplied() { return null !== $this->minimalAge && null !== $this->maximalAge; } // getters, setters, what ever }
我们还将使用 AgeRangeCriteriaBuilder(在 此处 描述),但当然您可以使用您自己的类或服务。
class AgeRangeCriteriaBuilder implements FilterImposerInterface { public function buildCriteria( CriteriaInterface $criteria, SearchingContextInterface $searchingContext ) { $searchingContext ->getQueryBuilder() ->andWhere('e.age >= :minimalAge') ->andWhere('e.age <= :maximalAge') ->setParameter('minimalAge', $criteria->getMinimalAge()) ->setParameter('maximalAge', $criteria->getMaximalAge()); } public function allowsCriteria( CriteriaInterface $criteria ) { // No need to check shouldBeApplied(). Searcher will check it return $criteria instanceof AgeRangeCriteria; } /** * You can skip this method if you will extend from QueryBuilderFilterImposer. */ public function supportsSearchingContext( SearchingContextInterface $searchingContext ) { return $searchingContext instanceof \KGzocha\Searcher\Context\Doctrine\QueryBuilderSearchingContext; } }
表单(可选)
现在我们可以创建示例表单。表单将允许Symfony处理从请求中获取和验证我们的标准。这一步是可选的,您不必从请求中获取标准。您可以根据自己的意愿这样做。
use KGzocha\Bundle\SearcherBundle\Form\SearchForm; class MySearchForm extends SearchForm { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('minimalAge', 'integer', [ 'property_path' => $this->getPath('ageRange', 'minimalAge'), ]) ->add('maximalAge', 'integer', [ 'property_path' => $this->getPath('ageRange', 'maximalAge'), ]) /** and any other fields.. **/ ->add('<PARAM NAME IN REQUEST>', '<ANY FORM TYPE>', [ 'property_path' => $this->getPath( '<CRITERIA NAME FROM CONFIG>', '<CRITERIA ATTRIBUTE NAME>' ), ]); } }
控制器
public function searchAction(Request $request) { $form = $this->createForm( new MySearchForm(), $this->get('k_gzocha_searcher.people.criteria_collection') ); $form->handleRequest($request); // Now we can check if form is valid $searcher = $this->get('k_gzocha_searcher.people.searcher'); $results = $searcher->search($form->getData()); // Yay, we have our results! // $results is instance of ResultCollection by default. Read for 'wrapper_class' }
包装类
默认情况下,SearcherBundle会将Searcher包装成WrappedResultsSearcher
,它将返回一个具有getResults()
方法的ResultCollection
,该方法将返回您的结果集合。当然,ResultCollection
本身是可遍历的,因此您可以在foreach
循环中使用它。在您不确定您的QueryBuilder
将返回数组还是可遍历对象的情况下,这种特性非常有用。尝试遍历返回null
的对象将导致错误。ResultCollection将防止这种情况发生。如果您想更改包装类,则需要在与搜索器相关的配置中指定wrapper_class
。当然,有时您可能只想让Searcher返回一个整数或其他东西,那么您可能不想包装您的Searcher。为了做到这一点,只需将wrapper_class
指定为null
即可。
链式搜索
Searcher库允许您执行链式搜索,您也可以使用这个包。您需要做的就是正确配置它并在配置文件中获取ChainSearch
服务。
示例链式搜索配置
k_gzocha_searcher: chains: people_log: # optional chain_searcher: class: \KGzocha\Searcher\Chain\ChainSearch service: chain_searcher_service transformers: - name: peopleIdToLogId service: transfomer_service class: \TransformerClass # at least two are required cells: - name: peopleCell searcher: people transformer: peopleIdToLogId class: \KGzocha\Searcher\Chain\Cell # optional service: cell_service_1 # optional - name: logCell searcher: logs transformer: ~ # If empty EndTransformer will be used class: \KGzocha\Searcher\Chain\Cell # optional service: cell_service_2 # optional
有了上述配置,您可以轻松地获取所有服务,如下所示:
$this->get('k_gzocha_searcher.chains.people_log.searcher'); // ChainSearch service $this->get('k_gzocha_searcher.chains.people_log.cell.peopleCell'); // #1 Cell service $this->get('k_gzocha_searcher.chains.people_log.cell.logCell'); // #2 Cell service $this->get('k_gzocha_searcher.chains.people_log.transformer.peopleToLogId'); // Transformer service
贡献
所有想法和pull request都受到欢迎和赞赏。请随时通过issues分享您的想法。
运行测试的命令:composer test
。