Skip to content

Instantly share code, notes, and snippets.

@wodCZ
Last active November 25, 2015 13:03
Show Gist options
  • Save wodCZ/4dc762aba13c8645e5f3 to your computer and use it in GitHub Desktop.
Save wodCZ/4dc762aba13c8645e5f3 to your computer and use it in GitHub Desktop.
Form: fill defaults from object

composer require symfony/property-access

method will silently set null if property is empty

<?php
namespace Libs\Forms;
use Nette\Forms\Controls;
use Nette\Utils\Strings;
use Symfony\Component\PropertyAccess\PropertyAccess;
class BaseForm extends Form
{
/**
* Tries to access entity property and set its value as related form input default value
*
* @param $entity
* @param $array ['name'] in case of same names or ['formFieldName' => 'entityFieldName'], for collection set append [] after collection field
*/
public function fillDefaultsFromObject($entity, $array)
{
$accessorBuilder = PropertyAccess::createPropertyAccessorBuilder();
$accessorBuilder->disableExceptionOnInvalidIndex();
$accessor = $accessorBuilder->getPropertyAccessor();
$innerEntityFieldName = 'id';
foreach ($array as $formFieldName => $entityFieldName) {
$array = FALSE;
if (Strings::contains($entityFieldName, '[]')) { // users[].id or users[]
$array = TRUE;
$explode = array_filter(explode('[]', $entityFieldName, 2));
list($entityFieldName, $innerEntityFieldName) = (count($explode) === 2 ? $explode : [
$explode[0],
$innerEntityFieldName,
]); // users & .id or users & id
$innerEntityFieldName = Strings::trim($innerEntityFieldName, '.');
}
$formFieldName = is_int($formFieldName) ? $entityFieldName : $formFieldName;
try {
$value = NULL;
if ($array) {
$value = array_map(function ($item) use ($innerEntityFieldName, $accessor) {
return $accessor->getValue($item, $innerEntityFieldName);
}, iterator_to_array($accessor->getValue($entity, $entityFieldName)));
} else {
$value = $accessor->getValue($entity, $entityFieldName);
}
$this->getComponent($formFieldName)->setDefaultValue($value);
} catch (\Exception $e) {
}
}
}
}
<?php
$form = new BaseForm;
$form->addText('name', 'name');
$form->addText('surname', 'surname');
$form->addSelect('user', 'user', $userList);
$form->addMultiSelect('hobbies', 'hobbies', $hobbiesList);
$form->addMultiSelect('tags', 'tags', ['lorem', 'ipsum', 'dolor']);
$form->fillDefaultsFromObject($editedEntity, [
'name', // form field name is same as entity property
'surname' => 'familyName' // form field name is different from entity property
'user' => 'user.id', // toOne access, returns $editedEntity->user->id
'hobbies[]', // collection support, returns list of ids in $editedEntity->hobbies
'tags[].title', // same as previous, but returns list of title properties
]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment