mirror of
https://github.com/standardebooks/web.git
synced 2025-07-06 14:50:39 -04:00
Add type hints and some other tweaks to satisfy PHPStan
This commit is contained in:
parent
caa623bd0b
commit
bef5aea7ad
11 changed files with 72 additions and 28 deletions
|
@ -7,6 +7,9 @@ parameters:
|
||||||
ignoreErrors:
|
ignoreErrors:
|
||||||
# Ignore errors caused by Template static class reflection
|
# Ignore errors caused by Template static class reflection
|
||||||
- '#Call to an undefined static method Template::[a-zA-Z0-9\\_]+\(\)\.#'
|
- '#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 typehint specified.#'
|
||||||
level:
|
level:
|
||||||
7
|
7
|
||||||
paths:
|
paths:
|
||||||
|
|
|
@ -11,7 +11,7 @@ mb_http_output('UTF-8');
|
||||||
date_default_timezone_set('UTC');
|
date_default_timezone_set('UTC');
|
||||||
|
|
||||||
// Custom error handler to output more details about the specific Apache request that caused an exception.
|
// Custom error handler to output more details about the specific Apache request that caused an exception.
|
||||||
set_exception_handler(function($ex){
|
set_exception_handler(function(Throwable $ex): void{
|
||||||
$errorString = "----------------------------------------\n";
|
$errorString = "----------------------------------------\n";
|
||||||
$errorString .= trim(vds(array_intersect_key($_SERVER, array('REQUEST_URI' => '', 'QUERY_STRING' => '', 'REQUEST_METHOD' => '', 'REDIRECT_QUERY_STRING' => '', 'REDIRECT_URL' => '', 'SCRIPT_FILENAME' => '', 'REMOTE_ADDR' => '', 'HTTP_COOKIE' => '', 'HTTP_USER_AGENT' => '', 'SCRIPT_URI' => ''))));
|
$errorString .= trim(vds(array_intersect_key($_SERVER, array('REQUEST_URI' => '', 'QUERY_STRING' => '', 'REQUEST_METHOD' => '', 'REDIRECT_QUERY_STRING' => '', 'REDIRECT_URL' => '', 'SCRIPT_FILENAME' => '', 'REMOTE_ADDR' => '', 'HTTP_COOKIE' => '', 'HTTP_USER_AGENT' => '', 'SCRIPT_URI' => ''))));
|
||||||
|
|
||||||
|
|
|
@ -5,21 +5,24 @@
|
||||||
use function Safe\ob_end_clean;
|
use function Safe\ob_end_clean;
|
||||||
|
|
||||||
// Convenience alias of var_dump.
|
// Convenience alias of var_dump.
|
||||||
function vd($var){
|
function vd($var): void{
|
||||||
var_dump($var);
|
var_dump($var);
|
||||||
}
|
}
|
||||||
|
|
||||||
// var_dump($var) then die().
|
// var_dump($var) then die().
|
||||||
function vdd($var){
|
function vdd($var): void{
|
||||||
var_dump($var);
|
var_dump($var);
|
||||||
die();
|
die();
|
||||||
}
|
}
|
||||||
|
|
||||||
// var_dump into a string.
|
// var_dump into a string.
|
||||||
function vds($var){
|
function vds($var): string{
|
||||||
ob_start();
|
ob_start();
|
||||||
var_dump($var);
|
var_dump($var);
|
||||||
$str = ob_get_contents();
|
$str = ob_get_contents();
|
||||||
|
if($str === false){
|
||||||
|
$str = '';
|
||||||
|
}
|
||||||
ob_end_clean();
|
ob_end_clean();
|
||||||
return $str;
|
return $str;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
<?
|
<?
|
||||||
use function Safe\preg_replace;
|
use Safe\DateTime;
|
||||||
use function Safe\file_get_contents;
|
use function Safe\file_get_contents;
|
||||||
use function Safe\preg_match;
|
|
||||||
use function Safe\glob;
|
|
||||||
use function Safe\substr;
|
|
||||||
use function Safe\json_encode;
|
use function Safe\json_encode;
|
||||||
|
use function Safe\glob;
|
||||||
|
use function Safe\preg_match;
|
||||||
|
use function Safe\preg_replace;
|
||||||
|
use function Safe\substr;
|
||||||
|
|
||||||
class Ebook{
|
class Ebook{
|
||||||
public $WwwFilesystemPath;
|
public $WwwFilesystemPath;
|
||||||
|
@ -153,7 +154,10 @@ class Ebook{
|
||||||
|
|
||||||
$this->FullTitle = $this->NullIfEmpty($xml->xpath('/package/metadata/dc:title[@id="fulltitle"]'));
|
$this->FullTitle = $this->NullIfEmpty($xml->xpath('/package/metadata/dc:title[@id="fulltitle"]'));
|
||||||
|
|
||||||
$this->Timestamp = new \DateTime((string)$xml->xpath('/package/metadata/dc:date')[0]);
|
$date = $xml->xpath('/package/metadata/dc:date');
|
||||||
|
if($date !== false && sizeof($date) > 0){
|
||||||
|
$this->Timestamp = new DateTime((string)$date[0]);
|
||||||
|
}
|
||||||
|
|
||||||
// Get SE tags
|
// Get SE tags
|
||||||
foreach($xml->xpath('/package/metadata/meta[@property="se:subject"]') ?: [] as $tag){
|
foreach($xml->xpath('/package/metadata/meta[@property="se:subject"]') ?: [] as $tag){
|
||||||
|
@ -170,14 +174,22 @@ class Ebook{
|
||||||
$this->LocTags[] = (string)$tag;
|
$this->LocTags[] = (string)$tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Figure out authors and contributors.
|
// Figure out authors and contributors
|
||||||
foreach($xml->xpath('/package/metadata/dc:creator') ?: [] as $author){
|
foreach($xml->xpath('/package/metadata/dc:creator') ?: [] as $author){
|
||||||
$id = '';
|
$id = '';
|
||||||
|
|
||||||
if($author->attributes() !== null){
|
if($author->attributes() !== null){
|
||||||
$id = $author->attributes()->id;
|
$id = $author->attributes()->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$refines = null;
|
||||||
|
$refinesElement = $xml->xpath('/package/metadata/meta[@property="file-as"][@refines="#' . $id . '"]');
|
||||||
|
if($refinesElement !== false && sizeof($refinesElement) > 0){
|
||||||
|
$refines = (string)$refinesElement[0];
|
||||||
|
}
|
||||||
|
|
||||||
$this->Authors[] = new Contributor( (string)$author,
|
$this->Authors[] = new Contributor( (string)$author,
|
||||||
(string)$xml->xpath('/package/metadata/meta[@property="file-as"][@refines="#' . $id . '"]')[0],
|
$refines,
|
||||||
$this->NullIfEmpty($xml->xpath('/package/metadata/meta[@property="se:name.person.full-name"][@refines="#' . $id . '"]')),
|
$this->NullIfEmpty($xml->xpath('/package/metadata/meta[@property="se:name.person.full-name"][@refines="#' . $id . '"]')),
|
||||||
$this->NullIfEmpty($xml->xpath('/package/metadata/meta[@property="se:url.encyclopedia.wikipedia"][@refines="#' . $id . '"]'))
|
$this->NullIfEmpty($xml->xpath('/package/metadata/meta[@property="se:url.encyclopedia.wikipedia"][@refines="#' . $id . '"]'))
|
||||||
);
|
);
|
||||||
|
@ -225,8 +237,20 @@ class Ebook{
|
||||||
$this->Description = $this->NullIfEmpty($xml->xpath('/package/metadata/dc:description'));
|
$this->Description = $this->NullIfEmpty($xml->xpath('/package/metadata/dc:description'));
|
||||||
$this->Language = $this->NullIfEmpty($xml->xpath('/package/metadata/dc:language'));
|
$this->Language = $this->NullIfEmpty($xml->xpath('/package/metadata/dc:language'));
|
||||||
$this->LongDescription = $this->NullIfEmpty($xml->xpath('/package/metadata/meta[@property="se:long-description"]'));
|
$this->LongDescription = $this->NullIfEmpty($xml->xpath('/package/metadata/meta[@property="se:long-description"]'));
|
||||||
$this->WordCount = (int)$xml->xpath('/package/metadata/meta[@property="se:word-count"]')[0] ?? 0;
|
|
||||||
$this->ReadingEase = (float)$xml->xpath('/package/metadata/meta[@property="se:reading-ease.flesch"]')[0] ?? 0;
|
$wordCount = 0;
|
||||||
|
$wordCountElement = $xml->xpath('/package/metadata/meta[@property="se:word-count"]');
|
||||||
|
if($wordCountElement !== false && sizeof($wordCountElement) > 0){
|
||||||
|
$wordCount = (int)$wordCountElement[0];
|
||||||
|
}
|
||||||
|
$this->WordCount = $wordCount;
|
||||||
|
|
||||||
|
$readingEase = 0;
|
||||||
|
$readingEaseElement = $xml->xpath('/package/metadata/meta[@property="se:reading-ease.flesch"]');
|
||||||
|
if($readingEaseElement !== false && sizeof($readingEaseElement) > 0){
|
||||||
|
$readingEase = (float)$readingEaseElement[0];
|
||||||
|
}
|
||||||
|
$this->ReadingEase = $readingEase;
|
||||||
|
|
||||||
if($this->ReadingEase !== null){
|
if($this->ReadingEase !== null){
|
||||||
if($this->ReadingEase >= 90){
|
if($this->ReadingEase >= 90){
|
||||||
|
@ -479,9 +503,10 @@ class Ebook{
|
||||||
return $object;
|
return $object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<Contributor> $contributors
|
||||||
|
*/
|
||||||
private function GenerateContributorList(array $contributors): string{
|
private function GenerateContributorList(array $contributors): string{
|
||||||
// Inputs: An array of Contributor objects.
|
|
||||||
|
|
||||||
$string = '';
|
$string = '';
|
||||||
$i = 0;
|
$i = 0;
|
||||||
foreach($contributors as $contributor){
|
foreach($contributors as $contributor){
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
<?
|
<?
|
||||||
|
use Safe\DateTimeImmutable;
|
||||||
|
|
||||||
class GitCommit{
|
class GitCommit{
|
||||||
public $Timestamp;
|
public $Timestamp;
|
||||||
public $Message;
|
public $Message;
|
||||||
|
|
||||||
public function __construct(string $unixTimestamp, string $message){
|
public function __construct(string $unixTimestamp, string $message){
|
||||||
$this->Timestamp = new \DateTimeImmutable('@' . $unixTimestamp);
|
$this->Timestamp = new DateTimeImmutable('@' . $unixTimestamp);
|
||||||
$this->Message = $message;
|
$this->Message = $message;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?
|
<?
|
||||||
class HttpInput{
|
class HttpInput{
|
||||||
public static function GetString(string $variable, bool $allowEmptyString = true, $default = null): ?string{
|
public static function GetString(string $variable, bool $allowEmptyString = true, string $default = null): ?string{
|
||||||
$var = self::GetHttpVar($variable, HTTP_VAR_STR, GET, $default);
|
$var = self::GetHttpVar($variable, HTTP_VAR_STR, GET, $default);
|
||||||
|
|
||||||
if(!$allowEmptyString && $var === ''){
|
if(!$allowEmptyString && $var === ''){
|
||||||
|
@ -10,15 +10,15 @@ class HttpInput{
|
||||||
return $var;
|
return $var;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function GetInt(string $variable, $default = null): ?int{
|
public static function GetInt(string $variable, int $default = null): ?int{
|
||||||
return self::GetHttpVar($variable, HTTP_VAR_INT, GET, $default);
|
return self::GetHttpVar($variable, HTTP_VAR_INT, GET, $default);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function GetBool(string $variable, $default = null): ?bool{
|
public static function GetBool(string $variable, bool $default = null): ?bool{
|
||||||
return self::GetHttpVar($variable, HTTP_VAR_BOOL, GET, $default);
|
return self::GetHttpVar($variable, HTTP_VAR_BOOL, GET, $default);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function GetDec(string $variable, $default = null): ?float{
|
public static function GetDec(string $variable, float $default = null): ?float{
|
||||||
return self::GetHttpVar($variable, HTTP_VAR_DEC, GET, $default);
|
return self::GetHttpVar($variable, HTTP_VAR_DEC, GET, $default);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,6 @@ class HttpInput{
|
||||||
switch($type){
|
switch($type){
|
||||||
case HTTP_VAR_STR:
|
case HTTP_VAR_STR:
|
||||||
return $var;
|
return $var;
|
||||||
break;
|
|
||||||
case HTTP_VAR_INT:
|
case HTTP_VAR_INT:
|
||||||
// Can't use ctype_digit because we may want negative integers
|
// Can't use ctype_digit because we may want negative integers
|
||||||
if(is_numeric($var) && mb_strpos($var, '.') === false){
|
if(is_numeric($var) && mb_strpos($var, '.') === false){
|
||||||
|
@ -62,7 +61,6 @@ class HttpInput{
|
||||||
else{
|
else{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case HTTP_VAR_DEC:
|
case HTTP_VAR_DEC:
|
||||||
if(is_numeric($var)){
|
if(is_numeric($var)){
|
||||||
try{
|
try{
|
||||||
|
|
|
@ -6,6 +6,9 @@ use function Safe\unlink;
|
||||||
use function Safe\usort;
|
use function Safe\usort;
|
||||||
|
|
||||||
class Library{
|
class Library{
|
||||||
|
/**
|
||||||
|
* @return array<Ebook>
|
||||||
|
*/
|
||||||
public static function GetEbooks(string $sort = null): array{
|
public static function GetEbooks(string $sort = null): array{
|
||||||
$ebooks = [];
|
$ebooks = [];
|
||||||
|
|
||||||
|
@ -69,6 +72,9 @@ class Library{
|
||||||
return $ebooks;
|
return $ebooks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<Ebook>
|
||||||
|
*/
|
||||||
public static function GetEbooksByAuthor(string $wwwFilesystemPath): array{
|
public static function GetEbooksByAuthor(string $wwwFilesystemPath): array{
|
||||||
// Do we have the author's ebooks cached?
|
// Do we have the author's ebooks cached?
|
||||||
$ebooks = [];
|
$ebooks = [];
|
||||||
|
@ -82,6 +88,9 @@ class Library{
|
||||||
return $ebooks;
|
return $ebooks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<Ebook>
|
||||||
|
*/
|
||||||
public static function GetEbooksByTag(string $tag): array{
|
public static function GetEbooksByTag(string $tag): array{
|
||||||
// Do we have the tag's ebooks cached?
|
// Do we have the tag's ebooks cached?
|
||||||
$ebooks = [];
|
$ebooks = [];
|
||||||
|
@ -95,6 +104,9 @@ class Library{
|
||||||
return $ebooks;
|
return $ebooks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<Ebook>
|
||||||
|
*/
|
||||||
public static function GetEbooksByCollection(string $collection): array{
|
public static function GetEbooksByCollection(string $collection): array{
|
||||||
// Do we have the tag's ebooks cached?
|
// Do we have the tag's ebooks cached?
|
||||||
$ebooks = [];
|
$ebooks = [];
|
||||||
|
@ -108,6 +120,9 @@ class Library{
|
||||||
return $ebooks;
|
return $ebooks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<Ebook>
|
||||||
|
*/
|
||||||
public static function Search(string $query): array{
|
public static function Search(string $query): array{
|
||||||
$ebooks = Library::GetEbooks();
|
$ebooks = Library::GetEbooks();
|
||||||
$matches = [];
|
$matches = [];
|
||||||
|
|
|
@ -5,7 +5,7 @@ use function Safe\fclose;
|
||||||
use function Safe\error_log;
|
use function Safe\error_log;
|
||||||
|
|
||||||
class Logger{
|
class Logger{
|
||||||
public static function WriteGithubWebhookLogEntry(string $requestId, string $text){
|
public static function WriteGithubWebhookLogEntry(string $requestId, string $text): void{
|
||||||
try{
|
try{
|
||||||
$fp = fopen(GITHUB_WEBHOOK_LOG_FILE_PATH, 'a+');
|
$fp = fopen(GITHUB_WEBHOOK_LOG_FILE_PATH, 'a+');
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ class Logger{
|
||||||
fclose($fp);
|
fclose($fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function WriteErrorLogEntry(string $text){
|
public static function WriteErrorLogEntry(string $text): void{
|
||||||
error_log($text);
|
error_log($text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
class SeeOtherEbookException extends \Exception{
|
class SeeOtherEbookException extends \Exception{
|
||||||
public $Url;
|
public $Url;
|
||||||
|
|
||||||
public function __construct($url = ''){
|
public function __construct(string $url = ''){
|
||||||
$this->Url = $url;
|
$this->Url = $url;
|
||||||
parent::__construct('This ebook is at a different URL: ' . $url);
|
parent::__construct('This ebook is at a different URL: ' . $url);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
class WebhookException extends \Exception{
|
class WebhookException extends \Exception{
|
||||||
public $PostData;
|
public $PostData;
|
||||||
|
|
||||||
public function __construct($message = '', $data = null){
|
public function __construct(string $message = '', string $data = null){
|
||||||
$this->PostData = $data;
|
$this->PostData = $data;
|
||||||
parent::__construct($message);
|
parent::__construct($message);
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,6 @@ try{
|
||||||
// Silence on success.
|
// Silence on success.
|
||||||
Logger::WriteGithubWebhookLogEntry($requestId, 'Event type: ping.');
|
Logger::WriteGithubWebhookLogEntry($requestId, 'Event type: ping.');
|
||||||
throw new NoopException();
|
throw new NoopException();
|
||||||
break;
|
|
||||||
case 'push':
|
case 'push':
|
||||||
Logger::WriteGithubWebhookLogEntry($requestId, 'Event type: push.');
|
Logger::WriteGithubWebhookLogEntry($requestId, 'Event type: push.');
|
||||||
|
|
||||||
|
@ -114,7 +113,6 @@ try{
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new WebhookException('Unrecognized GitHub webhook event.', $post);
|
throw new WebhookException('Unrecognized GitHub webhook event.', $post);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// "Success, no content"
|
// "Success, no content"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue