/[openfoncier]/trunk/obj/module.class.php
ViewVC logotype

Annotation of /trunk/obj/module.class.php

Parent Directory Parent Directory | Revision Log Revision Log


Revision 18407 - (hide annotations)
Thu Aug 8 16:18:08 2024 UTC (5 months, 4 weeks ago) by softime
File size: 19392 byte(s)
chore(branch): fusion de la branche d'intégration 6.6.0-develop dans le trunk

1 mbideau 17302 <?php
2    
3     /**
4     * Le namespace auxquels tous les modules doivent appartenir
5     */
6     namespace Module;
7    
8 softime 18407 use \ReflectionClass;
9 mbideau 17460 use \RuntimeException;
10     use \InvalidArgumentException;
11    
12 mbideau 17302 require_once __DIR__.'/utils.class.php';
13     use \application;
14    
15     require_once __DIR__.'/lien_module.class.php';
16     use \lien_module;
17    
18     require_once __DIR__.'/om_dbform.class.php';
19     use \om_dbform;
20    
21    
22     /**
23     * Classe (abstraite) représentant un module
24     */
25     abstract class module {
26    
27     /**
28     * Une instance du framework openmairie
29     *
30     * @var application
31     */
32     protected application $framework;
33    
34     /**
35     * Le chemin vers le répertoire contenant ce module
36     * @var string
37     */
38 mbideau 17345 public string $dir;
39 mbideau 17302
40     /**
41     * Une configuration statique
42     */
43 mbideau 17345 public array $conf = array();
44 mbideau 17302
45     /**
46     * Une liste de paramètres dynamiques
47     */
48 mbideau 17345 public array $params = array();
49 mbideau 17302
50     /**
51     * Une instance du lien avec l'objet auquel est associé ce module
52     */
53 mbideau 17345 public ?lien_module $object_link_instance = null;
54 mbideau 17302
55     /**
56     * Une instance de l'objet métier auquel est associé ce module
57     */
58 mbideau 17345 public ?om_dbform $object = null;
59 mbideau 17302
60     /**
61     * Renvoie la description du module (type libellé)
62     *
63     * @return string
64     */
65     abstract public function get_description();
66    
67     /**
68     * Installe le module.
69     *
70     * @return bool 'true' si l'installation s'est bien passée, 'false' sinon
71     */
72     abstract public function install();
73    
74     /**
75     * Désinstalle le module.
76     *
77     * @return bool 'true' si la désinstallation s'est bien passée, 'false' sinon
78     */
79     abstract public function uninstall();
80    
81     /**
82     * Créer une instance de module
83     *
84     * @param string $dir Le répertoire contenant le module
85     * @param application $framework Une instance du framework openmairie
86     * @param lien_module $object_link_instance Une instance d'objet lien
87     * @param om_dbform $object Une instance d'objet métier
88     *
89     * @return module
90     */
91 softime 18407 public function __construct(
92     string $dir,
93     application $framework,
94     ?lien_module $object_link_instance = null,
95     ?om_dbform $object = null
96     ) {
97 mbideau 17442 $this->framework = $framework;
98 softime 18407 $this->log(__METHOD__, 'object_link: '.($object_link_instance ? $object_link_instance->to_string() : 'null').
99     ', object: '.($object ? get_class($object).
100     '#'.$object->getVal($object->clePrimaire) : 'null'));
101 mbideau 17302 $this->dir = $dir;
102     $this->object_link_instance = $object_link_instance;
103     $this->object = $object;
104 softime 18407 if (! empty($this->object) && empty($this->object->getVal($this->object->clePrimaire))) {
105     $this->log(__METHOD__, "objet sans clé primaire définie (et probablement idem pour ses valeurs)");
106     }
107 mbideau 17302 $this->load_conf();
108     }
109    
110     /**
111     * Renvoie une représentation en "string" du module
112     *
113     * @return string
114     */
115     public function to_string() {
116     $str = sprintf(
117 softime 18407 '%s (link:%s, object:%s, ordre:%s)',
118 mbideau 17302 $this->get_short_name(),
119     $this->get_object_link_instance_id(),
120 softime 18407 $this->get_object_instance_id(),
121 mbideau 17302 $this->object_link_instance->getVal('ordre'));
122     return $str;
123     }
124    
125     /**
126     * Permet d'effectuer des actions lors de l'instanciation
127     *
128 softime 18407 * @param string $action L'action en cours (add, edit, delete)
129     *
130 mbideau 17302 * @return void
131     */
132 softime 18407 public function setup(string $action) {
133 mbideau 17302 $this->log(__METHOD__, 'BEGIN');
134     $this->log(__METHOD__, 'END');
135     }
136    
137     /**
138     * Charge la configuration statique
139     *
140     * @return void
141     */
142     public function load_conf() {
143     $conf_path = $this->get_conf_path();
144     if (is_file($conf_path)) {
145     $conf_path_ext = pathinfo($conf_path, PATHINFO_EXTENSION);
146     switch($conf_path_ext) {
147     case 'php':
148     $this->conf = include $conf_path;
149     break;
150     case 'ini':
151     $this->conf = parse_ini_file($conf_path);
152     break;
153     case 'json':
154     $this->conf = json_decode(
155     file_get_contents($conf_path), true,
156     512, JSON_THROW_ON_ERROR);
157     break;
158     }
159     }
160     }
161    
162     /**
163     * Renvoie le chemin vers la configuration statique du module
164     *
165     * @return string
166     */
167     protected function get_conf_path() {
168     $this->log(__METHOD__, 'BEGIN');
169     $module_name = $this->get_short_name();
170     $ret = $this->dir."/$module_name.conf.php";
171     $this->log(__METHOD__, 'return: '.var_export($ret, true));
172     $this->log(__METHOD__, 'END');
173     return $ret;
174     }
175    
176     /**
177     * Renvoie le nom court du module
178     *
179     * @return string
180     */
181     public function get_short_name() {
182     $ref = new \ReflectionClass($this);
183     return $ref->getShortName();
184     }
185    
186     /**
187     * Renvoie une URL (ou partie d'URL) pointant vers le répertoire contenant les "assets"
188     * (ressources publiques) du module
189     *
190     * @return string
191     */
192     public function get_url_assets_path_base() {
193     $this->log(__METHOD__, 'BEGIN');
194     $base_dir = $this->dir;
195     $app_dir = dirname(__DIR__);
196     if (strpos($base_dir, $app_dir) !== 0) {
197 mbideau 17460 throw new RuntimeException(
198 mbideau 17302 "Invalid module directory '$base_dir' or application directory '$app_dir'"
199     );
200     }
201     $base_url = str_replace($app_dir, '', $base_dir);
202     $url = "../$base_url";
203     $url_encoded = implode(
204     '/', array_map(
205     function ($v) { return rawurlencode($v); },
206     explode('/', $url)));
207     $ret = $url_encoded;
208     $this->log(__METHOD__, 'return: '.var_export($ret, true));
209     $this->log(__METHOD__, 'END');
210     return $ret;
211     }
212    
213     /**
214     * Récupère la valeur d'une directive de configuration
215     *
216     * @param string $key Le nom de la directive de configuration dont on veut la valeur
217     *
218     * @return mixed
219     */
220     protected function conf(string $key) {
221     return $this->conf[$key] ?? null;
222     }
223    
224     /**
225     * Assigne/Enregistre les paramètres du modules.
226     * Les formats d'entrée supportés sont INI et JSON.
227     *
228     * @param string $raw_params Une chaine contenant les paramètres dans un format supporté
229     * @param string $format Le nom du format de la chaine des paramètres
230     *
231     * @return void
232     */
233     public function set_parameters(string $raw_params, string $format = 'INI') {
234     $this->log(__METHOD__, "($format) BEGIN");
235     switch(strtoupper($format)) {
236     case 'INI':
237     $this->log(__METHOD__, "parsing INI string:");
238     $this->log(__METHOD__, var_export($raw_params, true));
239 softime 18407 $params = parse_ini_string($raw_params, true);
240 mbideau 17426 if ($params === false) {
241 mbideau 17444 $this->log(__METHOD__, "Failed to parse INI string: '$raw_params'", 'WARNING');
242 mbideau 17426 }
243     if (is_array($params)) {
244     $this->params = $params;
245     }
246 mbideau 17302 break;
247     case 'JSON':
248     $this->log(__METHOD__, "parsing JSON string:");
249     $this->log(__METHOD__, var_export($raw_params, true));
250 mbideau 17426 $params = json_decode(
251 mbideau 17302 $raw_params, true, 512/*, JSON_THROW_ON_ERROR*/);
252     if (json_last_error() !== JSON_ERROR_NONE) {
253 mbideau 17444 $this->log(__METHOD__, var_export(json_last_error_msg(), true), 'WARNING');
254 mbideau 17302 }
255 mbideau 17426 if (is_array($params)) {
256     $this->params = $params;
257     }
258 mbideau 17302 break;
259     }
260     $this->log(__METHOD__, 'END');
261     }
262    
263     /**
264     * Renvoi le nom d'une méthode principale du module.
265     * Celle-ci sera appelée à chaque hook et aurait en argument:
266     * - le nom du hook
267     * - l'objet courant
268     * - les données du contaxte
269     *
270     * @return string|null
271     */
272     public function get_main_method() {
273     $this->log(__METHOD__, 'BEGIN');
274     $ret = null;
275     $this->log(__METHOD__, 'return: '.var_export($ret, true));
276     $this->log(__METHOD__, 'END');
277     return $ret;
278     }
279    
280     /**
281     * Renvoie une liste d'action de portlet
282     *
283     * @return array
284     */
285     public function get_actions() {
286     $this->log(__METHOD__, 'BEGIN');
287     $ret = array();
288     $this->log(__METHOD__, 'return: '.var_export($ret, true));
289     $this->log(__METHOD__, 'END');
290     return $ret;
291     }
292    
293     /**
294     * Renvoie la liste des déclencheurs (hooks) supporté par ce module
295     *
296     * @param boolean $in_business_term 'true' pour renvoyer la liste avec des termes business
297     *
298     * @return array
299     */
300     public function get_supported_hooks(bool $in_business_term = false) {
301     $this->log(__METHOD__, 'BEGIN');
302     $ret = array();
303     $this->log(__METHOD__, 'return: '.var_export($ret, true));
304     $this->log(__METHOD__, 'END');
305     return $ret;
306     }
307    
308     /**
309 softime 18407 * Renvoie la liste des libellés des déclencheurs pour une liste de hook donnés.
310     * Le format est un tableau associatif:
311     * <hook> => <libellé>
312     *
313     * @param array $hooks Liste de hooks
314     *
315     * @return array
316     * @throw RuntimeException
317     */
318     protected function get_declencheurs_for_hooks(array $hooks) {
319     $all_hooks_data = $this->framework->module_manager->get_all_available_hooks();
320     $hooks_with_labels = array();
321     foreach($hooks as $hook) {
322     if (! isset($all_hooks_data[$hook])) {
323     throw new RuntimeException("No hook label found for '$hook'");
324     }
325     $hooks_with_labels[$hook] = $all_hooks_data[$hook];
326     }
327     return $hooks_with_labels;
328     }
329    
330     /**
331 mbideau 17302 * Renvoie la liste des scripts Javascript a inclure dans la balise HTML <head>
332     *
333     * @return array
334     */
335     public function get_header_scripts_js() {
336     $this->log(__METHOD__, 'BEGIN');
337     $ret = array();
338     $this->log(__METHOD__, 'return: '.var_export($ret, true));
339     $this->log(__METHOD__, 'END');
340     return $ret;
341     }
342    
343     /**
344     * Renvoie la liste des scripts Javascript a inclure dans le code HTML inline
345     *
346     * @param string $position 'top' pour inclure au début et 'bottom' à la fin
347     *
348     * @return array
349     */
350     public function get_inline_scripts_js(string $position) {
351     $this->log(__METHOD__, "($position) BEGIN");
352     if (! in_array($position, array('top', 'bottom'))) {
353     throw InvalidArgumentException("Invalid position '$position' (must be: 'top' or 'bottom')");
354     }
355     $ret = array();
356     $this->log(__METHOD__, 'return: '.var_export($ret, true));
357     $this->log(__METHOD__, 'END');
358     return $ret;
359     }
360    
361     /**
362     * Renvoie la liste des styles CSS a inclure dans la balise HTML <head>
363     *
364     * @return array
365     */
366     public function get_header_styles_css() {
367     $this->log(__METHOD__, 'BEGIN');
368     $ret = array();
369     $this->log(__METHOD__, 'return: '.var_export($ret, true));
370     $this->log(__METHOD__, 'END');
371     return $ret;
372     }
373    
374     /**
375     * Renvoie la liste des styles CSS a inclure dans le code HTML inline
376     *
377     * @param string $position 'top' pour inclure au début et 'bottom' à la fin
378     *
379     * @return array
380     */
381     public function get_inline_styles_css(string $position) {
382     $this->log(__METHOD__, "($position) BEGIN");
383     if (! in_array($position, array('top', 'bottom'))) {
384     throw InvalidArgumentException("Invalid position '$position' (must be: 'top' or 'bottom')");
385     }
386     $ret = array();
387     $this->log(__METHOD__, 'return: '.var_export($ret, true));
388     $this->log(__METHOD__, 'END');
389     return $ret;
390     }
391    
392     /**
393     * Renvoie l'identifiant de la classe de l'objet lien, ou
394     * null s'il n'y a pas d'objet lien
395     *
396     * @return int|null
397     */
398     public function get_object_link_instance_id() {
399     //$this->log(__METHOD__, 'BEGIN');
400     if (! empty($this->object_link_instance)) {
401     $id_key = $this->object_link_instance->clePrimaire;
402     $ret = $this->object_link_instance->getVal($id_key);
403     //$this->log(__METHOD__, 'return: '.var_export($ret, true));
404     //$this->log(__METHOD__, 'END');
405     return $ret;
406     }
407     $ret = null;
408     //$this->log(__METHOD__, 'return: '.var_export($ret, true));
409     //$this->log(__METHOD__, 'END');
410     return $ret;
411     }
412    
413     /**
414 softime 18407 * Renvoie l'identifiant de la classe de l'objet métier, ou
415     * null s'il n'y a pas d'objet métier
416     *
417     * @return int|null
418     */
419     public function get_object_instance_id() {
420     //$this->log(__METHOD__, 'BEGIN');
421     if (! empty($this->object)) {
422     $id_key = $this->object->clePrimaire;
423     $ret = $this->object->getVal($id_key);
424     //$this->log(__METHOD__, 'return: '.var_export($ret, true));
425     //$this->log(__METHOD__, 'END');
426     return $ret;
427     }
428     $ret = null;
429     //$this->log(__METHOD__, 'return: '.var_export($ret, true));
430     //$this->log(__METHOD__, 'END');
431     return $ret;
432     }
433    
434     /**
435     * Renvoie le nom de l'objet auquel le champ dynamique est rattaché.
436     * Si ce nom est défini dans les paramètres du module, alors il a la précédence.
437     * Ensuite si un objet métier (om_dbform) a été associé à ce module, alors celui-ci est revoyé.
438     * Enfin, si un objet "lien" est associé à ce module, alors c'est le nom de l'objet défini
439     * dans l'objet "lien" qui est utilisé.
440     *
441     * @return string
442     */
443     protected function get_object_name() {
444     // le nom renseigné dans le paramétrage a précédence
445     $object_name = $this->params['object_name'] ?? null;
446     $this->log(__METHOD__, "object_name[params]: $object_name");
447     if (! empty($object_name)) return $object_name;
448    
449     // puis le nom de la classe de l'objet métier rattaché à ce module
450     if (! empty($this->object)) {
451     $object_name = get_class($this->object);
452     $this->log(__METHOD__, "object_name[object]: $object_name");
453     if (! empty($object_name)) return $object_name;
454     }
455     // enfin le nom de l'objet défini dans l'object "lien" du module
456     if (! empty($this->object_link_instance)) {
457     $object_name = $this->object_link_instance->getVal('object_name');
458     $this->log(__METHOD__, "object_name[object_link]: $object_name");
459     if (! empty($object_name)) return $object_name;
460     }
461    
462     return $object_name;
463     }
464    
465     /**
466 mbideau 17442 * Log un message en lui ajoutant un préfixe.
467 mbideau 17302 *
468 mbideau 17442 * @param string $method La méthode d'où provient le message (càd: __METHOD__)
469     * @param string $message Le message à écire dans le ficheir de logs
470     * @param string $level Le niveau de log
471 mbideau 17302 *
472 mbideau 17442 * @return void
473 mbideau 17302 */
474 mbideau 17442 protected function log(string $method, string $message, string $level = 'DEBUG') {
475 mbideau 17302
476     // remplace la classe parente par la classe courante
477 mbideau 17442 $ref = new \ReflectionClass($this);
478 mbideau 17302 $parent_class_escaped = str_replace('\\', '\\\\', $ref->getParentClass()->getName());
479     $method = preg_replace(
480     '/^'.$parent_class_escaped.'/',
481     $ref->getName(),
482     $method);
483    
484     $namespace_escaped = str_replace('\\', '\\\\', $ref->getNamespaceName());
485     $method_short = preg_replace('/^'.$namespace_escaped.'\\\\/', '', $method);
486    
487 mbideau 17442 $this->framework->log($method_short, $message, $level);
488     //$this->framework->log($method_short, $message, $level, 'modules');
489 mbideau 17302 }
490 softime 18407
491     /**
492     * Transforme la valeur de declencheur de la table object_link_instance en un nom de hook propre
493     * @param boolean : $use_parent_name =>
494     *
495     * @return null|array
496     */
497     public function get_declencheur_hook_names($get_parent_hooks = true) {
498     $this->log(__METHOD__, 'BEGIN');
499     $hook_names = array();
500     if (!empty($this->object_link_instance) && !empty($this->object_link_instance->getVal('declencheur'))) {
501     if (strpos($this->object_link_instance->getVal('declencheur'),':') !== false) {
502     $explode_declencheur = explode(':', $this->object_link_instance->getVal('declencheur'));
503     $declencheur_object = $explode_declencheur[0];
504     $declencheur_hook = $explode_declencheur[1];
505    
506     // Calcul des noms de hook pour les om_dbforms et les classe filles
507     if ($get_parent_hooks){
508     $object_class = null;
509    
510     // Sans objet defini on cri
511     if (empty($this->object) ) {
512     $object_class = $this->get_object_name();
513     }else{
514     $object_class = get_class($this->object);
515     }
516    
517     // On se sert de ReflectionClass pour recupèrer la class parent de l'object
518     $reflection_class = new ReflectionClass('\\'.$object_class);
519     $parent_class = $reflection_class->getParentClass();
520     if ($parent_class === false) {
521     throw new RuntimeException("Error '".get_class($this->object)."' has no parent class. Should Be Impossible, Expecting 'om_dbform' or child of 'om_dbform'");
522     }
523    
524     $object_class_hook_name = $object_class.'_'.$declencheur_hook;
525    
526     // Calcul le nom du hook en remplacant OMDBFORM par la classe object metier
527     // Ou calcul le nom du hook de la class objet métier à partir du déclencheur de la classe parent
528     if (($declencheur_object == 'om_dbform' || $declencheur_object == $parent_class->name)
529     && !in_array($object_class_hook_name, $hook_names)
530     ) {
531     $hook_names[] = $object_class_hook_name;
532     }
533     }
534    
535     // Calcul le nom du hook du déclencheur parent
536     $hook_names[] = implode('_', $explode_declencheur);
537    
538     }
539     }
540     $this->log(__METHOD__, 'return: '.var_export($hook_names, true));
541     $this->log(__METHOD__, 'END');
542     return $hook_names;
543     }
544    
545     /**
546     * Renvoi la documentation du module au format HTML.
547     *
548     * Il est conseiller d'utiliser un fichier HTML à la racine du module nommé 'documentation.html',
549     * et de le renvoyer via cette méthode.
550     *
551     * @return string (html)
552     */
553     public function get_documentation() {
554     $this->log(__METHOD__, 'BEGIN');
555     $doc = '';
556     $module_name = $this->get_short_name();
557     $doc_path = $this->dir."/documentation.html";
558     $this->log(__METHOD__, 'doc path: '.var_export($doc_path, true));
559     if (file_exists($doc_path)) {
560     $doc = file_get_contents($doc_path);
561     }
562     $this->log(__METHOD__, 'END');
563     return $doc;
564     }
565 mbideau 17302 }

Properties

Name Value
svn:executable *

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26