Skip to content

Commit

Permalink
Merge pull request #242 from umanit/feature_form_options
Browse files Browse the repository at this point in the history
Add form options feature
  • Loading branch information
rossriley committed May 20, 2018
2 parents c8f86ad + 18b1506 commit b6b8d21
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 2 deletions.
51 changes: 51 additions & 0 deletions docs/form-options.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
Setting-up Form options
=======================

Should you want to set up your Form's global options, you can specify
them by setting the `options` key to it.

This is useful for custom validation on the whole form, e.g: say you want to
make sure your end-user only fills-in **one** out of two fields, you can define a
Callback validator like so:

```yaml
# app/config/extensions/boltforms.bolt.yml
options:
constraints:
- { Callback: { callback: [ 'Bundle\App\Form\Validator\FormValidator', 'validate'] } }
```

Then create the validator class.

```php
<?php

namespace Bundle\App\Form\Validator;

use Bolt\Extension\Bolt\BoltForms\Form\Entity\Content;
use Symfony\Component\Validator\Context\ExecutionContextInterface;

class FormValidator
{
/**
* Validates that either "adherent_structure" or "other_structure" is filled-in but not both.
*
* @param Content|mixed $object
* @param ExecutionContextInterface $context
*/
public function validate($object, ExecutionContextInterface $context)
{
if (true !== (null === $object->get('adherent_structure') xor null === $object->get('other_structure'))) {
$context
->buildViolation('You must fill-in one structure only.')
->addViolation()
;
}
}

}
```

Any option available from `FormType field can be defined.
See [Symfony's doc](https://symfony.com/doc/current/reference/forms/types/form.html)
for more information.
1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ BoltForms Documentation
- [Email Notifications](email.md)
- [Submission & Redirection](submission.md)
- [Saving to a contenttype or a database](saving-to-contenttype-database.md)
- [Setting-up Form options](form-options.md)
- [Events](events.md)
- [Recaptcha](recaptcha.md)
- [Upgrading](upgrading.md)
13 changes: 11 additions & 2 deletions src/BoltForms.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,12 @@ public function create($formName, $type = BoltFormType::class, $data = null, $op

$this->resolveFormConfiguration($formName);

/** @var FormBuilderInterface $builder */
$builder = $this->createFormBuilder($formName, $type, $data, $options);
/** @var Config\FormConfig $formConfig */
$formConfig = $this->config->getForm($formName);
// Merge options with the resolved, default ones
$options += $formConfig->getOptions()->all();
/** @var FormBuilderInterface $builder */
$builder = $this->createFormBuilder($formName, $type, $data, $options);
foreach ($formConfig->getFields()->all() as $key => $field) {
$builder->add($key, $this->getTypeClassName($field['type']), $field['options']);
}
Expand Down Expand Up @@ -303,6 +305,7 @@ private function resolveFormConfiguration($formName)
// Field option resolver factory
$resolverFactory = $this->app['boltforms.form.field_options.factory'];

// Resolve fields' options
foreach ($formConfig['fields'] as $fieldName => $data) {
$this->config->assetValidField($formName, $fieldName, $data);
$formConfig['fields'][$fieldName]['options'] = $resolverFactory(
Expand All @@ -311,6 +314,12 @@ private function resolveFormConfiguration($formName)
);
}

// Now, resolve global form's options
$formConfig['options'] = $resolverFactory(
BoltForms::class,
isset($formConfig['options']) ? (array) $formConfig['options'] : []
);

$resolvedFormConfig = new FormConfig($formName, $formConfig, $this->config);
$this->config->setResolvedFormConfig($formName, $resolvedFormConfig);
}
Expand Down
74 changes: 74 additions & 0 deletions src/Config/Form/FormOptionsBag.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php

namespace Bolt\Extension\Bolt\BoltForms\Config\Form;

use Symfony\Component\HttpFoundation\ParameterBag;

/**
* Form options configuration for BoltForms
*
* Copyright (c) 2014-2016 Gawain Lynch
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License or GNU Lesser
* General Public License as published by the Free Software Foundation,
* either version 3 of the Licenses, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @author Arthur Guigand <arthur@guigand.com>
* @license http://opensource.org/licenses/GPL-3.0 GNU Public License 3.0
* @license http://opensource.org/licenses/LGPL-3.0 GNU Lesser General Public License 3.0
*/
class FormOptionsBag extends ParameterBag
{
/**
* Constructor.
*
* @param array $parameters
*/
public function __construct(array $parameters)
{
foreach ($parameters as $key => $value) {
if (is_array($value)) {
$value = new ParameterBag($value);
}
$parameters[$key] = $value;
}

parent::__construct($parameters);
}

/**
* {@inheritdoc}
*/
public function all()
{
$parameters = $this->parameters;
foreach ($parameters as $key => $value) {
if ($value instanceof ParameterBag) {
$parameters[$key] = $value->all();
} else {
$parameters[$key] = $value;
}
}

return $parameters;
}

/**
* Get form's constraints.
*
* @return array
*/
public function getConstraints()
{
return $this->get('constraints');
}
}
14 changes: 14 additions & 0 deletions src/Config/FormConfig.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php

namespace Bolt\Extension\Bolt\BoltForms\Config;
use Bolt\Extension\Bolt\BoltForms\Config\Form\FormOptionsBag;

/**
* Form configuration for BoltForms
Expand Down Expand Up @@ -45,6 +46,8 @@ class FormConfig
protected $uploads;
/** @var string */
protected $formRecaptcha;
/** @var FormOptionsBag */
private $options;

/** @var Config */
private $rootConfig;
Expand All @@ -71,6 +74,7 @@ public function __construct($formName, array $formConfig, Config $rootConfig)
$this->submission = new Form\SubmissionOptionsBag($formConfig['submission']);
$this->templates = new Form\TemplateOptionsBag($formConfig['templates'], $rootConfig);
$this->uploads = new Form\UploadsOptionsBag($formConfig['uploads']);
$this->options = new Form\FormOptionsBag($formConfig['options']);
$this->formRecaptcha = $formConfig['recaptcha'] == false ? false : true;
}

Expand Down Expand Up @@ -172,6 +176,16 @@ public function getRecaptcha()
return $this->formRecaptcha;
}

/**
* Get form options.
*
* @return FormOptionsBag
*/
public function getOptions()
{
return $this->options;
}

/**
* A set of default keys for a form's config.
*
Expand Down

0 comments on commit b6b8d21

Please sign in to comment.