mirror of
https://github.com/standardebooks/web.git
synced 2025-07-06 06:40:33 -04:00
Allow editing of projects
This commit is contained in:
parent
e21f411191
commit
b2191d1219
16 changed files with 191 additions and 75 deletions
|
@ -1 +1,6 @@
|
||||||
RewriteRule ^/ebooks/([^\.]+?)/projects/new$ /projects/new.php?ebook-url-path=$1
|
RewriteRule ^/ebooks/([^\.]+?)/projects/new$ /projects/new.php?ebook-url-path=$1
|
||||||
|
|
||||||
|
RewriteRule ^/projects/([\d]+)/edit$ /projects/edit.php?project-id=$1
|
||||||
|
|
||||||
|
RewriteCond expr "tolower(%{REQUEST_METHOD}) =~ /^post$/"
|
||||||
|
RewriteRule ^/projects/([\d]+)$ /projects/post.php?project-id=$1 [L]
|
||||||
|
|
|
@ -36,6 +36,7 @@ use function Safe\shell_exec;
|
||||||
* @property string $ReadingTime
|
* @property string $ReadingTime
|
||||||
* @property string $AuthorsHtml
|
* @property string $AuthorsHtml
|
||||||
* @property string $AuthorsUrl This is a single URL even if there are multiple authors; for example, `/ebooks/karl-marx_friedrich-engels/`.
|
* @property string $AuthorsUrl This is a single URL even if there are multiple authors; for example, `/ebooks/karl-marx_friedrich-engels/`.
|
||||||
|
* @property string $AuthorsString
|
||||||
* @property string $ContributorsHtml
|
* @property string $ContributorsHtml
|
||||||
* @property string $TitleWithCreditsHtml
|
* @property string $TitleWithCreditsHtml
|
||||||
* @property string $TextUrl
|
* @property string $TextUrl
|
||||||
|
@ -115,6 +116,7 @@ class Ebook{
|
||||||
protected string $_ReadingTime;
|
protected string $_ReadingTime;
|
||||||
protected string $_AuthorsHtml;
|
protected string $_AuthorsHtml;
|
||||||
protected string $_AuthorsUrl;
|
protected string $_AuthorsUrl;
|
||||||
|
protected string $_AuthorsString;
|
||||||
protected string $_ContributorsHtml;
|
protected string $_ContributorsHtml;
|
||||||
protected string $_TitleWithCreditsHtml;
|
protected string $_TitleWithCreditsHtml;
|
||||||
protected string $_TextUrl;
|
protected string $_TextUrl;
|
||||||
|
@ -538,6 +540,14 @@ class Ebook{
|
||||||
return $this->_AuthorsUrl;
|
return $this->_AuthorsUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function GetAuthorsString(): string{
|
||||||
|
if(!isset($this->_AuthorsString)){
|
||||||
|
$this->_AuthorsString = strip_tags(Ebook::GenerateContributorList($this->Authors, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->_AuthorsString;
|
||||||
|
}
|
||||||
|
|
||||||
protected function GetContributorsHtml(): string{
|
protected function GetContributorsHtml(): string{
|
||||||
if(!isset($this->_ContributorsHtml)){
|
if(!isset($this->_ContributorsHtml)){
|
||||||
$this->_ContributorsHtml = '';
|
$this->_ContributorsHtml = '';
|
||||||
|
|
|
@ -16,6 +16,7 @@ use Safe\DateTimeImmutable;
|
||||||
* @property User $Manager
|
* @property User $Manager
|
||||||
* @property User $Reviewer
|
* @property User $Reviewer
|
||||||
* @property string $Url
|
* @property string $Url
|
||||||
|
* @property string $EditUrl
|
||||||
* @property DateTimeImmutable $LastActivityTimestamp The timestamp of the latest activity, whether it's a commit, a discussion post, or simply the started timestamp.
|
* @property DateTimeImmutable $LastActivityTimestamp The timestamp of the latest activity, whether it's a commit, a discussion post, or simply the started timestamp.
|
||||||
* @property array<ProjectReminder> $Reminders
|
* @property array<ProjectReminder> $Reminders
|
||||||
* @property ?string $VcsUrlDomain
|
* @property ?string $VcsUrlDomain
|
||||||
|
@ -46,6 +47,7 @@ class Project{
|
||||||
protected User $_Manager;
|
protected User $_Manager;
|
||||||
protected User $_Reviewer;
|
protected User $_Reviewer;
|
||||||
protected string $_Url;
|
protected string $_Url;
|
||||||
|
protected string $_EditUrl;
|
||||||
protected DateTimeImmutable $_LastActivityTimestamp;
|
protected DateTimeImmutable $_LastActivityTimestamp;
|
||||||
/** @var array<ProjectReminder> $_Reminders */
|
/** @var array<ProjectReminder> $_Reminders */
|
||||||
protected array $_Reminders;
|
protected array $_Reminders;
|
||||||
|
@ -115,6 +117,14 @@ class Project{
|
||||||
return $this->_Url;
|
return $this->_Url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function GetEditUrl(): string{
|
||||||
|
if(!isset($this->_EditUrl)){
|
||||||
|
$this->_EditUrl = $this->Url . '/edit';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->_EditUrl;
|
||||||
|
}
|
||||||
|
|
||||||
protected function GetLastActivityTimestamp(): DateTimeImmutable{
|
protected function GetLastActivityTimestamp(): DateTimeImmutable{
|
||||||
if(!isset($this->_LastActivityTimestamp)){
|
if(!isset($this->_LastActivityTimestamp)){
|
||||||
$dates = [
|
$dates = [
|
||||||
|
|
10
lib/User.php
10
lib/User.php
|
@ -9,6 +9,7 @@ use function Safe\preg_match;
|
||||||
* @property bool $IsRegistered A user is "registered" if they have an entry in the `Benefits` table; a password is required to log in.
|
* @property bool $IsRegistered A user is "registered" if they have an entry in the `Benefits` table; a password is required to log in.
|
||||||
* @property Benefits $Benefits
|
* @property Benefits $Benefits
|
||||||
* @property string $Url
|
* @property string $Url
|
||||||
|
* @property string $EditUrl
|
||||||
* @property ?Patron $Patron
|
* @property ?Patron $Patron
|
||||||
* @property ?NewsletterSubscription $NewsletterSubscription
|
* @property ?NewsletterSubscription $NewsletterSubscription
|
||||||
* @property ?Payment $LastPayment
|
* @property ?Payment $LastPayment
|
||||||
|
@ -32,6 +33,7 @@ class User{
|
||||||
protected ?Payment $_LastPayment;
|
protected ?Payment $_LastPayment;
|
||||||
protected Benefits $_Benefits;
|
protected Benefits $_Benefits;
|
||||||
protected string $_Url;
|
protected string $_Url;
|
||||||
|
protected string $_EditUrl;
|
||||||
protected ?Patron $_Patron;
|
protected ?Patron $_Patron;
|
||||||
protected ?NewsletterSubscription $_NewsletterSubscription;
|
protected ?NewsletterSubscription $_NewsletterSubscription;
|
||||||
protected string $_DisplayName;
|
protected string $_DisplayName;
|
||||||
|
@ -91,6 +93,14 @@ class User{
|
||||||
return $this->_Url;
|
return $this->_Url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function GetEditUrl(): string{
|
||||||
|
if(!isset($this->_EditUrl)){
|
||||||
|
$this->_EditUrl = $this->Url . '/edit';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->_EditUrl;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array<Payment>
|
* @return array<Payment>
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
/**
|
/**
|
||||||
* @var Ebook $ebook
|
* @var Ebook $ebook
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
$showPlaceholderMetadata = $showPlaceholderMetadata ?? false;
|
||||||
?>
|
?>
|
||||||
<section id="metadata">
|
<section id="metadata">
|
||||||
<h2>Metadata</h2>
|
<h2>Metadata</h2>
|
||||||
|
@ -11,7 +13,16 @@
|
||||||
<td>Ebook ID:</td>
|
<td>Ebook ID:</td>
|
||||||
<td><?= $ebook->EbookId ?></td>
|
<td><?= $ebook->EbookId ?></td>
|
||||||
</tr>
|
</tr>
|
||||||
<? if($ebook->IsPlaceholder() && $ebook->EbookPlaceholder !== null){ ?>
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<? if($showPlaceholderMetadata && $ebook->IsPlaceholder() && $ebook->EbookPlaceholder !== null){ ?>
|
||||||
|
<section id="placeholder-metadata">
|
||||||
|
<h2>Placeholder metadata</h2>
|
||||||
|
<p><a href="<?= $ebook->EditUrl ?>">Edit placeholder</a></p>
|
||||||
|
<table class="admin-table">
|
||||||
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Is wanted:</td>
|
<td>Is wanted:</td>
|
||||||
<td><? if($ebook->EbookPlaceholder->IsWanted){ ?>☑<? }else{ ?>☐<? } ?></td>
|
<td><? if($ebook->EbookPlaceholder->IsWanted){ ?>☑<? }else{ ?>☐<? } ?></td>
|
||||||
|
@ -26,7 +37,8 @@
|
||||||
<td>Difficulty:</td>
|
<td>Difficulty:</td>
|
||||||
<td><?= ucfirst($ebook->EbookPlaceholder->Difficulty->value ?? '') ?></td>
|
<td><?= ucfirst($ebook->EbookPlaceholder->Difficulty->value ?? '') ?></td>
|
||||||
</tr>
|
</tr>
|
||||||
<? } ?>
|
</tbody>
|
||||||
</tbody>
|
</table>
|
||||||
</table>
|
</section>
|
||||||
</section>
|
<? } ?>
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<?
|
<?
|
||||||
$ebook = $ebook ?? new Ebook();
|
$ebook = $ebook ?? new Ebook();
|
||||||
|
$isEditForm = $isEditForm ?? false;
|
||||||
?>
|
?>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>Contributors</legend>
|
<legend>Contributors</legend>
|
||||||
|
@ -189,21 +190,23 @@ $ebook = $ebook ?? new Ebook();
|
||||||
</label>
|
</label>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</details>
|
</details>
|
||||||
<fieldset>
|
<? if(!$isEditForm){ ?>
|
||||||
<legend>Project</legend>
|
<fieldset>
|
||||||
<label class="controls-following-fieldset">
|
<legend>Project</legend>
|
||||||
<span>In progress?</span>
|
<label class="controls-following-fieldset">
|
||||||
<input type="hidden" name="ebook-placeholder-is-in-progress" value="false" />
|
<span>In progress?</span>
|
||||||
<input
|
<input type="hidden" name="ebook-placeholder-is-in-progress" value="false" />
|
||||||
type="checkbox"
|
<input
|
||||||
name="ebook-placeholder-is-in-progress"
|
type="checkbox"
|
||||||
<? if($ebook->EbookPlaceholder?->IsInProgress){ ?>checked="checked"<? } ?>
|
name="ebook-placeholder-is-in-progress"
|
||||||
/>
|
<? if($ebook->EbookPlaceholder?->IsInProgress){ ?>checked="checked"<? } ?>
|
||||||
</label>
|
/>
|
||||||
<fieldset class="project-form">
|
</label>
|
||||||
<?= Template::ProjectForm(['project' => $ebook->ProjectInProgress, 'areFieldsRequired' => false]) ?>
|
<fieldset class="project-form">
|
||||||
|
<?= Template::ProjectForm(['project' => $ebook->ProjectInProgress, 'areFieldsRequired' => false]) ?>
|
||||||
|
</fieldset>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</fieldset>
|
<? } ?>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>Wanted list</legend>
|
<legend>Wanted list</legend>
|
||||||
<label class="controls-following-fieldset">
|
<label class="controls-following-fieldset">
|
||||||
|
|
|
@ -4,13 +4,16 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$showAddButton = $showAddButton ?? false;
|
$showAddButton = $showAddButton ?? false;
|
||||||
|
$showEditButton = $showEditButton ?? false;
|
||||||
?>
|
?>
|
||||||
<section id="projects">
|
<section id="projects">
|
||||||
<h2>Projects</h2>
|
<h2>Projects</h2>
|
||||||
<? if($showAddButton){ ?>
|
<? if($showAddButton){ ?>
|
||||||
<a href="<?= $ebook->Url ?>/projects/new">New project</a>
|
<p>
|
||||||
|
<a href="<?= $ebook->Url ?>/projects/new">New project</a>
|
||||||
|
</p>
|
||||||
<? } ?>
|
<? } ?>
|
||||||
<? if(sizeof($ebook->Projects) > 0){ ?>
|
<? if(sizeof($ebook->Projects) > 0){ ?>
|
||||||
<?= Template::ProjectsTable(['projects' => $ebook->Projects, 'includeTitle' => false]) ?>
|
<?= Template::ProjectsTable(['projects' => $ebook->Projects, 'includeTitle' => false, 'showEditButton' => $showEditButton]) ?>
|
||||||
<? } ?>
|
<? } ?>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -3,8 +3,11 @@ $project = $project ?? new Project();
|
||||||
$managers = User::GetAllByCanManageProjects();
|
$managers = User::GetAllByCanManageProjects();
|
||||||
$reviewers = User::GetAllByCanReviewProjects();
|
$reviewers = User::GetAllByCanReviewProjects();
|
||||||
$areFieldsRequired = $areFieldsRequired ?? true;
|
$areFieldsRequired = $areFieldsRequired ?? true;
|
||||||
|
$isEditForm = $isEditForm ?? false;
|
||||||
?>
|
?>
|
||||||
<input type="hidden" name="project-ebook-id" value="<?= $project->EbookId ?? '' ?>" />
|
<? if(!$isEditForm){ ?>
|
||||||
|
<input type="hidden" name="project-ebook-id" value="<?= $project->EbookId ?? '' ?>" />
|
||||||
|
<? } ?>
|
||||||
|
|
||||||
<label class="icon user">
|
<label class="icon user">
|
||||||
<span>Producer name</span>
|
<span>Producer name</span>
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
$includeTitle = $includeTitle ?? true;
|
$includeTitle = $includeTitle ?? true;
|
||||||
$includeStatus = $includeStatus ?? true;
|
$includeStatus = $includeStatus ?? true;
|
||||||
|
$showEditButton = $showEditButton ?? false;
|
||||||
?>
|
?>
|
||||||
<table class="data-table">
|
<table class="data-table">
|
||||||
<caption aria-hidden="true">Scroll right →</caption>
|
<caption aria-hidden="true">Scroll right →</caption>
|
||||||
|
@ -22,6 +23,9 @@ $includeStatus = $includeStatus ?? true;
|
||||||
<? } ?>
|
<? } ?>
|
||||||
<th></th>
|
<th></th>
|
||||||
<th></th>
|
<th></th>
|
||||||
|
<? if($showEditButton){ ?>
|
||||||
|
<th></th>
|
||||||
|
<? } ?>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -65,6 +69,11 @@ $includeStatus = $includeStatus ?? true;
|
||||||
<a href="<?= Formatter::EscapeHtml($project->DiscussionUrl) ?>">Discussion</a>
|
<a href="<?= Formatter::EscapeHtml($project->DiscussionUrl) ?>">Discussion</a>
|
||||||
<? } ?>
|
<? } ?>
|
||||||
</td>
|
</td>
|
||||||
|
<? if($showEditButton){ ?>
|
||||||
|
<td>
|
||||||
|
<a href="<?= $project->EditUrl ?>">Edit</a>
|
||||||
|
</td>
|
||||||
|
<? } ?>
|
||||||
</tr>
|
</tr>
|
||||||
<? } ?>
|
<? } ?>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
grid-column: 1 / span 2
|
grid-column: 1 / span 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.project-form label:has(input[name="project-manager-user-id"]){
|
.project-form label:has(input[name="project-manager-user-id"]){
|
||||||
grid-column-start: 1;
|
grid-column-start: 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,21 +3,11 @@ use function Safe\session_unset;
|
||||||
|
|
||||||
session_start();
|
session_start();
|
||||||
|
|
||||||
|
|
||||||
$exception = HttpInput::SessionObject('exception', Exceptions\AppException::class);
|
|
||||||
|
|
||||||
/** @var string $identifier Passed from script this is included from. */
|
/** @var string $identifier Passed from script this is included from. */
|
||||||
$ebook = HttpInput::SessionObject('ebook', Ebook::class);
|
$ebook = HttpInput::SessionObject('ebook', Ebook::class);
|
||||||
|
$exception = HttpInput::SessionObject('exception', Exceptions\AppException::class);
|
||||||
|
|
||||||
try{
|
try{
|
||||||
if(Session::$User === null){
|
|
||||||
throw new Exceptions\LoginRequiredException();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!Session::$User->Benefits->CanEditEbookPlaceholders){
|
|
||||||
throw new Exceptions\InvalidPermissionsException();
|
|
||||||
}
|
|
||||||
|
|
||||||
if($ebook === null){
|
if($ebook === null){
|
||||||
$ebook = Ebook::GetByIdentifier($identifier);
|
$ebook = Ebook::GetByIdentifier($identifier);
|
||||||
}
|
}
|
||||||
|
@ -26,6 +16,14 @@ try{
|
||||||
throw new Exceptions\EbookNotFoundException();
|
throw new Exceptions\EbookNotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(Session::$User === null){
|
||||||
|
throw new Exceptions\LoginRequiredException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!Session::$User->Benefits->CanEditEbookPlaceholders){
|
||||||
|
throw new Exceptions\InvalidPermissionsException();
|
||||||
|
}
|
||||||
|
|
||||||
if($exception){
|
if($exception){
|
||||||
http_response_code(Enums\HttpCode::UnprocessableContent->value);
|
http_response_code(Enums\HttpCode::UnprocessableContent->value);
|
||||||
session_unset();
|
session_unset();
|
||||||
|
@ -57,7 +55,7 @@ catch(Exceptions\InvalidPermissionsException){
|
||||||
|
|
||||||
<form class="create-update-ebook-placeholder" method="<?= Enums\HttpMethod::Post->value ?>" action="<?= $ebook->Url ?>" autocomplete="off">
|
<form class="create-update-ebook-placeholder" method="<?= Enums\HttpMethod::Post->value ?>" action="<?= $ebook->Url ?>" autocomplete="off">
|
||||||
<input type="hidden" name="_method" value="<?= Enums\HttpMethod::Put->value ?>" />
|
<input type="hidden" name="_method" value="<?= Enums\HttpMethod::Put->value ?>" />
|
||||||
<?= Template::EbookPlaceholderForm(['ebook' => $ebook]) ?>
|
<?= Template::EbookPlaceholderForm(['ebook' => $ebook, 'isEditForm' => true]) ?>
|
||||||
</form>
|
</form>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
|
|
|
@ -8,6 +8,7 @@ session_start();
|
||||||
$ebook = null;
|
$ebook = null;
|
||||||
|
|
||||||
$isSaved = HttpInput::Bool(SESSION, 'is-ebook-placeholder-saved') ?? false;
|
$isSaved = HttpInput::Bool(SESSION, 'is-ebook-placeholder-saved') ?? false;
|
||||||
|
$isProjectSaved = HttpInput::Bool(SESSION, 'is-project-saved') ?? false;
|
||||||
|
|
||||||
try{
|
try{
|
||||||
$ebook = Ebook::GetByIdentifier($identifier);
|
$ebook = Ebook::GetByIdentifier($identifier);
|
||||||
|
@ -63,7 +64,11 @@ catch(Exceptions\EbookNotFoundException){
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<? if($isSaved){ ?>
|
<? if($isSaved){ ?>
|
||||||
<p class="message success">Ebook Placeholder saved!</p>
|
<p class="message success">Ebook placeholder saved!</p>
|
||||||
|
<? } ?>
|
||||||
|
|
||||||
|
<? if($isProjectSaved){ ?>
|
||||||
|
<p class="message success">Project saved!</p>
|
||||||
<? } ?>
|
<? } ?>
|
||||||
|
|
||||||
<aside id="reading-ease">
|
<aside id="reading-ease">
|
||||||
|
@ -115,17 +120,12 @@ catch(Exceptions\EbookNotFoundException){
|
||||||
<? } ?>
|
<? } ?>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<? if(Session::$User?->Benefits->CanEditEbooks){ ?>
|
<? if(Session::$User?->Benefits->CanEditEbooks || Session::$User?->Benefits->CanEditEbookPlaceholders){ ?>
|
||||||
<?= Template::EbookMetadata(['ebook' => $ebook]) ?>
|
<?= Template::EbookMetadata(['ebook' => $ebook, 'showPlaceholderMetadata' => Session::$User?->Benefits->CanEditEbookPlaceholders]) ?>
|
||||||
<? } ?>
|
<? } ?>
|
||||||
|
|
||||||
<? if(Session::$User?->Benefits->CanEditProjects || Session::$User?->Benefits->CanManageProjects || Session::$User?->Benefits->CanReviewProjects){ ?>
|
<? if(Session::$User?->Benefits->CanEditProjects || Session::$User?->Benefits->CanManageProjects || Session::$User?->Benefits->CanReviewProjects){ ?>
|
||||||
<?= Template::EbookProjects(['ebook' => $ebook, 'showAddButton' => Session::$User->Benefits->CanEditProjects && $ebook->ProjectInProgress === null]) ?>
|
<?= Template::EbookProjects(['ebook' => $ebook, 'showAddButton' => Session::$User->Benefits->CanEditProjects && $ebook->ProjectInProgress === null, 'showEditButton' => Session::$User->Benefits->CanEditProjects]) ?>
|
||||||
<? } ?>
|
|
||||||
|
|
||||||
<? if(Session::$User?->Benefits->CanEditEbookPlaceholders){ ?>
|
|
||||||
<h2>Edit ebook placeholder</h2>
|
|
||||||
<p><a href="<?= $ebook->EditUrl ?>">Edit this ebook placeholder.</a></p>
|
|
||||||
<? } ?>
|
<? } ?>
|
||||||
</article>
|
</article>
|
||||||
</main>
|
</main>
|
||||||
|
|
|
@ -16,7 +16,7 @@ try{
|
||||||
throw new Exceptions\InvalidPermissionsException();
|
throw new Exceptions\InvalidPermissionsException();
|
||||||
}
|
}
|
||||||
|
|
||||||
// POSTing a new ebook placeholder.
|
// POSTing an `EbookPlaceholder`.
|
||||||
if($httpMethod == Enums\HttpMethod::Post){
|
if($httpMethod == Enums\HttpMethod::Post){
|
||||||
$ebook = new Ebook();
|
$ebook = new Ebook();
|
||||||
|
|
||||||
|
@ -61,7 +61,8 @@ try{
|
||||||
http_response_code(Enums\HttpCode::SeeOther->value);
|
http_response_code(Enums\HttpCode::SeeOther->value);
|
||||||
header('Location: /ebook-placeholders/new');
|
header('Location: /ebook-placeholders/new');
|
||||||
}
|
}
|
||||||
// PUT a new ebook placeholder.
|
|
||||||
|
// PUT an `EbookPlaceholder`.
|
||||||
if($httpMethod == Enums\HttpMethod::Put){
|
if($httpMethod == Enums\HttpMethod::Put){
|
||||||
$originalEbook = Ebook::GetByIdentifier($identifier);
|
$originalEbook = Ebook::GetByIdentifier($identifier);
|
||||||
$exceptionRedirectUrl = $originalEbook->EditUrl;
|
$exceptionRedirectUrl = $originalEbook->EditUrl;
|
||||||
|
@ -72,35 +73,8 @@ try{
|
||||||
$ebook->EbookId = $originalEbook->EbookId;
|
$ebook->EbookId = $originalEbook->EbookId;
|
||||||
$ebook->Created = $originalEbook->Created;
|
$ebook->Created = $originalEbook->Created;
|
||||||
|
|
||||||
// Do we have a `Project` to create/save at the same time?
|
|
||||||
$project = null;
|
|
||||||
if($ebook->EbookPlaceholder?->IsInProgress){
|
|
||||||
$originalProject = $originalEbook->ProjectInProgress;
|
|
||||||
$project = new Project();
|
|
||||||
$project->FillFromHttpPost();
|
|
||||||
$project->EbookId = $ebook->EbookId;
|
|
||||||
$project->Ebook = $ebook;
|
|
||||||
if(isset($originalProject)){
|
|
||||||
$project->ProjectId = $originalProject->ProjectId;
|
|
||||||
$project->Started = $originalProject->Started;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
$project->Started = NOW;
|
|
||||||
}
|
|
||||||
$project->Validate();
|
|
||||||
}
|
|
||||||
|
|
||||||
$ebook->Save();
|
$ebook->Save();
|
||||||
|
|
||||||
if($ebook->EbookPlaceholder?->IsInProgress && $project !== null){
|
|
||||||
if(isset($originalProject)){
|
|
||||||
$project->Save();
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
$project->Create();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$_SESSION['is-ebook-placeholder-saved'] = true;
|
$_SESSION['is-ebook-placeholder-saved'] = true;
|
||||||
http_response_code(Enums\HttpCode::SeeOther->value);
|
http_response_code(Enums\HttpCode::SeeOther->value);
|
||||||
header('Location: ' . $ebook->Url);
|
header('Location: ' . $ebook->Url);
|
||||||
|
|
65
www/projects/edit.php
Normal file
65
www/projects/edit.php
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
<?
|
||||||
|
use function Safe\session_unset;
|
||||||
|
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
$project = HttpInput::SessionObject('project', Project::class);
|
||||||
|
$exception = HttpInput::SessionObject('exception', Exceptions\AppException::class);
|
||||||
|
|
||||||
|
try{
|
||||||
|
if($project === null){
|
||||||
|
$project = Project::Get(HttpInput::Int(GET, 'project-id'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Session::$User === null){
|
||||||
|
throw new Exceptions\LoginRequiredException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!Session::$User->Benefits->CanEditProjects){
|
||||||
|
throw new Exceptions\InvalidPermissionsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if($exception){
|
||||||
|
http_response_code(Enums\HttpCode::UnprocessableContent->value);
|
||||||
|
session_unset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(Exceptions\ProjectNotFoundException){
|
||||||
|
Template::ExitWithCode(Enums\HttpCode::NotFound);
|
||||||
|
}
|
||||||
|
catch(Exceptions\LoginRequiredException){
|
||||||
|
Template::RedirectToLogin();
|
||||||
|
}
|
||||||
|
catch(Exceptions\InvalidPermissionsException){
|
||||||
|
Template::ExitWithCode(Enums\HttpCode::Forbidden);
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<?= Template::Header(
|
||||||
|
[
|
||||||
|
'title' => 'Edit Project for ' . $project->Ebook->Title,
|
||||||
|
'css' => ['/css/project.css'],
|
||||||
|
'highlight' => '',
|
||||||
|
'description' => 'Edit the project for ' . $project->Ebook->Title
|
||||||
|
]
|
||||||
|
) ?>
|
||||||
|
<main>
|
||||||
|
<section class="narrow">
|
||||||
|
<nav class="breadcrumbs">
|
||||||
|
<a href="<?= $project->Ebook->AuthorsUrl ?>"><?= $project->Ebook->AuthorsString ?></a> →
|
||||||
|
<a href="<?= $project->Ebook->Url ?>"><?= Formatter::EscapeHtml($project->Ebook->Title) ?></a> →
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<h1>Edit Project</h1>
|
||||||
|
|
||||||
|
<?= Template::Error(['exception' => $exception]) ?>
|
||||||
|
|
||||||
|
<form class="project-form" method="<?= Enums\HttpMethod::Post->value ?>" action="<?= $project->Url ?>" autocomplete="off">
|
||||||
|
<input type="hidden" name="_method" value="<?= Enums\HttpMethod::Put->value ?>" />
|
||||||
|
<?= Template::ProjectForm(['project' => $project, 'isEditForm' => true]) ?>
|
||||||
|
<div class="footer">
|
||||||
|
<button>Save</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
<?= Template::Footer() ?>
|
|
@ -4,6 +4,7 @@ try{
|
||||||
session_start();
|
session_start();
|
||||||
|
|
||||||
$httpMethod = HttpInput::ValidateRequestMethod([Enums\HttpMethod::Post, Enums\HttpMethod::Patch, Enums\HttpMethod::Put]);
|
$httpMethod = HttpInput::ValidateRequestMethod([Enums\HttpMethod::Post, Enums\HttpMethod::Patch, Enums\HttpMethod::Put]);
|
||||||
|
$exceptionRedirectUrl = '/projects/new';
|
||||||
|
|
||||||
if(Session::$User === null){
|
if(Session::$User === null){
|
||||||
throw new Exceptions\LoginRequiredException();
|
throw new Exceptions\LoginRequiredException();
|
||||||
|
@ -26,6 +27,20 @@ try{
|
||||||
http_response_code(Enums\HttpCode::SeeOther->value);
|
http_response_code(Enums\HttpCode::SeeOther->value);
|
||||||
header('Location: /projects');
|
header('Location: /projects');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PUTing a `Project`.
|
||||||
|
if($httpMethod == Enums\HttpMethod::Put){
|
||||||
|
$project = Project::Get(HttpInput::Int(GET, 'project-id'));
|
||||||
|
$exceptionRedirectUrl = $project->EditUrl;
|
||||||
|
|
||||||
|
$project->FillFromHttpPost();
|
||||||
|
|
||||||
|
$project->Save();
|
||||||
|
|
||||||
|
$_SESSION['is-project-saved'] = true;
|
||||||
|
http_response_code(Enums\HttpCode::SeeOther->value);
|
||||||
|
header('Location: ' . $project->Ebook->Url);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch(Exceptions\EbookNotFoundException){
|
catch(Exceptions\EbookNotFoundException){
|
||||||
Template::ExitWithCode(Enums\HttpCode::NotFound);
|
Template::ExitWithCode(Enums\HttpCode::NotFound);
|
||||||
|
@ -41,5 +56,5 @@ catch(Exceptions\InvalidProjectException | Exceptions\ProjectExistsException | E
|
||||||
$_SESSION['exception'] = $ex;
|
$_SESSION['exception'] = $ex;
|
||||||
|
|
||||||
http_response_code(Enums\HttpCode::SeeOther->value);
|
http_response_code(Enums\HttpCode::SeeOther->value);
|
||||||
header('Location: /projects/new');
|
header('Location: ' . $exceptionRedirectUrl);
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ catch(Exceptions\InvalidPermissionsException){
|
||||||
<p class="message success">User saved!</p>
|
<p class="message success">User saved!</p>
|
||||||
<? } ?>
|
<? } ?>
|
||||||
|
|
||||||
<a href="<?= $user->Url ?>/edit">Edit user</a>
|
<a href="<?= $user->EditUrl ?>">Edit user</a>
|
||||||
|
|
||||||
<? if($user->Benefits->CanManageProjects || $user->Benefits->CanReviewProjects){ ?>
|
<? if($user->Benefits->CanManageProjects || $user->Benefits->CanReviewProjects){ ?>
|
||||||
<a href="<?= $user->Url ?>/projects">Projects</a>
|
<a href="<?= $user->Url ?>/projects">Projects</a>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue