Continue improving type hints

This commit is contained in:
Alex Cabal 2024-05-10 22:28:24 -05:00
parent eb376c87bd
commit 703e1a7a03
73 changed files with 98 additions and 114 deletions

View file

@ -7,12 +7,6 @@ parameters:
ignoreErrors:
# Ignore errors caused by Template static class reflection
- '#Call to an undefined static method Template::[a-zA-Z0-9\\_]+\(\)\.#'
# Ignore errors caused by no type hints on class properties, as that's not available till PHP 7.4
- '#Property .+? has no type specified.#'
# Ignore setters for properties that accept several types
- '#Property Artwork::\$Tags \(array<ArtworkTag>\) does not accept.+#'
level:
8
paths:

View file

@ -1,6 +1,6 @@
CREATE TABLE `PollVotes` (
`UserId` int(10) unsigned NOT NULL,
`PollItemId` int(10) unsigned NOT NULL,
`Created` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
`Created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY `idxUnique` (`PollItemId`,`UserId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

View file

@ -8,20 +8,18 @@ use Safe\DateTimeImmutable;
* @property ?array<string> $AlternateNames
*/
class Artist{
/**
* @var array<string> $_AlternateNames
*/
use Traits\Accessor;
public ?int $ArtistId = null;
public ?string $Name = null;
public ?DateTimeImmutable $Created = null;
public ?DateTimeImmutable $Updated = null;
protected ?int $_DeathYear = null;
protected ?string $_UrlName = null;
protected ?string $_Url = null;
protected $_AlternateNames = null; // Don't type hint this here, otherwise PHPStan will complain
/** @var ?array<string> $_AlternateNames */
protected $_AlternateNames = null;
// *******
// SETTERS

View file

@ -1,12 +1,5 @@
<?
use Exceptions\InvalidImageUploadException;
use Exceptions\InvalidPageScanUrlException;
use Exceptions\InvalidUrlException;
use Safe\DateTimeImmutable;
use Safe\Exceptions\ExecException;
use Safe\Exceptions\FilesystemException;
use Safe\Exceptions\PcreException;
use function Safe\copy;
use function Safe\exec;
@ -19,7 +12,8 @@ use function Safe\preg_replace;
* @property string $UrlName
* @property string $Url
* @property string $EditUrl
* @property array<ArtworkTag> $Tags
* @property-read array<ArtworkTag> $Tags
* @property-write array<ArtworkTag>|string $Tags
* @property Artist $Artist
* @property string $ImageUrl
* @property string $ThumbUrl
@ -56,9 +50,11 @@ class Artwork{
public ?string $Notes = null;
public ?ImageMimeType $MimeType = null;
public ?ArtworkStatus $Status = null;
protected ?string $_UrlName = null;
protected ?string $_Url = null;
protected ?string $_EditUrl = null;
/** @var ?array<ArtworkTag> $_Tags */
protected $_Tags = null;
protected ?Artist $_Artist = null;
protected ?string $_ImageUrl = null;

View file

@ -1,7 +1,4 @@
<?
use Exceptions\InvalidArtworkTagException;
use function Safe\preg_match;
use function Safe\preg_replace;
@ -50,7 +47,7 @@ class ArtworkTag extends Tag{
}
/**
* @throws InvalidArtworkTagException
* @throws Exceptions\InvalidArtworkTagException
*/
public function Create(): void{
$this->Validate();

View file

@ -12,7 +12,7 @@ class AtomFeed extends Feed{
* @param string $subtitle
* @param string $url
* @param string $path
* @param array<Ebook> $entries
* @param array<Ebook|OpdsNavigationEntry> $entries
*/
public function __construct(string $title, string $subtitle, string $url, string $path, array $entries){
parent::__construct($title, $url, $path, $entries);

View file

@ -11,18 +11,6 @@ use function Safe\preg_replace;
use function Safe\sprintf;
use function Safe\shell_exec;
/**
* @property array<GitCommit> $GitCommits
* @property array<EbookTag> $EbookTags
* @property array<string> $LocTags
* @property array<Collection> $Collections
* @property array<EbookSource> $Sources
* @property array<Contributor> $Authors
* @property array<Contributor> $Illustrators
* @property array<Contributor> $Translators
* @property array<Contributor> $Contributors
* @property ?array<string> $TocEntries
*/
class Ebook{
public string $WwwFilesystemPath;
public string $RepoFilesystemPath;
@ -33,9 +21,13 @@ class Ebook{
public string $KepubUrl;
public string $Azw3Url;
public bool $HasDownloads;
/** @var array<GitCommit> $GitCommits */
public $GitCommits = [];
/** @var array<EbookTag> $Tags */
public $Tags = [];
/** @var array<string> $LocTags */
public $LocTags = [];
/** @var array<Collection> $Collections */
public $Collections = [];
public string $Identifier;
public string $UrlSafeIdentifier;
@ -60,12 +52,17 @@ class Ebook{
public string $ReadingTime;
public ?string $GitHubUrl = null;
public ?string $WikipediaUrl = null;
/** @var array<EbookSource> $Sources */
public $Sources = [];
/** @var array<Contributor> $Authors */
public $Authors = [];
public string $AuthorsHtml;
public string $AuthorsUrl; // This is a single URL even if there are multiple authors; for example, /ebooks/karl-marx_friedrich-engels/
/** @var array<Contributor> $Illustrators */
public $Illustrators = [];
/** @var array<Contributor> $Translators */
public $Translators = [];
/** @var array<Contributor> $Contributors */
public $Contributors = [];
public ?string $ContributorsHtml = null;
public string $TitleWithCreditsHtml = '';
@ -75,6 +72,7 @@ class Ebook{
public string $TextSinglePageUrl;
public ?string $TextSinglePageSizeNumber = null;
public ?string $TextSinglePageSizeUnit = null;
/** @var ?array<string> $TocEntries */
public $TocEntries = null; // A list of non-Roman ToC entries ONLY IF the work has the 'se:is-a-collection' metadata element, null otherwise
/**

View file

@ -2,9 +2,6 @@
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
/**
* @property array<array<string>> $Attachments
*/
class Email{
public string $To = '';
public string $ToName = '';
@ -14,6 +11,7 @@ class Email{
public string $Subject = '';
public string $Body = '';
public string $TextBody = '';
/** @var array<array<string>> $Attachments */
public $Attachments = [];
public ?string $PostmarkStream = null;

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class ArtistNameRequiredException extends AppException{
/** @var string $message */
protected $message = 'An artist name is required.';
}

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class ArtistNotFoundException extends AppException{
/** @var string $message */
protected $message = 'We couldnt locate that artist.';
}

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class ArtworkAlreadyExistsException extends AppException{
/** @var string $message */
protected $message = 'An artwork with this name already exists.';
}

View file

@ -2,10 +2,10 @@
namespace Exceptions;
class ArtworkImageDimensionsTooSmallException extends AppException{
protected $message;
// This has to be initialized in a constructor because we use the number_format() function.
public function __construct(){
$this->message = 'Image dimensions are too small. The minimum image size is ' . number_format(ARTWORK_IMAGE_MINIMUM_WIDTH) . ' × ' . number_format(ARTWORK_IMAGE_MINIMUM_HEIGHT) . '.';
parent::__construct($this->message);
}
}

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class ArtworkNameRequiredException extends AppException{
/** @var string $message */
protected $message = 'An artwork name is required.';
}

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class ArtworkNotFoundException extends AppException{
/** @var string $message */
protected $message = 'We couldnt locate that artwork.';
}

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class DuplicateDatabaseKeyException extends AppException{
/** @var string $message */
protected $message = 'An attempted row insertion has violated the database unique index.';
}

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class InvalidArtistException extends ValidationException{
/** @var string $message */
protected $message = 'Artist is invalid.';
}

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class InvalidArtworkException extends ValidationException{
/** @var string $message */
protected $message = 'Artwork is invalid.';
}

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class InvalidArtworkPageUrlException extends InvalidUrlException{
/** @var string $message */
protected $message = 'Invalid link to page with artwork.';
}

View file

@ -2,11 +2,14 @@
namespace Exceptions;
class InvalidArtworkTagException extends ValidationException{
/** @var string $message */
protected $message = 'Artwork tag is invalid.';
public function __construct(?string $tagName){
if($tagName !== null && trim($tagName) != ''){
$this->message = 'Artwork tag ' . $tagName . ' is invalid.';
}
parent::__construct($this->message);
}
}

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class InvalidArtworkTagNameException extends AppException{
/** @var string $message */
protected $message = 'Artwork tags can only contain letters and numbers.';
}

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class InvalidCaptchaException extends AppException{
/** @var string $message */
protected $message = 'We couldnt validate your CAPTCHA response.';
}

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class InvalidCompletedYearException extends AppException{
/** @var string $message */
protected $message = 'Invalid year of completion.';
}

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class InvalidCopyrightPageUrlException extends InvalidUrlException{
/** @var string $message */
protected $message = 'Invalid link to page with copyright details.';
}

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class InvalidCredentialsException extends AppException{
/** @var string $message */
protected $message = 'Invalid credentials.';
}

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class InvalidDeathYearException extends AppException{
/** @var string $message */
protected $message = 'Invalid year of death.';
}

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class InvalidEmailException extends AppException{
/** @var string $message */
protected $message = 'We couldnt understand your email address.';
}

View file

@ -3,11 +3,6 @@
namespace Exceptions;
class InvalidImageUploadException extends AppException{
public function __construct(?string $message = null){
if($message === null){
$message = 'Uploaded image is invalid.';
}
parent::__construct($message);
}
/** @var string $message */
protected $message = 'Uploaded image is invalid.';
}

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class InvalidLoginException extends AppException{
/** @var string $message */
protected $message = 'We couldnt validate your login information.';
}

View file

@ -3,5 +3,6 @@
namespace Exceptions;
class InvalidMimeTypeException extends AppException{
/** @var string $message */
protected $message = 'Uploaded image must be a JPG, BMP, PNG, or TIFF file.';
}

View file

@ -4,5 +4,7 @@ namespace Exceptions;
class InvalidMuseumUrlException extends InvalidUrlException{
public function __construct(string $url, string $exampleUrl){
$this->message = 'Invalid museum URL: <' . $url . '>. Expected a URL like: <'. $exampleUrl . '>.';
parent::__construct($this->message);
}
}

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class InvalidNewsletterSubscription extends ValidationException{
/** @var string $message */
protected $message = 'Newsletter subscription is invalid.';
}

View file

@ -4,5 +4,7 @@ namespace Exceptions;
class InvalidPageScanUrlException extends InvalidUrlException{
public function __construct(string $url, string $exampleUrl){
$this->message = 'Invalid page scan URL: <' . $url . '>. Expected a URL like: <'. $exampleUrl . '>.';
parent::__construct($this->message);
}
}

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class InvalidPermissionsException extends AppException{
/** @var string $message */
protected $message = 'You dont have permission to perform that action.';
}

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class InvalidPollVoteException extends ValidationException{
/** @var string $message */
protected $message = 'Vote is invalid.';
}

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class InvalidPublicationYearException extends AppException{
/** @var string $message */
protected $message = 'Invalid year of publication.';
}

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class InvalidPublicationYearPageUrlException extends InvalidUrlException{
/** @var string $message */
protected $message = 'Invalid link to page with year of publication.';
}

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class InvalidRequestException extends AppException{
/** @var string $message */
protected $message = 'Invalid HTTP request.';
}

View file

@ -2,6 +2,7 @@
namespace Exceptions;
class InvalidUrlException extends AppException{
/** @var string $message */
protected $message = 'Invalid URL.';
public function __construct(?string $url = null){

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class MissingEbookException extends AppException{
/** @var string $message */
protected $message = 'Artwork marked as “in use”, but the ebook couldnt be found in the filesystem.';
}

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class MissingPdProofException extends AppException{
/** @var string $message */
protected $message = 'Missing proof of U.S. public domain status.';
}

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class MuseumNotFoundException extends AppException{
/** @var string $message */
protected $message = 'We couldnt locate that museum.';
}

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class NewsletterRequiredException extends AppException{
/** @var string $message */
protected $message = 'You must select at least one newsletter to subscribe to.';
}

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class NewsletterSubscriptionExistsException extends AppException{
/** @var string $message */
protected $message = 'Youre already subscribed to the newsletter.';
}

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class NewsletterSubscriptionNotFoundException extends AppException{
/** @var string $message */
protected $message = 'We couldnt find you in our newsletter subscribers list.';
}

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class PatronNotFoundException extends AppException{
/** @var string $message */
protected $message = 'We couldnt locate you in the Patrons Circle.';
}

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class PaymentExistsException extends AppException{
/** @var string $message */
protected $message = 'This transaction ID already exists.';
}

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class PollClosedException extends AppException{
/** @var string $message */
protected $message = 'This poll is not open to voting right now.';
}

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class PollItemNotFoundException extends AppException{
/** @var string $message */
protected $message = 'We couldnt locate that poll item.';
}

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class PollItemRequiredException extends AppException{
/** @var string $message */
protected $message = 'You must select an item to vote on.';
}

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class PollNotFoundException extends AppException{
/** @var string $message */
protected $message = 'We couldnt locate that poll.';
}

View file

@ -2,7 +2,8 @@
namespace Exceptions;
class PollVoteExistsException extends AppException{
public $Vote = null;
public ?\PollVote $Vote = null;
/** @var string $message */
protected $message = 'Youve already voted in this poll.';
public function __construct(?\PollVote $vote = null){

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class PollVoteNotFoundException extends AppException{
/** @var string $message */
protected $message = 'We couldnt locate that vote.';
}

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class TagsRequiredException extends AppException{
/** @var string $message */
protected $message = 'At least one tag is required.';
}

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class TooManyTagsException extends AppException{
/** @var string $message */
protected $message = 'Too many tags; the maximum is ' . ARTWORK_MAX_TAGS . '.';
}

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class UserExistsException extends AppException{
/** @var string $message */
protected $message = 'This email already exists in the database.';
}

View file

@ -2,5 +2,6 @@
namespace Exceptions;
class UserNotFoundException extends AppException{
/** @var string $message */
protected $message = 'We couldnt locate that user.';
}

View file

@ -1,10 +1,8 @@
<?
namespace Exceptions;
/**
* @property array<\Exception> $Exceptions
*/
class ValidationException extends AppException{
/** @var array<\Exception> $Exceptions */
public $Exceptions = [];
public bool $HasExceptions = false;
public bool $IsFatal = false;

View file

@ -2,7 +2,7 @@
namespace Exceptions;
class WebhookException extends AppException{
public $PostData;
public ?string $PostData;
public function __construct(string $message = '', string $data = null){
$this->PostData = $data;

View file

@ -5,12 +5,10 @@ use function Safe\file_put_contents;
use function Safe\tempnam;
use function Safe\unlink;
/**
* @param array<string> $Entries
*/
class Feed{
public string $Url;
public string $Title;
/** @var array<Ebook|OpdsNavigationEntry> $Entries */
public $Entries = [];
public string $Path;
public ?string $Stylesheet = null;
@ -20,7 +18,7 @@ class Feed{
* @param string $title
* @param string $url
* @param string $path
* @param array<Ebook> $entries
* @param array<Ebook|OpdsNavigationEntry> $entries
*/
public function __construct(string $title, string $url, string $path, array $entries){
$this->Url = $url;

View file

@ -1,8 +1,4 @@
<?
use Safe\Exceptions\ImageException;
use Exceptions\InvalidImageUploadException;
use function Safe\exec;
use function Safe\imagecopyresampled;
use function Safe\imagecreatetruecolor;

View file

@ -1,14 +1,5 @@
<?
use Exceptions\AppException;
use Exceptions\ArtistNotFoundException;
use Safe\DateTimeImmutable;
use Safe\Exceptions\ExecException;
use Safe\Exceptions\PcreException;
use Safe\Exceptions\FilesystemException;
use Safe\Exceptions\DatetimeException;
use Safe\Exceptions\ArrayException;
use Safe\Exceptions\MiscException;
use function Safe\apcu_fetch;
use function Safe\exec;
@ -24,13 +15,11 @@ use function Safe\usort;
class Library{
/**
* @param string $query
* @param array<string> $tags
* @param EbookSort $sort
* @return array<Ebook>
* @throws Exceptions\AppException
*/
public static function FilterEbooks(string $query = null, array $tags = [], EbookSort $sort = null){
public static function FilterEbooks(string $query = null, array $tags = [], EbookSort $sort = null): array{
$ebooks = Library::GetEbooks();
$matches = $ebooks;

View file

@ -1,10 +1,4 @@
<?
use Exceptions\InvalidUrlException;
use Safe\Exceptions\PcreException;
use Exceptions\InvalidMuseumUrlException;
use Exceptions\InvalidPageScanUrlException;
use function Safe\parse_url;
use function Safe\preg_match;
use function Safe\preg_replace;

View file

@ -1,9 +1,5 @@
<?
use Exceptions\InvalidNewsletterSubscription;
use Exceptions\NewsletterSubscriptionExistsException;
use Safe\DateTimeImmutable;
use Safe\Exceptions\ErrorfuncException;
/**
* @property User $User
@ -17,8 +13,8 @@ class NewsletterSubscription{
public bool $IsSubscribedToNewsletter = false;
public ?int $UserId = null;
public DateTimeImmutable $Created;
protected $_User;
protected $_Url = null;
protected ?User $_User = null;
protected ?string $_Url = null;
// *******
// GETTERS

View file

@ -10,7 +10,7 @@ class OpdsFeed extends AtomFeed{
* @param string $subtitle
* @param string $url
* @param string $path
* @param array<Ebook> $entries
* @param array<Ebook|OpdsNavigationEntry> $entries
* @param OpdsNavigationFeed $parent
*/
public function __construct(string $title, string $subtitle, string $url, string $path, array $entries, ?OpdsNavigationFeed $parent){

View file

@ -4,12 +4,7 @@ use function Safe\file_get_contents;
class OpdsNavigationFeed extends OpdsFeed{
/**
* @param string $title
* @param string $subtitle
* @param string $url
* @param string $path
* @param array<Ebook> $entries
* @param OpdsNavigationFeed $parent
* @param array<OpdsNavigationEntry> $entries
*/
public function __construct(string $title, string $subtitle, string $url, string $path, array $entries, ?OpdsNavigationFeed $parent){
parent::__construct($title, $subtitle, $url, $path, $entries, $parent);
@ -24,6 +19,7 @@ class OpdsNavigationFeed extends OpdsFeed{
$xml = new SimpleXMLElement(str_replace('xmlns=', 'ns=', file_get_contents($this->Path)));
foreach($xml->xpath('//entry') ?: [] as $existingEntry){
foreach($this->Entries as $entry){
/** @var OpdsNavigationEntry $entry */
if($entry->Id == $existingEntry->id){
$entry->Updated = new DateTimeImmutable($existingEntry->updated);
}

View file

@ -8,13 +8,13 @@ class Patron{
use Traits\Accessor;
public ?int $UserId = null;
protected $_User = null;
public bool $IsAnonymous;
public ?string $AlternateName = null;
public bool $IsSubscribedToEmails;
public ?DateTimeImmutable $Created = null;
public ?DateTimeImmutable $Ended = null;
protected ?User $_User = null;
// *******
// METHODS

View file

@ -1,7 +1,4 @@
<?
use Exceptions\UserExistsException;
use Exceptions\PaymentExistsException;
use Safe\DateTimeImmutable;
/**
@ -19,6 +16,7 @@ class Payment{
public float $Fee;
public bool $IsRecurring;
public bool $IsMatchingDonation = false;
protected ?User $_User = null;

View file

@ -3,8 +3,6 @@ use Safe\DateTimeImmutable;
use function Safe\usort;
/**
* @property ?array<PollItem> $_PollItems
* @property ?array<PollItem> $_PollItemsByWinner
* @property string $Url
* @property array<PollItem> $PollItems
* @property array<PollItem> $PollItemsByWinner
@ -21,7 +19,9 @@ class Poll{
public DateTimeImmutable $Start;
public DateTimeImmutable $End;
protected ?string $_Url = null;
/** @var ?array<PollItem> $_PollItems */
protected $_PollItems = null;
/** @var ?array<PollItem> $_PollItemsByWinner */
protected $_PollItemsByWinner = null;
protected ?int $_VoteCount = null;

View file

@ -1,6 +1,4 @@
<?
use Exceptions\InvalidPollVoteException;
use Safe\DateTimeImmutable;
/**
@ -14,6 +12,7 @@ class PollVote{
public ?int $UserId = null;
public DateTimeImmutable $Created;
public ?int $PollItemId = null;
protected ?User $_User = null;
protected ?PollItem $_PollItem = null;
protected ?string $_Url = null;

View file

@ -1,8 +1,5 @@
<?
use Safe\DateTimeImmutable;
use Safe\Exceptions\DatetimeException;
use Safe\Exceptions\FilesystemException;
use Safe\Exceptions\ExecException;
use function Safe\file_get_contents;
use function Safe\filesize;
@ -12,10 +9,6 @@ class RssFeed extends Feed{
public string $Description;
/**
* @param string $title
* @param string $description
* @param string $url
* @param string $path
* @param array<Ebook> $entries
*/
public function __construct(string $title, string $description, string $url, string $path, array $entries){
@ -65,6 +58,7 @@ class RssFeed extends Feed{
$currentEntries = [];
foreach($this->Entries as $entry){
/** @var Ebook $entry */
$obj = new StdClass();
$obj->Size = (string)filesize(WEB_ROOT . $entry->EpubUrl);
$obj->Id = preg_replace('/^url:/ius', '', $entry->Identifier);

View file

@ -15,9 +15,10 @@ class Session{
use Traits\Accessor;
public int $UserId;
protected ?User $_User = null;
public DateTimeImmutable $Created;
public string $SessionId;
protected ?User $_User = null;
public ?string $_Url = null;

View file

@ -4,7 +4,6 @@ use function Safe\ob_start;
class Template{
/**
* @param string $templateName
* @param array<mixed> $arguments
*/
protected static function Get(string $templateName, array $arguments = []): string{
@ -23,7 +22,6 @@ class Template{
}
/**
* @param string $function
* @param array<mixed> $arguments
*/
public static function __callStatic(string $function, array $arguments): string{

View file

@ -1,16 +1,15 @@
<?
use Exceptions\UserExistsException;
use Ramsey\Uuid\Uuid;
use Safe\DateTimeImmutable;
/**
* @property array<Payment> $Payments
* @property ?bool $IsRegistered
* @property bool $IsRegistered
* @property Benefits $Benefits
* @property ?array<Payment> $_Payments
*/
class User{
use Traits\Accessor;
public int $UserId;
@ -19,7 +18,9 @@ class User{
public DateTimeImmutable $Created;
public string $Uuid;
public ?string $PasswordHash = null;
protected ?bool $_IsRegistered = null;
/** @var ?array<Payment> $_Payments */
protected $_Payments = null;
protected ?Benefits $_Benefits = null;