Skip to content

Commit 91b0a3b

Browse files
emyllerclaude
andauthored
feat(Engine)!: Use context-based evaluation engine (#126)
Co-authored-by: Claude <noreply@anthropic.com>
1 parent eab5568 commit 91b0a3b

19 files changed

+0
-2008
lines changed

src/Engine/Engine.php

Lines changed: 0 additions & 153 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,6 @@
22

33
namespace Flagsmith\Engine;
44

5-
use Flagsmith\Engine\Environments\EnvironmentModel;
6-
use Flagsmith\Engine\Features\FeatureStateModel;
7-
use Flagsmith\Engine\Identities\IdentityModel;
8-
use Flagsmith\Engine\Segments\SegmentEvaluator;
9-
use Flagsmith\Engine\Utils\Exceptions\FeatureStateNotFound;
105
use Flagsmith\Engine\Utils\Hashing;
116
use Flagsmith\Engine\Utils\Semver;
127
use Flagsmith\Engine\Utils\Types\Context\EvaluationContext;
@@ -424,152 +419,4 @@ private static function _getCaster($contextValue): ?callable
424419
'double' => fn ($v) => is_numeric($v) ? (float) $v : $v,
425420
};
426421
}
427-
428-
/**
429-
* Get the environment feature states.
430-
* @param EnvironmentModel $environment
431-
* @return array
432-
*/
433-
public static function getEnvironmentFeatureStates(EnvironmentModel $environment): array
434-
{
435-
if ($environment->getProject()->getHideDisabledFlags()) {
436-
return array_filter(
437-
$environment->getFeatureStates()->getArrayCopy(),
438-
fn (FeatureStateModel $fs) => $fs->getEnabled()
439-
);
440-
}
441-
442-
return $environment->getFeatureStates()->getArrayCopy();
443-
}
444-
445-
/**
446-
* get the environment feature state.
447-
* @param EnvironmentModel $environment
448-
* @param string $featureName
449-
* @return FeatureStateModel
450-
*/
451-
public static function getEnvironmentFeatureState(
452-
EnvironmentModel $environment,
453-
string $featureName
454-
): FeatureStateModel {
455-
$featureStates = $environment
456-
->getFeatureStates()
457-
->getArrayCopy();
458-
$filteredFeatureStates = array_filter(
459-
$featureStates,
460-
fn (FeatureStateModel $fs)
461-
=> $fs->getFeature()->getName() === $featureName
462-
);
463-
464-
if (count($filteredFeatureStates) === 0) {
465-
throw new FeatureStateNotFound();
466-
}
467-
468-
return array_shift($filteredFeatureStates);
469-
}
470-
471-
/**
472-
* get the identity feature states.
473-
* @param EnvironmentModel $environment
474-
* @param IdentityModel $identity
475-
* @param array|null $overrideTraits
476-
* @return array
477-
*/
478-
public static function getIdentityFeatureStates(
479-
EnvironmentModel $environment,
480-
IdentityModel $identity,
481-
?array $overrideTraits = null
482-
): array {
483-
$featureStates = self::_getIdentityFeatureStatesDict(
484-
$environment,
485-
$identity,
486-
$overrideTraits
487-
);
488-
489-
if ($environment->getProject()->getHideDisabledFlags()) {
490-
$filteredFeatureStates = [];
491-
foreach ($featureStates as $featureState) {
492-
if ($featureState->getEnabled()) {
493-
$filteredFeatureStates[] = $featureState;
494-
}
495-
}
496-
return $filteredFeatureStates;
497-
}
498-
499-
return array_values($featureStates);
500-
}
501-
502-
/**
503-
* get the identity feature state.
504-
* @param EnvironmentModel $environment
505-
* @param IdentityModel $identity
506-
* @param string $featureName
507-
* @param array|null $overrideTraits
508-
* @return FeatureStateModel
509-
*/
510-
public static function getIdentityFeatureState(
511-
EnvironmentModel $environment,
512-
IdentityModel $identity,
513-
string $featureName,
514-
?array $overrideTraits = null
515-
): FeatureStateModel {
516-
$featureStates = self::_getIdentityFeatureStatesDict(
517-
$environment,
518-
$identity,
519-
$overrideTraits
520-
);
521-
522-
$matchingFeatureState = null;
523-
foreach ($featureStates as $name => $featureState) {
524-
if ($name === $featureName) {
525-
$matchingFeatureState = $featureState;
526-
}
527-
}
528-
529-
if (empty($matchingFeatureState)) {
530-
throw new FeatureStateNotFound();
531-
}
532-
533-
return $matchingFeatureState;
534-
}
535-
536-
/**
537-
* get feature states list.
538-
* @param EnvironmentModel $environment
539-
* @param IdentityModel $identity
540-
* @param array|null $overrideTraits
541-
* @return array
542-
*/
543-
private static function _getIdentityFeatureStatesDict(
544-
EnvironmentModel $environment,
545-
IdentityModel $identity,
546-
?array $overrideTraits = null
547-
): array {
548-
$featureStates = [];
549-
foreach ($environment->getFeatureStates() as $fs) {
550-
$featureStates[$fs->getFeature()->getName()] = $fs;
551-
}
552-
553-
$identitySegments = SegmentEvaluator::getIdentitySegments($environment, $identity, $overrideTraits);
554-
555-
foreach ($identitySegments as $is) {
556-
foreach ($is->getFeatureStates() as $fs) {
557-
$feature = $fs->getFeature();
558-
$existing = $featureStates[$feature->getName()];
559-
if ($existing != null && $existing->isHigherPriority($fs)) {
560-
continue;
561-
}
562-
563-
$featureStates[$fs->getFeature()->getName()] = $fs;
564-
}
565-
}
566-
567-
foreach ($identity->getIdentityFeatures() as $if) {
568-
if (isset($featureStates[$if->getFeature()->getName()])) {
569-
$featureStates[$if->getFeature()->getName()] = $if;
570-
}
571-
}
572-
573-
return $featureStates;
574-
}
575422
}

src/Engine/Segments/SegmentConditionModel.php

Lines changed: 0 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44

55
use Flagsmith\Concerns\HasWith;
66
use Flagsmith\Concerns\JsonSerializer;
7-
use Flagsmith\Engine\Segments\SegmentConditions;
8-
use Flagsmith\Engine\Utils\Semver;
97

108
#[\AllowDynamicProperties]
119
class SegmentConditionModel
@@ -74,111 +72,4 @@ public function withOperator(string $operator): self
7472
{
7573
return $this->with('operator', $operator);
7674
}
77-
78-
public const EQUALS = 'EQUALS';
79-
80-
public function matchesTraitValue($traitValue): bool
81-
{
82-
$condition = false;
83-
$castedValue = $this->value;
84-
$traitValueType = gettype($traitValue);
85-
86-
if ($traitValueType === 'boolean') {
87-
$castedValue = filter_var($castedValue, FILTER_VALIDATE_BOOLEAN);
88-
} elseif ($this->operator === SegmentConditions::MODULO) {
89-
return $this->matchesModuloTraitValue($traitValue);
90-
} else {
91-
settype($castedValue, $traitValueType);
92-
}
93-
94-
if (is_string($castedValue) && Semver::isSemver($castedValue)) {
95-
return $this->matchesSemverTraitValue(
96-
Semver::isSemver($traitValue) ? Semver::removeSemverSuffix($traitValue) : $traitValue,
97-
Semver::removeSemverSuffix($castedValue),
98-
$this->operator
99-
);
100-
}
101-
102-
switch ($this->operator) {
103-
case (SegmentConditions::EQUAL):
104-
$condition = $traitValue === $castedValue;
105-
break;
106-
case (SegmentConditions::GREATER_THAN):
107-
$condition = $traitValue > $castedValue;
108-
break;
109-
case (SegmentConditions::GREATER_THAN_INCLUSIVE):
110-
$condition = $traitValue >= $castedValue;
111-
break;
112-
case (SegmentConditions::LESS_THAN):
113-
$condition = $traitValue < $castedValue;
114-
break;
115-
case (SegmentConditions::LESS_THAN_INCLUSIVE):
116-
$condition = $traitValue <= $castedValue;
117-
break;
118-
case (SegmentConditions::NOT_EQUAL):
119-
$condition = $traitValue !== $castedValue;
120-
break;
121-
case (SegmentConditions::CONTAINS):
122-
$condition = strpos($traitValue, (string) $this->value) !== false;
123-
break;
124-
case (SegmentConditions::NOT_CONTAINS):
125-
$condition = strpos($traitValue, (string) $this->value) === false;
126-
break;
127-
case (SegmentConditions::REGEX):
128-
$matchesCount = preg_match_all("/{$this->value}/", (string) $traitValue);
129-
$condition = $matchesCount && $matchesCount > 0;
130-
break;
131-
case (SegmentConditions::IN):
132-
if (in_array($traitValueType, ['string', 'integer'])) {
133-
$condition = in_array((string) $traitValue, explode(',', (string) $this->value), true);
134-
}
135-
break;
136-
}
137-
138-
return $condition;
139-
}
140-
141-
private function matchesSemverTraitValue($trait, $value, $condition)
142-
{
143-
switch ($this->operator) {
144-
case (SegmentConditions::EQUAL):
145-
$condition = version_compare($trait, $value, '==');
146-
break;
147-
case (SegmentConditions::GREATER_THAN):
148-
$condition = version_compare($trait, $value, '>');
149-
break;
150-
case (SegmentConditions::GREATER_THAN_INCLUSIVE):
151-
$condition = version_compare($trait, $value, '>=');
152-
break;
153-
case (SegmentConditions::LESS_THAN):
154-
$condition = version_compare($trait, $value, '<');
155-
break;
156-
case (SegmentConditions::LESS_THAN_INCLUSIVE):
157-
$condition = version_compare($trait, $value, '<=');
158-
break;
159-
case (SegmentConditions::NOT_EQUAL):
160-
$condition = version_compare($trait, $value, '!=');
161-
break;
162-
}
163-
164-
return $condition;
165-
}
166-
167-
private function matchesModuloTraitValue($traitValue)
168-
{
169-
$valueParts = explode('|', $this->value);
170-
171-
if (!is_numeric($valueParts[0]) || !is_numeric($valueParts[1]) || !is_numeric($traitValue)) {
172-
return false;
173-
}
174-
175-
$divisor = floatval($valueParts[0]);
176-
$remainder = floatval($valueParts[1]);
177-
178-
if ($divisor == 0) {
179-
return false;
180-
}
181-
182-
return floatval($traitValue) % $divisor == $remainder;
183-
}
18475
}

src/Engine/Segments/SegmentConditions.php

Lines changed: 0 additions & 21 deletions
This file was deleted.

0 commit comments

Comments
 (0)