mirror of
https://github.com/standardebooks/web.git
synced 2025-07-06 14:50:39 -04:00
Flesh out some PHPDocs, and consistently name enums
This commit is contained in:
parent
ace9cea6b7
commit
a9eab552ab
25 changed files with 205 additions and 118 deletions
|
@ -49,7 +49,7 @@ class Artwork{
|
||||||
public ?string $Exception = null;
|
public ?string $Exception = null;
|
||||||
public ?string $Notes = null;
|
public ?string $Notes = null;
|
||||||
public ?ImageMimeType $MimeType = null;
|
public ?ImageMimeType $MimeType = null;
|
||||||
public ?ArtworkStatus $Status = null;
|
public ?ArtworkStatusType $Status = null;
|
||||||
|
|
||||||
protected ?string $_UrlName = null;
|
protected ?string $_UrlName = null;
|
||||||
protected ?string $_Url = null;
|
protected ?string $_Url = null;
|
||||||
|
@ -287,7 +287,7 @@ class Artwork{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(($user->Benefits->CanReviewArtwork || $user->UserId == $this->SubmitterUserId) && ($this->Status == ArtworkStatus::Unverified || $this->Status == ArtworkStatus::Declined)){
|
if(($user->Benefits->CanReviewArtwork || $user->UserId == $this->SubmitterUserId) && ($this->Status == ArtworkStatusType::Unverified || $this->Status == ArtworkStatusType::Declined)){
|
||||||
// Editors can edit an artwork, and submitters can edit their own artwork, if it's not yet approved.
|
// Editors can edit an artwork, and submitters can edit their own artwork, if it's not yet approved.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -305,7 +305,7 @@ class Artwork{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if($user->Benefits->CanReviewArtwork && $user->UserId != $this->SubmitterUserId && ($this->Status == ArtworkStatus::Unverified || $this->Status == ArtworkStatus::Declined)){
|
if($user->Benefits->CanReviewArtwork && $user->UserId != $this->SubmitterUserId && ($this->Status == ArtworkStatusType::Unverified || $this->Status == ArtworkStatusType::Declined)){
|
||||||
// Editors can change the status of artwork they did not submit themselves, and that is not yet approved.
|
// Editors can change the status of artwork they did not submit themselves, and that is not yet approved.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -883,7 +883,7 @@ class Artwork{
|
||||||
$artwork->CompletedYear = HttpInput::Int(POST, 'artwork-year');
|
$artwork->CompletedYear = HttpInput::Int(POST, 'artwork-year');
|
||||||
$artwork->CompletedYearIsCirca = HttpInput::Bool(POST, 'artwork-year-is-circa') ?? false;
|
$artwork->CompletedYearIsCirca = HttpInput::Bool(POST, 'artwork-year-is-circa') ?? false;
|
||||||
$artwork->Tags = HttpInput::Str(POST, 'artwork-tags') ?? [];
|
$artwork->Tags = HttpInput::Str(POST, 'artwork-tags') ?? [];
|
||||||
$artwork->Status = ArtworkStatus::tryFrom(HttpInput::Str(POST, 'artwork-status') ?? '') ?? ArtworkStatus::Unverified;
|
$artwork->Status = ArtworkStatusType::tryFrom(HttpInput::Str(POST, 'artwork-status') ?? '') ?? ArtworkStatusType::Unverified;
|
||||||
$artwork->EbookUrl = HttpInput::Str(POST, 'artwork-ebook-url');
|
$artwork->EbookUrl = HttpInput::Str(POST, 'artwork-ebook-url');
|
||||||
$artwork->IsPublishedInUs = HttpInput::Bool(POST, 'artwork-is-published-in-us') ?? false;
|
$artwork->IsPublishedInUs = HttpInput::Bool(POST, 'artwork-is-published-in-us') ?? false;
|
||||||
$artwork->PublicationYear = HttpInput::Int(POST, 'artwork-publication-year');
|
$artwork->PublicationYear = HttpInput::Int(POST, 'artwork-publication-year');
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?
|
<?
|
||||||
enum ArtworkSort: string{
|
enum ArtworkSortType: string{
|
||||||
case CreatedNewest = 'created-newest';
|
case CreatedNewest = 'created-newest';
|
||||||
case ArtistAlpha = 'artist-alpha';
|
case ArtistAlpha = 'artist-alpha';
|
||||||
case CompletedNewest = 'completed-newest';
|
case CompletedNewest = 'completed-newest';
|
|
@ -1,5 +1,5 @@
|
||||||
<?
|
<?
|
||||||
enum ArtworkStatus: string{
|
enum ArtworkStatusType: string{
|
||||||
case Unverified = 'unverified';
|
case Unverified = 'unverified';
|
||||||
case Declined = 'declined';
|
case Declined = 'declined';
|
||||||
case Approved = 'approved';
|
case Approved = 'approved';
|
20
lib/Core.php
20
lib/Core.php
|
@ -12,18 +12,32 @@ mb_internal_encoding('UTF-8');
|
||||||
mb_http_output('UTF-8');
|
mb_http_output('UTF-8');
|
||||||
date_default_timezone_set('UTC');
|
date_default_timezone_set('UTC');
|
||||||
|
|
||||||
// Convenience alias of var_dump.
|
/**
|
||||||
|
* Convenient shorthand alias of `var_dump()`.
|
||||||
|
*
|
||||||
|
* @param mixed $var The variable to dump.
|
||||||
|
*/
|
||||||
function vd(mixed $var): void{
|
function vd(mixed $var): void{
|
||||||
var_dump($var);
|
var_dump($var);
|
||||||
}
|
}
|
||||||
|
|
||||||
// var_dump($var) then die().
|
/**
|
||||||
|
* Convenient shorthand alias to `var_dump()`, then `die()`.
|
||||||
|
*
|
||||||
|
* @param mixed $var The variable to dump.
|
||||||
|
*/
|
||||||
function vdd(mixed $var): void{
|
function vdd(mixed $var): void{
|
||||||
var_dump($var);
|
var_dump($var);
|
||||||
die();
|
die();
|
||||||
}
|
}
|
||||||
|
|
||||||
// var_dump into a string.
|
/**
|
||||||
|
* `var_dump()` into a string.
|
||||||
|
*
|
||||||
|
* @param mixed $var The variable to dump into a string.
|
||||||
|
*
|
||||||
|
* @return string The output of `var_dump()`.
|
||||||
|
*/
|
||||||
function vds(mixed $var): string{
|
function vds(mixed $var): string{
|
||||||
ob_start();
|
ob_start();
|
||||||
var_dump($var);
|
var_dump($var);
|
||||||
|
|
|
@ -8,6 +8,15 @@ class DbConnection{
|
||||||
public int $QueryCount = 0;
|
public int $QueryCount = 0;
|
||||||
public int $LastQueryAffectedRowCount = 0;
|
public int $LastQueryAffectedRowCount = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new database connection.
|
||||||
|
*
|
||||||
|
* @param ?string $defaultDatabase The default database to connect to, or `null` not to define one.
|
||||||
|
* @param string $host The database hostname.
|
||||||
|
* @param ?string $user The user to connect to, or `null` to log in as the current Unix user via a local socket.
|
||||||
|
* @param string $password The password to use, or an empty string if no password is required.
|
||||||
|
* @param bool $forceUtf8 If **TRUE**, issue `set names utf8mb4 collate utf8mb4_unicode_ci` when starting the connection.
|
||||||
|
*/
|
||||||
public function __construct(?string $defaultDatabase = null, string $host = 'localhost', ?string $user = null, string $password = '', bool $forceUtf8 = true){
|
public function __construct(?string $defaultDatabase = null, string $host = 'localhost', ?string $user = null, string $password = '', bool $forceUtf8 = true){
|
||||||
if($user === null){
|
if($user === null){
|
||||||
// Get the user running the script for local socket login
|
// Get the user running the script for local socket login
|
||||||
|
@ -53,11 +62,15 @@ class DbConnection{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute a generic query in the database.
|
* Execute a generic query in the database.
|
||||||
|
*
|
||||||
* @template T
|
* @template T
|
||||||
|
*
|
||||||
* @param string $sql The SQL query to execute.
|
* @param string $sql The SQL query to execute.
|
||||||
* @param array<mixed> $params An array of parameters to bind to the SQL statement.
|
* @param array<mixed> $params An array of parameters to bind to the SQL statement.
|
||||||
* @param class-string<T> $class The type of object to return in the return array.
|
* @param class-string<T> $class The type of object to return in the return array.
|
||||||
* @return Array<T>
|
*
|
||||||
|
* @return Array<T> An array of objects of type `$class`, or `stdClass` if `$class` is `null`.
|
||||||
|
*
|
||||||
* @throws Exceptions\DuplicateDatabaseKeyException When a unique key constraint has been violated.
|
* @throws Exceptions\DuplicateDatabaseKeyException When a unique key constraint has been violated.
|
||||||
* @throws Exceptions\DatabaseQueryException When an error occurs during execution of the query.
|
* @throws Exceptions\DatabaseQueryException When an error occurs during execution of the query.
|
||||||
*/
|
*/
|
||||||
|
@ -128,11 +141,14 @@ class DbConnection{
|
||||||
* **Important note:** When joining against two tables, SQL only returns one column for the join key (typically an ID value). Therefore, if both objects require an ID, the filler method must explicitly assign the ID to one of the two objects that's missing it. The above example shows this behavior: note how we join on UserId, but only the Users result has the UserId column, even though the Posts table also has a UserId column.
|
* **Important note:** When joining against two tables, SQL only returns one column for the join key (typically an ID value). Therefore, if both objects require an ID, the filler method must explicitly assign the ID to one of the two objects that's missing it. The above example shows this behavior: note how we join on UserId, but only the Users result has the UserId column, even though the Posts table also has a UserId column.
|
||||||
*
|
*
|
||||||
* @template T
|
* @template T
|
||||||
|
*
|
||||||
* @param string $sql The SQL query to execute.
|
* @param string $sql The SQL query to execute.
|
||||||
* @param array<mixed> $params An array of parameters to bind to the SQL statement.
|
* @param array<mixed> $params An array of parameters to bind to the SQL statement.
|
||||||
* @param class-string<T> $class The class to instantiate for each row, or null to return an array of rows.
|
* @param class-string<T> $class The class to instantiate for each row, or `null` to return an array of rows.
|
||||||
* @return array<T>|array<array<mixed>> Returns an array of $class if $class is not null, otherwise returns an array of rows.
|
*
|
||||||
* @throws Exceptions\AppException If a class was specified but the class doesn't have a FromMultiTableRow method.
|
* @return array<T>|array<array<mixed>> An array of `$class` if `$class` is not `null`, otherwise an array of rows.
|
||||||
|
*
|
||||||
|
* @throws Exceptions\AppException If a class was specified but the class doesn't have a `FromMultiTableRow` method.
|
||||||
* @throws Exceptions\DatabaseQueryException When an error occurs during execution of the query.
|
* @throws Exceptions\DatabaseQueryException When an error occurs during execution of the query.
|
||||||
*/
|
*/
|
||||||
public function MultiTableSelect(string $sql, array $params = [], ?string $class = null): array{
|
public function MultiTableSelect(string $sql, array $params = [], ?string $class = null): array{
|
||||||
|
@ -168,8 +184,13 @@ class DbConnection{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Given a string of SQL, prepare a PDO handle by binding the parameters to the query.
|
||||||
|
*
|
||||||
* @param string $sql The SQL query to execute.
|
* @param string $sql The SQL query to execute.
|
||||||
* @param array<mixed> $params An array of parameters to bind to the SQL statement.
|
* @param array<mixed> $params An array of parameters to bind to the SQL statement.
|
||||||
|
*
|
||||||
|
* @return \PdoStatement The `\PDOStatement` to be used to execute the query.
|
||||||
|
*
|
||||||
* @throws Exceptions\DatabaseQueryException When an error occurs during execution of the query.
|
* @throws Exceptions\DatabaseQueryException When an error occurs during execution of the query.
|
||||||
*/
|
*/
|
||||||
private function PreparePdoHandle(string $sql, array $params): \PDOStatement{
|
private function PreparePdoHandle(string $sql, array $params): \PDOStatement{
|
||||||
|
@ -208,9 +229,15 @@ class DbConnection{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Execute a regular query and return the result as an array of objects.
|
||||||
|
*
|
||||||
* @template T
|
* @template T
|
||||||
* @param class-string<T> $class
|
*
|
||||||
* @return array<T>
|
* @param \PdoStatement $handle The PDO handle to execute.
|
||||||
|
* @param class-string<T> $class The type of object to return in the return array.
|
||||||
|
*
|
||||||
|
* @return array<T> An array of objects of type `$class`, or `stdClass` if `$class` is `null`.
|
||||||
|
*
|
||||||
* @throws \PDOException When an error occurs during execution of the query.
|
* @throws \PDOException When an error occurs during execution of the query.
|
||||||
*/
|
*/
|
||||||
private function ExecuteQuery(\PDOStatement $handle, string $class = 'stdClass'): array{
|
private function ExecuteQuery(\PDOStatement $handle, string $class = 'stdClass'): array{
|
||||||
|
@ -282,9 +309,15 @@ class DbConnection{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Execute a multi-table select query.
|
||||||
|
*
|
||||||
* @template T
|
* @template T
|
||||||
* @param ?class-string<T> $class
|
*
|
||||||
* @return array<T>|array<array<mixed>>
|
* @param \PdoStatement $handle The PDO handle to execute.
|
||||||
|
* @param class-string<T> $class The class to instantiate for each row, or `null` to return an array of rows.
|
||||||
|
*
|
||||||
|
* @return array<T>|array<array<mixed>> An array of `$class` if `$class` is not `null`, otherwise an array of rows.
|
||||||
|
*
|
||||||
* @throws \PDOException When an error occurs during execution of the query.
|
* @throws \PDOException When an error occurs during execution of the query.
|
||||||
*/
|
*/
|
||||||
private function ExecuteMultiTableSelect(\PDOStatement $handle, ?string $class): array{
|
private function ExecuteMultiTableSelect(\PDOStatement $handle, ?string $class): array{
|
||||||
|
@ -333,7 +366,13 @@ class DbConnection{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<mixed> $metadata
|
* Given a column value and its database driver metadata, return a strongly-typed value.
|
||||||
|
*
|
||||||
|
* @param mixed $column The value of the column, most likely either a string or integer.
|
||||||
|
* @param array<mixed> $metadata An array of metadata returned from the database driver.
|
||||||
|
* @param string $class The type of object that this return value will be part of.
|
||||||
|
*
|
||||||
|
* @return mixed The strongly-typed column value.
|
||||||
*/
|
*/
|
||||||
private function GetColumnValue(mixed $column, array $metadata, string $class = 'stdClass'): mixed{
|
private function GetColumnValue(mixed $column, array $metadata, string $class = 'stdClass'): mixed{
|
||||||
if($column === null){
|
if($column === null){
|
||||||
|
@ -402,6 +441,9 @@ class DbConnection{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the ID of the last row that was inserted during this database connection.
|
* Get the ID of the last row that was inserted during this database connection.
|
||||||
|
*
|
||||||
|
* @return int The ID of the last row that was inserted during this database connection.
|
||||||
|
*
|
||||||
* @throws Exceptions\DatabaseQueryException When the last inserted ID can't be determined.
|
* @throws Exceptions\DatabaseQueryException When the last inserted ID can't be determined.
|
||||||
*/
|
*/
|
||||||
public function GetLastInsertedId(): int{
|
public function GetLastInsertedId(): int{
|
||||||
|
@ -421,9 +463,13 @@ class DbConnection{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Create a detailed `Exceptions\DatabaseQueryException` from a `\PDOException`.
|
||||||
|
*
|
||||||
* @param \PDOException $ex The exception to create details from.
|
* @param \PDOException $ex The exception to create details from.
|
||||||
* @param string $sql The prepared SQL that caused the exception.
|
* @param string $sql The prepared SQL that caused the exception.
|
||||||
* @param array<mixed> $params The parameters passed to the prepared SQL.
|
* @param array<mixed> $params The parameters passed to the prepared SQL.
|
||||||
|
*
|
||||||
|
* @return Exceptions\DatabaseQueryException A more detailed exception to be thrown further up the stack.
|
||||||
*/
|
*/
|
||||||
private function CreateDetailedException(\PDOException $ex, string $sql, array $params): Exceptions\DatabaseQueryException{
|
private function CreateDetailedException(\PDOException $ex, string $sql, array $params): Exceptions\DatabaseQueryException{
|
||||||
// Throw a custom exception that includes more information on the query and paramaters
|
// Throw a custom exception that includes more information on the query and paramaters
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?
|
<?
|
||||||
enum EbookFormat: string{
|
enum EbookFormatType: string{
|
||||||
case Epub = 'epub';
|
case Epub = 'epub';
|
||||||
case Azw3 = 'azw3';
|
case Azw3 = 'azw3';
|
||||||
case Kepub = 'kepub';
|
case Kepub = 'kepub';
|
|
@ -1,5 +1,5 @@
|
||||||
<?
|
<?
|
||||||
enum EbookSort: string{
|
enum EbookSortType: string{
|
||||||
case Newest = 'newest';
|
case Newest = 'newest';
|
||||||
case AuthorAlpha = 'author-alpha';
|
case AuthorAlpha = 'author-alpha';
|
||||||
case ReadingEase = 'reading-ease';
|
case ReadingEase = 'reading-ease';
|
|
@ -3,7 +3,7 @@ namespace Exceptions;
|
||||||
|
|
||||||
class ValidationException extends AppException{
|
class ValidationException extends AppException{
|
||||||
/** @var array<\Exception> $Exceptions */
|
/** @var array<\Exception> $Exceptions */
|
||||||
public $Exceptions = [];
|
public array $Exceptions = [];
|
||||||
public bool $HasExceptions = false;
|
public bool $HasExceptions = false;
|
||||||
public bool $IsFatal = false;
|
public bool $IsFatal = false;
|
||||||
|
|
||||||
|
@ -19,8 +19,7 @@ class ValidationException extends AppException{
|
||||||
|
|
||||||
public function Add(\Exception $exception, bool $isFatal = false): void{
|
public function Add(\Exception $exception, bool $isFatal = false): void{
|
||||||
/** @var ValidationException $exception */
|
/** @var ValidationException $exception */
|
||||||
if(is_a($exception, static::class)){
|
if($exception instanceof static){
|
||||||
/** @var ValidationException $childException */
|
|
||||||
foreach($exception->Exceptions as $childException){
|
foreach($exception->Exceptions as $childException){
|
||||||
$this->Add($childException);
|
$this->Add($childException);
|
||||||
}
|
}
|
||||||
|
@ -29,6 +28,8 @@ class ValidationException extends AppException{
|
||||||
$this->Exceptions[] = $exception;
|
$this->Exceptions[] = $exception;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Don't set $this->IsFatal directly, so that a non-fatal exception
|
||||||
|
// added later won't overwrite the fatality of a previous exception.
|
||||||
if($isFatal){
|
if($isFatal){
|
||||||
$this->IsFatal = true;
|
$this->IsFatal = true;
|
||||||
}
|
}
|
||||||
|
@ -45,10 +46,4 @@ class ValidationException extends AppException{
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function Clear(): void{
|
|
||||||
unset($this->Exceptions);
|
|
||||||
$this->Exceptions = [];
|
|
||||||
$this->HasExceptions = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
use function Safe\preg_replace;
|
use function Safe\preg_replace;
|
||||||
|
|
||||||
class Formatter{
|
class Formatter{
|
||||||
|
/**
|
||||||
|
* Remove diacritics from a string.
|
||||||
|
*/
|
||||||
public static function RemoveDiacritics(string $text): string{
|
public static function RemoveDiacritics(string $text): string{
|
||||||
if(!isset($GLOBALS['transliterator'])){
|
if(!isset($GLOBALS['transliterator'])){
|
||||||
$GLOBALS['transliterator'] = Transliterator::createFromRules(':: Any-Latin; :: Latin-ASCII; :: NFD; :: [:Nonspacing Mark:] Remove; :: Lower(); :: NFC;', Transliterator::FORWARD);
|
$GLOBALS['transliterator'] = Transliterator::createFromRules(':: Any-Latin; :: Latin-ASCII; :: NFD; :: [:Nonspacing Mark:] Remove; :: Lower(); :: NFC;', Transliterator::FORWARD);
|
||||||
|
@ -10,6 +13,21 @@ class Formatter{
|
||||||
return $GLOBALS['transliterator']->transliterate($text);
|
return $GLOBALS['transliterator']->transliterate($text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escape a string so that it's appropriate to use in a URL slug.
|
||||||
|
*
|
||||||
|
* This does the following to the string:
|
||||||
|
*
|
||||||
|
* 1. Removes any diacritics.
|
||||||
|
*
|
||||||
|
* 2. Removes apostrophes.
|
||||||
|
*
|
||||||
|
* 3. Converts the string to lowercase.
|
||||||
|
*
|
||||||
|
* 4. Converts any non-digit, non-letter character to a space.
|
||||||
|
*
|
||||||
|
* 5. Converts any sequence of one or more spaces to a single dash.
|
||||||
|
*/
|
||||||
public static function MakeUrlSafe(string $text): string{
|
public static function MakeUrlSafe(string $text): string{
|
||||||
// Remove accent characters
|
// Remove accent characters
|
||||||
$text = self::RemoveDiacritics($text);
|
$text = self::RemoveDiacritics($text);
|
||||||
|
@ -32,24 +50,38 @@ class Formatter{
|
||||||
return $text;
|
return $text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escape a string so that it's safe to output directly into an HTML document.
|
||||||
|
*/
|
||||||
public static function EscapeHtml(?string $text): string{
|
public static function EscapeHtml(?string $text): string{
|
||||||
return htmlspecialchars(trim($text ?? ''), ENT_QUOTES, 'utf-8');
|
return htmlspecialchars(trim($text ?? ''), ENT_QUOTES, 'utf-8');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escape a strin so that it's safe to output directly into an XML document. Note that this is **not the same** as escaping for HTML. Any query strings in URLs should already be URL-encoded, for example `?foo=bar+baz&x=y`.
|
||||||
|
*/
|
||||||
public static function EscapeXml(?string $text): string{
|
public static function EscapeXml(?string $text): string{
|
||||||
// Accepts a query string that has already been url-encoded. For example,
|
|
||||||
// ?foo=bar+baz&x=y
|
|
||||||
return htmlspecialchars(trim($text ?? ''), ENT_QUOTES|ENT_XML1, 'utf-8');
|
return htmlspecialchars(trim($text ?? ''), ENT_QUOTES|ENT_XML1, 'utf-8');
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function EscapeMarkdown(?string $text): string{
|
/**
|
||||||
$parsedown = new Parsedown();
|
* Convert a string of Markdown into HTML.
|
||||||
$parsedown->setSafeMode(true);
|
*/
|
||||||
return $parsedown->text($text);
|
public static function MarkdownToHtml(?string $text): string{
|
||||||
|
if(!isset($GLOBALS['markdown-parser'])){
|
||||||
|
$GLOBALS['markdown-parser'] = new Parsedown();
|
||||||
|
$GLOBALS['markdown-parser']->setSafeMode(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $GLOBALS['markdown-parser']->text($text);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a number of bytes, return a string containing a human-readable filesize.
|
||||||
|
*
|
||||||
|
* @see https://stackoverflow.com/a/5501447
|
||||||
|
*/
|
||||||
public static function ToFileSize(?int $bytes): string{
|
public static function ToFileSize(?int $bytes): string{
|
||||||
// See https://stackoverflow.com/a/5501447
|
|
||||||
$output = '';
|
$output = '';
|
||||||
|
|
||||||
if($bytes >= 1073741824){
|
if($bytes >= 1073741824){
|
||||||
|
|
|
@ -19,12 +19,12 @@ class Library{
|
||||||
* @return array<Ebook>
|
* @return array<Ebook>
|
||||||
* @throws Exceptions\AppException
|
* @throws Exceptions\AppException
|
||||||
*/
|
*/
|
||||||
public static function FilterEbooks(string $query = null, array $tags = [], EbookSort $sort = null): array{
|
public static function FilterEbooks(string $query = null, array $tags = [], EbookSortType $sort = null): array{
|
||||||
$ebooks = Library::GetEbooks();
|
$ebooks = Library::GetEbooks();
|
||||||
$matches = $ebooks;
|
$matches = $ebooks;
|
||||||
|
|
||||||
if($sort === null){
|
if($sort === null){
|
||||||
$sort = EbookSort::Newest;
|
$sort = EbookSortType::Newest;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sizeof($tags) > 0 && !in_array('all', $tags)){ // 0 tags means "all ebooks"
|
if(sizeof($tags) > 0 && !in_array('all', $tags)){ // 0 tags means "all ebooks"
|
||||||
|
@ -51,13 +51,13 @@ class Library{
|
||||||
}
|
}
|
||||||
|
|
||||||
switch($sort){
|
switch($sort){
|
||||||
case EbookSort::AuthorAlpha:
|
case EbookSortType::AuthorAlpha:
|
||||||
usort($matches, function($a, $b){
|
usort($matches, function($a, $b){
|
||||||
return strcmp(mb_strtolower($a->Authors[0]->SortName), mb_strtolower($b->Authors[0]->SortName));
|
return strcmp(mb_strtolower($a->Authors[0]->SortName), mb_strtolower($b->Authors[0]->SortName));
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EbookSort::Newest:
|
case EbookSortType::Newest:
|
||||||
usort($matches, function($a, $b){
|
usort($matches, function($a, $b){
|
||||||
if($a->Created < $b->Created){
|
if($a->Created < $b->Created){
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -73,7 +73,7 @@ class Library{
|
||||||
$matches = array_reverse($matches);
|
$matches = array_reverse($matches);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EbookSort::ReadingEase:
|
case EbookSortType::ReadingEase:
|
||||||
usort($matches, function($a, $b){
|
usort($matches, function($a, $b){
|
||||||
if($a->ReadingEase < $b->ReadingEase){
|
if($a->ReadingEase < $b->ReadingEase){
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -89,7 +89,7 @@ class Library{
|
||||||
$matches = array_reverse($matches);
|
$matches = array_reverse($matches);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EbookSort::Length:
|
case EbookSortType::Length:
|
||||||
usort($matches, function($a, $b){
|
usort($matches, function($a, $b){
|
||||||
if($a->WordCount < $b->WordCount){
|
if($a->WordCount < $b->WordCount){
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -170,10 +170,10 @@ class Library{
|
||||||
/**
|
/**
|
||||||
* @param string $query
|
* @param string $query
|
||||||
* @param string $status
|
* @param string $status
|
||||||
* @param ArtworkSort $sort
|
* @param ArtworkSortType $sort
|
||||||
* @return array<string, array<Artwork>|int>
|
* @return array<string, array<Artwork>|int>
|
||||||
*/
|
*/
|
||||||
public static function FilterArtwork(string $query = null, string $status = null, ArtworkSort $sort = null, int $submitterUserId = null, int $page = 1, int $perPage = ARTWORK_PER_PAGE): array{
|
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{
|
||||||
// Returns an array of:
|
// Returns an array of:
|
||||||
// ['artworks'] => array<Artwork>,
|
// ['artworks'] => array<Artwork>,
|
||||||
// ['artworksCount'] => int
|
// ['artworksCount'] => int
|
||||||
|
@ -191,29 +191,29 @@ class Library{
|
||||||
|
|
||||||
if($status === null || $status == 'all'){
|
if($status === null || $status == 'all'){
|
||||||
$statusCondition = 'Status = ?';
|
$statusCondition = 'Status = ?';
|
||||||
$params[] = ArtworkStatus::Approved->value;
|
$params[] = ArtworkStatusType::Approved->value;
|
||||||
}
|
}
|
||||||
elseif($status == 'all-admin'){
|
elseif($status == 'all-admin'){
|
||||||
$statusCondition = 'true';
|
$statusCondition = 'true';
|
||||||
}
|
}
|
||||||
elseif($status == 'all-submitter' && $submitterUserId !== null){
|
elseif($status == 'all-submitter' && $submitterUserId !== null){
|
||||||
$statusCondition = '(Status = ? or (Status = ? and SubmitterUserId = ?))';
|
$statusCondition = '(Status = ? or (Status = ? and SubmitterUserId = ?))';
|
||||||
$params[] = ArtworkStatus::Approved->value;
|
$params[] = ArtworkStatusType::Approved->value;
|
||||||
$params[] = ArtworkStatus::Unverified->value;
|
$params[] = ArtworkStatusType::Unverified->value;
|
||||||
$params[] = $submitterUserId;
|
$params[] = $submitterUserId;
|
||||||
}
|
}
|
||||||
elseif($status == 'unverified-submitter' && $submitterUserId !== null){
|
elseif($status == 'unverified-submitter' && $submitterUserId !== null){
|
||||||
$statusCondition = 'Status = ? and SubmitterUserId = ?';
|
$statusCondition = 'Status = ? and SubmitterUserId = ?';
|
||||||
$params[] = ArtworkStatus::Unverified->value;
|
$params[] = ArtworkStatusType::Unverified->value;
|
||||||
$params[] = $submitterUserId;
|
$params[] = $submitterUserId;
|
||||||
}
|
}
|
||||||
elseif($status == 'in-use'){
|
elseif($status == 'in-use'){
|
||||||
$statusCondition = 'Status = ? and EbookUrl is not null';
|
$statusCondition = 'Status = ? and EbookUrl is not null';
|
||||||
$params[] = ArtworkStatus::Approved->value;
|
$params[] = ArtworkStatusType::Approved->value;
|
||||||
}
|
}
|
||||||
elseif($status == ArtworkStatus::Approved->value){
|
elseif($status == ArtworkStatusType::Approved->value){
|
||||||
$statusCondition = 'Status = ? and EbookUrl is null';
|
$statusCondition = 'Status = ? and EbookUrl is null';
|
||||||
$params[] = ArtworkStatus::Approved->value;
|
$params[] = ArtworkStatusType::Approved->value;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
$statusCondition = 'Status = ?';
|
$statusCondition = 'Status = ?';
|
||||||
|
@ -221,10 +221,10 @@ class Library{
|
||||||
}
|
}
|
||||||
|
|
||||||
$orderBy = 'art.Created desc';
|
$orderBy = 'art.Created desc';
|
||||||
if($sort == ArtworkSort::ArtistAlpha){
|
if($sort == ArtworkSortType::ArtistAlpha){
|
||||||
$orderBy = 'a.Name';
|
$orderBy = 'a.Name';
|
||||||
}
|
}
|
||||||
elseif($sort == ArtworkSort::CompletedNewest){
|
elseif($sort == ArtworkSortType::CompletedNewest){
|
||||||
$orderBy = 'art.CompletedYear desc';
|
$orderBy = 'art.CompletedYear desc';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,13 +336,13 @@ class Library{
|
||||||
}
|
}
|
||||||
elseif($status == 'all-submitter' && $submitterUserId !== null){
|
elseif($status == 'all-submitter' && $submitterUserId !== null){
|
||||||
$statusCondition = '(Status = ? or (Status = ? and SubmitterUserId = ?))';
|
$statusCondition = '(Status = ? or (Status = ? and SubmitterUserId = ?))';
|
||||||
$params[] = ArtworkStatus::Approved->value;
|
$params[] = ArtworkStatusType::Approved->value;
|
||||||
$params[] = ArtworkStatus::Unverified->value;
|
$params[] = ArtworkStatusType::Unverified->value;
|
||||||
$params[] = $submitterUserId;
|
$params[] = $submitterUserId;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
$statusCondition = 'Status = ?';
|
$statusCondition = 'Status = ?';
|
||||||
$params[] = ArtworkStatus::Approved->value;
|
$params[] = ArtworkStatusType::Approved->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
$params[] = $artistUrlName; // a.UrlName
|
$params[] = $artistUrlName; // a.UrlName
|
||||||
|
|
|
@ -10,7 +10,7 @@ class Payment{
|
||||||
public int $PaymentId;
|
public int $PaymentId;
|
||||||
public ?int $UserId = null;
|
public ?int $UserId = null;
|
||||||
public DateTimeImmutable $Created;
|
public DateTimeImmutable $Created;
|
||||||
public PaymentProcessor $Processor;
|
public PaymentProcessorType $Processor;
|
||||||
public string $TransactionId;
|
public string $TransactionId;
|
||||||
public float $Amount;
|
public float $Amount;
|
||||||
public float $Fee;
|
public float $Fee;
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
<?
|
|
||||||
enum PaymentProcessor: string{
|
|
||||||
case FracturedAtlas = 'fractured_atlas';
|
|
||||||
}
|
|
4
lib/PaymentProcessorType.php
Normal file
4
lib/PaymentProcessorType.php
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<?
|
||||||
|
enum PaymentProcessorType: string{
|
||||||
|
case FracturedAtlas = 'fractured_atlas';
|
||||||
|
}
|
|
@ -190,9 +190,9 @@ $now = new DateTimeImmutable('now', new DateTimeZone('America/Juneau')); // Late
|
||||||
<span>Artwork approval status</span>
|
<span>Artwork approval status</span>
|
||||||
<span>
|
<span>
|
||||||
<select name="artwork-status">
|
<select name="artwork-status">
|
||||||
<option value="<?= ArtworkStatus::Unverified->value ?>"<? if($artwork->Status == ArtworkStatus::Unverified){ ?> selected="selected"<? } ?>>Unverified</option>
|
<option value="<?= ArtworkStatusType::Unverified->value ?>"<? if($artwork->Status == ArtworkStatusType::Unverified){ ?> selected="selected"<? } ?>>Unverified</option>
|
||||||
<option value="<?= ArtworkStatus::Declined->value ?>"<? if($artwork->Status == ArtworkStatus::Declined){ ?> selected="selected"<? } ?>>Declined</option>
|
<option value="<?= ArtworkStatusType::Declined->value ?>"<? if($artwork->Status == ArtworkStatusType::Declined){ ?> selected="selected"<? } ?>>Declined</option>
|
||||||
<option value="<?= ArtworkStatus::Approved->value ?>"<? if($artwork->Status == ArtworkStatus::Approved){ ?> selected="selected"<? } ?>>Approved</option>
|
<option value="<?= ArtworkStatusType::Approved->value ?>"<? if($artwork->Status == ArtworkStatusType::Approved){ ?> selected="selected"<? } ?>>Approved</option>
|
||||||
</select>
|
</select>
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
|
@ -11,11 +11,11 @@ $artworks = $artworks ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
switch($artwork->Status){
|
switch($artwork->Status){
|
||||||
case ArtworkStatus::Unverified:
|
case ArtworkStatusType::Unverified:
|
||||||
$class .= ' unverified';
|
$class .= ' unverified';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ArtworkStatus::Declined:
|
case ArtworkStatusType::Declined:
|
||||||
$class .= ' declined';
|
$class .= ' declined';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
$artwork = $artwork ?? null;
|
$artwork = $artwork ?? null;
|
||||||
?>
|
?>
|
||||||
<? if($artwork !== null){ ?>
|
<? if($artwork !== null){ ?>
|
||||||
<? if($artwork->Status == ArtworkStatus::Approved){ ?>Approved<? } ?>
|
<? if($artwork->Status == ArtworkStatusType::Approved){ ?>Approved<? } ?>
|
||||||
<? if($artwork->Status == ArtworkStatus::Declined){ ?>Declined<? } ?>
|
<? if($artwork->Status == ArtworkStatusType::Declined){ ?>Declined<? } ?>
|
||||||
<? if($artwork->Status == ArtworkStatus::Unverified){ ?>Unverified<? } ?>
|
<? if($artwork->Status == ArtworkStatusType::Unverified){ ?>Unverified<? } ?>
|
||||||
<? if($artwork->EbookUrl !== null){ ?> — in use<? if($artwork->EbookUrl !== null){ ?> by <? if($artwork->Ebook !== null && $artwork->Ebook->Url !== null){ ?><i><a href="<?= $artwork->Ebook->Url ?>"><?= Formatter::EscapeHtml($artwork->Ebook->Title) ?></a></i><? }else{ ?><code><?= Formatter::EscapeHtml($artwork->EbookUrl) ?></code> (unreleased)<? } ?><? } ?><? } ?>
|
<? if($artwork->EbookUrl !== null){ ?> — in use<? if($artwork->EbookUrl !== null){ ?> by <? if($artwork->Ebook !== null && $artwork->Ebook->Url !== null){ ?><i><a href="<?= $artwork->Ebook->Url ?>"><?= Formatter::EscapeHtml($artwork->Ebook->Title) ?></a></i><? }else{ ?><code><?= Formatter::EscapeHtml($artwork->EbookUrl) ?></code> (unreleased)<? } ?><? } ?><? } ?>
|
||||||
<? } ?>
|
<? } ?>
|
||||||
|
|
|
@ -17,10 +17,10 @@ $allSelected = sizeof($tags) == 0 || in_array('all', $tags);
|
||||||
<span>Sort</span>
|
<span>Sort</span>
|
||||||
<span>
|
<span>
|
||||||
<select name="sort">
|
<select name="sort">
|
||||||
<option value="<?= EbookSort::Newest->value ?>"<? if($sort == EbookSort::Newest){ ?> selected="selected"<? } ?>>S.E. release date (new → old)</option>
|
<option value="<?= EbookSortType::Newest->value ?>"<? if($sort == EbookSortType::Newest){ ?> selected="selected"<? } ?>>S.E. release date (new → old)</option>
|
||||||
<option value="<?= EbookSort::AuthorAlpha->value ?>"<? if($sort == EbookSort::AuthorAlpha){ ?> selected="selected"<? } ?>>Author name (a → z)</option>
|
<option value="<?= EbookSortType::AuthorAlpha->value ?>"<? if($sort == EbookSortType::AuthorAlpha){ ?> selected="selected"<? } ?>>Author name (a → z)</option>
|
||||||
<option value="<?= EbookSort::ReadingEase->value ?>"<? if($sort == EbookSort::ReadingEase){ ?> selected="selected"<? } ?>>Reading ease (easy → hard)</option>
|
<option value="<?= EbookSortType::ReadingEase->value ?>"<? if($sort == EbookSortType::ReadingEase){ ?> selected="selected"<? } ?>>Reading ease (easy → hard)</option>
|
||||||
<option value="<?= EbookSort::Length->value ?>"<? if($sort == EbookSort::Length){ ?> selected="selected"<? } ?>>Length (short → long)</option>
|
<option value="<?= EbookSortType::Length->value ?>"<? if($sort == EbookSortType::Length){ ?> selected="selected"<? } ?>>Length (short → long)</option>
|
||||||
</select>
|
</select>
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
|
@ -13,9 +13,9 @@ try{
|
||||||
|
|
||||||
// If the artwork is not approved, and we're not an admin or the submitter when they can edit, don't show it.
|
// If the artwork is not approved, and we're not an admin or the submitter when they can edit, don't show it.
|
||||||
if(
|
if(
|
||||||
($GLOBALS['User'] === null && $artwork->Status != ArtworkStatus::Approved)
|
($GLOBALS['User'] === null && $artwork->Status != ArtworkStatusType::Approved)
|
||||||
||
|
||
|
||||||
($GLOBALS['User'] !== null && $artwork->Status != ArtworkStatus::Approved && $artwork->SubmitterUserId != $GLOBALS['User']->UserId && !$isReviewerView)
|
($GLOBALS['User'] !== null && $artwork->Status != ArtworkStatusType::Approved && $artwork->SubmitterUserId != $GLOBALS['User']->UserId && !$isReviewerView)
|
||||||
){
|
){
|
||||||
throw new Exceptions\InvalidPermissionsException();
|
throw new Exceptions\InvalidPermissionsException();
|
||||||
}
|
}
|
||||||
|
@ -135,12 +135,12 @@ catch(Exceptions\InvalidPermissionsException){
|
||||||
|
|
||||||
<? if($artwork->Exception !== null){ ?>
|
<? if($artwork->Exception !== null){ ?>
|
||||||
<h3>Public domain status exception reason</h3>
|
<h3>Public domain status exception reason</h3>
|
||||||
<?= Formatter::EscapeMarkdown($artwork->Exception) ?>
|
<?= Formatter::MarkdownToHtml($artwork->Exception) ?>
|
||||||
<? } ?>
|
<? } ?>
|
||||||
|
|
||||||
<? if($artwork->Notes !== null){ ?>
|
<? if($artwork->Notes !== null){ ?>
|
||||||
<h2>Special notes</h2>
|
<h2>Special notes</h2>
|
||||||
<?= Formatter::EscapeMarkdown($artwork->Notes) ?>
|
<?= Formatter::MarkdownToHtml($artwork->Notes) ?>
|
||||||
<? } ?>
|
<? } ?>
|
||||||
|
|
||||||
<? if($artwork->CanBeEditedBy($GLOBALS['User'] ?? null)){ ?>
|
<? if($artwork->CanBeEditedBy($GLOBALS['User'] ?? null)){ ?>
|
||||||
|
@ -161,9 +161,9 @@ catch(Exceptions\InvalidPermissionsException){
|
||||||
<span>Artwork approval status</span>
|
<span>Artwork approval status</span>
|
||||||
<span>
|
<span>
|
||||||
<select name="artwork-status">
|
<select name="artwork-status">
|
||||||
<option value="<?= ArtworkStatus::Unverified->value ?>"<? if($artwork->Status == ArtworkStatus::Unverified){ ?> selected="selected"<? } ?>>Unverified</option>
|
<option value="<?= ArtworkStatusType::Unverified->value ?>"<? if($artwork->Status == ArtworkStatusType::Unverified){ ?> selected="selected"<? } ?>>Unverified</option>
|
||||||
<option value="<?= ArtworkStatus::Declined->value ?>"<? if($artwork->Status == ArtworkStatus::Declined){ ?> selected="selected"<? } ?>>Declined</option>
|
<option value="<?= ArtworkStatusType::Declined->value ?>"<? if($artwork->Status == ArtworkStatusType::Declined){ ?> selected="selected"<? } ?>>Declined</option>
|
||||||
<option value="<?= ArtworkStatus::Approved->value ?>"<? if($artwork->Status == ArtworkStatus::Approved){ ?> selected="selected"<? } ?>>Approved</option>
|
<option value="<?= ArtworkStatusType::Approved->value ?>"<? if($artwork->Status == ArtworkStatusType::Approved){ ?> selected="selected"<? } ?>>Approved</option>
|
||||||
</select>
|
</select>
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
|
@ -5,7 +5,7 @@ $query = HttpInput::Str(GET, 'query');
|
||||||
$queryEbookUrl = HttpInput::Str(GET, 'query-ebook-url');
|
$queryEbookUrl = HttpInput::Str(GET, 'query-ebook-url');
|
||||||
$status = HttpInput::Str(GET, 'status');
|
$status = HttpInput::Str(GET, 'status');
|
||||||
$filterArtworkStatus = $status;
|
$filterArtworkStatus = $status;
|
||||||
$sort = ArtworkSort::tryFrom(HttpInput::Str(GET, 'sort') ?? '');
|
$sort = ArtworkSortType::tryFrom(HttpInput::Str(GET, 'sort') ?? '');
|
||||||
$pages = 0;
|
$pages = 0;
|
||||||
$totalArtworkCount = 0;
|
$totalArtworkCount = 0;
|
||||||
$pageDescription = '';
|
$pageDescription = '';
|
||||||
|
@ -26,7 +26,7 @@ try{
|
||||||
|
|
||||||
// If we're passed string values that are the same as the defaults,
|
// If we're passed string values that are the same as the defaults,
|
||||||
// set them to null so that we can have cleaner query strings in the navigation footer
|
// set them to null so that we can have cleaner query strings in the navigation footer
|
||||||
if($sort == ArtworkSort::CreatedNewest){
|
if($sort == ArtworkSortType::CreatedNewest){
|
||||||
$sort = null;
|
$sort = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,25 +45,25 @@ try{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$isReviewerView && !$isSubmitterView && !in_array($status, array('all', ArtworkStatus::Approved->value, 'in-use'))){
|
if(!$isReviewerView && !$isSubmitterView && !in_array($status, array('all', ArtworkStatusType::Approved->value, 'in-use'))){
|
||||||
$status = ArtworkStatus::Approved->value;
|
$status = ArtworkStatusType::Approved->value;
|
||||||
$filterArtworkStatus = $status;
|
$filterArtworkStatus = $status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if($isReviewerView && !in_array($status, array('all', ArtworkStatus::Unverified->value, ArtworkStatus::Declined->value, ArtworkStatus::Approved->value, 'in-use'))
|
if($isReviewerView && !in_array($status, array('all', ArtworkStatusType::Unverified->value, ArtworkStatusType::Declined->value, ArtworkStatusType::Approved->value, 'in-use'))
|
||||||
&& !in_array($filterArtworkStatus, array('all-admin', ArtworkStatus::Unverified->value, ArtworkStatus::Declined->value, ArtworkStatus::Approved->value, 'in-use'))){
|
&& !in_array($filterArtworkStatus, array('all-admin', ArtworkStatusType::Unverified->value, ArtworkStatusType::Declined->value, ArtworkStatusType::Approved->value, 'in-use'))){
|
||||||
$status = ArtworkStatus::Approved->value;
|
$status = ArtworkStatusType::Approved->value;
|
||||||
$filterArtworkStatus = $status;
|
$filterArtworkStatus = $status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if($isSubmitterView && !in_array($status, array('all', ArtworkStatus::Unverified->value, ArtworkStatus::Approved->value, 'in-use'))
|
if($isSubmitterView && !in_array($status, array('all', ArtworkStatusType::Unverified->value, ArtworkStatusType::Approved->value, 'in-use'))
|
||||||
&& !in_array($filterArtworkStatus, array('all-submitter', 'unverified-submitter', ArtworkStatus::Approved->value, 'in-use'))){
|
&& !in_array($filterArtworkStatus, array('all-submitter', 'unverified-submitter', ArtworkStatusType::Approved->value, 'in-use'))){
|
||||||
$status = ArtworkStatus::Approved->value;
|
$status = ArtworkStatusType::Approved->value;
|
||||||
$filterArtworkStatus = $status;
|
$filterArtworkStatus = $status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if($queryEbookUrl !== null){
|
if($queryEbookUrl !== null){
|
||||||
$artworks = Db::Query('SELECT * from Artworks where EbookUrl = ? and Status = ? limit 1', [$queryEbookUrl, ArtworkStatus::Approved], Artwork::class);
|
$artworks = Db::Query('SELECT * from Artworks where EbookUrl = ? and Status = ? limit 1', [$queryEbookUrl, ArtworkStatusType::Approved], Artwork::class);
|
||||||
$totalArtworkCount = sizeof($artworks);
|
$totalArtworkCount = sizeof($artworks);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
@ -141,9 +141,9 @@ catch(Exceptions\PageOutOfBoundsException){
|
||||||
<span>
|
<span>
|
||||||
<select name="status" size="1">
|
<select name="status" size="1">
|
||||||
<option value="all"<? if($status === null){ ?> selected="selected"<? } ?>>All</option>
|
<option value="all"<? if($status === null){ ?> selected="selected"<? } ?>>All</option>
|
||||||
<? if($isReviewerView || $isSubmitterView){ ?><option value="<?= ArtworkStatus::Unverified->value ?>"<? if($status == ArtworkStatus::Unverified->value){ ?> selected="selected"<? } ?>>Unverified</option><? } ?>
|
<? if($isReviewerView || $isSubmitterView){ ?><option value="<?= ArtworkStatusType::Unverified->value ?>"<? if($status == ArtworkStatusType::Unverified->value){ ?> selected="selected"<? } ?>>Unverified</option><? } ?>
|
||||||
<? if($isReviewerView){ ?><option value="<?= ArtworkStatus::Declined->value ?>"<? if($status == ArtworkStatus::Declined->value){ ?> selected="selected"<? } ?>>Declined</option><? } ?>
|
<? if($isReviewerView){ ?><option value="<?= ArtworkStatusType::Declined->value ?>"<? if($status == ArtworkStatusType::Declined->value){ ?> selected="selected"<? } ?>>Declined</option><? } ?>
|
||||||
<option value="<?= ArtworkStatus::Approved->value ?>"<? if($status == ArtworkStatus::Approved->value){ ?> selected="selected"<? } ?>>Approved, not in use</option>
|
<option value="<?= ArtworkStatusType::Approved->value ?>"<? if($status == ArtworkStatusType::Approved->value){ ?> selected="selected"<? } ?>>Approved, not in use</option>
|
||||||
<option value="in-use"<? if($status == 'in-use'){ ?> selected="selected"<? } ?>>In use</option>
|
<option value="in-use"<? if($status == 'in-use'){ ?> selected="selected"<? } ?>>In use</option>
|
||||||
</select>
|
</select>
|
||||||
</span>
|
</span>
|
||||||
|
@ -155,9 +155,9 @@ catch(Exceptions\PageOutOfBoundsException){
|
||||||
<span>Sort</span>
|
<span>Sort</span>
|
||||||
<span>
|
<span>
|
||||||
<select name="sort">
|
<select name="sort">
|
||||||
<option value="<?= ArtworkSort::CreatedNewest->value ?>"<? if($sort == ArtworkSort::CreatedNewest){ ?> selected="selected"<? } ?>>Date added (new → old)</option>
|
<option value="<?= ArtworkSortType::CreatedNewest->value ?>"<? if($sort == ArtworkSortType::CreatedNewest){ ?> selected="selected"<? } ?>>Date added (new → old)</option>
|
||||||
<option value="<?= ArtworkSort::ArtistAlpha->value ?>"<? if($sort == ArtworkSort::ArtistAlpha){ ?> selected="selected"<? } ?>>Artist name (a → z)</option>
|
<option value="<?= ArtworkSortType::ArtistAlpha->value ?>"<? if($sort == ArtworkSortType::ArtistAlpha){ ?> selected="selected"<? } ?>>Artist name (a → z)</option>
|
||||||
<option value="<?= ArtworkSort::CompletedNewest->value ?>"<? if($sort == ArtworkSort::CompletedNewest){ ?> selected="selected"<? } ?>>Date of artwork completion (new → old)</option>
|
<option value="<?= ArtworkSortType::CompletedNewest->value ?>"<? if($sort == ArtworkSortType::CompletedNewest){ ?> selected="selected"<? } ?>>Date of artwork completion (new → old)</option>
|
||||||
</select>
|
</select>
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
|
@ -35,7 +35,7 @@ try{
|
||||||
$artwork->Artist = new Artist();
|
$artwork->Artist = new Artist();
|
||||||
|
|
||||||
if($GLOBALS['User']->Benefits->CanReviewOwnArtwork){
|
if($GLOBALS['User']->Benefits->CanReviewOwnArtwork){
|
||||||
$artwork->Status = ArtworkStatus::Approved;
|
$artwork->Status = ArtworkStatusType::Approved;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,12 +23,12 @@ try{
|
||||||
|
|
||||||
// Only approved reviewers can set the status to anything but unverified when uploading.
|
// Only approved reviewers can set the status to anything but unverified when uploading.
|
||||||
// The submitter cannot review their own submissions unless they have special permission.
|
// The submitter cannot review their own submissions unless they have special permission.
|
||||||
if($artwork->Status !== ArtworkStatus::Unverified && !$artwork->CanStatusBeChangedBy($GLOBALS['User'])){
|
if($artwork->Status !== ArtworkStatusType::Unverified && !$artwork->CanStatusBeChangedBy($GLOBALS['User'])){
|
||||||
throw new Exceptions\InvalidPermissionsException();
|
throw new Exceptions\InvalidPermissionsException();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the artwork is approved, set the reviewer
|
// If the artwork is approved, set the reviewer
|
||||||
if($artwork->Status !== ArtworkStatus::Unverified){
|
if($artwork->Status !== ArtworkStatusType::Unverified){
|
||||||
$artwork->ReviewerUserId = $GLOBALS['User']->UserId;
|
$artwork->ReviewerUserId = $GLOBALS['User']->UserId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ try{
|
||||||
$artwork->SubmitterUserId = $originalArtwork->SubmitterUserId;
|
$artwork->SubmitterUserId = $originalArtwork->SubmitterUserId;
|
||||||
$artwork->Status = $originalArtwork->Status; // Overwrite any value got from POST because we need permission to change the status
|
$artwork->Status = $originalArtwork->Status; // Overwrite any value got from POST because we need permission to change the status
|
||||||
|
|
||||||
$newStatus = ArtworkStatus::tryFrom(HttpInput::Str(POST, 'artwork-status') ?? '');
|
$newStatus = ArtworkStatusType::tryFrom(HttpInput::Str(POST, 'artwork-status') ?? '');
|
||||||
if($newStatus !== null){
|
if($newStatus !== null){
|
||||||
if($originalArtwork->Status != $newStatus && !$originalArtwork->CanStatusBeChangedBy($GLOBALS['User'])){
|
if($originalArtwork->Status != $newStatus && !$originalArtwork->CanStatusBeChangedBy($GLOBALS['User'])){
|
||||||
throw new Exceptions\InvalidPermissionsException();
|
throw new Exceptions\InvalidPermissionsException();
|
||||||
|
@ -108,7 +108,7 @@ try{
|
||||||
|
|
||||||
// We can PATCH the status, the ebook www filesystem path, or both.
|
// We can PATCH the status, the ebook www filesystem path, or both.
|
||||||
if(isset($_POST['artwork-status'])){
|
if(isset($_POST['artwork-status'])){
|
||||||
$newStatus = ArtworkStatus::tryFrom(HttpInput::Str(POST, 'artwork-status') ?? '');
|
$newStatus = ArtworkStatusType::tryFrom(HttpInput::Str(POST, 'artwork-status') ?? '');
|
||||||
if($newStatus !== null){
|
if($newStatus !== null){
|
||||||
if($artwork->Status != $newStatus && !$artwork->CanStatusBeChangedBy($GLOBALS['User'])){
|
if($artwork->Status != $newStatus && !$artwork->CanStatusBeChangedBy($GLOBALS['User'])){
|
||||||
throw new Exceptions\InvalidPermissionsException();
|
throw new Exceptions\InvalidPermissionsException();
|
||||||
|
|
|
@ -11,7 +11,7 @@ $downloadUrl = null;
|
||||||
|
|
||||||
try{
|
try{
|
||||||
$urlPath = HttpInput::Str(GET, 'url-path') ?? null;
|
$urlPath = HttpInput::Str(GET, 'url-path') ?? null;
|
||||||
$format = EbookFormat::tryFrom(HttpInput::Str(GET, 'format') ?? '') ?? EbookFormat::Epub;
|
$format = EbookFormatType::tryFrom(HttpInput::Str(GET, 'format') ?? '') ?? EbookFormatType::Epub;
|
||||||
$wwwFilesystemPath = EBOOKS_DIST_PATH . $urlPath;
|
$wwwFilesystemPath = EBOOKS_DIST_PATH . $urlPath;
|
||||||
|
|
||||||
// Do we have the ebook cached?
|
// Do we have the ebook cached?
|
||||||
|
@ -24,19 +24,19 @@ try{
|
||||||
}
|
}
|
||||||
|
|
||||||
switch($format){
|
switch($format){
|
||||||
case EbookFormat::Kepub:
|
case EbookFormatType::Kepub:
|
||||||
$downloadUrl = $ebook->KepubUrl;
|
$downloadUrl = $ebook->KepubUrl;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EbookFormat::Azw3:
|
case EbookFormatType::Azw3:
|
||||||
$downloadUrl = $ebook->Azw3Url;
|
$downloadUrl = $ebook->Azw3Url;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EbookFormat::AdvancedEpub:
|
case EbookFormatType::AdvancedEpub:
|
||||||
$downloadUrl = $ebook->AdvancedEpubUrl;
|
$downloadUrl = $ebook->AdvancedEpubUrl;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EbookFormat::Epub:
|
case EbookFormatType::Epub:
|
||||||
default:
|
default:
|
||||||
$downloadUrl = $ebook->EpubUrl;
|
$downloadUrl = $ebook->EpubUrl;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -230,7 +230,7 @@ catch(Exceptions\EbookNotFoundException){
|
||||||
<meta property="schema:description" content="epub"/>
|
<meta property="schema:description" content="epub"/>
|
||||||
<meta property="schema:encodingFormat" content="application/epub+zip"/>
|
<meta property="schema:encodingFormat" content="application/epub+zip"/>
|
||||||
<p>
|
<p>
|
||||||
<span><a property="schema:contentUrl" rel="nofollow" href="<?= $ebook->Url ?>/download?format=<?= EbookFormat::Epub->value ?>" class="epub">Compatible epub</a></span> <span>—</span> <span>All devices and apps except Kindles and Kobos.</span>
|
<span><a property="schema:contentUrl" rel="nofollow" href="<?= $ebook->Url ?>/download?format=<?= EbookFormatType::Epub->value ?>" class="epub">Compatible epub</a></span> <span>—</span> <span>All devices and apps except Kindles and Kobos.</span>
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
<? } ?>
|
<? } ?>
|
||||||
|
@ -239,7 +239,7 @@ catch(Exceptions\EbookNotFoundException){
|
||||||
<li property="schema:encoding" typeof="schema:MediaObject">
|
<li property="schema:encoding" typeof="schema:MediaObject">
|
||||||
<meta property="schema:encodingFormat" content="application/x-mobipocket-ebook"/>
|
<meta property="schema:encodingFormat" content="application/x-mobipocket-ebook"/>
|
||||||
<p>
|
<p>
|
||||||
<span><a property="schema:contentUrl" rel="nofollow" href="<?= $ebook->Url ?>/download?format=<?= EbookFormat::Azw3->value ?>" class="amazon"><span property="schema:description">azw3</span></a></span> <span>—</span> <span>Kindle devices and apps.<? if($ebook->KindleCoverUrl !== null){ ?> Also download the <a href="<?= $ebook->KindleCoverUrl ?>">Kindle cover thumbnail</a> to see the cover in your Kindle’s library. Despite what you’ve been told, <a href="/help/how-to-use-our-ebooks#kindle-epub">Kindle does not natively support epub.</a> You may also be interested in our <a href="/help/how-to-use-our-ebooks#kindle-faq">Kindle FAQ</a>.<? }else{ ?> Also see our <a href="/how-to-use-our-ebooks#kindle-faq">Kindle FAQ</a>.<? } ?></span>
|
<span><a property="schema:contentUrl" rel="nofollow" href="<?= $ebook->Url ?>/download?format=<?= EbookFormatType::Azw3->value ?>" class="amazon"><span property="schema:description">azw3</span></a></span> <span>—</span> <span>Kindle devices and apps.<? if($ebook->KindleCoverUrl !== null){ ?> Also download the <a href="<?= $ebook->KindleCoverUrl ?>">Kindle cover thumbnail</a> to see the cover in your Kindle’s library. Despite what you’ve been told, <a href="/help/how-to-use-our-ebooks#kindle-epub">Kindle does not natively support epub.</a> You may also be interested in our <a href="/help/how-to-use-our-ebooks#kindle-faq">Kindle FAQ</a>.<? }else{ ?> Also see our <a href="/how-to-use-our-ebooks#kindle-faq">Kindle FAQ</a>.<? } ?></span>
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
<? } ?>
|
<? } ?>
|
||||||
|
@ -248,7 +248,7 @@ catch(Exceptions\EbookNotFoundException){
|
||||||
<li property="schema:encoding" typeof="schema:MediaObject">
|
<li property="schema:encoding" typeof="schema:MediaObject">
|
||||||
<meta property="schema:encodingFormat" content="application/kepub+zip"/>
|
<meta property="schema:encodingFormat" content="application/kepub+zip"/>
|
||||||
<p>
|
<p>
|
||||||
<span><a property="schema:contentUrl" rel="nofollow" href="<?= $ebook->Url ?>/download?format=<?= EbookFormat::Kepub->value ?>" class="kobo"><span property="schema:description">kepub</span></a></span> <span>—</span> <span>Kobo devices and apps. You may also be interested in our <a href="/help/how-to-use-our-ebooks#kobo-faq">Kobo FAQ</a>.</span>
|
<span><a property="schema:contentUrl" rel="nofollow" href="<?= $ebook->Url ?>/download?format=<?= EbookFormatType::Kepub->value ?>" class="kobo"><span property="schema:description">kepub</span></a></span> <span>—</span> <span>Kobo devices and apps. You may also be interested in our <a href="/help/how-to-use-our-ebooks#kobo-faq">Kobo FAQ</a>.</span>
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
<? } ?>
|
<? } ?>
|
||||||
|
@ -257,7 +257,7 @@ catch(Exceptions\EbookNotFoundException){
|
||||||
<li property="schema:encoding" typeof="schema:MediaObject">
|
<li property="schema:encoding" typeof="schema:MediaObject">
|
||||||
<meta property="schema:encodingFormat" content="application/epub+zip"/>
|
<meta property="schema:encodingFormat" content="application/epub+zip"/>
|
||||||
<p>
|
<p>
|
||||||
<span><a property="schema:contentUrl" rel="nofollow" href="<?= $ebook->Url ?>/download?format=<?= EbookFormat::AdvancedEpub->value ?>" class="epub"><span property="schema:description">Advanced epub</span></a></span> <span>—</span> <span>An advanced format that uses the latest technology not yet fully supported by most ereaders.</span>
|
<span><a property="schema:contentUrl" rel="nofollow" href="<?= $ebook->Url ?>/download?format=<?= EbookFormatType::AdvancedEpub->value ?>" class="epub"><span property="schema:description">Advanced epub</span></a></span> <span>—</span> <span>An advanced format that uses the latest technology not yet fully supported by most ereaders.</span>
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
<? } ?>
|
<? } ?>
|
||||||
|
|
|
@ -7,7 +7,7 @@ $perPage = HttpInput::Int(GET, 'per-page') ?? EBOOKS_PER_PAGE;
|
||||||
$query = HttpInput::Str(GET, 'query') ?? '';
|
$query = HttpInput::Str(GET, 'query') ?? '';
|
||||||
$tags = HttpInput::Array(GET, 'tags') ?? [];
|
$tags = HttpInput::Array(GET, 'tags') ?? [];
|
||||||
$view = ViewType::tryFrom(HttpInput::Str(GET, 'view') ?? '');
|
$view = ViewType::tryFrom(HttpInput::Str(GET, 'view') ?? '');
|
||||||
$sort = EbookSort::tryFrom(HttpInput::Str(GET, 'sort') ?? '');
|
$sort = EbookSortType::tryFrom(HttpInput::Str(GET, 'sort') ?? '');
|
||||||
$queryString = '';
|
$queryString = '';
|
||||||
$queryStringParams = [];
|
$queryStringParams = [];
|
||||||
$queryStringWithoutPage = '';
|
$queryStringWithoutPage = '';
|
||||||
|
@ -27,7 +27,7 @@ try{
|
||||||
$view = null;
|
$view = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if($sort == EbookSort::Newest){
|
if($sort == EbookSortType::Newest){
|
||||||
$sort = null;
|
$sort = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ try{
|
||||||
values (utc_timestamp(),
|
values (utc_timestamp(),
|
||||||
?,
|
?,
|
||||||
?)
|
?)
|
||||||
', [PaymentProcessor::FracturedAtlas, $transactionId]);
|
', [PaymentProcessorType::FracturedAtlas, $transactionId]);
|
||||||
|
|
||||||
$log->Write('Donation ID: ' . $transactionId);
|
$log->Write('Donation ID: ' . $transactionId);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue