1
0
mirror of https://github.com/BookStackApp/BookStack.git synced 2025-10-28 05:14:50 +03:00

Maintenance: Addressed a range of phpstan level 3 issues

This commit is contained in:
Dan Brown
2025-09-03 10:47:45 +01:00
parent cee23de6c5
commit e05ec7da36
26 changed files with 84 additions and 151 deletions

View File

@@ -2,33 +2,18 @@
namespace BookStack\Access; namespace BookStack\Access;
use BookStack\Users\Models\User;
use Illuminate\Contracts\Auth\Authenticatable; use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Auth\UserProvider; use Illuminate\Contracts\Auth\UserProvider;
use Illuminate\Database\Eloquent\Model;
class ExternalBaseUserProvider implements UserProvider class ExternalBaseUserProvider implements UserProvider
{ {
public function __construct(
protected string $model
) {
}
/**
* Create a new instance of the model.
*/
public function createModel(): Model
{
$class = '\\' . ltrim($this->model, '\\');
return new $class();
}
/** /**
* Retrieve a user by their unique identifier. * Retrieve a user by their unique identifier.
*/ */
public function retrieveById(mixed $identifier): ?Authenticatable public function retrieveById(mixed $identifier): ?Authenticatable
{ {
return $this->createModel()->newQuery()->find($identifier); return User::query()->find($identifier);
} }
/** /**
@@ -59,10 +44,7 @@ class ExternalBaseUserProvider implements UserProvider
*/ */
public function retrieveByCredentials(array $credentials): ?Authenticatable public function retrieveByCredentials(array $credentials): ?Authenticatable
{ {
// Search current user base by looking up a uid return User::query()
$model = $this->createModel();
return $model->newQuery()
->where('external_auth_id', $credentials['external_auth_id']) ->where('external_auth_id', $credentials['external_auth_id'])
->first(); ->first();
} }

View File

@@ -4,7 +4,7 @@ namespace BookStack\Access\Guards;
use BookStack\Access\RegistrationService; use BookStack\Access\RegistrationService;
use Illuminate\Auth\GuardHelpers; use Illuminate\Auth\GuardHelpers;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract; use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Auth\StatefulGuard; use Illuminate\Contracts\Auth\StatefulGuard;
use Illuminate\Contracts\Auth\UserProvider; use Illuminate\Contracts\Auth\UserProvider;
use Illuminate\Contracts\Session\Session; use Illuminate\Contracts\Session\Session;
@@ -24,43 +24,31 @@ class ExternalBaseSessionGuard implements StatefulGuard
* The name of the Guard. Typically "session". * The name of the Guard. Typically "session".
* *
* Corresponds to guard name in authentication configuration. * Corresponds to guard name in authentication configuration.
*
* @var string
*/ */
protected $name; protected readonly string $name;
/** /**
* The user we last attempted to retrieve. * The user we last attempted to retrieve.
*
* @var \Illuminate\Contracts\Auth\Authenticatable
*/ */
protected $lastAttempted; protected Authenticatable $lastAttempted;
/** /**
* The session used by the guard. * The session used by the guard.
*
* @var \Illuminate\Contracts\Session\Session
*/ */
protected $session; protected Session $session;
/** /**
* Indicates if the logout method has been called. * Indicates if the logout method has been called.
*
* @var bool
*/ */
protected $loggedOut = false; protected bool $loggedOut = false;
/** /**
* Service to handle common registration actions. * Service to handle common registration actions.
*
* @var RegistrationService
*/ */
protected $registrationService; protected RegistrationService $registrationService;
/** /**
* Create a new authentication guard. * Create a new authentication guard.
*
* @return void
*/ */
public function __construct(string $name, UserProvider $provider, Session $session, RegistrationService $registrationService) public function __construct(string $name, UserProvider $provider, Session $session, RegistrationService $registrationService)
{ {
@@ -72,13 +60,11 @@ class ExternalBaseSessionGuard implements StatefulGuard
/** /**
* Get the currently authenticated user. * Get the currently authenticated user.
*
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/ */
public function user() public function user(): Authenticatable|null
{ {
if ($this->loggedOut) { if ($this->loggedOut) {
return; return null;
} }
// If we've already retrieved the user for the current request we can just // If we've already retrieved the user for the current request we can just
@@ -101,13 +87,11 @@ class ExternalBaseSessionGuard implements StatefulGuard
/** /**
* Get the ID for the currently authenticated user. * Get the ID for the currently authenticated user.
*
* @return int|null
*/ */
public function id() public function id(): int|null
{ {
if ($this->loggedOut) { if ($this->loggedOut) {
return; return null;
} }
return $this->user() return $this->user()
@@ -117,12 +101,8 @@ class ExternalBaseSessionGuard implements StatefulGuard
/** /**
* Log a user into the application without sessions or cookies. * Log a user into the application without sessions or cookies.
*
* @param array $credentials
*
* @return bool
*/ */
public function once(array $credentials = []) public function once(array $credentials = []): bool
{ {
if ($this->validate($credentials)) { if ($this->validate($credentials)) {
$this->setUser($this->lastAttempted); $this->setUser($this->lastAttempted);
@@ -135,12 +115,8 @@ class ExternalBaseSessionGuard implements StatefulGuard
/** /**
* Log the given user ID into the application without sessions or cookies. * Log the given user ID into the application without sessions or cookies.
*
* @param mixed $id
*
* @return \Illuminate\Contracts\Auth\Authenticatable|false
*/ */
public function onceUsingId($id) public function onceUsingId($id): Authenticatable|false
{ {
if (!is_null($user = $this->provider->retrieveById($id))) { if (!is_null($user = $this->provider->retrieveById($id))) {
$this->setUser($user); $this->setUser($user);
@@ -153,38 +129,26 @@ class ExternalBaseSessionGuard implements StatefulGuard
/** /**
* Validate a user's credentials. * Validate a user's credentials.
*
* @param array $credentials
*
* @return bool
*/ */
public function validate(array $credentials = []) public function validate(array $credentials = []): bool
{ {
return false; return false;
} }
/** /**
* Attempt to authenticate a user using the given credentials. * Attempt to authenticate a user using the given credentials.
*
* @param array $credentials
* @param bool $remember * @param bool $remember
*
* @return bool
*/ */
public function attempt(array $credentials = [], $remember = false) public function attempt(array $credentials = [], $remember = false): bool
{ {
return false; return false;
} }
/** /**
* Log the given user ID into the application. * Log the given user ID into the application.
*
* @param mixed $id
* @param bool $remember * @param bool $remember
*
* @return \Illuminate\Contracts\Auth\Authenticatable|false
*/ */
public function loginUsingId($id, $remember = false) public function loginUsingId(mixed $id, $remember = false): Authenticatable|false
{ {
// Always return false as to disable this method, // Always return false as to disable this method,
// Logins should route through LoginService. // Logins should route through LoginService.
@@ -194,12 +158,9 @@ class ExternalBaseSessionGuard implements StatefulGuard
/** /**
* Log a user into the application. * Log a user into the application.
* *
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @param bool $remember * @param bool $remember
*
* @return void
*/ */
public function login(AuthenticatableContract $user, $remember = false) public function login(Authenticatable $user, $remember = false): void
{ {
$this->updateSession($user->getAuthIdentifier()); $this->updateSession($user->getAuthIdentifier());
@@ -208,12 +169,8 @@ class ExternalBaseSessionGuard implements StatefulGuard
/** /**
* Update the session with the given ID. * Update the session with the given ID.
*
* @param string $id
*
* @return void
*/ */
protected function updateSession($id) protected function updateSession(string|int $id): void
{ {
$this->session->put($this->getName(), $id); $this->session->put($this->getName(), $id);
@@ -222,10 +179,8 @@ class ExternalBaseSessionGuard implements StatefulGuard
/** /**
* Log the user out of the application. * Log the user out of the application.
*
* @return void
*/ */
public function logout() public function logout(): void
{ {
$this->clearUserDataFromStorage(); $this->clearUserDataFromStorage();
@@ -239,62 +194,48 @@ class ExternalBaseSessionGuard implements StatefulGuard
/** /**
* Remove the user data from the session and cookies. * Remove the user data from the session and cookies.
*
* @return void
*/ */
protected function clearUserDataFromStorage() protected function clearUserDataFromStorage(): void
{ {
$this->session->remove($this->getName()); $this->session->remove($this->getName());
} }
/** /**
* Get the last user we attempted to authenticate. * Get the last user we attempted to authenticate.
*
* @return \Illuminate\Contracts\Auth\Authenticatable
*/ */
public function getLastAttempted() public function getLastAttempted(): Authenticatable
{ {
return $this->lastAttempted; return $this->lastAttempted;
} }
/** /**
* Get a unique identifier for the auth session value. * Get a unique identifier for the auth session value.
*
* @return string
*/ */
public function getName() public function getName(): string
{ {
return 'login_' . $this->name . '_' . sha1(static::class); return 'login_' . $this->name . '_' . sha1(static::class);
} }
/** /**
* Determine if the user was authenticated via "remember me" cookie. * Determine if the user was authenticated via "remember me" cookie.
*
* @return bool
*/ */
public function viaRemember() public function viaRemember(): bool
{ {
return false; return false;
} }
/** /**
* Return the currently cached user. * Return the currently cached user.
*
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/ */
public function getUser() public function getUser(): Authenticatable|null
{ {
return $this->user; return $this->user;
} }
/** /**
* Set the current user. * Set the current user.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
*
* @return $this
*/ */
public function setUser(AuthenticatableContract $user) public function setUser(Authenticatable $user): self
{ {
$this->user = $user; $this->user = $user;

View File

@@ -39,7 +39,7 @@ class Comment extends Model implements Loggable, OwnableInterface
/** /**
* Get the parent comment this is in reply to (if existing). * Get the parent comment this is in reply to (if existing).
* @return BelongsTo<Comment, Comment> * @return BelongsTo<Comment, $this>
*/ */
public function parent(): BelongsTo public function parent(): BelongsTo
{ {

View File

@@ -59,8 +59,8 @@ class AuthServiceProvider extends ServiceProvider
*/ */
public function register(): void public function register(): void
{ {
Auth::provider('external-users', function ($app, array $config) { Auth::provider('external-users', function () {
return new ExternalBaseUserProvider($config['model']); return new ExternalBaseUserProvider();
}); });
// Bind and provide the default system user as a singleton to the app instance when needed. // Bind and provide the default system user as a singleton to the app instance when needed.

View File

@@ -15,7 +15,7 @@ class EventServiceProvider extends ServiceProvider
/** /**
* The event listener mappings for the application. * The event listener mappings for the application.
* *
* @var array<class-string, array<int, class-string>> * @var array<class-string, array<int, string>>
*/ */
protected $listen = [ protected $listen = [
SocialiteWasCalled::class => [ SocialiteWasCalled::class => [

View File

@@ -98,7 +98,7 @@ class PageRevisionController extends Controller
throw new NotFoundException(); throw new NotFoundException();
} }
$prev = $revision->getPrevious(); $prev = $revision->getPreviousRevision();
$prevContent = $prev->html ?? ''; $prevContent = $prev->html ?? '';
$diff = Diff::excecute($prevContent, $revision->html); $diff = Diff::excecute($prevContent, $revision->html);

View File

@@ -60,7 +60,7 @@ class PageRevision extends Model implements Loggable
/** /**
* Get the previous revision for the same page if existing. * Get the previous revision for the same page if existing.
*/ */
public function getPrevious(): ?PageRevision public function getPreviousRevision(): ?PageRevision
{ {
$id = static::newQuery()->where('page_id', '=', $this->page_id) $id = static::newQuery()->where('page_id', '=', $this->page_id)
->where('id', '<', $this->id) ->where('id', '<', $this->id)

View File

@@ -94,7 +94,7 @@ class Handler extends ExceptionHandler
* If the callable returns a response, this response will be returned * If the callable returns a response, this response will be returned
* to the request upon error. * to the request upon error.
*/ */
public function prepareForOutOfMemory(callable $onOutOfMemory) public function prepareForOutOfMemory(callable $onOutOfMemory): void
{ {
$this->onOutOfMemory = $onOutOfMemory; $this->onOutOfMemory = $onOutOfMemory;
} }
@@ -102,7 +102,7 @@ class Handler extends ExceptionHandler
/** /**
* Forget the current out of memory handler, if existing. * Forget the current out of memory handler, if existing.
*/ */
public function forgetOutOfMemoryHandler() public function forgetOutOfMemoryHandler(): void
{ {
$this->onOutOfMemory = null; $this->onOutOfMemory = null;
} }

View File

@@ -39,6 +39,9 @@ class ImportRepo
return $this->queryVisible()->get(); return $this->queryVisible()->get();
} }
/**
* @return Builder<Import>
*/
public function queryVisible(): Builder public function queryVisible(): Builder
{ {
$query = Import::query(); $query = Import::query();

View File

@@ -6,7 +6,7 @@ use BookStack\Exports\ZipExports\ZipExportFiles;
use BookStack\Exports\ZipExports\ZipValidationHelper; use BookStack\Exports\ZipExports\ZipValidationHelper;
use BookStack\Uploads\Attachment; use BookStack\Uploads\Attachment;
class ZipExportAttachment extends ZipExportModel final class ZipExportAttachment extends ZipExportModel
{ {
public ?int $id = null; public ?int $id = null;
public string $name; public string $name;
@@ -52,9 +52,9 @@ class ZipExportAttachment extends ZipExportModel
return $context->validateData($data, $rules); return $context->validateData($data, $rules);
} }
public static function fromArray(array $data): self public static function fromArray(array $data): static
{ {
$model = new self(); $model = new static();
$model->id = $data['id'] ?? null; $model->id = $data['id'] ?? null;
$model->name = $data['name']; $model->name = $data['name'];

View File

@@ -8,7 +8,7 @@ use BookStack\Entities\Models\Page;
use BookStack\Exports\ZipExports\ZipExportFiles; use BookStack\Exports\ZipExports\ZipExportFiles;
use BookStack\Exports\ZipExports\ZipValidationHelper; use BookStack\Exports\ZipExports\ZipValidationHelper;
class ZipExportBook extends ZipExportModel final class ZipExportBook extends ZipExportModel
{ {
public ?int $id = null; public ?int $id = null;
public string $name; public string $name;
@@ -101,9 +101,9 @@ class ZipExportBook extends ZipExportModel
return $errors; return $errors;
} }
public static function fromArray(array $data): self public static function fromArray(array $data): static
{ {
$model = new self(); $model = new static();
$model->id = $data['id'] ?? null; $model->id = $data['id'] ?? null;
$model->name = $data['name']; $model->name = $data['name'];

View File

@@ -7,7 +7,7 @@ use BookStack\Entities\Models\Page;
use BookStack\Exports\ZipExports\ZipExportFiles; use BookStack\Exports\ZipExports\ZipExportFiles;
use BookStack\Exports\ZipExports\ZipValidationHelper; use BookStack\Exports\ZipExports\ZipValidationHelper;
class ZipExportChapter extends ZipExportModel final class ZipExportChapter extends ZipExportModel
{ {
public ?int $id = null; public ?int $id = null;
public string $name; public string $name;
@@ -79,9 +79,9 @@ class ZipExportChapter extends ZipExportModel
return $errors; return $errors;
} }
public static function fromArray(array $data): self public static function fromArray(array $data): static
{ {
$model = new self(); $model = new static();
$model->id = $data['id'] ?? null; $model->id = $data['id'] ?? null;
$model->name = $data['name']; $model->name = $data['name'];

View File

@@ -7,7 +7,7 @@ use BookStack\Exports\ZipExports\ZipValidationHelper;
use BookStack\Uploads\Image; use BookStack\Uploads\Image;
use Illuminate\Validation\Rule; use Illuminate\Validation\Rule;
class ZipExportImage extends ZipExportModel final class ZipExportImage extends ZipExportModel
{ {
public ?int $id = null; public ?int $id = null;
public string $name; public string $name;
@@ -43,9 +43,9 @@ class ZipExportImage extends ZipExportModel
return $context->validateData($data, $rules); return $context->validateData($data, $rules);
} }
public static function fromArray(array $data): self public static function fromArray(array $data): static
{ {
$model = new self(); $model = new static();
$model->id = $data['id'] ?? null; $model->id = $data['id'] ?? null;
$model->name = $data['name']; $model->name = $data['name'];

View File

@@ -30,12 +30,12 @@ abstract class ZipExportModel implements JsonSerializable
/** /**
* Decode the array of data into this export model. * Decode the array of data into this export model.
*/ */
abstract public static function fromArray(array $data): self; abstract public static function fromArray(array $data): static;
/** /**
* Decode an array of array data into an array of export models. * Decode an array of array data into an array of export models.
* @param array[] $data * @param array[] $data
* @return self[] * @return static[]
*/ */
public static function fromManyArray(array $data): array public static function fromManyArray(array $data): array
{ {

View File

@@ -7,7 +7,7 @@ use BookStack\Entities\Tools\PageContent;
use BookStack\Exports\ZipExports\ZipExportFiles; use BookStack\Exports\ZipExports\ZipExportFiles;
use BookStack\Exports\ZipExports\ZipValidationHelper; use BookStack\Exports\ZipExports\ZipValidationHelper;
class ZipExportPage extends ZipExportModel final class ZipExportPage extends ZipExportModel
{ {
public ?int $id = null; public ?int $id = null;
public string $name; public string $name;
@@ -86,9 +86,9 @@ class ZipExportPage extends ZipExportModel
return $errors; return $errors;
} }
public static function fromArray(array $data): self public static function fromArray(array $data): static
{ {
$model = new self(); $model = new static();
$model->id = $data['id'] ?? null; $model->id = $data['id'] ?? null;
$model->name = $data['name']; $model->name = $data['name'];

View File

@@ -5,7 +5,7 @@ namespace BookStack\Exports\ZipExports\Models;
use BookStack\Activity\Models\Tag; use BookStack\Activity\Models\Tag;
use BookStack\Exports\ZipExports\ZipValidationHelper; use BookStack\Exports\ZipExports\ZipValidationHelper;
class ZipExportTag extends ZipExportModel final class ZipExportTag extends ZipExportModel
{ {
public string $name; public string $name;
public ?string $value = null; public ?string $value = null;
@@ -39,9 +39,9 @@ class ZipExportTag extends ZipExportModel
return $context->validateData($data, $rules); return $context->validateData($data, $rules);
} }
public static function fromArray(array $data): self public static function fromArray(array $data): static
{ {
$model = new self(); $model = new static();
$model->name = $data['name']; $model->name = $data['name'];
$model->value = $data['value'] ?? null; $model->value = $data['value'] ?? null;

View File

@@ -9,6 +9,8 @@ class Kernel extends HttpKernel
/** /**
* The application's global HTTP middleware stack. * The application's global HTTP middleware stack.
* These middleware are run during every request to your application. * These middleware are run during every request to your application.
*
* @var list<class-string>
*/ */
protected $middleware = [ protected $middleware = [
\BookStack\Http\Middleware\PreventRequestsDuringMaintenance::class, \BookStack\Http\Middleware\PreventRequestsDuringMaintenance::class,
@@ -21,7 +23,7 @@ class Kernel extends HttpKernel
/** /**
* The application's route middleware groups. * The application's route middleware groups.
* *
* @var array * @var array<string, array<int, class-string>>
*/ */
protected $middlewareGroups = [ protected $middlewareGroups = [
'web' => [ 'web' => [
@@ -47,7 +49,7 @@ class Kernel extends HttpKernel
/** /**
* The application's middleware aliases. * The application's middleware aliases.
* *
* @var array * @var array<string, class-string>
*/ */
protected $middlewareAliases = [ protected $middlewareAliases = [
'auth' => \BookStack\Http\Middleware\Authenticate::class, 'auth' => \BookStack\Http\Middleware\Authenticate::class,

View File

@@ -9,7 +9,7 @@ class EncryptCookies extends Middleware
/** /**
* The names of the cookies that should not be encrypted. * The names of the cookies that should not be encrypted.
* *
* @var array * @var array<int, string>
*/ */
protected $except = [ protected $except = [
// //

View File

@@ -9,7 +9,7 @@ class PreventRequestsDuringMaintenance extends Middleware
/** /**
* The URIs that should be reachable while maintenance mode is enabled. * The URIs that should be reachable while maintenance mode is enabled.
* *
* @var array * @var array<int, string>
*/ */
protected $except = [ protected $except = [
// //

View File

@@ -9,7 +9,7 @@ class TrimStrings extends Middleware
/** /**
* The names of the attributes that should not be trimmed. * The names of the attributes that should not be trimmed.
* *
* @var array * @var array<int, string>
*/ */
protected $except = [ protected $except = [
'password', 'password',

View File

@@ -11,7 +11,7 @@ class TrustProxies extends Middleware
/** /**
* The trusted proxies for this application. * The trusted proxies for this application.
* *
* @var array * @var array<int,string>|string|null
*/ */
protected $proxies; protected $proxies;

View File

@@ -16,7 +16,7 @@ class VerifyCsrfToken extends Middleware
/** /**
* The URIs that should be excluded from CSRF verification. * The URIs that should be excluded from CSRF verification.
* *
* @var array * @var array<int, string>
*/ */
protected $except = [ protected $except = [
'saml2/*', 'saml2/*',

View File

@@ -14,6 +14,9 @@ class SearchOptionSet
*/ */
protected array $options = []; protected array $options = [];
/**
* @param T[] $options
*/
public function __construct(array $options = []) public function __construct(array $options = [])
{ {
$this->options = $options; $this->options = $options;

View File

@@ -285,7 +285,7 @@ class SearchRunner
* *
* @param array<string, int> $termCounts * @param array<string, int> $termCounts
* *
* @return array<string, int> * @return array<string, float>
*/ */
protected function rawTermCountsToAdjustments(array $termCounts): array protected function rawTermCountsToAdjustments(array $termCounts): array
{ {

View File

@@ -26,6 +26,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Notifications\Notifiable; use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
@@ -64,7 +65,7 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
/** /**
* The attributes that are mass assignable. * The attributes that are mass assignable.
* *
* @var array * @var list<string>
*/ */
protected $fillable = ['name', 'email']; protected $fillable = ['name', 'email'];
@@ -73,7 +74,7 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
/** /**
* The attributes excluded from the model's JSON form. * The attributes excluded from the model's JSON form.
* *
* @var array * @var list<string>
*/ */
protected $hidden = [ protected $hidden = [
'password', 'remember_token', 'system_name', 'email_confirmed', 'external_auth_id', 'email', 'password', 'remember_token', 'system_name', 'email_confirmed', 'external_auth_id', 'email',
@@ -118,14 +119,10 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
/** /**
* The roles that belong to the user. * The roles that belong to the user.
* *
* @return BelongsToMany * @return BelongsToMany<Role, $this>
*/ */
public function roles() public function roles(): BelongsToMany
{ {
if ($this->id === 0) {
return;
}
return $this->belongsToMany(Role::class); return $this->belongsToMany(Role::class);
} }

View File

@@ -42,7 +42,7 @@ class OutOfMemoryHandler
} }
/** /**
* Forget the handler so no action is taken place on out of memory. * Forget the handler, so no action is taken place on out of memory.
*/ */
public function forget(): void public function forget(): void
{ {
@@ -53,6 +53,11 @@ class OutOfMemoryHandler
protected function getHandler(): Handler protected function getHandler(): Handler
{ {
/**
* We want to resolve our specific BookStack handling via the set app handler
* singleton, but phpstan will only infer based on the interface.
* @phpstan-ignore return.type
*/
return app()->make(ExceptionHandler::class); return app()->make(ExceptionHandler::class);
} }
} }