mirror of
https://github.com/standardebooks/web.git
synced 2025-07-18 20:36:38 -04:00
Move enums into their own namespace
This commit is contained in:
parent
c3c588cc1b
commit
be5574eaec
45 changed files with 164 additions and 154 deletions
|
@ -48,8 +48,8 @@ class Artwork{
|
|||
public ?bool $IsPublishedInUs = null;
|
||||
public ?string $Exception = null;
|
||||
public ?string $Notes = null;
|
||||
public ?ImageMimeType $MimeType = null;
|
||||
public ?ArtworkStatusType $Status = null;
|
||||
public ?Enums\ImageMimeType $MimeType = null;
|
||||
public ?Enums\ArtworkStatusType $Status = null;
|
||||
|
||||
protected ?string $_UrlName = null;
|
||||
protected ?string $_Url = null;
|
||||
|
@ -290,7 +290,7 @@ class Artwork{
|
|||
return true;
|
||||
}
|
||||
|
||||
if(($user->Benefits->CanReviewArtwork || $user->UserId == $this->SubmitterUserId) && ($this->Status == ArtworkStatusType::Unverified || $this->Status == ArtworkStatusType::Declined)){
|
||||
if(($user->Benefits->CanReviewArtwork || $user->UserId == $this->SubmitterUserId) && ($this->Status == Enums\ArtworkStatusType::Unverified || $this->Status == Enums\ArtworkStatusType::Declined)){
|
||||
// Editors can edit an artwork, and submitters can edit their own artwork, if it's not yet approved.
|
||||
return true;
|
||||
}
|
||||
|
@ -308,7 +308,7 @@ class Artwork{
|
|||
return true;
|
||||
}
|
||||
|
||||
if($user->Benefits->CanReviewArtwork && $user->UserId != $this->SubmitterUserId && ($this->Status == ArtworkStatusType::Unverified || $this->Status == ArtworkStatusType::Declined)){
|
||||
if($user->Benefits->CanReviewArtwork && $user->UserId != $this->SubmitterUserId && ($this->Status == Enums\ArtworkStatusType::Unverified || $this->Status == Enums\ArtworkStatusType::Declined)){
|
||||
// Editors can change the status of artwork they did not submit themselves, and that is not yet approved.
|
||||
return true;
|
||||
}
|
||||
|
@ -661,7 +661,7 @@ class Artwork{
|
|||
* @throws Exceptions\InvalidImageUploadException
|
||||
*/
|
||||
public function Create(?string $imagePath = null): void{
|
||||
$this->MimeType = ImageMimeType::FromFile($imagePath);
|
||||
$this->MimeType = Enums\ImageMimeType::FromFile($imagePath);
|
||||
|
||||
$this->Validate($imagePath, true);
|
||||
|
||||
|
@ -729,7 +729,7 @@ class Artwork{
|
|||
$this->_UrlName = null;
|
||||
|
||||
if($imagePath !== null){
|
||||
$this->MimeType = ImageMimeType::FromFile($imagePath);
|
||||
$this->MimeType = Enums\ImageMimeType::FromFile($imagePath);
|
||||
|
||||
// Manually set the updated timestamp, because if we only update the image and nothing else, the row's updated timestamp won't change automatically.
|
||||
$this->Updated = NOW;
|
||||
|
@ -880,7 +880,7 @@ class Artwork{
|
|||
$artwork->CompletedYear = HttpInput::Int(POST, 'artwork-year');
|
||||
$artwork->CompletedYearIsCirca = HttpInput::Bool(POST, 'artwork-year-is-circa') ?? false;
|
||||
$artwork->Tags = HttpInput::Str(POST, 'artwork-tags') ?? [];
|
||||
$artwork->Status = ArtworkStatusType::tryFrom(HttpInput::Str(POST, 'artwork-status') ?? '') ?? ArtworkStatusType::Unverified;
|
||||
$artwork->Status = Enums\ArtworkStatusType::tryFrom(HttpInput::Str(POST, 'artwork-status') ?? '') ?? Enums\ArtworkStatusType::Unverified;
|
||||
$artwork->EbookUrl = HttpInput::Str(POST, 'artwork-ebook-url');
|
||||
$artwork->IsPublishedInUs = HttpInput::Bool(POST, 'artwork-is-published-in-us') ?? false;
|
||||
$artwork->PublicationYear = HttpInput::Int(POST, 'artwork-publication-year');
|
||||
|
|
|
@ -4,7 +4,7 @@ use function Safe\preg_replace;
|
|||
|
||||
class ArtworkTag extends Tag{
|
||||
public function __construct(){
|
||||
$this->Type = TagType::Artwork;
|
||||
$this->Type = Enums\TagType::Artwork;
|
||||
}
|
||||
|
||||
// *******
|
||||
|
@ -45,7 +45,7 @@ class ArtworkTag extends Tag{
|
|||
$error->Add(new Exceptions\InvalidArtworkTagNameException());
|
||||
}
|
||||
|
||||
if($this->Type != TagType::Artwork){
|
||||
if($this->Type != Enums\TagType::Artwork){
|
||||
$error->Add(new Exceptions\InvalidArtworkTagTypeException($this->Type));
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ class ArtworkTag extends Tag{
|
|||
from Tags
|
||||
where Name = ?
|
||||
and Type = ?
|
||||
', [$artworkTag->Name, TagType::Artwork], ArtworkTag::class);
|
||||
', [$artworkTag->Name, Enums\TagType::Artwork], ArtworkTag::class);
|
||||
|
||||
if(isset($result[0])){
|
||||
return $result[0];
|
||||
|
|
|
@ -10,7 +10,7 @@ class Collection{
|
|||
public int $CollectionId;
|
||||
public string $Name;
|
||||
public string $UrlName;
|
||||
public ?CollectionType $Type = null;
|
||||
public ?Enums\CollectionType $Type = null;
|
||||
protected ?string $_Url = null;
|
||||
|
||||
protected function GetUrl(): string{
|
||||
|
@ -85,7 +85,7 @@ class Collection{
|
|||
$error->Add(new Exceptions\CollectionUrlNameRequiredException());
|
||||
}
|
||||
|
||||
if($this->Type !== null && ($this->Type != CollectionType::Series && $this->Type != CollectionType::Set)){
|
||||
if($this->Type !== null && ($this->Type != Enums\CollectionType::Series && $this->Type != Enums\CollectionType::Set)){
|
||||
$error->Add(new Exceptions\InvalidCollectionTypeException($this->Type));
|
||||
}
|
||||
|
||||
|
|
|
@ -775,7 +775,7 @@ class Ebook{
|
|||
$cm->SequenceNumber = (int)$s;
|
||||
}
|
||||
foreach($xml->xpath('/package/metadata/meta[@refines="#' . $id . '"][@property="collection-type"]') ?: [] as $s){
|
||||
$cm->Collection->Type = CollectionType::tryFrom((string)$s) ?? CollectionType::Unknown;
|
||||
$cm->Collection->Type = Enums\CollectionType::tryFrom((string)$s) ?? Enums\CollectionType::Unknown;
|
||||
}
|
||||
$collectionMemberships[] = $cm;
|
||||
}
|
||||
|
@ -901,32 +901,32 @@ class Ebook{
|
|||
foreach($xml->xpath('/package/metadata/dc:source') ?: [] as $element){
|
||||
$ebookSource = new EbookSource();
|
||||
$ebookSource->Url = (string)$element;
|
||||
$ebookSource->Type = EbookSourceType::Other;
|
||||
$ebookSource->Type = Enums\EbookSourceType::Other;
|
||||
|
||||
if(mb_stripos($ebookSource->Url, 'gutenberg.org/') !== false){
|
||||
$ebookSource->Type = EbookSourceType::ProjectGutenberg;
|
||||
$ebookSource->Type = Enums\EbookSourceType::ProjectGutenberg;
|
||||
}
|
||||
elseif(mb_stripos($ebookSource->Url, 'gutenberg.net.au/') !== false){
|
||||
$ebookSource->Type = EbookSourceType::ProjectGutenbergAustralia;
|
||||
$ebookSource->Type = Enums\EbookSourceType::ProjectGutenbergAustralia;
|
||||
}
|
||||
elseif(mb_stripos($ebookSource->Url, 'gutenberg.ca/') !== false){
|
||||
$ebookSource->Type = EbookSourceType::ProjectGutenbergCanada;
|
||||
$ebookSource->Type = Enums\EbookSourceType::ProjectGutenbergCanada;
|
||||
}
|
||||
elseif(mb_stripos($ebookSource->Url, 'archive.org/details') !== false){
|
||||
// `/details` excludes Wayback Machine URLs which may sometimes occur, for example in Lyrical Ballads.
|
||||
$ebookSource->Type = EbookSourceType::InternetArchive;
|
||||
$ebookSource->Type = Enums\EbookSourceType::InternetArchive;
|
||||
}
|
||||
elseif(mb_stripos($ebookSource->Url, 'hathitrust.org/') !== false){
|
||||
$ebookSource->Type = EbookSourceType::HathiTrust;
|
||||
$ebookSource->Type = Enums\EbookSourceType::HathiTrust;
|
||||
}
|
||||
elseif(mb_stripos($ebookSource->Url, 'wikisource.org/') !== false){
|
||||
$ebookSource->Type = EbookSourceType::Wikisource;
|
||||
$ebookSource->Type = Enums\EbookSourceType::Wikisource;
|
||||
}
|
||||
elseif(mb_stripos($ebookSource->Url, 'books.google.com/') !== false || mb_stripos($ebookSource->Url, 'google.com/books/') !== false){
|
||||
$ebookSource->Type = EbookSourceType::GoogleBooks;
|
||||
$ebookSource->Type = Enums\EbookSourceType::GoogleBooks;
|
||||
}
|
||||
elseif(mb_stripos($ebookSource->Url, 'www.fadedpage.com') !== false){
|
||||
$ebookSource->Type = EbookSourceType::FadedPage;
|
||||
$ebookSource->Type = Enums\EbookSourceType::FadedPage;
|
||||
}
|
||||
|
||||
$sources[] = $ebookSource;
|
||||
|
|
|
@ -4,7 +4,7 @@ use Safe\DateTimeImmutable;
|
|||
|
||||
class EbookSource{
|
||||
public ?int $EbookId = null;
|
||||
public EbookSourceType $Type;
|
||||
public Enums\EbookSourceType $Type;
|
||||
public string $Url;
|
||||
public ?int $SortOrder = null;
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?
|
||||
class EbookTag extends Tag{
|
||||
public function __construct(){
|
||||
$this->Type = TagType::Ebook;
|
||||
$this->Type = Enums\TagType::Ebook;
|
||||
}
|
||||
|
||||
// *******
|
||||
|
@ -48,7 +48,7 @@ class EbookTag extends Tag{
|
|||
$error->Add(new Exceptions\EbookTagNameRequiredException());
|
||||
}
|
||||
|
||||
if($this->Type != TagType::Ebook){
|
||||
if($this->Type != Enums\TagType::Ebook){
|
||||
$error->Add(new Exceptions\InvalidEbookTagTypeException($this->Type));
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,7 @@ class EbookTag extends Tag{
|
|||
from Tags
|
||||
where Name = ?
|
||||
and Type = ?
|
||||
', [$name, TagType::Ebook], EbookTag::class);
|
||||
', [$name, Enums\TagType::Ebook], EbookTag::class);
|
||||
|
||||
if(isset($result[0])){
|
||||
return $result[0];
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
<?
|
||||
namespace Enums;
|
||||
|
||||
enum ArtworkSortType: string{
|
||||
case CreatedNewest = 'created-newest';
|
||||
case ArtistAlpha = 'artist-alpha';
|
|
@ -1,4 +1,6 @@
|
|||
<?
|
||||
namespace Enums;
|
||||
|
||||
enum ArtworkStatusType: string{
|
||||
case Unverified = 'unverified';
|
||||
case Declined = 'declined';
|
|
@ -1,4 +1,6 @@
|
|||
<?
|
||||
namespace Enums;
|
||||
|
||||
enum CollectionType: string{
|
||||
case Series = 'series';
|
||||
case Set = 'set';
|
|
@ -1,4 +1,6 @@
|
|||
<?
|
||||
namespace Enums;
|
||||
|
||||
enum EbookFormatType: string{
|
||||
case Epub = 'epub';
|
||||
case Azw3 = 'azw3';
|
|
@ -1,4 +1,6 @@
|
|||
<?
|
||||
namespace Enums;
|
||||
|
||||
enum EbookSortType: string{
|
||||
case Newest = 'newest';
|
||||
case AuthorAlpha = 'author-alpha';
|
|
@ -1,4 +1,6 @@
|
|||
<?
|
||||
namespace Enums;
|
||||
|
||||
enum EbookSourceType: string{
|
||||
case ProjectGutenberg = 'project_gutenberg';
|
||||
case ProjectGutenbergAustralia = 'project_gutenberg_australia';
|
|
@ -1,4 +1,6 @@
|
|||
<?
|
||||
namespace Enums;
|
||||
|
||||
use function Safe\mime_content_type;
|
||||
|
||||
enum ImageMimeType: string{
|
|
@ -1,4 +1,6 @@
|
|||
<?
|
||||
namespace Enums;
|
||||
|
||||
enum PaymentProcessorType: string{
|
||||
case FracturedAtlas = 'fractured_atlas';
|
||||
}
|
|
@ -1,4 +1,6 @@
|
|||
<?
|
||||
namespace Enums;
|
||||
|
||||
enum TagType: string{
|
||||
case Artwork = 'artwork';
|
||||
case Ebook = 'ebook';
|
|
@ -1,4 +1,6 @@
|
|||
<?
|
||||
namespace Enums;
|
||||
|
||||
enum ViewType: string{
|
||||
case Grid = 'grid';
|
||||
case List = 'list';
|
|
@ -1,13 +1,11 @@
|
|||
<?
|
||||
namespace Exceptions;
|
||||
|
||||
use \TagType;
|
||||
|
||||
class InvalidArtworkTagTypeException extends AppException{
|
||||
/** @var string $message */
|
||||
protected $message = 'Type should be `TagType::Artwork`.';
|
||||
protected $message = 'Type should be `Enums\TagType::Artwork`.';
|
||||
|
||||
public function __construct(?TagType $tagType){
|
||||
public function __construct(?\Enums\TagType $tagType){
|
||||
if($tagType !== null){
|
||||
$this->message .= ' Type provided: ' . $tagType->value;
|
||||
}
|
||||
|
|
|
@ -1,14 +1,11 @@
|
|||
<?php
|
||||
|
||||
<?
|
||||
namespace Exceptions;
|
||||
|
||||
use \CollectionType;
|
||||
|
||||
class InvalidCollectionTypeException extends AppException{
|
||||
/** @var string $message */
|
||||
protected $message = 'Collection type should be `series` or `set` according to the EPUB specification.';
|
||||
|
||||
public function __construct(?CollectionType $collectionType){
|
||||
public function __construct(?\Enums\CollectionType $collectionType){
|
||||
if($collectionType !== null){
|
||||
$this->message .= ' Type provided: ' . $collectionType->value;
|
||||
}
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
<?
|
||||
namespace Exceptions;
|
||||
|
||||
use \TagType;
|
||||
|
||||
class InvalidEbookTagTypeException extends AppException{
|
||||
/** @var string $message */
|
||||
protected $message = 'Type should be `TagType::Ebook`.';
|
||||
protected $message = 'Type should be `Enums\TagType::Ebook`.';
|
||||
|
||||
public function __construct(?TagType $tagType){
|
||||
public function __construct(?\Enums\TagType $tagType){
|
||||
if($tagType !== null){
|
||||
$this->message .= ' Type provided: ' . $tagType->value;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
<?
|
||||
namespace Exceptions;
|
||||
|
||||
class InvalidFileUploadException extends AppException{
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
<?
|
||||
namespace Exceptions;
|
||||
|
||||
class InvalidImageUploadException extends AppException{
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
|
||||
<?
|
||||
namespace Exceptions;
|
||||
|
||||
class InvalidMimeTypeException extends AppException{
|
||||
|
|
|
@ -8,11 +8,11 @@ use function Safe\unlink;
|
|||
|
||||
class Image{
|
||||
public string $Path;
|
||||
public ?ImageMimeType $MimeType = null;
|
||||
public ?Enums\ImageMimeType $MimeType = null;
|
||||
|
||||
public function __construct(string $path){
|
||||
$this->Path = $path;
|
||||
$this->MimeType = ImageMimeType::FromFile($path);
|
||||
$this->MimeType = Enums\ImageMimeType::FromFile($path);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -22,16 +22,16 @@ class Image{
|
|||
*/
|
||||
private function GetImageHandle(){
|
||||
switch($this->MimeType){
|
||||
case ImageMimeType::JPG:
|
||||
case Enums\ImageMimeType::JPG:
|
||||
$handle = \Safe\imagecreatefromjpeg($this->Path);
|
||||
break;
|
||||
case ImageMimeType::BMP:
|
||||
case Enums\ImageMimeType::BMP:
|
||||
$handle = \Safe\imagecreatefrombmp($this->Path);
|
||||
break;
|
||||
case ImageMimeType::PNG:
|
||||
case Enums\ImageMimeType::PNG:
|
||||
$handle = \Safe\imagecreatefrompng($this->Path);
|
||||
break;
|
||||
case ImageMimeType::TIFF:
|
||||
case Enums\ImageMimeType::TIFF:
|
||||
$handle = $this->GetImageHandleFromTiff();
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -16,7 +16,7 @@ class Library{
|
|||
* @param array<string> $tags
|
||||
* @return array{ebooks: array<Ebook>, ebooksCount: int}
|
||||
*/
|
||||
public static function FilterEbooks(string $query = null, array $tags = [], EbookSortType $sort = null, int $page = 1, int $perPage = EBOOKS_PER_PAGE): array{
|
||||
public static function FilterEbooks(string $query = null, array $tags = [], Enums\EbookSortType $sort = null, int $page = 1, int $perPage = EBOOKS_PER_PAGE): array{
|
||||
$limit = $perPage;
|
||||
$offset = (($page - 1) * $perPage);
|
||||
$joinContributors = '';
|
||||
|
@ -25,15 +25,15 @@ class Library{
|
|||
$whereCondition = 'where true';
|
||||
|
||||
$orderBy = 'e.EbookCreated desc';
|
||||
if($sort == EbookSortType::AuthorAlpha){
|
||||
if($sort == Enums\EbookSortType::AuthorAlpha){
|
||||
$joinContributors = 'inner join Contributors con using (EbookId)';
|
||||
$whereCondition .= ' AND con.MarcRole = "aut"';
|
||||
$orderBy = 'con.SortName, e.EbookCreated desc';
|
||||
}
|
||||
elseif($sort == EbookSortType::ReadingEase){
|
||||
elseif($sort == Enums\EbookSortType::ReadingEase){
|
||||
$orderBy = 'e.ReadingEase desc';
|
||||
}
|
||||
elseif($sort == EbookSortType::Length){
|
||||
elseif($sort == Enums\EbookSortType::Length){
|
||||
$orderBy = 'e.WordCount';
|
||||
}
|
||||
|
||||
|
@ -200,7 +200,7 @@ class Library{
|
|||
/**
|
||||
* @return array{artworks: array<Artwork>, artworksCount: int}
|
||||
*/
|
||||
public static function FilterArtwork(?string $query = null, ?string $status = null, ?ArtworkSortType $sort = null, ?int $submitterUserId = null, int $page = 1, int $perPage = ARTWORK_PER_PAGE): array{
|
||||
public static function FilterArtwork(?string $query = null, ?string $status = null, ?Enums\ArtworkSortType $sort = null, ?int $submitterUserId = null, int $page = 1, int $perPage = ARTWORK_PER_PAGE): array{
|
||||
// $status is either the string value of an ArtworkStatus enum, or one of these special statuses:
|
||||
// null: same as "all"
|
||||
// "all": Show all approved and in use artwork
|
||||
|
@ -214,29 +214,29 @@ class Library{
|
|||
|
||||
if($status === null || $status == 'all'){
|
||||
$statusCondition = 'Status = ?';
|
||||
$params[] = ArtworkStatusType::Approved->value;
|
||||
$params[] = Enums\ArtworkStatusType::Approved->value;
|
||||
}
|
||||
elseif($status == 'all-admin'){
|
||||
$statusCondition = 'true';
|
||||
}
|
||||
elseif($status == 'all-submitter' && $submitterUserId !== null){
|
||||
$statusCondition = '(Status = ? or (Status = ? and SubmitterUserId = ?))';
|
||||
$params[] = ArtworkStatusType::Approved->value;
|
||||
$params[] = ArtworkStatusType::Unverified->value;
|
||||
$params[] = Enums\ArtworkStatusType::Approved->value;
|
||||
$params[] = Enums\ArtworkStatusType::Unverified->value;
|
||||
$params[] = $submitterUserId;
|
||||
}
|
||||
elseif($status == 'unverified-submitter' && $submitterUserId !== null){
|
||||
$statusCondition = 'Status = ? and SubmitterUserId = ?';
|
||||
$params[] = ArtworkStatusType::Unverified->value;
|
||||
$params[] = Enums\ArtworkStatusType::Unverified->value;
|
||||
$params[] = $submitterUserId;
|
||||
}
|
||||
elseif($status == 'in-use'){
|
||||
$statusCondition = 'Status = ? and EbookUrl is not null';
|
||||
$params[] = ArtworkStatusType::Approved->value;
|
||||
$params[] = Enums\ArtworkStatusType::Approved->value;
|
||||
}
|
||||
elseif($status == ArtworkStatusType::Approved->value){
|
||||
elseif($status == Enums\ArtworkStatusType::Approved->value){
|
||||
$statusCondition = 'Status = ? and EbookUrl is null';
|
||||
$params[] = ArtworkStatusType::Approved->value;
|
||||
$params[] = Enums\ArtworkStatusType::Approved->value;
|
||||
}
|
||||
else{
|
||||
$statusCondition = 'Status = ?';
|
||||
|
@ -244,10 +244,10 @@ class Library{
|
|||
}
|
||||
|
||||
$orderBy = 'art.Created desc';
|
||||
if($sort == ArtworkSortType::ArtistAlpha){
|
||||
if($sort == Enums\ArtworkSortType::ArtistAlpha){
|
||||
$orderBy = 'a.Name';
|
||||
}
|
||||
elseif($sort == ArtworkSortType::CompletedNewest){
|
||||
elseif($sort == Enums\ArtworkSortType::CompletedNewest){
|
||||
$orderBy = 'art.CompletedYear desc';
|
||||
}
|
||||
|
||||
|
@ -364,13 +364,13 @@ class Library{
|
|||
}
|
||||
elseif($status == 'all-submitter' && $submitterUserId !== null){
|
||||
$statusCondition = '(Status = ? or (Status = ? and SubmitterUserId = ?))';
|
||||
$params[] = ArtworkStatusType::Approved->value;
|
||||
$params[] = ArtworkStatusType::Unverified->value;
|
||||
$params[] = Enums\ArtworkStatusType::Approved->value;
|
||||
$params[] = Enums\ArtworkStatusType::Unverified->value;
|
||||
$params[] = $submitterUserId;
|
||||
}
|
||||
else{
|
||||
$statusCondition = 'Status = ?';
|
||||
$params[] = ArtworkStatusType::Approved->value;
|
||||
$params[] = Enums\ArtworkStatusType::Approved->value;
|
||||
}
|
||||
|
||||
$params[] = $artistUrlName; // a.UrlName
|
||||
|
|
|
@ -10,7 +10,7 @@ class Payment{
|
|||
public int $PaymentId;
|
||||
public ?int $UserId = null;
|
||||
public DateTimeImmutable $Created;
|
||||
public PaymentProcessorType $Processor;
|
||||
public Enums\PaymentProcessorType $Processor;
|
||||
public string $TransactionId;
|
||||
public float $Amount;
|
||||
public float $Fee;
|
||||
|
|
|
@ -8,7 +8,7 @@ class Tag{
|
|||
|
||||
public int $TagId;
|
||||
public string $Name;
|
||||
public TagType $Type;
|
||||
public Enums\TagType $Type;
|
||||
protected ?string $_UrlName = null;
|
||||
protected ?string $_Url = null;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue