mirror of
https://github.com/koel/koel
synced 2024-12-22 10:33:16 +00:00
120 lines
3.7 KiB
PHP
120 lines
3.7 KiB
PHP
<?php
|
|
|
|
namespace App\Values;
|
|
|
|
use Illuminate\Contracts\Support\Arrayable;
|
|
use Illuminate\Support\Str;
|
|
use Webmozart\Assert\Assert;
|
|
|
|
final class SmartPlaylistRule implements Arrayable
|
|
{
|
|
public const OPERATOR_IS = 'is';
|
|
public const OPERATOR_IS_NOT = 'isNot';
|
|
public const OPERATOR_CONTAINS = 'contains';
|
|
public const OPERATOR_NOT_CONTAIN = 'notContain';
|
|
public const OPERATOR_IS_BETWEEN = 'isBetween';
|
|
public const OPERATOR_IS_GREATER_THAN = 'isGreaterThan';
|
|
public const OPERATOR_IS_LESS_THAN = 'isLessThan';
|
|
public const OPERATOR_BEGINS_WITH = 'beginsWith';
|
|
public const OPERATOR_ENDS_WITH = 'endsWith';
|
|
public const OPERATOR_IN_LAST = 'inLast';
|
|
public const OPERATOR_NOT_IN_LAST = 'notInLast';
|
|
public const OPERATOR_IS_NOT_BETWEEN = 'isNotBetween';
|
|
|
|
public const VALID_OPERATORS = [
|
|
self::OPERATOR_BEGINS_WITH,
|
|
self::OPERATOR_CONTAINS,
|
|
self::OPERATOR_ENDS_WITH,
|
|
self::OPERATOR_IN_LAST,
|
|
self::OPERATOR_IS,
|
|
self::OPERATOR_IS_BETWEEN,
|
|
self::OPERATOR_IS_NOT_BETWEEN,
|
|
self::OPERATOR_IS_GREATER_THAN,
|
|
self::OPERATOR_IS_LESS_THAN,
|
|
self::OPERATOR_IS_NOT,
|
|
self::OPERATOR_NOT_CONTAIN,
|
|
self::OPERATOR_NOT_IN_LAST,
|
|
];
|
|
|
|
private const MODEL_TITLE = 'title';
|
|
public const MODEL_ALBUM_NAME = 'album.name';
|
|
public const MODEL_ARTIST_NAME = 'artist.name';
|
|
private const MODEL_PLAY_COUNT = 'interactions.play_count';
|
|
public const MODEL_LAST_PLAYED = 'interactions.last_played_at';
|
|
private const MODEL_USER_ID = 'interactions.user_id';
|
|
private const MODEL_LENGTH = 'length';
|
|
public const MODEL_DATE_ADDED = 'created_at';
|
|
public const MODEL_DATE_MODIFIED = 'updated_at';
|
|
private const MODEL_GENRE = 'genre';
|
|
private const MODEL_YEAR = 'year';
|
|
|
|
private const VALID_MODELS = [
|
|
self::MODEL_TITLE,
|
|
self::MODEL_ALBUM_NAME,
|
|
self::MODEL_ARTIST_NAME,
|
|
self::MODEL_PLAY_COUNT,
|
|
self::MODEL_LAST_PLAYED,
|
|
self::MODEL_LENGTH,
|
|
self::MODEL_DATE_ADDED,
|
|
self::MODEL_DATE_MODIFIED,
|
|
self::MODEL_GENRE,
|
|
self::MODEL_YEAR,
|
|
];
|
|
|
|
public string $id;
|
|
public string $operator;
|
|
public array $value;
|
|
public string $model;
|
|
|
|
private function __construct(array $config)
|
|
{
|
|
self::assertConfig($config);
|
|
|
|
$this->id = $config['id'] ?? Str::uuid()->toString();
|
|
$this->value = $config['value'];
|
|
$this->model = $config['model'];
|
|
$this->operator = $config['operator'];
|
|
}
|
|
|
|
public static function assertConfig(array $config, bool $allowUserIdModel = true): void
|
|
{
|
|
if ($config['id'] ?? null) {
|
|
Assert::uuid($config['id']);
|
|
}
|
|
|
|
Assert::oneOf($config['operator'], self::VALID_OPERATORS);
|
|
Assert::oneOf(
|
|
$config['model'],
|
|
$allowUserIdModel ? array_prepend(self::VALID_MODELS, self::MODEL_USER_ID) : self::VALID_MODELS
|
|
);
|
|
Assert::isArray($config['value']);
|
|
Assert::countBetween($config['value'], 1, 2);
|
|
}
|
|
|
|
public static function make(array $config): self
|
|
{
|
|
return new self($config);
|
|
}
|
|
|
|
/** @return array<mixed> */
|
|
public function toArray(): array
|
|
{
|
|
return [
|
|
'id' => $this->id,
|
|
'model' => $this->model,
|
|
'operator' => $this->operator,
|
|
'value' => $this->value,
|
|
];
|
|
}
|
|
|
|
public function equals(array|self $rule): bool
|
|
{
|
|
if (is_array($rule)) {
|
|
$rule = self::make($rule);
|
|
}
|
|
|
|
return $this->operator === $rule->operator
|
|
&& !array_diff($this->value, $rule->value)
|
|
&& $this->model === $rule->model;
|
|
}
|
|
}
|