Add type hints for remaining classes

This commit is contained in:
Alex Cabal 2024-01-08 14:11:53 -06:00
parent d7718218ad
commit 783c09864f
35 changed files with 212 additions and 210 deletions

View file

@ -128,8 +128,6 @@ Before submitting design contributions, please discuss them with the Standard Eb
### Main website
- Add type hints for class variables.
- Convert ebooks from being stored in an APCu cache to our MariaDB database. (This is a big project!)
- Creating a search bar for the SE Manual of Style.
@ -186,7 +184,7 @@ Before submitting design contributions, please discuss them with the Standard Eb
- Check for `null` using `===` and `!==`.
- Where possible, include type hints for functions. Due to PHP limitations this may not always be possible, for example in cases where `null` may be passed or returned.
- Where possible, include type hints for class properties and all functions.
- If using regex to parse HTML, use `|` as the regex delimiter instead of `/`.

View file

@ -1,5 +1,4 @@
<?
class ArtworkTag extends Tag{
// *******
// GETTERS
@ -19,11 +18,11 @@ class ArtworkTag extends Tag{
protected function Validate(): void{
$error = new Exceptions\ValidationException();
if($this->Name === null || strlen($this->Name) === 0){
if(strlen($this->Name) == 0){
$error->Add(new Exceptions\InvalidArtworkTagException());
}
if($this->Url === null || strlen($this->Url) === 0){
if($this->Url === null || strlen($this->Url) == 0){
$error->Add(new Exceptions\InvalidArtworkTagException());
}

View file

@ -1,16 +1,11 @@
<?
use Safe\DateTime;
use function Safe\file_get_contents;
use function Safe\file_put_contents;
use function Safe\preg_replace;
use function Safe\rename;
use function Safe\tempnam;
use function Safe\unlink;
class AtomFeed extends Feed{
public $Id;
public $Updated = null;
public $Subtitle = null;
public string $Id;
public ?DateTime $Updated = null;
public ?string $Subtitle = null;
/**
* @param string $title
@ -26,7 +21,6 @@ class AtomFeed extends Feed{
$this->Stylesheet = SITE_URL . '/feeds/atom/style';
}
// *******
// METHODS
// *******

View file

@ -1,8 +1,8 @@
<?
class Benefits{
public $CanAccessFeeds = false;
public $CanVote = false;
public $CanBulkDownload = false;
public $CanUploadArtwork = false;
public $CanReviewArtwork = false;
public bool $CanAccessFeeds = false;
public bool $CanVote = false;
public bool $CanBulkDownload = false;
public bool $CanUploadArtwork = false;
public bool $CanReviewArtwork = false;
}

View file

@ -1,12 +1,11 @@
<?
use function Safe\preg_replace;
class Collection{
public $Name;
public $Url;
public $SequenceNumber = null;
public $Type = null;
public string $Name;
public string $Url;
public ?int $SequenceNumber = null;
public ?string $Type = null;
public function __construct(string $name){
$this->Name = $name;

View file

@ -1,12 +1,12 @@
<?
class Contributor{
public $Name;
public $UrlName;
public $SortName;
public $WikipediaUrl;
public $MarcRole;
public $FullName;
public $NacoafUrl;
public string $Name;
public string $UrlName;
public ?string $SortName;
public ?string $WikipediaUrl;
public ?string $MarcRole;
public ?string $FullName;
public ?string $NacoafUrl;
public function __construct(string $name, string $sortName = null, string $fullName = null, string $wikipediaUrl = null, string $marcRole = null, string $nacoafUrl = null){
$this->Name = str_replace('\'', '', $name);

View file

@ -1,5 +1,4 @@
<?
class Db{
public static function GetLastInsertedId(): int{
return $GLOBALS['DbConnection']->GetLastInsertedId();

View file

@ -4,10 +4,9 @@ use function Safe\preg_match;
use function Safe\posix_getpwuid;
class DbConnection{
private $_link = null;
public $IsConnected = false;
public $QueryCount = 0;
public $LastQueryAffectedRowCount = 0;
private ?\PDO $_link = null;
public int $QueryCount = 0;
public int $LastQueryAffectedRowCount = 0;
public function __construct(?string $defaultDatabase = null, string $host = 'localhost', ?string $user = null, string$password = '', bool $forceUtf8 = true, bool $require = true){
if($user === null){
@ -51,8 +50,6 @@ class DbConnection{
// We can't use persistent connections (connection pooling) because we would have race condition problems with last_insert_id()
$this->_link = new \PDO($connectionString, $user, $password, $params);
$this->IsConnected = true;
}
catch(Exception $ex){
if(SITE_STATUS == SITE_STATUS_DEV){
@ -79,7 +76,7 @@ class DbConnection{
* @return Array<mixed>
*/
public function Query(string $sql, array $params = [], string $class = 'stdClass'): array{
if(!$this->IsConnected){
if($this->_link === null){
return [];
}
@ -245,8 +242,19 @@ class DbConnection{
// Gets the last auto-increment id
public function GetLastInsertedId(): ?int{
if($this->_link === null){
return null;
}
$id = $this->_link->lastInsertId();
if($id === false){
return null;
}
else{
$id = (int)$id;
}
if($id == 0){
return null;
}

View file

@ -10,58 +10,70 @@ use function Safe\sprintf;
use function Safe\shell_exec;
use function Safe\substr;
/**
* @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 $WwwFilesystemPath;
public $RepoFilesystemPath;
public $Url;
public $KindleCoverUrl;
public $EpubUrl;
public $AdvancedEpubUrl;
public $KepubUrl;
public $Azw3Url;
public $HasDownloads;
public string $WwwFilesystemPath;
public string $RepoFilesystemPath;
public string $Url;
public string $KindleCoverUrl;
public string $EpubUrl;
public string $AdvancedEpubUrl;
public string $KepubUrl;
public string $Azw3Url;
public bool $HasDownloads;
public $GitCommits = [];
public $Tags = [];
public $LocTags = [];
public $Collections = [];
public $Identifier;
public $UrlSafeIdentifier;
public $HeroImageUrl;
public $HeroImageAvifUrl;
public $HeroImage2xUrl;
public $HeroImage2xAvifUrl;
public $CoverImageUrl;
public $CoverImageAvifUrl;
public $CoverImage2xUrl;
public $CoverImage2xAvifUrl;
public $DistCoverUrl;
public $Title;
public $FullTitle;
public $AlternateTitle;
public $Description;
public $LongDescription;
public $Language;
public $WordCount;
public $ReadingEase;
public $ReadingEaseDescription;
public $ReadingTime;
public $GitHubUrl;
public $WikipediaUrl;
public string $Identifier;
public string $UrlSafeIdentifier;
public string $HeroImageUrl;
public string $HeroImageAvifUrl;
public string $HeroImage2xUrl;
public string $HeroImage2xAvifUrl;
public string $CoverImageUrl;
public string $CoverImageAvifUrl;
public string $CoverImage2xUrl;
public string $CoverImage2xAvifUrl;
public string $DistCoverUrl;
public ?string $Title = null;
public ?string $FullTitle = null;
public ?string $AlternateTitle = null;
public ?string $Description = null;
public ?string $LongDescription = null;
public ?string $Language = null;
public int $WordCount;
public float $ReadingEase;
public string $ReadingEaseDescription;
public string $ReadingTime;
public ?string $GitHubUrl = null;
public ?string $WikipediaUrl = null;
public $Sources = [];
public $Authors = []; // Array of Contributors
public $AuthorsHtml;
public $AuthorsUrl; // This is a single URL even if there are multiple authors; for example, /ebooks/karl-marx_friedrich-engels/
public $Illustrators = []; // Array of Contributors
public $Translators = []; // Array of Contributors
public $Contributors = []; // Array of Contributors
public $ContributorsHtml;
public $TitleWithCreditsHtml = '';
public $Created;
public $Updated;
public $TextUrl;
public $TextSinglePageUrl;
public $TextSinglePageSizeNumber = null;
public $TextSinglePageSizeUnit = null;
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/
public $Illustrators = [];
public $Translators = [];
public $Contributors = [];
public ?string $ContributorsHtml = null;
public string $TitleWithCreditsHtml = '';
public DateTime $Created;
public DateTime $Updated;
public string $TextUrl;
public string $TextSinglePageUrl;
public ?string $TextSinglePageSizeNumber = null;
public ?string $TextSinglePageSizeUnit = null;
public $TocEntries = null; // A list of non-Roman ToC entries ONLY IF the work has the 'se:is-a-collection' metadata element, null otherwise
public function __construct(?string $wwwFilesystemPath = null){
@ -384,7 +396,7 @@ class Ebook{
// Figure out the reading time.
$readingTime = ceil($this->WordCount / AVERAGE_READING_WORDS_PER_MINUTE);
$this->ReadingTime = $readingTime;
$this->ReadingTime = (string)$readingTime;
if($readingTime < 60){
$this->ReadingTime .= ' minute';

View file

@ -1,7 +1,7 @@
<?
class EbookSource{
public $Type;
public $Url;
public int $Type;
public string $Url;
public function __construct(int $type, string $url){
$this->Type = $type;

View file

@ -6,7 +6,6 @@ class EbookTag extends Tag{
$this->_Url = '/subjects/' . $this->UrlName;
}
// *******
// GETTERS
// *******

View file

@ -2,20 +2,20 @@
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
use function Safe\define;
use function Safe\file_get_contents;
/**
* @property array<array<string>> $Attachments
*/
class Email{
public $To = '';
public $ToName = '';
public $From = '';
public $FromName = '';
public $ReplyTo = '';
public $Subject = '';
public $Body = '';
public $TextBody = '';
public string $To = '';
public string $ToName = '';
public string $From = '';
public string $FromName = '';
public string $ReplyTo = '';
public string $Subject = '';
public string $Body = '';
public string $TextBody = '';
public $Attachments = [];
public $PostmarkStream = null;
public ?string $PostmarkStream = null;
public function __construct(bool $isNoReplyEmail = false){
if($isNoReplyEmail){
@ -35,7 +35,7 @@ class Email{
$this->ReplyTo = $this->From;
}
if($this->To === null || $this->To == ''){
if($this->To == ''){
return false;
}

View file

@ -1,18 +1,20 @@
<?
use Safe\DateTime;
use function Safe\exec;
use function Safe\file_get_contents;
use function Safe\file_put_contents;
use function Safe\tempnam;
use function Safe\unlink;
/**
* @param array<string> $Entries
*/
class Feed{
public $Url;
public $Title;
public string $Url;
public string $Title;
public $Entries = [];
public $Path = null;
public $Stylesheet = null;
protected $XmlString = null;
public string $Path;
public ?string $Stylesheet = null;
protected ?string $XmlString = null;
/**
* @param string $title

View file

@ -2,9 +2,9 @@
use Safe\DateTimeImmutable;
class GitCommit{
public $Created;
public $Message;
public $Hash;
public DateTimeImmutable $Created;
public string $Message;
public string $Hash;
public function __construct(string $unixTimestamp, string $hash, string $message){
$this->Created = new DateTimeImmutable('@' . $unixTimestamp);

View file

@ -7,8 +7,8 @@ use function Safe\getimagesize;
use function Safe\unlink;
class Image{
public $Path;
public $MimeType;
public string $Path;
public ?ImageMimeType $MimeType;
public function __construct(string $path){
$this->Path = $path;

View file

@ -7,14 +7,11 @@ use function Safe\filesize;
use function Safe\glob;
use function Safe\gmdate;
use function Safe\ksort;
use function Safe\preg_match;
use function Safe\preg_replace;
use function Safe\shell_exec;
use function Safe\sleep;
use function Safe\sort;
use function Safe\usort;
class Library{
/**
* @param string $query

View file

@ -7,8 +7,8 @@ use function Safe\gmdate;
use function Safe\substr;
class Log{
private $RequestId = null;
private $LogFilePath = null;
private string $RequestId;
private ?string $LogFilePath = null;
public function __construct(?string $logFilePath){
// Get a semi-random ID to identify this request within the log.

View file

@ -1,9 +1,8 @@
<?
class Museum extends PropertiesBase{
public $MuseumId;
public $Name;
public $Domain;
public int $MuseumId;
public string $Name;
public string $Domain;
public static function GetByUrl(?string $url): Museum{
if($url === null){

View file

@ -6,12 +6,12 @@ use Safe\DateTime;
* @property string $Url
*/
class NewsletterSubscription extends PropertiesBase{
public $IsConfirmed = false;
public $IsSubscribedToSummary;
public $IsSubscribedToNewsletter;
public $UserId;
public bool $IsConfirmed = false;
public bool $IsSubscribedToSummary;
public bool $IsSubscribedToNewsletter;
public int $UserId;
public DateTime $Created;
protected $_User;
public $Created;
protected $_Url = null;
// *******
@ -85,8 +85,8 @@ class NewsletterSubscription extends PropertiesBase{
public function SendConfirmationEmail(): void{
$em = new Email(true);
$em->PostmarkStream = EMAIL_POSTMARK_STREAM_BROADCAST;
$em->To = $this->User->Email;
if($this->User->Name != ''){
$em->To = $this->User->Email ?? '';
if($this->User->Name !== null && $this->User->Name != ''){
$em->ToName = $this->User->Name;
}
$em->Subject = 'Action required: confirm your newsletter subscription';

View file

@ -2,7 +2,7 @@
use Safe\DateTime;
class OpdsAcquisitionFeed extends OpdsFeed{
public $IsCrawlable;
public bool $IsCrawlable;
public function __construct(string $title, string $subtitle, string $url, string $path, array $entries, ?OpdsNavigationFeed $parent, bool $isCrawlable = false){
parent::__construct($title, $subtitle, $url, $path, $entries, $parent);

View file

@ -3,7 +3,7 @@ use Safe\DateTime;
use function Safe\file_put_contents;
class OpdsFeed extends AtomFeed{
public $Parent = null; // OpdsNavigationFeed class
public ?OpdsNavigationFeed $Parent = null;
/**
* @param string $title

View file

@ -1,13 +1,13 @@
<?
class OpdsNavigationEntry{
public $Id;
public $Url;
public $Rel;
public $Type;
public $Updated;
public $Description;
public $Title;
public $SortTitle;
public string $Id;
public string $Url;
public string $Rel;
public string $Type;
public ?DateTime $Updated;
public string $Description;
public string $Title;
public string $SortTitle;
public function __construct(string $title, string $description, string $url, ?DateTime $updated, string $rel, string $type){
$this->Id = SITE_URL . $url;

View file

@ -1,6 +1,5 @@
<?
use Safe\DateTime;
use function Safe\file_get_contents;
class OpdsNavigationFeed extends OpdsFeed{

View file

@ -5,13 +5,13 @@ use Safe\DateTime;
* @property User $User
*/
class Patron extends PropertiesBase{
public $UserId = null;
public ?int $UserId = null;
protected $_User = null;
public $IsAnonymous;
public $AlternateName;
public $IsSubscribedToEmails;
public $Created = null;
public $Ended = null;
public bool $IsAnonymous;
public ?string $AlternateName;
public bool $IsSubscribedToEmails;
public ?DateTime $Created = null;
public ?DateTime $Ended = null;
// *******
@ -54,8 +54,8 @@ class Patron extends PropertiesBase{
private function SendWelcomeEmail(bool $isReturning): void{
if($this->User !== null){
$em = new Email();
$em->To = $this->User->Email;
$em->ToName = $this->User->Name;
$em->To = $this->User->Email ?? '';
$em->ToName = $this->User->Name ?? '';
$em->From = EDITOR_IN_CHIEF_EMAIL_ADDRESS;
$em->FromName = EDITOR_IN_CHIEF_NAME;
$em->Subject = 'Thank you for supporting Standard Ebooks!';

View file

@ -1,19 +1,18 @@
<?
/**
* @property User $User
*/
class Payment extends PropertiesBase{
public $PaymentId;
public $UserId = null;
protected $_User = null;
public $Created;
public $ChannelId;
public $TransactionId;
public $Amount;
public $Fee;
public $IsRecurring;
public $IsMatchingDonation = false;
public int $PaymentId;
public ?int $UserId = null;
public DateTime $Created;
public int $ChannelId;
public string $TransactionId;
public float $Amount;
public float $Fee;
public bool $IsRecurring;
public bool $IsMatchingDonation = false;
protected ?User $_User = null;
// *******

View file

@ -3,23 +3,25 @@ use Safe\DateTime;
use function Safe\usort;
/**
* @property ?array<PollItem> $_PollItems
* @property ?array<PollItem> $_PollItemsByWinner
* @property string $Url
* @property array<PollItem> $PollItems
* @property array<PollItem> $PollItemsByWinner
* @property int $VoteCount
*/
class Poll extends PropertiesBase{
public $PollId;
public $Name;
public $UrlName;
public $Description;
public $Created;
public $Start;
public $End;
protected $_Url = null;
public int $PollId;
public string $Name;
public string $UrlName;
public string $Description;
public DateTime $Created;
public DateTime $Start;
public DateTime $End;
protected ?string $_Url = null;
protected $_PollItems = null;
protected $_PollItemsByWinner = null;
protected $_VoteCount = null;
protected ?int $_VoteCount = null;
// *******
@ -71,7 +73,7 @@ class Poll extends PropertiesBase{
$this->_PollItemsByWinner = $this->PollItems;
usort($this->_PollItemsByWinner, function(PollItem $a, PollItem $b){ return $a->VoteCount <=> $b->VoteCount; });
$this->_PollItemsByWinner = array_reverse($this->_PollItemsByWinner);
$this->_PollItemsByWinner = array_reverse($this->_PollItemsByWinner ?? []);
}
return $this->_PollItemsByWinner;

View file

@ -1,16 +1,15 @@
<?
/**
* @property int $VoteCount
* @property Poll $Poll
*/
class PollItem extends PropertiesBase{
public $PollItemId;
public $PollId;
public $Name;
public $Description;
protected $_VoteCount = null;
protected $_Poll = null;
public int $PollItemId;
public int $PollId;
public string $Name;
public string $Description;
protected ?int $_VoteCount = null;
protected ?Poll $_Poll = null;
// *******

View file

@ -7,12 +7,12 @@ use Safe\DateTime;
* @property string $Url
*/
class PollVote extends PropertiesBase{
public $UserId;
protected $_User = null;
public $Created;
public $PollItemId;
protected $_PollItem = null;
protected $_Url = null;
public int $UserId;
public DateTime $Created;
public ?int $PollItemId = null;
protected ?User $_User = null;
protected ?PollItem $_PollItem = null;
protected ?string $_Url = null;
// *******
@ -35,7 +35,7 @@ class PollVote extends PropertiesBase{
protected function Validate(): void{
$error = new Exceptions\ValidationException();
if($this->UserId === null || $this->User === null){
if($this->User === null){
$error->Add(new Exceptions\InvalidUserException());
}

View file

@ -1,6 +1,4 @@
<?
use function Safe\substr;
abstract class PropertiesBase{
/**
* @return mixed

View file

@ -5,7 +5,7 @@ use function Safe\filesize;
use function Safe\preg_replace;
class RssFeed extends Feed{
public $Description;
public string $Description;
/**
* @param string $title

View file

@ -8,11 +8,11 @@ use function Safe\strtotime;
* @property string $Url
*/
class Session extends PropertiesBase{
public $UserId;
protected $_User = null;
public $Created;
public $SessionId;
public $_Url;
public int $UserId;
protected ?User $_User = null;
public DateTime $Created;
public string $SessionId;
public ?string $_Url = null;
// *******

View file

@ -1,11 +1,10 @@
<?
/**
* @property string $Url
*/
class Tag extends PropertiesBase{
public $TagId;
public $Name;
public $UrlName;
protected $_Url;
public int $TagId;
public string $Name;
public string $UrlName;
protected ?string $_Url;
}

View file

@ -4,19 +4,20 @@ use Safe\DateTime;
/**
* @property Array<Payment> $Payments
* @property ?bool $IsRegistered
* @property Benefits $Benefits
* @property ?array<Payment> $_Payments
*/
class User extends PropertiesBase{
public $UserId;
public $Name;
public $Email;
public $Created;
public $Uuid;
public $PasswordHash;
protected $_IsRegistered = null;
public int $UserId;
public ?string $Name;
public ?string $Email;
public DateTime $Created;
public string $Uuid;
public ?string $PasswordHash;
protected ?bool $_IsRegistered = null;
protected $_Payments = null;
protected $_Benefits = null;
protected ?Benefits $_Benefits = null;
// *******
// GETTERS
@ -59,7 +60,7 @@ class User extends PropertiesBase{
return $this->_Benefits;
}
protected function GetIsRegistered(): bool{
protected function GetIsRegistered(): ?bool{
if($this->_IsRegistered === null){
// A user is "registered" if they have a benefits entry in the table.
// This function will fill it out for us.

View file

@ -35,8 +35,8 @@ if(HttpInput::Str(POST, 'automationtest', false)){
try{
$subscription->User = new User();
$subscription->User->Email = HttpInput::Str(POST, 'email', false);
$subscription->IsSubscribedToNewsletter = HttpInput::Bool(POST, 'issubscribedtonewsletter', false);
$subscription->IsSubscribedToSummary = HttpInput::Bool(POST, 'issubscribedtosummary', false);
$subscription->IsSubscribedToNewsletter = HttpInput::Bool(POST, 'issubscribedtonewsletter') ?? false;
$subscription->IsSubscribedToSummary = HttpInput::Bool(POST, 'issubscribedtosummary') ?? false;
$captcha = HttpInput::Str(SESSION, 'captcha', false) ?? '';

View file

@ -1,5 +1,4 @@
<?
use function Safe\preg_match;
use function Safe\session_unset;
if(HttpInput::RequestMethod() != HTTP_POST){