mirror of
https://github.com/standardebooks/web.git
synced 2025-07-13 10:02:02 -04:00
Artwork db code tweaks, also remove 'in use' as a status
This commit is contained in:
parent
73bcae0c84
commit
5ef6d3aef8
13 changed files with 249 additions and 174 deletions
|
@ -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.
|
||||||
|
|
118
lib/Artwork.php
118
lib/Artwork.php
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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';
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 *
|
||||||
|
|
|
@ -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">
|
|
@ -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"/>
|
||||||
|
|
|
@ -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)<? } ?><? } ?><? } ?>
|
||||||
<? } ?>
|
<? } ?>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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');
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue