developer.jelix.org n'est plus utilisée, et existe uniquement pour son historique. Postez les nouveaux tickets sur le compte github.
Opened 13 years ago
Closed 13 years ago
#323 closed enhancement (fixed)
jForms : added a new datasource based on a class
Reported by: | laurentj | Owned by: | |
---|---|---|---|
Priority: | normal | Milestone: | Jelix 1.0 RC1 |
Component: | jelix:forms | Version: | 1.0 beta 3.1 |
Severity: | normal | Keywords: | |
Cc: | Blocked By: | ||
Blocking: | Documentation needed: | ||
Hosting Provider: | Php version: |
Description (last modified by laurentj)
We could define a datasource based on a class :
<menulist dsclass="mymodule~myclass">
Then you can create a class which should implements a new interface, jIDatasourceClass
interface jIDatasourceClass { function getDatas(); }
The class in mymodule/classes/myclass.class.php :
class myclass implements jIDatasourceClass { function getDatas(){ return array('value1'=>'label1', 'value2'=>'label2',...); }
Why an interface and why not an attribute to indicates a specific method ? because to avoid an untrusted jforms file to call anything.
Attachments (2)
Change History (11)
comment:1 Changed 13 years ago by laurentj
- Description modified (diff)
comment:2 Changed 13 years ago by laurentj
- Milestone set to Jelix 1.0 RC1
- Owner set to laurentj
- Status changed from new to assigned
comment:3 Changed 13 years ago by laurentj
- Milestone changed from Jelix 1.0 RC1 to Jelix 1.1
- Owner laurentj deleted
- Status changed from assigned to new
comment:4 Changed 13 years ago by Uriel C
Changed 13 years ago by Uriel C
comment:5 Changed 13 years ago by Uriel C
J'attache un patch qui implémente une version légèrement différente de ce ticket.
Les classes métier dérivent directement de jIFormDatasource. On peut y adjoindre un constructeur, qui prend en paramètre l'id du formulaire.
Exemple de classe :
class listDatas implements jIFormDatasource { protected $formId = 0; protected $datas = array(); function __construct($id) { $this->formId = $id; $this->datas = array(0 => 'test', 1 => 'test 2', 2 => 'Id = '. $id); } public function getDatas() { return ($this->datas); } public function getLabel($key) { if(isset($this->datas[$key])) return $this->datas[$key]; else return null; } }
et le contrôle jForm correspondant :
<menulist ref="icone" dsclass="monmodule~listDatas"> <label locale="elements.crud.label.icone" /> </menulist>
Avec cette solution le patch est bien plus court, moins de 10 lignes, et les classes sont simples à construire.
comment:6 Changed 13 years ago by laurentj
- Milestone changed from Jelix 1.1 to Jelix 1.0 RC1
Oui, c'est bien plus simple effectivement :-) Peut être faudrait-il ajouter un test (instanceof avant d'assigner l'objet à la propriété datasource) pour savoir si la classe en question implémente bien jIFormDatasource. Cela serait une protection pour éviter d'appeler n'importe quelle classe quand le fichier jforms est uploadé par un utilisateur dans une appli CMS par ex.
Changed 13 years ago by Uriel C
Version sécurisée qui fait un instanceof jIFormDatasource avant d'assigner la datasource
comment:7 Changed 13 years ago by Uriel C
Précision avant que j'oublie : cette version modifiée fait la vérification au runtime et pas à la compilation, des fois qu'une classe serait modifiée entre temps.
Le code compilé en est un peu plus lourd mais rien de dramatique.
comment:8 Changed 13 years ago by laurentj
Oui, c'est mieux de le faire au runtime.
comment:9 Changed 13 years ago by laurentj
- Resolution set to fixed
- Status changed from new to closed
Patch landed in the trunk. Thanks for this patch !
Je pense que getDatas() pourrait prendre en paramètre $id l'identifiant du record que l'on modifie, ou null en cas de création d'un nouvel enregistrement. Ca permettrait de ne pas toujours retourner les mêmes valeurs lorsque c'est nécessaire.