mirror of
https://code.castopod.org/adaures/castopod
synced 2025-05-13 01:35:47 +00:00
167 lines
5.0 KiB
PHP
167 lines
5.0 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Modules\Plugins\Manifest;
|
|
|
|
use CodeIgniter\Validation\Validation;
|
|
use Exception;
|
|
|
|
abstract class ManifestObject
|
|
{
|
|
/**
|
|
* @var array<string,string>
|
|
*/
|
|
public static array $validation_rules = [];
|
|
|
|
/**
|
|
* @var array<string,string|array{string}>
|
|
*/
|
|
protected array $casts = [];
|
|
|
|
/**
|
|
* @var array<string,array<string,string>>
|
|
*/
|
|
protected static array $errors = [];
|
|
|
|
public function __construct(
|
|
protected readonly string $pluginKey,
|
|
) {
|
|
self::$errors[$pluginKey] = [];
|
|
|
|
$class = static::class;
|
|
$validation_rules = [];
|
|
$casts = [];
|
|
while ($class = get_parent_class($class)) {
|
|
$validation_rules = [...$validation_rules, ...get_class_vars($class)['validation_rules']];
|
|
$casts = [...$casts, ...get_class_vars($class)['casts']];
|
|
}
|
|
|
|
$this::$validation_rules = [...$validation_rules, ...$this::$validation_rules];
|
|
$this->casts = [...$casts, ...$this->casts];
|
|
}
|
|
|
|
public function __get(string $name): mixed
|
|
{
|
|
if (property_exists($this, $name)) {
|
|
// if a get method exists for this property, return that
|
|
$method = 'get' . str_replace(' ', '', ucwords(str_replace(['-', '_'], ' ', $name)));
|
|
if (method_exists($this, $method)) {
|
|
return $this->{$method}();
|
|
}
|
|
|
|
return $this->{$name};
|
|
}
|
|
|
|
throw new Exception('Undefined object property ' . static::class . '::' . $name);
|
|
}
|
|
|
|
public function __isset(string $property): bool
|
|
{
|
|
return property_exists($this, $property);
|
|
}
|
|
|
|
public function loadFromFile(string $manifestPath): void
|
|
{
|
|
$manifestContents = @file_get_contents($manifestPath);
|
|
|
|
if (! $manifestContents) {
|
|
$manifestContents = '{}';
|
|
$this->addError('manifest', lang('Plugins.errors.manifestMissing', [
|
|
'manifestPath' => $manifestPath,
|
|
]));
|
|
}
|
|
|
|
/** @var array<mixed>|null $manifestData */
|
|
$manifestData = json_decode($manifestContents, true);
|
|
|
|
if ($manifestData === null) {
|
|
$manifestData = [];
|
|
$this->addError('manifest', lang('Plugins.errors.manifestJsonInvalid', [
|
|
'manifestPath' => $manifestPath,
|
|
]));
|
|
}
|
|
|
|
$this->loadData($manifestData);
|
|
}
|
|
|
|
/**
|
|
* @param array<mixed> $data
|
|
*/
|
|
public function loadData(array $data): void
|
|
{
|
|
/** @var Validation $validation */
|
|
$validation = service('validation');
|
|
|
|
$validation->setRules($this::$validation_rules);
|
|
|
|
if (! $validation->run($data)) {
|
|
foreach ($validation->getErrors() as $key => $message) {
|
|
$this->addError($key, $message);
|
|
}
|
|
|
|
$validation->reset();
|
|
}
|
|
|
|
foreach ($validation->getValidated() as $key => $value) {
|
|
$method = 'set' . str_replace(' ', '', ucwords(str_replace('_', ' ', $key)));
|
|
if (is_callable([$this, $method])) {
|
|
$this->{$method}($value);
|
|
continue;
|
|
}
|
|
|
|
if (array_key_exists($key, $this->casts)) {
|
|
$cast = $this->casts[$key];
|
|
if (is_array($cast) && is_array($value)) {
|
|
foreach ($value as $valueKey => $valueElement) {
|
|
if (is_subclass_of($cast[0], self::class)) {
|
|
$manifestClass = $cast[0] === Field::class ? $this->getFieldClass(
|
|
$valueElement
|
|
) : $cast[0];
|
|
$value[$valueKey] = new $manifestClass($this->pluginKey);
|
|
$value[$valueKey]->loadData($valueElement);
|
|
} else {
|
|
$value[$valueKey] = new $cast[0]($valueElement);
|
|
}
|
|
}
|
|
} elseif (is_subclass_of($cast, self::class)) {
|
|
$manifestClass = $cast === Field::class ? $this->getFieldClass($value) : $cast;
|
|
$valueElement = $value;
|
|
$value = new $manifestClass($this->pluginKey);
|
|
$value->loadData($valueElement ?? []);
|
|
} else {
|
|
$value = new $cast($value ?? []);
|
|
}
|
|
}
|
|
|
|
$this->{$key} = $value;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return array<string,string>
|
|
*/
|
|
public static function getPluginErrors(string $pluginKey): array
|
|
{
|
|
return self::$errors[$pluginKey];
|
|
}
|
|
|
|
protected function addError(string $errorKey, string $errorMessage): void
|
|
{
|
|
self::$errors[$this->pluginKey][$errorKey] = $errorMessage;
|
|
}
|
|
|
|
/**
|
|
* @param array<mixed> $data
|
|
*/
|
|
private function getFieldClass(array $data): string
|
|
{
|
|
$fieldType = $data['type'] ?? 'text';
|
|
return rtrim(Field::class, "\Field") . '\\Fields\\' . str_replace(
|
|
' ',
|
|
'',
|
|
ucwords(str_replace('-', ' ', $fieldType))
|
|
);
|
|
}
|
|
}
|