mirror of
https://github.com/JBDevLabs/ezmigrationbundle.git
synced 2026-03-24 08:52:16 +01:00
139 lines
5.0 KiB
PHP
139 lines
5.0 KiB
PHP
<?php
|
|
|
|
namespace Kaliop\eZMigrationBundle\Core\Matcher;
|
|
|
|
use Kaliop\eZMigrationBundle\API\MatcherInterface;
|
|
use Kaliop\eZMigrationBundle\API\EnumerableMatcherInterface;
|
|
use Kaliop\eZMigrationBundle\API\Exception\InvalidMatchResultsNumberException;
|
|
use Kaliop\eZMigrationBundle\API\Exception\InvalidMatchConditionsException;
|
|
|
|
abstract class AbstractMatcher implements MatcherInterface, EnumerableMatcherInterface
|
|
{
|
|
/** @var string[] $allowedConditions the keywords we allow to be used for matching on*/
|
|
protected $allowedConditions = array();
|
|
/** @var string $returns user-readable name of the type of object returned */
|
|
protected $returns;
|
|
/** @var int $maxConditions the maximum number of conditions we allow to match on for a single match request */
|
|
protected $maxConditions = 1;
|
|
/** @var int $minConditions the minimum number of conditions we allow to match on for a single match request. It could be replaced with an array of mandatory conditions, really... */
|
|
protected $minConditions = 1;
|
|
|
|
/**
|
|
* @param array $conditions
|
|
* @throws InvalidMatchConditionsException
|
|
*/
|
|
protected function validateConditions(array $conditions)
|
|
{
|
|
if ($this->minConditions > 0 && count($conditions) < $this->minConditions) {
|
|
throw new InvalidMatchConditionsException($this->returns . ' can not be matched because the matching conditions are empty');
|
|
}
|
|
|
|
if ($this->maxConditions > 0 && count($conditions) > $this->maxConditions) {
|
|
throw new InvalidMatchConditionsException($this->returns . " can not be matched because multiple matching conditions are specified. Only {$this->maxConditions} condition(s) are supported");
|
|
}
|
|
|
|
foreach ($conditions as $key => $value) {
|
|
if (!in_array((string)$key, $this->allowedConditions)) {
|
|
throw new InvalidMatchConditionsException($this->returns . " can not be matched because matching condition '$key' is not supported. Supported conditions are: " .
|
|
implode(', ', $this->allowedConditions));
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return string[]
|
|
*/
|
|
public function listAllowedConditions()
|
|
{
|
|
return $this->allowedConditions;
|
|
}
|
|
|
|
/**
|
|
* @param $conditionsArray
|
|
* @return array|\ArrayObject
|
|
* @throws InvalidMatchConditionsException
|
|
*/
|
|
protected function matchAnd($conditionsArray)
|
|
{
|
|
/// @todo introduce proper re-validation of all child conditions
|
|
if (!is_array($conditionsArray) || !count($conditionsArray)) {
|
|
throw new InvalidMatchConditionsException($this->returns . " can not be matched because no matching conditions found for 'and' clause.");
|
|
}
|
|
|
|
$class = null;
|
|
foreach ($conditionsArray as $conditions) {
|
|
$out = $this->match($conditions);
|
|
if ($out instanceof \ArrayObject) {
|
|
$class = get_class($out);
|
|
$out = $out->getArrayCopy();
|
|
}
|
|
if (!isset($results)) {
|
|
$results = $out;
|
|
} else {
|
|
$results = array_intersect_key($results, $out);
|
|
}
|
|
}
|
|
|
|
if ($class) {
|
|
$results = new $class($results);
|
|
}
|
|
|
|
return $results;
|
|
}
|
|
|
|
/**
|
|
* @param $conditionsArray
|
|
* @return array
|
|
* @throws InvalidMatchConditionsException
|
|
*/
|
|
protected function matchOr($conditionsArray)
|
|
{
|
|
/// @todo introduce proper re-validation of all child conditions
|
|
if (!is_array($conditionsArray) || !count($conditionsArray)) {
|
|
throw new InvalidMatchConditionsException($this->returns . " can not be matched because no matching conditions found for 'or' clause.");
|
|
}
|
|
|
|
$class = null;
|
|
$results = array();
|
|
foreach ($conditionsArray as $conditions) {
|
|
$out = $this->match($conditions);
|
|
if ($out instanceof \ArrayObject) {
|
|
$class = get_class($out);
|
|
$out = $out->getArrayCopy();
|
|
}
|
|
$results = array_replace($results, $out);
|
|
}
|
|
|
|
if ($class) {
|
|
$results = new $class($results);
|
|
}
|
|
|
|
return $results;
|
|
}
|
|
|
|
/**
|
|
* @param array $conditions
|
|
* @return mixed
|
|
* @throws InvalidMatchConditionsException
|
|
* @throws InvalidMatchResultsNumberException
|
|
*/
|
|
public function matchOne(array $conditions)
|
|
{
|
|
$results = $this->match($conditions)->getIterator();
|
|
$count = count($results);
|
|
if ($count !== 1) {
|
|
throw new InvalidMatchResultsNumberException("Found $count " . $this->returns . " when expected exactly only one to match the conditions");
|
|
}
|
|
reset($results);
|
|
|
|
return $results->current();
|
|
}
|
|
|
|
/**
|
|
* @param array $conditions
|
|
* @return array|\ArrayObject the keys must be a unique identifier of the matched entities
|
|
* @throws \Kaliop\eZMigrationBundle\API\Exception\InvalidMatchConditionsException
|
|
*/
|
|
abstract public function match(array $conditions);
|
|
}
|