diff --git a/CHANGELOG.md b/CHANGELOG.md index cbc99ef..25255d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,21 @@ 2. Then, change the addon's version constraint to `^3.0` 3. If you have any references to `DoubleThreeDigital` within your site in relation to this addon, replace it with `DuncanMcClean` +## v2.1.3 (2023-04-21) + +### What's new + +- Added `{{ guest-entries:success }}` tag #53 #48 + +### What's fixed + +- Fixed `error_redirect` parameter #51 #49 +- Fixed an issue when using title formats on collections #52 #50 + +### Breaking changes + +The `success` key added in the last release has been reverted, in favour of the new `{{ guest-entries:success }}` tag. Apologies for any inconvenience. + ## v2.1.2 (2023-04-17) ### What's improved diff --git a/docs/tags.md b/docs/tags.md index 28e371b..d66d145 100644 --- a/docs/tags.md +++ b/docs/tags.md @@ -106,10 +106,10 @@ If you'd like to show any errors after a user has submitted the Guest Entries fo ### Success -If you'd like to show a success message after a user has submitted a Guest entry, you can test for the session success key. +If you'd like to show a success message after a user has submitted the Guest Entries form, you can use the `{{ guest-entries:success }}` tag, like shown below: ```antlers -{{ if {session:has key="success"} }} +{{ if {guest-entries:success} }} Well done buddy! {{ /if }} ``` diff --git a/src/Http/Controllers/GuestEntryController.php b/src/Http/Controllers/GuestEntryController.php index e6e9e36..d1ad59d 100644 --- a/src/Http/Controllers/GuestEntryController.php +++ b/src/Http/Controllers/GuestEntryController.php @@ -43,12 +43,6 @@ public function store(StoreRequest $request) ->locale($this->guessSiteFromRequest($request)) ->published(false); - if ($request->has('slug')) { - $entry->slug($request->get('slug')); - } else { - $entry->slug(Str::slug($request->get('title'))); - } - if ($collection->dated()) { $this->ignoredParameters[] = 'date'; $entry->date($request->get('date') ?? now()); @@ -70,13 +64,19 @@ public function store(StoreRequest $request) ); } + if ($request->has('slug')) { + $entry->slug($request->get('slug')); + } elseif ($collection->entryBlueprint()->hasField('title')) { + $entry->slug( + Str::slug($request->get('title') ?? $entry->autoGeneratedTitle(), '-', $entry->site()->lang()) + ); + } + $entry->touch(); event(new GuestEntryCreated($entry)); - return $this->withSuccess($request, [ - 'success' => true, - ]); + return $this->withSuccess($request); } public function update(UpdateRequest $request) @@ -149,9 +149,7 @@ public function update(UpdateRequest $request) event(new GuestEntryUpdated($entry)); - return $this->withSuccess($request, [ - 'success' => true, - ]); + return $this->withSuccess($request); } public function destroy(DestroyRequest $request) @@ -166,9 +164,7 @@ public function destroy(DestroyRequest $request) event(new GuestEntryDeleted($entry)); - return $this->withSuccess($request, [ - 'success' => true, - ]); + return $this->withSuccess($request); } protected function processField(Field $field, $key, $value, $request): mixed @@ -337,22 +333,10 @@ protected function withSuccess(Request $request, array $data = []) return response()->json($data); } + $request->session()->put('guest-entries.success', true); + return $request->_redirect ? redirect($request->_redirect)->with($data) : back()->with($data); } - - protected function withErrors(Request $request, string $errorMessage) - { - if ($request->wantsJson()) { - return response()->json([ - 'status' => 'error', - 'message' => $errorMessage, - ]); - } - - return $request->_error_redirect - ? redirect($request->_error_redirect)->withErrors($errorMessage, 'guest-entries') - : back()->withErrors($errorMessage, 'guest-entries'); - } } diff --git a/src/Http/Requests/Concerns/HandleFailedValidation.php b/src/Http/Requests/Concerns/HandleFailedValidation.php new file mode 100644 index 0000000..fe69d47 --- /dev/null +++ b/src/Http/Requests/Concerns/HandleFailedValidation.php @@ -0,0 +1,20 @@ +has('_error_redirect')) { + return $this->get('_error_redirect'); + } + + return parent::getRedirectUrl(); + } +} diff --git a/src/Http/Requests/DestroyRequest.php b/src/Http/Requests/DestroyRequest.php index 2a54b9e..3807021 100644 --- a/src/Http/Requests/DestroyRequest.php +++ b/src/Http/Requests/DestroyRequest.php @@ -8,7 +8,8 @@ class DestroyRequest extends FormRequest { - use Concerns\WhitelistedCollections; + use Concerns\WhitelistedCollections, + Concerns\HandleFailedValidation; public function authorize() { diff --git a/src/Http/Requests/StoreRequest.php b/src/Http/Requests/StoreRequest.php index 2c23c7f..fe83e32 100644 --- a/src/Http/Requests/StoreRequest.php +++ b/src/Http/Requests/StoreRequest.php @@ -4,11 +4,13 @@ use DuncanMcClean\GuestEntries\Rules\CollectionExists; use Illuminate\Foundation\Http\FormRequest; +use Statamic\Facades\Collection; class StoreRequest extends FormRequest { use Concerns\AcceptsFormRequests, - Concerns\WhitelistedCollections; + Concerns\WhitelistedCollections, + Concerns\HandleFailedValidation; public function authorize() { @@ -24,7 +26,11 @@ public function rules() '_redirect' => ['nullable', 'string'], '_error_redirect' => ['nullable', 'string'], '_request' => ['nullable', 'string'], - 'slug' => ['required_without:title'], + 'slug' => [ + Collection::find($this->get('_collection'))->autoGeneratesTitles() + ? null + : 'required_without:title', + ], ]; if ($formRequest = $this->get('_request')) { diff --git a/src/Http/Requests/UpdateRequest.php b/src/Http/Requests/UpdateRequest.php index c6590be..e2db64c 100644 --- a/src/Http/Requests/UpdateRequest.php +++ b/src/Http/Requests/UpdateRequest.php @@ -9,7 +9,8 @@ class UpdateRequest extends FormRequest { use Concerns\AcceptsFormRequests, - Concerns\WhitelistedCollections; + Concerns\WhitelistedCollections, + Concerns\HandleFailedValidation; public function authorize() { diff --git a/src/Tags/Concerns/FormBuilder.php b/src/Tags/Concerns/FormBuilder.php index d3d182b..27a8678 100644 --- a/src/Tags/Concerns/FormBuilder.php +++ b/src/Tags/Concerns/FormBuilder.php @@ -26,6 +26,10 @@ protected function createForm(string $action, array $data = [], string $method = $html .= $this->redirectField(); } + if ($this->params->get('error_redirect') != null) { + $html .= $this->errorRedirectField(); + } + if ($this->params->get('request') != null) { $html .= $this->requestField(); } @@ -61,6 +65,11 @@ private function redirectField() return ''; } + private function errorRedirectField() + { + return ''; + } + private function requestField() { return ''; @@ -73,8 +82,8 @@ private function params(): array return $params[$param] = $redirect; } })->filter() - ->values() - ->all(); + ->values() + ->all(); } /** diff --git a/src/Tags/GuestEntriesTag.php b/src/Tags/GuestEntriesTag.php index 02d24fb..ffa5356 100644 --- a/src/Tags/GuestEntriesTag.php +++ b/src/Tags/GuestEntriesTag.php @@ -97,4 +97,9 @@ public function hasErrors() { return session()->has('errors'); } + + public function success(): bool + { + return session()->get('guest-entries.success', false); + } } diff --git a/tests/Http/Controllers/GuestEntryControllerTest.php b/tests/Http/Controllers/GuestEntryControllerTest.php index 0fe4343..d9442e6 100644 --- a/tests/Http/Controllers/GuestEntryControllerTest.php +++ b/tests/Http/Controllers/GuestEntryControllerTest.php @@ -36,8 +36,7 @@ 'title' => 'This is great', 'slug' => 'this-is-great', ]) - ->assertRedirect() - ->assertSessionHas('success'); + ->assertRedirect(); $entry = Entry::all()->last(); @@ -65,6 +64,24 @@ $this->assertSame($entry->slug(), 'this-is-fantastic'); }); +it('can store entry when collection has title format', function () { + Collection::make('comments')->titleFormats(['default' => 'BLAH {{ name }}'])->save(); + + $this + ->post(route('statamic.guest-entries.store'), [ + '_collection' => 'comments', + 'name' => 'So, I was sitting there and somebody came up to me and I asked them something.', + ]) + ->assertRedirect(); + + $entry = Entry::all()->last(); + + $this->assertNotNull($entry); + $this->assertSame($entry->collectionHandle(), 'comments'); + $this->assertSame($entry->get('title'), 'BLAH So, I was sitting there and somebody came up to me and I asked them something.'); + $this->assertSame($entry->slug(), 'blah-so-i-was-sitting-there-and-somebody-came-up-to-me-and-i-asked-them-something'); +}); + it('can store entry with custom form request', function () { Collection::make('comments')->save(); @@ -119,14 +136,14 @@ Collection::make('comments')->save(); $this - ->post(route('statamic.guest-entries.store'), [ - '_collection' => 'comments', - '_redirect' => '/whatever', - '_error_redirect' => '/whatever-else', - 'title' => 'This is great', - 'slug' => 'this-is-great', - ]) - ->assertRedirect(); + ->post(route('statamic.guest-entries.store'), [ + '_collection' => 'comments', + '_redirect' => '/whatever', + '_error_redirect' => '/whatever-else', + 'title' => 'This is great', + 'slug' => 'this-is-great', + ]) + ->assertRedirect(); $entry = Entry::all()->last(); @@ -449,60 +466,60 @@ AssetContainer::make('assets')->disk('local')->save(); Blueprint::make('comments') - ->setNamespace('collections.comments') - ->setContents([ - 'title' => 'Comments', - 'sections' => [ - 'main' => [ - 'display' => 'main', - 'fields' => [ - [ - 'handle' => 'title', - 'field' => [ - 'type' => 'text', - ], + ->setNamespace('collections.comments') + ->setContents([ + 'title' => 'Comments', + 'sections' => [ + 'main' => [ + 'display' => 'main', + 'fields' => [ + [ + 'handle' => 'title', + 'field' => [ + 'type' => 'text', ], - [ - 'handle' => 'slug', - 'field' => [ - 'type' => 'slug', - ], + ], + [ + 'handle' => 'slug', + 'field' => [ + 'type' => 'slug', ], - [ - 'handle' => 'attachments', - 'field' => [ - 'mode' => 'list', - 'container' => 'assets', - 'restrict' => false, - 'allow_uploads' => true, - 'show_filename' => true, - 'display' => 'Attachment', - 'type' => 'assets', - 'icon' => 'assets', - 'listable' => 'hidden', - ], + ], + [ + 'handle' => 'attachments', + 'field' => [ + 'mode' => 'list', + 'container' => 'assets', + 'restrict' => false, + 'allow_uploads' => true, + 'show_filename' => true, + 'display' => 'Attachment', + 'type' => 'assets', + 'icon' => 'assets', + 'listable' => 'hidden', ], ], ], ], - ]) - ->save(); + ], + ]) + ->save(); Collection::make('comments')->save(); $this->withoutExceptionHandling(); $this - ->post(route('statamic.guest-entries.store'), [ - '_collection' => 'comments', - 'title' => 'This is great', - 'slug' => 'this-is-great', - 'attachments' => [ - UploadedFile::fake()->create('foobar.png'), - UploadedFile::fake()->create('barfoo.jpg'), - ], - ]) - ->assertRedirect(); + ->post(route('statamic.guest-entries.store'), [ + '_collection' => 'comments', + 'title' => 'This is great', + 'slug' => 'this-is-great', + 'attachments' => [ + UploadedFile::fake()->create('foobar.png'), + UploadedFile::fake()->create('barfoo.jpg'), + ], + ]) + ->assertRedirect(); $entry = Entry::all()->last(); @@ -987,8 +1004,7 @@ '_id' => 'allo-mate-idee', 'record_label' => 'Unknown', ]) - ->assertRedirect() - ->assertSessionHas('success'); + ->assertRedirect(); $entry = Entry::find('allo-mate-idee'); @@ -999,6 +1015,36 @@ $this->assertSame($entry->slug(), 'allo-mate'); }); +it('can update entry if collection has title format', function () { + Collection::make('albums')->titleFormats(['default' => '{{ artist }} - {{ name }}'])->save(); + + Entry::make() + ->id('allo-mate-idee') + ->collection('albums') + ->slug('allo-mate') + ->data([ + 'title' => 'Guvna B - Allo Mate!', + 'name' => 'Allo Mate!', + 'artist' => 'Guvna B', + ]) + ->save(); + + $this + ->post(route('statamic.guest-entries.update'), [ + '_collection' => 'albums', + '_id' => 'allo-mate-idee', + 'record_label' => 'Unknown', + 'name' => 'Allo Mate', + ]) + ->assertRedirect(); + + $entry = Entry::find('allo-mate-idee'); + + $this->assertNotNull($entry); + $this->assertSame($entry->collectionHandle(), 'albums'); + $this->assertSame($entry->get('title'), 'Guvna B - Allo Mate'); +}); + it('can update entry with custom form request', function () { Collection::make('albums')->save(); @@ -1940,22 +1986,21 @@ Collection::make('albums')->save(); Entry::make() - ->id('allo-mate-idee') - ->collection('albums') - ->slug('allo-mate') - ->data([ - 'title' => 'Allo Mate!', - 'artist' => 'Guvna B', - ]) - ->save(); + ->id('allo-mate-idee') + ->collection('albums') + ->slug('allo-mate') + ->data([ + 'title' => 'Allo Mate!', + 'artist' => 'Guvna B', + ]) + ->save(); $this ->delete(route('statamic.guest-entries.destroy'), [ '_collection' => 'albums', '_id' => 'allo-mate-idee', ]) - ->assertRedirect() - ->assertSessionHas('success'); + ->assertRedirect(); $entry = Entry::find('allo-mate-idee'); diff --git a/tests/Tags/GuestEntriesTagTest.php b/tests/Tags/GuestEntriesTagTest.php index e9ecf88..6c5ec2e 100644 --- a/tests/Tags/GuestEntriesTagTest.php +++ b/tests/Tags/GuestEntriesTagTest.php @@ -81,6 +81,24 @@ $usage = $tag->create(); })->throws(CollectionNotFoundException::class); +it('returns create guest entry form with redirect and error_redirect hidden inputs', function () use (&$tag) { + Collection::make('guestbook')->save(); + + $tag->setParameters([ + 'collection' => 'guestbook', + 'redirect' => '/thank-you', + 'error_redirect' => '/error', + ]); + + $usage = $tag->create(); + + assertStringContainsString('http://localhost/!/guest-entries/create', $usage); + assertStringContainsString('save(); @@ -263,6 +281,33 @@ assertStringContainsString('', $usage); }); +it('returns update guest entry form with redirect and error_redirect hidden inputs', function () use (&$tag) { + Collection::make('guestbook')->save(); + + Entry::make() + ->collection('guestbook') + ->id('hello') + ->slug('hello') + ->data(['title' => 'Hello World']) + ->save(); + + $tag->setParameters([ + 'collection' => 'guestbook', + 'id' => 'hello', + 'redirect' => '/thank-you', + 'error_redirect' => '/error', + ]); + + $usage = $tag->update(); + + assertStringContainsString('http://localhost/!/guest-entries/update', $usage); + assertStringContainsString('save(); @@ -420,3 +465,30 @@ assertStringContainsString('

Delete Guestbook Entry: Hello World

', $usage); assertStringContainsString('', $usage); }); + +it('returns delete guest entry form with redirect and error_redirect hidden inputs', function () use (&$tag) { + Collection::make('guestbook')->save(); + + Entry::make() + ->collection('guestbook') + ->id('hello') + ->slug('hello') + ->data(['title' => 'Hello World']) + ->save(); + + $tag->setParameters([ + 'collection' => 'guestbook', + 'id' => 'hello', + 'redirect' => '/thank-you', + 'error_redirect' => '/error', + ]); + + $usage = $tag->delete(); + + assertStringContainsString('http://localhost/!/guest-entries/delete', $usage); + assertStringContainsString('