-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
- added support for new banner option `fetchpriority` - added support for banner options defined in the AMP administration - the option `loading` is now processed as an expression. The option `loading-offset` is ignored - updated docs
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace SixtyEightPublishers\AmpClient\Expression; | ||
|
||
use function array_map; | ||
use function explode; | ||
use function preg_match; | ||
use function trim; | ||
|
||
final class ExpressionParser implements ExpressionParserInterface | ||
{ | ||
private const ExpressionRegex = '/^(?:(?<INTERVAL_FROM>\d+)-(?<INTERVAL_TO>\d+):|(?<EQ>\d+):|<(?<LT>\d+):|<=(?<LTE>\d+):|>(?<GT>\d+):|>=(?<GTE>\d+):)?(?<VALUE>[^:\s]+)$/'; | ||
|
||
/** @var array<string, ParsedExpression> */ | ||
private array $cache = []; | ||
|
||
public function parseExpression(string $expression): ParsedExpression | ||
{ | ||
if (isset($this->cache[$expression])) { | ||
return $this->cache[$expression]; | ||
} | ||
|
||
$parts = array_map( | ||
static fn (string $part) => trim($part), | ||
explode(',', $expression), | ||
); | ||
$rules = []; | ||
|
||
foreach ($parts as $part) { | ||
if (!preg_match(self::ExpressionRegex, $part, $matches)) { | ||
continue; | ||
} | ||
|
||
$value = $matches['VALUE'] ?? null; | ||
Check failure on line 36 in src/Expression/ExpressionParser.php GitHub Actions / PHPStan
|
||
|
||
if (null === $value) { | ||
continue; | ||
} | ||
|
||
switch (true) { | ||
case '' !== ($matches['INTERVAL_FROM'] ?? '') && '' !== ($matches['INTERVAL_TO'] ?? ''): | ||
Check failure on line 43 in src/Expression/ExpressionParser.php GitHub Actions / PHPStan
Check failure on line 43 in src/Expression/ExpressionParser.php GitHub Actions / PHPStan
|
||
$rules[] = ExpressionRule::range( | ||
(int) $matches['INTERVAL_FROM'], | ||
(int) $matches['INTERVAL_TO'], | ||
$value, | ||
); | ||
|
||
break; | ||
case '' !== ($matches['EQ'] ?? ''): | ||
Check failure on line 51 in src/Expression/ExpressionParser.php GitHub Actions / PHPStan
|
||
$rules[] = ExpressionRule::eq( | ||
(int) $matches['EQ'], | ||
$value, | ||
); | ||
|
||
break; | ||
case '' !== ($matches['LT'] ?? ''): | ||
Check failure on line 58 in src/Expression/ExpressionParser.php GitHub Actions / PHPStan
|
||
$rules[] = ExpressionRule::lt( | ||
(int) $matches['LT'], | ||
$value, | ||
); | ||
|
||
break; | ||
case '' !== ($matches['LTE'] ?? ''): | ||
Check failure on line 65 in src/Expression/ExpressionParser.php GitHub Actions / PHPStan
|
||
$rules[] = ExpressionRule::lte( | ||
(int) $matches['LTE'], | ||
$value, | ||
); | ||
|
||
break; | ||
case '' !== ($matches['GT'] ?? ''): | ||
Check failure on line 72 in src/Expression/ExpressionParser.php GitHub Actions / PHPStan
|
||
$rules[] = ExpressionRule::gt( | ||
(int) $matches['GT'], | ||
$value, | ||
); | ||
|
||
break; | ||
case '' !== ($matches['GTE'] ?? ''): | ||
Check failure on line 79 in src/Expression/ExpressionParser.php GitHub Actions / PHPStan
|
||
$rules[] = ExpressionRule::gte( | ||
(int) $matches['GTE'], | ||
$value, | ||
); | ||
|
||
break; | ||
default: | ||
$rules[] = ExpressionRule::positive($value); | ||
} | ||
} | ||
|
||
return $this->cache[$expression] = new ParsedExpression($rules); | ||
} | ||
|
||
public function evaluateExpression(string $expression, int $index): ?string | ||
{ | ||
return $this->parseExpression($expression)->evaluate($index); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace SixtyEightPublishers\AmpClient\Expression; | ||
|
||
interface ExpressionParserInterface | ||
{ | ||
public function parseExpression(string $expression): ParsedExpression; | ||
|
||
public function evaluateExpression(string $expression, int $index): ?string; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace SixtyEightPublishers\AmpClient\Expression; | ||
|
||
use Closure; | ||
|
||
final class ExpressionRule | ||
{ | ||
public string $value; | ||
|
||
/** @var Closure(int $index): bool */ | ||
private Closure $matcher; | ||
|
||
/** | ||
* @param Closure(int $index): bool $matcher | ||
*/ | ||
private function __construct( | ||
string $value, | ||
Closure $matcher | ||
) { | ||
$this->value = $value; | ||
$this->matcher = $matcher; | ||
} | ||
|
||
public static function eq(int $eq, string $value): self | ||
{ | ||
return new self( | ||
$value, | ||
function (int $index) use ($eq): bool { | ||
return $index === $eq; | ||
}, | ||
); | ||
} | ||
|
||
public static function range(int $from, int $to, string $value): self | ||
{ | ||
return new self( | ||
$value, | ||
function (int $index) use ($from, $to): bool { | ||
return $index >= $from && $index <= $to; | ||
}, | ||
); | ||
} | ||
|
||
public static function lt(int $lt, string $value): self | ||
{ | ||
return new self( | ||
$value, | ||
function (int $index) use ($lt): bool { | ||
return $index < $lt; | ||
}, | ||
); | ||
} | ||
|
||
public static function lte(int $lte, string $value): self | ||
{ | ||
return new self( | ||
$value, | ||
function (int $index) use ($lte): bool { | ||
return $index <= $lte; | ||
}, | ||
); | ||
} | ||
|
||
public static function gt(int $gt, string $value): self | ||
{ | ||
return new self( | ||
$value, | ||
function (int $index) use ($gt): bool { | ||
return $index > $gt; | ||
}, | ||
); | ||
} | ||
|
||
public static function gte(int $gte, string $value): self | ||
{ | ||
return new self( | ||
$value, | ||
function (int $index) use ($gte): bool { | ||
return $index >= $gte; | ||
}, | ||
); | ||
} | ||
|
||
public static function positive(string $value): self | ||
{ | ||
return new self( | ||
$value, | ||
function (): bool { | ||
return true; | ||
}, | ||
); | ||
} | ||
|
||
public function matches(int $index): bool | ||
{ | ||
return ($this->matcher)($index); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace SixtyEightPublishers\AmpClient\Expression; | ||
|
||
use function array_key_exists; | ||
|
||
final class ParsedExpression | ||
{ | ||
/** @var list<ExpressionRule> */ | ||
private array $rules; | ||
|
||
/** @var array<string, string|null> */ | ||
private array $cache = []; | ||
|
||
/** | ||
* @param list<ExpressionRule> $rules | ||
*/ | ||
public function __construct( | ||
array $rules | ||
) { | ||
$this->rules = $rules; | ||
} | ||
|
||
public function evaluate(int $index): ?string | ||
{ | ||
$cacheKey = 'i_' . $index; | ||
|
||
if (array_key_exists($cacheKey, $this->cache)) { | ||
return $this->cache[$cacheKey]; | ||
} | ||
|
||
foreach ($this->rules as $rule) { | ||
if ($rule->matches($index)) { | ||
return $this->cache[$cacheKey] = $rule->value; | ||
} | ||
} | ||
|
||
return $this->cache[$cacheKey] = null; | ||
} | ||
} |