Overview
Comment:Implement validate_only for {{:save}}
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | dev
Files: files | file ages | folders
SHA3-256: 66b22c9173158ab418bdbda7677bb38978ade098e310b7420a55e283c63bc6a9
User & Date: bohwaz on 2023-03-15 11:24:34
Other Links: branch diff | manifest | tags
References
2023-03-24
14:03 New ticket [31f18de6a8] brindille Impossible de charger module/_header.html. artifact: e4ec292817 user: alinaar
13:05 New ticket [e4fe4245c7] brindille Les parenthèses ne fonctionnent plus dans les {{if}}. artifact: a3018f3313 user: alinaar
Context
2023-03-24
16:41
Always use string in replace modifier check-in: eedd8379c6 user: bohwaz tags: dev
12:30
Invoice module: merge dev branch check-in: d5276a5aee user: alinaar tags: invoice_module
2023-03-19
00:04
Create new branch named "blocks-editor" check-in: e6b4bfd0b6 user: bohwaz tags: blocks-editor
2023-03-15
11:24
Implement validate_only for {{:save}} check-in: 66b22c9173 user: bohwaz tags: dev
11:24
Update doc on priority of skeletons check-in: 1fa2fe5faf user: bohwaz tags: dev
Changes

Modified doc/admin/brindille_functions.md from [b5e3698b79] to [4cfdb06ea7].

324
325
326
327
328
329
330

331
332
333
334
335
336
337
Note : un appel à cette fonction depuis le code du site web provoquera une erreur, elle ne peut être appelée que depuis un module.

| Paramètre | Obligatoire ou optionnel ? | Fonction |
| :- | :- | :- |
| `key` | optionnel | Clé unique du document |
| `id` | optionnel | Numéro unique du document |
| `validate_schema` | optionnel | Fichier de schéma JSON à utiliser pour valider les données avant enregistrement |

| `assign_new_id` | optionnel | Si renseigné, le nouveau numéro unique du document sera indiqué dans cette variable. |
| … | optionnel | Autres paramètres : traités comme des valeurs à enregistrer dans le document |

Si ni `key` ni `id` ne sont indiqués, un nouveau document sera créé avec un nouveau numéro unique.

Si le document indiqué existe déjà, il sera mis à jour. Les valeurs nulles (`NULL`) seront effacées.








>







324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
Note : un appel à cette fonction depuis le code du site web provoquera une erreur, elle ne peut être appelée que depuis un module.

| Paramètre | Obligatoire ou optionnel ? | Fonction |
| :- | :- | :- |
| `key` | optionnel | Clé unique du document |
| `id` | optionnel | Numéro unique du document |
| `validate_schema` | optionnel | Fichier de schéma JSON à utiliser pour valider les données avant enregistrement |
| `validate_only` | optionnel | Liste des paramètres à valider (par exemple pour ne faire qu'une mise à jour partielle), séparés par des virgules. |
| `assign_new_id` | optionnel | Si renseigné, le nouveau numéro unique du document sera indiqué dans cette variable. |
| … | optionnel | Autres paramètres : traités comme des valeurs à enregistrer dans le document |

Si ni `key` ni `id` ne sont indiqués, un nouveau document sera créé avec un nouveau numéro unique.

Si le document indiqué existe déjà, il sera mis à jour. Les valeurs nulles (`NULL`) seront effacées.

353
354
355
356
357
358
359












360
361
362
363
364
365
366

Exemple de récupération du nouvel ID :

```
{{:save titre="Coucou !" assign_new_id="id"}}
Le document n°{{$id}} a bien été enregistré.
```













## delete

Supprime un document lié au module courant.

Note : un appel à cette fonction depuis le code du site web provoquera une erreur, elle ne peut être appelée que depuis un module.








>
>
>
>
>
>
>
>
>
>
>
>







354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379

Exemple de récupération du nouvel ID :

```
{{:save titre="Coucou !" assign_new_id="id"}}
Le document n°{{$id}} a bien été enregistré.
```

### Validation avec un schéma JSON

```
{{:save titre="Coucou" texte="Très long" validate_schema="./document.schema.json"}}
```

Pour ne valider qu'une partie du schéma, par exemple si on veut faire une mise à jour du document :

```
{{:save key="test" titre="Coucou" validate_schema="./document.schema.json" validate_only="titre"}}
```

## delete

Supprime un document lié au module courant.

Note : un appel à cette fonction depuis le code du site web provoquera une erreur, elle ne peut être appelée que depuis un module.

Modified src/include/lib/Garradin/UserTemplate/Functions.php from [9167089dcb] to [e1fd9ee79c].

104
105
106
107
108
109
110

111
112
113
114
115
116
117
118
119
			$field = null;
		}

		$key = $params['key'] ?? null;
		$id = $params['id'] ?? null;
		$assign_new_id = $params['assign_new_id'] ?? null;
		$validate = $params['validate_schema'] ?? null;


		unset($params['key'], $params['id'], $params['assign_new_id'], $params['validate_schema']);

		$db = DB::getInstance();

		if ($key == 'config') {
			$result = $db->firstColumn(sprintf('SELECT config FROM %s WHERE name = ?;', Module::TABLE), $name);
		}
		else {







>

|







104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
			$field = null;
		}

		$key = $params['key'] ?? null;
		$id = $params['id'] ?? null;
		$assign_new_id = $params['assign_new_id'] ?? null;
		$validate = $params['validate_schema'] ?? null;
		$validate_only = $params['validate_only'] ?? null;

		unset($params['key'], $params['id'], $params['assign_new_id'], $params['validate_schema'], $params['validate_only']);

		$db = DB::getInstance();

		if ($key == 'config') {
			$result = $db->firstColumn(sprintf('SELECT config FROM %s WHERE name = ?;', Module::TABLE), $name);
		}
		else {
137
138
139
140
141
142
143








144
145
146





147

148
149
150
151
152
153
154
		if ($result) {
			$result = json_decode((string) $result, true);
			$params = array_merge($result, $params);
		}

		if ($validate) {
			$schema = self::read(['file' => $validate], $tpl, $line);









			try {
				$s = JSONSchema::fromString($schema);





				$s->validate($params);

			}
			catch (\RuntimeException $e) {
				throw new Brindille_Exception(sprintf("ligne %d: impossible de valider le schéma:\n%s\n\n%s",
					$line, $e->getMessage(), json_encode($params, JSON_PRETTY_PRINT)));
			}
		}








>
>
>
>
>
>
>
>



>
>
>
>
>
|
>







138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
		if ($result) {
			$result = json_decode((string) $result, true);
			$params = array_merge($result, $params);
		}

		if ($validate) {
			$schema = self::read(['file' => $validate], $tpl, $line);

			if ($validate_only && is_string($validate_only)) {
				$validate_only = explode(',', $validate_only);
				$validate_only = array_map('trim', $validate_only);
			}
			else {
				$validate_only = null;
			}

			try {
				$s = JSONSchema::fromString($schema);

				if ($validate_only) {
					$s->validateOnly($params, $validate_only);
				}
				else {
					$s->validate($params);
				}
			}
			catch (\RuntimeException $e) {
				throw new Brindille_Exception(sprintf("ligne %d: impossible de valider le schéma:\n%s\n\n%s",
					$line, $e->getMessage(), json_encode($params, JSON_PRETTY_PRINT)));
			}
		}

Modified src/www/admin/static/doc/brindille_functions.html from [272aec7fa9] to [4ef57a6845].

64
65
66
67
68
69
70
71




72
73
74
75
76
77
78
			<li><a href="#http">http</a></li>
			<li><a href="#include">include</a></li>
			<li><a href="#captcha">captcha</a></li>
			<li><a href="#mail">mail</a>
		</ol></li>
		<li><a href="#fonctions-relatives-aux-modules">Fonctions relatives aux Modules</a>
		<ol>
			<li><a href="#save">save</a></li>




			<li><a href="#admin_header">admin_header</a></li>
			<li><a href="#admin_footer">admin_footer</a></li>
			<li><a href="#input">input</a>
			<ol>
				<li><a href="#valeur-du-champ">Valeur du champ</a></li>
				<li><a href="#types-de-champs-supportes">Types de champs supportés</a>
			</ol></li>







|
>
>
>
>







64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
			<li><a href="#http">http</a></li>
			<li><a href="#include">include</a></li>
			<li><a href="#captcha">captcha</a></li>
			<li><a href="#mail">mail</a>
		</ol></li>
		<li><a href="#fonctions-relatives-aux-modules">Fonctions relatives aux Modules</a>
		<ol>
			<li><a href="#save">save</a>
			<ol>
				<li><a href="#validation-avec-un-schema-json">Validation avec un schéma JSON</a>
			</ol></li>
			<li><a href="#delete">delete</a></li>
			<li><a href="#admin_header">admin_header</a></li>
			<li><a href="#admin_footer">admin_footer</a></li>
			<li><a href="#input">input</a>
			<ol>
				<li><a href="#valeur-du-champ">Valeur du champ</a></li>
				<li><a href="#types-de-champs-supportes">Types de champs supportés</a>
			</ol></li>
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
  &lt;dt&gt;{{:captcha html=true}}&lt;/dt&gt;
&lt;/dl&gt;
&lt;p&gt;&lt;input type="submit" name="send" value="Envoyer !" /&gt;&lt;/p&gt;
&lt;/form&gt;</code></pre>
<h1 id="fonctions-relatives-aux-modules">Fonctions relatives aux Modules</h1>
<h2 id="save">save</h2>
<p>Enregistre des données, sous la forme d'un document, dans la base de données, pour le module courant.</p>
<p>Note : un appel de cette fonction depuis le code du site web provoquera une erreur, il ne peut être appelé que depuis un module.</p>
<table>
<thead>
<tr>
<th style="text-align: left;">Paramètre</th>
<th style="text-align: left;">Obligatoire ou optionnel ?</th>
<th style="text-align: left;">Fonction</th>
</tr>







|







433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
  &lt;dt&gt;{{:captcha html=true}}&lt;/dt&gt;
&lt;/dl&gt;
&lt;p&gt;&lt;input type="submit" name="send" value="Envoyer !" /&gt;&lt;/p&gt;
&lt;/form&gt;</code></pre>
<h1 id="fonctions-relatives-aux-modules">Fonctions relatives aux Modules</h1>
<h2 id="save">save</h2>
<p>Enregistre des données, sous la forme d'un document, dans la base de données, pour le module courant.</p>
<p>Note : un appel à cette fonction depuis le code du site web provoquera une erreur, elle ne peut être appelée que depuis un module.</p>
<table>
<thead>
<tr>
<th style="text-align: left;">Paramètre</th>
<th style="text-align: left;">Obligatoire ou optionnel ?</th>
<th style="text-align: left;">Fonction</th>
</tr>
454
455
456
457
458
459
460





461
462
463
464
465
466
467
<td style="text-align: left;">Numéro unique du document</td>
</tr>
<tr>
<td style="text-align: left;"><code>validate_schema</code></td>
<td style="text-align: left;">optionnel</td>
<td style="text-align: left;">Fichier de schéma JSON à utiliser pour valider les données avant enregistrement</td>
</tr>





<tr>
<td style="text-align: left;"><code>assign_new_id</code></td>
<td style="text-align: left;">optionnel</td>
<td style="text-align: left;">Si renseigné, le nouveau numéro unique du document sera indiqué dans cette variable.</td>
</tr>
<tr>
<td style="text-align: left;">…</td>







>
>
>
>
>







458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
<td style="text-align: left;">Numéro unique du document</td>
</tr>
<tr>
<td style="text-align: left;"><code>validate_schema</code></td>
<td style="text-align: left;">optionnel</td>
<td style="text-align: left;">Fichier de schéma JSON à utiliser pour valider les données avant enregistrement</td>
</tr>
<tr>
<td style="text-align: left;"><code>validate_only</code></td>
<td style="text-align: left;">optionnel</td>
<td style="text-align: left;">Liste des paramètres à valider (par exemple pour ne faire qu'une mise à jour partielle), séparés par des virgules.</td>
</tr>
<tr>
<td style="text-align: left;"><code>assign_new_id</code></td>
<td style="text-align: left;">optionnel</td>
<td style="text-align: left;">Si renseigné, le nouveau numéro unique du document sera indiqué dans cette variable.</td>
</tr>
<tr>
<td style="text-align: left;">…</td>
476
477
478
479
480
481
482































483
484
485
486
487
488
489
<p>Enregistrera dans la base de données le document suivant sous la clé <code>facture_43</code> :</p>
<pre><code>{"nom": "Atelier mobile", "montant": 250}</code></pre>
<p>Exemple de mise à jour :</p>
<pre><code>{{:save key="facture_43" montant=300}}</code></pre>
<p>Exemple de récupération du nouvel ID :</p>
<pre><code>{{:save titre="Coucou !" assign_new_id="id"}}
Le document n°{{$id}} a bien été enregistré.</code></pre>































<h2 id="admin_header">admin_header</h2>
<p>Affiche l'entête de l'administration de l'association.</p>
<table>
<thead>
<tr>
<th style="text-align: left;">Paramètre</th>
<th style="text-align: left;">Obligatoire ou optionnel ?</th>







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
<p>Enregistrera dans la base de données le document suivant sous la clé <code>facture_43</code> :</p>
<pre><code>{"nom": "Atelier mobile", "montant": 250}</code></pre>
<p>Exemple de mise à jour :</p>
<pre><code>{{:save key="facture_43" montant=300}}</code></pre>
<p>Exemple de récupération du nouvel ID :</p>
<pre><code>{{:save titre="Coucou !" assign_new_id="id"}}
Le document n°{{$id}} a bien été enregistré.</code></pre>
<h3 id="validation-avec-un-schema-json">Validation avec un schéma JSON</h3>
<pre><code>{{:save titre="Coucou" texte="Très long" validate_schema="./document.schema.json"}}</code></pre>
<p>Pour ne valider qu'une partie du schéma, par exemple si on veut faire une mise à jour du document :</p>
<pre><code>{{:save key="test" titre="Coucou" validate_schema="./document.schema.json" validate_only="titre"}}</code></pre>
<h2 id="delete">delete</h2>
<p>Supprime un document lié au module courant.</p>
<p>Note : un appel à cette fonction depuis le code du site web provoquera une erreur, elle ne peut être appelée que depuis un module.</p>
<table>
<thead>
<tr>
<th style="text-align: left;">Paramètre</th>
<th style="text-align: left;">Obligatoire ou optionnel ?</th>
<th style="text-align: left;">Fonction</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: left;"><code>key</code></td>
<td style="text-align: left;">optionnel</td>
<td style="text-align: left;">Clé unique du document</td>
</tr>
<tr>
<td style="text-align: left;"><code>id</code></td>
<td style="text-align: left;">optionnel</td>
<td style="text-align: left;">Numéro unique du document</td>
</tr>
</tbody>
</table>
<p>Si ni <code>key</code> ni <code>id</code> ne sont indiqués, une erreur sera affichée.</p>
<p>Exemple :</p>
<pre><code>{{:delete key="facture_43"}}</code></pre>
<h2 id="admin_header">admin_header</h2>
<p>Affiche l'entête de l'administration de l'association.</p>
<table>
<thead>
<tr>
<th style="text-align: left;">Paramètre</th>
<th style="text-align: left;">Obligatoire ou optionnel ?</th>