2022-06-01 09:47:31 +02:00
|
|
|
<?php
|
|
|
|
|
2022-11-18 18:06:46 +01:00
|
|
|
namespace Core\Objects\Router;
|
2022-06-01 09:47:31 +02:00
|
|
|
|
2022-11-27 12:33:27 +01:00
|
|
|
use Core\Driver\SQL\SQL;
|
2022-11-18 18:06:46 +01:00
|
|
|
use Core\Elements\Document;
|
|
|
|
use Core\Objects\Context;
|
2024-03-28 11:56:17 +01:00
|
|
|
use Core\Objects\DatabaseEntity\Attribute\Transient;
|
2022-11-27 12:33:27 +01:00
|
|
|
use Core\Objects\DatabaseEntity\Route;
|
2022-11-18 18:06:46 +01:00
|
|
|
use Core\Objects\Search\Searchable;
|
|
|
|
use Core\Objects\Search\SearchQuery;
|
2022-11-27 12:33:27 +01:00
|
|
|
use JetBrains\PhpStorm\Pure;
|
2022-06-01 09:47:31 +02:00
|
|
|
use ReflectionException;
|
|
|
|
|
2022-11-27 12:33:27 +01:00
|
|
|
class DocumentRoute extends Route {
|
2022-06-01 09:47:31 +02:00
|
|
|
|
2022-08-20 22:17:17 +02:00
|
|
|
use Searchable;
|
|
|
|
|
2024-03-28 11:56:17 +01:00
|
|
|
#[Transient]
|
2022-06-01 09:47:31 +02:00
|
|
|
private array $args;
|
2024-03-28 11:56:17 +01:00
|
|
|
|
|
|
|
#[Transient]
|
2022-11-27 12:33:27 +01:00
|
|
|
private ?\ReflectionClass $reflectionClass = null;
|
2022-06-01 09:47:31 +02:00
|
|
|
|
|
|
|
public function __construct(string $pattern, bool $exact, string $className, ...$args) {
|
2022-11-27 12:33:27 +01:00
|
|
|
parent::__construct("dynamic", $pattern, $className, $exact);
|
2022-06-01 09:47:31 +02:00
|
|
|
$this->args = $args;
|
2022-11-27 12:33:27 +01:00
|
|
|
$this->extra = json_encode($args);
|
|
|
|
}
|
|
|
|
|
2022-11-27 15:58:44 +01:00
|
|
|
protected function readExtra() {
|
|
|
|
parent::readExtra();
|
2023-01-15 00:32:17 +01:00
|
|
|
$this->args = json_decode($this->extra) ?? [];
|
2022-11-27 12:33:27 +01:00
|
|
|
}
|
|
|
|
|
2022-11-27 15:58:44 +01:00
|
|
|
public function preInsert(array &$row) {
|
|
|
|
parent::preInsert($row);
|
2024-03-29 14:06:27 +01:00
|
|
|
$this->extra = json_encode($this->args, JSON_UNESCAPED_SLASHES);
|
2022-11-27 15:58:44 +01:00
|
|
|
}
|
|
|
|
|
2022-11-27 12:33:27 +01:00
|
|
|
#[Pure] private function getClassName(): string {
|
|
|
|
return $this->getTarget();
|
2022-06-01 09:47:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private function loadClass(): bool {
|
|
|
|
|
|
|
|
if ($this->reflectionClass === null) {
|
|
|
|
try {
|
2022-11-27 12:33:27 +01:00
|
|
|
$file = getClassPath($this->getClassName());
|
2022-06-01 09:47:31 +02:00
|
|
|
if (file_exists($file)) {
|
2022-11-27 12:33:27 +01:00
|
|
|
$this->reflectionClass = new \ReflectionClass($this->getClassName());
|
2022-06-01 09:47:31 +02:00
|
|
|
if ($this->reflectionClass->isSubclassOf(Document::class)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (ReflectionException $exception) {
|
|
|
|
$this->reflectionClass = null;
|
2022-08-20 22:17:17 +02:00
|
|
|
throw $exception;
|
2022-06-01 09:47:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
$this->reflectionClass = null;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2024-03-27 20:50:57 +01:00
|
|
|
public function match(string $url): bool|array {
|
2022-06-01 09:47:31 +02:00
|
|
|
$match = parent::match($url);
|
|
|
|
if ($match === false || !$this->loadClass()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $match;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function getArgs(): array {
|
2022-11-27 12:33:27 +01:00
|
|
|
return array_merge(parent::getArgs(), [$this->getClassName()], $this->args);
|
2022-06-01 09:47:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public function call(Router $router, array $params): string {
|
2022-11-27 12:33:27 +01:00
|
|
|
$className = $this->getClassName();
|
|
|
|
|
2022-06-01 09:47:31 +02:00
|
|
|
try {
|
2022-08-20 22:17:17 +02:00
|
|
|
if (!$this->loadClass()) {
|
2024-04-22 19:01:04 +02:00
|
|
|
$router->getLogger()->warning("Error loading class: $className");
|
2022-11-27 12:33:27 +01:00
|
|
|
return $router->returnStatusCode(500, [ "message" => "Error loading class: $className"]);
|
2022-08-20 22:17:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
$args = array_merge([$router], $this->args, $params);
|
2022-06-01 09:47:31 +02:00
|
|
|
$document = $this->reflectionClass->newInstanceArgs($args);
|
2022-08-20 22:17:17 +02:00
|
|
|
return $document->load($params);
|
2022-06-01 09:47:31 +02:00
|
|
|
} catch (\ReflectionException $e) {
|
2024-04-22 19:01:04 +02:00
|
|
|
$router->getLogger()->error("Error loading class: $className: " . $e->getMessage());
|
2022-11-27 12:33:27 +01:00
|
|
|
return $router->returnStatusCode(500, [ "message" => "Error loading class $className: " . $e->getMessage()]);
|
2022-06-01 09:47:31 +02:00
|
|
|
}
|
|
|
|
}
|
2022-08-20 22:17:17 +02:00
|
|
|
|
|
|
|
public function doSearch(Context $context, SearchQuery $query): array {
|
|
|
|
try {
|
|
|
|
if ($this->loadClass()) {
|
|
|
|
$args = array_merge([$context->router], $this->args);
|
|
|
|
$document = $this->reflectionClass->newInstanceArgs($args);
|
|
|
|
if ($document->isSearchable()) {
|
|
|
|
return $document->doSearch($query, $this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return [];
|
|
|
|
} catch (\ReflectionException) {
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
}
|
2022-06-01 09:47:31 +02:00
|
|
|
}
|