Skip to content

Commit

Permalink
Releasing version 4.0 #90 #92 (#95)
Browse files Browse the repository at this point in the history
* Collection improvements (#94)

* Added common AbstractCollection

* CR Fixes

* Migrating ResultCollection

* Improvements in chain searching

* CellCollection introduced

* Added missing PHPDocs

* Added PHPDoc and documentation

* Composer improvements

* Documentation typo fix

* PSR-2 code style fixes. Scrolling Searching Context

* Lowest version of ruflin/elastica upgraded to 2.1

* Added example QueryBuilderSearchingContext definition

* Added dummy example of KnpPaginatorAdapter configuration and usage

* Added warning about changing SearchingContext class
  • Loading branch information
krzysztof-gzocha authored Sep 23, 2016
1 parent d14d29d commit 0e0537e
Show file tree
Hide file tree
Showing 51 changed files with 779 additions and 353 deletions.
7 changes: 4 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"name": "krzysztof-gzocha/searcher",
"description": "Searcher is a framework-agnostic search query builder. Search queries are written using Criterias and can be run against MySQL, MongoDB or even files.",
"description": "Searcher is a framework-agnostic search query builder. Search queries are written using Criterias and can be run against MySQL, MongoDB, ElasticSearch or even files.",
"keywords": ["search", "searcher", "agnostic", "query", "builder", "elastic", "mongo", "doctrine", "criteria"],
"license": "MIT",
"type": "library",
"homepage": "http://searcher.rtfd.io",
Expand Down Expand Up @@ -38,15 +39,15 @@
"phpmd/phpmd": "^2.4.3",
"doctrine/orm": "^2.5.0",
"doctrine/mongodb-odm": "^1.0.0",
"ruflin/elastica": ">=2.0.0",
"ruflin/elastica": ">=2.1.0",
"symfony/finder": "^2.0.5",
"phpdocumentor/reflection-docblock": "2.0.4"
},
"scripts": {
"test": ["phpunit tests/"],
"coverage": ["phpunit tests/ --coverage-clover=coverage.clover"],
"coverage-html": ["phpunit tests/ --coverage-html coverage/", "open coverage/index.html"],
"cs-fix": ["php-cs-fixer fix src/", "php-cs-fixer fix tests/"],
"cs-fix": ["php-cs-fixer fix src/ --level=psr2", "php-cs-fixer fix tests/ --level=psr2"],
"phpmd": ["phpmd src/ text cleancode,codesize,controversial,design,unusedcode --exclude tests/"],
"ci": ["@coverage", "@phpmd"]
}
Expand Down
18 changes: 12 additions & 6 deletions docs/chain-search.rst
Original file line number Diff line number Diff line change
Expand Up @@ -85,18 +85,19 @@ Now we are ready and we can create an instance of ``ChainSearch`` and populate i

.. code:: php
$cells = [
new Cell(
$cells = new CellCollection([
// Optionally you can specify a name for ease of fetching sub-results
'users' => new Cell(
$userSearcher,
new Transformer(),
'users' // Just an optional name
),
new Cell(
'statistics' => new Cell(
$statisticSearcher,
new EndTransformer(), // We don't want to go further
'statistics'
),
];
]);
$chainSearch = new ChainSearch($cells);
$results = $chainSearch->search($entryCriteria);
Expand All @@ -109,3 +110,8 @@ Now, the variable ``$results`` will hold a ``ResultCollection`` with two element
'users' => [/** results from $userSearcher **/],
'statistics' => [/** results from $statisticSearcher **/],
]
.. warning::

When trying to use CellCollection will less than 2 elements InvalidArgumentException will be thrown, because
there is no sense in using chain search with just 1 cell.
91 changes: 91 additions & 0 deletions docs/integration/symfony.rst
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,35 @@ Those services will be accessible for you. Here is a list of them:

You can found complete configuration reference in `here <https://github.com/krzysztof-gzocha/searcher-bundle/blob/master/src/KGzocha/Bundle/SearcherBundle/configReference.yml>`_.

Example searching context definition
-------------------------------------

Below code will show an example definition of ``QueryBuilderSearchingContext`` for Doctrine ORM.
The code is assuming that service ``entity.repository`` actually exists and you want to use alias ``alias`` for it.

.. code:: yaml
services:
project_doctor.entity.query_builder:
class: Doctrine\ORM\QueryBuilder
factory: ['@entity.repository', 'createQueryBuilder']
arguments:
- 'alias'
project_doctor.entity.searching_context:
class: 'KGzocha\Searcher\Context\Doctrine\QueryBuilderSearchingContext'
arguments:
- '@project_doctor.entity.query_builder'
With definition like that we can now use it in SearcherBundle configuration as follows:

.. code:: yaml
k_gzocha_searcher:
contexts:
people:
context:
service: project_doctor.entity.searching_context
Hydration
----------
Expand Down Expand Up @@ -179,3 +208,65 @@ simple action inside a controller:
By default Searcher is wrapped with WrappedResultsSearcher, so results will be actually an instance of ResultCollection.
If you would like to have pure Searcher then you have to specify searcher.wrapper_class in the config as null
or create searcher service yourself and specify searcher.service.

Using KnpPaginatorAdapter
--------------------------

Searcher bundle has already implemented class for KnpPaginatorBundle, but you need to configure it before you use it.
One of the methods to do it is to create a Configurator service and use it within adapters service definition.
Code below is an dummy example of such configurator:

.. code:: php
class KnpPaginatorAdapterConfigurator
{
/**
* @param KnpPaginatorAdapter $paginatorAdapter
*
* @return KnpPaginatorAdapter
*/
public static function configure(KnpPaginatorAdapter $paginatorAdapter)
{
// You need to fetch those values in the way you want
$page = 2;
$limit = 23;
$paginatorAdapter->setLimit($limit);
$paginatorAdapter->setPage($page);
return $paginatorAdapter;
}
}
Then we need to define such service:

.. code:: yaml
# Original KnpPaginatorAdapter
project_doctor.knp_paginator_searching_context:
class: 'KGzocha\Bundle\SearcherBundle\Context\KnpPaginatorAdapter'
arguments:
- '@knp_paginator'
- '@project_doctor.searching_context'
# Configured KnpPaginatorAdapter - use this one as SearchingContext
project_doctor.configured_knp_paginator:
class: 'KGzocha\Bundle\SearcherBundle\Context\KnpPaginatorAdapter'
factory: ['\KnpPaginatorConfigurator', 'configure']
arguments:
- '@project_doctor.knp_paginator_searching_context'
And finally we can use configured KnpPaginatorAdapter service as a searching context in our searching process:

.. code:: yaml
k_gzocha_searcher:
contexts:
doctor:
context:
service: project_doctor.configured_knp_paginator
.. warning::

Remember that you are changing class of SearchingContext to KnpPaginatorAdapter, so you might need to update
yours criteria builders, because they might not support such change.
2 changes: 1 addition & 1 deletion docs/introduction.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Searcher
What?
-----------------
*Searcher* is a framework-agnostic search query builder.
Search queries are written using Criterias and can be run againstMySQL, MongoDB or even files.
Search queries are written using Criterias and can be run against MySQL, MongoDB or even files.
Supported PHP versions: >=5.4, 7 and HHVM.
You can find searcher in two most important places:

Expand Down
136 changes: 136 additions & 0 deletions src/KGzocha/Searcher/AbstractCollection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
<?php

namespace KGzocha\Searcher;

/**
* @author Krzysztof Gzocha <[email protected]>
*/
abstract class AbstractCollection implements \Countable, \IteratorAggregate
{
/**
* @var array
*/
private $items;

/**
* @param \Traversable|array $items
*/
public function __construct($items = [])
{
$this->items = [];
$this->isTraversable($items);
$this->checkItems($items);

$this->items = $items;
}

/**
* @param object $item
*
* @return bool
*/
abstract protected function isItemValid($item);

/**
* {@inheritdoc}
*/
public function getIterator()
{
return new \ArrayIterator($this->items);
}

/**
* {@inheritdoc}
*/
public function count()
{
return count($this->items);
}

/**
* @param mixed $item
*
* @return $this
*/
protected function addItem($item)
{
$this->items[] = $item;

return $this;
}

/**
* @param string $name
* @param mixed $item
*
* @return $this
*/
protected function addNamedItem($name, $item)
{
$this->items[$name] = $item;

return $this;
}

/**
* @return array
*/
protected function getItems()
{
return $this->items;
}

/**
* @param string $name
*
* @return mixed|null
*/
protected function getNamedItem($name)
{
if (array_key_exists($name, $this->items)) {
return $this->items[$name];
}

return null;
}

/**
* @param mixed $items
*
* @throws \InvalidArgumentException
*/
private function isTraversable($items)
{
if (is_array($items)) {
return;
}

if ($items instanceof \Traversable) {
return;
}

throw new \InvalidArgumentException(sprintf(
'Argument passed to collection %s needs to be an array or traversable object',
get_class($this)
));
}

/**
* @param array|\Traversable $items
*
* @throws \InvalidArgumentException
*/
private function checkItems($items)
{
foreach ($items as $item) {
if ($this->isItemValid($item)) {
continue;
}

throw new \InvalidArgumentException(sprintf(
'At least one item in collection "%s" is invalid.',
get_class($this)
));
}
}
}
20 changes: 2 additions & 18 deletions src/KGzocha/Searcher/Chain/Cell.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* It represents single cell in the chain. It holds sub-searcher and it's transformer, which will
* transform results from it's sub-searcher to CriteriaCollection that can be used in next sub-search.
* Name of the cell will be used as the key of end result collection to allow finding all the results.
*
*
* @author Krzysztof Gzocha <[email protected]>
*/
class Cell implements CellInterface
Expand All @@ -23,24 +23,16 @@ class Cell implements CellInterface
*/
private $transformer;

/**
* @var string|null
*/
private $name;

/**
* @param SearcherInterface $searcher
* @param TransformerInterface $transformer
* @param string $name
*/
public function __construct(
SearcherInterface $searcher,
TransformerInterface $transformer,
$name = null
TransformerInterface $transformer
) {
$this->searcher = $searcher;
$this->transformer = $transformer;
$this->name = $name;
}

/**
Expand All @@ -59,14 +51,6 @@ public function getTransformer()
return $this->transformer;
}

/**
* @return null|string
*/
public function getName()
{
return $this->name;
}

/**
* @return bool
*/
Expand Down
5 changes: 0 additions & 5 deletions src/KGzocha/Searcher/Chain/CellInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,6 @@ public function getSearcher();
*/
public function getTransformer();

/**
* @return null|string
*/
public function getName();

/**
* @return bool
*/
Expand Down
Loading

0 comments on commit 0e0537e

Please sign in to comment.