HI. I tried to update a document of MongoDB I use the Doctrine Module for Laminas and I follow this example in the Doctrine module documentation A Complete Example using Laminas\Form - Doctrine Doctrine Laminas Hydrators.
When I tried to update the document with embed subdocuments the validation failed, It works fine when I create a new document.
This is my updated code method:
public function updateAccountWithForm(string $vendorAccountId, array $data): array
{
$form = new UpdateAccountForm($this->dm);
$account = $this->dm->getRepository(Account::class)->findOneBy(['vendorAccountId' => $vendorAccountId]);
if (is_null($account)) {
return [
'message' => 'Vendor Account is not found',
'statusCode' => 411,
];
}
$form->bind($account);
$form->setData($data);
if ($form->isValid()) {
try {
$this->dm->flush();
error_log("[" . __LINE__ . "]:" . __CLASS__ . ", account updated:");
$response['status'] = true;
$response['vendorAccountId'] = $vendorAccountId;
$response['companyName'] = $account->getCompany()->getCompanyName();
} catch (MongoDBException $e) {
error_log("[" . __LINE__ . "]:" . __CLASS__
. ", account error form:" . $e->getMessage()
);
$response['errorMessage'] = $e->getMessage();
}
} else {
$data = $form->getData();
print_r(['error'=> $data]);
$messages = $form->getMessages();
error_log("[" . __LINE__ . "]:" . __CLASS__ . ", invalid form:");
$response['statusCode'] = 400;
$response['errorMessage'] = 'validation error';
$response['errors'] = $messages;
}
return $response;
}
When I populate the form with de existing values ($account) with bind()
this works fine but when I do setData
all data is missed and I only have the data that I set with setData
.
My UpdateAccountForm.php
class UpdateAccountForm extends Form
{
public function __construct(DocumentManager $dm)
{
parent::__construct('update-account-form');
$this->setHydrator(new DoctrineHydrator($dm));
$accountFieldset = new AccountFieldset($dm);
$accountFieldset->setUseAsBaseFieldset(true);
$this->add($accountFieldset);
}
}
AccountFieldset.php
class AccountFieldset extends Fieldset implements InputFilterProviderInterface
{
public function __construct(DocumentManager $dm)
{
parent::__construct('account');
$this->setHydrator(new DoctrineHydrator($dm))
->setObject(new Account());
$company = new CompanyFieldset($dm);
$company->setName('company');
$this->add($company);
$this->add([
'type' => Text::class,
'name' => 'realm',
]);
$this->add([
'type' => Text::class,
'name' => 'domain',
]);
}
public function getInputFilterSpecification(): array
{
return [
"realm" => ['required' => false],
"domain" => ['required' => false],
];
}
}
CompanyFieldset.php
class CompanyFieldset extends Fieldset implements InputFilterProviderInterface
{
public function __construct(DocumentManager $dm)
{
parent::__construct('company');
$this->setHydrator(new DoctrineHydrator($dm))
->setObject(new Company());
$this->add([
'type' => Text::class,
'name' => 'companyId',
]);
$this->add([
'type' => Text::class,
'name' => 'companyVersion',
]);
$this->add([
'type' => Text::class,
'name' => 'companyName',
]);
$address = new AddressLocationFieldset($dm);
$address->setName('address');
$this->add($address);
$this->add([
'type' => Email::class,
'name' => 'emailAddress',
]);
$this->add([
'type' => Text::class,
'name' => 'phoneNumber',
]);
$this->add([
'type' => Url::class,
'name' => 'websiteUrl',
]);
$this->add([
'type' => Text::class,
'name' => 'creationDate',
]);
}
public function getInputFilterSpecification(): array
{
return [
"companyId" => ['required' => true],
"companyVersion" => ['required' => true],
"companyName" => ['required' => true],
"emailAddress" => ['required' => false],
"phoneNumber" => ['required' => false],
"websiteUrl" => ['required' => false],
"creationDate" => ['required' => false],
];
}
}
I found this in the documentation:
This said:
One such change is that if a collection is found in a form, but has no associated data, an empty array is assigned to it, even when not in the validation group. This effectively wipes out the collection data when you bind values.
Currently, I have a validation group in createForm.
Example: I want to edit only the field then I send the field.
[account] => Array
(
[company] => Array
(
[companyId] => bcos1.company.0e68afc9-9f53-3ee4-a94f-2cf7b8e1701c
[companyVersion] => 2
)
)
But I have an error with the validation because in the company the required fields are: companyId
, companyVersion
, and companyName
; and I send only two required fields but the other one is in the current entity.
The data when I use the bind method ($account):
Array
(
[account] => Array
(
[id] => 62795cc9dcb19701ea757442
[vendorAccountId] => vendor-account-id-62795cc9227b0
[company] => Array
(
[companyId] => bcos1.company.5c966432-1a56-37fb-846c-8de8157470e9
[companyVersion] => 1
[companyName] => Sporer Group
[address] => Array
(
[streetAddress] => 70110 Stokes Locks Apt. 369
[city] => Kochchester
[region] => Delaware
[country] => US
[postalCode] => 75178-6851
[storeName] => Brekke LLC PLC
[coordinates] => Array
(
[latitude] => 45.99282
[longitude] => 45.99282
)
)
[emailAddress] => clifton.hoppe@turner.com
[phoneNumber] => (729) 995-0270
[websiteUrl] => http://hahn.com/iste-repellat-sunt-voluptates-sit
[creationDate] => DateTime Object
(
[date] => 2022-05-09 18:26:17.000000
[timezone_type] => 3
[timezone] => UTC
)
)
[realm] => NAA
[domain] => beta
[status] => PENDING
[createdAt] => DateTime Object
(
[date] => 2022-05-09 18:26:17.141000
[timezone_type] => 3
[timezone] => UTC
)
)
)
How I fix this and that pass the validation?
Sorry for the long post and thank you in advance for your help.