Skip to content

[5.x] Make it possible to add to form configuration screen #8491

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 27 commits into from
Jul 30, 2024
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
8b70221
Initial concept
ryanmitchell Jul 26, 2023
40c5da8
Add some test coverage
ryanmitchell Aug 1, 2023
1df616e
Remove un-needed use statements
ryanmitchell Aug 1, 2023
3ecdeec
:beer:
ryanmitchell Aug 1, 2023
174f0b4
Change method signature to make it more intuitive
ryanmitchell Aug 1, 2023
96171a7
Missed this test update
ryanmitchell Aug 1, 2023
77a36f1
Use the correct reserved words
ryanmitchell Aug 1, 2023
ef2ce6b
Change method name to appendConfigFields for consistency
ryanmitchell Sep 20, 2023
a354d17
Merge branch '4.x' into feature/form-config-config
ryanmitchell Oct 10, 2023
bef04b1
Merge branch '4.x' into feature/form-config-config
ryanmitchell Nov 13, 2023
f9f0c19
Merge branch '4.x' into pr/8491
duncanmcclean Nov 22, 2023
896deeb
Merge branch '4.x' into pr/8491
duncanmcclean Dec 4, 2023
9d88f0a
Add ability to add to existing sections
ryanmitchell Dec 4, 2023
7933ff0
:beer:
ryanmitchell Dec 4, 2023
a357911
Merge branch '4.x' into feature/form-config-config
ryanmitchell Jan 10, 2024
77852db
Merge branch '4.x' into pr/8491
duncanmcclean Feb 13, 2024
36eca54
Merge branch '5.x' into feature/form-config-config
ryanmitchell May 10, 2024
29dcafa
:beer:
ryanmitchell May 10, 2024
69e40b5
Yep
ryanmitchell May 10, 2024
1f03cca
Merge branch '5.x' into feature/form-config-config
jasonvarga Jul 29, 2024
9e64231
Add test to assert fields can be added to existing sections
jasonvarga Jul 29, 2024
af065a6
method name
jasonvarga Jul 29, 2024
1ae9b25
my brain wasnt braining
jasonvarga Jul 29, 2024
5e98987
use the property
jasonvarga Jul 29, 2024
7b25e50
adjust test and use snake case
jasonvarga Jul 30, 2024
eb4dbbd
key by handle, it doesnt really matter, but the rest of it is.
jasonvarga Jul 30, 2024
31c2841
add hints to facade
jasonvarga Jul 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 23 additions & 11 deletions src/Forms/Form.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Statamic\Contracts\Data\Augmented;
use Statamic\Contracts\Forms\Form as FormContract;
use Statamic\Contracts\Forms\Submission;
use Statamic\Data\ContainsData;
use Statamic\Data\HasAugmentedInstance;
use Statamic\Events\FormBlueprintFound;
use Statamic\Events\FormCreated;
Expand All @@ -27,7 +28,7 @@

class Form implements Arrayable, Augmentable, FormContract
{
use FluentlyGetsAndSets, HasAugmentedInstance;
use ContainsData, FluentlyGetsAndSets, HasAugmentedInstance;

protected $handle;
protected $title;
Expand All @@ -39,6 +40,11 @@ class Form implements Arrayable, Augmentable, FormContract
protected $afterSaveCallbacks = [];
protected $withEvents = true;

public function __construct()
{
$this->data = collect();
}

/**
* Get or set the handle.
*
Expand Down Expand Up @@ -184,7 +190,7 @@ public function save()
}
}

$data = collect([
$data = $this->data->merge(collect([
'title' => $this->title,
'honeypot' => $this->honeypot,
'email' => collect(isset($this->email['to']) ? [$this->email] : $this->email)->map(function ($email) {
Expand All @@ -194,7 +200,7 @@ public function save()
return Arr::removeNullValues($email);
})->all(),
'metrics' => $this->metrics,
])->filter()->all();
]))->filter()->all();

if ($this->store === false) {
$data['store'] = false;
Expand Down Expand Up @@ -234,14 +240,20 @@ public function delete()
*/
public function hydrate()
{
collect(YAML::parse(File::get($this->path())))
->filter(function ($value, $property) {
return in_array($property, [
'title',
'honeypot',
'store',
'email',
]);
$contents = YAML::parse(File::get($this->path()));

$methods = [
'title',
'honeypot',
'store',
'email',
];

$this->merge(collect($contents)->except($methods));

collect($contents)
->filter(function ($value, $property) use ($methods) {
return in_array($property, $methods);
})
->each(function ($value, $property) {
$this->{$property}($value);
Expand Down
34 changes: 34 additions & 0 deletions src/Forms/FormRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@
use Statamic\Facades\File;
use Statamic\Facades\Folder;
use Statamic\Forms\Exporters\ExporterRepository;
use Statamic\Support\Arr;
use Statamic\Support\Str;

class FormRepository implements Contract
{
private $configs = [];
private $redirects = [];

/**
Expand Down Expand Up @@ -70,6 +73,37 @@ public function make($handle = null)
return $form;
}

public function appendConfigFields($handles, string $display, array $fields)
{
$this->configs[] = [
'display' => $display,
'handles' => Arr::wrap($handles),
'fields' => $fields,
];
}

public function getConfigFor($handle)
{
$reserved = ['title', 'honeypot', 'store', 'email'];

return collect($this->configs)
->filter(function ($config) use ($handle) {
return in_array('*', $config['handles']) || in_array($handle, $config['handles']);
})
->flatMap(function ($config) use ($reserved) {

return [
Str::slugify($config['display']) => [
'display' => $config['display'],
'fields' => collect($config['fields'])
->filter(fn ($field, $index) => ! in_array($field['handle'] ?? $index, $reserved))
->all(),
],
];
})
->all();
}

public function redirect(string $form, Closure $callback)
{
$this->redirects[$form] = $callback;
Expand Down
17 changes: 12 additions & 5 deletions src/Http/Controllers/CP/Forms/FormsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -139,13 +139,13 @@ public function edit($form)
{
$this->authorize('edit', $form);

$values = [
$values = array_merge($form->data()->all(), [
'handle' => $form->handle(),
'title' => $form->title(),
'honeypot' => $form->honeypot(),
'store' => $form->store(),
'email' => $form->email(),
];
]);

$fields = ($blueprint = $this->editFormBlueprint($form))
->fields()
Expand All @@ -170,11 +170,14 @@ public function update($form, Request $request)

$values = $fields->process()->values()->all();

$data = collect($values)->except(['title', 'honeypot', 'store', 'email']);

$form
->title($values['title'])
->honeypot($values['honeypot'])
->store($values['store'])
->email($values['email']);
->email($values['email'])
->merge($data);

$form->save();

Expand All @@ -190,7 +193,7 @@ public function destroy($form)

protected function editFormBlueprint($form)
{
return Blueprint::makeFromTabs([
$fields = array_merge([
'name' => [
'display' => __('Name'),
'fields' => [
Expand Down Expand Up @@ -312,6 +315,10 @@ protected function editFormBlueprint($form)
],

// metrics
]);
// ...

], Form::getConfigFor($form->handle()));

return Blueprint::makeFromTabs($fields);
}
}
33 changes: 33 additions & 0 deletions tests/Feature/Forms/UpdateFormTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,39 @@ public function it_updates_emails()
], $updated->email());
}

/** @test */
public function it_updates_data()
{
$form = tap(Form::make('test'))->save();
$this->assertNull($form->email());

Form::appendConfigFields('*', 'Test Config', [
'another_config' => [
'handle' => 'another_config',
'field' => [
'type' => 'text',
],
],
'some_config' => [
'handle' => 'some_config',
'field' => [
'type' => 'text',
],
],
]);

$this
->actingAs($this->userWithPermission())
->update($form, ['some_config' => 'foo', 'another_config' => 'bar'])
->assertOk();

$updated = Form::all()->first();
$this->assertEquals([
'another_config' => 'bar',
'some_config' => 'foo',
], $updated->data()->all());
}

private function userWithoutPermission()
{
$this->setTestRoles(['test' => ['access cp']]);
Expand Down
53 changes: 53 additions & 0 deletions tests/Forms/FormRepositoryTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

namespace Tests\Forms;

use Statamic\Facades\Form;
use Tests\TestCase;

class FormRepositoryTest extends TestCase
{
/** @test */
public function it_registers_config()
{
Form::appendConfigFields('test_form', 'Test Config', [
'another_config' => [
'handle' => 'another_config',
'field' => [
'type' => 'text',
],
],
'some_config' => [
'handle' => 'some_config',
'field' => [
'type' => 'text',
],
],
]);

$this->assertNotNull(Form::getConfigFor('test_form'));
$this->assertEmpty(Form::getConfigFor('another_form'));
}

/** @test */
public function it_registers_wildcard_config()
{
Form::appendConfigFields('*', 'Test Config', [
'another_config' => [
'handle' => 'another_config',
'field' => [
'type' => 'text',
],
],
'some_config' => [
'handle' => 'some_config',
'field' => [
'type' => 'text',
],
],
]);

$this->assertNotNull(Form::getConfigFor('test_form'));
$this->assertNotNull(Form::getConfigFor('another_form'));
}
}
10 changes: 9 additions & 1 deletion tests/Forms/FormTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,21 @@ public function it_saves_a_form()

$form = Form::make('contact_us')
->title('Contact Us')
->honeypot('winnie');
->honeypot('winnie')
->data([
'foo' => 'bar',
'roo' => 'rar',
]);

$form->save();

$this->assertEquals('contact_us', $form->handle());
$this->assertEquals('Contact Us', $form->title());
$this->assertEquals('winnie', $form->honeypot());
$this->assertEquals([
'foo' => 'bar',
'roo' => 'rar',
], $form->data()->all());

Event::assertDispatched(FormCreating::class, function ($event) use ($form) {
return $event->form === $form;
Expand Down