Skip to content

Commit

Permalink
Merge pull request #1 from Lansoweb/php8
Browse files Browse the repository at this point in the history
add php 8.0 support and minimum 7.4
  • Loading branch information
Lansoweb authored May 7, 2021
2 parents ebbafc0 + 9822f8c commit bcc8b02
Show file tree
Hide file tree
Showing 6 changed files with 201 additions and 122 deletions.
17 changes: 9 additions & 8 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,18 @@
}
],
"require": {
"php": "^7.1",
"php": "^7.4 | ^8.0",
"ext-json": "*",
"psr/http-message": "^1.0"
},
"require-dev": {
"laminas/laminas-db": "^2.9",
"laminas/laminas-coding-standard": "^1.0",
"squizlabs/php_codesniffer": "^2.7",
"phpstan/phpstan": "^0.9.2",
"phpunit/phpunit": "^7.1",
"laminas/laminas-diactoros": "^1.7",
"php-coveralls/php-coveralls": "^2.0"
"squizlabs/php_codesniffer": "^3.6",
"phpstan/phpstan": "^0.12.85",
"phpunit/phpunit": "^9.5",
"laminas/laminas-diactoros": "^2.0",
"php-coveralls/php-coveralls": "^2.0",
"doctrine/coding-standard": "^9.0"
},
"autoload": {
"psr-4": {
Expand All @@ -39,7 +40,7 @@
"@phpstan",
"@test"
],
"cs-check": "phpcs",
"cs-check": "phpcs -s",
"cs-fix": "phpcbf",
"phpstan": "phpstan analyse -l max src",
"test": "phpunit --colors=always",
Expand Down
34 changes: 32 additions & 2 deletions phpcs.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,36 @@
<?xml version="1.0"?>
<ruleset name="Zend Framework Coding Standard">
<rule ref="./vendor/laminas/laminas-coding-standard/ruleset.xml"/>
<ruleset name="App coding standard">
<description>App coding standard</description>

<!-- display progress -->
<arg value="p"/>
<arg name="colors"/>

<!-- inherit rules from: -->
<rule ref="Doctrine">
<exclude name="SlevomatCodingStandard.TypeHints.ReturnTypeHint.MissingTraversableTypeHintSpecification"/>
<exclude name="SlevomatCodingStandard.TypeHints.PropertyTypeHint.MissingTraversableTypeHintSpecification"/>
<exclude name="SlevomatCodingStandard.TypeHints.PropertyTypeHint.MissingAnyTypeHint"/>
<exclude name="SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingTraversableTypeHintSpecification"/>
<!-- <exclude name="SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingAnyTypeHint"/>-->
<exclude name="SlevomatCodingStandard.Classes.SuperfluousInterfaceNaming.SuperfluousSuffix"/>
<exclude name="SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingTraversableParameterTypeHintSpecification"/>
<exclude name="SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingTraversablePropertyTypeHintSpecification"/>
<exclude name="SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingTraversableReturnTypeHintSpecification"/>
<!-- <exclude name="Squiz.Commenting.FunctionComment.WrongStyle"/>-->
</rule>
<rule ref="Generic.Arrays.DisallowLongArraySyntax"/>
<rule ref="Squiz.WhiteSpace.SuperfluousWhitespace"/>
<rule ref="Generic.Files.LineLength">
<properties>
<property name="lineLimit" value="160"/>
<property name="absoluteLineLimit" value="180"/>
</properties>
</rule>

<rule ref="Generic.CodeAnalysis.EmptyStatement.DetectedCatch">
<severity>5</severity>
</rule>

<!-- Paths to check -->
<file>src</file>
Expand Down
55 changes: 33 additions & 22 deletions src/BuilderInterface.php
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
<?php

declare(strict_types=1);

namespace Los\Uql;

use Laminas\Db\Sql\Select;
use Psr\Http\Message\ServerRequestInterface;

interface BuilderInterface
{
// Logical
const OP_NOT = '$not';
const OP_IN = '$in';
const OP_NOT_IN = '$nin';
const OP_LIKE = '$like';
const OP_OR = '$or';
const OP_AND = '$and';
const OP_NULL = '$null';
const OP_NOT_NULL = '$nnull';

const OP_LOGIC = [
public const OP_NOT = '$not';
public const OP_IN = '$in';
public const OP_NOT_IN = '$nin';
public const OP_LIKE = '$like';
public const OP_OR = '$or';
public const OP_AND = '$and';
public const OP_NULL = '$null';
public const OP_NOT_NULL = '$nnull';

public const OP_LOGIC = [
self::OP_NOT,
self::OP_IN,
self::OP_NOT_IN,
Expand All @@ -29,28 +31,37 @@ interface BuilderInterface
];

// Conditional
const OP_GREATER = '$gt';
const OP_GREATER_EQUAL = '$gte';
const OP_LESS = '$lt';
const OP_LESS_EQUAL = '$lte';
const OP_BETWEEN = '$bt';
public const OP_GREATER = '$gt';
public const OP_GREATER_EQUAL = '$gte';
public const OP_LESS = '$lt';
public const OP_LESS_EQUAL = '$lte';
public const OP_BETWEEN = '$bt';

const OP_CONDITIONAL = [
public const OP_CONDITIONAL = [
self::OP_GREATER,
self::OP_GREATER_EQUAL,
self::OP_LESS,
self::OP_LESS_EQUAL,
self::OP_BETWEEN
self::OP_BETWEEN,
];

// Hints
const HINT_SORT = '$sort';
const HINT_LIMIT = '$limit';
const HINT_SKIP = '$skip';
public const HINT_SORT = '$sort';
public const HINT_LIMIT = '$limit';
public const HINT_SKIP = '$skip';

const HINT_ORDER_ASC = ['asc', 'ASC', 1, '1'];
const HINT_ORDER_DESC = ['desc', 'DESC', -1, '-1'];
public const HINT_ORDER_ASC = ['asc', 'ASC', 1, '1'];
public const HINT_ORDER_DESC = ['desc', 'DESC', -1, '-1'];

/**
* @phpcs:disable SlevomatCodingStandard.TypeHints.ReturnTypeHint.MissingNativeTypeHint
*
* @return Select|array
*/
public function fromRequest(ServerRequestInterface $request);

/**
* @return Select|array
*/
public function fromParams(array $query, array $hint = []);
}
120 changes: 78 additions & 42 deletions src/ElasticSearchBuilder.php
Original file line number Diff line number Diff line change
@@ -1,27 +1,36 @@
<?php

declare(strict_types=1);

namespace Los\Uql;

use Psr\Http\Message\ServerRequestInterface;

use function array_merge;
use function in_array;
use function is_array;
use function json_decode;
use function key;
use function reset;
use function str_replace;

final class ElasticSearchBuilder implements BuilderInterface
{
private $queryName;
private $hintName;
private $params = [];
private string $queryName;
private string $hintName;
private array $params = [];

public function __construct(string $queryName = 'q', string $hintName = 'h')
{
$this->queryName = $queryName;
$this->hintName = $hintName;
$this->hintName = $hintName;
}

public function fromRequest(ServerRequestInterface $request) : array
public function fromRequest(ServerRequestInterface $request): array
{
$queryParams = $request->getQueryParams();
$query = json_decode($queryParams['q'] ?? '{}', true);
$hint = json_decode($queryParams['h'] ?? '{}', true);
$query = json_decode($queryParams[$this->queryName] ?? '{}', true);
$hint = json_decode($queryParams[$this->hintName] ?? '{}', true);

if (! is_array($query) || ! is_array($hint)) {
throw new Exception\MalformedException('Invalid query or hint');
Expand All @@ -30,7 +39,7 @@ public function fromRequest(ServerRequestInterface $request) : array
return $this->fromParams($query, $hint);
}

public function fromParams(array $query, array $hint = []) : array
public function fromParams(array $query, array $hint = []): array
{
foreach ($query as $key => $value) {
$this->params = array_merge($this->params, $this->parseQuery($key, $value));
Expand All @@ -41,54 +50,64 @@ public function fromParams(array $query, array $hint = []) : array
$hintParams = array_merge($hintParams, $this->parseHint($key, $value));
}

$result = [ 'body' => [ 'query' => ['constant_score' => [ 'filter' => [ 'bool' => $this->params ] ] ] ] ];
$result = ['body' => ['query' => ['constant_score' => ['filter' => ['bool' => $this->params]]]]];

if (!empty($hintParams)) {
if (! empty($hintParams)) {
$result = array_merge($result, $hintParams);
}

return $result;
}

private function parseQuery(string $key, $value, bool $withoutOperator = false) : array
/**
* @phpcs:disable SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint
*
* @param mixed $value
*/
private function parseQuery(string $key, $value, bool $withoutOperator = false): array
{
if ($key === BuilderInterface::OP_NULL) {
$params = [ 'exists' => [ 'field' => $value ] ];
return $withoutOperator ? $params : [ 'must_not' => $params ];
$params = ['exists' => ['field' => $value]];

return $withoutOperator ? $params : ['must_not' => $params];
}

if ($key === BuilderInterface::OP_NOT_NULL) {
$params = [ 'field' => $value ];
return $withoutOperator ? $params : [ 'exists' => $params ];
$params = ['field' => $value];

return $withoutOperator ? $params : ['exists' => $params];
}

if (! is_array($value)) {
$params = [ 'term' => [ $key => $value ] ];
return $withoutOperator ? $params : [ 'must' => $params ];
$params = ['term' => [$key => $value]];

return $withoutOperator ? $params : ['must' => $params];
}

if ($key === BuilderInterface::OP_OR) {
$params = [];
foreach ($value as $query) {
$value2 = reset($query);
$key2 = key($query);
$value2 = reset($query);
$key2 = key($query);
$params[] = $this->parseQuery($key2, $value2, true);
}
return $withoutOperator ? $params : [ 'should' => $params ];

return $withoutOperator ? $params : ['should' => $params];
}

if ($key === BuilderInterface::OP_AND) {
$params = [];
foreach ($value as $query) {
$value2 = reset($query);
$key2 = key($query);
$value2 = reset($query);
$key2 = key($query);
$params[] = $this->parseQuery($key2, $value2, true);
}
return $withoutOperator ? $params : [ 'must' => $params ];

return $withoutOperator ? $params : ['must' => $params];
}

$opValue = reset($value);
$op = key($value);
$op = key($value);

if (in_array($op, BuilderInterface::OP_LOGIC)) {
return $this->parseLogic($key, $op, $opValue);
Expand All @@ -101,65 +120,82 @@ private function parseQuery(string $key, $value, bool $withoutOperator = false)
return [];
}

private function parseLogic(string $key, $op, $value) : array
/**
* @phpcs:disable SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint
*
* @param mixed $value
*/
private function parseLogic(string $key, string $op, $value): array
{
if ($op === BuilderInterface::OP_NOT) {
return [ 'must_not' => [ 'term' => [ $key => $value ] ] ];
return ['must_not' => ['term' => [$key => $value]]];
}

if ($op === BuilderInterface::OP_IN) {
return [ 'filter' => [ 'terms' => [ $key => $value ] ] ];
return ['filter' => ['terms' => [$key => $value]]];
}

if ($op === BuilderInterface::OP_NOT_IN) {
return [ 'must_not' => [ 'terms' => [ $key => $value ] ] ];
return ['must_not' => ['terms' => [$key => $value]]];
}

// At this point, should only be BuilderInterface::OP_LIKE . No if to keep PHPUnit happy
return [ 'wildcard' => [ $key => str_replace('%', '*', $value) ] ];
return ['wildcard' => [$key => str_replace('%', '*', $value)]];
}

private function parseConditional(string $key, $op, $value) : array
/**
* @phpcs:disable SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint
*
* @param mixed $value
*/
private function parseConditional(string $key, string $op, $value): array
{
if ($op === BuilderInterface::OP_GREATER) {
return [ 'filter' => [ 'range' => [ $key => [ 'gt' => $value ] ] ] ];
return ['filter' => ['range' => [$key => ['gt' => $value]]]];
}

if ($op === BuilderInterface::OP_GREATER_EQUAL) {
return [ 'filter' => [ 'range' => [ $key => [ 'gte' => $value ] ] ] ];
return ['filter' => ['range' => [$key => ['gte' => $value]]]];
}

if ($op === BuilderInterface::OP_LESS) {
return [ 'filter' => [ 'range' => [ $key => [ 'lt' => $value ] ] ] ];
return ['filter' => ['range' => [$key => ['lt' => $value]]]];
}

if ($op === BuilderInterface::OP_LESS_EQUAL) {
return [ 'filter' => [ 'range' => [ $key => [ 'lte' => $value ] ] ] ];
return ['filter' => ['range' => [$key => ['lte' => $value]]]];
}

// At this point, should only be BuilderInterface::OP_BETWEEN . No if to keep PHPUnit happy
return [ 'filter' => [ 'range' => [ $key => [ 'gt' => $value[0], 'lt' => $value[1] ] ] ] ];
return ['filter' => ['range' => [$key => ['gt' => $value[0], 'lt' => $value[1]]]]];
}

private function parseHint($key, $value) : array
/**
* @phpcs:disable SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint
*
* @param mixed $value
*/
private function parseHint(string $key, $value): array
{
if ($key === BuilderInterface::HINT_SORT) {
if (! is_array($value)) {
return [ 'sort' => [ $value ] ];
return ['sort' => [$value]];
}

$params = [];
foreach ($value as $field => $order) {
$order = in_array($order, BuilderInterface::HINT_ORDER_ASC) ? 'asc' : 'desc';
$params[] = [ $field => [ 'order' => $order ] ];
$order = in_array($order, BuilderInterface::HINT_ORDER_ASC) ? 'asc' : 'desc';
$params[] = [$field => ['order' => $order]];
}
return [ 'sort' => $params ];

return ['sort' => $params];
}

if ($key === BuilderInterface::HINT_LIMIT) {
return [ 'size' => $value ];
return ['size' => $value];
}

// At this point, should only be BuilderInterface::HINT_SKIP . No if to keep PHPUnit happy
return [ 'from' => $value ];
return ['from' => $value];
}
}
Loading

0 comments on commit bcc8b02

Please sign in to comment.