Artwork db code tweaks, also remove 'in use' as a status

This commit is contained in:
Alex Cabal 2024-01-17 16:04:11 -06:00
parent 73bcae0c84
commit 5ef6d3aef8
13 changed files with 249 additions and 174 deletions

View file

@ -138,16 +138,14 @@ Before submitting design contributions, please discuss them with the Standard Eb
### Artwork database ### Artwork database
- Allow submitter or admins to edit unapproved artwork submissions. Approved/in use submissions should not be editable by anyone.
- Tags should be searched as whole words. For example a search for `male` should not return items tagged as `female`. - Tags should be searched as whole words. For example a search for `male` should not return items tagged as `female`.
- Include in-use ebook slug as a search parameter when searching for artwork by keyword. - Include in-use ebook slug as a search parameter when searching for artwork by keyword.
- Remove `in_use` status for an artwork; instead, an artwork with an `EbookWwwFilesystemPath` that is not `null` should be considered to be "in use" regardless of its `Status`.
- Artwork searching/filtering should be done in pure SQL, no after-sql filtering in PHP. - Artwork searching/filtering should be done in pure SQL, no after-sql filtering in PHP.
- Allow listing artwork by artist by visiting `/artworks/<artist-name>`, and link instances of artist name to that URL.
## PHP code style ## PHP code style
- Indent with tabs. - Indent with tabs.

View file

@ -58,9 +58,6 @@ class Artwork extends PropertiesBase{
protected ?string $_ImageUrl = null; protected ?string $_ImageUrl = null;
protected ?string $_ThumbUrl = null; protected ?string $_ThumbUrl = null;
protected ?string $_Thumb2xUrl = null; protected ?string $_Thumb2xUrl = null;
protected ?string $_ImageFsPath = null;
protected ?string $_ThumbFsPath = null;
protected ?string $_Thumb2xFsPath = null;
protected ?string $_Dimensions = null; protected ?string $_Dimensions = null;
protected ?Ebook $_Ebook = null; protected ?Ebook $_Ebook = null;
protected ?Museum $_Museum = null; protected ?Museum $_Museum = null;
@ -252,15 +249,15 @@ class Artwork extends PropertiesBase{
} }
protected function GetImageFsPath(): string{ protected function GetImageFsPath(): string{
return WEB_ROOT . rtrim($this->ImageUrl, '?ts=0123456789'); return WEB_ROOT . preg_replace('/\?[^\?]*$/ius', '', $this->ImageUrl);
} }
protected function GetThumbFsPath(): string{ protected function GetThumbFsPath(): string{
return WEB_ROOT . rtrim($this->ThumbUrl, '?ts=0123456789'); return WEB_ROOT . preg_replace('/\?[^\?]*$/ius', '', $this->ThumbUrl);
} }
protected function GetThumb2xFsPath(): string{ protected function GetThumb2xFsPath(): string{
return WEB_ROOT . rtrim($this->Thumb2xUrl, '?ts=0123456789'); return WEB_ROOT . preg_replace('/\?[^\?]*$/ius', '', $this->Thumb2xUrl);
} }
protected function GetDimensions(): string{ protected function GetDimensions(): string{
@ -289,6 +286,55 @@ class Artwork extends PropertiesBase{
// ******* // *******
// METHODS // METHODS
// ******* // *******
public function CanBeEditedBy(?User $user): bool{
if($user === null){
return false;
}
if($user->Benefits->CanReviewOwnArtwork){
// Admins can edit all artwork.
return true;
}
if(($user->Benefits->CanReviewArtwork || $user->UserId == $this->SubmitterUserId) && ($this->Status == ArtworkStatus::Unverified || $this->Status == ArtworkStatus::Declined)){
// Editors can edit an artwork, and submitters can edit their own artwork, if it's not yet approved.
return true;
}
return false;
}
public function CanStatusBeChangedBy(?User $user): bool{
if($user === null){
return false;
}
if($user->Benefits->CanReviewOwnArtwork){
// Admins can change the status of all artwork.
return true;
}
if($user->Benefits->CanReviewArtwork && $user->UserId != $this->SubmitterUserId && ($this->Status == ArtworkStatus::Unverified || $this->Status == ArtworkStatus::Declined)){
// Editors can change the status of artwork they did not submit themselves, and that is not yet approved.
return true;
}
return false;
}
public function CanEbookWwwFilesysemPathBeChangedBy(?User $user): bool{
if($user === null){
return false;
}
if($user->Benefits->CanReviewArtwork || $user->Benefits->CanReviewOwnArtwork){
// Admins and editors can change the file system path of all artwork.
return true;
}
return false;
}
/** /**
* @param array<mixed> $uploadedFile * @param array<mixed> $uploadedFile
* @throws \Exceptions\ValidationException * @throws \Exceptions\ValidationException
@ -341,15 +387,8 @@ class Artwork extends PropertiesBase{
$error->Add(new Exceptions\InvalidArtworkException('Invalid status.')); $error->Add(new Exceptions\InvalidArtworkException('Invalid status.'));
} }
if($this->Status == ArtworkStatus::InUse && $this->EbookWwwFilesystemPath === null){
$error->Add(new Exceptions\MissingEbookException());
}
if(count($this->Tags) == 0){ if(count($this->Tags) == 0){
// In-use artwork doesn't have user-provided tags. $error->Add(new Exceptions\TagsRequiredException());
if($this->Status != ArtworkStatus::InUse){
$error->Add(new Exceptions\TagsRequiredException());
}
} }
if(count($this->Tags) > ARTWORK_MAX_TAGS){ if(count($this->Tags) > ARTWORK_MAX_TAGS){
@ -686,6 +725,13 @@ class Artwork extends PropertiesBase{
if(!empty($uploadedFile) && $uploadedFile['error'] == UPLOAD_ERR_OK){ if(!empty($uploadedFile) && $uploadedFile['error'] == UPLOAD_ERR_OK){
$this->MimeType = ImageMimeType::FromFile($uploadedFile['tmp_name'] ?? null); $this->MimeType = ImageMimeType::FromFile($uploadedFile['tmp_name'] ?? null);
// Manually set the updated timestamp, because if we only update the image and nothing else, the row's
// updated timestamp won't change automatically.
$this->Updated = new DateTime('now', new DateTimeZone('UTC'));
$this->_ImageUrl = null;
$this->_ThumbUrl = null;
$this->_Thumb2xUrl = null;
} }
$this->Validate($uploadedFile); $this->Validate($uploadedFile);
@ -696,8 +742,15 @@ class Artwork extends PropertiesBase{
} }
$this->Tags = $tags; $this->Tags = $tags;
$newDeathYear = $this->Artist->DeathYear;
$this->Artist = Artist::GetOrCreate($this->Artist); $this->Artist = Artist::GetOrCreate($this->Artist);
// Save the artist death year in case we changed it
if($newDeathYear != $this->Artist->DeathYear){
Db::Query('UPDATE Artists set DeathYear = ? where ArtistId = ?', [$newDeathYear , $this->Artist->ArtistId]);
}
// Save the artwork
Db::Query(' Db::Query('
UPDATE Artworks UPDATE Artworks
set set
@ -706,7 +759,7 @@ class Artwork extends PropertiesBase{
UrlName = ?, UrlName = ?,
CompletedYear = ?, CompletedYear = ?,
CompletedYearIsCirca = ?, CompletedYearIsCirca = ?,
Created = ?, Updated = ?,
Status = ?, Status = ?,
SubmitterUserId = ?, SubmitterUserId = ?,
ReviewerUserId = ?, ReviewerUserId = ?,
@ -723,7 +776,7 @@ class Artwork extends PropertiesBase{
where where
ArtworkId = ? ArtworkId = ?
', [$this->Artist->ArtistId, $this->Name, $this->UrlName, $this->CompletedYear, $this->CompletedYearIsCirca, ', [$this->Artist->ArtistId, $this->Name, $this->UrlName, $this->CompletedYear, $this->CompletedYearIsCirca,
$this->Created, $this->Status, $this->SubmitterUserId, $this->ReviewerUserId, $this->MuseumUrl, $this->PublicationYear, $this->PublicationYearPageUrl, $this->Updated, $this->Status, $this->SubmitterUserId, $this->ReviewerUserId, $this->MuseumUrl, $this->PublicationYear, $this->PublicationYearPageUrl,
$this->CopyrightPageUrl, $this->ArtworkPageUrl, $this->IsPublishedInUs, $this->EbookWwwFilesystemPath, $this->MimeType, $this->Exception, $this->Notes, $this->CopyrightPageUrl, $this->ArtworkPageUrl, $this->IsPublishedInUs, $this->EbookWwwFilesystemPath, $this->MimeType, $this->Exception, $this->Notes,
$this->ArtworkId] $this->ArtworkId]
); );
@ -731,16 +784,16 @@ class Artwork extends PropertiesBase{
Artist::DeleteUnreferencedArtists(); Artist::DeleteUnreferencedArtists();
Db::Query(' Db::Query('
DELETE FROM ArtworkTags DELETE from ArtworkTags
WHERE where
ArtworkId = ? ArtworkId = ?
', [$this->ArtworkId] ', [$this->ArtworkId]
); );
foreach($this->Tags as $tag){ foreach($this->Tags as $tag){
Db::Query(' Db::Query('
INSERT INTO ArtworkTags (ArtworkId, TagId) INSERT into ArtworkTags (ArtworkId, TagId)
VALUES (?, values (?,
?) ?)
', [$this->ArtworkId, $tag->TagId]); ', [$this->ArtworkId, $tag->TagId]);
} }
@ -840,4 +893,29 @@ class Artwork extends PropertiesBase{
return $result[0]; return $result[0];
} }
public static function FromHttpPost(): Artwork{
$artwork = new Artwork();
$artwork->Artist = new Artist();
$artwork->Artist->Name = HttpInput::Str(POST, 'artist-name', false);
$artwork->Artist->DeathYear = HttpInput::Int(POST, 'artist-year-of-death');
$artwork->Name = HttpInput::Str(POST, 'artwork-name', false);
$artwork->CompletedYear = HttpInput::Int(POST, 'artwork-year');
$artwork->CompletedYearIsCirca = HttpInput::Bool(POST, 'artwork-year-is-circa', false) ?? false;
$artwork->Tags = HttpInput::Str(POST, 'artwork-tags', false) ?? [];
$artwork->Status = HttpInput::Str(POST, 'artwork-status', false) ?? ArtworkStatus::Unverified;
$artwork->EbookWwwFilesystemPath = HttpInput::Str(POST, 'artwork-ebook-www-filesystem-path', false);
$artwork->IsPublishedInUs = HttpInput::Bool(POST, 'artwork-is-published-in-us', false);
$artwork->PublicationYear = HttpInput::Int(POST, 'artwork-publication-year');
$artwork->PublicationYearPageUrl = HttpInput::Str(POST, 'artwork-publication-year-page-url', false);
$artwork->CopyrightPageUrl = HttpInput::Str(POST, 'artwork-copyright-page-url', false);
$artwork->ArtworkPageUrl = HttpInput::Str(POST, 'artwork-artwork-page-url', false);
$artwork->MuseumUrl = HttpInput::Str(POST, 'artwork-museum-url', false);
$artwork->Exception = HttpInput::Str(POST, 'artwork-exception', false);
$artwork->Notes = HttpInput::Str(POST, 'artwork-notes', false);
return $artwork;
}
} }

View file

@ -3,5 +3,4 @@ enum ArtworkStatus: string{
case Unverified = 'unverified'; case Unverified = 'unverified';
case Declined = 'declined'; case Declined = 'declined';
case Approved = 'approved'; case Approved = 'approved';
case InUse = 'in_use';
} }

View file

@ -162,12 +162,13 @@ class Library{
* @return array<Artwork> * @return array<Artwork>
*/ */
public static function FilterArtwork(string $query = null, string $status = null, string $sort = null, int $submitterUserId = null): array{ public static function FilterArtwork(string $query = null, string $status = null, string $sort = null, int $submitterUserId = null): array{
// Possible special statuses: // $status is either the string value of an ArtworkStatus enum, or one of these special statuses:
// null: same as "all" // null: same as "all"
// "all": Show all approved and in use artwork // "all": Show all approved and in use artwork
// "all-admin": Show all artwork regardless of status // "all-admin": Show all artwork regardless of status
// "all-submitter": Show all approved and in use artwork, plus unverified artwork from the submitter // "all-submitter": Show all approved and in use artwork, plus unverified artwork from the submitter
// "unverified-submitter": Show unverified artwork from the submitter // "unverified-submitter": Show unverified artwork from the submitter
// "in-use": Show only in-use artwork
$artworks = []; $artworks = [];
@ -175,19 +176,26 @@ class Library{
$artworks = Db::Query(' $artworks = Db::Query('
SELECT * SELECT *
from Artworks from Artworks
where Status in (?, ?)', [ArtworkStatus::Approved->value, ArtworkStatus::InUse->value], 'Artwork'); where Status in (?)', [ArtworkStatus::Approved->value], 'Artwork');
} }
elseif($status == 'all-admin'){ elseif($status == 'all-admin'){
$artworks = Db::Query(' $artworks = Db::Query('
SELECT * SELECT *
from Artworks', [], 'Artwork'); from Artworks', [], 'Artwork');
} }
elseif($status == 'in-use'){
$artworks = Db::Query('
SELECT *
from Artworks
where Status = ? and EbookWwwFilesystemPath is not null
', [ArtworkStatus::Approved->value], 'Artwork');
}
elseif($status == 'all-submitter' && $submitterUserId !== null){ elseif($status == 'all-submitter' && $submitterUserId !== null){
$artworks = Db::Query(' $artworks = Db::Query('
SELECT * SELECT *
from Artworks from Artworks
where Status in (?, ?) where Status = ?
or (Status = ? and SubmitterUserId = ?)', [ArtworkStatus::Approved->value, ArtworkStatus::InUse->value, ArtworkStatus::Unverified->value, $submitterUserId], 'Artwork'); or (Status = ? and SubmitterUserId = ?)', [ArtworkStatus::Approved->value, ArtworkStatus::Unverified->value, $submitterUserId], 'Artwork');
} }
elseif($status == 'unverified-submitter' && $submitterUserId !== null){ elseif($status == 'unverified-submitter' && $submitterUserId !== null){
$artworks = Db::Query(' $artworks = Db::Query('
@ -195,6 +203,12 @@ class Library{
from Artworks from Artworks
where Status = ? and SubmitterUserId = ?', [ArtworkStatus::Unverified->value, $submitterUserId], 'Artwork'); where Status = ? and SubmitterUserId = ?', [ArtworkStatus::Unverified->value, $submitterUserId], 'Artwork');
} }
elseif($status == ArtworkStatus::Approved->value){
$artworks = Db::Query('
SELECT *
from Artworks
where Status = ? and EbookWwwFilesystemPath is null', [ArtworkStatus::Approved->value], 'Artwork');
}
else{ else{
$artworks = Db::Query(' $artworks = Db::Query('
SELECT * SELECT *

View file

@ -2,7 +2,13 @@
use Safe\DateTime; use Safe\DateTime;
$artwork = $artwork ?? null; $artwork = $artwork ?? null;
$imageRequired = $imageRequired ?? true;
if($artwork === null){
$artwork = new Artwork();
$artwork->Artist = new Artist();
}
$isEditForm = $isEditForm ?? false;
$isAdminView = $isAdminView ?? false; $isAdminView = $isAdminView ?? false;
$now = new DateTime('now', new DateTimeZone('America/Juneau')); // Latest continental US time zone $now = new DateTime('now', new DateTimeZone('America/Juneau')); // Latest continental US time zone
@ -16,7 +22,7 @@ $now = new DateTime('now', new DateTimeZone('America/Juneau')); // Latest contin
<? foreach(Library::GetAllArtists() as $artist){ ?> <? foreach(Library::GetAllArtists() as $artist){ ?>
<option value="<?= Formatter::ToPlainText($artist->Name) ?>"><?= Formatter::ToPlainText($artist->Name) ?>, d. <? if($artist->DeathYear !== null){ ?><?= $artist->DeathYear ?><? }else{ ?>unknown<? } ?></option> <option value="<?= Formatter::ToPlainText($artist->Name) ?>"><?= Formatter::ToPlainText($artist->Name) ?>, d. <? if($artist->DeathYear !== null){ ?><?= $artist->DeathYear ?><? }else{ ?>unknown<? } ?></option>
<? foreach($artist->AlternateSpellings as $alternateSpelling){ ?> <? foreach($artist->AlternateSpellings as $alternateSpelling){ ?>
<option value="<?= Formatter::ToPlainText($alternateSpelling) ?>"><?= Formatter::ToPlainText($alternateSpelling) ?>, d. <? if($artist->DeathYear !== null){ ?><?= $artist->DeathYear ?><? }else{ ?>unknown<? } ?></option> <option value="<?= Formatter::ToPlainText($alternateSpelling) ?>"><?= Formatter::ToPlainText($alternateSpelling) ?>, d. <? if($artist->DeathYear !== null){ ?><?= Formatter::ToPlainText($artist->DeathYear) ?><? }else{ ?>unknown<? } ?></option>
<? } ?> <? } ?>
<? } ?> <? } ?>
</datalist> </datalist>
@ -38,7 +44,7 @@ $now = new DateTime('now', new DateTimeZone('America/Juneau')); // Latest contin
name="artist-year-of-death" name="artist-year-of-death"
inputmode="numeric" inputmode="numeric"
pattern="[0-9]+" pattern="[0-9]+"
value="<?= $artwork->Artist->DeathYear ?>" value="<?= Formatter::ToPlainText($artwork->Artist->DeathYear) ?>"
/> />
</label> </label>
</fieldset> </fieldset>
@ -57,7 +63,7 @@ $now = new DateTime('now', new DateTimeZone('America/Juneau')); // Latest contin
name="artwork-year" name="artwork-year"
inputmode="numeric" inputmode="numeric"
pattern="[0-9]+" pattern="[0-9]+"
value="<?= $artwork->CompletedYear ?>" value="<?= Formatter::ToPlainText($artwork->CompletedYear) ?>"
/> />
</label> </label>
<label> <label>
@ -81,11 +87,11 @@ $now = new DateTime('now', new DateTimeZone('America/Juneau')); // Latest contin
</label> </label>
<label> <label>
<span>High-resolution image</span> <span>High-resolution image</span>
<span>jpg, bmp, png, and tiff are accepted; <?= number_format(ARTWORK_IMAGE_MINIMUM_WIDTH) ?> × <?= number_format(ARTWORK_IMAGE_MINIMUM_HEIGHT) ?> minimum; 32MB max.</span> <span>jpg, bmp, png, and tiff are accepted; <?= number_format(ARTWORK_IMAGE_MINIMUM_WIDTH) ?> × <?= number_format(ARTWORK_IMAGE_MINIMUM_HEIGHT) ?> minimum; 32MB max.<? if($isEditForm){ ?> Leave this blank to not change the image.<? } ?></span>
<input <input
type="file" type="file"
name="artwork-image" name="artwork-image"
<? if($imageRequired){ ?>required="required"<? } ?> <? if(!$isEditForm){ ?>required="required"<? } ?>
accept="<?= implode(',', ImageMimeType::Values()) ?>" accept="<?= implode(',', ImageMimeType::Values()) ?>"
/> />
</label> </label>
@ -123,7 +129,7 @@ $now = new DateTime('now', new DateTimeZone('America/Juneau')); // Latest contin
name="artwork-publication-year" name="artwork-publication-year"
inputmode="numeric" inputmode="numeric"
pattern="[0-9]+" pattern="[0-9]+"
value="<?= $artwork->PublicationYear ?>" value="<?= Formatter::ToPlainText($artwork->PublicationYear) ?>"
/> />
</label> </label>
<label> <label>
@ -174,10 +180,10 @@ $now = new DateTime('now', new DateTimeZone('America/Juneau')); // Latest contin
<textarea maxlength="1024" name="artwork-notes"><?= Formatter::ToPlainText($artwork->Notes) ?></textarea> <textarea maxlength="1024" name="artwork-notes"><?= Formatter::ToPlainText($artwork->Notes) ?></textarea>
</label> </label>
</fieldset> </fieldset>
<? if($isAdminView){ ?> <? if($artwork->CanStatusBeChangedBy($GLOBALS['User'] ?? null) || $artwork->CanEbookWwwFilesysemPathBeChangedBy($GLOBALS['User'] ?? null)){ ?>
<fieldset> <fieldset>
<legend>Editor options</legend> <legend>Editor options</legend>
<? if($GLOBALS['User']->Benefits->CanReviewOwnArtwork){ ?> <? if($artwork->CanStatusBeChangedBy($GLOBALS['User'] ?? null)){ ?>
<label class="select"> <label class="select">
<span>Artwork approval status</span> <span>Artwork approval status</span>
<span> <span>
@ -185,16 +191,17 @@ $now = new DateTime('now', new DateTimeZone('America/Juneau')); // Latest contin
<option value="<?= ArtworkStatus::Unverified->value ?>"<? if($artwork->Status == ArtworkStatus::Unverified){ ?> selected="selected"<? } ?>>Unverified</option> <option value="<?= ArtworkStatus::Unverified->value ?>"<? if($artwork->Status == ArtworkStatus::Unverified){ ?> selected="selected"<? } ?>>Unverified</option>
<option value="<?= ArtworkStatus::Declined->value ?>"<? if($artwork->Status == ArtworkStatus::Declined){ ?> selected="selected"<? } ?>>Declined</option> <option value="<?= ArtworkStatus::Declined->value ?>"<? if($artwork->Status == ArtworkStatus::Declined){ ?> selected="selected"<? } ?>>Declined</option>
<option value="<?= ArtworkStatus::Approved->value ?>"<? if($artwork->Status == ArtworkStatus::Approved){ ?> selected="selected"<? } ?>>Approved</option> <option value="<?= ArtworkStatus::Approved->value ?>"<? if($artwork->Status == ArtworkStatus::Approved){ ?> selected="selected"<? } ?>>Approved</option>
<option value="<?= ArtworkStatus::InUse->value ?>"<? if($artwork->Status == ArtworkStatus::InUse){ ?> selected="selected"<? } ?>>In use</option>
</select> </select>
</span> </span>
</label> </label>
<? } ?> <? } ?>
<label> <? if($artwork->CanEbookWwwFilesysemPathBeChangedBy($GLOBALS['User'] ?? null)){ ?>
<span>In use by</span> <label>
<span>Ebook file system slug, like <code>c-s-lewis_poetry</code>. If not in use, leave this blank.</span> <span>In use by</span>
<input type="text" name="artwork-ebook-www-filesystem-path" value="<?= Formatter::ToPlainText($artwork->EbookWwwFilesystemPath) ?>"/> <span>Ebook file system slug, like <code>c-s-lewis_poetry</code>. If not in use, leave this blank.</span>
</label> <input type="text" name="artwork-ebook-www-filesystem-path" value="<?= Formatter::ToPlainText($artwork->EbookWwwFilesystemPath) ?>"/>
</label>
<? } ?>
</fieldset> </fieldset>
<? } ?> <? } ?>
<div class="footer"> <div class="footer">

View file

@ -3,7 +3,7 @@ $artworks = $artworks ?? [];
?> ?>
<ol class="artwork-list"> <ol class="artwork-list">
<? foreach($artworks as $artwork){ ?> <? foreach($artworks as $artwork){ ?>
<li <? if($artwork->Status == ArtworkStatus::InUse){ ?> class="in-use"<? } ?>> <li <? if($artwork->EbookWwwFilesystemPath !== null){ ?> class="in-use"<? } ?>>
<a href="<?= $artwork->Url ?>"> <a href="<?= $artwork->Url ?>">
<picture> <picture>
<source srcset="<?= $artwork->Thumb2xUrl ?> 2x, <?= $artwork->ThumbUrl ?> 1x" type="image/jpg"/> <source srcset="<?= $artwork->Thumb2xUrl ?> 2x, <?= $artwork->ThumbUrl ?> 1x" type="image/jpg"/>

View file

@ -5,5 +5,5 @@ $artwork = $artwork ?? null;
<? if($artwork->Status == ArtworkStatus::Approved){ ?>Approved<? } ?> <? if($artwork->Status == ArtworkStatus::Approved){ ?>Approved<? } ?>
<? if($artwork->Status == ArtworkStatus::Declined){ ?>Declined<? } ?> <? if($artwork->Status == ArtworkStatus::Declined){ ?>Declined<? } ?>
<? if($artwork->Status == ArtworkStatus::Unverified){ ?>Unverified<? } ?> <? if($artwork->Status == ArtworkStatus::Unverified){ ?>Unverified<? } ?>
<? if($artwork->Status == ArtworkStatus::InUse){ ?>In use<? if($artwork->EbookWwwFilesystemPath !== null){ ?> for <? if($artwork->Ebook !== null && $artwork->Ebook->Url !== null){ ?><i><a href="<?= $artwork->Ebook->Url ?>"><?= Formatter::ToPlainText($artwork->Ebook->Title) ?></a></i><? }else{ ?><code><?= Formatter::ToPlainText($artwork->EbookWwwFilesystemPath) ?></code> (Unreleased)<? } ?><? } ?><? } ?> <? if($artwork->EbookWwwFilesystemPath !== null){ ?> — in use<? if($artwork->EbookWwwFilesystemPath !== null){ ?> by <? if($artwork->Ebook !== null && $artwork->Ebook->Url !== null){ ?><i><a href="<?= $artwork->Ebook->Url ?>"><?= Formatter::ToPlainText($artwork->Ebook->Title) ?></a></i><? }else{ ?><code><?= Formatter::ToPlainText($artwork->EbookWwwFilesystemPath) ?></code> (unreleased)<? } ?><? } ?><? } ?>
<? } ?> <? } ?>

View file

@ -4,7 +4,7 @@ use function Safe\session_unset;
session_start(); session_start();
$exception = $_SESSION['exception'] ?? null; $exception = $_SESSION['exception'] ?? null;
/** @var Artwork $artwork */ /** @var ?Artwork $artwork */
$artwork = $_SESSION['artwork'] ?? null; $artwork = $_SESSION['artwork'] ?? null;
try{ try{
@ -13,11 +13,10 @@ try{
} }
if($artwork === null){ if($artwork === null){
$artwork = Artwork::GetByUrl(HttpInput::Str(GET, 'artist-url-name') ?? '', HttpInput::Str(GET, 'artwork-url-name') ?? ''); $artwork = Artwork::GetByUrl(HttpInput::Str(GET, 'artist-url-name', false) ?? '', HttpInput::Str(GET, 'artwork-url-name', false) ?? '');
} }
$isEditingAllowed = ($artwork->Status == ArtworkStatus::Unverified) && ($GLOBALS['User']->Benefits->CanReviewArtwork || ($artwork->SubmitterUserId == $GLOBALS['User']->UserId)); if(!$artwork->CanBeEditedBy($GLOBALS['User'])){
if(!$isEditingAllowed){
throw new Exceptions\InvalidPermissionsException(); throw new Exceptions\InvalidPermissionsException();
} }
@ -36,13 +35,13 @@ catch(Exceptions\LoginRequiredException){
Template::RedirectToLogin(); Template::RedirectToLogin();
} }
catch(Exceptions\InvalidPermissionsException){ catch(Exceptions\InvalidPermissionsException){
Template::Emit403(); // No permissions to submit artwork Template::Emit403(); // No permissions to edit artwork
} }
?> ?>
<?= Template::Header( <?= Template::Header(
[ [
'title' => 'Edit Artwork', 'title' => 'Edit ' . $artwork->Name . ', by ' . $artwork->Artist->Name,
'artwork' => true, 'artwork' => true,
'highlight' => '', 'highlight' => '',
'description' => 'Edit public domain artwork to the database for use as cover art.' 'description' => 'Edit public domain artwork to the database for use as cover art.'
@ -54,23 +53,14 @@ catch(Exceptions\InvalidPermissionsException){
<?= Template::Error(['exception' => $exception]) ?> <?= Template::Error(['exception' => $exception]) ?>
<a href="<?= $artwork->ImageUrl ?>"> <picture>
<picture> <source srcset="<?= $artwork->Thumb2xUrl ?> 2x, <?= $artwork->ThumbUrl ?> 1x" type="image/jpg"/>
<source srcset="<?= $artwork->Thumb2xUrl ?> 2x, <?= $artwork->ThumbUrl ?> 1x" type="image/jpg"/> <img src="<?= $artwork->ThumbUrl ?>" alt="" property="schema:image"/>
<img src="<?= $artwork->ThumbUrl ?>" alt="" property="schema:image"/> </picture>
</picture>
</a>
<form class="create-update-artwork" method="post" action="<?= $artwork->Url ?>" enctype="multipart/form-data"> <form class="create-update-artwork" method="post" action="<?= $artwork->Url ?>" enctype="multipart/form-data">
<input type="hidden" name="_method" value="PUT" /> <input type="hidden" name="_method" value="PUT" />
<?= Template::ArtworkForm(['artwork' => $artwork, 'isEditForm' => true,'isAdminView' => $isAdminView]) ?>
<?= Template::ArtworkCreateEditFields(
[
'artwork' => $artwork,
'imageRequired' => false,
'isAdminView' => $isAdminView
]
) ?>
</form> </form>
</section> </section>
</main> </main>

View file

@ -9,12 +9,14 @@ $exception = $_SESSION['exception'] ?? null;
try{ try{
$artwork = Artwork::GetByUrl(HttpInput::Str(GET, 'artist-url-name') ?? '', HttpInput::Str(GET, 'artwork-url-name') ?? ''); $artwork = Artwork::GetByUrl(HttpInput::Str(GET, 'artist-url-name') ?? '', HttpInput::Str(GET, 'artwork-url-name') ?? '');
$isAdminView = $GLOBALS['User']->Benefits->CanReviewArtwork ?? false; $isAdminView = $GLOBALS['User']->Benefits->CanReviewArtwork ?? false;
$userId = $GLOBALS['User']->UserId ?? null;
$isEditingAllowed = ($artwork->Status == ArtworkStatus::Unverified) && ($isAdminView || ($userId !== null && $userId == $artwork->SubmitterUserId));
// 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($artwork->Status != ArtworkStatus::Approved && $artwork->Status != ArtworkStatus::InUse && !$isAdminView && !$isEditingAllowed){ if(
throw new Exceptions\ArtworkNotFoundException(); ($GLOBALS['User'] === null && $artwork->Status != ArtworkStatus::Approved)
||
($GLOBALS['User'] !== null && $artwork->SubmitterUserId != $GLOBALS['User']->UserId && !$isAdminView)
){
throw new Exceptions\InvalidPermissionsException();
} }
// We got here because an artwork was successfully submitted // We got here because an artwork was successfully submitted
@ -22,16 +24,26 @@ try{
session_unset(); session_unset();
} }
// We got here because an artwork submission had errors and the user has to try again // We got here because an artwork PATCH operation had errors and the user has to try again
if($exception){ if($exception){
http_response_code(422); http_response_code(422);
// Before we overwrite the original artwork with our new one, restore the old status,
// because if the new status is 'approved' then it will hide the status form entirely,
// which will be confusing.
$oldStatus = $artwork->Status;
$artwork = $_SESSION['artwork'] ?? $artwork; $artwork = $_SESSION['artwork'] ?? $artwork;
$artwork->Status = $oldStatus;
session_unset(); session_unset();
} }
} }
catch(Exceptions\ArtworkNotFoundException){ catch(Exceptions\ArtworkNotFoundException){
Template::Emit404(); Template::Emit404();
} }
catch(Exceptions\InvalidPermissionsException){
Template::Emit403();
}
?><?= Template::Header(['title' => $artwork->Name, 'artwork' => true]) ?> ?><?= Template::Header(['title' => $artwork->Name, 'artwork' => true]) ?>
<main class="artworks"> <main class="artworks">
@ -130,17 +142,22 @@ catch(Exceptions\ArtworkNotFoundException){
<?= Formatter::EscapeMarkdown($artwork->Notes) ?> <?= Formatter::EscapeMarkdown($artwork->Notes) ?>
<? } ?> <? } ?>
<? if($isEditingAllowed){ ?> <? if($artwork->CanBeEditedBy($GLOBALS['User'] ?? null)){ ?>
<h2>Edit artwork</h2> <h2>Edit artwork</h2>
<p>Before approval, the editor and submitter may <a href="<?= $artwork->EditUrl ?>">edit <i><?= Formatter::ToPlainText($artwork->Name) ?></i></a>.</p> <p>Before approval, the editor and submitter may <a href="<?= $artwork->EditUrl ?>">edit <i><?= Formatter::ToPlainText($artwork->Name) ?></i></a>.</p>
<? } ?> <? } ?>
<? if($isAdminView){ ?> <? if($artwork->CanStatusBeChangedBy($GLOBALS['User'] ?? null) || $artwork->CanEbookWwwFilesysemPathBeChangedBy($GLOBALS['User'] ?? null)){ ?>
<h2>Editor options</h2> <h2>Editor options</h2>
<p>Review the metadata and PD proof for this artwork submission. Approve to make it available for future producers.</p> <? if($artwork->CanStatusBeChangedBy($GLOBALS['User'] ?? null)){ ?>
<p>Review the metadata and PD proof for this artwork submission. Approve to make it available for future producers. Once an artwork is approved, it can no longer be edited.</p>
<? } ?>
<? if($artwork->CanEbookWwwFilesysemPathBeChangedBy($GLOBALS['User'] ?? null)){ ?>
<p>Set a file system slug to mark this artwork as “in use.</p>
<? } ?>
<form method="post" action="<?= $artwork->Url ?>"> <form method="post" action="<?= $artwork->Url ?>">
<input type="hidden" name="_method" value="PATCH" /> <input type="hidden" name="_method" value="PATCH" />
<? if(($artwork->SubmitterUserId != $GLOBALS['User']->UserId) || $GLOBALS['User']->Benefits->CanReviewOwnArtwork){ ?> <? if($artwork->CanStatusBeChangedBy($GLOBALS['User'] ?? null)){ ?>
<label class="select"> <label class="select">
<span>Artwork approval status</span> <span>Artwork approval status</span>
<span> <span>
@ -148,16 +165,21 @@ catch(Exceptions\ArtworkNotFoundException){
<option value="<?= ArtworkStatus::Unverified->value ?>"<? if($artwork->Status == ArtworkStatus::Unverified){ ?> selected="selected"<? } ?>>Unverified</option> <option value="<?= ArtworkStatus::Unverified->value ?>"<? if($artwork->Status == ArtworkStatus::Unverified){ ?> selected="selected"<? } ?>>Unverified</option>
<option value="<?= ArtworkStatus::Declined->value ?>"<? if($artwork->Status == ArtworkStatus::Declined){ ?> selected="selected"<? } ?>>Declined</option> <option value="<?= ArtworkStatus::Declined->value ?>"<? if($artwork->Status == ArtworkStatus::Declined){ ?> selected="selected"<? } ?>>Declined</option>
<option value="<?= ArtworkStatus::Approved->value ?>"<? if($artwork->Status == ArtworkStatus::Approved){ ?> selected="selected"<? } ?>>Approved</option> <option value="<?= ArtworkStatus::Approved->value ?>"<? if($artwork->Status == ArtworkStatus::Approved){ ?> selected="selected"<? } ?>>Approved</option>
<option value="<?= ArtworkStatus::InUse->value ?>"<? if($artwork->Status == ArtworkStatus::InUse){ ?> selected="selected"<? } ?>>In use</option>
</select> </select>
</span> </span>
</label> </label>
<? }else{ ?>
<input type="hidden" name="artwork-status" value="<?= Formatter::ToPlainText($artwork->Status->value ?? '') ?>" />
<? } ?>
<? if($artwork->CanEbookWwwFilesysemPathBeChangedBy($GLOBALS['User'] ?? null)){ ?>
<label>
<span>In use by</span>
<span>Ebook file system slug, like <code>c-s-lewis_poetry</code>. If not in use, leave this blank.</span>
<input type="text" name="artwork-ebook-www-filesystem-path" value="<?= Formatter::ToPlainText($artwork->EbookWwwFilesystemPath) ?>"/>
</label>
<? }else{ ?>
<input type="hidden" name="artwork-ebook-www-filesystem-path" value="<?= Formatter::ToPlainText($artwork->EbookWwwFilesystemPath) ?>" />
<? } ?> <? } ?>
<label>
<span>In use by</span>
<span>Ebook file system slug, like <code>c-s-lewis_poetry</code>. If not in use, leave this blank.</span>
<input type="text" name="artwork-ebook-www-filesystem-path" value="<?= Formatter::ToPlainText($artwork->EbookWwwFilesystemPath) ?>"/>
</label>
<div class="footer"> <div class="footer">
<button>Save changes</button> <button>Save changes</button>
</div> </div>

View file

@ -49,19 +49,19 @@ if($isSubmitterView){
} }
} }
if(!$isAdminView && !$isSubmitterView && !in_array($status, array('all', ArtworkStatus::Approved->value, ArtworkStatus::InUse->value))){ if(!$isAdminView && !$isSubmitterView && !in_array($status, array('all', ArtworkStatus::Approved->value, 'in-use'))){
$status = ArtworkStatus::Approved->value; $status = ArtworkStatus::Approved->value;
$filterArtworkStatus = $status; $filterArtworkStatus = $status;
} }
if($isAdminView && !in_array($status, array('all', ArtworkStatus::Unverified->value, ArtworkStatus::Declined->value, ArtworkStatus::Approved->value, ArtworkStatus::InUse->value)) if($isAdminView && !in_array($status, array('all', ArtworkStatus::Unverified->value, ArtworkStatus::Declined->value, ArtworkStatus::Approved->value, 'in-use'))
&& !in_array($filterArtworkStatus, array('all-admin', ArtworkStatus::Unverified->value, ArtworkStatus::Declined->value, ArtworkStatus::Approved->value, ArtworkStatus::InUse->value))){ && !in_array($filterArtworkStatus, array('all-admin', ArtworkStatus::Unverified->value, ArtworkStatus::Declined->value, ArtworkStatus::Approved->value, 'in-use'))){
$status = ArtworkStatus::Approved->value; $status = ArtworkStatus::Approved->value;
$filterArtworkStatus = $status; $filterArtworkStatus = $status;
} }
if($isSubmitterView && !in_array($status, array('all', ArtworkStatus::Unverified->value, ArtworkStatus::Approved->value, ArtworkStatus::InUse->value)) if($isSubmitterView && !in_array($status, array('all', ArtworkStatus::Unverified->value, ArtworkStatus::Approved->value, 'in-use'))
&& !in_array($filterArtworkStatus, array('all-submitter', 'unverified-submitter', ArtworkStatus::Approved->value, ArtworkStatus::InUse->value))){ && !in_array($filterArtworkStatus, array('all-submitter', 'unverified-submitter', ArtworkStatus::Approved->value, 'in-use'))){
$status = ArtworkStatus::Approved->value; $status = ArtworkStatus::Approved->value;
$filterArtworkStatus = $status; $filterArtworkStatus = $status;
} }
@ -107,8 +107,8 @@ if($perPage !== ARTWORK_PER_PAGE){
<option value="all"<? if($status === null){ ?> selected="selected"<? } ?>>All</option> <option value="all"<? if($status === null){ ?> selected="selected"<? } ?>>All</option>
<? if($isAdminView || $isSubmitterView){ ?><option value="<?= ArtworkStatus::Unverified->value ?>"<? if($status == ArtworkStatus::Unverified->value){ ?> selected="selected"<? } ?>>Unverified</option><? } ?> <? if($isAdminView || $isSubmitterView){ ?><option value="<?= ArtworkStatus::Unverified->value ?>"<? if($status == ArtworkStatus::Unverified->value){ ?> selected="selected"<? } ?>>Unverified</option><? } ?>
<? if($isAdminView){ ?><option value="<?= ArtworkStatus::Declined->value ?>"<? if($status == ArtworkStatus::Declined->value){ ?> selected="selected"<? } ?>>Declined</option><? } ?> <? if($isAdminView){ ?><option value="<?= ArtworkStatus::Declined->value ?>"<? if($status == ArtworkStatus::Declined->value){ ?> selected="selected"<? } ?>>Declined</option><? } ?>
<option value="<?= ArtworkStatus::Approved->value ?>"<? if($status == ArtworkStatus::Approved->value){ ?> selected="selected"<? } ?>>Approved</option> <option value="<?= ArtworkStatus::Approved->value ?>"<? if($status == ArtworkStatus::Approved->value){ ?> selected="selected"<? } ?>>Approved, not in use</option>
<option value="<?= ArtworkStatus::InUse->value ?>"<? if($status == ArtworkStatus::InUse->value){ ?> selected="selected"<? } ?>>In use</option> <option value="in-use"<? if($status == 'in-use'){ ?> selected="selected"<? } ?>>In use</option>
</select> </select>
</span> </span>
</label> </label>

View file

@ -68,13 +68,7 @@ catch(Exceptions\InvalidPermissionsException){
<? } ?> <? } ?>
<form class="create-update-artwork" method="post" action="/artworks" enctype="multipart/form-data"> <form class="create-update-artwork" method="post" action="/artworks" enctype="multipart/form-data">
<?= Template::ArtworkCreateEditFields( <?= Template::ArtworkForm(['artwork' => $artwork, 'isAdminView' => $isAdminView]) ?>
[
'artwork' => $artwork,
'imageRequired' => true,
'isAdminView' => $isAdminView
]
) ?>
</form> </form>
</section> </section>
</main> </main>

View file

@ -1,39 +1,8 @@
<? <?
function populateArtworkFields(Artwork $artwork): void{
$artwork->Artist = new Artist();
$artwork->Artist->Name = HttpInput::Str(POST, 'artist-name', false);
$artwork->Artist->DeathYear = HttpInput::Int(POST, 'artist-year-of-death');
$artwork->Name = HttpInput::Str(POST, 'artwork-name', false);
$artwork->CompletedYear = HttpInput::Int(POST, 'artwork-year');
$artwork->CompletedYearIsCirca = HttpInput::Bool(POST, 'artwork-year-is-circa', false) ?? false;
$artwork->Tags = HttpInput::Str(POST, 'artwork-tags', false) ?? [];
$artwork->Status = HttpInput::Str(POST, 'artwork-status', false) ?? ArtworkStatus::Unverified;
$artwork->EbookWwwFilesystemPath = HttpInput::Str(POST, 'artwork-ebook-www-filesystem-path', false);
$artwork->IsPublishedInUs = HttpInput::Bool(POST, 'artwork-is-published-in-us', false);
$artwork->PublicationYear = HttpInput::Int(POST, 'artwork-publication-year');
$artwork->PublicationYearPageUrl = HttpInput::Str(POST, 'artwork-publication-year-page-url', false);
$artwork->CopyrightPageUrl = HttpInput::Str(POST, 'artwork-copyright-page-url', false);
$artwork->ArtworkPageUrl = HttpInput::Str(POST, 'artwork-artwork-page-url', false);
$artwork->MuseumUrl = HttpInput::Str(POST, 'artwork-museum-url', false);
$artwork->Exception = HttpInput::Str(POST, 'artwork-exception', false);
$artwork->Notes = HttpInput::Str(POST, 'artwork-notes', false);
// 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
if($artwork->Status !== ArtworkStatus::Unverified && !$GLOBALS['User']->Benefits->CanReviewOwnArtwork){
throw new Exceptions\InvalidPermissionsException();
}
// If the artwork is approved, set the reviewer
if($artwork->Status !== ArtworkStatus::Unverified){
$artwork->ReviewerUserId = $GLOBALS['User']->UserId;
}
}
try{ try{
session_start(); session_start();
$httpMethod =HttpInput::RequestMethod(); $httpMethod =HttpInput::RequestMethod();
$exceptionRedirectUrl = '/artworks/new';
if($httpMethod != HTTP_POST && $httpMethod != HTTP_PATCH && $httpMethod != HTTP_PUT){ if($httpMethod != HTTP_POST && $httpMethod != HTTP_PATCH && $httpMethod != HTTP_PUT){
throw new Exceptions\InvalidRequestException(); throw new Exceptions\InvalidRequestException();
@ -53,10 +22,20 @@ try{
throw new Exceptions\InvalidPermissionsException(); throw new Exceptions\InvalidPermissionsException();
} }
$artwork = new Artwork(); $artwork = Artwork::FromHttpPost();
populateArtworkFields($artwork);
$artwork->SubmitterUserId = $GLOBALS['User']->UserId ?? null; $artwork->SubmitterUserId = $GLOBALS['User']->UserId ?? null;
// 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.
if($artwork->Status !== ArtworkStatus::Unverified && !$artwork->CanStatusBeChangedBy($GLOBALS['User'])){
throw new Exceptions\InvalidPermissionsException();
}
// If the artwork is approved, set the reviewer
if($artwork->Status !== ArtworkStatus::Unverified){
$artwork->ReviewerUserId = $GLOBALS['User']->UserId;
}
// Confirm that the files came from POST // Confirm that the files came from POST
if(!is_uploaded_file($_FILES['artwork-image']['tmp_name'])){ if(!is_uploaded_file($_FILES['artwork-image']['tmp_name'])){
throw new Exceptions\InvalidImageUploadException(); throw new Exceptions\InvalidImageUploadException();
@ -71,20 +50,31 @@ try{
header('Location: /artworks/new'); header('Location: /artworks/new');
} }
// PUTing a new artwork // PUTing an artwork
if($httpMethod == HTTP_PUT){ if($httpMethod == HTTP_PUT){
$originalArtwork = Artwork::GetByUrl(HttpInput::Str(GET, 'artist-url-name', false), HttpInput::Str(GET, 'artwork-url-name', false)); $originalArtwork = Artwork::GetByUrl(HttpInput::Str(GET, 'artist-url-name', false), HttpInput::Str(GET, 'artwork-url-name', false));
if(!$GLOBALS['User']->Benefits->CanReviewArtwork && !($originalArtwork->SubmitterUserId == $GLOBALS['User']->UserId)){ if(!$originalArtwork->CanBeEditedBy($GLOBALS['User'])){
throw new Exceptions\InvalidPermissionsException(); throw new Exceptions\InvalidPermissionsException();
} }
$artwork = new Artwork(); $exceptionRedirectUrl = $originalArtwork->EditUrl;
populateArtworkFields($artwork);
$artwork = Artwork::FromHttpPost();
$artwork->ArtworkId = $originalArtwork->ArtworkId; $artwork->ArtworkId = $originalArtwork->ArtworkId;
$artwork->Created = $originalArtwork->Created; $artwork->Created = $originalArtwork->Created;
$artwork->SubmitterUserId = $originalArtwork->SubmitterUserId; $artwork->SubmitterUserId = $originalArtwork->SubmitterUserId;
$newStatus = ArtworkStatus::tryFrom(HttpInput::Str(POST, 'artwork-status', false) ?? '');
if($newStatus !== null){
if($originalArtwork->Status != $newStatus && !$originalArtwork->CanStatusBeChangedBy($GLOBALS['User'])){
throw new Exceptions\InvalidPermissionsException();
}
$artwork->ReviewerUserId = $GLOBALS['User']->UserId;
$artwork->Status = $newStatus;
}
$uploadedFile = []; $uploadedFile = [];
$uploadError = $_FILES['artwork-image']['error']; $uploadError = $_FILES['artwork-image']['error'];
@ -107,43 +97,31 @@ try{
// PATCHing a new artwork // PATCHing a new artwork
if($httpMethod == HTTP_PATCH){ if($httpMethod == HTTP_PATCH){
if(!$GLOBALS['User']->Benefits->CanReviewArtwork){
throw new Exceptions\InvalidPermissionsException();
}
$artwork = Artwork::GetByUrl(HttpInput::Str(GET, 'artist-url-name', false), HttpInput::Str(GET, 'artwork-url-name', false)); $artwork = Artwork::GetByUrl(HttpInput::Str(GET, 'artist-url-name', false), HttpInput::Str(GET, 'artwork-url-name', false));
$artwork->Artist->Name = HttpInput::Str(POST, 'artist-name', false) ?? $artwork->Artist->Name; $exceptionRedirectUrl = $artwork->Url;
$artwork->Artist->DeathYear = HttpInput::Int(POST, 'artist-year-of-death') ?? $artwork->Artist->DeathYear;
$artwork->Name = HttpInput::Str(POST, 'artwork-name', false) ?? $artwork->Name; // We can PATCH either the status or the ebook www filesystem path.
$artwork->CompletedYear = HttpInput::Int(POST, 'artwork-year') ?? $artwork->CompletedYear;
$artwork->CompletedYearIsCirca = HttpInput::Bool(POST, 'artwork-year-is-circa', false) ?? $artwork->CompletedYearIsCirca;
$artwork->Tags = HttpInput::Str(POST, 'artwork-tags', false) ?? $artwork->Tags;
$artwork->EbookWwwFilesystemPath = HttpInput::Str(POST, 'artwork-ebook-www-filesystem-path', false) ?? $artwork->EbookWwwFilesystemPath;
$artwork->IsPublishedInUs = HttpInput::Bool(POST, 'artwork-is-published-in-us', false) ?? $artwork->IsPublishedInUs;
$artwork->PublicationYear = HttpInput::Int(POST, 'artwork-publication-year') ?? $artwork->PublicationYear;
$artwork->PublicationYearPageUrl = HttpInput::Str(POST, 'artwork-publication-year-page-url', false) ?? $artwork->PublicationYearPageUrl;
$artwork->CopyrightPageUrl = HttpInput::Str(POST, 'artwork-copyright-page-url', false) ?? $artwork->CopyrightPageUrl;
$artwork->ArtworkPageUrl = HttpInput::Str(POST, 'artwork-artwork-page-url', false) ?? $artwork->ArtworkPageUrl;
$artwork->MuseumUrl = HttpInput::Str(POST, 'artwork-museum-url', false) ?? $artwork->MuseumUrl;
$artwork->Exception = HttpInput::Str(POST, 'artwork-exception', false) ?? $artwork->Exception;
$artwork->Notes = HttpInput::Str(POST, 'artwork-notes', false) ?? $artwork->Notes;
$artwork->ReviewerUserId = $GLOBALS['User']->UserId;
$newStatus = ArtworkStatus::tryFrom(HttpInput::Str(POST, 'artwork-status', false) ?? ''); $newStatus = ArtworkStatus::tryFrom(HttpInput::Str(POST, 'artwork-status', false) ?? '');
if($newStatus !== null){ if($newStatus !== null){
if($artwork->Status != $newStatus){ if($artwork->Status != $newStatus && !$artwork->CanStatusBeChangedBy($GLOBALS['User'])){
// Is the user attempting to review their own artwork? throw new Exceptions\InvalidPermissionsException();
if($artwork->Status != ArtworkStatus::Unverified && $GLOBALS['User']->UserId == $artwork->SubmitterUserId && !$GLOBALS['User']->Benefits->CanReviewOwnArtwork){
throw new Exceptions\InvalidPermissionsException();
}
} }
$artwork->ReviewerUserId = $GLOBALS['User']->UserId;
$artwork->Status = $newStatus; $artwork->Status = $newStatus;
} }
$newEbookWwwFilesystemPath = HttpInput::Str(POST, 'artwork-ebook-www-filesystem-path', false) ?? null;
if($artwork->EbookWwwFilesystemPath != $newEbookWwwFilesystemPath && !$artwork->CanEbookWwwFilesysemPathBeChangedBy($GLOBALS['User'])){
throw new Exceptions\InvalidPermissionsException();
}
$artwork->ReviewerUserId = $GLOBALS['User']->UserId;
$artwork->Status = $newStatus;
$artwork->EbookWwwFilesystemPath = $newEbookWwwFilesystemPath;
$artwork->Save(); $artwork->Save();
$_SESSION['artwork'] = $artwork; $_SESSION['artwork'] = $artwork;
@ -172,15 +150,5 @@ catch(Exceptions\AppException $exception){
$_SESSION['exception'] = $exception; $_SESSION['exception'] = $exception;
http_response_code(303); http_response_code(303);
header('Location: ' . $exceptionRedirectUrl);
if($httpMethod == HTTP_PATCH && $artwork !== null){
header('Location: ' . $artwork->Url);
}
else if($httpMethod == HTTP_PUT && $artwork !== null){
header('Location: ' . $artwork->EditUrl);
}
else{
header('Location: /artworks/new');
}
} }

View file

@ -145,9 +145,13 @@ form.create-update-artwork fieldset p:first-of-type{
} }
form.create-update-artwork legend{ form.create-update-artwork legend{
font-size: 1.2rem; font-size: 1.4rem;
font-weight: bold; font-family: "League Spartan", Arial, sans-serif;
margin: 0.5rem 0; margin-top: 2rem;
margin-bottom: 1rem;
line-height: 1.2;
letter-spacing: 1px;
text-transform: uppercase;
} }
form.create-update-artwork label{ form.create-update-artwork label{
@ -178,7 +182,8 @@ form div.footer{
} }
main h1 ~ a[href^="/images/cover-uploads"], main h1 ~ a[href^="/images/cover-uploads"],
.artworks h1 ~ a[href^="/images/cover-uploads"]{ .artworks h1 ~ a[href^="/images/cover-uploads"],
main section.narrow h1 + picture{
width: auto; width: auto;
line-height: 0; line-height: 0;
} }