Skip to content

Commit

Permalink
Adding Registering alias feature to the package (#132)
Browse files Browse the repository at this point in the history
  • Loading branch information
nyamsprod committed Jan 14, 2022
1 parent 9b377d5 commit d10f969
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 1 deletion.
74 changes: 73 additions & 1 deletion src/Cron/CronExpression.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use DateTimeZone;
use Exception;
use InvalidArgumentException;
use LogicException;
use RuntimeException;
use Webmozart\Assert\Assert;

Expand Down Expand Up @@ -73,6 +74,77 @@ class CronExpression
self::MINUTE,
];

/**
* @var array<string, string>
*/
private static $registeredAliases = self::MAPPINGS;

/**
* Registered a user defined CRON Expression Alias.
*
* @throws LogicException If the expression or the alias name are invalid
* or if the alias is already registered.
*/
public static function registerAlias(string $alias, string $expression): void
{
try {
new self($expression);
} catch (InvalidArgumentException $exception) {
throw new LogicException("The expression `$expression` is invalid", 0, $exception);
}

$shortcut = strtolower($alias);
if (1 !== preg_match('/^@\w+$/', $shortcut)) {
throw new LogicException("The alias `$alias` is invalid. It must start with an `@` character and contain alphanumeric (letters, numbers, regardless of case) plus underscore (_).");
}

if (isset(self::$registeredAliases[$shortcut])) {
throw new LogicException("The alias `$alias` is already registered.");
}

self::$registeredAliases[$shortcut] = $expression;
}

/**
* Unregistered a user defined CRON Expression Alias.
*
* @throws LogicException If the user tries to unregister a built-in alias
*/
public static function unregisterAlias(string $alias): bool
{
$shortcut = strtolower($alias);
if (isset(self::MAPPINGS[$shortcut])) {
throw new LogicException("The alias `$alias` is a built-in alias; it can not be unregistered.");
}

if (!isset(self::$registeredAliases[$shortcut])) {
return false;
}

unset(self::$registeredAliases[$shortcut]);

return true;
}

/**
* Tells whether a CRON Expression alias is registered.
*/
public static function supportsAlias(string $alias): bool
{
return isset(self::$registeredAliases[strtolower($alias)]);
}

/**
* Returns all registered aliases as an associated array where the aliases are the key
* and their associated expressions are the values.
*
* @return array<string, string>
*/
public static function getAliases(): array
{
return self::$registeredAliases;
}

/**
* @deprecated since version 3.0.2, use __construct instead.
*/
Expand Down Expand Up @@ -109,7 +181,7 @@ public static function isValidExpression(string $expression): bool
public function __construct(string $expression, FieldFactoryInterface $fieldFactory = null)
{
$shortcut = strtolower($expression);
$expression = self::MAPPINGS[$shortcut] ?? $expression;
$expression = self::$registeredAliases[$shortcut] ?? $expression;

$this->fieldFactory = $fieldFactory ?: new FieldFactory();
$this->setExpression($expression);
Expand Down
57 changes: 57 additions & 0 deletions tests/Cron/CronExpressionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use DateTimeImmutable;
use DateTimeZone;
use InvalidArgumentException;
use LogicException;
use PHPUnit\Framework\TestCase;
use Webmozart\Assert\Assert;

Expand Down Expand Up @@ -724,4 +725,60 @@ public function testIssue128()
$prev = $e->getPreviousRunDate(new \DateTime('2022-08-20 03:44:02'), 1);
$this->assertEquals($expected, $prev);
}

public function testItCanRegisterAnValidExpression(): void
{
CronExpression::registerAlias('@every', '* * * * *');

self::assertCount(8, CronExpression::getAliases());
self::assertArrayHasKey('@every', CronExpression::getAliases());
self::assertTrue(CronExpression::supportsAlias('@every'));
self::assertEquals(new CronExpression('@every'), new CronExpression('* * * * *'));

self::assertTrue(CronExpression::unregisterAlias('@every'));
self::assertFalse(CronExpression::unregisterAlias('@every'));

self::assertCount(7, CronExpression::getAliases());
self::assertArrayNotHasKey('@every', CronExpression::getAliases());
self::assertFalse(CronExpression::supportsAlias('@every'));

$this->expectException(LogicException::class);
new CronExpression('@every');
}

public function testItWillFailToRegisterAnInvalidExpression(): void
{
$this->expectException(LogicException::class);

CronExpression::registerAlias('@every', 'foobar');
}

public function testItWillFailToRegisterAnInvalidName(): void
{
$this->expectException(LogicException::class);

CronExpression::registerAlias('every', '* * * * *');
}

public function testItWillFailToRegisterAnInvalidName2(): void
{
$this->expectException(LogicException::class);

CronExpression::registerAlias('@évery', '* * * * *');
}

public function testItWillFailToRegisterAValidNameTwice(): void
{
CronExpression::registerAlias('@Ev_eR_y', '* * * * *');

$this->expectException(LogicException::class);
CronExpression::registerAlias('@eV_Er_Y', '2 2 2 2 2');
}

public function testItWillFailToUnregisterADefaultExpression(): void
{
$this->expectException(LogicException::class);

CronExpression::unregisterAlias('@daily');
}
}

0 comments on commit d10f969

Please sign in to comment.