Skip to content

Commit 694a6f8

Browse files
author
Mike van den Hoek
committed
(feat): implement support for multiple suppliers
1 parent 1b89217 commit 694a6f8

14 files changed

Lines changed: 541 additions & 264 deletions

config/suppliers.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
return [
4+
'openzaak' => 'OpenZaak',
5+
'decos-join' => 'DecosJoin',
6+
'enable-u' => 'EnableU'
7+
];
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<script type="text/javascript">
2+
jQuery(document).on('gform_post_render', function(){
3+
jQuery('.owc_prefilled input').attr('readonly','readonly');
4+
});
5+
</script>
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
/**
3+
* Select element for custom field
4+
*/
5+
?>
6+
<li class="label_setting field_setting">
7+
<label for="linkedField" class="section_label">
8+
<?php _e('Automatisch invullen', 'prefill-gravity-forms'); ?>
9+
</label>
10+
<select id="linkedField" onchange="SetFieldProperty('linkedFieldValue', this.value);">
11+
<option value=""><?php _e('Kies veldnaam', 'prefill-gravity-forms'); ?></option>
12+
<option value="burgerservicenummer"><?php _e('Burgerservicenummer', 'prefill-gravity-forms'); ?></option>
13+
<option value="aNummer"><?php _e('aNummer', 'prefill-gravity-forms'); ?></option>
14+
<option value="geslachtsaanduiding"><?php _e('Geslachtsaanduiding', 'prefill-gravity-forms'); ?></option>
15+
<option value="leeftijd"><?php _e('Leeftijd', 'prefill-gravity-forms'); ?></option>
16+
<optgroup label="Naam">
17+
<option value="naam.geslachtsnaam"><?php _e('Geslachtsnaam', 'prefill-gravity-forms'); ?></option>
18+
<option value="naam.voorletters"><?php _e('Voorletters', 'prefill-gravity-forms'); ?></option>
19+
<option value="naam.voornamen"><?php _e('Voornamen', 'prefill-gravity-forms'); ?></option>
20+
<option value="naam.voorvoegsel"><?php _e('Voorvoegsel', 'prefill-gravity-forms'); ?></option>
21+
<option value="naam.aanschrijfwijze"><?php _e('Aanschrijfwijze', 'prefill-gravity-forms'); ?></option>
22+
<option value="naam.aanduidingNaamgebruik"><?php _e('AanduidingNaamgebruik', 'prefill-gravity-forms'); ?></option>
23+
</optgroup>
24+
<optgroup label="Nationaliteiten">
25+
<option value="nationaliteiten.datumIngangGeldigheid.datum"><?php _e('Datum', 'prefill-gravity-forms'); ?></option>
26+
<option value="nationaliteiten.datumIngangGeldigheid.jaar"><?php _e('Jaar', 'prefill-gravity-forms'); ?></option>
27+
<option value="nationaliteiten.datumIngangGeldigheid.maand"><?php _e('Maand', 'prefill-gravity-forms'); ?></option>
28+
<option value="nationaliteiten.datumIngangGeldigheid.dag"><?php _e('Dag', 'prefill-gravity-forms'); ?></option>
29+
<option value="nationaliteiten.nationaliteit.omschrijving"><?php _e('Omschrijving', 'prefill-gravity-forms'); ?></option>
30+
<option value="nationaliteiten.nationaliteit.code"><?php _e('Code', 'prefill-gravity-forms'); ?></option>
31+
</optgroup>
32+
<optgroup label="Geboorte">
33+
<option value="geboorte.datum.datum"><?php _e('Geboortedatum', 'prefill-gravity-forms'); ?></option>
34+
<option value="geboorte.land.omschrijving"><?php _e('Geboorteland', 'prefill-gravity-forms'); ?></option>
35+
<option value="geboorte.plaats.omschrijving"><?php _e('Geboorteplaats', 'prefill-gravity-forms'); ?></option>
36+
</optgroup>
37+
<optgroup label="Verblijftplaats">
38+
<option value="verblijfplaats.straatnaam"><?php _e('Straat', 'prefill-gravity-forms'); ?></option>
39+
<option value="verblijfplaats.huisnummer"><?php _e('Huisnummer', 'prefill-gravity-forms'); ?></option>
40+
<option value="verblijfplaats.huisletter"><?php _e('Huisletter', 'prefill-gravity-forms'); ?></option>
41+
<option value="verblijfplaats.postcode"><?php _e('Postcode', 'prefill-gravity-forms'); ?></option>
42+
<option value="verblijfplaats.woonplaats"><?php _e('Woonplaats', 'prefill-gravity-forms'); ?></option>
43+
<option value="verblijfplaats.adresregel1"><?php _e('Adres', 'prefill-gravity-forms'); ?></option>
44+
<option value="verblijfplaats.adresregel2"><?php _e('Postcode + plaats', 'prefill-gravity-forms'); ?></option>
45+
</optgroup>
46+
<optgroup label="Huwelijk/Partnerschap-gegevens">
47+
<option value="_embedded.partners.soortVerbintenis"><?php _e('Soort verbintenis', 'prefill-gravity-forms'); ?></option>
48+
<option value="_embedded.partners.naam.geslachtsnaam"><?php _e('Geslachtsnaam', 'prefill-gravity-forms'); ?></option>
49+
<option value="_embedded.partners.naam.voornamen"><?php _e('Voornamen', 'prefill-gravity-forms'); ?></option>
50+
</optgroup>
51+
</select>
52+
</li>

views/select.php renamed to resources/views/partials/gf-field-options-openzaak.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
<li class="label_setting field_setting">
77
<label for="linkedField" class="section_label">
88
<?php _e('Automatisch invullen', 'prefill-gravity-forms'); ?>
9-
<?php gform_tooltip('caseCategoryToolTip'); ?>
109
</label>
1110
<select id="linkedField" onchange="SetFieldProperty('linkedFieldValue', this.value);">
1211
<option value=""><?php _e('Kies veldnaam', 'prefill-gravity-forms'); ?></option>
Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
<?php
2+
3+
namespace OWC\PrefillGravityForms\Controllers;
4+
5+
use function OWC\PrefillGravityForms\Foundation\Helpers\view;
6+
use function Yard\DigiD\Foundation\Helpers\decrypt;
7+
use function Yard\DigiD\Foundation\Helpers\resolve;
8+
use OWC\PrefillGravityForms\Foundation\TeamsLogger;
9+
use OWC\PrefillGravityForms\GravityForms\GravityFormsSettings;
10+
11+
abstract class BaseController
12+
{
13+
protected GravityFormsSettings $settings;
14+
protected TeamsLogger $teams;
15+
protected string $supplier;
16+
17+
public function __construct()
18+
{
19+
$this->settings = GravityFormsSettings::make();
20+
$this->teams = $this->resolveTeams();
21+
}
22+
23+
public function resolveTeams(): TeamsLogger
24+
{
25+
try {
26+
if (! function_exists('Yard\DigiD\Foundation\Helpers\resolve')) {
27+
throw new \Exception;
28+
}
29+
30+
return TeamsLogger::make(resolve('teams'));
31+
} catch (\Exception $e) {
32+
return TeamsLogger::make(new \Psr\Log\NullLogger());
33+
}
34+
}
35+
36+
/**
37+
* Validate if form has a DigiD field.
38+
* If so return the decrypted BSN number.
39+
*/
40+
protected function getBSN(array $form): string
41+
{
42+
$bsn = '';
43+
44+
foreach ($form['fields'] as $field) {
45+
if ($field->type !== 'digid') {
46+
continue;
47+
}
48+
49+
$resolvedBSN = resolve('session')->getSegment('digid')->get('bsn');
50+
51+
if (empty($resolvedBSN)) {
52+
continue;
53+
}
54+
55+
$bsn = decrypt($resolvedBSN);
56+
57+
break;
58+
}
59+
60+
return $bsn;
61+
}
62+
63+
/**
64+
* BSN numbers could start with one or more zero's at the beginning.
65+
* The zero's are not returned by DigiD so the required length of 9 characters is not met.
66+
* Supplement the value so it meets the required length of 9.
67+
*/
68+
protected function supplementBSN(string $bsn): string
69+
{
70+
$bsnLength = strlen($bsn);
71+
$requiredLength = 9;
72+
$difference = $requiredLength - $bsnLength;
73+
74+
if ($difference < 1 || $difference > $requiredLength) {
75+
return $bsn;
76+
}
77+
78+
return sprintf("%'.0" . $requiredLength . "d", $bsn);
79+
}
80+
81+
protected function preFillFields(array $form, array $response): array
82+
{
83+
foreach ($form['fields'] as $field) {
84+
$linkedValue = $field->linkedFieldValue ?? '';
85+
$foundValue = $this->findLinkedValue($linkedValue, $response);
86+
87+
if (empty($foundValue)) {
88+
continue;
89+
}
90+
91+
if ($field->type === 'text') {
92+
$field->defaultValue = ucfirst($foundValue);
93+
$field->cssClass = 'owc_prefilled';
94+
}
95+
96+
if ($field->type === 'date') {
97+
$field->defaultValue = (new \DateTime($foundValue))->format('d-m-Y');
98+
$field->displayOnly = true;
99+
$field->cssClass = 'owc_prefilled';
100+
}
101+
}
102+
103+
return $form;
104+
}
105+
106+
public function findLinkedValue(string $linkedValue = '', array $response = []): string
107+
{
108+
if (empty($linkedValue) || empty($response)) {
109+
return $linkedValue;
110+
}
111+
112+
return $this->explodeDotNotationValue($linkedValue, $response);
113+
}
114+
115+
/**
116+
* Explode string in to array items.
117+
* Use these array items to retrieve nested array values from the response.
118+
*/
119+
public function explodeDotNotationValue(string $dotNotationString, array $response): string
120+
{
121+
$exploded = explode('.', $dotNotationString);
122+
$holder = [];
123+
124+
foreach ($exploded as $key => $item) {
125+
if ($key === 0) {
126+
// Place the wanted part of the response in $holder.
127+
$holder = $response[$item] ?? '';
128+
continue;
129+
}
130+
131+
// If $holder is empty there is no need to proceed.
132+
if (empty($holder)) {
133+
break;
134+
}
135+
136+
// If holder is a multidimensional array, unflatten.
137+
if (!empty($holder[0]) && is_array($holder[0])) {
138+
$holder = $this->unflattenHolderArray($holder);
139+
}
140+
141+
// Place the nested part of the response in $holder.
142+
$holder = $holder[$item] ?? '';
143+
}
144+
145+
return is_string($holder) || is_numeric($holder) ? $holder : '';
146+
}
147+
148+
protected function unflattenHolderArray(array $holder): array
149+
{
150+
$backupHolder = [];
151+
152+
foreach ($holder as $part) {
153+
$backupHolder = array_merge($backupHolder, $part);
154+
}
155+
156+
return $backupHolder;
157+
}
158+
159+
public function getRequestURL(string $identifier = '', string $expand = ''): string
160+
{
161+
$baseURL = $this->settings->getBaseURL();
162+
163+
if (empty($baseURL) || empty($identifier)) {
164+
return '';
165+
}
166+
167+
$url = sprintf('%s/%s', $baseURL, $identifier);
168+
169+
if (! empty($expand)) {
170+
$url = sprintf('%s?%s', $url, $this->createExpandArguments($expand));
171+
}
172+
173+
return $url;
174+
}
175+
176+
protected function createExpandArguments(string $expand): string
177+
{
178+
$exploded = explode(',', $expand);
179+
$filtered = array_filter($exploded);
180+
$new = array_map('trim', $filtered);
181+
$imploded = implode(',', $new);
182+
183+
return urldecode(http_build_query(['expand' => $imploded], '', ','));
184+
}
185+
186+
protected function getCurlHeaders(string $doelBinding = ''): array
187+
{
188+
$headers = [
189+
'x-doelbinding: ' . $doelBinding,
190+
'x-origin-oin: ' . $this->settings->getNumberOIN()
191+
];
192+
193+
return array_filter($headers);
194+
}
195+
196+
protected function handleCurl(array $args): array
197+
{
198+
try {
199+
$curl = curl_init();
200+
201+
curl_setopt_array($curl, $this->getDefaultCurlArgs() + $args);
202+
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
203+
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
204+
205+
$output = curl_exec($curl);
206+
207+
if (curl_error($curl)) {
208+
throw new \Exception(curl_error($curl));
209+
}
210+
211+
$decoded = json_decode($output, true);
212+
213+
if (! $decoded || json_last_error() !== JSON_ERROR_NONE) {
214+
throw new \Exception('Something went wrong with decoding of the JSON output.');
215+
}
216+
217+
return $decoded;
218+
} catch (\Exception $e) {
219+
return [
220+
'status' => $e->getMessage()
221+
];
222+
}
223+
}
224+
225+
protected function getDefaultCurlArgs(): array
226+
{
227+
return [
228+
CURLOPT_RETURNTRANSFER => true,
229+
CURLOPT_ENCODING => '',
230+
CURLOPT_MAXREDIRS => 10,
231+
CURLOPT_TIMEOUT => 0,
232+
CURLOPT_FOLLOWLOCATION => true,
233+
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
234+
CURLOPT_CUSTOMREQUEST => 'GET',
235+
];
236+
}
237+
238+
/**
239+
* Prefilled fields have a custom css class
240+
* Based on this custom class fields are disabled.
241+
*/
242+
protected function disableFormFields(): string
243+
{
244+
return view('disabledFormFields.php');
245+
}
246+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
3+
namespace OWC\PrefillGravityForms\Controllers;
4+
5+
class EnableUController extends BaseController
6+
{
7+
public function handle(array $form)
8+
{
9+
$bsn = $this->getBSN($form);
10+
// $bsn = '999995078';
11+
12+
if (empty($bsn)) {
13+
return $form;
14+
}
15+
16+
$bsn = $this->supplementBSN($bsn);
17+
18+
if (strlen($bsn) !== 9) {
19+
$this->teams->addRecord('error', 'BSN', [
20+
'message' => 'BSN does not meet the required length of 9.'
21+
]);
22+
23+
return $form;
24+
}
25+
26+
$doelBinding = rgar($form, 'owc-iconnect-doelbinding', '');
27+
$expand = rgar($form, 'owc-iconnect-expand', '');
28+
29+
if (! is_string($doelBinding)) {
30+
$doelBinding = (string) $doelBinding;
31+
}
32+
33+
$response = $this->request($bsn, $doelBinding, $expand);
34+
35+
if (isset($response['status'])) {
36+
$this->teams->addRecord('error', 'Prefill data', [
37+
'message' => 'Retrieving prefill data failed.',
38+
'status' => $response['status']
39+
]);
40+
return $form;
41+
}
42+
43+
echo $this->disableFormFields();
44+
45+
return $this->preFillFields($form, $response);
46+
}
47+
48+
protected function request(string $bsn = '', string $doelBinding = '', string $expand = ''): array
49+
{
50+
$curlArgs = [
51+
CURLOPT_URL => $this->getRequestURL($bsn, $expand),
52+
CURLOPT_HTTPHEADER => $this->getCurlHeaders($doelBinding),
53+
];
54+
55+
return $this->handleCurl($curlArgs);
56+
}
57+
}

0 commit comments

Comments
 (0)