Skip to content

Commit

Permalink
feat(revisions): Allow draft revisions on top of published content
Browse files Browse the repository at this point in the history
  • Loading branch information
pboivin committed Jun 30, 2022
1 parent b86ae53 commit 2da2200
Show file tree
Hide file tree
Showing 6 changed files with 214 additions and 21 deletions.
5 changes: 5 additions & 0 deletions lang/en/lang.php
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,11 @@
'restore-live-new' => 'Restore as published and create new',
'restore-message' => 'You are currently editing an older revision of this content (saved by :user on :date). Make changes if needed and click restore to save a new revision.',
'restore-success' => 'Revision restored.',
'draft-revision' => 'Save as draft revision',
'draft-revision-close' => 'Save as draft revision and close',
'draft-revision-new' => 'Save as draft revision and create new',
'draft-revisions-available' => 'You are currently viewing the published version of this content. There are newer draft revisions available.',
'editing-draft-revision' => 'You are currently editing a draft revision of this content. Make changes if needed and click Save as revision or Publish.',
'revisions' => 'Revisions',
'save' => 'Save as draft',
'save-close' => 'Save as draft and close',
Expand Down
127 changes: 127 additions & 0 deletions src/Http/Controllers/Admin/Concerns/FormSubmitOptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ trait FormSubmitOptions
{
public function getSubmitOptions(Model $item): ?array
{
if ($this->moduleHas('revisions') && $this->enableDraftRevisions) {
return $this->getSubmitOptionsForDraftRevisions($item);
}

if ($item->cmsRestoring ?? false) {
return [
'draft' => [
Expand Down Expand Up @@ -124,4 +128,127 @@ public function getSubmitOptions(Model $item): ?array
],
];
}

protected function getSubmitOptionsForDraftRevisions(Model $item): ?array
{
if ($item->cmsRestoring ?? false) {
return [
'draft' => [
[
'name' => 'draft-revision',
'text' => twillTrans('twill::lang.publisher.draft-revision'),
],
[
'name' => 'draft-revision-close',
'text' => twillTrans('twill::lang.publisher.draft-revision-close'),
],
[
'name' => 'draft-revision-new',
'text' => twillTrans('twill::lang.publisher.draft-revision-new'),
],
[
'name' => 'cancel',
'text' => twillTrans('twill::lang.publisher.cancel'),
],
],
'live' => [
[
'name' => 'restore',
'text' => twillTrans('twill::lang.publisher.publish'),
],
[
'name' => 'restore-close',
'text' => twillTrans('twill::lang.publisher.publish-close'),
],
[
'name' => 'restore-new',
'text' => twillTrans('twill::lang.publisher.publish-new'),
],
[
'name' => 'cancel',
'text' => twillTrans('twill::lang.publisher.cancel'),
],
],
'update' => [
[
'name' => 'restore',
'text' => twillTrans('twill::lang.publisher.publish'),
],
[
'name' => 'restore-close',
'text' => twillTrans('twill::lang.publisher.publish-close'),
],
[
'name' => 'restore-new',
'text' => twillTrans('twill::lang.publisher.publish-new'),
],
[
'name' => 'cancel',
'text' => twillTrans('twill::lang.publisher.cancel'),
],
],
];
}

return [
'draft' => [
[
'name' => 'save',
'text' => twillTrans('twill::lang.publisher.save'),
],
[
'name' => 'save-close',
'text' => twillTrans('twill::lang.publisher.save-close'),
],
[
'name' => 'save-new',
'text' => twillTrans('twill::lang.publisher.save-new'),
],
[
'name' => 'cancel',
'text' => twillTrans('twill::lang.publisher.cancel'),
],
],
'live' => [
[
'name' => 'publish',
'text' => twillTrans('twill::lang.publisher.publish'),
],
[
'name' => 'publish-close',
'text' => twillTrans('twill::lang.publisher.publish-close'),
],
[
'name' => 'publish-new',
'text' => twillTrans('twill::lang.publisher.publish-new'),
],
[
'name' => 'cancel',
'text' => twillTrans('twill::lang.publisher.cancel'),
],
],
'update' => [
[
'name' => 'draft-revision',
'text' => twillTrans('twill::lang.publisher.draft-revision'),
],
[
'name' => 'publish',
'text' => twillTrans('twill::lang.publisher.publish'),
],
[
'name' => 'publish-close',
'text' => twillTrans('twill::lang.publisher.publish-close'),
],
[
'name' => 'publish-new',
'text' => twillTrans('twill::lang.publisher.publish-new'),
],
[
'name' => 'cancel',
'text' => twillTrans('twill::lang.publisher.cancel'),
],
],
];
}
}
55 changes: 44 additions & 11 deletions src/Http/Controllers/Admin/ModuleController.php
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,13 @@ abstract class ModuleController extends Controller
*/
protected $fieldsPermissions = [];

/**
* Determines if draft revisions can be added on top of published content.
*
* @var bool
*/
protected $enableDraftRevisions = false;

public function __construct(Application $app, Request $request)
{
parent::__construct();
Expand Down Expand Up @@ -478,7 +485,17 @@ public function edit($id, $submoduleId = null)
return View::exists($view);
});

return View::make($view, $this->form($id));
$item = $this->repository->getById($id);

if ($this->moduleHas('revisions')) {
$latestRevision = $item->revisions->first();

if ($latestRevision && $latestRevision->isDraft()) {
Session::flash('status', twillTrans('twill::lang.publisher.draft-revisions-available'));
}
}

return View::make($view, $this->form($id, $item));
}

/**
Expand Down Expand Up @@ -538,13 +555,7 @@ public function update($id, $submoduleId = null)
[Str::singular($this->moduleName) => $id]
));
} else {
$formRequest = $this->validateFormRequest();

$this->repository->update($id, $formRequest->all());

activity()->performedOn($item)->log('updated');

$this->fireEvent();
$this->performUpdate($item);

if (isset($input['cmsSaveType'])) {
if (Str::endsWith($input['cmsSaveType'], '-close')) {
Expand Down Expand Up @@ -580,14 +591,32 @@ public function update($id, $submoduleId = null)
return Response::json([
'message' => twillTrans('twill::lang.publisher.save-success'),
'variant' => FlashLevel::SUCCESS,
'revisions' => $item->revisionsArray(),
'revisions' => $item->refresh()->revisionsArray(),
]);
}

return $this->respondWithSuccess(twillTrans('twill::lang.publisher.save-success'));
}
}

protected function performUpdate($item)
{
$formRequest = $this->validateFormRequest();
$data = $formRequest->all();

if (Str::startsWith($data['cmsSaveType'] ?? '', 'draft-revision')) {
$data['published'] = false;

$this->repository->createRevisionIfNeeded($item, $data);
} else {
$this->repository->update($item->id, $data);

activity()->performedOn($item)->log('updated');

$this->fireEvent();
}
}

/**
* @param int $id
* @return \Illuminate\View\View
Expand Down Expand Up @@ -639,9 +668,13 @@ public function restoreRevision($id)
});

$revision = $item->revisions()->where('id', $this->request->get('revisionId'))->first();
$date = $revision->created_at->toDayDateTimeString();

Session::flash('restoreMessage', twillTrans('twill::lang.publisher.restore-message', ['user' => $revision->byUser, 'date' => $date]));
if ($revision->isDraft()) {
Session::flash('restoreMessage', twillTrans('twill::lang.publisher.editing-draft-revision'));
} else {
$date = $revision->created_at->toDayDateTimeString();
Session::flash('restoreMessage', twillTrans('twill::lang.publisher.restore-message', ['user' => $revision->byUser, 'date' => $date]));
}

return View::make($view, $this->form($id, $item));
}
Expand Down
24 changes: 16 additions & 8 deletions src/Models/Behaviors/HasRevisions.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,22 @@ public function scopeMine($query)
*/
public function revisionsArray()
{
return $this->revisions->map(function ($revision, $index) {
return [
'id' => $revision->id,
'author' => $revision->user->name ?? 'Unknown',
'datetime' => $revision->created_at->toIso8601String(),
'label' => $index === 0 ? twillTrans('twill::lang.publisher.current') : '',
];
})->toArray();
$currentRevision = null;

return $this->revisions
->map(function ($revision, $index) use (&$currentRevision) {
if (!$currentRevision && !$revision->isDraft()) {
$currentRevision = $revision;
}

return [
'id' => $revision->id,
'author' => $revision->user->name ?? 'Unknown',
'datetime' => $revision->created_at->toIso8601String(),
'label' => $currentRevision === $revision ? twillTrans('twill::lang.publisher.current') : '',
];
})
->toArray();
}

protected function getRevisionModel()
Expand Down
10 changes: 10 additions & 0 deletions src/Models/Revision.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace A17\Twill\Models;

use Illuminate\Database\Eloquent\Model as BaseModel;
use Illuminate\Support\Str;

abstract class Revision extends BaseModel
{
Expand Down Expand Up @@ -35,4 +36,13 @@ public function getByUserAttribute()
{
return isset($this->user) ? $this->user->name : 'System';
}

public function isDraft(): bool
{
$data = json_decode($this->payload, true);

$cmsSaveType = $data['cmsSaveType'] ?? '';

return Str::startsWith($cmsSaveType, 'draft-revision');
}
}
14 changes: 12 additions & 2 deletions src/Repositories/Behaviors/HandleRevisions.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,18 @@ public function hydrateHandleRevisions($object, $fields)
* @return array
*/
public function beforeSaveHandleRevisions($object, $fields)
{
$this->createRevisionIfNeeded($object, $fields);

return $fields;
}

/**
* @param \A17\Twill\Models\Model $object
* @param array $fields
* @return void
*/
public function createRevisionIfNeeded($object, $fields)
{
$lastRevisionPayload = json_decode($object->revisions->first()->payload ?? "{}", true);

Expand All @@ -47,8 +59,6 @@ public function beforeSaveHandleRevisions($object, $fields)
'user_id' => Auth::guard('twill_users')->user()->id ?? null,
]);
}

return $fields;
}

/**
Expand Down

0 comments on commit 2da2200

Please sign in to comment.