Ticket Hash: c6975007ce667980d257b66c11e8f3e14715fe45
Title: [brindille] Impossible d'accéder dynamiquement à l'élément d'un tableau assigné
Status: Fixed Type: Bug
Severity: Important Priority: Immediate
Subsystem: Resolution: Fixed
Last Modified: 2023-02-03 15:02:43
Version Found In: 1.3.0-alpha1 [6c451e5927]
User Comments:

alinaar added on 2023-01-31 12:15:14:

Bonjour,

Contexte :

{{:assign var='my_array' foo='bye' bar='hello'}} // Construction is ok
{{:assign var='my_key' value='bar'}}  

Dysfonctionnement :
{{$my_array.$my_key}} ne fonctionne pas

Aucune des tests suivants ne fonctionnent ({{:debug}} renvoit toujours des tableau rempli de NULL) :

{{:debug test=$my_array.$my_key}}

{{:assign var='my_test' value=$my_array.$my_key}}
{{:debug test=$my_test}}

{{:assign var='my_second_test' value=$my_array[$my_key]}}
{{:debug test=$my_second_test}}

{{:assign var='another_array[foo]' value='bye'}}
{{:assign var='another_array[bar]' value='hello'}}
{{:debug test=$another_array}} // Construction is ok

{{:debug test=$another_array.$my_key}}

{{:assign var='my_third_test' value=$another_array[$my_key]}}
{{:debug test=$my_third_test}}  

Seul l'accès direct fonctionne {{$my_array.foo}} mais ici l'intérêt est de taper dynamiquement dans le tableau.


bohwaz added on 2023-02-02 03:41:55:

Il n'est pas prévu à priori de pouvoir faire ce genre de chose, le but étant de rester sur un langage assez simple, autant au niveau du parseur, que du développement.

Du coup ça serait intéressant de savoir pourquoi tu aurais besoin de ça :)


alinaar added on 2023-02-02 11:34:46:

Pour éviter toute une batterie de if et avoir un code bien lisible voici ce que je fais habituellement en PHP :

$type_labels = [
    'quotation' => 'Devis',
    'invoice' => 'Facture',
    'id' = > 'Pièce d'identité',
    'receipt' => 'Reçu',
    'internal_receipt' = > 'Reçu à garder en interne',
    'iso927588' => 'Document pour la norme ISO 927588'
];  

[...]

foreach ($documents as $document) {
	$output .= '<tr>
		<td>' . $type_labels[$document->type] . '</td>
		<td>' . $document->name . '</td>
		[...]
	</tr>';
}

Dans mon cas présent je suis dans un module donc je n'ai pas accès au PHP et ne peux donc pas créer mon tableau $type_labels en PHP et doit utiliser la fonction {{:assign}} de brindille.
L'équivalent en brindilles donnerait donc :

{{:assign var='type_labels'
    quotation='Devis'
    invoice='Facture'
    id='Pièce d'identité'
    receipt='Reçu'
    internal_receipt='Reçu à garder en interne'
    iso927588='Document pour la norme ISO 927588'
}}

[...]

{{#load}}
	<tr>
		<td>{{$type_labels.$type}}</td>
		<td>{{$name}}</td>
		[...]
	</tr>
{{/load}}  

Autre exemple, cela permettrait de faire une whitelist :

{{#load}}
	<tr>
		{{if isset($type_labels.$type)}}
		    <td>{{$type_labels.$type}}</td>
		    <td>{{$name}}</td>
		    [...]
		{{else}}
		    <td>Type non supporté pour {{$name}}. Soit les données sont corrompues, soit vous avez effectué un rétrogradage de la version du module.</td>
		{{/if}}
	</tr>
{{/load}}

alinaar added on 2023-02-02 12:37:16:

Un cas d'utilisation utile de la whitelist dans les modules :

{{#load}}
	{{if array_key_exists($type, $type_labels)}}
            {{:include file='document/'|cat:$type keep='id, key, type, name, content'}}
	{{else}}
	    <p>Type non supporté pour {{$name}}. Soit les données sont corrompues, soit vous avez effectué un rétrogradage de la version du module.</p>
	{{/if}}
{{/load}}

La whitelist, tout en restant simple en code permet d'éviter qu'un malveillant est mis en base une valeur comme ../../../../config.local.php dans le champ type du document pour se récupérer la SECRET_KEY


alinaar added on 2023-02-02 12:42:44:

Oups, cliqué trop vite.
Version complète :

Un cas d'utilisation utile de la whitelist dans les modules :

{{#load}}
	{{if array_key_exists($type, $type_labels)}}
            {{:assign type_label=$type_labels.$type}}
            {{:include file='document/'|cat:$type keep='id, key, type_label, name, content'}}
	{{else}}
	    <p>Type non supporté pour {{$name}}. Soit les données sont corrompues, soit vous avez effectué un rétrogradage de la version du module.</p>
	{{/if}}
{{/load}}

La whitelist, tout en restant simple en code permet d'éviter qu'un malveillant est mis en base une valeur comme ../../../../config.local.php dans le champ type du document pour se récupérer la SECRET_KEY


bohwaz added on 2023-02-03 14:02:43:

Je viens de rajouter un paramètre from à :assign, ça devrait résoudre le besoin :

{{:assign var="tableau[42]" value="Coucou"}}
{{:assign var="test" from="tableau.%d"|args:42}}