Skip to content

Commit c2972a4

Browse files
committed
Update Code Quality on Filter Abstraction + Add All Filters to Filter Builder
1 parent 20377de commit c2972a4

38 files changed

+923
-119
lines changed

rector.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
SimplifyEmptyCheckOnEmptyArrayRector::class,
1515
])
1616
->withSets([
17-
SetList::PHP_80,
17+
SetList::PHP_82,
18+
SetList::PHP_83,
19+
SetList::PHP_84,
1820
SetList::DEAD_CODE,
1921
SetList::CODE_QUALITY,
2022
SetList::CODING_STYLE,
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
namespace Sugarcrm\REST\Endpoint\Data\Filters;
4+
5+
use Sugarcrm\REST\Endpoint\Data\Filters\Operator\AbstractOperator;
6+
7+
abstract class AbstractPredefinedFilter extends AbstractOperator
8+
{
9+
public function __construct(array $arguments = [])
10+
{
11+
if (!empty($arguments) && count($arguments) < 2) {
12+
$arguments = [
13+
$this->getOperator(),
14+
$arguments[0] ?? '',
15+
];
16+
}
17+
18+
parent::__construct($arguments);
19+
}
20+
21+
public function compile(): array
22+
{
23+
return [
24+
$this->getOperator() => $this->getValue(),
25+
];
26+
}
27+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace Sugarcrm\REST\Endpoint\Data\Filters;
4+
5+
class Creator extends AbstractPredefinedFilter
6+
{
7+
public const OPERATOR = '$creator';
8+
}

src/Endpoint/Data/Filters/Expression/AbstractExpression.php

Lines changed: 50 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@
66

77
namespace Sugarcrm\REST\Endpoint\Data\Filters\Expression;
88

9+
use Sugarcrm\REST\Endpoint\Data\Filters\Creator;
10+
use Sugarcrm\REST\Endpoint\Data\Filters\Favorite;
11+
use Sugarcrm\REST\Endpoint\Data\Filters\Following;
912
use Sugarcrm\REST\Endpoint\Data\Filters\Operator\Equals;
13+
use Sugarcrm\REST\Endpoint\Data\Filters\Operator\InRadiusFromCoords;
14+
use Sugarcrm\REST\Endpoint\Data\Filters\Operator\InRadiusFromZip;
1015
use Sugarcrm\REST\Endpoint\Data\Filters\Operator\NotEquals;
1116
use Sugarcrm\REST\Endpoint\Data\Filters\Operator\Starts;
1217
use Sugarcrm\REST\Endpoint\Data\Filters\Operator\Ends;
@@ -22,48 +27,52 @@
2227
use Sugarcrm\REST\Endpoint\Data\Filters\Operator\Between;
2328
use Sugarcrm\REST\Endpoint\Data\Filters\Operator\DateBetween;
2429
use Sugarcrm\REST\Endpoint\Data\Filters\FilterInterface;
30+
use Sugarcrm\REST\Endpoint\Data\Filters\Owner;
31+
use Sugarcrm\REST\Endpoint\Data\Filters\Tracker;
2532
use Sugarcrm\REST\Exception\Filter\UnknownFilterOperator;
2633

2734
/**
2835
* The default expression implementation provides an API for acess to all Sugar filter operators
2936
* @package Sugarcrm\REST\Endpoint\Data\Filters\Expression
3037
* @method AndExpression and()
3138
* @method OrExpression or()
32-
* @method DateExpression date($field)
33-
* @method $this equals($field,$value)
34-
* @method $this notEquals($field,$value)
35-
* @method $this starts($field,$value)
36-
* @method $this ends($field,$value)
37-
* @method $this contains($field,$value)
38-
* @method $this in($field,array $value)
39-
* @method $this notIn($field,array $value)
40-
* @method $this isNull($field)
41-
* @method $this notNull($field)
42-
* @method $this lt($field,$value)
43-
* @method $this lessThan($field,$value)
44-
* @method $this lte($field,$value)
45-
* @method $this lessThanOrEqualTo($field,$value)
46-
* @method $this lessThanOrEquals($field,$value)
47-
* @method $this greaterThan($field,$value)
48-
* @method $this gte($field,$value)
49-
* @method $this greaterThanOrEqualTo($field,$value)
50-
* @method $this greaterThanOrEquals($field,$value)
51-
* @method $this between($field,$value)
52-
* @method $this dateBetween($field,$value)
39+
* @method DateExpression date(string $field)
40+
* @method DistanceExpression distance(string $field)
41+
* @method static equals(string $field, mixed $value)
42+
* @method static notEquals(string $field, mixed $value)
43+
* @method static starts(string $field,mixed $value)
44+
* @method static ends(string $field, mixed $value)
45+
* @method static contains(string $field, mixed $value)
46+
* @method static in(string $field, array $value)
47+
* @method static notIn(string $field, array $value)
48+
* @method static isNull(string $field)
49+
* @method static notNull(string $field)
50+
* @method static lt(string $field,int|float $value)
51+
* @method static lessThan(string $field, int|float $value)
52+
* @method static lte(string $field, int|float $value)
53+
* @method static lessThanOrEqualTo(string $field, int|float $value)
54+
* @method static lessThanOrEquals(string $field, int|float $value)
55+
* @method static greaterThan(string $field, int|float $value)
56+
* @method static gte(string $field, int|float $value)
57+
* @method static greaterThanOrEqualTo(string $field, int|float $value)
58+
* @method static greaterThanOrEquals(string $field, int|float$value)
59+
* @method static between(string $field, array $value)
60+
* @method static dateBetween(string $field,array $value)
61+
* @method static inRadiusFromCoords(string $field, array $coords, int|float $radius, string $unitType = 'km')
62+
* @method static inRadiusFromZip(string $field, string $zip, int|float $radius, string $country, string $unitType = 'km')
63+
* @method static favorite()
64+
* @method static following()
65+
* @method static owner()
66+
* @method static creator()
67+
* @method static tracker(string $interval)
5368
*/
5469
abstract class AbstractExpression implements FilterInterface, ExpressionInterface
5570
{
56-
/**
57-
* @var array
58-
*/
59-
protected $filters = [];
71+
protected array $filters = [];
6072

61-
private ?\Sugarcrm\REST\Endpoint\Data\Filters\Expression\AbstractExpression $parentExpression = null;
73+
private AbstractExpression $parentExpression;
6274

63-
/**
64-
* @var array
65-
*/
66-
protected $operators = [
75+
protected array $operators = [
6776
'equals' => Equals::class,
6877
'notEquals' => NotEquals::class,
6978
'starts' => Starts::class,
@@ -85,15 +94,20 @@ abstract class AbstractExpression implements FilterInterface, ExpressionInterfac
8594
'greaterThanOrEquals' => GreaterThanOrEqual::class,
8695
'between' => Between::class,
8796
'dateBetween' => DateBetween::class,
97+
'inRadiusFromCoords' => InRadiusFromCoords::class,
98+
'inRadiusFromZip' => InRadiusFromZip::class,
99+
'favorite' => Favorite::class,
100+
'following' => Following::class,
101+
'owner' => Owner::class,
102+
'tracker' => Tracker::class,
103+
'creator' => Creator::class,
88104
];
89105

90-
/**
91-
* @var array
92-
*/
93-
protected $expressions = [
106+
protected array $expressions = [
94107
'and' => AndExpression::class,
95108
'or' => OrExpression::class,
96109
'date' => DateExpression::class,
110+
'distance' => DistanceExpression::class,
97111
];
98112

99113
/**
@@ -126,7 +140,7 @@ public function __call($name, $arguments)
126140
* Sets Parent Expression to allow for nested tree structure
127141
* @return $this
128142
*/
129-
public function setParentExpression(AbstractExpression $Expression)
143+
public function setParentExpression(AbstractExpression $Expression): static
130144
{
131145
$this->parentExpression = $Expression;
132146
return $this;
@@ -156,7 +170,7 @@ public function compile(): array
156170
/**
157171
* @inheritDoc
158172
*/
159-
public function clear()
173+
public function clear(): static
160174
{
161175
$this->filters = [];
162176
return $this;

src/Endpoint/Data/Filters/Expression/DateExpression.php

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
use Sugarcrm\REST\Endpoint\Data\Filters\Operator\GreaterThanOrEqual;
1717
use Sugarcrm\REST\Endpoint\Data\Filters\Operator\DateBetween;
1818
use Sugarcrm\REST\Endpoint\Data\Filters\Operator\DateRange;
19-
use Sugarcrm\REST\Exception\Filter\MissingFieldForDateExpression;
19+
use Sugarcrm\REST\Exception\Filter\MissingFieldForFilterExpression;
2020
use Sugarcrm\REST\Exception\Filter\UnknownFilterOperator;
2121

2222
/**
@@ -54,9 +54,9 @@ class DateExpression extends AbstractExpression
5454
{
5555
public const OPERATOR = '';
5656

57-
protected $dateField;
57+
protected string $dateField;
5858

59-
protected $ranges = [
59+
protected array $ranges = [
6060
'yesterday' => 'yesterday',
6161
'today' => 'today',
6262
'tomorrow' => 'tomorrow',
@@ -72,10 +72,7 @@ class DateExpression extends AbstractExpression
7272
'nextYear' => 'next_year',
7373
];
7474

75-
/**
76-
* @var array
77-
*/
78-
protected $operators = [
75+
protected array $operators = [
7976
'equals' => Equals::class,
8077
'notEquals' => NotEquals::class,
8178
'isNull' => IsNull::class,
@@ -94,10 +91,7 @@ class DateExpression extends AbstractExpression
9491
'between' => DateBetween::class,
9592
];
9693

97-
/**
98-
* @var array
99-
*/
100-
protected $expressions = [];
94+
protected array $expressions = [];
10195

10296
/**
10397
* DateExpression constructor.
@@ -114,21 +108,32 @@ public function __construct(array $arguments = [])
114108
* @param $field
115109
* @return $this
116110
*/
117-
public function field($field): self
111+
public function field(string $field): self
118112
{
119113
$this->dateField = $field;
120114
return $this;
121115
}
122116

117+
protected function isDateRange(string $name): string|false
118+
{
119+
$range = false;
120+
if (array_key_exists($name, $this->ranges)) {
121+
$range = $this->ranges[$name];
122+
} elseif (in_array($name, $this->ranges)) {
123+
$range = $name;
124+
}
125+
126+
return $range;
127+
}
128+
123129
public function __call($name, $arguments)
124130
{
125131
if (empty($this->dateField)) {
126-
throw new MissingFieldForDateExpression();
132+
throw new MissingFieldForFilterExpression();
127133
}
128134

129135
$args = [$this->dateField];
130-
if (array_key_exists($name, $this->ranges)) {
131-
$range = $this->ranges[$name];
136+
if ($range = $this->isDateRange($name)) {
132137
$args[] = $range;
133138
$Op = new DateRange($args);
134139
$this->filters[0] = $Op;
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<?php
2+
3+
namespace Sugarcrm\REST\Endpoint\Data\Filters\Expression;
4+
5+
use Sugarcrm\REST\Endpoint\Data\Filters\Operator\InRadiusFromCoords;
6+
use Sugarcrm\REST\Endpoint\Data\Filters\Operator\InRadiusFromZip;
7+
use Sugarcrm\REST\Exception\Filter\MissingFieldForFilterExpression;
8+
use Sugarcrm\REST\Exception\Filter\UnknownFilterOperator;
9+
10+
/**
11+
* Class DistanceExpression
12+
* @package Sugarcrm\REST\Endpoint\Data\Filters\Expression
13+
*
14+
* @method DistanceExpression radiusFromZip(string $zipCode, string $country = 'US', float $radius = 0, string $unitType = 'km')
15+
* @method DistanceExpression radiusFromCoords(float|array $latitude, float|null $longitude = null, float $radius = 0, string $unitType = 'km')
16+
*/
17+
class DistanceExpression extends AbstractExpression
18+
{
19+
protected array $operators = [
20+
'radiusFromZip' => InRadiusFromZip::class,
21+
'radiusFromCoords' => InRadiusFromCoords::class,
22+
];
23+
24+
protected array $expressions = [];
25+
26+
protected string $distanceField;
27+
28+
/**
29+
* DateExpression constructor.
30+
*/
31+
public function __construct(array $arguments = [])
32+
{
33+
if (isset($arguments[0])) {
34+
$this->field($arguments[0]);
35+
}
36+
}
37+
38+
/**
39+
* Set the field that date expression is against
40+
* @param $field
41+
* @return $this
42+
*/
43+
public function field(string $field): self
44+
{
45+
$this->distanceField = $field;
46+
return $this;
47+
}
48+
49+
public function __call($name, $arguments)
50+
{
51+
if (empty($this->distanceField)) {
52+
throw new MissingFieldForFilterExpression();
53+
}
54+
55+
$args = [$this->distanceField];
56+
if (array_key_exists($name, $this->operators)) {
57+
$args = array_merge($args, $arguments);
58+
$Operator = $this->operators[$name];
59+
$O = new $Operator($args);
60+
$this->filters[0] = $O;
61+
return $this;
62+
}
63+
64+
throw new UnknownFilterOperator([$name]);
65+
}
66+
67+
/**
68+
* Human Friendly Expression End, allow you to traverse back up the Filter expression
69+
* @codeCoverageIgnore
70+
*/
71+
public function endDistance(): AbstractExpression
72+
{
73+
return $this->getParentExpression();
74+
}
75+
}

src/Endpoint/Data/Filters/Expression/ExpressionInterface.php

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,17 @@
66

77
namespace Sugarcrm\REST\Endpoint\Data\Filters\Expression;
88

9+
use Sugarcrm\REST\Endpoint\Data\Filters\FilterInterface;
10+
911
/**
1012
* The Expression Interface defines the basic API needed for an Expression object used in the Filter API Data Layer
1113
* @package Sugarcrm\REST\Endpoint\Data\Filters\Expression
1214
**/
13-
interface ExpressionInterface
15+
interface ExpressionInterface extends FilterInterface
1416
{
15-
/**
16-
* Compiles the Filter Expression into an array to be passed to Sugar Filter API
17-
*/
18-
public function compile(): array;
19-
2017
/**
2118
* Clear out Filters included in Expression
2219
* @return $this
2320
*/
24-
public function clear();
21+
public function clear(): static;
2522
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace Sugarcrm\REST\Endpoint\Data\Filters;
4+
5+
class Favorite extends AbstractPredefinedFilter
6+
{
7+
public const OPERATOR = '$favorite';
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace Sugarcrm\REST\Endpoint\Data\Filters;
4+
5+
class Following extends AbstractPredefinedFilter
6+
{
7+
public const OPERATOR = '$following';
8+
}

0 commit comments

Comments
 (0)