Overview
Comment: | Archives .tar.gz plutôt que .phar |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
4b166c4876c9c78fa2e4c67c1d806285 |
User & Date: | bohwaz on 2014-04-01 18:33:18 |
Other Links: | manifest | tags |
Context
2014-04-01
| ||
18:35 | Accepter les points dans les noms de plugins check-in: ea95d5d478 user: bohwaz tags: trunk | |
18:33 | Archives .tar.gz plutôt que .phar check-in: 4b166c4876 user: bohwaz tags: trunk | |
18:10 | Suppression des associations écritures/cotisations check-in: 60da784ccd user: bohwaz tags: trunk | |
Changes
Modified doc/dev/plugins.skriv from [fadf7c1a26] to [fbe43be174].
︙ | ︙ | |||
31 32 33 34 35 36 37 | * respecter la vie privée des utilisateurs et notamment : ** NE PAS contacter un serveur distant (sauf besoin spécifique) ni transmettre des informations ou statistiques à un serveur tiers. == Détails techniques == === Format des plugins === | | | < < | < < < < < < < < < < < < < | | | 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | * respecter la vie privée des utilisateurs et notamment : ** NE PAS contacter un serveur distant (sauf besoin spécifique) ni transmettre des informations ou statistiques à un serveur tiers. == Détails techniques == === Format des plugins === Les plugins sont des archives .tar.gz : tous les fichiers du plugin (code PHP, CSS, templates, images, etc.) sont stockés dans l'archive et y restent. Il est possible de créer soi-même l'archive .tar.gz de cette manière : $ tar czvf src/plugins/test.tar.gz ~/dev/plugins/test Un script PHP (**make_plugin.php**) est fourni dans le répertoire **tools/** de la version de développement de Garradin afin de vérifier l'arborescence et de créer l'archive en ligne de commande. Son utilisation est très simple : $ php ~/dev/plugins/test ~/garradin/src/plugins/test.tar.gz === Informations sur le plugin (garradin_plugin.ini) === Chaque plugin doit au moins fournir à la racine de son archive un fichier nommé ''garradin_plugin.ini''. Ce fichier fournit le nom, la description et quelques détails sur le plugin : nom="Ma première extension Garradin" description="Affiche un message trop cool" |
︙ | ︙ | |||
104 105 106 107 108 109 110 | * setConfig(string $key, string $value) : enregistre la configuration du plugin, si $value est null alors tte clé est effacée de la configuration * getConfig(string $key) : récupère la valeur de la clé $key pour la configuration du plugin * getInfos() : renvoie les informations enregistrées sur le plugin * upgrade() : mise à jour du plugin * needsUpgrade() : le plugin doit-il être mis à jour ? * uninstall() : désinstaller le plugin * id() : renvoie l'identifiant du plugin | | | 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | * setConfig(string $key, string $value) : enregistre la configuration du plugin, si $value est null alors tte clé est effacée de la configuration * getConfig(string $key) : récupère la valeur de la clé $key pour la configuration du plugin * getInfos() : renvoie les informations enregistrées sur le plugin * upgrade() : mise à jour du plugin * needsUpgrade() : le plugin doit-il être mis à jour ? * uninstall() : désinstaller le plugin * id() : renvoie l'identifiant du plugin * path() : renvoie le chemin vers l'archive du plugin === Base de données === Tous les plugins ont un accès illimité à la base de données principale de Garradin. Cependant il est interdit d'ajouter, modifier ou supprimer des données directement dans les tables de cette BDD afin de ne pas compromettre l'intégrité des données. Pour modifier ces données il faut utiliser les méthodes de Garradin. Chaque plugin peut créer une ou plusieurs tables dans cette BDD, elles devront par contre être supprimées à la désinstallation. Dans ce cas un plugin peut modifier directement ses tables. |
︙ | ︙ |
Modified src/include/class.plugin.php from [a31ccbe5ea] to [247fc79739].
︙ | ︙ | |||
51 52 53 54 55 56 57 | /** * Renvoie le chemin absolu vers l'archive du plugin * @return string Chemin PHAR vers l'archive */ public function path() { | | | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | /** * Renvoie le chemin absolu vers l'archive du plugin * @return string Chemin PHAR vers l'archive */ public function path() { return 'phar://' . PLUGINS_ROOT . '/' . $this->id . '.tar.gz'; } /** * Renvoie une entrée de la configuration ou la configuration complète * @param string $key Clé à rechercher, ou NULL si on désire toutes les entrées de la * @return mixed L'entrée demandée (mixed), ou l'intégralité de la config (array), * ou NULL si l'entrée demandée n'existe pas. |
︙ | ︙ | |||
198 199 200 201 202 203 204 | public function uninstall() { if (file_exists($this->path() . '/uninstall.php')) { include $this->path() . '/uninstall.php'; } | | | 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 | public function uninstall() { if (file_exists($this->path() . '/uninstall.php')) { include $this->path() . '/uninstall.php'; } unlink(PLUGINS_ROOT . '/' . $this->id . '.tar.gz'); $db = DB::getInstance(); return $db->simpleExec('DELETE FROM plugins WHERE id = ?;', $this->id); } /** * Renvoie TRUE si le plugin a besoin d'être mis à jour |
︙ | ︙ | |||
273 274 275 276 277 278 279 | $dir = dir(PLUGINS_ROOT); while ($file = $dir->read()) { if (substr($file, 0, 1) == '.') continue; | | | | 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 | $dir = dir(PLUGINS_ROOT); while ($file = $dir->read()) { if (substr($file, 0, 1) == '.') continue; if (!preg_match('!^([a-z0-9_-]+)\.tar.gz$!', $file, $match)) continue; if (array_key_exists($match[1], $installed)) continue; $list[$match[1]] = parse_ini_file('phar://' . PLUGINS_ROOT . '/' . $match[1] . '.tar.gz/garradin_plugin.ini', false); } $dir->close(); return $list; } |
︙ | ︙ | |||
344 345 346 347 348 349 350 | static public function checkHash($id) { $list = self::fetchOfficialList(); if (!array_key_exists($id, $list)) return null; | | | 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 | static public function checkHash($id) { $list = self::fetchOfficialList(); if (!array_key_exists($id, $list)) return null; $hash = sha1_file(PLUGINS_ROOT . '/' . $id . '.tar.gz'); return ($hash === $list[$id]['hash']); } /** * Est-ce que le plugin est officiel ? * @param string $id Identifiant du plugin |
︙ | ︙ | |||
377 378 379 380 381 382 383 | $list = self::fetchOfficialList(); if (!array_key_exists($id, $list)) { throw new \LogicException($id . ' n\'est pas un plugin officiel (absent de la liste)'); } | | | 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 | $list = self::fetchOfficialList(); if (!array_key_exists($id, $list)) { throw new \LogicException($id . ' n\'est pas un plugin officiel (absent de la liste)'); } if (file_exists(PLUGINS_ROOT . '/' . $id . '.tar.gz')) { throw new UserException('Le plugin '.$id.' existe déjà.'); } $url = parse_url(PLUGINS_URL); $context_options = [ |
︙ | ︙ | |||
399 400 401 402 403 404 405 | 'disable_compression' => true, ] ]; $context = stream_context_create($context_options); try { | | | | | | | | | | | | | | 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 | 'disable_compression' => true, ] ]; $context = stream_context_create($context_options); try { copy($list[$id]['phar'], PLUGINS_ROOT . '/' . $id . '.tar.gz', $context); } catch (\Exception $e) { throw new UserException('Le téléchargement du plugin '.$id.' a échoué : ' . $e->getMessage()); } if (!self::checkHash($id)) { unlink(PLUGINS_ROOT . '/' . $id . '.tar.gz'); throw new \RuntimeException('L\'archive du plugin '.$id.' est corrompue (le hash SHA1 ne correspond pas).'); } self::install($id, true); return true; } /** * Installer un plugin * @param string $id Identifiant du plugin * @param boolean $official TRUE si le plugin est officiel * @return boolean TRUE si tout a fonctionné */ static public function install($id, $official = false) { if (!file_exists('phar://' . PLUGINS_ROOT . '/' . $id . '.tar.gz')) { throw new \RuntimeException('Le plugin ' . $id . ' ne semble pas exister et ne peut donc être installé.'); } if (!file_exists('phar://' . PLUGINS_ROOT . '/' . $id . '.tar.gz/garradin_plugin.ini')) { throw new UserException('L\'archive '.$id.'.tar.gz n\'est pas une extension Garradin : fichier garradin_plugin.ini manquant.'); } $infos = parse_ini_file('phar://' . PLUGINS_ROOT . '/' . $id . '.tar.gz/garradin_plugin.ini', false); $required = ['nom', 'description', 'auteur', 'url', 'version', 'menu', 'config']; foreach ($required as $key) { if (!array_key_exists($key, $infos)) { throw new \RuntimeException('Le fichier garradin_plugin.ini ne contient pas d\'entrée "'.$key.'".'); } } if (!empty($infos['menu']) && !file_exists('phar://' . PLUGINS_ROOT . '/' . $id . '.tar.gz/www/admin/index.php')) { throw new \RuntimeException('Le plugin '.$id.' ne comporte pas de fichier www/admin/index.php alors qu\'il demande à figurer au menu.'); } $config = ''; if ((bool)$infos['config']) { if (!file_exists('phar://' . PLUGINS_ROOT . '/' . $id . '.tar.gz/config.json')) { throw new \RuntimeException('L\'archive '.$id.'.tar.gz ne comporte pas de fichier config.json alors que le plugin nécessite le stockage d\'une configuration.'); } if (!file_exists('phar://' . PLUGINS_ROOT . '/' . $id . '.tar.gz/www/admin/config.php')) { throw new \RuntimeException('L\'archive '.$id.'.tar.gz ne comporte pas de fichier www/admin/config.php alors que le plugin nécessite le stockage d\'une configuration.'); } $config = json_decode(file_get_contents('phar://' . PLUGINS_ROOT . '/' . $id . '.tar.gz/config.json'), true); if (is_null($config)) { throw new \RuntimeException('config.json invalide. Code erreur JSON: ' . json_last_error()); } $config = json_encode($config); |
︙ | ︙ | |||
491 492 493 494 495 496 497 | 'auteur' => $infos['auteur'], 'url' => $infos['url'], 'version' => $infos['version'], 'menu' => (int)(bool)$infos['menu'], 'config' => $config, ]); | | | | 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 | 'auteur' => $infos['auteur'], 'url' => $infos['url'], 'version' => $infos['version'], 'menu' => (int)(bool)$infos['menu'], 'config' => $config, ]); if (file_exists('phar://' . PLUGINS_ROOT . '/' . $id . '.tar.gz/install.php')) { include 'phar://' . PLUGINS_ROOT . '/' . $id . '.tar.gz/install.php'; } return true; } /** * Renvoie la version installée d'un plugin ou FALSE s'il n'est pas installé |
︙ | ︙ |
Modified src/include/lib.utils.php from [d25c56997f] to [6668e725cc].
︙ | ︙ | |||
606 607 608 609 610 611 612 | rmdir($path); return true; } static public function plugin_url($params = []) { | | | 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 | rmdir($path); return true; } static public function plugin_url($params = []) { if (isset($params['id'])) { $url = WWW_URL . 'admin/plugin/' . $params['id'] . '/'; } else { $url = PLUGIN_URL; } |
︙ | ︙ |
Modified tools/make_plugin.php from [18fb83b9c1] to [7ff5f9f8d3].
1 2 | <?php | < < < < < | > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <?php if (empty($argv[1]) || empty($argv[2])) { die("Usage : " . basename(__FILE__) . " /path/to/plugin/source /path/to/plugin/archive\n"); } $plugin_file = $argv[2]; $plugin_file = preg_replace('/\.(?:tar(?:\.gz)?|phar)?$/', '', $plugin_file); $target = realpath($argv[1]); if (!file_exists($target . '/garradin_plugin.ini')) { die("ERREUR : Le fichier $target/garradin_plugin.ini est introuvable.\n"); } |
︙ | ︙ | |||
45 46 47 48 49 50 51 | } if (!empty($infos['menu']) && !file_exists($target . '/www/admin/index.php')) { die("ERREUR : Le fichier www/admin/index.php est obligatoire quand menu=1\n"); } | | < | | | | | 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | } if (!empty($infos['menu']) && !file_exists($target . '/www/admin/index.php')) { die("ERREUR : Le fichier www/admin/index.php est obligatoire quand menu=1\n"); } @unlink($plugin_file . '.tar'); @unlink($plugin_file . '.tar.gz'); $p = new PharData($plugin_file . '.tar'); $p->buildFromDirectory($target); $p->compress(Phar::GZ); @unlink($plugin_file . '.tar'); |