Skip to content

Commit 3a77b00

Browse files
committed
POC formatter for combine condition
1 parent 266fab9 commit 3a77b00

14 files changed

+246
-65
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,13 @@ The library allows you to override the default operators and/or to provide new o
9898
- Finally, pass the `OperatorPool` object in the construct of the `ConditionManager` class.
9999

100100
*Eg: In the following example, we override the default comparators with ours and add a new one.*
101+
101102
```php
102103
$operatorPool = new \LogicTree\Operator\OperatorPool();
103104

104105
$operatorPool->addOperator(
105106
\LogicTree\Operator\OperatorType::Logical,
106-
\LogicTree\Operator\Logical\AndOperator::CODE,
107+
\LogicTree\Operator\Logical\LogicalOperatorConverter::CODE,
107108
new \My\Class\AndOperator()
108109
);
109110
$operatorPool->addOperator(

examples/index.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@
66

77
require_once dirname(__DIR__) . '/vendor/autoload.php';
88

9+
use LogicTree\Formatter\ConverterInterface;
10+
use LogicTree\Formatter\NaturalFormatter;
911
use LogicTree\LogicTreeFacade;
1012
use LogicTree\Node\Combine;
1113
use LogicTree\Node\Condition;
1214
use LogicTree\Operator\OperatorInterface;
13-
use LogicTree\Operator\OperatorPool;
1415
use LogicTree\Operator\OperatorType;
1516

1617
/**
@@ -29,6 +30,14 @@ public function execute(...$expressions): bool
2930
}
3031
}
3132

33+
class CustomOpConverter implements ConverterInterface
34+
{
35+
public function convert(...$expressions): string
36+
{
37+
return 'SUM(' . implode(', ', $expressions) . ') > 5';
38+
}
39+
}
40+
3241
/**
3342
* USE CASES
3443
*/
@@ -45,3 +54,8 @@ public function execute(...$expressions): bool
4554

4655
// Execute combine conditions
4756
var_dump($logicTreeFacade->executeCombineConditions($logicTree, $dataSource));
57+
58+
$formatter = new NaturalFormatter();
59+
$formatter->register('custom_op', new CustomOpConverter());
60+
echo '<hr>';
61+
echo $formatter->format($logicTree, $dataSource);
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php declare(strict_types=1);
2+
/**
3+
* Copyright © Thomas Klein, All rights reserved.
4+
* See LICENSE bundled with this library for license details.
5+
*/
6+
7+
namespace LogicTree\Formatter;
8+
9+
/**
10+
* @api
11+
*/
12+
interface ConverterInterface
13+
{
14+
public function convert(mixed ...$expressions): string;
15+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php declare(strict_types=1);
2+
/**
3+
* Copyright © Thomas Klein, All rights reserved.
4+
* See LICENSE bundled with this library for license details.
5+
*/
6+
7+
namespace LogicTree\Formatter;
8+
9+
use LogicTree\DataSource;
10+
use LogicTree\Node\NodeInterface;
11+
12+
/**
13+
* @api
14+
*/
15+
interface FormatterInterface
16+
{
17+
public function format(NodeInterface $node, DataSource $dataSource): string;
18+
19+
public function register(string $operator, ConverterInterface $converter): void;
20+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php declare(strict_types=1);
2+
/**
3+
* Copyright © Thomas Klein, All rights reserved.
4+
* See LICENSE bundled with this library for license details.
5+
*/
6+
7+
namespace LogicTree\Formatter\Natural\Comparator;
8+
9+
use InvalidArgumentException;
10+
use LogicTree\Formatter\ConverterInterface;
11+
12+
use function var_export;
13+
14+
final class CompareListConverter implements ConverterInterface
15+
{
16+
public function __construct(private string $comparator) {}
17+
18+
public function convert(mixed ...$expressions): string
19+
{
20+
$count = count($expressions);
21+
22+
if ($count !== 2) {
23+
throw new InvalidArgumentException('2 expressions expected, ' . $count . ' given.');
24+
}
25+
26+
[$expr1, $expr2] = $expressions;
27+
28+
return var_export($expr1, true) . ' ' . $this->comparator . ' (' . var_export($expr2, true) . ')';
29+
}
30+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php declare(strict_types=1);
2+
/**
3+
* Copyright © Thomas Klein, All rights reserved.
4+
* See LICENSE bundled with this library for license details.
5+
*/
6+
7+
namespace LogicTree\Formatter\Natural\Comparator;
8+
9+
use InvalidArgumentException;
10+
use LogicTree\Formatter\ConverterInterface;
11+
12+
use function var_export;
13+
14+
final class CompareOneConverter implements ConverterInterface
15+
{
16+
public function __construct(private string $comparator) {}
17+
18+
public function convert(mixed ...$expressions): string
19+
{
20+
$count = count($expressions);
21+
22+
if ($count !== 1) {
23+
throw new InvalidArgumentException('1 expression expected, ' . $count . ' given.');
24+
}
25+
26+
return var_export($expressions[0], true) . ' ' . $this->comparator;
27+
}
28+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php declare(strict_types=1);
2+
/**
3+
* Copyright © Thomas Klein, All rights reserved.
4+
* See LICENSE bundled with this library for license details.
5+
*/
6+
7+
namespace LogicTree\Formatter\Natural\Comparator;
8+
9+
use InvalidArgumentException;
10+
use LogicTree\Formatter\ConverterInterface;
11+
12+
use function var_export;
13+
14+
final class CompareTwoConverter implements ConverterInterface
15+
{
16+
public function __construct(private string $comparator) {}
17+
18+
public function convert(mixed ...$expressions): string
19+
{
20+
$count = count($expressions);
21+
22+
if ($count !== 2) {
23+
throw new InvalidArgumentException('2 expressions expected, ' . $count . ' given.');
24+
}
25+
26+
return var_export($expressions[0], true) . ' ' . $this->comparator . ' ' . var_export($expressions[1], true);
27+
}
28+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php declare(strict_types=1);
2+
/**
3+
* Copyright © Thomas Klein, All rights reserved.
4+
* See LICENSE bundled with this library for license details.
5+
*/
6+
7+
namespace LogicTree\Formatter\Natural\Logical;
8+
9+
use LogicTree\Formatter\ConverterInterface;
10+
11+
use function implode;
12+
13+
final class LogicalOperatorConverter implements ConverterInterface
14+
{
15+
public function __construct(private string $symbol) {}
16+
17+
public function convert(mixed ...$expressions): string
18+
{
19+
return '(' . implode(' ' . $this->symbol . ' ', $expressions) . ')';
20+
}
21+
}

src/Formatter/NaturalFormatter.php

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<?php declare(strict_types=1);
2+
/**
3+
* Copyright © Thomas Klein, All rights reserved.
4+
* See LICENSE bundled with this library for license details.
5+
*/
6+
7+
namespace LogicTree\Formatter;
8+
9+
use LogicTree\DataSource;
10+
use LogicTree\Formatter\Natural\Comparator\CompareListConverter;
11+
use LogicTree\Formatter\Natural\Comparator\CompareOneConverter;
12+
use LogicTree\Formatter\Natural\Comparator\CompareTwoConverter;
13+
use LogicTree\Formatter\Natural\Logical\LogicalOperatorConverter;
14+
use LogicTree\Node\CombineInterface;
15+
use LogicTree\Node\ConditionInterface;
16+
use LogicTree\Node\NodeInterface;
17+
18+
use function array_map;
19+
20+
final class NaturalFormatter implements FormatterInterface
21+
{
22+
/**
23+
* @var ConverterInterface[]
24+
*/
25+
private array $converters = [];
26+
27+
public function __construct()
28+
{
29+
$this->register('empty', new CompareOneConverter('IS EMPTY'));
30+
$this->register('eq', new CompareTwoConverter('=='));
31+
$this->register('gteq', new CompareTwoConverter('>='));
32+
$this->register('gt', new CompareTwoConverter('>'));
33+
$this->register('iden', new CompareTwoConverter('==='));
34+
$this->register('iniden', new CompareTwoConverter('IN STRICT'));
35+
$this->register('in', new CompareTwoConverter('IN'));
36+
$this->register('lteq', new CompareTwoConverter('<='));
37+
$this->register('lt', new CompareTwoConverter('<'));
38+
$this->register('neq', new CompareTwoConverter('!='));
39+
$this->register('niden', new CompareTwoConverter('!=='));
40+
$this->register('niniden', new CompareTwoConverter('NOT IN STRICT'));
41+
$this->register('nin', new CompareListConverter('NOT IN'));
42+
$this->register('notnull', new CompareOneConverter('IS NOT NULL'));
43+
$this->register('null', new CompareOneConverter('IS NULL'));
44+
$this->register('regexp', new CompareTwoConverter('MATCH REGEX'));
45+
$this->register('and', new LogicalOperatorConverter('AND'));
46+
$this->register('nand', new LogicalOperatorConverter('NAND'));
47+
$this->register('nor', new LogicalOperatorConverter('NOR'));
48+
$this->register('or', new LogicalOperatorConverter('OR'));
49+
$this->register('xnor', new LogicalOperatorConverter('XNOR'));
50+
$this->register('xor', new LogicalOperatorConverter('XOR'));
51+
}
52+
53+
public function register(string $operator, ConverterInterface $converter): void
54+
{
55+
$this->converters[$operator] = $converter;
56+
}
57+
58+
public function format(NodeInterface $node, DataSource $dataSource): string
59+
{
60+
return match (true) {
61+
$node instanceof CombineInterface => $this->formatCombine($node, $dataSource),
62+
$node instanceof ConditionInterface => $this->formatCondition($node, $dataSource),
63+
default => throw new \Exception()//ToDo
64+
};
65+
}
66+
67+
private function formatCombine(CombineInterface $combine, DataSource $dataSource): string
68+
{
69+
return ($combine->isInvert() ? 'NOT ' : '') . $this->converters[$combine->getOperator()]->convert(
70+
...array_map(fn (NodeInterface $node) => $this->format($node, $dataSource), $combine->getChildren())
71+
);
72+
}
73+
74+
private function formatCondition(ConditionInterface $condition, DataSource $dataSource): string
75+
{//ToDo exception if not exists
76+
return $this->converters[$condition->getOperator()]->convert(
77+
$dataSource->getValue($condition->getValueIdentifier()),
78+
$condition->getValueCompare()
79+
);
80+
}
81+
}

src/Node/CombineInterface.php

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,44 +21,30 @@ public function getChildren(): array;
2121
* Set the logic structure as conditions or combinations
2222
*
2323
* @param NodeInterface[] $children
24-
* @return Combine
2524
*/
2625
public function setChildren(array $children): CombineInterface;
2726

2827
/**
2928
* Add a logic structure as condition or combination
3029
*
3130
* @param NodeInterface $node
32-
* @return Combine
3331
*/
3432
public function addChild(NodeInterface $node): CombineInterface;
3533

3634
/**
3735
* Retrieve the count of children nodes
38-
*
39-
* @return int
4036
*/
4137
public function getCount(): int;
4238

43-
/**
44-
* Check if it has children
45-
*
46-
* @return bool
47-
*/
4839
public function hasChildren(): bool;
4940

5041
/**
5142
* Check if the result should be inverted
52-
*
53-
* @return bool
5443
*/
5544
public function isInvert(): bool;
5645

5746
/**
5847
* Set is result of combination inverted
59-
*
60-
* @param bool $isInvert
61-
* @return Combine
6248
*/
6349
public function setIsInvert(bool $isInvert): CombineInterface;
6450
}

0 commit comments

Comments
 (0)