Skip to content

Instantly share code, notes, and snippets.

@anboo
Created November 22, 2017 07:51
Show Gist options
  • Save anboo/4b18a910fc463725b63e1718cd23e9bb to your computer and use it in GitHub Desktop.
Save anboo/4b18a910fc463725b63e1718cd23e9bb to your computer and use it in GitHub Desktop.
<?php
namespace BookerBundle\OData\Query;
/**
* Class AbstractQuery
*/
abstract class AbstractQuery implements QueryInterface
{
/** @return string */
abstract public function formalize();
/** @return string */
public function __toString()
{
return (string) $this->formalize();
}
}
<?php
namespace BookerBundle\OData\Query;
/**
* Class Cast
*/
class Cast extends AbstractQuery
{
/** @var string */
private $field;
/** @var string */
private $method;
/**
* Cast constructor.
* @param string $field
* @param string $method
*/
public function __construct($field, $method)
{
$this->method = $method;
$this->field = $field;
}
/**
* @return string
*/
public function formalize()
{
return sprintf('cast(%s, %s)', $this->field, $this->method);
}
}
<?php
namespace BookerBundle\OData\Query;
use BookerBundle\OData\Value\ValueInterface;
/**
* Class Eq
*/
class Eq extends AbstractQuery
{
/** @var string */
private $field;
/** @var string */
private $value;
/**
* Lt constructor.
* @param string $field
* @param ValueInterface $value
*/
public function __construct($field, ValueInterface $value)
{
$this->field = $field;
$this->value = $value;
}
/**
* @return string
*/
public function formalize()
{
return sprintf('%s eq %s', $this->field, $this->value);
}
}
<?php
namespace BookerBundle\Tests\OData\Query\Fixtures;
use BookerBundle\OData\Query\AbstractQuery;
use BookerBundle\OData\Value\ValueInterface;
class TestFilter extends AbstractQuery
{
private $field;
private $value;
public function __construct($field, ValueInterface $value)
{
$this->field = $field;
$this->value = $value;
}
public function formalize()
{
return sprintf('%s = %s', $this->field, $this->value);
}
}
<?php
namespace BookerBundle\OData\Query;
use BookerBundle\OData\Value\ValueInterface;
/**
* Class Gt
*/
class Gt extends AbstractQuery
{
/** @var string */
private $field;
/** @var string */
private $value;
/**
* Lt constructor.
* @param string $field
* @param ValueInterface $value
*/
public function __construct($field, ValueInterface $value)
{
$this->field = $field;
$this->value = $value;
}
/**
* @return string
*/
public function formalize()
{
return sprintf('%s gt %s', $this->field, $this->value);
}
}
<?php
namespace BookerBundle\OData\Query;
use BookerBundle\OData\Value\ValueInterface;
/**
* Class Lt
*/
class Lt extends AbstractQuery
{
/** @var string */
private $field;
/** @var string */
private $value;
/**
* Lt constructor.
* @param string $field
* @param ValueInterface $value
*/
public function __construct($field, ValueInterface $value)
{
$this->field = $field;
$this->value = $value;
}
/**
* @return string
*/
public function formalize()
{
return sprintf('%s lt %s', $this->field, $this->value);
}
}
<?php
namespace BookerBundle\OData\Query\Part;
use BookerBundle\OData\Query\AbstractQuery;
use BookerBundle\OData\Query\QueryInterface;
/**
* Class AndQuery
*/
class AndQuery extends AbstractQuery
{
/** @var QueryInterface */
private $queries;
/** @param QueryInterface[] ...$queries */
public function __construct(... $queries)
{
$this->queries = $queries;
}
/**
* @return string
*/
public function formalize()
{
$query = implode(' and ', $this->queries);
return count($this->queries) > 1 ? '('.$query.')' : $query;
}
}
<?php
namespace BookerBundle\OData\Query\Part;
use BookerBundle\OData\Query\AbstractQuery;
use BookerBundle\OData\Query\QueryInterface;
/**
* Class AndQuery
*/
class OrQuery extends AbstractQuery
{
/** @var QueryInterface */
private $queries;
/** @param QueryInterface[] ...$queries */
public function __construct(... $queries)
{
$this->queries = $queries;
}
/**
* @return string
*/
public function formalize()
{
$query = implode(' or ', $this->queries);
return count($this->queries) > 1 ? '('.$query.')' : $query;
}
}
<?php
namespace BookerBundle\OData\Query;
/**
* Interface QueryInterface
*/
interface QueryInterface
{
/** @return string */
public function formalize();
}
<?php
namespace BookerBundle\Tests\OData\Query;
use BookerBundle\OData\Query\Eq;
use BookerBundle\OData\Query\Gt;
use BookerBundle\OData\Query\Lt;
use BookerBundle\OData\Query\Part\AndQuery;
use BookerBundle\OData\Query\Part\OrQuery;
use BookerBundle\OData\Value\Integer;
use BookerBundle\OData\Value\Text;
use BookerBundle\Tests\OData\Query\Fixtures\TestFilter;
class VariantTest extends \PHPUnit_Framework_TestCase
{
public function testFormalizeAnd()
{
$andQuery = new AndQuery(
new TestFilter('a', new Text('and')),
new TestFilter('b', new Text('or')),
new AndQuery(
new TestFilter('c', new Text('\'')),
new TestFilter('z', new Text('/'))
)
);
$this->assertEquals('(a = \'and\' and b = \'or\' and (c = \'\'\' and z = \'/\'))', (string)$andQuery);
}
public function testFormalizeOr()
{
$andQuery = new OrQuery(
new Lt('Нетто', new Integer('6000')),
new Gt('Брутто', new Integer('3000')),
new AndQuery(
new Eq('НоменклатурнаяГруппа', new Text('Услуги')),
new Eq('Description', new Text('Перевозки'))
)
);
$this->assertEquals('(Нетто lt 6000 or Брутто gt 3000 or (НоменклатурнаяГруппа eq \'Услуги\' and Description eq \'Перевозки\'))', (string)$andQuery);
}
}
<?php
namespace BookerBundle\OData\Value;
use BookerBundle\Exception\FatalIntegrationException;
use BookerBundle\Exception\NotValidDataException;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Validation;
/**
* Class AbstractValue
*/
abstract class AbstractValue implements ValueInterface
{
/**
* @var mixed
*/
protected $value;
/**
* AbstractValue constructor.
*
* @throws NotValidDataException
*
* @param mixed $value
*/
public function __construct($value)
{
$this->value = $value;
$this->validate();
}
/** @return array|Constraint */
abstract public function rules();
/** @return string */
abstract public function formalize();
/**
* @throws FatalIntegrationException
* @throws NotValidDataException
*/
public function validate()
{
if (!$rules = $this->rules()) {
return;
}
$validator = Validation::createValidator();
if ($violations = $validator->validate($this->value, $rules)) {
$preparedMsg[] = 'Validation errors: ';
foreach ($violations as $violation) {
$preparedMsg[] = $violation->getPropertyPath().' '.$violation->getMessage();
}
throw new NotValidDataException(implode(', ', $preparedMsg));
}
}
/**
* @return string
*/
public function __toString()
{
return (string) $this->formalize() ?: '';
}
}
<?php
namespace BookerBundle\OData\Value;
/**
* Class Integer
*/
class Integer extends AbstractValue
{
/**
* @return array
*/
public function rules()
{
return [];
}
/**
* @return int
*/
public function formalize()
{
return (int) $this->value;
}
}
<?php
namespace BookerBundle\OData\Value;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Class ReferenceKey
*/
class ReferenceKey extends AbstractValue
{
/** @return array */
public function rules()
{
return [
new Assert\NotBlank(),
new Assert\Uuid(),
];
}
/** @return string */
public function formalize()
{
return 'guid\''.$this->value.'\'';
}
}
<?php
namespace BookerBundle\OData\Value;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Class Text
*/
class Text extends AbstractValue
{
/** @var bool */
private $validateNotBlank;
/**
* Text constructor.
* @param string $value
* @param bool $validateNotBlank
*/
public function __construct($value, $validateNotBlank = false)
{
$this->validateNotBlank = $validateNotBlank;
parent::__construct($value);
}
/**
* @return array|Assert\NotBlank
*/
public function rules()
{
if ($this->validateNotBlank) {
return new Assert\NotBlank();
}
return [];
}
/**
* @return mixed
*/
public function formalize()
{
return '\''.$this->value.'\'';
}
}
<?php
namespace BookerBundle\OData\Value;
/**
* Interface ValueInterface
*/
interface ValueInterface
{
/**
* @return void
*/
public function validate();
/**
* @return string
*/
public function formalize();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment