You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
81 lines
2.3 KiB
81 lines
2.3 KiB
<?php
|
|
|
|
namespace App\Http\Middleware;
|
|
|
|
use App\Attributes\Seo;
|
|
use App\UI\Actions\SetSeoMetadata;
|
|
use Closure;
|
|
use Exception;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Routing\ViewController;
|
|
use ReflectionException;
|
|
use ReflectionMethod;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
|
|
class HandleSeoAttributes
|
|
{
|
|
public function __construct(
|
|
protected SetSeoMetadata $setSeo
|
|
) {}
|
|
|
|
public function handle(Request $request, Closure $next): Response
|
|
{
|
|
$route = $request->route();
|
|
|
|
if ($route) {
|
|
$seoInstance = $this->getSeoAttributeDirectly($route);
|
|
|
|
if ($seoInstance) {
|
|
$this->setSeo->applySeo($seoInstance, $request->all(), $request);
|
|
}
|
|
}
|
|
|
|
return $next($request);
|
|
}
|
|
|
|
/**
|
|
* Extracts the attribute directly from the route structure safely.
|
|
*
|
|
* @throws Exception
|
|
*/
|
|
private function getSeoAttributeDirectly(mixed $route): ?Seo
|
|
{
|
|
if (isset($route->defaults['seo']) && $route->defaults['seo'] instanceof Seo) {
|
|
return $route->defaults['seo'];
|
|
}
|
|
|
|
try {
|
|
$controller = $route->getController();
|
|
|
|
if ($controller instanceof ViewController) {
|
|
return isset($route->defaults['seo']) && $route->defaults['seo'] instanceof Seo
|
|
? $route->defaults['seo']
|
|
: null;
|
|
}
|
|
|
|
$method = $route->getActionMethod();
|
|
|
|
if ($method === get_class($controller) || (method_exists($controller, '__invoke') && ! method_exists($controller, $method))) {
|
|
$method = '__invoke';
|
|
}
|
|
|
|
if (method_exists($controller, $method)) {
|
|
$reflection = new ReflectionMethod($controller, $method);
|
|
$attributes = $reflection->getAttributes(Seo::class);
|
|
|
|
if (! empty($attributes)) {
|
|
$seoInstance = $attributes[0]->newInstance();
|
|
if (! $seoInstance instanceof Seo) {
|
|
throw new Exception('Expected type of Seo object');
|
|
}
|
|
|
|
return $seoInstance;
|
|
}
|
|
}
|
|
} catch (ReflectionException $e) {
|
|
return null;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|
|
|