Skip to content

Commit

Permalink
Implement Result Transformations
Browse files Browse the repository at this point in the history
  • Loading branch information
merk committed Mar 26, 2016
1 parent b9a158e commit 2867782
Show file tree
Hide file tree
Showing 6 changed files with 217 additions and 2 deletions.
29 changes: 27 additions & 2 deletions lib/Elastica/Result.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ class Result
*/
protected $_hit = array();

/**
* If the result can be transformed, this stores the transformed result.
*
* @var mixed
*/
private $_transformed;

/**
* Constructs a single results object.
*
Expand Down Expand Up @@ -70,6 +77,14 @@ public function getId()
return $this->getParam('_id');
}

/**
* @return mixed
*/
public function getTransformed()
{
return $this->_transformed;
}

/**
* Returns the type of the result.
*
Expand Down Expand Up @@ -191,11 +206,11 @@ public function getExplanation()
/**
* Returns Document.
*
* @return \Elastica\Document
* @return Document
*/
public function getDocument()
{
$doc = new \Elastica\Document();
$doc = new Document();
$doc->setData($this->getSource());
$hit = $this->getHit();
if ($this->hasParam('_source')) {
Expand All @@ -215,6 +230,16 @@ public function getDocument()
return $doc;
}

/**
* Sets the transformed object derived from the result.
*
* @param mixed $transformed
*/
public function setTransformed($transformed)
{
$this->_transformed = $transformed;
}

/**
* Magic function to directly access keys inside the result.
*
Expand Down
49 changes: 49 additions & 0 deletions lib/Elastica/ResultSet/TransformingBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

namespace Elastica\ResultSet;

use Elastica\Query;
use Elastica\Response;
use Elastica\ResultSet;
use Elastica\Transformer\TransformerInterface;

class TransformingBuilder implements BuilderInterface
{
/**
* @var BuilderInterface
*/
private $builder;

/**
* @var TransformerInterface
*/
private $transformer;

/**
* @param BuilderInterface $builder
* @param TransformerInterface $transformer
*/
public function __construct(BuilderInterface $builder, TransformerInterface $transformer)
{
$this->builder = $builder;
$this->transformer = $transformer;
}

/**
* Runs any registered transformers on the ResultSet before
* returning it, allowing the transformers to inject additional
* data into each Result.
*
* @param Response $response
* @param Query $query
* @return ResultSet
*/
public function buildResultSet(Response $response, Query $query)
{
$resultSet = $this->builder->buildResultSet($response, $query);

$this->transformer->fromElasticSearch($resultSet);

return $resultSet;
}
}
31 changes: 31 additions & 0 deletions lib/Elastica/Transformer/ChainTransformer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Elastica\Transformer;

use Elastica\ResultSet;

class ChainTransformer implements TransformerInterface
{
/**
* @var TransformerInterface[]
*/
private $transformers;

/**
* @param TransformerInterface[] $transformers
*/
public function __construct($transformers)
{
$this->transformers = $transformers;
}

/**
* @inheritdoc
*/
public function fromElasticSearch(ResultSet $resultSet)
{
foreach ($this->transformers as $transformer) {
$transformer->fromElasticSearch($resultSet);
}
}
}
18 changes: 18 additions & 0 deletions lib/Elastica/Transformer/TransformerInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace Elastica\Transformer;

use Elastica\ResultSet;

interface TransformerInterface
{
/**
* Iterates over a ResultSet setting transformed objects against Results if available.
*
* If a result has no transformed object or has a transformed object already set, the transformer
* should leave the Result alone.
*
* @param ResultSet $resultSet
*/
public function fromElasticSearch(ResultSet $resultSet);
}
59 changes: 59 additions & 0 deletions test/lib/Elastica/Test/ResultSet/TransformingBuilderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

namespace Elastica\Test\ResultSet;

use Elastica\Query;
use Elastica\Response;
use Elastica\ResultSet;
use Elastica\ResultSet\BuilderInterface;
use Elastica\ResultSet\TransformingBuilder;
use Elastica\Transformer\TransformerInterface;
use Elastica\Test\Base as BaseTest;

/**
* @group unit
*/
class TransformingBuilderTest extends BaseTest
{
/**
* @var TransformingBuilder
*/
private $builder;

/**
* @var BuilderInterface
*/
private $innerBuilder;

/**
* @var TransformerInterface
*/
private $transformer;

protected function setUp()
{
parent::setUp();

$this->innerBuilder = $this->getMock('Elastica\\ResultSet\\BuilderInterface');
$this->transformer = $this->getMock('Elastica\\Transformer\\TransformerInterface');

$this->builder = new TransformingBuilder($this->innerBuilder, $this->transformer);
}

public function testTransforms()
{
$response = new Response('');
$query = new Query();
$resultSet = new ResultSet($response, $query, []);

$this->innerBuilder->expects($this->once())
->method('buildResultSet')
->with($response, $query)
->willReturn($resultSet);
$this->transformer->expects($this->once())
->method('fromElasticSearch')
->with($resultSet);

$this->builder->buildResultSet($response, $query);
}
}
33 changes: 33 additions & 0 deletions test/lib/Elastica/Test/Transformer/ChainTransformerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace Elastica\Test\Transformer;

use Elastica\Query;
use Elastica\Response;
use Elastica\ResultSet;
use Elastica\Test\Base as BaseTest;
use Elastica\Transformer\ChainTransformer;

/**
* @group unit
*/
class ChainTransformerTest extends BaseTest
{
public function testTransformer()
{
$transformer = new ChainTransformer([
$transformer1 = $this->getMock('Elastica\Transformer\TransformerInterface'),
$transformer2 = $this->getMock('Elastica\Transformer\TransformerInterface')
]);
$resultSet = new ResultSet(new Response(''), new Query(), []);

$transformer1->expects($this->once())
->method('fromElasticSearch')
->with($resultSet);
$transformer2->expects($this->once())
->method('fromElasticSearch')
->with($resultSet);

$transformer->fromElasticSearch($resultSet);
}
}

0 comments on commit 2867782

Please sign in to comment.