Changes In Branch dev Through [2e72b91d09] Excluding Merge-Ins
This is equivalent to a diff from a0c15d9d73 to 2e72b91d09
2018-10-25
| ||
11:25 | Ajouter la colonne de tri dans les colonnes affichées, fix [0a59dffc92c5566e334ab0100a703801fd2c235f] check-in: 99a7c5c699 user: bohwaz tags: dev | |
11:19 | Recherche avancée : meilleure traduction de "ANY" (fix [026bac40f8e17f7668f40484abd773fec43dec61]) check-in: 2e72b91d09 user: bohwaz tags: dev | |
10:56 | Fix [9afefc9f2b6b1f4b] : permettre de chercher les champs nuls / non-nuls check-in: fd31435777 user: bohwaz tags: dev | |
2018-08-26
| ||
01:19 | Evitons les conflits de noms de champs quand quelqu'un a déjà créé un champ nommé "catégorie" check-in: 96c5022fb3 user: bohwaz tags: trunk, stable | |
2018-08-02
| ||
22:58 | Merge avec trunk check-in: e9ab0666a3 user: bohwaz tags: dev | |
22:52 | Erreur plus explicite quand on essaye de modifier une écriture qui n'existe pas check-in: a0c15d9d73 user: bohwaz tags: trunk, stable | |
14:18 | Ne pas afficher l'ID check-in: b5b5a3632c user: bohwaz tags: trunk, stable | |
2018-07-20
| ||
22:15 | Erreur plus explicite quand on essaye de modifier une écriture qui n'existe pas check-in: 1f94d65a20 user: bohwaz tags: dev | |
Modified src/README from [fbebcdff15] to [b24af5ed67].
1 2 3 4 5 6 7 8 9 10 | Garradin - Gestionnaire d'association libre =========================================== Inclus les bibliothèques suivantes : - Gibberish AES https://github.com/mdp/gibberish-aes Copyright : Mark Percival 2008 - http://markpercival.us Licence : MIT | < < < < | | 1 2 3 4 5 6 7 8 9 10 11 12 13 | Garradin - Gestionnaire d'association libre =========================================== Inclus les bibliothèques suivantes : - Gibberish AES https://github.com/mdp/gibberish-aes Copyright : Mark Percival 2008 - http://markpercival.us Licence : MIT - KD2fw Copyright : 2001-2018 BohwaZ Licence : GNU AGPL v3 |
Modified src/VERSION from [d1cc680d2c] to [f8bcdfe8a5].
|
| | | 1 | 0.9.0-rc4 |
Modified src/config.dist.php from [1f09233dd8] to [4b1bdaf310].
︙ | ︙ | |||
234 235 236 237 238 239 240 | * STARTTLS = utilisation de STARTTLS (moyennement sécurisé) * * Défaut : STARTTLS */ const SMTP_SECURITY = 'STARTTLS'; /** | | | | < < < > | > > | | | 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 | * STARTTLS = utilisation de STARTTLS (moyennement sécurisé) * * Défaut : STARTTLS */ const SMTP_SECURITY = 'STARTTLS'; /** * Activer les sauvegardes automatiques * * Utile à désactiver si vous avez déjà des sauvegardes effectuées * automatiquement au niveau du système. * * Sinon les sauvegardes seront effectuées soit par la tâche cron * soit à l'affichage de la page d'accueil (si nécessaire). * * Voir paramètre USE_CRON aussi * * Défaut : true */ const ENABLE_AUTOMATIC_BACKUPS = true; |
Modified src/cron.php from [d4a8acbd51] to [0a002d599e].
1 2 3 4 5 6 7 8 | <?php namespace Garradin; require_once __DIR__ . '/include/init.php'; // Exécution des tâches automatiques | | < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <?php namespace Garradin; require_once __DIR__ . '/include/init.php'; // Exécution des tâches automatiques if (ENABLE_AUTOMATIC_BACKUPS && $config->get('frequence_sauvegardes') && $config->get('nombre_sauvegardes')) { $s = new Sauvegarde; $s->auto(); } // Exécution des rappels automatiques $rappels = new Rappels; if ($rappels->countAll()) { $rappels->sendPending(); } // Nettoyage du cache statique Static_Cache::clean(); |
Deleted src/include/data/0.4.0.sql version [19c558523f].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/include/data/0.4.3.sql version [074264b547].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/include/data/0.6.0.sql version [95aac309bf].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added src/include/data/0.9.0.sql version [9f23495ff4].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | -- Désactivation de l'accès aux membres, pour les groupes qui n'avaient que le droit de lecture -- car maintenant ce droit permet de voir les fiches de membres complètes UPDATE membres_categories SET droit_membres = 0 WHERE droit_membres = 1; -- Suppression de la colonne description des catégories ALTER TABLE membres_categories RENAME TO membres_categories_old; -- Mise à jour table compta_rapprochement: la foreign key sur membres est passée -- à ON DELETE SET NULL ALTER TABLE compta_rapprochement RENAME TO compta_rapprochement_old; -- Re-créer la table -- Créer également les nouvelles tables email .read schema.sql -- Copie des données, sauf la colonne description INSERT INTO membres_categories SELECT id, nom, droit_wiki, droit_membres, droit_compta, droit_inscription, droit_connexion, droit_config, cacher, id_cotisation_obligatoire FROM membres_categories_old; -- Suppression des anciennes tables DROP TABLE membres_categories_old; -- Migration des données INSERT INTO compta_rapprochement SELECT * FROM compta_rapprochement_old; DROP TABLE compta_rapprochement_old; -- Cette variable n'est plus utilisée DELETE FROM config WHERE cle = 'email_envoi_automatique'; ALTER TABLE plugins ADD COLUMN menu_condition TEXT NULL; -- Supprimer le début dans le nom des plugins UPDATE plugins_signaux SET callback = replace(callback, 'Garradin\Plugin\', ''); |
Modified src/include/data/schema.sql from [80be656e5d] to [efe750515a].
︙ | ︙ | |||
9 10 11 12 13 14 15 | -- compta_categorie_dons => id_categorie CREATE TABLE IF NOT EXISTS membres_categories -- Catégories de membres ( id INTEGER PRIMARY KEY NOT NULL, nom TEXT NOT NULL, | < | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | -- compta_categorie_dons => id_categorie CREATE TABLE IF NOT EXISTS membres_categories -- Catégories de membres ( id INTEGER PRIMARY KEY NOT NULL, nom TEXT NOT NULL, droit_wiki INTEGER NOT NULL DEFAULT 1, droit_membres INTEGER NOT NULL DEFAULT 1, droit_compta INTEGER NOT NULL DEFAULT 1, droit_inscription INTEGER NOT NULL DEFAULT 0, droit_connexion INTEGER NOT NULL DEFAULT 1, droit_config INTEGER NOT NULL DEFAULT 0, |
︙ | ︙ | |||
315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 | officiel INTEGER NOT NULL DEFAULT 0, nom TEXT NOT NULL, description TEXT NULL, auteur TEXT NULL, url TEXT NULL, version TEXT NOT NULL, menu INTEGER NOT NULL DEFAULT 0, config TEXT NULL ); CREATE TABLE IF NOT EXISTS plugins_signaux -- Association entre plugins et signaux (hooks) ( signal TEXT NOT NULL, plugin TEXT NOT NULL REFERENCES plugins (id), callback TEXT NOT NULL, PRIMARY KEY (signal, plugin) ); CREATE TABLE IF NOT EXISTS compta_rapprochement -- Rapprochement entre compta et relevés de comptes ( id_operation INTEGER NOT NULL PRIMARY KEY REFERENCES compta_journal (id) ON DELETE CASCADE, date TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP CHECK (datetime(date) IS NOT NULL AND datetime(date) = date), | > | | 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 | officiel INTEGER NOT NULL DEFAULT 0, nom TEXT NOT NULL, description TEXT NULL, auteur TEXT NULL, url TEXT NULL, version TEXT NOT NULL, menu INTEGER NOT NULL DEFAULT 0, menu_condition TEXT NULL, config TEXT NULL ); CREATE TABLE IF NOT EXISTS plugins_signaux -- Association entre plugins et signaux (hooks) ( signal TEXT NOT NULL, plugin TEXT NOT NULL REFERENCES plugins (id), callback TEXT NOT NULL, PRIMARY KEY (signal, plugin) ); CREATE TABLE IF NOT EXISTS compta_rapprochement -- Rapprochement entre compta et relevés de comptes ( id_operation INTEGER NOT NULL PRIMARY KEY REFERENCES compta_journal (id) ON DELETE CASCADE, date TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP CHECK (datetime(date) IS NOT NULL AND datetime(date) = date), id_auteur INTEGER NULL REFERENCES membres (id) ON DELETE SET NULL ); CREATE TABLE IF NOT EXISTS fichiers -- Données sur les fichiers ( id INTEGER NOT NULL PRIMARY KEY, nom TEXT NOT NULL, -- nom de fichier (par exemple image1234.jpeg) |
︙ | ︙ | |||
382 383 384 385 386 387 388 | CREATE TABLE IF NOT EXISTS fichiers_compta_journal -- Associations entre fichiers et journal de compta (pièce comptable par exemple) ( fichier INTEGER NOT NULL REFERENCES fichiers (id), id INTEGER NOT NULL REFERENCES compta_journal (id), PRIMARY KEY(fichier, id) ); | > > > > > > > > > > > > | 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 | CREATE TABLE IF NOT EXISTS fichiers_compta_journal -- Associations entre fichiers et journal de compta (pièce comptable par exemple) ( fichier INTEGER NOT NULL REFERENCES fichiers (id), id INTEGER NOT NULL REFERENCES compta_journal (id), PRIMARY KEY(fichier, id) ); CREATE TABLE IF NOT EXISTS recherches -- Recherches enregistrées ( id INTEGER NOT NULL PRIMARY KEY, id_membre INTEGER NULL REFERENCES membres (id) ON DELETE CASCADE, -- Si non NULL, alors la recherche ne sera visible que par le membre associé intitule TEXT NOT NULL, creation TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP CHECK (datetime(creation) IS NOT NULL AND datetime(creation) = creation), cible TEXT NOT NULL, -- "membres" ou "compta_journal" type TEXT NOT NULL, -- "json" ou "sql" contenu TEXT NOT NULL ); |
Modified src/include/init.php from [5ff1d716c3] to [bfe2446b5f].
︙ | ︙ | |||
105 106 107 108 109 110 111 | 'SMTP_HOST' => false, 'SMTP_USER' => null, 'SMTP_PASSWORD' => null, 'SMTP_PORT' => 587, 'SMTP_SECURITY' => 'STARTTLS', 'ADMIN_URL' => WWW_URL . 'admin/', 'NTP_SERVER' => 'fr.pool.ntp.org', | | | 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | 'SMTP_HOST' => false, 'SMTP_USER' => null, 'SMTP_PASSWORD' => null, 'SMTP_PORT' => 587, 'SMTP_SECURITY' => 'STARTTLS', 'ADMIN_URL' => WWW_URL . 'admin/', 'NTP_SERVER' => 'fr.pool.ntp.org', 'ENABLE_AUTOMATIC_BACKUPS' => true, ]; foreach ($default_config as $const => $value) { $const = sprintf('Garradin\\%s', $const); if (!defined($const)) |
︙ | ︙ |
Modified src/include/lib/Garradin/Compta/Import.php from [19a1972b2f] to [d8cc440c1c].
1 2 3 4 | <?php namespace Garradin\Compta; | | | | | < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <?php namespace Garradin\Compta; use Garradin\DB; use Garradin\Utils; use Garradin\UserException; use Garradin\Config; class Import { protected $header = [ 'Numéro mouvement', 'Date', 'Type de mouvement', |
︙ | ︙ | |||
25 26 27 28 29 30 31 | 'Numéro de chèque', 'Numéro de pièce', 'Remarques' ]; protected function export($exercice) { | | | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | 'Numéro de chèque', 'Numéro de pièce', 'Remarques' ]; protected function export($exercice) { return DB::getInstance()->iterate('SELECT journal.id, strftime(\'%d/%m/%Y\', date) AS date, (CASE cat.type WHEN 1 THEN \'Recette\' WHEN -1 THEN \'Dépense\' ELSE \'Autre\' END) AS type, (CASE cat.intitule WHEN NULL THEN \'\' ELSE cat.intitule END) AS cat, journal.libelle, montant, compte_debit, |
︙ | ︙ | |||
47 48 49 50 51 52 53 | FROM compta_journal AS journal LEFT JOIN compta_categories AS cat ON cat.id = journal.id_categorie LEFT JOIN compta_comptes AS debit ON debit.id = journal.compte_debit LEFT JOIN compta_comptes AS credit ON credit.id = journal.compte_credit LEFT JOIN compta_moyens_paiement AS moyen ON moyen.code = journal.moyen_paiement WHERE id_exercice = '.(int)$exercice.' ORDER BY journal.date; | | | < | < | < < < < < | < | | | | | < < | < < < < < < < < < < | 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | FROM compta_journal AS journal LEFT JOIN compta_categories AS cat ON cat.id = journal.id_categorie LEFT JOIN compta_comptes AS debit ON debit.id = journal.compte_debit LEFT JOIN compta_comptes AS credit ON credit.id = journal.compte_credit LEFT JOIN compta_moyens_paiement AS moyen ON moyen.code = journal.moyen_paiement WHERE id_exercice = '.(int)$exercice.' ORDER BY journal.date; '); } protected function exportName() { return sprintf('Export comptabilité - %s - %s', Config::getInstance()->get('nom_asso'), date('Y-m-d')); } public function toCSV($exercice) { return Utils::toCSV($this->exportName(), $this->export($exercice), $this->header); } public function toODS($exercice) { return Utils::toODS($this->exportName(), $this->export($exercice), $this->header); } public function fromCSV($path) { if (!file_exists($path) || !is_readable($path)) { throw new \RuntimeException('Fichier inconnu : '.$path); } |
︙ | ︙ |
Modified src/include/lib/Garradin/Config.php from [868d015351] to [52d2a7f213].
︙ | ︙ | |||
16 17 18 19 20 21 22 23 24 25 26 27 28 29 | * Singleton simple * @return Config */ static public function getInstance() { return self::$_instance ?: self::$_instance = new Config; } /** * Empêche de cloner l'objet * @return void */ private function __clone() { | > > > > > | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | * Singleton simple * @return Config */ static public function getInstance() { return self::$_instance ?: self::$_instance = new Config; } static public function deleteInstance() { self::$_instance = null; } /** * Empêche de cloner l'objet * @return void */ private function __clone() { |
︙ | ︙ | |||
65 66 67 68 69 70 71 72 73 74 75 76 77 78 | 'champ_identite' => $string, 'version' => $string, 'couleur1' => $string, 'couleur2' => $string, 'image_fond' => $string, ]; $db = DB::getInstance(); $this->config = $db->getAssoc('SELECT cle, valeur FROM config ORDER BY cle;'); foreach ($this->config as $key=>&$value) | > > | 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | 'champ_identite' => $string, 'version' => $string, 'couleur1' => $string, 'couleur2' => $string, 'image_fond' => $string, 'desactiver_site' => $bool, ]; $db = DB::getInstance(); $this->config = $db->getAssoc('SELECT cle, valeur FROM config ORDER BY cle;'); foreach ($this->config as $key=>&$value) |
︙ | ︙ |
Modified src/include/lib/Garradin/DB.php from [1dead0b7c1] to [69073dd36f].
︙ | ︙ | |||
22 23 24 25 26 27 28 29 30 31 32 33 34 35 | private function __clone() { // Désactiver le clonage, car on ne veut qu'une seule instance } public function __construct($create = false) { $flags = \SQLITE3_OPEN_READWRITE; if ($create) { $flags |= \SQLITE3_OPEN_CREATE; } | > > > > > | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | private function __clone() { // Désactiver le clonage, car on ne veut qu'une seule instance } public function __construct($create = false) { if (!defined('\SQLITE3_OPEN_READWRITE')) { throw new \Exception('Module SQLite3 de PHP non présent. Merci de l\'installer.'); } $flags = \SQLITE3_OPEN_READWRITE; if ($create) { $flags |= \SQLITE3_OPEN_CREATE; } |
︙ | ︙ | |||
45 46 47 48 49 50 51 52 53 54 55 56 57 58 | // Activer les contraintes des foreign keys $this->db->exec('PRAGMA foreign_keys = ON;'); $this->db->createFunction('transliterate_to_ascii', ['Garradin\Utils', 'transliterateToAscii']); } } /** * Import a file containing SQL commands * Allows to use the statement ".read other_file.sql" to load other files * @param string $file Path to file containing SQL commands * @return boolean */ | > > > > > | 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | // Activer les contraintes des foreign keys $this->db->exec('PRAGMA foreign_keys = ON;'); $this->db->createFunction('transliterate_to_ascii', ['Garradin\Utils', 'transliterateToAscii']); } } public function close() { parent::close(); self::$_instance = null; } /** * Import a file containing SQL commands * Allows to use the statement ".read other_file.sql" to load other files * @param string $file Path to file containing SQL commands * @return boolean */ |
︙ | ︙ |
Modified src/include/lib/Garradin/Install.php from [e286e959c9] to [c6e1ea55f9].
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <?php namespace Garradin; /** * Pour procéder à l'installation de l'instance Garradin * Utile pour automatiser l'installation sans passer par la page d'installation */ class Install { static public function install($nom_asso, $adresse_asso, $email_asso, $nom_categorie, $nom_membre, $email_membre, $passe_membre, $site_asso = WWW_URL) { $db = DB::getInstance(true); // Taille de la page de DB, on force à 4096 (défaut dans les dernières // versions de SQLite mais pas les vieilles) $db->exec('PRAGMA page_size = 4096;'); | > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | <?php namespace Garradin; /** * Pour procéder à l'installation de l'instance Garradin * Utile pour automatiser l'installation sans passer par la page d'installation */ class Install { static public function reset(Membres\Session $session, $password, array $options = []) { $config = (object) Config::getInstance()->getConfig(); $user = $session->getUser(); if (!$session->checkPassword($password, $user->passe)) { throw new UserException('Le mot de passe ne correspond pas.'); } (new Sauvegarde)->create(date('Y-m-d-His-') . 'avant-remise-a-zero'); DB::getInstance()->close(); Config::deleteInstance(); unlink(DB_FILE); return self::install($config->nom_asso, $config->adresse_asso, $config->email_asso, 'Bureau', $user->identite, $user->email, $password, $config->site_asso); } static public function install($nom_asso, $adresse_asso, $email_asso, $nom_categorie, $nom_membre, $email_membre, $passe_membre, $site_asso = WWW_URL) { $db = DB::getInstance(true); // Taille de la page de DB, on force à 4096 (défaut dans les dernières // versions de SQLite mais pas les vieilles) $db->exec('PRAGMA page_size = 4096;'); |
︙ | ︙ | |||
35 36 37 38 39 40 41 | $config->setVersion(garradin_version()); $champs = Membres\Champs::importInstall(); $champs->save(false); // Pas de copie car pas de table membres existante $config->set('champ_identifiant', 'email'); $config->set('champ_identite', 'nom'); | | | 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | $config->setVersion(garradin_version()); $champs = Membres\Champs::importInstall(); $champs->save(false); // Pas de copie car pas de table membres existante $config->set('champ_identifiant', 'email'); $config->set('champ_identite', 'nom'); // Création catégories $cats = new Membres\Categories; $id = $cats->add([ 'nom' => 'Membres actifs', ]); $config->set('categorie_membres', $id); |
︙ | ︙ | |||
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | $ex = new Compta\Exercices; $ex->add([ 'libelle' => 'Premier exercice', 'debut' => date('Y-01-01'), 'fin' => date('Y-12-31') ]); return $config->save(); } static public function checkAndCreateDirectories() { // Vérifier que les répertoires vides existent, sinon les créer $paths = [DATA_ROOT, PLUGINS_ROOT, CACHE_ROOT, CACHE_ROOT . '/static', CACHE_ROOT . '/compiled']; foreach ($paths as $path) { | > > > > > > > > > > > > > > > > > > > > < < | | < | | | | | | | | | | | 135 136 137 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 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 | $ex = new Compta\Exercices; $ex->add([ 'libelle' => 'Premier exercice', 'debut' => date('Y-01-01'), 'fin' => date('Y-12-31') ]); // Ajout d'une recherche avancée en exemple $query = [ 'query' => [[ 'operator' => 'AND', 'conditions' => [ [ 'column' => 'lettre_infos', 'operator' => '= 1', 'values' => [], ], ], ]], 'order' => 'numero', 'desc' => true, 'limit' => '10000', ]; $recherche = new Recherche; $recherche->add('Membres inscrits à la lettre d\'information', null, $recherche::TYPE_JSON, 'membres', $query); return $config->save(); } static public function checkAndCreateDirectories() { // Vérifier que les répertoires vides existent, sinon les créer $paths = [DATA_ROOT, PLUGINS_ROOT, CACHE_ROOT, CACHE_ROOT . '/static', CACHE_ROOT . '/compiled']; foreach ($paths as $path) { Utils::safe_mkdir($path); if (!is_dir($path)) { throw new UserException('Le répertoire '.$path.' n\'existe pas ou n\'est pas un répertoire.'); } // On en profite pour vérifier qu'on peut y lire et écrire if (!is_writable($path) || !is_readable($path)) { throw new UserException('Le répertoire '.$path.' n\'est pas accessible en lecture/écriture.'); } } return true; } static public function setLocalConfig($key, $value) { $path = ROOT . DIRECTORY_SEPARATOR . 'config.local.php'; $new_line = sprintf('const %s = %s;', $key, var_export($value, true)); if (file_exists($path)) { $config = file_get_contents($path); $pattern = sprintf('/^.*(?:const\s+%s|define\s*\(.*%1$s).*$/m', $key); $config = preg_replace($pattern, $new_line, $config, -1, $count); if (!$count) { $config = preg_replace('/\?>.*/s', '', $config); $config .= PHP_EOL . $new_line . PHP_EOL; } |
︙ | ︙ |
Modified src/include/lib/Garradin/Membres.php from [79cc6c1e41] to [c01bb47300].
︙ | ︙ | |||
290 291 292 293 294 295 296 | } public function getIDWithNumero($numero) { return DB::getInstance()->firstColumn('SELECT id FROM membres WHERE numero = ?;', (int) $numero); } | | > > > > > | > > > > > > > > > > > > > > > < | < < < | < | < | < < < | | < | < | | | < < < < < < < < < < < < < < < < | < < < | < | < < < < < < < < < < < < < < < < < < < < | 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 | } public function getIDWithNumero($numero) { return DB::getInstance()->firstColumn('SELECT id FROM membres WHERE numero = ?;', (int) $numero); } public function getSearchHeaderFields(array $result) { if (!count($result)) { return false; } $champs = Config::getInstance()->get('champs_membres'); $fields = []; foreach (reset($result) as $field=>$value) { if ($config = $champs->get($field)) { $fields[$field] = $config; } } return $fields; } public function sendMessage(array $recipients, $subject, $message, $send_copy) { $config = Config::getInstance(); foreach ($recipients as $recipient) { Utils::sendEmail(Utils::EMAIL_CONTEXT_BULK, $recipient->email, $subject, $message, $recipient->id); } if ($send_copy) { Utils::sendEmail(Utils::EMAIL_CONTEXT_BULK, $config->get('email_asso'), $subject, $message); } return true; } public function listAllByCategory($id_categorie) { return DB::getInstance()->get('SELECT id, email FROM membres WHERE id_categorie = ?;', (int)$id_categorie); } public function listByCategory($cat, $fields, $page = 1, $order = null, $desc = false) { $begin = ($page - 1) * self::ITEMS_PER_PAGE; $db = DB::getInstance(); |
︙ | ︙ | |||
454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 | } static protected function _deleteMembres($membres) { foreach ($membres as &$id) { $id = (int) $id; } Plugin::fireSignal('membre.suppression', $membres); $db = DB::getInstance(); // Suppression du membre return $db->delete('membres', $db->where('id', $membres)); } | > > > > > > > > > | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 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 | } static protected function _deleteMembres($membres) { foreach ($membres as &$id) { $id = (int) $id; // Suppression des fichiers liés $files = Fichiers::listLinkedFiles(Fichiers::LIEN_MEMBRES, $id, null); foreach ($files as $file) { $file = new Fichiers($file->id, $file); $file->remove(); } } Plugin::fireSignal('membre.suppression', $membres); $db = DB::getInstance(); // Suppression du membre return $db->delete('membres', $db->where('id', $membres)); } } |
Modified src/include/lib/Garradin/Membres/Categories.php from [af4fccf952] to [5b61a5fe1b].
︙ | ︙ | |||
45 46 47 48 49 50 51 | } } public function add($data) { $this->_checkData($data); | < < < < < | 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | } } public function add($data) { $this->_checkData($data); foreach ($this->droits as $key=>$value) { if (!isset($data['droit_'.$key])) $data['droit_'.$key] = $value; else $data['droit_'.$key] = (int)$data['droit_'.$key]; } |
︙ | ︙ |
Modified src/include/lib/Garradin/Membres/Champs.php from [6839687f0f] to [a027cb81e3].
︙ | ︙ | |||
248 249 250 251 252 253 254 | } elseif ($config->type == 'number' || $config->type == 'multiple') { $rules[] = 'numeric'; } elseif ($config->type == 'select') { | | | 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 | } elseif ($config->type == 'number' || $config->type == 'multiple') { $rules[] = 'numeric'; } elseif ($config->type == 'select') { $rules[] = 'in:' . range(0, count($config->options) - 1); } elseif ($config->type == 'checkbox') { $rules[] = 'boolean'; } if ($name == 'passe') |
︙ | ︙ | |||
528 529 530 531 532 533 534 | /** * Enregistre les changements de champs en base de données * @param boolean $enable_copy Recopier les anciennes champs dans les nouveaux ? * @return boolean true */ public function save($enable_copy = true) { | | | | | | | | | | > | 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 | /** * Enregistre les changements de champs en base de données * @param boolean $enable_copy Recopier les anciennes champs dans les nouveaux ? * @return boolean true */ public function save($enable_copy = true) { $db = DB::getInstance(); $config = Config::getInstance(); // Champs à créer $create = [ 'id INTEGER PRIMARY KEY, -- Numéro attribué automatiquement', 'id_categorie INTEGER NOT NULL,', 'date_connexion TEXT NULL CHECK (date_connexion IS NULL OR datetime(date_connexion) = date_connexion), -- Date de dernière connexion', 'date_inscription TEXT NOT NULL DEFAULT CURRENT_DATE CHECK (date(date_inscription) IS NOT NULL AND date(date_inscription) = date_inscription), -- Date d\'inscription', 'secret_otp TEXT NULL, -- Code secret pour TOTP', 'clef_pgp TEXT NULL, -- Clé publique PGP' ]; // Clés à créer, permet aussi de clôturer la syntaxe du tableau, noter l'absence de virgule dans cette ligne $create_keys = [ 'FOREIGN KEY (id_categorie) REFERENCES membres_categories (id)' ]; // Champs à recopier $copy = [ 'id' => 'id', |
︙ | ︙ |
Modified src/include/lib/Garradin/Membres/Cotisations.php from [05dee5b004] to [a0fca4e3fd].
︙ | ︙ | |||
259 260 261 262 263 264 265 266 | $champ_id = Config::getInstance()->get('champ_identite'); if (empty($order)) $order = 'date'; switch ($order) { case 'date': | > > | | 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 | $champ_id = Config::getInstance()->get('champ_identite'); if (empty($order)) $order = 'date'; switch ($order) { case 'a_jour': break; case 'date': $order = 'cm.date'; break; case 'identite': $order = 'transliterate_to_ascii('.$champ_id.') COLLATE NOCASE'; break; default: $order = 'cm.id_membre'; break; } |
︙ | ︙ |
Modified src/include/lib/Garradin/Membres/Import.php from [032b787733] to [f63328115c].
1 2 3 4 5 6 7 8 9 10 | <?php namespace Garradin\Membres; use Garradin\Membres; use Garradin\Config; use Garradin\DB; use Garradin\Utils; use Garradin\UserException; | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < | < | < | < < < < < < < < < | < > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | > | > | > > | > > | > > > > > > > > | > > > > > > | > < < | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | <?php namespace Garradin\Membres; use Garradin\Membres; use Garradin\Config; use Garradin\DB; use Garradin\Utils; use Garradin\UserException; class Import { public function getCSVAsArray($path) { if (!file_exists($path) || !is_readable($path)) { throw new \RuntimeException('Fichier inconnu : '.$path); } $fp = fopen($path, 'r'); if (!$fp) { return false; } $delim = Utils::find_csv_delim($fp); Utils::skip_bom($fp); $line = 0; $out = []; $nb_columns = null; while (!feof($fp)) { $row = fgetcsv($fp, 4096, $delim); $line++; if (empty($row)) { continue; } if (null === $nb_columns) { $nb_columns = count($row); } if (count($row) != $nb_columns) { throw new UserException('Erreur sur la ligne ' . $line . ' : incohérence dans le nombre de colonnes avec la première ligne.'); } $out[$line] = $row; } fclose($fp); return $out; } /** * Importer un CSV générique * @param string $path Chemin vers le CSV * @param array $translation_table Tableau indiquant la correspondance à effectuer entre les colonnes * du CSV et les champs de Garradin. Par exemple : ['Date création fiche' => 'date_inscription'] * @return boolean TRUE en cas de succès */ public function fromArray(array $table, $translation_table, $skip_lines = 0) { $db = DB::getInstance(); $db->begin(); $membres = new Membres; $champs = Config::getInstance()->get('champs_membres'); $nb_columns = count($translation_table); if ($skip_lines) { $table = array_slice($table, $skip_lines, null, true); } foreach ($table as $line => $row) { if (empty($row)) { continue; } if (count($row) != $nb_columns) { $db->rollback(); throw new UserException('Erreur sur la ligne ' . $line . ' : le nombre de colonnes est incorrect.'); } $data = []; foreach ($translation_table as $column_index => $garradin_field) { // Champs qu'on ne veut pas importer if (empty($garradin_field)) { continue; } // Concaténer plusieurs champs, si on choisit d'indiquer plusieurs fois // le même champ pour plusieurs colonnes (par exemple pour mettre nom et prénom // dans un seul champ) if (isset($data[$garradin_field])) { $champ = $champs->get($garradin_field); if ($champ->type == 'text') { $data[$garradin_field] .= ' ' . $row[$column_index]; } elseif ($champ->type == 'textarea') { $data[$garradin_field] .= "\n" . $row[$column_index]; } else { throw new UserException(sprintf('Erreur sur la ligne %d : impossible de concaténer des colonnes avec le champ %s : n\'est pas un champ de type texte', $line, $champ->title)); } } else { $data[$garradin_field] = $row[$column_index]; } } try { $membres->add($data, false); } catch (UserException $e) { $db->rollback(); throw new UserException('Erreur sur la ligne ' . $line . ' : ' . $e->getMessage()); } } $db->commit(); return true; } /** * Importer un CSV de la liste des membres depuis un export Garradin * @param string $path Chemin vers le CSV * @param int $current_user_id * @return boolean TRUE en cas de succès */ public function fromGarradinCSV($path, $current_user_id) { if (!file_exists($path) || !is_readable($path)) { throw new \RuntimeException('Fichier inconnu : '.$path); } $fp = fopen($path, 'r'); |
︙ | ︙ | |||
260 261 262 263 264 265 266 | $db->commit(); fclose($fp); return true; } | | | | | > | | > > | < | < < | | < < | < < < | < | < < < | < < | < | | | | | | < < | < | < < < < < < < < | 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 | $db->commit(); fclose($fp); return true; } protected function export(array $list = null) { $db = DB::getInstance(); $champs = Config::getInstance()->get('champs_membres')->getKeys(); $champs_sql = 'm.' . implode(', m.', $champs); $where = $list ? 'WHERE ' . $db->where('m.id', $list) : ''; $res = $db->iterate('SELECT ' . $champs_sql . ', c.nom AS "Catégorie membre" FROM membres AS m INNER JOIN membres_categories AS c ON m.id_categorie = c.id ' . $where . ' ORDER BY c.id;'); return [ array_keys((array) $res->current()), $res, sprintf('Export membres - %s - %s', Config::getInstance()->get('nom_asso'), date('Y-m-d')), ]; } public function toCSV(array $list = null) { list($champs, $result, $name) = $this->export($list); return Utils::toCSV($name, $result, $champs); } public function toODS(array $list = null) { list($champs, $result, $name) = $this->export($list); return Utils::toODS($name, $result, $champs); } } |
Modified src/include/lib/Garradin/Membres/Session.php from [b9cd12a177] to [76f4ec5c54].
1 2 3 4 5 6 7 8 9 10 11 12 13 | <?php namespace Garradin\Membres; use Garradin\Config; use Garradin\DB; use Garradin\Utils; use Garradin\Membres; use Garradin\UserException; use const Garradin\SECRET_KEY; use const Garradin\WWW_URL; use const Garradin\ADMIN_URL; | < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <?php namespace Garradin\Membres; use Garradin\Config; use Garradin\DB; use Garradin\Utils; use Garradin\Membres; use Garradin\UserException; use const Garradin\SECRET_KEY; use const Garradin\WWW_URL; use const Garradin\ADMIN_URL; use KD2\Security; use KD2\Security_OTP; use KD2\QRCode; class Session extends \KD2\UserSession { |
︙ | ︙ | |||
108 109 110 111 112 113 114 | protected function deleteAllRememberMeSelectors($user_id) { return $this->db->delete('membres_sessions', $this->db->where('id_membre', $user_id)); } // Ajout de la gestion de LOCAL_LOGIN | | | > > | > | 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | protected function deleteAllRememberMeSelectors($user_id) { return $this->db->delete('membres_sessions', $this->db->where('id_membre', $user_id)); } // Ajout de la gestion de LOCAL_LOGIN public function isLogged($disable_local_login = false) { $logged = parent::isLogged(); if (!$disable_local_login && defined('\Garradin\LOCAL_LOGIN') && is_int(\Garradin\LOCAL_LOGIN) && \Garradin\LOCAL_LOGIN > 0) { if (!$logged || ($logged && $this->user->id != \Garradin\LOCAL_LOGIN)) { $logged = $this->create(\Garradin\LOCAL_LOGIN); } } return $logged; } // Ici checkOTP utilise NTP en second recours public function checkOTP($secret, $code) |
︙ | ︙ | |||
189 190 191 192 193 194 195 | $query = sprintf('%s.%s.%s', $id, $expire, $hash); $message = "Bonjour,\n\nVous avez oublié votre mot de passe ? Pas de panique !\n\n"; $message.= "Il vous suffit de cliquer sur le lien ci-dessous pour recevoir un nouveau mot de passe.\n\n"; $message.= ADMIN_URL . 'password.php?c=' . $query; $message.= "\n\nSi vous n'avez pas demandé à recevoir ce message, ignorez-le, votre mot de passe restera inchangé."; | | < | 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 | $query = sprintf('%s.%s.%s', $id, $expire, $hash); $message = "Bonjour,\n\nVous avez oublié votre mot de passe ? Pas de panique !\n\n"; $message.= "Il vous suffit de cliquer sur le lien ci-dessous pour recevoir un nouveau mot de passe.\n\n"; $message.= ADMIN_URL . 'password.php?c=' . $query; $message.= "\n\nSi vous n'avez pas demandé à recevoir ce message, ignorez-le, votre mot de passe restera inchangé."; return Utils::sendEmail(Utils::EMAIL_CONTEXT_SYSTEM, $membre->email, 'Mot de passe perdu ?', $message, $membre->id, $membre->clef_pgp); } static public function recoverPasswordConfirm($code) { if (substr_count($code, '.') !== 2) { return false; |
︙ | ︙ | |||
241 242 243 244 245 246 247 | $message.= "Votre nouveau mot de passe : ".$password."\n\n"; $message.= "Si vous n'avez pas demandé à recevoir ce message, merci de nous le signaler."; $password = Membres::hashPassword($password); $db->update('membres', ['passe' => $password], 'id = :id', ['id' => (int)$id]); | | | | 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 | $message.= "Votre nouveau mot de passe : ".$password."\n\n"; $message.= "Si vous n'avez pas demandé à recevoir ce message, merci de nous le signaler."; $password = Membres::hashPassword($password); $db->update('membres', ['passe' => $password], 'id = :id', ['id' => (int)$id]); return Utils::sendEmail(Utils::EMAIL_CONTEXT_SYSTEM, $membre->email, 'Nouveau mot de passe', $message, $membre->id, $membre->clef_pgp); } public function editUser($data) { (new Membres)->edit($this->user->id, $data, false); $this->refresh(false); return true; } public function canAccess($category, $permission) { if (!$this->user) |
︙ | ︙ | |||
286 287 288 289 290 291 292 | return $out; } public function sendMessage($dest, $sujet, $message, $copie = false) { $user = $this->getUser(); | < > | | < | | | | 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 | return $out; } public function sendMessage($dest, $sujet, $message, $copie = false) { $user = $this->getUser(); $content = "Ce message vous a été envoyé par :\n"; $content.= sprintf("%s\n%s\n\n", $user->identite, $user->email); $content.= str_repeat('=', 70) . "\n\n"; $content.= $message; if ($copie) { Utils::sendEmail(Utils::EMAIL_CONTEXT_PRIVATE, $user->email, $sujet, $content, $user->id); } return Utils::sendEmail(Utils::EMAIL_CONTEXT_PRIVATE, $dest, $sujet, $content); } public function editSecurity(Array $data = []) { $allowed_fields = ['passe', 'clef_pgp', 'secret_otp']; foreach ($data as $key=>$value) |
︙ | ︙ | |||
339 340 341 342 343 344 345 | { throw new UserException('Clé PGP invalide : impossible d\'extraire l\'empreinte.'); } } $db = DB::getInstance(); $db->update('membres', $data, $db->where('id', (int)$this->user->id)); | | | 339 340 341 342 343 344 345 346 347 348 349 350 | { throw new UserException('Clé PGP invalide : impossible d\'extraire l\'empreinte.'); } } $db = DB::getInstance(); $db->update('membres', $data, $db->where('id', (int)$this->user->id)); $this->refresh(false); return true; } } |
Modified src/include/lib/Garradin/Plugin.php from [a13d03f59d] to [45828504b6].
1 2 3 4 5 6 7 8 9 10 11 12 13 | <?php namespace Garradin; class Plugin { protected $id = null; protected $plugin = null; protected $config_changed = false; protected $mimes = [ 'css' => 'text/css', 'gif' => 'image/gif', | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <?php namespace Garradin; class Plugin { const PLUGIN_ID_SYNTAX = '[a-z]+(?:_[a-z]+)*'; protected $id = null; protected $plugin = null; protected $config_changed = false; protected $mimes = [ 'css' => 'text/css', 'gif' => 'image/gif', |
︙ | ︙ | |||
21 22 23 24 25 26 27 | 'pdf' => 'application/pdf', 'png' => 'image/png', 'swf' => 'application/shockwave-flash', 'xml' => 'text/xml', 'svg' => 'image/svg+xml', ]; | < < | > > | > > > | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | 'pdf' => 'application/pdf', 'png' => 'image/png', 'swf' => 'application/shockwave-flash', 'xml' => 'text/xml', 'svg' => 'image/svg+xml', ]; static public function getPath($id, $fail_with_exception = true) { if (file_exists(PLUGINS_ROOT . '/' . $id . '.tar.gz')) { return 'phar://' . PLUGINS_ROOT . '/' . $id . '.tar.gz'; } elseif (is_dir(PLUGINS_ROOT . '/' . $id)) { return PLUGINS_ROOT . '/' . $id; } if ($fail_with_exception) { throw new \LogicException(sprintf('Le plugin "%s" n\'existe pas dans le répertoire des plugins.', $id)); } return false; } /** * Construire un objet Plugin pour un plugin * @param string $id Identifiant du plugin * @throws UserException Si le plugin n'est pas installé (n'existe pas en DB) */ |
︙ | ︙ | |||
58 59 60 61 62 63 64 65 66 67 68 69 70 71 | $this->plugin->config = json_decode($this->plugin->config); if (!is_object($this->plugin->config)) { $this->plugin->config = new \stdClass; } $this->id = $id; } /** * Enregistrer les changements dans la config */ | > > > | 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | $this->plugin->config = json_decode($this->plugin->config); if (!is_object($this->plugin->config)) { $this->plugin->config = new \stdClass; } // Juste pour vérifier que le fichier source du plugin existe bien self::getPath($id); $this->id = $id; } /** * Enregistrer les changements dans la config */ |
︙ | ︙ | |||
186 187 188 189 190 191 192 | $file = preg_replace('!^[./]*!', '', $file); if (preg_match('!(?:\.\.|[/\\\\]\.|\.[/\\\\])!', $file)) { throw new \RuntimeException('Chemin de fichier incorrect.'); } | | | 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 | $file = preg_replace('!^[./]*!', '', $file); if (preg_match('!(?:\.\.|[/\\\\]\.|\.[/\\\\])!', $file)) { throw new \RuntimeException('Chemin de fichier incorrect.'); } $forbidden = ['install.php', 'garradin_plugin.ini', 'upgrade.php', 'uninstall.php']; if (in_array($file, $forbidden)) { throw new UserException('Le fichier ' . $file . ' ne peut être appelé par cette méthode.'); } if (!file_exists($this->path() . '/www/' . $file)) |
︙ | ︙ | |||
258 259 260 261 262 263 264 | * Renvoie TRUE si le plugin a besoin d'être mis à jour * (si la version notée dans la DB est différente de la version notée dans garradin_plugin.ini) * @return boolean TRUE si le plugin doit être mis à jour, FALSE sinon */ public function needUpgrade() { $infos = (object) parse_ini_file($this->path() . '/garradin_plugin.ini', false); | | | 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 | * Renvoie TRUE si le plugin a besoin d'être mis à jour * (si la version notée dans la DB est différente de la version notée dans garradin_plugin.ini) * @return boolean TRUE si le plugin doit être mis à jour, FALSE sinon */ public function needUpgrade() { $infos = (object) parse_ini_file($this->path() . '/garradin_plugin.ini', false); if (version_compare($this->plugin->version, $infos->version, '!=')) return true; return false; } /** |
︙ | ︙ | |||
280 281 282 283 284 285 286 | { $plugin = $this; include $this->path() . '/upgrade.php'; } $infos = (object) parse_ini_file($this->path() . '/garradin_plugin.ini', false); | | > > > > | < > > | < > > > > > > > > | 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 | { $plugin = $this; include $this->path() . '/upgrade.php'; } $infos = (object) parse_ini_file($this->path() . '/garradin_plugin.ini', false); return DB::getInstance()->update('plugins', [ 'nom' => $infos->nom, 'description'=> $infos->description, 'auteur' => $infos->auteur, 'url' => $infos->url, 'version' => $infos->version, 'menu' => (int)(bool)$infos->menu, 'menu_condition' => $infos->menu && isset($infos->menu_condition) ? trim($infos->menu_condition) : null, ], 'id = :id', ['id' => $this->id]); } /** * Associer un signal à un callback du plugin * @param string $signal Nom du signal (par exemple boucle.agenda pour la boucle de type AGENDA) * @param mixed $callback Callback, sous forme d'un nom de fonction ou de méthode statique * @return boolean TRUE */ public function registerSignal($signal, $callback) { $callable_name = ''; if (!is_callable($callback, true, $callable_name) || !is_string($callable_name)) { throw new \LogicException('Le callback donné n\'est pas valide.'); } // pour empêcher d'appeler des méthodes de Garradin après un import de base de données "hackée" if (strpos($callable_name, 'Garradin\\Plugin\\') !== 0) { throw new \LogicException('Le callback donné n\'utilise pas le namespace Garradin\\Plugin'); } $db = DB::getInstance(); // Signaux exclusifs, qui ne peuvent être attribués qu'à un seul plugin if (strpos($signal, 'boucle.') === 0) { $registered = $db->firstColumn('SELECT plugin FROM plugins_signaux WHERE signal = ? AND plugin != ?;', $signal, $this->id); if ($registered) { throw new \LogicException('Le signal ' . $signal . ' est exclusif et déjà associé au plugin "'.$registered.'"'); } } $callable_name = str_replace('Garradin\\Plugin\\', '', $callable_name); $st = $db->prepare('INSERT OR REPLACE INTO plugins_signaux VALUES (:signal, :plugin, :callback);'); $st->bindValue(':signal', $signal); $st->bindValue(':plugin', $this->id); $st->bindValue(':callback', $callable_name); return $st->execute(); } |
︙ | ︙ | |||
335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 | $db = DB::getInstance(); $plugins = $db->getGrouped('SELECT id, * FROM plugins ORDER BY nom;'); $system = explode(',', PLUGINS_SYSTEM); foreach ($plugins as &$row) { $row->system = in_array($row->id, $system); } return $plugins; } /** * Vérifie que les plugins système sont bien installés et sinon les réinstalle * @return void */ static public function checkAndInstallSystemPlugins() { $system = explode(',', PLUGINS_SYSTEM); if (count($system) == 0) { return true; } | > > > > > > | 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 380 381 382 383 384 385 | $db = DB::getInstance(); $plugins = $db->getGrouped('SELECT id, * FROM plugins ORDER BY nom;'); $system = explode(',', PLUGINS_SYSTEM); foreach ($plugins as &$row) { $row->system = in_array($row->id, $system); $row->disabled = !self::getPath($row->id, false); } return $plugins; } /** * Vérifie que les plugins système sont bien installés et sinon les réinstalle * @return void */ static public function checkAndInstallSystemPlugins() { if (!PLUGINS_SYSTEM) { return true; } $system = explode(',', PLUGINS_SYSTEM); if (count($system) == 0) { return true; } |
︙ | ︙ | |||
375 376 377 378 379 380 381 | return true; } /** * Liste les plugins qui doivent être affichés dans le menu * @return array Tableau associatif id => nom (ou un tableau vide si aucun plugin ne doit être affiché) */ | | > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | 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 483 484 485 486 487 488 489 490 491 | return true; } /** * Liste les plugins qui doivent être affichés dans le menu * @return array Tableau associatif id => nom (ou un tableau vide si aucun plugin ne doit être affiché) */ static public function listMenu($user) { self::checkAndInstallSystemPlugins(); $db = DB::getInstance(); $list = $db->getGrouped('SELECT id, nom, menu_condition FROM plugins WHERE menu = 1 ORDER BY nom;'); foreach ($list as $id => &$row) { if (!self::getPath($row->id, false)) { // Ne pas lister les plugins dont le code a disparu unset($list[$id]); continue; } if (!$row->menu_condition) { $row = $row->nom; continue; } $condition = strtr($row->menu_condition, [ '{Membres::DROIT_AUCUN}' => Membres::DROIT_AUCUN, '{Membres::DROIT_ACCES}' => Membres::DROIT_ACCES, '{Membres::DROIT_ECRITURE}' => Membres::DROIT_ECRITURE, '{Membres::DROIT_ADMIN}' => Membres::DROIT_ADMIN, ]); $condition = preg_replace_callback('/\{\$user\.(\w+)\}/', function ($m) use ($user) { return $user->{$m[1]}; }, $condition); $query = 'SELECT 1 WHERE ' . $condition . ';'; $st = $db->prepare($query); if (!$st->readOnly()) { throw new \LogicException('Requête plugin pour affichage dans le menu n\'est pas en lecture : ' . $query); } $res = $st->execute(); if (!$res->fetchArray(\SQLITE3_NUM)) { unset($list[$id]); continue; } $row = $row->nom; } unset($row); return $list; } /** * Liste les plugins téléchargés mais non installés * @return array Liste des plugins téléchargés */ static public function listDownloaded() { $installed = self::listInstalled(); $list = []; $dir = dir(PLUGINS_ROOT); while ($file = $dir->read()) { if (substr($file, 0, 1) == '.') continue; if (preg_match('!^(' . self::PLUGIN_ID_SYNTAX . ')\.tar\.gz$!', $file, $match)) { // Sélectionner les archives PHAR $file = $match[1]; } elseif (is_dir(PLUGINS_ROOT . '/' . $file) && preg_match('!^' . self::PLUGIN_ID_SYNTAX . '$!', $file) && is_file(sprintf('%s/%s/garradin_plugin.ini', PLUGINS_ROOT, $file))) { // Rien à faire, le nom valide du plugin est déjà dans "$file" } else { // ignorer tout ce qui n'est pas un répertoire ou une archive PHAR valides |
︙ | ︙ | |||
547 548 549 550 551 552 553 | catch (\Exception $e) { throw new UserException('Le téléchargement du plugin '.$id.' a échoué : ' . $e->getMessage()); } if (!self::checkHash($id)) { | | | 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 | catch (\Exception $e) { throw new UserException('Le téléchargement du plugin '.$id.' a échoué : ' . $e->getMessage()); } if (!self::checkHash($id)) { Utils::safe_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; } |
︙ | ︙ | |||
635 636 637 638 639 640 641 642 643 644 645 646 647 648 | 'officiel' => (int)(bool)$official, 'nom' => $infos->nom, 'description'=> $infos->description, 'auteur' => $infos->auteur, 'url' => $infos->url, 'version' => $infos->version, 'menu' => (int)(bool)$infos->menu, 'config' => $config, ]); if (file_exists($path . '/install.php')) { $plugin = new Plugin($id); require $plugin->path() . '/install.php'; | > | 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 | 'officiel' => (int)(bool)$official, 'nom' => $infos->nom, 'description'=> $infos->description, 'auteur' => $infos->auteur, 'url' => $infos->url, 'version' => $infos->version, 'menu' => (int)(bool)$infos->menu, 'menu_condition' => $infos->menu && isset($infos->menu_condition) ? trim($infos->menu_condition) : null, 'config' => $config, ]); if (file_exists($path . '/install.php')) { $plugin = new Plugin($id); require $plugin->path() . '/install.php'; |
︙ | ︙ | |||
665 666 667 668 669 670 671 | /** * Déclenche le signal donné auprès des plugins enregistrés * @param string $signal Nom du signal * @param array $params Paramètres du callback (array ou null) * @return NULL NULL si aucun plugin n'a été appelé, true sinon */ | | > > > | < > | > | | > | | 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 | /** * Déclenche le signal donné auprès des plugins enregistrés * @param string $signal Nom du signal * @param array $params Paramètres du callback (array ou null) * @return NULL NULL si aucun plugin n'a été appelé, true sinon */ static public function fireSignal($signal, $params = null, &$callback_return = null) { $list = DB::getInstance()->get('SELECT * FROM plugins_signaux WHERE signal = ?;', $signal); $system = explode(',', PLUGINS_SYSTEM); foreach ($list as $row) { // Ne pas appeler les plugins dont le code n'existe pas/plus, // SAUF si c'est un plugin système (auquel cas ça fera une erreur) if (!self::getPath($row->plugin, in_array($row->plugin, $system))) { continue; } $return = call_user_func_array('Garradin\\Plugin\\' . $row->callback, [&$params, &$callback_return]); if ($return) { return $return; } } return !empty($list) ? false : null; } } |
Modified src/include/lib/Garradin/Rappels_Envoyes.php from [4ab2f9f384] to [fcaa354186].
︙ | ︙ | |||
146 147 148 149 150 151 152 | $replace['nb_jours'] = abs($replace['nb_jours']); $replace['delai'] = abs($replace['delai']); $subject = $this->replaceTagsInContent($data->sujet, $replace); $text = $this->replaceTagsInContent($data->texte, $replace); // Envoi du mail | | | 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | $replace['nb_jours'] = abs($replace['nb_jours']); $replace['delai'] = abs($replace['delai']); $subject = $this->replaceTagsInContent($data->sujet, $replace); $text = $this->replaceTagsInContent($data->texte, $replace); // Envoi du mail Utils::sendEmail(Utils::EMAIL_CONTEXT_PRIVATE, $data->email, $subject, $text, $data->id); // Enregistrement en DB $this->add([ 'id_cotisation' => $data->id_cotisation, 'id_membre' => $data->id, 'id_rappel' => $data->id_rappel, 'media' => Rappels_Envoyes::MEDIA_EMAIL, |
︙ | ︙ |
Added src/include/lib/Garradin/Recherche.php version [a738c3a98e].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 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 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 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 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 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 | <?php namespace Garradin; class Recherche { const TYPE_JSON = 'json'; const TYPE_SQL = 'sql'; const TARGETS = [ 'membres', 'compta_journal', ]; protected function _checkFields($data) { $db = DB::getInstance(); if (array_key_exists('intitule', $data) && trim($data['intitule']) === '') { throw new UserException('Le champ intitulé ne peut être vide.'); } if (array_key_exists('id_membre', $data) && null !== $data['id_membre']) { $data['id_membre'] = (int)$data['id_membre']; } if (array_key_exists('id_membre', $data) && null !== $data['id_membre'] && !$db->test('membres', 'id = ?', $data['id_membre'])) { throw new \InvalidArgumentException('Numéro d\'utilisateur inconnu.'); } if (array_key_exists('type', $data) && $data['type'] !== self::TYPE_SQL && $data['type'] !== self::TYPE_JSON) { throw new \InvalidArgumentException('Type de recherche inconnu.'); } if (array_key_exists('cible', $data) && !in_array($data['cible'], self::TARGETS, true)) { throw new \InvalidArgumentException('Cible de recherche invalide.'); } $query = null; if (array_key_exists('type', $data)) { if (empty($data['contenu'])) { throw new UserException('Le contenu ne peut être vide.'); } if ($data['type'] == self::TYPE_SQL && !is_string($data['contenu'])) { throw new \InvalidArgumentException('Recherche invalide pour le type SQL'); } $query = $data['contenu']; if ($data['type'] == self::TYPE_JSON) { if (!is_array($query)) { throw new \InvalidArgumentException('Recherche invalide pour le type JSON'); } $query = json_encode($query); if (!json_decode($query)) { throw new \InvalidArgumentException('JSON invalide pour le type JSON'); } } } return $query; } public function edit($id, $data) { $allowed = ['intitule', 'id_membre', 'type', 'cible', 'contenu']; // Supprimer les champs qui ne sont pas ceux de la BDD $data = array_intersect_key($data, array_flip($allowed)); $query = $this->_checkFields($data); if (isset($data['contenu'])) { $data['contenu'] = $query; } return DB::getInstance()->update('recherches', $data, 'id = ' . (int)$id); } public function add($intitule, $id_membre, $type, $cible, $contenu) { $data = compact('intitule', 'id_membre', 'type', 'cible', 'contenu'); $data['contenu'] = $this->_checkFields($data); $db = DB::getInstance(); $db->insert('recherches', $data); return $db->lastInsertRowId(); } public function remove($id) { return DB::getInstance()->delete('recherches', 'id = ?', (int) $id); } public function get($id) { $r = DB::getInstance()->first('SELECT * FROM recherches WHERE id = ?;', (int) $id); if ($r && $r->type == self::TYPE_JSON) { $q = json_decode($r->contenu, true); $r->query = $q['query']; $r->order = $q['order']; $r->desc = $q['desc']; $r->limit = $q['limit']; unset($q); } return $r; } public function getList($id_membre, $cible) { return DB::getInstance()->get('SELECT id, type, intitule, type, id_membre FROM recherches WHERE (id_membre IS NULL OR id_membre = ?) AND cible = ? ORDER BY intitule;', (int)$id_membre, $cible); } /** * Lancer une recherche enregistrée */ public function search($id, $force_select = null) { $search = $this->get($id); if (!$search) { return false; } if ($search->type == self::TYPE_JSON) { $search->contenu = $this->buildQuery($search->cible, $search->query, $search->order, $search->desc, $search->limit); } return $this->searchSQL($search->cible, $search->contenu, $force_select); } /** * Renvoie la liste des colonnes d'une cible */ public function getColumns($target) { $columns = []; $db = DB::getInstance(); if ($target == 'membres') { $champs = Config::getInstance()->get('champs_membres'); $columns['id_categorie'] = (object) [ 'realType' => 'select', 'textMatch'=> false, 'label' => 'Catégorie', 'type' => 'enum', 'null' => false, 'values' => $db->getAssoc('SELECT id, nom FROM membres_categories ORDER BY nom;'), ]; foreach ($champs->getList() as $champ => $config) { $column = (object) [ 'realType' => $config->type, 'textMatch'=> $champs->isText($champ), 'label' => $config->title, 'type' => 'text', 'null' => $config->mandatory ? false : true, ]; if ($config->type == 'checkbox') { $column->type = 'boolean'; } elseif ($config->type == 'select') { $column->type = 'enum'; $column->values = array_combine($config->options, $config->options); } elseif ($config->type == 'multiple') { $column->type = 'bitwise'; $column->values = $config->options; } elseif ($config->type == 'date' || $config->type == 'datetime') { $column->type = $config->type; } elseif ($config->type == 'number' || $champ == 'numero') { $column->type = 'integer'; } $columns[$champ] = $column; } } return $columns; } /** * Construire une recherche SQL à partir d'un objet généré par QueryBuilder * @param string $target Cible de la requête : membres, compta_journal, etc. * @param array $groups Groupes de critères * @param string $order Ordre de tri * @param boolean $desc Inverser le tri * @param integer $limit Limite * @return string Chaîne SQL */ public function buildQuery($target, array $groups, $order, $desc = false, $limit = 100) { if (!in_array($target, self::TARGETS, true)) { throw new \InvalidArgumentException('Cible inconnue : ' . $target); } if ($target == 'membres') { $config = Config::getInstance(); $champs = $config->get('champs_membres'); } $db = DB::getInstance(); $target_columns = $this->getColumns($target); $query_columns = []; $query_groups = []; static $no_transform_operators = ['IS NULL', 'IS NOT NULL', '= 0', '= 1', '&']; foreach ($groups as $group) { if (!isset($group['conditions'], $group['operator']) || !is_array($group['conditions']) || ($group['operator'] != 'AND' && $group['operator'] != 'OR')) { // Ignorer les groupes de conditions invalides continue; } $query_group_conditions = []; foreach ($group['conditions'] as $condition) { if (!isset($condition['column'], $condition['operator']) || (isset($condition['values']) && !is_array($condition['values']))) { // Ignorer les conditions invalides continue; } if (!array_key_exists($condition['column'], $target_columns)) { // Ignorer une condition qui se rapporte à une colonne // qui n'existe pas, cas possible si on reprend une recherche // après avoir modifié les fiches de membres throw new UserException('Cette recherche fait référence à un champ qui n\'existe plus dans les fiches de membres.'); } $query_columns[] = $condition['column']; $column = $target_columns[$condition['column']]; if ($column->textMatch == 'text' && !in_array($condition['operator'], $no_transform_operators)) { $query = sprintf('transliterate_to_ascii(%s) COLLATE NOCASE %s', $db->quoteIdentifier($condition['column']), $condition['operator']); } else { $query = sprintf('%s %s', $db->quoteIdentifier($condition['column']), $condition['operator']); } $values = isset($condition['values']) ? $condition['values'] : []; $values = array_map(['Garradin\Utils', 'transliterateToAscii'], $values); if ($column->type == 'tel') { // Normaliser le numéro de téléphone $values = array_map(['Garradin\Utils', 'normalizePhoneNumber'], $values); } // L'opérateur binaire est un peu spécial if ($condition['operator'] == '&') { $new_query = []; foreach ($values as $value) { $new_query[] = sprintf('%s (1 << %d)', $query, (int) $value); } $query = '(' . implode(' AND ', $new_query) . ')'; } // Remplacement de liste elseif (strpos($query, '??') !== false) { $values = array_map([$db, 'quote'], $values); $query = str_replace('??', implode(', ', $values), $query); } // Remplacement de recherche LIKE elseif (preg_match('/%\?%|%\?|\?%/', $query, $match)) { $value = str_replace(['%_'], ['\\%', '\\_'], reset($values)); $value = str_replace('?', $value, $match[0]); $query = str_replace($match[0], sprintf('%s ESCAPE \'\\\'', $db->quote($value)), $query); } // Remplacement de paramètre elseif (strpos($query, '?') !== false) { $expected = substr_count($query, '?'); $found = count($values); if ($expected != $found) { throw new \RuntimeException(sprintf('Operator %s expects at least %d parameters, only %d supplied', $condition['operator'], $expected, $found)); } for ($i = 0; $i < $expected; $i++) { $pos = strpos($query, '?'); $query = substr_replace($query, $db->quote(array_shift($values)), $pos, 1); } } $query_group_conditions[] = $query; } if (count($query_group_conditions)) { $query_groups[] = implode(' ' . $group['operator'] . ' ', $query_group_conditions); } } if (!count($query_groups)) { throw new UserException('Aucune clause trouvée dans la recherche.'); } $query_columns = array_unique($query_columns); // Ajout du champ identité si pas présent if ($target == 'membres' && !in_array($config->get('champ_identite'), $query_columns)) { array_unshift($query_columns, $config->get('champ_identite')); } if ($target_columns[$order]->textMatch) { $order = sprintf('transliterate_to_ascii(%s) COLLATE NOCASE', $db->quoteIdentifier($order)); } else { $order = $db->quoteIdentifier($order); } $query_columns = array_map([$db, 'quoteIdentifier'], $query_columns); $sql_query = sprintf('SELECT id, %s FROM %s WHERE %s ORDER BY %s %s LIMIT %d;', implode(', ', $query_columns), $target, '(' . implode(') AND (', $query_groups) . ')', $order, $desc ? 'DESC' : 'ASC', (int) $limit); return $sql_query; } /** * Lancer une recherche SQL */ public function searchSQL($target, $query, $force_select = null) { if (!in_array($target, self::TARGETS, true)) { throw new \InvalidArgumentException('Cible inconnue : ' . $target); } $db = DB::getInstance(); if ($force_select) { $query = preg_replace('/^\s*SELECT.*FROM\s+/Ui', 'SELECT ' . $force_select . ' FROM ', $query); } if (!preg_match('/LIMIT\s+/i', $query)) { $query = preg_replace('/;?\s*$/', '', $query); $query .= ' LIMIT 100'; } if (preg_match('/;\s*(.+?)$/', $query)) { throw new UserException('Une seule requête peut être envoyée en même temps.'); } $st = $db->prepare($query); if (!$st->readOnly()) { throw new UserException('Seules les requêtes en lecture sont autorisées.'); } $res = $st->execute(); $out = []; while ($row = $res->fetchArray(SQLITE3_ASSOC)) { $out[] = (object) $row; } return $out; } public function schema($target) { $db = DB::getInstance(); if ($target == 'membres') { $tables = [ 'membres' => $db->firstColumn('SELECT sql FROM sqlite_master WHERE type = \'table\' AND name = \'membres\';'), 'categories'=> $db->firstColumn('SELECT sql FROM sqlite_master WHERE type = \'table\' AND name = \'membres_categories\';'), ]; } return $tables; } } |
Modified src/include/lib/Garradin/Sauvegarde.php from [ba865c4dc1] to [3200010089].
︙ | ︙ | |||
142 143 144 145 146 147 148 | { if (preg_match('!\.\.+!', $file) || !preg_match('!^[\w\d._-]+\.sqlite$!i', $file) || $file == basename(DB_FILE)) { throw new UserException('Nom de fichier non valide.'); } | | | 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | { if (preg_match('!\.\.+!', $file) || !preg_match('!^[\w\d._-]+\.sqlite$!i', $file) || $file == basename(DB_FILE)) { throw new UserException('Nom de fichier non valide.'); } return Utils::safe_unlink(DATA_ROOT . '/' . $file); } /** * Renvoie sur la sortie courante le contenu du fichier de base de données courant * @return boolean true */ public function dump() |
︙ | ︙ | |||
227 228 229 230 231 232 233 | } } $r = $this->restoreDB($file['tmp_name'], $user_id); if ($r) { | | | 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 | } } $r = $this->restoreDB($file['tmp_name'], $user_id); if ($r) { Utils::safe_unlink($file['tmp_name']); } return $r; } /** * Vérifie l'intégrité d'une sauvegarde Garradin |
︙ | ︙ |
Modified src/include/lib/Garradin/Squelette.php from [a6a2b8cd25] to [fc1698f7ac].
︙ | ︙ | |||
878 879 880 881 882 883 884 | static private function compile_store($tpl, $content) { $path = self::compile_get_path($tpl); if (!file_exists(dirname($path))) { | | > | > | 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 | static private function compile_store($tpl, $content) { $path = self::compile_get_path($tpl); if (!file_exists(dirname($path))) { Utils::safe_mkdir(dirname($path), 0777, true); } file_put_contents($path, $content); return true; } static public function compile_clear($tpl) { $path = self::compile_get_path($tpl); if (file_exists($path)) { Utils::safe_unlink($path); } return true; } protected function getVariable($var) { if (isset($this->current[$var])) |
︙ | ︙ | |||
951 952 953 954 955 956 957 | static public function resetSource($template) { if (!preg_match('!^[\w\d_-]+(?:\.[\w\d_-]+)*$!i', $template)) return false; if (file_exists(DATA_ROOT . '/www/squelettes/' . $template)) { | | | | 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 | static public function resetSource($template) { if (!preg_match('!^[\w\d_-]+(?:\.[\w\d_-]+)*$!i', $template)) return false; if (file_exists(DATA_ROOT . '/www/squelettes/' . $template)) { return Utils::safe_unlink(DATA_ROOT . '/www/squelettes/' . $template); } return false; } static public function listSources() { if (!file_exists(DATA_ROOT . '/www/squelettes')) { Utils::safe_mkdir(DATA_ROOT . '/www/squelettes', 0775, true); } $sources = []; $dir = dir(ROOT . '/www/squelettes-dist'); while ($file = $dir->read()) |
︙ | ︙ |
Modified src/include/lib/Garradin/Squelette_Filtres.php from [b4203fb585] to [a2925f4fde].
︙ | ︙ | |||
251 252 253 254 255 256 257 | static public function supprimer_tags($value, $replace = '') { return preg_replace('!<[^>]*>!', $replace, $value); } static public function supprimer_skriv($value) { | < < < | | | 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 | static public function supprimer_tags($value, $replace = '') { return preg_replace('!<[^>]*>!', $replace, $value); } static public function supprimer_skriv($value) { $value = self::formatter_texte($value); return self::supprimer_tags($value); } static public function couper($texte, $taille, $etc = ' (...)') { if (strlen($texte) > $taille) { $texte = substr($texte, 0, $taille); |
︙ | ︙ |
Modified src/include/lib/Garradin/Static_Cache.php from [453588f5aa] to [1abb2553b4].
︙ | ︙ | |||
9 10 11 12 13 14 15 | protected static function _getCacheDir() { $dir = CACHE_ROOT . '/static'; if (!file_exists($dir)) { | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | protected static function _getCacheDir() { $dir = CACHE_ROOT . '/static'; if (!file_exists($dir)) { Utils::safe_mkdir(CACHE_ROOT . '/static', 0777, true); } return CACHE_ROOT . '/static'; } protected static function _getCachePath($id) { |
︙ | ︙ | |||
82 83 84 85 86 87 88 | { return file_exists(self::_getCachePath($id)); } static public function remove($id) { $path = self::_getCachePath($id); | | | | 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | { return file_exists(self::_getCachePath($id)); } static public function remove($id) { $path = self::_getCachePath($id); return Utils::safe_unlink($path); } static public function clean($expire = self::CLEAN_EXPIRE) { $dir = self::_getCacheDir(); $d = dir($dir); $expire = time() - $expire; while ($file = $d->read()) { if ($file[0] == '.') { continue; } if (filemtime($dir . '/' . $file) > $expire) { Utils::safe_unlink($dir . '/' . $file); } } $d->close(); return true; } } |
Modified src/include/lib/Garradin/Template.php from [8050b58d78] to [1f698e9c13].
︙ | ︙ | |||
15 16 17 18 19 20 21 22 23 | private function __clone() { } public function __construct() { if (!file_exists(CACHE_ROOT . '/compiled')) { | > > | > | < > < > > > > > > > | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | private function __clone() { } public function __construct() { parent::__construct(); if (!file_exists(CACHE_ROOT . '/compiled')) { Utils::safe_mkdir(CACHE_ROOT . '/compiled', 0777, true); } $this->setTemplatesDir(ROOT . '/templates'); $this->setCompiledDir(CACHE_ROOT . '/compiled'); $this->setNamespace('Garradin'); // Hash de la version pour les éléments statiques (cache) // On ne peut pas utiliser la version directement comme query string // pour les éléments statiques (genre /admin/static/admin.css?v0.9.0) // car cela dévoilerait la version de Garradin utilisée, posant un souci // en cas de faille, on cache donc la version utilisée, chaque instance // aura sa propre version $this->assign('version_hash', substr(sha1(VERSION . ROOT . SECRET_KEY), 0, 10)); $this->assign('www_url', WWW_URL); $this->assign('self_url', Utils::getSelfUrl()); $this->assign('self_url_no_qs', Utils::getSelfUrl(false)); $this->assign('is_logged', false); |
︙ | ︙ | |||
359 360 361 362 363 364 365 366 367 368 369 370 371 372 | { $binary |= 0x01 << $k; } } $value = $binary; } foreach ($options as $k=>$v) { $b = 0x01 << (int)$k; $field .= '<label><input type="checkbox" name="' . htmlspecialchars($params['name'], ENT_QUOTES, 'UTF-8') . '[' . (int)$k . ']" value="1" ' . (($value & $b) ? 'checked="checked"' : '') . ' ' . $attributes . '/> ' | > > > | 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 | { $binary |= 0x01 << $k; } } $value = $binary; } // Forcer la valeur à être un entier (depuis PHP 7.1) $value = (int)$value; foreach ($options as $k=>$v) { $b = 0x01 << (int)$k; $field .= '<label><input type="checkbox" name="' . htmlspecialchars($params['name'], ENT_QUOTES, 'UTF-8') . '[' . (int)$k . ']" value="1" ' . (($value & $b) ? 'checked="checked"' : '') . ' ' . $attributes . '/> ' |
︙ | ︙ |
Modified src/include/lib/Garradin/Utils.php from [4680da7c34] to [b08ae6096e].
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <?php namespace Garradin; use KD2\Security; use KD2\Form; use KD2\Translate; use KD2\SMTP; class Utils { static protected $skriv = null; static private $french_date_names = [ 'January'=>'Janvier', 'February'=>'Février', 'March'=>'Mars', 'April'=>'Avril', 'May'=>'Mai', 'June'=>'Juin', 'July'=>'Juillet', 'August'=>'Août', 'September'=>'Septembre', 'October'=>'Octobre', 'November'=>'Novembre', 'December'=>'Décembre', 'Monday'=>'Lundi', 'Tuesday'=>'Mardi', 'Wednesday'=>'Mercredi', 'Thursday'=>'Jeudi','Friday'=>'Vendredi','Saturday'=>'Samedi','Sunday'=>'Dimanche', | > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <?php namespace Garradin; use KD2\Security; use KD2\Form; use KD2\Translate; use KD2\SMTP; use KD2\ODSWriter; class Utils { const EMAIL_CONTEXT_BULK = 'bulk'; const EMAIL_CONTEXT_PRIVATE = 'private'; const EMAIL_CONTEXT_SYSTEM = 'system'; static protected $skriv = null; static private $french_date_names = [ 'January'=>'Janvier', 'February'=>'Février', 'March'=>'Mars', 'April'=>'Avril', 'May'=>'Mai', 'June'=>'Juin', 'July'=>'Juillet', 'August'=>'Août', 'September'=>'Septembre', 'October'=>'Octobre', 'November'=>'Novembre', 'December'=>'Décembre', 'Monday'=>'Lundi', 'Tuesday'=>'Mardi', 'Wednesday'=>'Mercredi', 'Thursday'=>'Jeudi','Friday'=>'Vendredi','Saturday'=>'Samedi','Sunday'=>'Dimanche', |
︙ | ︙ | |||
371 372 373 374 375 376 377 | $str = preg_replace('/<em>(\V*?)<\/em>/', '\'\'$1\'\'', $str); $str = preg_replace('/<li>(\V*?)<\/li>/', '* $1', $str); $str = preg_replace('/<ul>|<\/ul>/', '', $str); $str = preg_replace('/<a href="([^"]*?)">(\V*?)<\/a>/', '[[$2 | $1]]', $str); return $str; } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < > > > > > > > > > > > > > > > > > > > > > > | 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 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 | $str = preg_replace('/<em>(\V*?)<\/em>/', '\'\'$1\'\'', $str); $str = preg_replace('/<li>(\V*?)<\/li>/', '* $1', $str); $str = preg_replace('/<ul>|<\/ul>/', '', $str); $str = preg_replace('/<a href="([^"]*?)">(\V*?)<\/a>/', '[[$2 | $1]]', $str); return $str; } static public function clearCaches($path = false) { if (!$path) { self::clearCaches('compiled'); self::clearCaches('static'); return true; } $path = CACHE_ROOT . '/' . $path; $dir = dir($path); while ($file = $dir->read()) { if ($file[0] != '.') { self::safe_unlink($path . DIRECTORY_SEPARATOR . $file); } } $dir->close(); return true; } static public function safe_unlink($path) { if (!@unlink($path)) { return true; } if (!file_exists($path)) { return true; } throw new \RuntimeException(sprintf('Impossible de supprimer le fichier %s: %s', $path, error_get_last())); return true; } static public function safe_mkdir($path, $mode = 0777, $recursive = false) { return @mkdir($path, $mode, $recursive) || is_dir($path); } static public function suggestPassword() { return Security::getRandomPassphrase(ROOT . '/include/data/dictionary.fr'); } static public function checkIBAN($value) |
︙ | ︙ | |||
659 660 661 662 663 664 665 | if (is_dir($path . '/' . $file)) { if (!self::deleteRecursive($path . '/' . $file)) return false; } else { | | | 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 | if (is_dir($path . '/' . $file)) { if (!self::deleteRecursive($path . '/' . $file)) return false; } else { utils::safe_unlink($path . '/' . $file); } } $dir->close(); rmdir($path); return true; |
︙ | ︙ | |||
739 740 741 742 743 744 745 | array_walk($row, function (&$field) { $field = strtr($field, ['"' => '""', "\r\n" => "\n"]); }); return sprintf("\"%s\"\r\n", implode('","', $row)); } | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 | array_walk($row, function (&$field) { $field = strtr($field, ['"' => '""', "\r\n" => "\n"]); }); return sprintf("\"%s\"\r\n", implode('","', $row)); } static public function toCSV($name, $iterator, $header = null) { header('Content-type: application/csv'); header(sprintf('Content-Disposition: attachment; filename="%s.csv"', $name)); $fp = fopen('php://output', 'w'); if ($header) { fputs($fp, self::row_to_csv($header)); } foreach ($iterator as $row) { if (!$header) { fputs($fp, self::row_to_csv(array_keys($row))); $header = true; } fputs($fp, self::row_to_csv($row)); } fclose($fp); return true; } static public function toODS($name, $iterator, $header = null) { header('Content-type: application/vnd.oasis.opendocument.spreadsheet'); header(sprintf('Content-Disposition: attachment; filename="%s.ods"', $name)); $ods = new ODSWriter; $ods->table_name = $name; if ($header) { $ods->add((array) $header); } foreach ($iterator as $row) { if (!$header) { $ods->add(array_keys($row)); $header = true; } $ods->add((array) $row); } $ods->output(); return true; } static public function sendEmail($context, $recipient, $subject, $content, $id_membre = null, $pgp_key = null) { // Ne pas envoyer de mail à des adresses invalides if (!SMTP::checkEmailIsValid($recipient, false)) { throw new UserException('Adresse email invalide: ' . $recipient); } $config = Config::getInstance(); $subject = sprintf('[%s] %s', $config->get('nom_asso'), $subject); // Tentative d'envoi du message en utilisant un plugin $email_sent_via_plugin = Plugin::fireSignal('email.envoi', compact('context', 'recipient', 'subject', 'content', 'id_membre', 'pgp_key')); if (!$email_sent_via_plugin) { // L'envoi d'email n'a pas été effectué par un plugin, utilisons l'envoi interne // via mail() ou SMTP donc return self::mail($context, $recipient, $subject, $content, $id_membre, $pgp_key); } return true; } static public function mail($context, $to, $subject, $content, $id_membre, $pgp_key) { $headers = []; $config = Config::getInstance(); $content = wordwrap($content); $content = trim($content); $content .= sprintf("\n\n-- \n%s\n%s\n\n", $config->get('nom_asso'), $config->get('site_asso')); $content .= "Vous recevez ce message car vous êtes inscrit comme membre de\nl'association.\n"; $content .= "Pour ne plus recevoir de message de notre part merci de nous contacter :\n" . $config->get('email_asso'); $content = preg_replace("#(?<!\r)\n#si", "\r\n", $content); if ($pgp_key) { $content = Security::encryptWithPublicKey($pgp_key, $content); } $headers['From'] = sprintf('"%s" <%s>', sprintf('=?UTF-8?B?%s?=', base64_encode($config->get('nom_asso'))), $config->get('email_asso')); $headers['Return-Path'] = $config->get('email_asso'); $headers['MIME-Version'] = '1.0'; $headers['Content-type'] = 'text/plain; charset=UTF-8'; if ($context == self::EMAIL_CONTEXT_BULK) { $headers['Precedence'] = 'bulk'; } $hash = sha1(uniqid() . var_export([$headers, $to, $subject, $content], true)); $headers['Message-ID'] = sprintf('%s@%s', $hash, isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : gethostname()); if (SMTP_HOST) { $const = '\KD2\SMTP::' . strtoupper(SMTP_SECURITY); if (!defined($const)) { throw new \LogicException('Configuration: SMTP_SECURITY n\'a pas une valeur reconnue. Valeurs acceptées: STARTTLS, TLS, SSL, NONE.'); } $secure = constant($const); $smtp = new SMTP(SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASSWORD, $secure); return $smtp->send($to, $subject, $content, $headers); } else { // Encodage du sujet $subject = sprintf('=?UTF-8?B?%s?=', base64_encode($subject)); $raw_headers = ''; // Sérialisation des entêtes foreach ($headers as $name=>$value) { $raw_headers .= sprintf("%s: %s\r\n", $name, $value); } return \mail($to, $subject, $content, $raw_headers); } } } |
Added src/include/test_required.php version [69fc54870f].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | <?php /* * Tests : vérification que les conditions pour s'exécuter sont remplies */ function test_requis($condition, $message) { if ($condition) { return true; } if (PHP_SAPI != 'cli') { header('Content-Type: text/html; charset=utf-8'); echo "<!DOCTYPE html>\n<html>\n<head>\n<title>Erreur</title>\n<meta charset=\"utf-8\" />\n"; echo '<style type="text/css">body { font-family: sans-serif; } '; echo '.error { color: darkred; padding: .5em; margin: 1em; border: 3px double red; background: yellow; }</style>'; echo "\n</head>\n<body>\n<h2>Erreur</h2>\n<h3>Le problème suivant empêche Garradin de fonctionner :</h3>\n"; echo '<p class="error">' . htmlspecialchars($message, ENT_QUOTES, 'UTF-8') . '</p>'; echo '<hr /><p>Pour plus d\'informations consulter '; echo '<a href="http://dev.kd2.org/garradin/Probl%C3%A8mes%20fr%C3%A9quents">l\'aide sur les problèmes à l\'installation</a>.</p>'; echo "\n</body>\n</html>"; } else { echo "[ERREUR] Le problème suivant empêche Garradin de fonctionner :\n"; echo $message . "\n"; echo "Pour plus d'informations consulter http://dev.kd2.org/garradin/Probl%C3%A8mes%20fr%C3%A9quents\n"; } exit; } test_requis( version_compare(phpversion(), '5.6', '>='), 'PHP 5.6 ou supérieur requis. PHP version ' . phpversion() . ' installée.' ); test_requis( defined('CRYPT_BLOWFISH') && CRYPT_BLOWFISH, 'L\'algorithme de hashage de mot de passe Blowfish n\'est pas présent (pas installé ou pas compilé).' ); test_requis( class_exists('SQLite3'), 'Le module de base de données SQLite3 n\'est pas disponible.' ); $v = \SQLite3::version(); test_requis( version_compare($v['versionString'], '3.7.4', '>='), 'SQLite3 version 3.7.4 ou supérieur requise. Version installée : ' . $v['versionString'] ); test_requis( file_exists(__DIR__ . '/lib/KD2'), 'Librairie KD2 non disponible.' ); |
Modified src/index.html from [23f2c346a2] to [008e979f23].
1 2 3 4 | <h1>Erreur</h1> <p>Garradin n'est pas installé sur un sous-domaine dédié.</p> <p>Merci de positionner un sous-domaine dédié sur le répertoire www/</p> <p>Voir <a href="http://dev.kd2.org/garradin/Installation">la documentation</a>.</p> | > | 1 2 3 4 5 | <h1>Erreur</h1> <p>Garradin n'est pas installé sur un sous-domaine dédié.</p> <p>Ce mode de fonctionnement n'est pas supporté officiellement.</p> <p>Merci de positionner un sous-domaine dédié sur le répertoire www/</p> <p>Voir <a href="http://dev.kd2.org/garradin/Installation">la documentation</a>.</p> |
Modified src/templates/admin/_head.tpl from [aa97d73757] to [d5fc274287].
1 2 3 4 5 6 7 | <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr"> <head> <meta charset="utf-8" /> <title>{$title}</title> <link rel="icon" type="image/png" href="{$admin_url}static/icon.png" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, target-densitydpi=device-dpi" /> | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr"> <head> <meta charset="utf-8" /> <title>{$title}</title> <link rel="icon" type="image/png" href="{$admin_url}static/icon.png" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, target-densitydpi=device-dpi" /> <link rel="stylesheet" type="text/css" href="{$admin_url}static/admin.css?{$version_hash}1" media="all" /> {if isset($js) || isset($custom_js)} <script type="text/javascript" src="{$admin_url}static/scripts/global.js?{$version_hash}"></script> {/if} {if isset($custom_js)} {foreach from=$custom_js item="js"} <script type="text/javascript" src="{$admin_url}static/scripts/{$js}?{$version_hash}"></script> {/foreach} {/if} {if isset($custom_css)} {foreach from=$custom_css item="css"} <link rel="stylesheet" type="text/css" href="{$admin_url}static/{$css}?{$version_hash}" media="all" /> {/foreach} {/if} {if isset($plugin_css)} {foreach from=$plugin_css item="css"} <link rel="stylesheet" type="text/css" href="{plugin_url file=$css}?{$version_hash}" /> {/foreach} {/if} {if isset($plugin_js)} {foreach from=$plugin_js item="js"} <script type="text/javascript" src="{plugin_url file=$js}?{$version_hash}"></script> {/foreach} {/if} <link rel="stylesheet" type="text/css" href="{$admin_url}static/print.css?{$version_hash}" media="print" /> <link rel="stylesheet" type="text/css" href="{$admin_url}static/handheld.css?{$version_hash}" media="handheld,screen and (max-width:981px)" /> {if isset($config)} {custom_colors config=$config} {/if} </head> <body{if !empty($body_id)} id="{$body_id}"{/if} data-url="{$admin_url}"> |
︙ | ︙ | |||
53 54 55 56 57 58 59 | <?php $current_parent = substr($current, 0, strpos($current, '/')); ?> <li class="home{if $current == 'home'} current{elseif $current_parent == 'home'} current_parent{/if}"> <a href="{$admin_url}"><b class="icn">⌂</b><i> Accueil</i></a> {if !empty($plugins_menu)} <ul> | | | | | < < | < | | | | | | | 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | <?php $current_parent = substr($current, 0, strpos($current, '/')); ?> <li class="home{if $current == 'home'} current{elseif $current_parent == 'home'} current_parent{/if}"> <a href="{$admin_url}"><b class="icn">⌂</b><i> Accueil</i></a> {if !empty($plugins_menu)} <ul> {foreach from=$plugins_menu key="plugin_id" item="name"} <li class="plugins {if $current == sprintf("plugin_%s", $plugin_id)} current{/if}"><a href="{plugin_url id=$plugin_id}">{$name}</a></li> {/foreach} </ul> {/if} </li> {if $session->canAccess('membres', Membres::DROIT_ACCES)} <li class="member list{if $current == 'membres'} current{elseif $current_parent == 'membres'} current_parent{/if}"><a href="{$admin_url}membres/"><b class="icn">👪</b><i> Membres</i></a> {if $session->canAccess('membres', Membres::DROIT_ECRITURE)} <ul> <li class="member new{if $current == 'membres/ajouter'} current{/if}"><a href="{$admin_url}membres/ajouter.php">Ajouter</a></li> <li class="member cotisations{if $current == 'membres/cotisations'} current{/if}"><a href="{$admin_url}membres/cotisations/">Cotisations</a></li> <li class="member message{if $current == 'membres/message'} current{/if}"><a href="{$admin_url}membres/message_collectif.php">Message collectif</a></li> </ul> {/if} </li> {/if} {if $session->canAccess('compta', Membres::DROIT_ACCES)} <li class="compta{if $current == 'compta'} current{elseif $current_parent == 'compta'} current_parent{/if}"><a href="{$admin_url}compta/"><b>€</b><i> Comptabilité</i></a> <ul> {if $session->canAccess('compta', Membres::DROIT_ECRITURE)} <li class="compta new{if $current == 'compta/saisie'} current{/if}"><a href="{$admin_url}compta/operations/saisir.php">Saisie</a></li> {/if} <li class="compta list{if $current == 'compta/gestion'} current{/if}"><a href="{$admin_url}compta/operations/">Suivi des opérations</a></li> <li class="compta banks{if $current == 'compta/banques'} current{/if}"><a href="{$admin_url}compta/banques/">Banques & caisse</a></li> {if $session->canAccess('compta', Membres::DROIT_ADMIN)} <li class="compta admin config{if $current == 'compta/categories'} current{/if}"><a href="{$admin_url}compta/categories/">Catégories & comptes</a></li> {/if} <li class="compta admin reports{if $current == 'compta/exercices'} current{/if}"><a href="{$admin_url}compta/exercices/">Exercices & projets</a></li> </ul> </li> {/if} {if $session->canAccess('wiki', Membres::DROIT_ACCES)} <li class="wiki{if $current == 'wiki'} current{elseif $current_parent == 'wiki'} current_parent{/if}"><a href="{$admin_url}wiki/"><b class="icn">✎</b><i> Wiki</i></a> <ul> <li class="wiki list{if $current == 'wiki/recent'} current{/if}"><a href="{$admin_url}wiki/recent.php">Dernières modifications</a> <li class="wiki search{if $current == 'wiki/chercher'} current{/if}"><a href="{$admin_url}wiki/chercher.php">Recherche</a> {*<li class="wiki follow{if $current == 'wiki/suivi'} current{/if}"><a href="{$admin_url}wiki/suivi.php">Mes pages suivies</a>*} {*<li class="wiki follow{if $current == 'wiki/contribution'} current{/if}"><a href="{$admin_url}wiki/contributions.php">Mes contributions</a>*} </ul> </li> {/if} {if $session->canAccess('config', Membres::DROIT_ADMIN)} <li class="main config{if $current == 'config'} current{elseif $current_parent == 'config'} current_parent{/if}"><a href="{$admin_url}config/"><b class="icn">☸</b><i> Configuration</i></a> {/if} <li class="my config{if $current == 'mes_infos'} current{elseif $current_parent == 'mes_infos'} current_parent{/if}"><a href="{$admin_url}mes_infos.php"><b class="icn">👤</b><i> Mes infos personnelles</i></a> <ul> <li class="my cotisations{if $current == 'mes_cotisations'} current{/if}"><a href="{$admin_url}mes_cotisations.php">Mes cotisations</a></li> </ul> </li> {if !defined('Garradin\LOCAL_LOGIN') || !LOCAL_LOGIN} <li class="logout"><a href="{$admin_url}logout.php"><b class="icn">⤝</b><i> Déconnexion</i></a></li> {/if} {/if} </ul> </nav> <h1>{$title}</h1> </header> {/if} <main> |
Modified src/templates/admin/compta/banques/index.tpl from [9584129965] to [dfa7e103a3].
︙ | ︙ | |||
25 26 27 28 29 30 31 | <td>{$compte.banque}</td> <th>{$compte.libelle}</th> <td><strong>{$compte.solde|escape|html_money} {$config.monnaie}</strong></td> <td>{$compte.iban|escape|format_iban}</td> <td>{$compte.bic}</td> <td class="actions"> <a class="icn" href="{$admin_url}compta/comptes/journal.php?id={$compte.id}&suivi" title="Journal">𝍢</a> | | | | | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | <td>{$compte.banque}</td> <th>{$compte.libelle}</th> <td><strong>{$compte.solde|escape|html_money} {$config.monnaie}</strong></td> <td>{$compte.iban|escape|format_iban}</td> <td>{$compte.bic}</td> <td class="actions"> <a class="icn" href="{$admin_url}compta/comptes/journal.php?id={$compte.id}&suivi" title="Journal">𝍢</a> {if $session->canAccess('compta', Membres::DROIT_ECRITURE)} <a class="icn" href="{$admin_url}compta/banques/rapprocher.php?id={$compte.id}" title="Rapprocher">☑</a> {/if} {if $session->canAccess('compta', Membres::DROIT_ADMIN)} <a class="icn" href="{$admin_url}compta/banques/modifier.php?id={$compte.id}" title="Modifier">✎</a> <a class="icn" href="{$admin_url}compta/banques/supprimer.php?id={$compte.id}" title="Supprimer">✘</a> {/if} </td> </tr> {/foreach} </tbody> </table> </dl> {/if} {if $session->canAccess('compta', Membres::DROIT_ADMIN)} {form_errors} <form method="post" action="{$self_url}"> <fieldset> <legend>Ajouter un compte bancaire</legend> <dl> |
︙ | ︙ |
Modified src/templates/admin/compta/banques/rapprocher.tpl from [8c929d9cb6] to [8d52e0242d].
︙ | ︙ | |||
8 9 10 11 12 13 14 | <form method="get" action="{$self_url_no_qs}"> {if !empty($prev) && !empty($next)} <fieldset class="shortFormRight"> <legend>Rapprochement par mois</legend> <dl> <dd class="actions"> | | | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | <form method="get" action="{$self_url_no_qs}"> {if !empty($prev) && !empty($next)} <fieldset class="shortFormRight"> <legend>Rapprochement par mois</legend> <dl> <dd class="actions"> <a class="icn" href="{$self_url_no_qs}?id={$compte.id}&debut={$prev|date_fr:'Y-m-01'}&fin={$prev|date_fr:'Y-m-t'}{if qg('sauf')}&sauf=1{/if}">← {$prev|date_fr:'F Y'}</a> | <a class="icn" href="{$self_url_no_qs}?id={$compte.id}&debut={$next|date_fr:'Y-m-01'}&fin={$next|date_fr:'Y-m-t'}{if qg('sauf')}&sauf=1{/if}">{$next|date_fr:'F Y'} →</a> </dd> </dl> </fieldset> {/if} <fieldset> <legend>Période de rapprochement</legend> <p> Du <span><input type="date" name="debut" id="f_debut" value="{$debut}" /></span> au <span><input type="date" name="fin" id="f_fin" value="{$fin}" /></span> <label><input type="checkbox" name="sauf" value="1" {if qg('sauf')} checked="checked"{/if} /> Ne pas inclure les écritures déjà rapprochées</label> <input type="hidden" name="id" value="{$compte.id}" /> <input type="submit" value="Afficher" /> </p> </fieldset> </form> {form_errors} |
︙ | ︙ | |||
63 64 65 66 67 68 69 | <th>Solde au {$debut|format_sqlite_date_to_french}</th> </tr> {foreach from=$journal item="ligne"} <tr> <td class="check"><input type="checkbox" name="rapprocher[{$ligne.id}]" value="1" {if $ligne.date_rapprochement}checked="checked"{/if} /></td> <td class="num"><a href="{$admin_url}compta/operations/voir.php?id={$ligne.id}">{$ligne.id}</a></td> <td class="actions"> | | | 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | <th>Solde au {$debut|format_sqlite_date_to_french}</th> </tr> {foreach from=$journal item="ligne"} <tr> <td class="check"><input type="checkbox" name="rapprocher[{$ligne.id}]" value="1" {if $ligne.date_rapprochement}checked="checked"{/if} /></td> <td class="num"><a href="{$admin_url}compta/operations/voir.php?id={$ligne.id}">{$ligne.id}</a></td> <td class="actions"> {if $session->canAccess('compta', Membres::DROIT_ADMIN)} <a class="icn" href="{$admin_url}compta/operations/modifier.php?id={$ligne.id}" title="Modifier cette opération">✎</a> {/if} </td> <td>{$ligne.date|date_fr:'d/m/Y'}</td> <td>{if $ligne.compte_credit == $compte.id}-{else}+{/if}{$ligne.montant|escape|html_money}</td> <td>{$ligne.solde|escape|html_money}</td> <th>{$ligne.libelle}</th> |
︙ | ︙ |
Modified src/templates/admin/compta/comptes/journal.tpl from [ac05873329] to [76d3a0a881].
︙ | ︙ | |||
30 31 32 33 34 35 36 | </tr> </thead> <tbody> {foreach from=$journal item="ligne"} <tr> <td class="num"><a href="{$admin_url}compta/operations/voir.php?id={$ligne.id}">{$ligne.id}</a></td> <td class="actions"> | | | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | </tr> </thead> <tbody> {foreach from=$journal item="ligne"} <tr> <td class="num"><a href="{$admin_url}compta/operations/voir.php?id={$ligne.id}">{$ligne.id}</a></td> <td class="actions"> {if $session->canAccess('compta', Membres::DROIT_ADMIN)} <a class="icn" href="{$admin_url}compta/operations/modifier.php?id={$ligne.id}" title="Modifier cette opération">✎</a> {/if} </td> <td>{$ligne.date|date_fr:'d/m/Y'}</td> <td>{if $ligne.compte_credit == $compte.id}{$credit}{else}{$debit}{/if}{$ligne.montant|escape|html_money}</td> <td>{$ligne.solde|escape|html_money}</td> <th>{$ligne.libelle}</th> |
︙ | ︙ |
Modified src/templates/admin/compta/exercices/index.tpl from [e945d5a3d0] to [ec3f086414].
︙ | ︙ | |||
24 25 26 27 28 29 30 | </dd> <dd class="desc"> <a href="{$admin_url}compta/rapports/journal.php?exercice={$exercice.id}">Journal général</a> | <a href="{$admin_url}compta/rapports/grand_livre.php?exercice={$exercice.id}">Grand livre</a> | <a href="{$admin_url}compta/rapports/compte_resultat.php?exercice={$exercice.id}">Compte de résultat</a> | <a href="{$admin_url}compta/rapports/bilan.php?exercice={$exercice.id}">Bilan</a> </dd> | | | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | </dd> <dd class="desc"> <a href="{$admin_url}compta/rapports/journal.php?exercice={$exercice.id}">Journal général</a> | <a href="{$admin_url}compta/rapports/grand_livre.php?exercice={$exercice.id}">Grand livre</a> | <a href="{$admin_url}compta/rapports/compte_resultat.php?exercice={$exercice.id}">Compte de résultat</a> | <a href="{$admin_url}compta/rapports/bilan.php?exercice={$exercice.id}">Bilan</a> </dd> {if $session->canAccess('compta', Membres::DROIT_ADMIN)} <dd class="actions"> {if !$exercice.cloture} <a class="icn" href="{$admin_url}compta/exercices/modifier.php?id={$exercice.id}" title="Modifier">✎</a> <a class="icn" href="{$admin_url}compta/exercices/supprimer.php?id={$exercice.id}" title="Supprimer">✘</a> <a class="icn" href="{$admin_url}compta/exercices/cloturer.php?id={$exercice.id}" title="Clôturer cet exercice">🔒</a> {elseif $exercice.cloture && $exercice.nb_operations == 0} <a class="icn" href="{$admin_url}compta/exercices/supprimer.php?id={$exercice.id}" title="Supprimer">✘</a> |
︙ | ︙ |
Modified src/templates/admin/compta/index.tpl from [07195fed01] to [9d6a3b1dd3].
1 2 | {include file="admin/_head.tpl" title="Comptabilité" current="compta"} | | | 1 2 3 4 5 6 7 8 9 10 | {include file="admin/_head.tpl" title="Comptabilité" current="compta"} {if $session->canAccess('compta', Membres::DROIT_ADMIN)} <ul class="actions"> <li><a href="{$admin_url}compta/import.php">Import / export</a></li> <li><a href="{$admin_url}compta/operations/recherche_sql.php">Recherche par requête SQL</a></li> </ul> {/if} <div class="infos"> |
︙ | ︙ |
Modified src/templates/admin/compta/operations/cotisation.tpl from [00adde6ecd] to [a490130f82].
1 2 3 4 5 | {include file="admin/_head.tpl" title="Écritures liées à une cotisation" current="compta/gestion"} <ul class="actions"> <li><a href="{$admin_url}membres/fiche.php?id={$membre.id}"><b>{$membre.identite}</b></a></li> <li><a href="{$admin_url}membres/modifier.php?id={$membre.id}">Modifier</a></li> | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 | {include file="admin/_head.tpl" title="Écritures liées à une cotisation" current="compta/gestion"} <ul class="actions"> <li><a href="{$admin_url}membres/fiche.php?id={$membre.id}"><b>{$membre.identite}</b></a></li> <li><a href="{$admin_url}membres/modifier.php?id={$membre.id}">Modifier</a></li> {if $session->canAccess('membres', Membres::DROIT_ADMIN)} <li><a href="{$admin_url}membres/supprimer.php?id={$membre.id}">Supprimer</a></li> {/if} <li><a href="{$admin_url}membres/cotisations.php?id={$membre.id}">Suivi des cotisations</a></li> </ul> {if empty($journal)} <p class="alert">Aucune écriture comptable n'est associée à cette cotisation.</p> |
︙ | ︙ | |||
32 33 34 35 36 37 38 | </tr> </thead> <tbody> {foreach from=$journal item="ligne"} <tr> <td><a href="{$admin_url}compta/operations/voir.php?id={$ligne.id}">{$ligne.id}</a></td> <td class="actions"> | | | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | </tr> </thead> <tbody> {foreach from=$journal item="ligne"} <tr> <td><a href="{$admin_url}compta/operations/voir.php?id={$ligne.id}">{$ligne.id}</a></td> <td class="actions"> {if $session->canAccess('compta', Membres::DROIT_ADMIN)} <a class="icn" href="{$admin_url}compta/operations/modifier.php?id={$ligne.id}" title="Modifier cette opération">✎</a> {/if} </td> <td>{$ligne.date|format_sqlite_date_to_french}</td> <td>{$ligne.montant|escape|html_money}</td> <th>{$ligne.libelle}</th> <td>{$ligne.compte_debit} — {$ligne.compte_debit|get_nom_compte}</td> |
︙ | ︙ |
Modified src/templates/admin/compta/operations/index.tpl from [14d2513231] to [5baa65eca3].
1 2 3 | {include file="admin/_head.tpl" title="Suivi des opérations" current="compta/gestion"} <ul class="actions"> | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | {include file="admin/_head.tpl" title="Suivi des opérations" current="compta/gestion"} <ul class="actions"> <li class="recettes{if $type == Compta\Categories::RECETTES} current{/if}"><a href="{$admin_url}compta/operations/?recettes">Recettes</a></li> <li class="depenses{if $type == Compta\Categories::DEPENSES} current{/if}"><a href="{$admin_url}compta/operations/?depenses">Dépenses</a></li> <li class="autres{if $type == Compta\Categories::AUTRES} current{/if}"><a href="{$admin_url}compta/operations/?autres">Autres</a></li> {*<li><a href="{$admin_url}compta/operations/recherche.php">Recherche d'opération</a></li>*} {if $session->canAccess('compta', Membres::DROIT_ADMIN)} <li><a href="{$admin_url}compta/operations/recherche_sql.php">Recherche par requête SQL</a></li> {/if} </ul> {if $type != Compta\Categories::AUTRES} <form method="get" action="{$self_url}"> <fieldset> <legend>Filtrer par catégorie</legend> <select name="cat" onchange="if (!this.value) location.href = '?{if $type == Compta\Categories::RECETTES}recettes{else}depenses{/if}'; else this.form.submit();"> <option value="">-- Toutes</option> {foreach from=$liste_cats item="cat"} <option value="{$cat.id}"{if $cat.id == $categorie.id} selected="selected"{/if}>{$cat.intitule}</option> {/foreach} </select> <input type="submit" value="OK" /> </fieldset> |
︙ | ︙ |
Modified src/templates/admin/compta/operations/membre.tpl from [c7d34a4a3b] to [8524d38029].
1 2 3 4 5 | {include file="admin/_head.tpl" title="Écritures réalisées par le membre" current="compta/gestion"} <ul class="actions"> <li><a href="{$admin_url}membres/fiche.php?id={$membre.id}"><b>{$membre.identite}</b></a></li> <li><a href="{$admin_url}membres/modifier.php?id={$membre.id}">Modifier</a></li> | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 | {include file="admin/_head.tpl" title="Écritures réalisées par le membre" current="compta/gestion"} <ul class="actions"> <li><a href="{$admin_url}membres/fiche.php?id={$membre.id}"><b>{$membre.identite}</b></a></li> <li><a href="{$admin_url}membres/modifier.php?id={$membre.id}">Modifier</a></li> {if $session->canAccess('membres', Membres::DROIT_ADMIN)} <li><a href="{$admin_url}membres/supprimer.php?id={$membre.id}">Supprimer</a></li> {/if} <li><a href="{$admin_url}membres/cotisations.php?id={$membre.id}">Suivi des cotisations</a></li> </ul> <form method="get" action="{$self_url}"> <fieldset> |
︙ | ︙ | |||
54 55 56 57 58 59 60 | </tr> </thead> <tbody> {foreach from=$journal item="ligne"} <tr> <td><a href="{$admin_url}compta/operations/voir.php?id={$ligne.id}">{$ligne.id}</a></td> <td class="actions"> | | | 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | </tr> </thead> <tbody> {foreach from=$journal item="ligne"} <tr> <td><a href="{$admin_url}compta/operations/voir.php?id={$ligne.id}">{$ligne.id}</a></td> <td class="actions"> {if $session->canAccess('compta', Membres::DROIT_ADMIN)} <a class="icn" href="{$admin_url}compta/operations/modifier.php?id={$ligne.id}" title="Modifier cette opération">✎</a> {/if} </td> <td>{$ligne.date|format_sqlite_date_to_french}</td> <td>{$ligne.montant|escape|html_money}</td> <th>{$ligne.libelle}</th> <td>{$ligne.compte_debit} — {$ligne.compte_debit|get_nom_compte}</td> |
︙ | ︙ |
Modified src/templates/admin/compta/operations/modifier.tpl from [fd3771f52b] to [da5bdb03fc].
︙ | ︙ | |||
34 35 36 37 38 39 40 | </dd> <dt class="f_cheque"><label for="f_numero_cheque">Numéro de chèque</label></dt> <dd class="f_cheque"><input type="text" name="numero_cheque" id="f_numero_cheque" value="{form_field name=numero_cheque data=$operation}" /></dd> <dt class="f_banque"><label for="f_banque">Compte bancaire</label></dt> <dd class="f_banque"> <select name="banque" id="f_banque"> {foreach from=$comptes_bancaires item="compte"} | | | | 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | </dd> <dt class="f_cheque"><label for="f_numero_cheque">Numéro de chèque</label></dt> <dd class="f_cheque"><input type="text" name="numero_cheque" id="f_numero_cheque" value="{form_field name=numero_cheque data=$operation}" /></dd> <dt class="f_banque"><label for="f_banque">Compte bancaire</label></dt> <dd class="f_banque"> <select name="banque" id="f_banque"> {foreach from=$comptes_bancaires item="compte"} <option value="{$compte.id}"{if ($type == Compta\Categories::DEPENSES && $compte.id == $operation.compte_credit) || $compte.id == $operation.compte_debit} selected="selected"{/if}>{$compte.libelle} - {$compte.banque}</option> {/foreach} {if ($type == Compta\Categories::RECETTES)} <option value="{$id_cheque_a_encaisser}"{form_field name="banque" selected=$id_cheque_a_encaisser default=$operation.compte_debit}>Chèques à encaisser</option> <option value="{$id_carte_a_encaisser}"{form_field name="banque" selected=$id_carte_a_encaisser default=$operation.compte_debit}>Paiement CB à encaisser</option> {/if} </select> </dd> {/if} |
︙ | ︙ |
Modified src/templates/admin/compta/operations/voir.tpl from [1a3a9051ba] to [eaf9901138].
1 2 | {include file="admin/_head.tpl" title="Opération n°%d"|args:$operation.id current="compta/gestion"} | | | 1 2 3 4 5 6 7 8 9 10 | {include file="admin/_head.tpl" title="Opération n°%d"|args:$operation.id current="compta/gestion"} {if $session->canAccess('compta', Membres::DROIT_ADMIN) && $operation.compte_credit !== null && $operation.compte_debit !== null} <ul class="actions"> <li class="edit"><a href="{$admin_url}compta/operations/modifier.php?id={$operation.id}">Modifier cette opération</a></li> <li class="delete"><a href="{$admin_url}compta/operations/supprimer.php?id={$operation.id}">Supprimer cette opération</a></li> </ul> {/if} <dl class="describe"> |
︙ | ︙ | |||
30 31 32 33 34 35 36 | {if $operation.moyen_paiement && $operation.moyen_paiement != 'ES'} <dt>Compte bancaire</dt> <dd>{$compte}</dd> {/if} <dt>Catégorie</dt> <dd> | | | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | {if $operation.moyen_paiement && $operation.moyen_paiement != 'ES'} <dt>Compte bancaire</dt> <dd>{$compte}</dd> {/if} <dt>Catégorie</dt> <dd> <a href="{$admin_url}compta/operations/?{if $categorie.type == Compta\Categories::DEPENSES}depenses{else}recettes{/if}">{if $categorie.type == Compta\Categories::DEPENSES}Dépense{else}Recette{/if}</a> : <a href="{$admin_url}compta/operations/?cat={$operation.id_categorie}">{$categorie.intitule}</a> </dd> {/if} <dt>Exercice</dt> <dd> <a href="{$admin_url}compta/exercices/">{$exercice.libelle}</a> |
︙ | ︙ | |||
52 53 54 55 56 57 58 | <a href="{$admin_url}compta/projets/">{$projet.libelle}</a> </dd> {/if} <dt>Opération créée par</dt> <dd> {if $operation.id_auteur} | | | 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | <a href="{$admin_url}compta/projets/">{$projet.libelle}</a> </dd> {/if} <dt>Opération créée par</dt> <dd> {if $operation.id_auteur} {if $session->canAccess('compta', Membres::DROIT_ACCES)} <a href="{$admin_url}membres/fiche.php?id={$operation.id_auteur}">{$nom_auteur}</a> {else} {$nom_auteur} {/if} {else} <em>membre supprimé</em> {/if} |
︙ | ︙ |
Modified src/templates/admin/compta/projets/index.tpl from [4cae68a2fd] to [c946bff41c].
︙ | ︙ | |||
52 53 54 55 56 57 58 | <dd class="compte">{$projet.nb_operations} opérations</dd> <dd class="desc"> <a href="{$admin_url}compta/rapports/journal.php?projet={$projet.id}">Journal général</a> | <a href="{$admin_url}compta/rapports/grand_livre.php?projet={$projet.id}">Grand livre</a> | <a href="{$admin_url}compta/rapports/compte_resultat.php?projet={$projet.id}">Compte de résultat</a> | <a href="{$admin_url}compta/rapports/bilan.php?projet={$projet.id}">Bilan</a> </dd> | | | | 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | <dd class="compte">{$projet.nb_operations} opérations</dd> <dd class="desc"> <a href="{$admin_url}compta/rapports/journal.php?projet={$projet.id}">Journal général</a> | <a href="{$admin_url}compta/rapports/grand_livre.php?projet={$projet.id}">Grand livre</a> | <a href="{$admin_url}compta/rapports/compte_resultat.php?projet={$projet.id}">Compte de résultat</a> | <a href="{$admin_url}compta/rapports/bilan.php?projet={$projet.id}">Bilan</a> </dd> {if $session->canAccess('compta', Membres::DROIT_ADMIN)} <dd class="actions"> <a class="icn" href="{$admin_url}compta/projets/?modifier={$projet.id}" title="Modifier">✎</a> <a class="icn" href="{$admin_url}compta/projets/?supprimer={$projet.id}" title="Supprimer">✘</a> </dd> {/if} {/foreach} </dl> {/if} {if $session->canAccess('compta', Membres::DROIT_ADMIN)} <form method="post" action="{$self_url}"> <fieldset> <legend>Ajouter un nouveau projet</legend> <dl> <dt><label for="f_libelle">Libellé</label></dt> <dd><input type="text" name="libelle" id="f_labelle" value="{form_field name=libelle}" /></dd> </dl> |
︙ | ︙ |
Modified src/templates/admin/config/_menu.tpl from [b62a4fdea8] to [53db92aa96].
1 | <ul class="actions"> | | > | | | < | | 1 2 3 4 5 6 7 8 | <ul class="actions"> <li{if $current == 'index'} class="current"{/if}><a href="{$admin_url}config/">Général</a></li> <li{if $current == 'categories'} class="current"{/if}><a href="{$admin_url}config/categories/">Catégories de membres</a></li> <li{if $current == 'fiches_membres'} class="current"{/if}><a href="{$admin_url}config/membres.php">Fiche des membres</a></li> <li{if $current == 'site'} class="current"{/if}><a href="{$admin_url}config/site.php">Site public</a></li> <li{if $current == 'donnees'} class="current"{/if}><a href="{$admin_url}config/donnees/">Sauvegarde et restauration</a></li> <li{if $current == 'plugins'} class="current"{/if}><a href="{$admin_url}config/plugins.php">Extensions</a></li> </ul> |
Added src/templates/admin/config/categories/index.tpl version [7ab8e26a24].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | {include file="admin/_head.tpl" title="Catégories de membres" current="config"} {include file="admin/config/_menu.tpl" current="categories"} <table class="list"> <thead> <th>Nom</th> <td class="num">Membres</td> <td>Droits</td> <td></td> </thead> <tbody> {foreach from=$liste item="cat"} <tr> <th>{$cat.nom}</th> <td class="num">{$cat.nombre}</td> <td class="droits"> {format_droits droits=$cat} </td> <td class="actions"> <a class="icn" href="{$admin_url}membres/?cat={$cat.id}" title="Liste des membres">👪</a> <a class="icn" href="{$admin_url}config/categories/modifier.php?id={$cat.id}" title="Modifier">✎</a> {if $cat.id != $user.id_categorie} <a class="icn" href="{$admin_url}config/categories/supprimer.php?id={$cat.id}" title="Supprimer">✘</a> {/if} </td> </tr> {/foreach} </tbody> </table> <form method="post" action="{$self_url}"> <fieldset> <legend>Ajouter une catégorie</legend> <dl> <dt><label for="f_nom">Nom</label> <b title="(Champ obligatoire)">obligatoire</b></dt> <dd><input type="text" name="nom" id="f_nom" value="{form_field name=nom}" required="required" /></dd> </dl> </fieldset> <p class="submit"> {csrf_field key="new_cat"} <input type="submit" name="save" value="Enregistrer →" /> </p> </form> {include file="admin/_foot.tpl"} |
Added src/templates/admin/config/categories/modifier.tpl version [7b22c4c7fb].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | {include file="admin/_head.tpl" title="Modifier une catégorie de membre" current="config"} {include file="admin/config/_menu.tpl" current="categories"} {form_errors} <form method="post" action="{$self_url}"> <fieldset> <legend>Informations générales</legend> <dl> <dt><label for="f_nom">Nom</label> <b title="(Champ obligatoire)">obligatoire</b></dt> <dd><input type="text" name="nom" id="f_nom" value="{form_field data=$cat name=nom}" required="required" /></dd> <dt> <input type="checkbox" name="cacher" value="1" id="f_cacher" {if $cat.cacher}checked="checked"{/if} /> <label for="f_cacher">Catégorie cachée</label> </dt> <dd class="help"> Si coché cette catégorie ne sera visible qu'aux administrateurs et ne recevra pas de messages collectifs ou de rappels. </dd> </dl> </fieldset> <fieldset> <legend>Cotisation obligatoire</legend> <dl> <dt><label for="f_id_cotisation_obligatoire">Cotisation obligatoire</label></dt> <dd> <select name="id_cotisation_obligatoire" id="f_id_cotisation_obligatoire"> <option value="">-- Non</option> {foreach from=$cotisations item="cotisation"} <option value="{$cotisation.id}" {form_field name="id_cotisation_obligatoire" selected=$cotisation.id data=$cat}> {$cotisation.intitule} — {$cotisation.montant|escape|html_money} {$config.monnaie} — {if $cotisation.duree}pour {$cotisation.duree} jours {elseif $cotisation.debut} du {$cotisation.debut|format_sqlite_date_to_french} au {$cotisation.fin|format_sqlite_date_to_french} {else} ponctuelle {/if} </option> {/foreach} </select> </dd> </dl> </fieldset> <fieldset> <legend>Droits</legend> <dl class="droits"> <dt><label for="f_droit_connexion_aucun">Les membres de cette catégorie peuvent-ils se connecter ?</label></dt> {if $readonly} <dd class="help"> Il n'est pas possible de désactiver ce droit pour votre propre catégorie. </dd> {/if} <dd> <input type="radio" name="droit_connexion" value="{$membres::DROIT_AUCUN}" id="f_droit_connexion_aucun" {if $cat.droit_connexion == $membres::DROIT_AUCUN}checked="checked"{/if} {$readonly} /> <label for="f_droit_connexion_aucun"><b class="aucun">C</b> Non</label> </dd> <dd> <input type="radio" name="droit_connexion" value="{$membres::DROIT_ACCES}" id="f_droit_connexion_acces" {if $cat.droit_connexion == $membres::DROIT_ACCES}checked="checked"{/if} {$readonly} /> <label for="f_droit_connexion_acces"><b class="acces">C</b> Oui</label> </dd> </dl> <dl class="droits"> <dt><label for="f_droit_inscription_aucun">Les membres de cette catégorie peuvent-ils s'inscrire d'eux-même ?</label></dt> <dd> <input type="radio" name="droit_inscription" value="{$membres::DROIT_AUCUN}" id="f_droit_inscription_aucun" {if $cat.droit_inscription == $membres::DROIT_AUCUN}checked="checked"{/if} /> <label for="f_droit_inscription_aucun"><b class="aucun">I</b> Non</label> </dd> <dd> <input type="radio" name="droit_inscription" value="{$membres::DROIT_ACCES}" id="f_droit_inscription_acces" {if $cat.droit_inscription == $membres::DROIT_ACCES}checked="checked"{/if} /> <label for="f_droit_inscription_acces"><b class="acces">I</b> Oui</label> </dd> </dl> <dl class="droits"> <dt><label for="f_droit_membres_aucun">Gestion des membres :</label></dt> <dd> <input type="radio" name="droit_membres" value="{$membres::DROIT_AUCUN}" id="f_droit_membres_aucun" {if $cat.droit_membres == $membres::DROIT_AUCUN}checked="checked"{/if} /> <label for="f_droit_membres_aucun"><b class="aucun">M</b> Pas d'accès</label> </dd> <dd> <input type="radio" name="droit_membres" value="{$membres::DROIT_ACCES}" id="f_droit_membres_acces" {if $cat.droit_membres == $membres::DROIT_ACCES}checked="checked"{/if} /> <label for="f_droit_membres_acces"><b class="acces">M</b> Lecture uniquement</label> </dd> <dd> <input type="radio" name="droit_membres" value="{$membres::DROIT_ECRITURE}" id="f_droit_membres_ecriture" {if $cat.droit_membres == $membres::DROIT_ECRITURE}checked="checked"{/if} /> <label for="f_droit_membres_ecriture"><b class="ecriture">M</b> Lecture & écriture</label> </dd> <dd> <input type="radio" name="droit_membres" value="{$membres::DROIT_ADMIN}" id="f_droit_membres_admin" {if $cat.droit_membres == $membres::DROIT_ADMIN}checked="checked"{/if} /> <label for="f_droit_membres_admin"><b class="admin">M</b> Administration</label> </dd> </dl> <dl class="droits"> <dt><label for="f_droit_compta_aucun">Comptabilité :</label></dt> <dd> <input type="radio" name="droit_compta" value="{$membres::DROIT_AUCUN}" id="f_droit_compta_aucun" {if $cat.droit_compta == $membres::DROIT_AUCUN}checked="checked"{/if} /> <label for="f_droit_compta_aucun"><b class="aucun">€</b> Pas d'accès</label> </dd> <dd> <input type="radio" name="droit_compta" value="{$membres::DROIT_ACCES}" id="f_droit_compta_acces" {if $cat.droit_compta == $membres::DROIT_ACCES}checked="checked"{/if} /> <label for="f_droit_compta_acces"><b class="acces">€</b> Lecture uniquement</label> </dd> <dd> <input type="radio" name="droit_compta" value="{$membres::DROIT_ECRITURE}" id="f_droit_compta_ecriture" {if $cat.droit_compta == $membres::DROIT_ECRITURE}checked="checked"{/if} /> <label for="f_droit_compta_ecriture"><b class="ecriture">€</b> Lecture & écriture</label> </dd> <dd> <input type="radio" name="droit_compta" value="{$membres::DROIT_ADMIN}" id="f_droit_compta_admin" {if $cat.droit_compta == $membres::DROIT_ADMIN}checked="checked"{/if} /> <label for="f_droit_compta_admin"><b class="admin">€</b> Administration</label> </dd> </dl> <dl class="droits"> <dt><label for="f_droit_wiki_aucun">Wiki :</label></dt> <dd> <input type="radio" name="droit_wiki" value="{$membres::DROIT_AUCUN}" id="f_droit_wiki_aucun" {if $cat.droit_wiki == $membres::DROIT_AUCUN}checked="checked"{/if} /> <label for="f_droit_wiki_aucun"><b class="aucun">W</b> Pas d'accès</label> </dd> <dd> <input type="radio" name="droit_wiki" value="{$membres::DROIT_ACCES}" id="f_droit_wiki_acces" {if $cat.droit_wiki == $membres::DROIT_ACCES}checked="checked"{/if} /> <label for="f_droit_wiki_acces"><b class="acces">W</b> Lecture uniquement</label> </dd> <dd> <input type="radio" name="droit_wiki" value="{$membres::DROIT_ECRITURE}" id="f_droit_wiki_ecriture" {if $cat.droit_wiki == $membres::DROIT_ECRITURE}checked="checked"{/if} /> <label for="f_droit_wiki_ecriture"><b class="ecriture">W</b> Lecture & écriture</label> </dd> <dd> <input type="radio" name="droit_wiki" value="{$membres::DROIT_ADMIN}" id="f_droit_wiki_admin" {if $cat.droit_wiki == $membres::DROIT_ADMIN}checked="checked"{/if} /> <label for="f_droit_wiki_admin"><b class="admin">W</b> Administration</label> </dd> </dl> <dl class="droits"> <dt><label for="f_droit_config_aucun">Les membres de cette catégorie peuvent-ils modifier la configuration ?</label></dt> {if $readonly} <dd class="help"> Il n'est pas possible de désactiver ce droit pour votre propre catégorie. </dd> {/if} <dd> <input type="radio" name="droit_config" value="{$membres::DROIT_AUCUN}" id="f_droit_config_aucun" {if $cat.droit_config == $membres::DROIT_AUCUN}checked="checked"{/if} {$readonly} /> <label for="f_droit_config_aucun"><b class="aucun">☑</b> Non</label> </dd> <dd> <input type="radio" name="droit_config" value="{$membres::DROIT_ADMIN}" id="f_droit_config_admin" {if $cat.droit_config == $membres::DROIT_ADMIN}checked="checked"{/if} {$readonly} /> <label for="f_droit_config_admin"><b class="admin">☑</b> Oui</label> </dd> </dl> </fieldset> <p class="submit"> {csrf_field key="edit_cat_"|cat:$cat.id} <input type="submit" name="save" value="Enregistrer →" /> </p> </form> {include file="admin/_foot.tpl"} |
Added src/templates/admin/config/categories/supprimer.tpl version [9ebed2a419].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | {include file="admin/_head.tpl" title="Supprimer une catégorie de membre" current="config"} {include file="admin/config/_menu.tpl" current="categories"} {form_errors} <form method="post" action="{$self_url}"> <fieldset> <legend>Supprimer la catégorie de membres ?</legend> <h3 class="warning"> Êtes-vous sûr de vouloir supprimer la catégorie « {$cat.nom} » ? </h3> <p class="help"> Attention, la catégorie ne doit plus contenir de membres pour pouvoir être supprimée. </p> <p class="help"> Notez que si des pages du wiki étaient restreintes à la lecture ou à l'écriture aux seuls membres de ce groupe, elles redeviendront lisibles et modifiables par tous les membres ayant accès au wiki ! </p> </fieldset> <p class="submit"> {csrf_field key="delete_cat_"|cat:$cat.id} <input type="submit" name="delete" value="Supprimer →" /> </p> </form> {include file="admin/_foot.tpl"} |
Deleted src/templates/admin/config/donnees.tpl version [396a0ea87b].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added src/templates/admin/config/donnees/_menu.tpl version [27f416469b].
> > > > > > > > > | 1 2 3 4 5 6 7 8 9 | <ul class="actions sub"> <li{if $current == 'index'} class="current"{/if}><a href="{$admin_url}config/donnees/">Sauvegarder et restaurer</a></li> <li{if $current == 'import'} class="current"{/if}><a href="{$admin_url}config/donnees/import.php">Import et export</a></li> <li{if $current == 'local'} class="current"{/if}><a href="{$admin_url}config/donnees/local.php">Gestion des sauvegardes</a></li> {if ENABLE_AUTOMATIC_BACKUPS} <li{if $current == 'automatique'} class="current"{/if}><a href="{$admin_url}config/donnees/automatique.php">Configuration de la sauvegarde automatique</a></li> {/if} <li{if $current == 'reset'} class="current"{/if}><a href="{$admin_url}config/donnees/reset.php">Remise à zéro</a></li> </ul> |
Added src/templates/admin/config/donnees/automatique.tpl version [1804eff257].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | {include file="admin/_head.tpl" title="Sauvegarde et restauration" current="config"} {include file="admin/config/_menu.tpl" current="donnees"} {include file="admin/config/donnees/_menu.tpl" current="automatique"} {form_errors} {if $ok == 'config'} <p class="confirm">La configuration a bien été enregistrée.</p> {/if} <form method="post" action="{$self_url_no_qs}"> <fieldset> <legend>Configuration de la sauvegarde automatique</legend> <p class="help"> En activant cette option une sauvegarde sera automatiquement créée à chaque intervalle donné. Par exemple en activant une sauvegarde hebdomadaire, une copie des données sera réalisée une fois par semaine, sauf si aucune modification n'a été effectuée sur les données ou que personne ne s'est connecté. </p> <dl> <dt><label for="f_frequency">Intervalle de sauvegarde</label> <b title="(Champ obligatoire)">obligatoire</b></dt> <dd> <select name="frequence_sauvegardes" required="required" id="f_frequency"> <option value="0"{form_field name=frequence_sauvegardes data=$config selected=0}>Aucun — les sauvegardes automatiques sont désactivées</option> <option value="1"{form_field name=frequence_sauvegardes data=$config selected=1}>Quotidien, tous les jours</option> <option value="7"{form_field name=frequence_sauvegardes data=$config selected=7}>Hebdomadaire, tous les 7 jours</option> <option value="15"{form_field name=frequence_sauvegardes data=$config selected=15}>Bimensuel, tous les 15 jours</option> <option value="30"{form_field name=frequence_sauvegardes data=$config selected=30}>Mensuel</option> <option value="90"{form_field name=frequence_sauvegardes data=$config selected=90}>Trimestriel</option> <option value="365{form_field name=frequence_sauvegardes data=$config selected=365}">Annuel</option> </select> </dd> <dt><label for="f_max_backups">Nombre de sauvegardes conservées</label> <b title="(Champ obligatoire)">obligatoire</b></dt> <dd class="help"> Par exemple avec l'intervalle mensuel, en indiquant de conserver 12 sauvegardes, vous pourrez garder un an d'historique de sauvegardes. </dd> <dd class="help"> <strong>Attention :</strong> si vous choisissez un nombre important et un intervalle réduit, l'espace disque occupé par vos sauvegardes va rapidement augmenter. </dd> <dd><input type="number" name="nombre_sauvegardes" value="{form_field name=nombre_sauvegardes data=$config}" if="f_max_backups" min="1" max="90" required="required" /></dd> </dl> <p> {csrf_field key="backup_config"} <input type="submit" name="config" value="Enregistrer →" /> </p> </fieldset> </form> {include file="admin/_foot.tpl"} |
Added src/templates/admin/config/donnees/import.tpl version [79252f8a0f].
> > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | {include file="admin/_head.tpl" title="Import & export" current="config"} {include file="admin/config/_menu.tpl" current="donnees"} {include file="admin/config/donnees/_menu.tpl" current="import"} <fieldset> <dl> <dt>Membres</dt> <dd><a href="{$admin_url}membres/import.php">Import de la liste des membres</a></dd> <dd><a href="{$admin_url}membres/import.php?export=ods">Export de la liste des membres au format tableur Calc / Excel</a></dd> <dd><a href="{$admin_url}membres/import.php?export=csv">Export de la liste des membres au format CSV</a></dd> <dt>Comptabilité</dt> <dd><a href="{$admin_url}compta/import.php">Import des données comptables</a></dd> <dd><a href="{$admin_url}compta/import.php?export=ods">Export des données comptables au format tableur Calc / Excel</a></dd> <dd><a href="{$admin_url}compta/import.php?export=csv">Export des données comptables au format CSV</a></dd> </dl> </fieldset> {include file="admin/_foot.tpl"} |
Added src/templates/admin/config/donnees/index.tpl version [87fb524e37].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | {include file="admin/_head.tpl" title="Sauvegarde et restauration" current="config"} {include file="admin/config/_menu.tpl" current="donnees"} {include file="admin/config/donnees/_menu.tpl" current="index"} {form_errors} {if $code == Sauvegarde::INTEGRITY_FAIL && ALLOW_MODIFIED_IMPORT} <p class="alert">Pour passer outre, renvoyez le fichier en cochant la case « Ignorer les erreurs ». Attention, si vous avez effectué des modifications dans la base de données, cela peut créer des bugs !</p> {/if} {if $ok} <p class="confirm"> {if $ok == 'restore'}La restauration a bien été effectuée. Si vous désirez revenir en arrière, vous pouvez utiliser la sauvegarde automatique nommée <em>{$now_date}.avant_restauration.sqlite</em>, sinon vous pouvez l'effacer. {if $ok_code & Sauvegarde::NOT_AN_ADMIN} </p> <p class="alert"> <strong>Vous n'êtes pas administrateur dans cette sauvegarde.</strong> Garradin a donné les droits d'administration à toutes les catégories afin d'empêcher de ne plus pouvoir se connecter. Merci de corriger les droits des catégories maintenant. {/if} {elseif $ok == 'remove'}La sauvegarde a été supprimée. {/if} </p> {/if} <form method="post" action="{$self_url_no_qs}"> <fieldset> <legend>Téléchargement d'une sauvegarde</legend> <p class="help"> Info : la base de données fait actuellement {$db_size|format_bytes} (dont {$files_size|format_bytes} pour les documents et images). </p> <p> {csrf_field key="backup_download"} <input type="submit" name="download" value="Télécharger une copie de la base de données sur mon ordinateur →" /> </p> </fieldset> </form> <form method="post" action="{$self_url_no_qs}" enctype="multipart/form-data"> <fieldset> <legend><label for="f_file">Restaurer depuis un fichier de sauvegarde</label></legend> <p class="alert"> Attention, l'intégralité des données courantes seront effacées et remplacées par celles contenues dans le fichier fourni. </p> <p class="help"> Une sauvegarde des données courantes sera effectuée avant le remplacement, en cas de besoin d'annuler cette restauration. </p> <p> {csrf_field key="backup_restore"} <input type="hidden" name="MAX_FILE_SIZE" value="{$max_file_size}" /> <input type="file" name="file" id="f_file" required="required" /> (maximum {$max_file_size|format_bytes}) <input type="submit" name="restore_file" value="Restaurer depuis le fichier sélectionné →" /> </p> {if $code && ($code == Sauvegarde::INTEGRITY_FAIL && ALLOW_MODIFIED_IMPORT)} <p> <label><input type="checkbox" name="force_import" value="1" /> Ignorer les erreurs, je sais ce que je fait</label> </p> {/if} </fieldset> </form> {include file="admin/_foot.tpl"} |
Added src/templates/admin/config/donnees/local.tpl version [4984d48811].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | {include file="admin/_head.tpl" title="Gestion des sauvegardes" current="config"} {include file="admin/config/_menu.tpl" current="donnees"} {include file="admin/config/donnees/_menu.tpl" current="local"} {form_errors} {if $ok} <p class="confirm"> {if $ok == 'create'}Une nouvelle sauvegarde a été créée. {elseif $ok == 'restore'}La restauration a bien été effectuée. Si vous désirez revenir en arrière, vous pouvez utiliser la sauvegarde automatique nommée <em>date-du-jour.avant_restauration.sqlite</em>, sinon vous pouvez l'effacer. {if $ok_code & Sauvegarde::NOT_AN_ADMIN} </p> <p class="alert"> <strong>Vous n'êtes pas administrateur dans cette sauvegarde.</strong> Garradin a donné les droits d'administration à toutes les catégories afin d'empêcher de ne plus pouvoir se connecter. Merci de corriger les droits des catégories maintenant. {/if} {elseif $ok == 'remove'}La sauvegarde a été supprimée. {/if} </p> {/if} <form method="post" action="{$self_url_no_qs}"> <fieldset> <legend>Copies de sauvegarde disponibles</legend> {if empty($liste)} <p class="help">Aucune copie de sauvegarde disponible.</p> {else} <dl> <dt><label for="f_select">Sélectionner une sauvegarde</label></dt> <dd> <select name="file" id="f_select"> {foreach from=$liste key="f" item="d"} <option value="{$f}">{$f} — {$d|date_fr:'d/m/Y à H:i'}</option> {/foreach} </select> </dd> <dd class="help"> Attention, en cas de restauration, l'intégralité des données courantes seront effacées et remplacées par celles contenues dans la sauvegarde sélectionnée. Cependant, afin de prévenir toute erreur une sauvegarde des données sera réalisée avant la restauration. </dd> </dl> <p> {csrf_field key="backup_manage"} <input type="submit" name="restore" value="Restaurer cette sauvegarde" /> <input type="submit" name="remove" value="Supprimer cette sauvegarde" /> </p> {/if} </fieldset> </form> <form method="post" action="{$self_url_no_qs}"> <fieldset> <legend>Sauvegarde manuelle</legend> <p> {csrf_field key="backup_create"} <input type="submit" name="create" value="Créer une nouvelle sauvegarde des données →" /> </p> </fieldset> </form> {include file="admin/_foot.tpl"} |
Added src/templates/admin/config/donnees/reset.tpl version [b44198b72b].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | {include file="admin/_head.tpl" title="Remise à zéro" current="config"} {include file="admin/config/_menu.tpl" current="donnees"} {include file="admin/config/donnees/_menu.tpl" current="reset"} {form_errors} {if $ok !== null} <p class="confirm">La remise à zéro a été effectuée. Une sauvegarde a également été créée.</p> </p> {/if} <form method="post" action="{$self_url_no_qs}"> <fieldset> <legend>Remise à zéro</legend> <p class="error"> Attention : toutes les données seront effacées ! Ceci inclut les membres, les opérations comptables, les pages du wiki, etc. Seul votre compte membre sera re-créé avec le même email et mot de passe. </p> <p class="help"> Une sauvegarde sera automatiquement créée avant de procéder à la remise à zéro. </p> <dl> <dt><label for="f_passe_verif">Votre mot de passe</label> (pour vérification)</dt> <dd><input type="password" name="passe_verif" id="f_passe_verif" /></dd> </dl> <p> {csrf_field key="reset"} <input type="submit" name="reset_ok" value="Oui, je veux remettre à zéro" /> </p> </fieldset> </form> {include file="admin/_foot.tpl"} |
Deleted src/templates/admin/config/import.tpl version [e2b6c250be].
|
| < < < < < < < < < < < < < < < < |
Modified src/templates/admin/config/index.tpl from [8b2246c56b] to [6078c55f63].
1 2 3 4 | {include file="admin/_head.tpl" title="Configuration" current="config"} {include file="admin/config/_menu.tpl" current="index"} | | | 1 2 3 4 5 6 7 8 9 10 11 12 | {include file="admin/_head.tpl" title="Configuration" current="config"} {include file="admin/config/_menu.tpl" current="index"} {if $ok && !$form->hasErrors()} <p class="confirm"> La configuration a bien été enregistrée. </p> {/if} {form_errors} |
︙ | ︙ |
Modified src/templates/admin/config/membres.tpl from [79611cc039] to [fcc1959f81].
1 2 | {include file="admin/_head.tpl" current="config" js=1} | | | 1 2 3 4 5 6 7 8 9 10 | {include file="admin/_head.tpl" current="config" js=1} {include file="admin/config/_menu.tpl" current="fiches_membres"} {if isset($status) && $status == 'OK'} <p class="confirm"> La configuration a bien été enregistrée. </p> {elseif isset($status) && $status == 'ADDED'} <p class="confirm"> |
︙ | ︙ |
Modified src/templates/admin/config/plugins.tpl from [f3dbb74805] to [d99e6b054a].
︙ | ︙ | |||
25 26 27 28 29 30 31 | </form> {else} {if !empty($liste_installes)} <table class="list"> <thead> <tr> <th>Extension</th> | | | > > > > > > > | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | </form> {else} {if !empty($liste_installes)} <table class="list"> <thead> <tr> <th>Extension</th> <td></td> <td>Version installée</td> <td></td> </tr> </thead> <tbody> {foreach from=$liste_installes item="plugin"} <tr{if $plugin.disabled} class="disabled"{/if}> <th> <h4>{$plugin.nom}</h4> <small>{$plugin.description}</small> </th> {if $plugin.disabled} <td colspan="3"> <span class="alert">Code source du plugin non trouvé dans le répertoire <em>plugins</em> !</span><br /> Ce plugin ne peut fonctionner ou être désinstallé. </td> {else} <td> <a href="{$plugin.url}" onclick="return !window.open(this.href);">{$plugin.auteur}</a> </td> <td> {$plugin.version} </td> <td class="actions"> {if empty($plugin.system)} <a href="{$admin_url}config/plugins.php?delete={$plugin.id}">Désinstaller</a> {/if} {if !empty($plugin.config)} {if empty($plugin.system)}|{/if} <a href="{plugin_url id=$plugin.id file="config.php"}">Configurer</a> {/if} </td> {/if} </tr> {/foreach} </tbody> </table> {else} <p class="help"> Aucune extension n'est installée. |
︙ | ︙ |
Modified src/templates/admin/config/site.tpl from [012fc113de] to [04150e10c9].
1 2 3 4 5 6 | {include file="admin/_head.tpl" title="Configuration — Site public" current="config" js=1} {form_errors} {include file="admin/config/_menu.tpl" current="site"} | > > > > > > > > > > > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | {include file="admin/_head.tpl" title="Configuration — Site public" current="config" js=1} {form_errors} {include file="admin/config/_menu.tpl" current="site"} {if $config.desactiver_site} <div class="alert"> <h3>Site public désactivé</h3> <p>Le site public est désactivé, les visiteurs sont redirigés automatiquement vers la page de connexion.</p> <form method="post" action="{$self_url}"> <p class="submit"> {csrf_field key="config_site"} <input type="submit" name="activer_site" value="Réactiver le site public →" /> </p> </form> </div> {elseif isset($edit)} <form method="post" action="{$self_url}"> <h3>Éditer un squelette</h3> {if $ok} <p class="confirm"> Modifications enregistrées. </p> |
︙ | ︙ | |||
33 34 35 36 37 38 39 | var skel_list = {$sources|escape:json}; var skel_current = "{$edit.file|escape:'js'}"; </script> <script type="text/javascript" src="{$admin_url}static/scripts/skel_editor.js"></script> {else} <fieldset> | | > > > > > > > > > > > > > | > > > > > | 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | var skel_list = {$sources|escape:json}; var skel_current = "{$edit.file|escape:'js'}"; </script> <script type="text/javascript" src="{$admin_url}static/scripts/skel_editor.js"></script> {else} <fieldset> <legend>Activation du site public</legend> <dl> <dt> <form method="post" action="{$self_url}"> <input type="submit" name="desactiver_site" value="Désactiver le site public" /> {csrf_field key="config_site"} </form> </dt> <dd class="help"> En désactivant le site public, les visiteurs seront automatiquement redirigés vers la page de connexion.<br /> Cette option est utile si vous avez déjà un site web et ne souhaitez pas utiliser la fonctionnalité site web de Garradin. </dd> </dl> </fieldset> <fieldset> <legend>Gérer le contenu du site public</legend> <p class="help"> Le contenu affiché sur le site est celui présent dans le wiki, il suffit de sélectionner « Cette page est visible ur le site de l'association » à l'édition d'une page wiki. Il est également possible de <a href="{$admin_url}wiki/creer.php?public">créer une nouvelle page publique sur le wiki</a>. </p> </fieldset> <form method="post" action="{$self_url}"> <fieldset class="templatesList"> <legend>Squelettes du site</legend> {if $reset_ok} |
︙ | ︙ |
Modified src/templates/admin/index.tpl from [82c846a0c8] to [68896b2b83].
1 2 3 4 5 6 7 8 | {include file="admin/_head.tpl" title="Bonjour %s !"|args:$user.identite current="home"} <ul class="actions"> <li><a href="{$admin_url}mes_infos.php">Modifier mes informations personnelles</a></li> {if $cotisation} <li> {if !$cotisation.a_jour} <b class="error">Cotisation en retard !</b> | > > | 1 2 3 4 5 6 7 8 9 10 | {include file="admin/_head.tpl" title="Bonjour %s !"|args:$user.identite current="home"} {$banniere|raw} <ul class="actions"> <li><a href="{$admin_url}mes_infos.php">Modifier mes informations personnelles</a></li> {if $cotisation} <li> {if !$cotisation.a_jour} <b class="error">Cotisation en retard !</b> |
︙ | ︙ |
Modified src/templates/admin/login.tpl from [a6078916db] to [ae198371c7].
|
| | | 1 2 3 4 5 6 7 8 | {include file="admin/_head.tpl" title="Connexion" js=1} {form_errors} {show_error if=$fail message="Connexion impossible. Vérifiez l'adresse e-mail et le mot de passe."} {if !$ssl_enabled && $prefer_ssl} <p class="alert"> <strong>Message de sécurité</strong><br /> |
︙ | ︙ | |||
43 44 45 46 47 48 49 50 51 | </p> <p class="help"> <a href="{$admin_url}password.php">Pas de mot de passe ou mot de passe perdu ?</a> </p> </form> {include file="admin/_foot.tpl"} | > > > > | 43 44 45 46 47 48 49 50 51 52 53 54 55 | </p> <p class="help"> <a href="{$admin_url}password.php">Pas de mot de passe ou mot de passe perdu ?</a> </p> </form> <script type="text/javascript"> g.enhancePasswordField($('#f_passe')); </script> {include file="admin/_foot.tpl"} |
Added src/templates/admin/membres/_list_actions.tpl version [92e160c09f].
> > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <tfoot> <tr> {if $session->canAccess('membres', Membres::DROIT_ADMIN)}<td class="check"><input type="checkbox" value="Tout cocher / décocher" /></td>{/if} <td class="actions" colspan="{$colspan}"> <em>Pour les membres cochés :</em> {csrf_field key="membres_action"} <select name="action"> <option value="">— Choisir une action à effectuer —</option> <option value="move">Changer de catégorie</option> <option value="csv">Exporter en tableau CSV</option> <option value="ods">Exporter en classeur ODS</option> <option value="delete">Supprimer</option> </select> <noscript> <input type="submit" value="OK" /> </noscript> </td> </tr> </tfoot> |
Added src/templates/admin/membres/_nav.tpl version [308ec1b1ac].
> > > > > > > > > | 1 2 3 4 5 6 7 8 9 | <ul class="actions"> <li{if $current == 'index'} class="current"{/if}><a href="{$admin_url}membres/">Liste des membres</a></li> <li{if $current == 'recherche'} class="current"{/if}><a href="{$admin_url}membres/recherche.php">Recherche avancée</a></li> <li{if $current == 'recherches'} class="current"{/if}><a href="{$admin_url}membres/recherches.php">Recherches enregistrées</a></li> {if $session->canAccess('membres', Membres::DROIT_ADMIN)} <li{if $current == 'sql'} class="current"{/if}><a href="{$admin_url}membres/recherche_sql.php">Recherche SQL</a></li> <li{if $current == 'import'} class="current"{/if}><a href="{$admin_url}membres/import.php">Import & export</a></li> {/if} </ul> |
Modified src/templates/admin/membres/action.tpl from [d79c9cc41b] to [a933fed19a].
1 2 3 4 5 6 7 8 | {include file="admin/_head.tpl" title="Action collective sur les membres" current="membres"} {form_errors} <form method="post" action="{$self_url}"> {foreach from=$selected item="id"} <input type="hidden" name="selected[]" value="{$id}" /> {/foreach} | > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 | {include file="admin/_head.tpl" title="Action collective sur les membres" current="membres"} <p class="alert"> {$selected|count} membres sélectionnés </p> {form_errors} <form method="post" action="{$self_url}"> {foreach from=$selected item="id"} <input type="hidden" name="selected[]" value="{$id}" /> {/foreach} |
︙ | ︙ |
Modified src/templates/admin/membres/ajouter.tpl from [f017ed08b2] to [a19929b9a3].
︙ | ︙ | |||
27 28 29 30 31 32 33 | </dd> <dd><input type="password" name="passe" id="f_passe" value="{form_field name=passe}" pattern=".{ldelim}6,{rdelim}" /></dd> <dt><label for="f_repasse">Encore le mot de passe</label> (vérification)</dt> <dd><input type="password" name="passe_confirmed" id="f_repasse" value="{form_field name=passe_confirmed}" pattern=".{ldelim}6,{rdelim}" /></dd> </dl> </fieldset> | | | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | </dd> <dd><input type="password" name="passe" id="f_passe" value="{form_field name=passe}" pattern=".{ldelim}6,{rdelim}" /></dd> <dt><label for="f_repasse">Encore le mot de passe</label> (vérification)</dt> <dd><input type="password" name="passe_confirmed" id="f_repasse" value="{form_field name=passe_confirmed}" pattern=".{ldelim}6,{rdelim}" /></dd> </dl> </fieldset> {if $session->canAccess('membres', Membres::DROIT_ADMIN)} <fieldset> <legend>Général</legend> <dl> <dt><label for="f_cat">Catégorie du membre</label> <b title="(Champ obligatoire)">obligatoire</b></dt> <dd> <select name="id_categorie" id="f_cat"> {foreach from=$membres_cats key="id" item="nom"} |
︙ | ︙ |
Deleted src/templates/admin/membres/categories/index.tpl version [9c762d5e02].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/templates/admin/membres/categories/modifier.tpl version [206fa39a37].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/templates/admin/membres/categories/supprimer.tpl version [145753eeb5].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Modified src/templates/admin/membres/cotisations.tpl from [90b6408dfe] to [9d70dea083].
1 2 3 4 | {include file="admin/_head.tpl" title="Cotisations du membre" current="membres/cotisations"} <ul class="actions"> <li><a href="{$admin_url}membres/fiche.php?id={$membre.id}"><b>{$membre.identite}</b></a></li> | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 | {include file="admin/_head.tpl" title="Cotisations du membre" current="membres/cotisations"} <ul class="actions"> <li><a href="{$admin_url}membres/fiche.php?id={$membre.id}"><b>{$membre.identite}</b></a></li> {if $session->canAccess('membres', Membres::DROIT_ECRITURE)}<li><a href="{$admin_url}membres/modifier.php?id={$membre.id}">Modifier</a></li>{/if} {if $session->canAccess('membres', Membres::DROIT_ADMIN) && $user.id != $membre.id} <li><a href="{$admin_url}membres/supprimer.php?id={$membre.id}">Supprimer</a></li> {/if} <li class="current"><a href="{$admin_url}membres/cotisations.php?id={$membre.id}">Suivi des cotisations</a></li> </ul> <dl class="cotisation"> {if $cotisation} |
︙ | ︙ | |||
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | {else} <span class="error">En retard</span> — <a href="{$admin_url}membres/cotisations/rappels.php?id={$membre.id}">Suivi des rappels</a> {/if} </dd> {/foreach} {/if} <dt><form method="get" action="{$admin_url}membres/cotisations/ajout.php"><input type="submit" value="Enregistrer une cotisation →" /><input type="hidden" name="id" value="{$membre.id}" /></form></dt> </dl> {if !empty($cotisations)} <table class="list"> <thead> <th>Date</th> <td>Cotisation</td> | > > | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | {else} <span class="error">En retard</span> — <a href="{$admin_url}membres/cotisations/rappels.php?id={$membre.id}">Suivi des rappels</a> {/if} </dd> {/foreach} {/if} {if $session->canAccess('membres', Membres::DROIT_ECRITURE)} <dt><form method="get" action="{$admin_url}membres/cotisations/ajout.php"><input type="submit" value="Enregistrer une cotisation →" /><input type="hidden" name="id" value="{$membre.id}" /></form></dt> {/if} </dl> {if !empty($cotisations)} <table class="list"> <thead> <th>Date</th> <td>Cotisation</td> |
︙ | ︙ | |||
78 79 80 81 82 83 84 | du {$c.debut|format_sqlite_date_to_french} au {$c.fin|format_sqlite_date_to_french} {else} ponctuelle {/if} — {$c.montant|escape|html_money} {$config.monnaie} </td> <td> | | > > | 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | du {$c.debut|format_sqlite_date_to_french} au {$c.fin|format_sqlite_date_to_french} {else} ponctuelle {/if} — {$c.montant|escape|html_money} {$config.monnaie} </td> <td> {if $session->canAccess('compta', Membres::DROIT_ECRITURE) && !empty($c.nb_operations)} <a href="{$admin_url}compta/operations/cotisation.php?id={$c.id}">{$c.nb_operations} écriture{if $c.nb_operations > 1}s{/if}</a> {/if} </td> <td class="actions"> <a class="icn" href="{$admin_url}membres/cotisations/voir.php?id={$c.id_cotisation}" title="Liste des membres inscrits à cette cotisation">👪</a> {if $session->canAccess('membres', Membres::DROIT_ECRITURE)} <a class="icn" href="{$admin_url}membres/cotisations/supprimer.php?id={$c.id}" title="Supprimer cette cotisation pour ce membre">✘</a> {/if} </td> </tr> {/foreach} </tbody> </table> {/if} {include file="admin/_foot.tpl"} |
Modified src/templates/admin/membres/cotisations/ajout.tpl from [3866bd8690] to [433111eec2].
1 2 3 4 5 6 | {if $membre} {include file="admin/_head.tpl" title="Enregistrer une cotisation pour le membre" current="membres/cotisations" js=1} <ul class="actions"> <li><a href="{$admin_url}membres/fiche.php?id={$membre.id}"><b>{$membre.identite}</b></a></li> <li><a href="{$admin_url}membres/modifier.php?id={$membre.id}">Modifier</a></li> | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | {if $membre} {include file="admin/_head.tpl" title="Enregistrer une cotisation pour le membre" current="membres/cotisations" js=1} <ul class="actions"> <li><a href="{$admin_url}membres/fiche.php?id={$membre.id}"><b>{$membre.identite}</b></a></li> <li><a href="{$admin_url}membres/modifier.php?id={$membre.id}">Modifier</a></li> {if $session->canAccess('membres', Membres::DROIT_ADMIN) && $user.id != $membre.id} <li><a href="{$admin_url}membres/supprimer.php?id={$membre.id}">Supprimer</a></li> {/if} <li><a href="{$admin_url}membres/cotisations.php?id={$membre.id}">Suivi des cotisations</a></li> </ul> {else} {include file="admin/_head.tpl" title="Enregistrer une cotisation" current="membres/cotisations" js=1} <ul class="actions"> <li><a href="{$admin_url}membres/cotisations/">Cotisations</a></li> <li class="current"><a href="{$admin_url}membres/cotisations/ajout.php">Saisie d'une cotisation</a></li> {if $session->canAccess('membres', Membres::DROIT_ADMIN)} <li><a href="{$admin_url}membres/cotisations/gestion/rappels.php">Gestion des rappels automatiques</a></li> {/if} </ul> {/if} {form_errors} {if $session->canAccess('compta', Membres::DROIT_ECRITURE)} <p class="help"> Cette page sert à enregistrer les cotisations des membres de l'association. Pour enregistrer un don ou une dépense, comme le paiement d'un prestataire ou une facture, il est possible de <a href="{$admin_url}compta/operations/saisir.php">saisir une opération comptable</a>. </p> {/if} <form method="post" action="{$self_url}"> |
︙ | ︙ |
Modified src/templates/admin/membres/cotisations/gestion/modifier.tpl from [a056f65f4d] to [0430bb0891].
1 2 3 4 5 | {include file="admin/_head.tpl" title="Modifier une cotisation" current="membres/cotisations" js=1} <ul class="actions"> <li class="current"><a href="{$admin_url}membres/cotisations/">Cotisations</a></li> <li><a href="{$admin_url}membres/cotisations/ajout.php">Saisie d'une cotisation</a></li> | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 | {include file="admin/_head.tpl" title="Modifier une cotisation" current="membres/cotisations" js=1} <ul class="actions"> <li class="current"><a href="{$admin_url}membres/cotisations/">Cotisations</a></li> <li><a href="{$admin_url}membres/cotisations/ajout.php">Saisie d'une cotisation</a></li> {if $session->canAccess('membres', Membres::DROIT_ADMIN)} <li><a href="{$admin_url}membres/cotisations/gestion/rappels.php">Gestion des rappels automatiques</a></li> {/if} </ul> {form_errors} <form method="post" action="{$self_url}"> |
︙ | ︙ |
Modified src/templates/admin/membres/cotisations/gestion/supprimer.tpl from [0c6872fd04] to [002d1f0636].
1 2 3 4 5 | {include file="admin/_head.tpl" title="Supprimer une cotisation" current="membres/cotisations"} <ul class="actions"> <li class="current"><a href="{$admin_url}membres/cotisations/">Cotisations</a></li> <li><a href="{$admin_url}membres/cotisations/ajout.php">Saisie d'une cotisation</a></li> | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 | {include file="admin/_head.tpl" title="Supprimer une cotisation" current="membres/cotisations"} <ul class="actions"> <li class="current"><a href="{$admin_url}membres/cotisations/">Cotisations</a></li> <li><a href="{$admin_url}membres/cotisations/ajout.php">Saisie d'une cotisation</a></li> {if $session->canAccess('membres', Membres::DROIT_ADMIN)} <li><a href="{$admin_url}membres/cotisations/gestion/rappels.php">Gestion des rappels automatiques</a></li> {/if} </ul> {form_errors} <form method="post" action="{$self_url}"> |
︙ | ︙ |
Modified src/templates/admin/membres/cotisations/index.tpl from [94a8f288ff] to [2f3ec3b601].
1 2 3 4 | {include file="admin/_head.tpl" title="Cotisations" current="membres/cotisations" js=1} <ul class="actions"> <li class="current"><a href="{$admin_url}membres/cotisations/">Cotisations</a></li> | > | > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | {include file="admin/_head.tpl" title="Cotisations" current="membres/cotisations" js=1} <ul class="actions"> <li class="current"><a href="{$admin_url}membres/cotisations/">Cotisations</a></li> {if $session->canAccess('membres', Membres::DROIT_ECRITURE)} <li><a href="{$admin_url}membres/cotisations/ajout.php">Saisie d'une cotisation</a></li> {/if} {if $session->canAccess('membres', Membres::DROIT_ADMIN)} <li><a href="{$admin_url}membres/cotisations/gestion/rappels.php">Gestion des rappels automatiques</a></li> {/if} </ul> <table class="list"> <thead> <th>Cotisation</th> |
︙ | ︙ | |||
31 32 33 34 35 36 37 | {/if} </td> <td class="num">{$co.montant|escape|html_money} {$config.monnaie}</td> <td class="num">{$co.nb_membres}</td> <td class="num">{$co.nb_a_jour}</td> <td class="actions"> <a class="icn" href="{$admin_url}membres/cotisations/voir.php?id={$co.id}" title="Liste des membres cotisants">👪</a> | | | | 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | {/if} </td> <td class="num">{$co.montant|escape|html_money} {$config.monnaie}</td> <td class="num">{$co.nb_membres}</td> <td class="num">{$co.nb_a_jour}</td> <td class="actions"> <a class="icn" href="{$admin_url}membres/cotisations/voir.php?id={$co.id}" title="Liste des membres cotisants">👪</a> {if $session->canAccess('membres', Membres::DROIT_ADMIN)} <a class="icn" href="{$admin_url}membres/cotisations/gestion/modifier.php?id={$co.id}" title="Modifier">✎</a> <a class="icn" href="{$admin_url}membres/cotisations/gestion/supprimer.php?id={$co.id}" title="Supprimer">✘</a> {/if} </td> </tr> {/foreach} </tbody> </table> {if $session->canAccess('membres', Membres::DROIT_ADMIN)} {form_errors} <p class="help"> Idée : les cotisations peuvent également être utilisées pour suivre les activités auxquelles sont inscrits les membres de l'association. </p> |
︙ | ︙ |
Modified src/templates/admin/membres/cotisations/rappels.tpl from [5544f55d3d] to [6fd6dc7342].
1 2 3 4 | {include file="admin/_head.tpl" title="Rappels pour cotisations du membre" current="membres/cotisations" js=1} <ul class="actions"> <li><a href="{$admin_url}membres/fiche.php?id={$membre.id}"><b>{$membre.identite}</b></a></li> | > | > | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | {include file="admin/_head.tpl" title="Rappels pour cotisations du membre" current="membres/cotisations" js=1} <ul class="actions"> <li><a href="{$admin_url}membres/fiche.php?id={$membre.id}"><b>{$membre.identite}</b></a></li> {if $session->canAccess('membres', Membres::DROIT_ECRITURE)} <li><a href="{$admin_url}membres/modifier.php?id={$membre.id}">Modifier</a></li> {/if} {if $session->canAccess('membres', Membres::DROIT_ADMIN) && $user.id != $membre.id} <li><a href="{$admin_url}membres/supprimer.php?id={$membre.id}">Supprimer</a></li> {/if} <li class="current"><a href="{$admin_url}membres/cotisations.php?id={$membre.id}">Suivi des cotisations</a></li> </ul> {if $session->canAccess('membres', Membres::DROIT_ECRITURE)} <form method="post" action="{$self_url}"> <fieldset> <legend>Enregistrer un rappel fait à ce membre</legend> <dl> <dt><label for="f_id_cotisation">Cotisation</label></dt> <dd> <select id="f_id_cotisation" name="id_cotisation"> |
︙ | ︙ | |||
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | </dl> <p class="submit"> {csrf_field key="add_rappel_%s"|args:$membre.id} <input type="submit" name="save" value="Enregistrer le rappel →" /> </p> </fieldset> </form> {if !empty($rappels)} <table class="list"> <thead> <th>Date du rappel</th> <td>Moyen de communication</td> <td>Cotisation</td> <td class="actions"></td> </thead> <tbody> {foreach from=$rappels item="r"} <tr> <th>{$r.date|format_sqlite_date_to_french}</th> <td> | > | | | | 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | </dl> <p class="submit"> {csrf_field key="add_rappel_%s"|args:$membre.id} <input type="submit" name="save" value="Enregistrer le rappel →" /> </p> </fieldset> </form> {/if} {if !empty($rappels)} <table class="list"> <thead> <th>Date du rappel</th> <td>Moyen de communication</td> <td>Cotisation</td> <td class="actions"></td> </thead> <tbody> {foreach from=$rappels item="r"} <tr> <th>{$r.date|format_sqlite_date_to_french}</th> <td> {if $r.media == Rappels_envoyes::MEDIA_AUTRE} Autre {elseif $r.media == Rappels_envoyes::MEDIA_COURRIER} Courrier {elseif $r.media == Rappels_envoyes::MEDIA_TELEPHONE} Téléphone {else} E-Mail {/if} </td> <td> {$r.intitule} — |
︙ | ︙ |
Modified src/templates/admin/membres/cotisations/supprimer.tpl from [14282381fd] to [979b1b65a7].
1 2 3 4 5 | {include file="admin/_head.tpl" title="Supprimer une cotisation pour le membre n°%s"|args:$membre.id current="membres/cotisations"} <ul class="actions"> <li><a href="{$admin_url}membres/fiche.php?id={$membre.id}">Membre n°{$membre.id}</a></li> <li><a href="{$admin_url}membres/modifier.php?id={$membre.id}">Modifier</a></li> | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 | {include file="admin/_head.tpl" title="Supprimer une cotisation pour le membre n°%s"|args:$membre.id current="membres/cotisations"} <ul class="actions"> <li><a href="{$admin_url}membres/fiche.php?id={$membre.id}">Membre n°{$membre.id}</a></li> <li><a href="{$admin_url}membres/modifier.php?id={$membre.id}">Modifier</a></li> {if $session->canAccess('membres', Membres::DROIT_ADMIN) && $user.id != $membre.id} <li><a href="{$admin_url}membres/supprimer.php?id={$membre.id}">Supprimer</a></li> {/if} <li class="current"><a href="{$admin_url}membres/cotisations.php?id={$membre.id}">Suivi des cotisations</a></li> </ul> {form_errors} |
︙ | ︙ | |||
24 25 26 27 28 29 30 | Celles-ci ne seront pas supprimées lors de la suppression de la cotisation membre. </p> {else} <p class="help"> Aucune écriture comptable n'est liée à cette cotisation. </p> {/if} | < | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | Celles-ci ne seront pas supprimées lors de la suppression de la cotisation membre. </p> {else} <p class="help"> Aucune écriture comptable n'est liée à cette cotisation. </p> {/if} </fieldset> <p class="submit"> {csrf_field key="del_cotisation_%s"|args:$cotisation.id} <input type="submit" name="delete" value="Supprimer →" /> </p> </form> {include file="admin/_foot.tpl"} |
Modified src/templates/admin/membres/cotisations/voir.tpl from [ae243e1d50] to [3ab24d7fdd].
1 2 3 4 | {include file="admin/_head.tpl" title="Membres ayant cotisé" current="membres/cotisations"} <ul class="actions"> <li class="current"><a href="{$admin_url}membres/cotisations/">Cotisations</a></li> | > | > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | {include file="admin/_head.tpl" title="Membres ayant cotisé" current="membres/cotisations"} <ul class="actions"> <li class="current"><a href="{$admin_url}membres/cotisations/">Cotisations</a></li> {if $session->canAccess('membres', Membres::DROIT_ECRITURE)} <li><a href="{$admin_url}membres/cotisations/ajout.php">Saisie d'une cotisation</a></li> {/if} {if $session->canAccess('membres', Membres::DROIT_ADMIN)} <li><a href="{$admin_url}membres/cotisations/gestion/rappels.php">Gestion des rappels automatiques</a></li> {/if} </ul> <dl class="cotisation"> <dt>Cotisation</dt> <dd>{$cotisation.intitule} — |
︙ | ︙ | |||
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | {foreach from=$liste item="co"} <tr> <td class="num"><a href="{$admin_url}membres/fiche.php?id={$co.id_membre}">{$co.numero}</a></td> <th>{$co.nom}</th> <td>{if $co.a_jour}<b class="confirm">À jour</b>{else}<b class="error">En retard</b>{/if}</td> <td>{$co.date|format_sqlite_date_to_french}</td> <td class="actions"> <a class="icn" href="{$admin_url}membres/cotisations/ajout.php?id={$co.id_membre}&cotisation={$cotisation.id}" title="Saisir une cotisation">➕</a> <a class="icn" href="{$admin_url}membres/cotisations.php?id={$co.id_membre}" title="Voir toutes les cotisations de ce membre">𝍢</a> <a class="icn" href="{$admin_url}membres/cotisations/rappels.php?id={$co.id_membre}" title="Rappels envoyés à ce membre">⚠</a> </td> </tr> {/foreach} </tbody> </table> {pagination url=$pagination_url page=$page bypage=$bypage total=$total} {/if} {include file="admin/_foot.tpl"} | > > | 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | {foreach from=$liste item="co"} <tr> <td class="num"><a href="{$admin_url}membres/fiche.php?id={$co.id_membre}">{$co.numero}</a></td> <th>{$co.nom}</th> <td>{if $co.a_jour}<b class="confirm">À jour</b>{else}<b class="error">En retard</b>{/if}</td> <td>{$co.date|format_sqlite_date_to_french}</td> <td class="actions"> {if $session->canAccess('membres', Membres::DROIT_ECRITURE)} <a class="icn" href="{$admin_url}membres/cotisations/ajout.php?id={$co.id_membre}&cotisation={$cotisation.id}" title="Saisir une cotisation">➕</a> {/if} <a class="icn" href="{$admin_url}membres/cotisations.php?id={$co.id_membre}" title="Voir toutes les cotisations de ce membre">𝍢</a> <a class="icn" href="{$admin_url}membres/cotisations/rappels.php?id={$co.id_membre}" title="Rappels envoyés à ce membre">⚠</a> </td> </tr> {/foreach} </tbody> </table> {pagination url=$pagination_url page=$page bypage=$bypage total=$total} {/if} {include file="admin/_foot.tpl"} |
Modified src/templates/admin/membres/fiche.tpl from [184a802b43] to [afe9db5157].
1 2 3 4 | {include file="admin/_head.tpl" title="%s (%s)"|args:$membre.identite:$categorie.nom current="membres"} <ul class="actions"> <li class="current"><a href="{$admin_url}membres/fiche.php?id={$membre.id}"><b>{$membre.identite}</b></a></li> | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 | {include file="admin/_head.tpl" title="%s (%s)"|args:$membre.identite:$categorie.nom current="membres"} <ul class="actions"> <li class="current"><a href="{$admin_url}membres/fiche.php?id={$membre.id}"><b>{$membre.identite}</b></a></li> {if $session->canAccess('membres', Membres::DROIT_ECRITURE)}<li><a href="{$admin_url}membres/modifier.php?id={$membre.id}">Modifier</a></li>{/if} {if $session->canAccess('membres', Membres::DROIT_ADMIN) && $user.id != $membre.id} <li><a href="{$admin_url}membres/supprimer.php?id={$membre.id}">Supprimer</a></li> {/if} <li><a href="{$admin_url}membres/cotisations.php?id={$membre.id}">Suivi des cotisations</a></li> </ul> <dl class="cotisation"> {if $cotisation} |
︙ | ︙ | |||
42 43 44 45 46 47 48 | {else} Aucune cotisation enregistrée {/if} </dt> <dd> <a href="{$admin_url}membres/cotisations.php?id={$membre.id}">Voir l'historique</a> </dd> | > | | | | | | | > | 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | {else} Aucune cotisation enregistrée {/if} </dt> <dd> <a href="{$admin_url}membres/cotisations.php?id={$membre.id}">Voir l'historique</a> </dd> {if $session->canAccess('membres', Membres::DROIT_ECRITURE)} <dd><form method="get" action="{$admin_url}membres/cotisations/ajout.php"><input type="submit" value="Enregistrer une cotisation →" /><input type="hidden" name="id" value="{$membre.id}" /></form></dd> {if !empty($nb_operations)} <dt>Écritures comptables</dt> <dd>{$nb_operations} écritures comptables — <a href="{$admin_url}compta/operations/membre.php?id={$membre.id}">Voir la liste des écritures ajoutées par ce membre</a> </dd> {/if} {/if} </dl> <aside class="describe"> <dl class="describe"> <dt>Catégorie</dt> <dd>{$categorie.nom} <span class="droits">{format_droits droits=$categorie}</span></dd> <dt>Inscription</dt> |
︙ | ︙ | |||
76 77 78 79 80 81 82 | {/if} {/if} </dd> </dl> </aside> <dl class="describe"> | | | | | | | > | | < | | | | | | | 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | {/if} {/if} </dd> </dl> </aside> <dl class="describe"> {foreach from=$champs key="c" item="c_config"} <dt>{$c_config.title}</dt> <dd> {if $c_config.type == 'checkbox'} {if $membre->$c}Oui{else}Non{/if} {elseif empty($membre->$c)} <em>(Non renseigné)</em> {elseif $c == $c_config.champ_identite} <strong>{$membre->$c}</strong> {elseif $c_config.type == 'email'} <a href="mailto:{$membre->$c|escape:'url'}">{$membre->$c}</a> {if $c == 'email'} | <a href="{$admin_url}membres/message.php?id={$membre.id}"><b class="icn action">✉</b> Envoyer un message</a> {/if} {elseif $c_config.type == 'tel'} <a href="tel:{$membre->$c}">{$membre->$c|format_tel}</a> {elseif $c_config.type == 'country'} {$membre->$c|get_country_name} {elseif $c_config.type == 'date' || $c_config.type == 'datetime'} {$membre->$c|format_sqlite_date_to_french} {elseif $c_config.type == 'password'} ******* {elseif $c_config.type == 'multiple'} <ul> {foreach from=$c_config.options key="b" item="name"} {if $membre->$c & (0x01 << $b)} <li>{$name}</li> {/if} {/foreach} </ul> {else} {$membre->$c|escape|rtrim|nl2br} {/if} </dd> {/foreach} </dl> {include file="admin/_foot.tpl"} |
Modified src/templates/admin/membres/import.tpl from [239f90c5ba] to [f774ddb844].
1 2 | {include file="admin/_head.tpl" title="Import & export des membres" current="membres" js=1} | > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | < < < < | < | < < < < < < < < < < < < < < < < > > < < < < < < < < < < < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | {include file="admin/_head.tpl" title="Import & export des membres" current="membres" js=1} {include file="admin/membres/_nav.tpl" current="import"} <ul class="actions sub"> <li class="current"><a href="{$admin_url}membres/import.php">Importer</a></li> <li><a href="{$admin_url}membres/import.php?export=csv">Exporter en CSV</a></li> <li><a href="{$admin_url}membres/import.php?export=ods">Exporter en classeur Office</a></li> </ul> {form_errors} {if $ok} <p class="confirm"> L'import s'est bien déroulé. </p> {/if} <form method="post" action="{$self_url}" enctype="multipart/form-data"> {if $csv_file} <fieldset> <legend>Importer depuis un fichier CSV générique</legend> <p class="help">{$csv_file|count} lignes trouvées dans le fichier</p> <dl> <dt><label><input type="checkbox" name="skip_first_line" value="1" checked="checked" /> Ne pas importer la première ligne</label></dt> <dd class="help">Décocher cette case si la première ligne ne contient pas l'intitulé des colonnes mais des données.</dd> <dt><label>Correspondance des champs</label></dt> <dd class="help">Indiquer la correspondance entre colonnes du CSV et champs des fiches membre.</dd> <dd> <table class="list auto"> <tbody> {foreach from=$csv_first_line key="index" item="csv_field"} <tr> <th>{$csv_field}</th> <td> <select name="csv_translate[{$index}]"> <option value="">-- Ne pas importer ce champ</option> {foreach from=$garradin_champs item="champ" key="name"} {if $champ.type == 'multiple' || $champ.type == 'file' || $name == 'passe'}{continue}{/if} <option value="{$name}">{$champ.title}</option> {/foreach} </select> </td> </tr> {/foreach} </tbody> </table> </dd> <dd class="help">Pour fusionner des colonnes, il suffit d'indiquer le même nom de champ pour plusieurs colonnes.</dd> </dl> </fieldset> <input type="hidden" name="csv_encoded" value="{$csv_file|escape:'json'|escape}" /> {else} <fieldset> <legend>Importer depuis un fichier</legend> <dl> <dt><label for="f_file">Fichier à importer</label> <b title="(Champ obligatoire)">obligatoire</b></dt> <dd><input type="file" name="upload" id="f_file" required="required" /></dd> <dt><label for="f_type">Type de fichier</label> <b title="(Champ obligatoire)">obligatoire</b></dt> <dd> <input type="radio" name="type" id="f_type" value="garradin" {form_field name=type checked="garradin" default="garradin"} /> <label for="f_type">Fichier CSV de Garradin</label> </dd> <dd class="help"> Export de la liste des membres au format CSV provenant de Garradin. Les lignes comportant un numéro de membre mettront à jour les fiches des membres ayant ce numéro (si le numéro existe), les lignes sans numéro ou avec un numéro inexistant créeront de nouveaux membres. </dd> <dd> <input type="radio" name="type" id="f_type_csv" value="csv" {form_field name=type checked="csv"} /> <label for="f_type_csv">Fichier CSV générique</label> </dd> <dd class="help"> Vous pourrez choisir la correspondance entre colonnes du CSV et champs des fiches membres dans le prochain écran. </dd> </dl> </fieldset> {/if} <p class="submit"> {csrf_field key="membres_import"} <input type="submit" name="import" value="Importer →" /> </p> </form> {include file="admin/_foot.tpl"} |
Modified src/templates/admin/membres/index.tpl from [346b3591a7] to [079c03ecc2].
1 2 | {include file="admin/_head.tpl" title="Liste des membres" current="membres" js=1} | | < < < < < < < < < | | | < < | | | | | < < | < < < < < < > > | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | {include file="admin/_head.tpl" title="Liste des membres" current="membres" js=1} {include file="admin/membres/_nav.tpl" current="index"} {if $sent} <p class="confirm">Votre message a été envoyé.</p> {/if} {if !empty($membres_cats)} <form method="get" action="{$self_url}" class="shortFormRight"> <fieldset> <legend>Filtrer par catégorie</legend> <select name="cat" id="f_cat" onchange="this.form.submit();"> <option value="0" {if $current_cat == 0} selected="selected"{/if}>-- Toutes</option> {foreach from=$membres_cats key="id" item="nom"} {if $session->canAccess('membres', Membres::DROIT_ECRITURE) || !array_key_exists($id, $membres_cats_cachees)} <option value="{$id}"{if $current_cat == $id} selected="selected"{/if}>{$nom}</option> {/if} {/foreach} </select> <noscript><input type="submit" value="Filtrer →" /></noscript> </fieldset> </form> {/if} <form method="get" action="{$admin_url}membres/recherche.php" class="shortFormLeft"> <fieldset> <legend>Rechercher un membre</legend> <input type="text" name="qt" value="" /> <input type="submit" value="Chercher →" /> </fieldset> </form> <form method="post" action="action.php" class="memberList"> {if !empty($liste)} <table class="list"> <thead class="userOrder"> <tr> {if $session->canAccess('membres', Membres::DROIT_ADMIN)}<td class="check"><input type="checkbox" title="Tout cocher / décocher" /></td>{/if} {foreach from=$champs key="c" item="champ"} <td class="{if $order == $c} cur {if $desc}desc{else}asc{/if}{/if}">{if $c == "numero"}#{else}{$champ.title}{/if} <a href="?o={$c}&a&cat={$current_cat}" class="icn up">↑</a><a href="?o={$c}&d&cat={$current_cat}" class="icn dn">↓</a></td> {/foreach} <td></td> </tr> </thead> <tbody> {foreach from=$liste item="membre"} <tr> {if $session->canAccess('membres', Membres::DROIT_ADMIN)}<td class="check"><input type="checkbox" name="selected[]" value="{$membre.id}" /></td>{/if} {foreach from=$champs key="c" item="cfg"} <td> {if $c == $config.champ_identite}<a href="{$admin_url}membres/fiche.php?id={$membre.id}">{/if} {$membre->$c|raw|display_champ_membre:$cfg} {if $c == $config.champ_identite}</a>{/if} </td> {/foreach} <td class="actions"> <a class="icn" href="{$admin_url}membres/fiche.php?id={$membre.id}" title="Fiche membre">👤</a> {if $session->canAccess('membres', Membres::DROIT_ECRITURE)}<a class="icn" href="{$admin_url}membres/modifier.php?id={$membre.id}" title="Modifier la fiche membre">✎</a>{/if} </td> </tr> {/foreach} </tbody> {if $session->canAccess('membres', Membres::DROIT_ADMIN)} {include file="admin/membres/_list_actions.tpl" colspan=count((array)$champs)+1} {/if} </table> {pagination url=$pagination_url page=$page bypage=$bypage total=$total} {else} <p class="alert"> Aucun membre trouvé. </p> {/if} </form> {include file="admin/_foot.tpl"} |
Modified src/templates/admin/membres/message.tpl from [6ceb73fe1d] to [3012105144].
1 2 3 4 5 6 7 8 9 10 | {include file="admin/_head.tpl" title="Contacter un membre" current="membres"} {form_errors} <form method="post" action="{$self_url}"> <fieldset class="memberMessage"> <legend>Message</legend> <dl> <dt>Expéditeur</dt> <dd>{$user.identite} <{$user.email}></dd> | < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | {include file="admin/_head.tpl" title="Contacter un membre" current="membres"} {form_errors} <form method="post" action="{$self_url}"> <fieldset class="memberMessage"> <legend>Message</legend> <dl> <dt>Expéditeur</dt> <dd>{$user.identite} <{$user.email}></dd> <dt>Destinataire</dt> <dd>{$membre.identite} ({$categorie.nom})</dd> <dt><label for="f_sujet">Sujet</label> <b title="(Champ obligatoire)">obligatoire</b></dt> <dd><input type="text" name="sujet" id="f_sujet" value="{form_field name=sujet}" required="required" /></dd> <dt><label for="f_message">Message</label> <b title="(Champ obligatoire)">obligatoire</b></dt> <dd><textarea name="message" id="f_message" cols="72" rows="25" required="required">{form_field name=message}</textarea></dd> <dd> |
︙ | ︙ |
Modified src/templates/admin/membres/message_collectif.tpl from [c3a52f70e1] to [873e17c7a4].
|
| | | | | | | | | | | | | | | > > > > > > | | > | | | > | > | < | | | > > > > | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | {include file="admin/_head.tpl" title="Envoyer un message collectif" current="membres/message"} {form_errors} <form method="post" action="{$self_url}"> <fieldset class="memberMessage"> <legend>Message</legend> <dl> <dt>Expéditeur</dt> <dd>{$config.nom_asso} <{$config.email_asso}></dd> <dt>Destinataires</dt> <dd> <select name="recipients"> <optgroup label="Catégorie de membres"> {foreach from=$categories key="id" item="nom"} <option value="categorie_{$id}" {form_field name="recipients" selected="categorie_%d"|args:$id}>{$nom}</option> {/foreach} </optgroup> <optgroup label="Recherche de membres"> {foreach from=$recherches item="r"} <option value="recherche_{$r.id}" {form_field name="recipients" selected="recherche_%d"|args:$r.qid}>{$r.intitule}</option> {/foreach} </optgroup> </select> </dd> {* FIXME : pas encore possible, en attente de refonte gestion cotisations <dd> <label><input type="checkbox" name="paid_members_only" value="1" {form_field name="paid_members_only" checked=1 default=1} /> Seulement les membres à jour de cotisation </label> </dd> *} <dt><label for="f_sujet">Sujet</label> <b title="(Champ obligatoire)">obligatoire</b></dt> <dd><input type="text" name="sujet" id="f_sujet" value="{form_field name=sujet}" required="required" /></dd> <dt><label for="f_message">Message</label> <b title="(Champ obligatoire)">obligatoire</b></dt> <dd><textarea name="message" id="f_message" cols="72" rows="25" required="required">{form_field name=message}</textarea></dd> <dd> <input type="checkbox" name="copie" id="f_copie" value="1" /> <label for="f_copie">Recevoir par e-mail une copie du message envoyé</label> </dd> </dl> </fieldset> <p class="submit"> {csrf_field key="send_message_co"} <input type="submit" name="send" value="Envoyer →" /> </p> </form> {include file="admin/_foot.tpl"} |
Modified src/templates/admin/membres/modifier.tpl from [f71297003d] to [fad59c5b3b].
1 2 3 4 5 | {include file="admin/_head.tpl" title="Modifier un membre" current="membres" js=1} <ul class="actions"> <li><a href="{$admin_url}membres/fiche.php?id={$membre.id}"><b>{$membre.identite}</b></a></li> <li class="current"><a href="{$admin_url}membres/modifier.php?id={$membre.id}">Modifier</a></li> | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 | {include file="admin/_head.tpl" title="Modifier un membre" current="membres" js=1} <ul class="actions"> <li><a href="{$admin_url}membres/fiche.php?id={$membre.id}"><b>{$membre.identite}</b></a></li> <li class="current"><a href="{$admin_url}membres/modifier.php?id={$membre.id}">Modifier</a></li> {if $session->canAccess('membres', Membres::DROIT_ADMIN) && $user.id != $membre.id} <li><a href="{$admin_url}membres/supprimer.php?id={$membre.id}">Supprimer</a></li> {/if} <li><a href="{$admin_url}membres/cotisations.php?id={$membre.id}">Suivi des cotisations</a></li> </ul> {form_errors} |
︙ | ︙ | |||
41 42 43 44 45 46 47 | </dd> <dd><input type="password" name="passe" id="f_passe" value="{form_field name=passe}" pattern=".{ldelim}6,{rdelim}" /></dd> <dt><label for="f_repasse">Encore le mot de passe</label> (vérification){if $champs.passe.mandatory} <b title="(Champ obligatoire)">obligatoire</b>{/if}</dt> <dd><input type="password" name="passe_confirmed" id="f_repasse" value="{form_field name=passe_confirmed}" pattern=".{ldelim}6,{rdelim}" /></dd> </dl> </fieldset> | | | 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | </dd> <dd><input type="password" name="passe" id="f_passe" value="{form_field name=passe}" pattern=".{ldelim}6,{rdelim}" /></dd> <dt><label for="f_repasse">Encore le mot de passe</label> (vérification){if $champs.passe.mandatory} <b title="(Champ obligatoire)">obligatoire</b>{/if}</dt> <dd><input type="password" name="passe_confirmed" id="f_repasse" value="{form_field name=passe_confirmed}" pattern=".{ldelim}6,{rdelim}" /></dd> </dl> </fieldset> {if $session->canAccess('membres', Membres::DROIT_ADMIN) && $user.id != $membre.id} <fieldset> <legend>Général</legend> <dl> <dt><label for="f_cat">Catégorie du membre</label> <b title="(Champ obligatoire)">obligatoire</b></dt> <dd> <select name="id_categorie" id="f_cat"> {foreach from=$membres_cats key="id" item="nom"} |
︙ | ︙ |
Modified src/templates/admin/membres/recherche.tpl from [3886f956f8] to [f88de1f28b].
|
| | | < < < < < < > | | | < > > | < | < < < < < < < < < < < | | | | | < < < < | < < > | < | > | | < < < < < > < < < | | < | < > | < | < > | > > > > > | | | | | | | | | > > > | > | < < < < | > > > | | | > | < < < | | > > | > | | < | < < > | > | > > | < < < < < < < < < | < | < < | < | < | > > | < < > > > > > > | < | > > | < < < < | < | < < < < < < < < | | | > > > > | > | | | | > > > > > > > > | > > > > > > > > > | | > > > | | | | < < < | < > | < | < < < < < < < < < < < < | | < > | < < < < < | | | < < < | | > | > > < < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 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 | {include file="admin/_head.tpl" title="Recherche de membre" current="membres" js=1 custom_js=['query_builder.min.js']} {include file="admin/membres/_nav.tpl" current="recherche"} {form_errors} <form method="post" action="{$admin_url}membres/recherche.php" id="queryBuilderForm"> <fieldset> <legend>Rechercher un membre</legend> <div class="queryBuilder" id="queryBuilder"></div> <p class="actions"> <label>Trier par <select name="order"> {foreach from=$colonnes key="colonne" item="config"} <option value="{$colonne}"{form_field name="order" selected=$colonne}>{$config.label}</option> {/foreach} </select> </label> <label><input type="checkbox" name="desc" value="1" {form_field name="desc" checked=1 default=$desc} /> Tri inversé</label> <label>Limiter à <input type="number" value="{$limit}" name="limit" size="5" /> résultats</label> </p> <p class="submit"> <input type="submit" value="Chercher →" id="send" /> <input type="hidden" name="q" id="jsonQuery" /> <input type="hidden" name="id" value="{$id}" /> <input type="submit" name="save" value="{if $id}Enregistrer : {$recherche.intitule|truncate:40:"…":true}{else}Enregistrer cette recherche{/if}" class="minor" /> </p> </fieldset> </form> <script type="text/javascript"> var colonnes = {$colonnes|escape:'json'}; {literal} var traductions = { "after": "après", "before": "avant", "is equal to": "est égal à", "is equal to one of": "est égal à une des ces options", "is not equal to one of": "n'est pas égal à une des ces options", "is not equal to": "n'est pas égal à", "is greater than": "est supérieur à", "is greater than or equal to": "est supérieur ou égal à", "is less than": "est inférieur à", "is less than or equal to": "est inférieur ou égal à", "is between": "est situé entre", "is not between": "n'est pas situé entre", "is null": "est nul", "is not null": "n'est pas nul", "begins with": "commence par", "doesn't begin with": "ne commence pas par", "ends with": "se termine par", "doesn't end with": "ne se termine pas par", "contains": "contient", "doesn't contain": "ne contient pas", "matches one of": "correspond à", "is true": "oui", "is false": "non", "Matches ALL of the following conditions:": "Correspond à TOUS les critères suivants :", "Matches ANY of the following conditions:": "Correspond à UN des critères suivants :", "Add a new set of conditions below this one": "-- Ajouter un groupe de critères", "Remove this set of conditions": "-- Supprimer ce groupe de critères" }; var q = new SQLQueryBuilder(colonnes); q.__ = function (str) { return traductions[str]; }; q.loadDefaultOperators(); q.buildInput = function (type, label, column) { if (label == '+') { label = '➕'; } else if (label == '-') { label = '➖'; } var i = document.createElement('input'); i.type = type == 'integer' ? 'number' : type; i.value = label; if (type == 'button') { i.className = 'icn action'; } return i; }; q.init(document.getElementById('queryBuilder')); $('#queryBuilderForm').onsubmit = function () { $('#jsonQuery').value = JSON.stringify(q.export()); }; {/literal} q.import({$query|escape:'json'}); </script> {if !empty($result)} {if $session->canAccess('membres', Membres::DROIT_ECRITURE)} <form method="post" action="{$admin_url}membres/action.php" class="memberList"> {/if} <p class="help">{$result|count} membres trouvés pour cette recherche.</p> <table class="list search"> <thead> <tr> {if $session->canAccess('membres', Membres::DROIT_ADMIN)}<td class="check"><input type="checkbox" value="Tout cocher / décocher" /></td>{/if} {foreach from=$result_header key="c" item="cfg"} <td>{$cfg.title}</td> {/foreach} <td></td> </tr> </thead> <tbody> {foreach from=$result item="row"} <tr> {if $session->canAccess('membres', Membres::DROIT_ADMIN)}<td class="check"><input type="checkbox" name="selected[]" value="{$row.id}" /></td>{/if} {foreach from=$row key="key" item="value"} <?php $link = false; ?> {if isset($result_header[$key])} <td> {if !$link} <a href="{$admin_url}membres/fiche.php?id={$row.id}"> {/if} {$value|raw|display_champ_membre:$result_header[$key]} {if !$link} <?php $link = true; ?> </a> {/if} </td> {/if} {/foreach} <td class="actions"> <a class="icn" href="{$admin_url}membres/fiche.php?id={$row.id}" title="Fiche membre">👤</a> {if $session->canAccess('membres', Membres::DROIT_ECRITURE)} <a class="icn" href="{$admin_url}membres/modifier.php?id={$row.id}" title="Modifier la fiche membre">✎</a> {/if} </td> </tr> {/foreach} </tbody> {if $session->canAccess('membres', Membres::DROIT_ADMIN)} {include file="admin/membres/_list_actions.tpl" colspan=count($result_header)+1} {/if} </table> {if $session->canAccess('membres', Membres::DROIT_ECRITURE)} </form> {/if} {elseif $result !== null} <p class="alert"> Aucun membre trouvé. </p> </form> {/if} {include file="admin/_foot.tpl"} |
Modified src/templates/admin/membres/recherche_sql.tpl from [4ba2fc1f34] to [af64d8399c].
|
| | > > > | | | | | | | | | | | > > > > | | | > < < < | < < > | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > > | < < < < < < < < < < | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | {include file="admin/_head.tpl" title="Recherche par requête SQL" current="membres" js=1} {include file="admin/membres/_nav.tpl" current="sql"} {if $session->canAccess('membres', Membres::DROIT_ADMIN)} <form method="get" action="{$admin_url}membres/recherche_sql.php"> <fieldset> <legend>Schéma des tables SQL</legend> <pre class="sql_schema">{$schema.membres}</pre> <dl> <dt><label for="f_query">Requête SQL</label></dt> <dd class="help">Si aucune limite n'est précisée, une limite de 100 résultats sera appliquée.</dd> <dd><textarea name="query" id="f_query" cols="70" rows="7" required="required">{$query}</textarea></dd> </dl> <p class="submit"> <input type="submit" name="run" value="Exécuter →" /> {if $query} {if $id}<input type="hidden" name="id" value="{$id}" />{/if} <input type="submit" name="save" value="{if $id}Enregistrer : {$recherche.intitule}{else}Enregistrer cette recherche{/if}" class="minor" /> {/if} </p> </fieldset> </form> {/if} {form_errors} <form method="post" action="{$admin_url}membres/action.php" class="memberList"> {if !empty($result)} <p class="alert">{$result|count} résultats retournés.</p> <table class="list search"> <thead> {if array_key_exists('id', $result[0])} <td class="check"><input type="checkbox" value="Tout cocher / décocher" onclick="g.checkUncheck();" /></td> {/if} {foreach from=$result[0] key="col" item="ignore"} <td>{$col}</td> {/foreach} {if array_key_exists('id', $result[0])} <td></td> {/if} </thead> <tbody> {foreach from=$result item="row"} <tr> {if $session->canAccess('membres', Membres::DROIT_ADMIN) && array_key_exists('id', $result[0])} <td class="check">{if !empty($row.id)}<input type="checkbox" name="selected[]" value="{$row.id}" />{/if}</td> {/if} {foreach from=$row item="col"} <td>{$col}</td> {/foreach} {if array_key_exists('id', $result[0])} <td class="actions"> {if !empty($row.id)} <a class="icn" href="{$admin_url}membres/fiche.php?id={$row.id}" title="Fiche membre">👤</a> <a class="icn" href="{$admin_url}membres/modifier.php?id={$row.id}" title="Modifier ce membre">✎</a> {/if} </td> {/if} </tr> {/foreach} </tbody> {if $session->canAccess('membres', Membres::DROIT_ADMIN)} {include file="admin/membres/_list_actions.tpl" colspan=count((array)$result[0])+1} {/if} </table> {else} <p class="alert"> Aucun membre trouvé. </p> {/if} </form> {include file="admin/_foot.tpl"} |
Added src/templates/admin/membres/recherches.tpl version [3685bb7adf].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | {include file="admin/_head.tpl" title="Recherches enregistrées" current="membres"} {include file="admin/membres/_nav.tpl" current="recherches"} {form_errors} {if $mode == 'edit'} <form method="post" action="{$self_url}"> <fieldset> <legend>Modifier une recherche enregistrée</legend> <dl> <dt><label for="f_intitule">Intitulé</label> <b title="(Champ obligatoire)">obligatoire</b></dt> <dd><input type="text" name="intitule" id="f_intitule" value="{form_field name="intitule" data=$recherche}" size="80" required="required" /></dd> <dt>Statut</dt> <dd><label><input type="radio" name="prive" value="1" {if $recherche.id_membre}checked="checked"{/if} /> Recherche privée</label> — Visible seulement par moi-même</dd> <dd><label><input type="radio" name="prive" value="0" {if !$recherche.id_membre}checked="checked"{/if} /> Recherche publique</label> — Visible et exécutable par tous les membres ayant accès à la gestion des membres</dd> <dt>Type</dt> <dd>{if $recherche.type == Recherche::TYPE_JSON}Avancée{else}SQL{/if}</dd> <dt>Cible</dt> <dd>{$recherche.cible}</dd> </dl> </fieldset> <p class="submit"> {csrf_field key="edit_recherche_%s"|args:$recherche.id} <input type="submit" name="save" value="Enregistrer →" /> </p> </form> {elseif $mode == 'delete'} <form method="post" action="{$self_url}"> <fieldset> <legend>Supprimer une recherche enregistrée</legend> <h3 class="warning"> Êtes-vous sûr de vouloir supprimer la recherche enregistrée {$recherche.intitule} ? </h3> </fieldset> <p class="submit"> {csrf_field key="del_recherche_%s"|args:$recherche.id} <input type="submit" name="delete" value="Supprimer →" /> </p> </form> {elseif count($liste) == 0} <p class="alert">Aucune recherche enregistrée. <a href="{$admin_url}membres/recherche.php">Faire une nouvelle recherche</a></p> {else} <table class="list"> <thead> <tr> <th>Recherche</th> <th>Type</th> <th>Statut</th> <th></th> </tr> </thead> <tbody> {foreach from=$liste item="recherche"} <tr> <th>{$recherche.intitule}</th> <td>{if $recherche.type == Recherche::TYPE_JSON}Avancée{else}SQL{/if}</td> <td>{if !$recherche.id_membre}Publique{else}Privée{/if}</td> <td class="actions"> <a href="{$admin_url}membres/recherche{if $recherche.type == Recherche::TYPE_SQL}_sql{/if}.php?id={$recherche.id}" class="icn" title="Exécuter">𝍢</a> {if $recherche.id_membre || $session->canAccess('membres', Membres::DROIT_ADMIN)} <a href="{$admin_url}membres/recherches.php?edit={$recherche.id}" class="icn" title="Modifier">✎</a> <a href="{$admin_url}membres/recherches.php?delete={$recherche.id}" class="icn" title="Supprimer">✘</a> {/if} </td> </tr> {/foreach} </tbody> </table> {/if} {include file="admin/_foot.tpl"} |
Modified src/templates/admin/membres/supprimer.tpl from [8d6ea3457e] to [3ee78004e1].
1 2 3 4 5 | {include file="admin/_head.tpl" title="Supprimer un membre" current="membres"} <ul class="actions"> <li><a href="{$admin_url}membres/fiche.php?id={$membre.id}"><b>{$membre.identite}</b></a></li> <li><a href="{$admin_url}membres/modifier.php?id={$membre.id}">Modifier</a></li> | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 | {include file="admin/_head.tpl" title="Supprimer un membre" current="membres"} <ul class="actions"> <li><a href="{$admin_url}membres/fiche.php?id={$membre.id}"><b>{$membre.identite}</b></a></li> <li><a href="{$admin_url}membres/modifier.php?id={$membre.id}">Modifier</a></li> {if $session->canAccess('membres', Membres::DROIT_ADMIN)} <li class="current"><a href="{$admin_url}membres/supprimer.php?id={$membre.id}">Supprimer</a></li> {/if} <li><a href="{$admin_url}membres/cotisations.php?id={$membre.id}">Suivi des cotisations</a></li> </ul> {form_errors} |
︙ | ︙ |
Modified src/templates/admin/mes_infos_securite.tpl from [7c9c1d22c9] to [811d2ba17a].
︙ | ︙ | |||
63 64 65 66 67 68 69 | </form> {else} <form method="post" action="{$self_url_no_qs}"> <fieldset> <legend>Changer mon mot de passe</legend> | | | 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | </form> {else} <form method="post" action="{$self_url_no_qs}"> <fieldset> <legend>Changer mon mot de passe</legend> {if $user.droit_membres < Membres::DROIT_ADMIN && (!empty($champs.passe.private) || empty($champs.passe.editable))} <p class="help">Vous devez contacter un administrateur pour changer votre mot de passe.</p> {else} <dl> <dd>Vous avez déjà un mot de passe, ne remplissez les champs suivants que si vous souhaitez en changer.</dd> <dt><label for="f_passe">Nouveau mot de passe</label></dt> <dd class="help"> Astuce : un mot de passe de quatre mots choisis au hasard dans le dictionnaire est plus sûr |
︙ | ︙ |
Modified src/templates/admin/wiki/historique.tpl from [d5a6d6126a] to [7c0d2ecc52].
1 2 3 | {include file="admin/_head.tpl" title="Historique : %s"|args:$page.titre current="wiki"} <ul class="actions"> | | | 1 2 3 4 5 6 7 8 9 10 11 | {include file="admin/_head.tpl" title="Historique : %s"|args:$page.titre current="wiki"} <ul class="actions"> <li><a href="{$admin_url}wiki/?{$page.uri}">Retour à la page</a></li> </ul> {if !empty($revisions)} <table class="list wikiRevisions"> {foreach from=$revisions item="rev"} <tr> <td> |
︙ | ︙ | |||
23 24 25 26 27 28 29 | {else} <a href="?id={$page.id}&diff={$rev.revision-1}.{$rev.revision}">diff</a> {/if} {/if} </td> <th>{$rev.date|date_fr:'d/m/Y à H:i'}</th> <td> | | | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | {else} <a href="?id={$page.id}&diff={$rev.revision-1}.{$rev.revision}">diff</a> {/if} {/if} </td> <th>{$rev.date|date_fr:'d/m/Y à H:i'}</th> <td> {if $session->canAccess('membres', Membres::DROIT_ACCES)} <a href="{$admin_url}membres/fiche.php?id={$rev.id_auteur}">{$rev.nom_auteur}</a> {/if} </td> <td class="length"> {$rev.taille} octets {if $rev.revision > 1 && !$rev.chiffrement} {if $rev.diff_taille > 0} |
︙ | ︙ | |||
50 51 52 53 54 55 56 | </td> </tr> {/foreach} </table> {elseif !empty($diff)} <div class="wikiRevision revisionLeft"> <h3>Version du {$rev1.date|date_fr:'d/m/Y à H:i'}</h3> | | | | 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | </td> </tr> {/foreach} </table> {elseif !empty($diff)} <div class="wikiRevision revisionLeft"> <h3>Version du {$rev1.date|date_fr:'d/m/Y à H:i'}</h3> {if $session->canAccess('membres', Membres::DROIT_ACCES)} <h4>De <a href="{$admin_url}membres/fiche.php?id={$rev1.id_auteur}">{$rev1.nom_auteur}</a></h4> {/if} {if $rev1.modification} <p><em>{$rev1.modification}</em></p> {/if} </div> <div class="wikiRevision revisionRight"> <h3>Version {if $rev2.revision == $page.revision}actuelle en date{/if} du {$rev2.date|date_fr:'d/m/Y à H:i'}</h3> {if $session->canAccess('membres', Membres::DROIT_ACCES)} <h4>De <a href="{$admin_url}membres/fiche.php?id={$rev2.id_auteur}">{$rev2.nom_auteur}</a></h4> {/if} {if $rev2.modification} <p><em>{$rev2.modification}</em></p> {/if} </div> {diff old=$rev1.contenu new=$rev2.contenu} |
︙ | ︙ |
Modified src/templates/admin/wiki/page.tpl from [9618962284] to [c9d6b7be81].
1 2 3 4 5 6 7 | {if !empty($page.titre) && $can_read} {include file="admin/_head.tpl" title=$page.titre current="wiki" js=1} {else} {include file="admin/_head.tpl" title="Wiki" current="wiki"} {/if} <ul class="actions"> | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | {if !empty($page.titre) && $can_read} {include file="admin/_head.tpl" title=$page.titre current="wiki" js=1} {else} {include file="admin/_head.tpl" title="Wiki" current="wiki"} {/if} <ul class="actions"> {if $session->canAccess('wiki', Membres::DROIT_ECRITURE)} <li><a href="{$admin_url}wiki/creer.php?parent={if $config.accueil_wiki == $page.uri}0{else}{$page.id}{/if}"><strong>Créer une nouvelle page</strong></a></li> {/if} {if $can_edit} <li><a href="{$admin_url}wiki/editer.php?id={$page.id}">Éditer</a></li> {/if} {if $can_read && $page && $page.contenu} <li><a href="{$admin_url}wiki/historique.php?id={$page.id}">Historique</a> {if $page.droit_lecture == Wiki::LECTURE_PUBLIC} <li><a href="{$www_url}{$page.uri}{if $has_public_children}/{/if}">Voir sur le site</a> {/if} {/if} {if $session->canAccess('wiki', Membres::DROIT_ADMIN)} <li><a href="{$admin_url}wiki/supprimer.php?id={$page.id}">Supprimer</a></li> {/if} </ul> {if !$can_read} <p class="alert">Vous n'avez pas le droit de lire cette page.</p> {else} |
︙ | ︙ | |||
116 117 118 119 120 121 122 | </ul> {/if} </div> {/if} <p class="wikiFooter"> Dernière modification le {$page.date_modification|date_fr:'d/m/Y à H:i'} | | | 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | </ul> {/if} </div> {/if} <p class="wikiFooter"> Dernière modification le {$page.date_modification|date_fr:'d/m/Y à H:i'} {if $session->canAccess('membres', Membres::DROIT_ACCES)} par <a href="{$admin_url}membres/fiche.php?id={$page.contenu.id_auteur}">{$auteur}</a> {/if} </p> {/if} {/if} {/if} {include file="admin/_foot.tpl"} |
Modified src/templates/error.tpl from [f1a21eb4e1] to [52bccc1e68].
1 2 3 4 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> | | | 1 2 3 4 5 6 7 8 9 10 11 12 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>{if empty($title)}Erreur{else}{$title}{/if}</title> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <style type="text/css"> {literal} * { margin: 0; padding: 0; } html { width: 100%; height: 100%; } body { |
︙ | ︙ | |||
27 28 29 30 31 32 33 | } {/literal} </style> </head> <body> | | | | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | } {/literal} </style> </head> <body> <h1>{if empty($title)}Erreur{else}{$title}{/if}</h1> <p class="error"> {$error|escape|nl2br} </p> <p> <a href="{$www_url}" onclick="return history.back();">← Retour</a> </p> </body> </html> |
Modified src/www/.htaccess from [9e40080631] to [8c789141ef].
1 2 | Options -MultiViews -Indexes | > > | | < < | | < < | < | 1 2 3 4 5 6 7 8 9 10 11 | Options -MultiViews -Indexes DirectoryIndex index.php # FallbackResource n'est dispo que depuis Apache 2.2.16, soit Debian Wheezy (2013) <IfModule mod_version.c> <IfVersion >= 2.2.16> FallbackResource /_route.php </IfVersion> </IfModule> ErrorDocument 404 /_route.php |
Modified src/www/admin/_inc.php from [e0bbbc300b] to [d6f6a6d40f].
︙ | ︙ | |||
66 67 68 69 70 71 72 | $tpl->assign('is_logged', true); $user = $session->getUser(); $tpl->assign('user', $user); $tpl->assign('current', ''); | < | > | > | > > | 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | $tpl->assign('is_logged', true); $user = $session->getUser(); $tpl->assign('user', $user); $tpl->assign('current', ''); if ($session->get('plugins_menu') === null) { // Construction de la liste de plugins pour le menu // et stockage en session pour ne pas la recalculer à chaque page $session->set('plugins_menu', Plugin::listMenu($user)); } $tpl->assign('plugins_menu', $session->get('plugins_menu')); } |
Modified src/www/admin/compta/import.php from [7e73141123] to [d14bd1f9b9].
1 2 3 4 5 6 7 8 9 10 11 12 | <?php namespace Garradin; require_once __DIR__ . '/_inc.php'; $session->requireAccess('compta', Membres::DROIT_ADMIN); $e = new Compta\Exercices; $import = new Compta\Import; if (qg('export') == 'csv') { | < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <?php namespace Garradin; require_once __DIR__ . '/_inc.php'; $session->requireAccess('compta', Membres::DROIT_ADMIN); $e = new Compta\Exercices; $import = new Compta\Import; if (qg('export') == 'csv') { $import->toCSV($e->getCurrentId()); exit; } elseif (qg('export') == 'ods') { $import->toODS($e->getCurrentId()); exit; } if (f('import')) { $form->check('compta_import', [ |
︙ | ︙ |
Added src/www/admin/config/categories/index.php version [c7ce3325e0].
> > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | <?php namespace Garradin; require_once __DIR__ . '/../_inc.php'; $cats = new Membres\Categories; if (f('save')) { $form->check('new_cat', [ 'nom' => 'required', ]); if (!$form->hasErrors()) { $cats->add([ 'nom' => f('nom'), ]); Utils::redirect(ADMIN_URL . 'config/categories/'); } } $tpl->assign('liste', $cats->listCompleteWithStats()); $tpl->display('admin/config/categories/index.tpl'); |
Added src/www/admin/config/categories/modifier.php version [6a75b928b9].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | <?php namespace Garradin; require_once __DIR__ . '/../_inc.php'; $cats = new Membres\Categories; qv(['id' => 'required|numeric']); $id = (int) qg('id'); $cat = $cats->get($id); if (!$cat) { throw new UserException("Cette catégorie n'existe pas."); } if (f('save')) { $droits = implode(',', [ Membres::DROIT_AUCUN, Membres::DROIT_ACCES, Membres::DROIT_ECRITURE, Membres::DROIT_ADMIN, ]); $form->check('edit_cat_' . $id, [ 'nom' => 'required', 'droit_wiki' => 'in:' . $droits, 'droit_compta' => 'in:' . $droits, 'droit_membres' => 'in:' . $droits, 'droit_config' => sprintf('in:%s,%s', Membres::DROIT_ADMIN, Membres::DROIT_AUCUN), 'droit_connexion' => sprintf('in:%s,%s', Membres::DROIT_ACCES, Membres::DROIT_AUCUN), 'droit_inscription' => sprintf('in:%s,%s', Membres::DROIT_ACCES, Membres::DROIT_AUCUN), 'cacher' => 'boolean', 'id_cotisation_obligatoire' => 'numeric', ]); if (!$form->hasErrors()) { $data = [ 'nom' => f('nom'), 'droit_wiki' => (int) f('droit_wiki'), 'droit_compta' => (int) f('droit_compta'), 'droit_config' => (int) f('droit_config'), 'droit_membres' => (int) f('droit_membres'), 'droit_connexion' => (int) f('droit_connexion'), 'droit_inscription' => (int) f('droit_inscription'), 'cacher' => (int) f('cacher'), 'id_cotisation_obligatoire' => (int) f('id_cotisation_obligatoire'), ]; // Ne pas permettre de modifier la connexion, l'accès à la config et à la gestion des membres // pour la catégorie du membre qui édite les catégories, sinon il pourrait s'empêcher // de se connecter ou n'avoir aucune catégorie avec le droit de modifier les catégories ! if ($cat->id == $user->id_categorie) { $data['droit_connexion'] = Membres::DROIT_ACCES; $data['droit_config'] = Membres::DROIT_ADMIN; } try { $cats->edit($id, $data); if ($id == $user->id_categorie) { // Mise à jour de la session courante $session->refresh(); } Utils::redirect(ADMIN_URL . 'config/categories/'); } catch (UserException $e) { $form->addError($e->getMessage()); } } } $tpl->assign('cat', $cat); $tpl->assign('readonly', $cat->id == $user->id_categorie ? 'disabled="disabled"' : ''); $cotisations = new Cotisations; $tpl->assign('cotisations', $cotisations->listCurrent()); $tpl->assign('membres', new Membres); $tpl->display('admin/config/categories/modifier.tpl'); |
Added src/www/admin/config/categories/supprimer.php version [93c453e7a7].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | <?php namespace Garradin; require_once __DIR__ . '/../_inc.php'; $cats = new Membres\Categories; qv(['id' => 'required|numeric']); $id = (int) qg('id'); $cat = $cats->get($id); if (!$cat) { throw new UserException("Cette catégorie n'existe pas."); } if ($cat->id == $user->id_categorie) { throw new UserException("Vous ne pouvez pas supprimer votre catégorie."); } if (f('delete')) { $form->check('delete_cat_' . $id); if (!$form->hasErrors()) { try { $cats->remove($id); Utils::redirect(ADMIN_URL . 'config/categories/'); } catch (UserException $e) { $form->addError($e->getMessage()); } } } $tpl->assign('cat', $cat); $tpl->display('admin/config/categories/supprimer.tpl'); |
Deleted src/www/admin/config/donnees.php version [37588fe983].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Added src/www/admin/config/donnees/automatique.php version [05a939d15b].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | <?php namespace Garradin; require_once __DIR__ . '/../_inc.php'; if (!ENABLE_AUTOMATIC_BACKUPS) { throw new UserException('Les sauvegardes automatiques sont désactivées.'); } if (f('config')) { $form->check('backup_config', [ 'frequence_sauvegardes' => 'present|numeric|min:0|max:365', 'nombre_sauvegardes' => 'present|numeric|min:1|max:90', ]); if (!$form->hasErrors()) { try { $config->set('frequence_sauvegardes', f('frequence_sauvegardes')); $config->set('nombre_sauvegardes', f('nombre_sauvegardes')); $config->save(); Utils::redirect(ADMIN_URL . 'config/donnees/automatique.php?ok=config'); } catch (UserException $e) { $form->addError($e->getMessage()); } } } $tpl->assign('ok', qg('ok')); $tpl->display('admin/config/donnees/automatique.tpl'); |
Added src/www/admin/config/donnees/import.php version [f13c6c5a62].
> > > > > > | 1 2 3 4 5 6 | <?php namespace Garradin; require_once __DIR__ . '/../_inc.php'; $tpl->display('admin/config/donnees/import.tpl'); |
Added src/www/admin/config/donnees/index.php version [a41ebc5c56].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | <?php namespace Garradin; require_once __DIR__ . '/../_inc.php'; $s = new Sauvegarde; if (f('download')) { $form->check('backup_download'); if (!$form->hasErrors()) { header('Content-type: application/octet-stream'); header('Content-Disposition: attachment; filename="' . $config->get('nom_asso') . ' - Sauvegarde données - ' . date('Y-m-d') . '.sqlite"'); header('Content-Length: ' . $s->getDBSize(true)); $s->dump(); exit; } } elseif (f('restore_file')) { $form->check('backup_restore'); if (!$form->hasErrors()) { // Ignorer la vérification d'intégrité si autorisé et demandé $check = (ALLOW_MODIFIED_IMPORT && f('force_import')) ? false : true; try { $r = $s->restoreFromUpload($_FILES['file'], $user->id, $check); Utils::redirect(ADMIN_URL . 'config/donnees/?ok=restore&code=' . (int)$r); } catch (UserException $e) { $form->addError($e->getMessage()); $code = $e->getCode(); } } } $tpl->assign('db_size', $s->getDBSize()); $tpl->assign('files_size', $s->getDBFilesSize()); $tpl->assign('code', isset($code) ? $code : null); $tpl->assign('ok_code', qg('code')); $tpl->assign('ok', qg('ok')); $tpl->assign('now_date', date('Y-m-d')); $tpl->assign('max_file_size', Utils::getMaxUploadSize()); $tpl->display('admin/config/donnees/index.tpl'); |
Added src/www/admin/config/donnees/local.php version [c67b3c1387].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | <?php namespace Garradin; require_once __DIR__ . '/../_inc.php'; $s = new Sauvegarde; if (f('create')) { $form->check('backup_create'); if (!$form->hasErrors()) { try { $s->create(); Utils::redirect(ADMIN_URL . 'config/donnees/local.php?ok=create'); } catch (UserException $e) { $form->addError($e->getMessage()); } } } if (f('restore')) { $form->check('backup_manage'); if (!$form->hasErrors()) { try { $r = $s->restoreFromLocal(f('file')); Utils::redirect(ADMIN_URL . 'config/donnees/local.php?ok=restore&code=' . (int)$r); } catch (UserException $e) { $form->addError($e->getMessage()); } } } elseif (f('remove')) { $form->check('backup_manage'); if (!$form->hasErrors()) { try { $s->remove(f('file')); Utils::redirect(ADMIN_URL . 'config/donnees/local.php?ok=remove'); } catch (UserException $e) { $form->addError($e->getMessage()); } } } $tpl->assign('ok_code', qg('code')); $tpl->assign('ok', qg('ok')); $tpl->assign('liste', $s->getList()); $tpl->display('admin/config/donnees/local.tpl'); |
Added src/www/admin/config/donnees/reset.php version [3891123042].
> > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <?php namespace Garradin; require_once __DIR__ . '/../_inc.php'; $s = new Sauvegarde; if (f('reset_ok')) { $form->check('reset'); if (!$form->hasErrors()) { try { Install::reset($session, f('passe_verif')); Utils::redirect(ADMIN_URL . 'config/donnees/reset.php?ok'); } catch (UserException $e) { $form->addError($e->getMessage()); } } } $tpl->assign('ok', qg('ok')); $tpl->display('admin/config/donnees/reset.tpl'); |
Deleted src/www/admin/config/import.php version [0d90db7427].
|
| < < < < < < |
Modified src/www/admin/config/plugins.php from [e71350c226] to [3d32d903c2].
︙ | ︙ | |||
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 'plugin' => 'required', ]); if (!$form->hasErrors()) { try { Plugin::install(f('plugin'), false); Utils::redirect(ADMIN_URL . 'config/plugins.php'); } catch (UserException $e) { $form->addError($e->getMessage()); } } } if (f('delete')) { | > | < < > | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | 'plugin' => 'required', ]); if (!$form->hasErrors()) { try { Plugin::install(f('plugin'), false); $session->set('plugins_menu', null); Utils::redirect(ADMIN_URL . 'config/plugins.php'); } catch (UserException $e) { $form->addError($e->getMessage()); } } } if (f('delete')) { $form->check('delete_plugin_' . qg('delete')); if (!$form->hasErrors()) { try { $plugin = new Plugin(qg('delete')); $plugin->uninstall(); $session->set('plugins_menu', null); Utils::redirect(ADMIN_URL . 'config/plugins.php'); } catch (UserException $e) { $form->addError($e->getMessage()); } } |
︙ | ︙ |
Modified src/www/admin/config/site.php from [6929129da8] to [dd99638235].
1 2 3 4 5 | <?php namespace Garradin; require_once __DIR__ . '/_inc.php'; | | < < < | | < | | < > | > | < > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <?php namespace Garradin; require_once __DIR__ . '/_inc.php'; if (f('desactiver_site') && $form->check('config_site')) { $config->set('desactiver_site', true); $config->save(); Utils::redirect(ADMIN_URL . 'config/site.php'); } elseif (f('activer_site') && $form->check('config_site')) { $config->set('desactiver_site', false); $config->save(); Utils::redirect(ADMIN_URL . 'config/site.php'); } if (f('select') && f('reset') && $form->check('squelettes')) { try { foreach (f('select') as $source) { |
︙ | ︙ |
Added src/www/admin/email.php version [0a473d143d].
> > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <?php namespace Garradin; require_once __DIR__ . '/../../include/init.php'; $tpl = Template::getInstance(); if (!empty($_GET['optout'])) { $email = new Email; $email->setRejectedStatus($_GET['optout'], $email::REJET_OPTOUT, 'Demande de désinscription'); $tpl->assign('title', 'Confirmation'); $tpl->assign('error', 'Votre adresse a bien été désinscrite, vous ne recevrez plus de messages de notre part.'); } $tpl->display('error.tpl'); |
Modified src/www/admin/index.php from [dd9c88b1a0] to [5988e390c9].
︙ | ︙ | |||
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | } else { $tpl->assign('cotisation', false); } $tpl->assign('custom_css', ['wiki.css']); $tpl->display('admin/index.tpl'); flush(); // Si pas de cron on réalise les tâches automatisées à ce moment-là // c'est pas idéal mais mieux que rien if (!USE_CRON) { require_once ROOT . '/cron.php'; } | > > | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | } else { $tpl->assign('cotisation', false); } $tpl->assign('custom_css', ['wiki.css']); $tpl->assign('banniere', Plugin::fireSignal('accueil.banniere', ['user' => $user, 'session' => $session])); $tpl->display('admin/index.tpl'); flush(); // Si pas de cron on réalise les tâches automatisées à ce moment-là // c'est pas idéal mais mieux que rien if (!USE_CRON) { require_once ROOT . '/cron.php'; } |
Modified src/www/admin/install.php from [0d0c1e0547] to [29602daaba].
1 2 3 | <?php namespace Garradin; | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < > | 1 2 3 4 5 6 7 8 9 10 11 12 13 | <?php namespace Garradin; const INSTALL_PROCESS = true; require_once __DIR__ . '/../../include/test_required.php'; require_once __DIR__ . '/../../include/init.php'; Install::checkAndCreateDirectories(); if (!file_exists(DB_FILE)) { // Renommage du fichier sqlite à la version 0.5.0 |
︙ | ︙ |
Modified src/www/admin/membres/action.php from [c6d0a5fc14] to [d0b4b091d1].
1 2 3 4 5 6 7 8 9 10 11 12 | <?php namespace Garradin; require_once __DIR__ . '/_inc.php'; $session->requireAccess('membres', Membres::DROIT_ADMIN); if (!f('selected') || !is_array(f('selected')) || !count(f('selected'))) { throw new UserException("Aucun membre sélectionné."); } | > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | | | | | | | < < < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | <?php namespace Garradin; require_once __DIR__ . '/_inc.php'; $session->requireAccess('membres', Membres::DROIT_ADMIN); if (!f('selected') || !is_array(f('selected')) || !count(f('selected'))) { throw new UserException("Aucun membre sélectionné."); } $action = f('action'); $list = f('selected'); if (!$action) { throw new UserException('Aucune action sélectionnée.'); } if ($action == 'ods' || $action == 'csv') { $import = new Membres\Import; if ($action == 'ods') { $import->toODS($list); } else { $import->toCSV($list); } exit; } elseif ($action == 'move' || $action == 'delete') { foreach (f('selected') as &$id) { $id = (int) $id; // On ne permet pas d'action collective sur l'utilisateur courant pour éviter les risques // d'erreur genre "oh je me suis supprimé du coup j'ai plus accès à rien" if ($id == $user->id) { throw new UserException("Il n'est pas possible de se modifier ou supprimer soi-même."); } } } if ($action == 'move' && f('confirm')) { $form->check('membres_action', [ 'selected' => 'required|array', 'id_categorie' => 'required|numeric', ]); |
︙ | ︙ | |||
51 52 53 54 55 56 57 | if (!$form->hasErrors()) { $membres->delete(f('selected')); Utils::redirect(ADMIN_URL . 'membres/'); } } | | | | 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | if (!$form->hasErrors()) { $membres->delete(f('selected')); Utils::redirect(ADMIN_URL . 'membres/'); } } $tpl->assign('selected', $list); $tpl->assign('nb_selected', count($list)); if ($action == 'move') { $cats = new Membres\Categories; $tpl->assign('membres_cats', $cats->listSimple()); } $tpl->assign('action', $action); $tpl->display('admin/membres/action.tpl'); |
Deleted src/www/admin/membres/categories/index.php version [a435abf714].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/www/admin/membres/categories/modifier.php version [624c7118d6].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/www/admin/membres/categories/supprimer.php version [43f9a12d7b].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Modified src/www/admin/membres/cotisations.php from [32cdb67ed5] to [d156e1e5bb].
1 2 3 4 5 | <?php namespace Garradin; require_once __DIR__ . '/_inc.php'; | < < | 1 2 3 4 5 6 7 8 9 10 11 12 | <?php namespace Garradin; require_once __DIR__ . '/_inc.php'; qv(['id' => 'required|numeric']); $id = (int) qg('id'); $membre = $membres->get($id); if (!$membre) |
︙ | ︙ |
Modified src/www/admin/membres/cotisations/index.php from [b198d992d0] to [960a734ef2].
1 2 3 4 5 | <?php namespace Garradin; require_once __DIR__ . '/../_inc.php'; | < < | 1 2 3 4 5 6 7 8 9 10 11 12 | <?php namespace Garradin; require_once __DIR__ . '/../_inc.php'; $cotisations = new Cotisations; if ($session->canAccess('membres', Membres::DROIT_ADMIN)) { $cats = new Compta\Categories; if (f('save')) |
︙ | ︙ |
Modified src/www/admin/membres/cotisations/rappels.php from [3c87990373] to [c3e2281ab7].
1 2 3 4 5 | <?php namespace Garradin; require_once __DIR__ . '/../_inc.php'; | < < > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | <?php namespace Garradin; require_once __DIR__ . '/../_inc.php'; qv(['id' => 'required|numeric']); $id = (int) qg('id'); $membre = $membres->get($id); if (!$membre) { throw new UserException("Ce membre n'existe pas."); } $re = new Rappels_Envoyes; $cm = new Membres\Cotisations; if (f('save')) { $session->requireAccess('membres', Membres::DROIT_ECRITURE); $medias = implode(',', [$re::MEDIA_EMAIL, $re::MEDIA_COURRIER, $re::MEDIA_TELEPHONE, $re::MEDIA_AUTRE]); $form->check('add_rappel_' . $membre->id, [ 'id_cotisation' => 'numeric|required', 'media' => 'numeric|required|in:' . $medias, 'date' => 'required|date_format:Y-m-d' ]); |
︙ | ︙ |
Modified src/www/admin/membres/cotisations/voir.php from [5e91281c68] to [db337019a9].
1 2 3 4 5 | <?php namespace Garradin; require_once __DIR__ . '/../_inc.php'; | < < | 1 2 3 4 5 6 7 8 9 10 11 12 | <?php namespace Garradin; require_once __DIR__ . '/../_inc.php'; qv(['id' => 'required|numeric']); $id = (int) qg('id'); $cotisations = new Cotisations; $m_cotisations = new Membres\Cotisations; |
︙ | ︙ |
Modified src/www/admin/membres/fiche.php from [173904eaef] to [890dac5864].
1 2 3 4 5 | <?php namespace Garradin; require_once __DIR__ . '/_inc.php'; | < < | 1 2 3 4 5 6 7 8 9 10 11 12 | <?php namespace Garradin; require_once __DIR__ . '/_inc.php'; qv(['id' => 'required|numeric']); $id = (int) qg('id'); $membre = $membres->get($id); if (!$membre) |
︙ | ︙ |
Modified src/www/admin/membres/import.php from [414da74c86] to [b710d208b2].
1 2 3 4 5 6 7 8 9 10 11 12 13 | <?php namespace Garradin; require_once __DIR__ . '/_inc.php'; $session->requireAccess('membres', Membres::DROIT_ADMIN); $import = new Membres\Import; $tpl->assign('tab', null !== qg('export') ? 'export' : 'import'); if (qg('export') == 'csv') { | < < < < > > > > > > > > > > > > > > > > > > > > > > > > > | | < | | > | | < < > > > < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | <?php namespace Garradin; require_once __DIR__ . '/_inc.php'; $session->requireAccess('membres', Membres::DROIT_ADMIN); $import = new Membres\Import; $tpl->assign('tab', null !== qg('export') ? 'export' : 'import'); if (qg('export') == 'csv') { $import->toCSV(); exit; } elseif (qg('export') == 'ods') { $import->toODS(); exit; } $champs = $config->get('champs_membres')->getAll(); $champs->date_inscription = (object) ['title' => 'Date inscription', 'type' => 'date']; $csv_file = false; if (f('csv_encoded')) { $form->check('membres_import', [ 'csv_encoded' => 'required|json', 'csv_translate' => 'required|array', 'skip_first_line' => 'boolean', ]); $csv_file = json_decode(f('csv_encoded'), true); if (!$form->hasErrors()) { try { $import->fromArray($csv_file, f('csv_translate'), f('skip_first_line') ? 1 : 0); Utils::redirect(ADMIN_URL . 'membres/import.php?ok'); } catch (UserException $e) { $form->addError($e->getMessage()); } } } elseif (f('import')) { $form->check('membres_import', [ 'upload' => 'file|required', 'type' => 'required|in:csv,garradin', ]); if (!$form->hasErrors()) { try { if (f('type') == 'garradin') { $import->fromGarradinCSV($_FILES['upload']['tmp_name'], $user->id); Utils::redirect(ADMIN_URL . 'membres/import.php?ok'); } elseif (f('type') == 'csv') { $csv_file = $import->getCSVAsArray($_FILES['upload']['tmp_name']); } else { throw new UserException('Import inconnu.'); } } catch (UserException $e) { $form->addError($e->getMessage()); } } } $tpl->assign('ok', null !== qg('ok') ? true : false); $tpl->assign('csv_file', $csv_file); $tpl->assign('csv_first_line', $csv_file ? reset($csv_file) : null); $tpl->assign('garradin_champs', $champs); $tpl->display('admin/membres/import.tpl'); |
Modified src/www/admin/membres/index.php from [e45d2413f7] to [33e9d88bdd].
1 2 3 4 5 | <?php namespace Garradin; require_once __DIR__ . '/_inc.php'; | < < < < < < < < < < < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | <?php namespace Garradin; require_once __DIR__ . '/_inc.php'; $cats = new Membres\Categories; $champs = $config->get('champs_membres'); $membres_cats = $cats->listSimple(); $membres_cats_cachees = $cats->listHidden(); $cat_id = (int) qg('cat') ?: 0; $page = (int) qg('p') ?: 1; if ($cat_id) { if (!$session->canAccess('membres', Membres::DROIT_ECRITURE) && array_key_exists($cat_id, $membres_cats_cachees)) { $cat_id = 0; } } if (!$cat_id) { $cat_id = array_diff(array_keys((array) $membres_cats), array_keys((array) $membres_cats_cachees)); } // Par défaut le champ de tri c'est l'identité $order = $config->get('champ_identite'); $desc = false; if (qg('o')) $order = qg('o'); if (null !== qg('d')) $desc = true; $fields = $champs->getListedFields(); // Vérifier que le champ de tri existe bien dans la table if (!isset($fields->$order)) { // Sinon par défaut c'est le premier champ de la table qui fait le tri $order = $champs->getFirstListed(); } $tpl->assign('order', $order); $tpl->assign('desc', $desc); $tpl->assign('champs', $fields); $tpl->assign('liste', $membres->listByCategory($cat_id, array_keys((array) $fields), $page, $order, $desc)); $tpl->assign('total', $membres->countByCategory($cat_id)); $cat_id = is_array($cat_id) ? 0 : $cat_id; $tpl->assign('pagination_url', Utils::getSelfUrl([ 'p' => '[ID]', 'o' => $order, ($desc ? 'd' : 'a') => '', 'cat' => $cat_id, ])); $tpl->assign('membres_cats', $membres_cats); $tpl->assign('membres_cats_cachees', $membres_cats_cachees); $tpl->assign('current_cat', $cat_id); $tpl->assign('page', $page); $tpl->assign('bypage', Membres::ITEMS_PER_PAGE); $tpl->assign('sent', null !== qg('sent')); $tpl->display('admin/membres/index.tpl'); |
Modified src/www/admin/membres/message_collectif.php from [2bd7d9d11b] to [528d973d74].
1 2 3 4 5 | <?php namespace Garradin; require_once __DIR__ . '/_inc.php'; | | > | | | < > > > > > > > > > > > > > > > > > > > > > > | > < < | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | <?php namespace Garradin; require_once __DIR__ . '/_inc.php'; $cats = new Membres\Categories; $recherche = new Recherche; if (f('send')) { $form->check('send_message_co', [ 'sujet' => 'required|string', 'message' => 'required|string', 'recipients' => 'required|string', ]); if (preg_match('/^(categorie|recherche)_(\d+)$/', f('recipients'), $match)) { if ($match[1] == 'categorie') { $recipients = $membres->listAllByCategory($match[2]); } else { $recipients = $recherche->search($match[2], 'id, email'); } if (!count($recipients) || !isset($recipients[0]->email)) { $form->addError('Aucun membre dans la liste.'); } } else { throw new UserException('Destinataires invalides : ' . f('recipients')); } if (!$form->hasErrors()) { try { $membres->sendMessage($recipients, f('sujet'), f('message'), (bool) f('copie')); Utils::redirect(ADMIN_URL . 'membres/?sent'); } catch (UserException $e) { $form->addError($e->getMessage()); } } } $tpl->assign('categories', $cats->listNotHidden()); $tpl->assign('recherches', $recherche->getList($user->id, 'membres')); $tpl->display('admin/membres/message_collectif.tpl'); |
Modified src/www/admin/membres/recherche.php from [f11a643a77] to [873735cdf8].
1 2 3 4 5 | <?php namespace Garradin; require_once __DIR__ . '/_inc.php'; | < < | < | > > | > > > | | | | > | > | > | > > > > > > > > > > > > > > > > | > > | > | | > > > | | > > > > | > > | > | > > | > > > > > > > > | | < | < > | | | > | | < > > > > > | | < > > | < | | > | > > | > > | | | < > > > > > > > > > > > | | > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | <?php namespace Garradin; require_once __DIR__ . '/_inc.php'; $recherche = new Recherche; $champs = $config->get('champs_membres'); $text_query = trim(qg('qt')); $query = null; $limit = f('limit') ?: 100; $order = f('order'); $desc = (bool) f('desc'); $sql_query = null; $id = f('id') ?: qg('id'); // Recherche simple if ($text_query !== '') { $operator = 'LIKE %?%'; if (is_numeric(trim($text_query))) { $column = 'numero'; $operator = '= ?'; } elseif (strpos($text_query, '@') !== false) { $column = 'email'; } else { $column = $config->get('champ_identite'); } $query = [[ 'operator' => 'AND', 'conditions' => [ [ 'column' => $column, 'operator' => $operator, 'values' => [$text_query], ], ], ]]; $order = $column; } elseif ($id) { $r = $recherche->get($id); if (!$r || $r->type != Recherche::TYPE_JSON) { throw new UserException('Recherche inconnue ou invalide'); } $query = $r->query; $order = $r->order; $desc = $r->desc; $limit = $r->limit; $tpl->assign('recherche', $r); } if (f('q') !== null) { $query = json_decode(f('q'), true); } if ($query) { try { $sql_query = $recherche->buildQuery('membres', $query, $order, $desc, $limit); $result = $recherche->searchSQL('membres', $sql_query); } catch (UserException $e) { $form->addError($e->getMessage()); $query = null; } } if ($query) { if (count($result) == 1 && $text_query !== '') { Utils::redirect(ADMIN_URL . 'membres/fiche.php?id=' . (int)$result[0]->id); } if (f('save') && !$form->hasErrors()) { $query = [ 'query' => $query, 'order' => $order, 'limit' => $limit, 'desc' => $desc, ]; if ($id) { $recherche->edit($id, [ 'type' => Recherche::TYPE_JSON, 'contenu' => $query, ]); } else { $id = $recherche->add('Recherche avancée du ' . date('d/m/Y H:i:s'), $user->id, $recherche::TYPE_JSON, 'membres', $query); } Utils::redirect('/admin/membres/recherches.php?id=' . $id); } $tpl->assign('result_header', $membres->getSearchHeaderFields($result)); } else { $query = [[ 'operator' => 'AND', 'conditions' => [ [ 'column' => $config->get('champ_identite'), 'operator' => '= ?', 'values' => ['Souad Massi'], ], ], ]]; $result = null; } $tpl->assign('id', $id); $tpl->assign('query', $query); $tpl->assign('sql_query', $sql_query); $tpl->assign('result', $result); $tpl->assign('order', $order); $tpl->assign('desc', $desc); $tpl->assign('limit', $limit); $tpl->assign('colonnes', $recherche->getColumns('membres')); $tpl->display('admin/membres/recherche.tpl'); |
Modified src/www/admin/membres/recherche_sql.php from [d0f26422b0] to [b02dad85af].
1 2 3 4 5 | <?php namespace Garradin; require_once __DIR__ . '/_inc.php'; | | > > > > > > > > > > > > > > > > > > > > > > > | | | | | | < | | | > > > > > > > > > | | > > | > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | <?php namespace Garradin; require_once __DIR__ . '/_inc.php'; $recherche = new Recherche; $query = trim(qg('query')); $result = null; $id = (int) qg('id'); if ($id) { $r = $recherche->get($id); if (!$r || $r->type != Recherche::TYPE_SQL) { throw new UserException('Recherche inconnue'); } if (!$session->canAccess('membres', Membres::DROIT_ADMIN) || !$query) { $query = $r->contenu; } $tpl->assign('recherche', $r); } else { $session->requireAccess('membres', Membres::DROIT_ADMIN); } $tpl->assign('schema', $recherche->schema('membres')); $tpl->assign('query', $query); if ($query != '') { try { $result = $recherche->searchSQL('membres', $query); } catch (\Exception $e) { $form->addError($e->getMessage()); } if (!$form->hasErrors() && qg('save')) { if ($id) { $recherche->edit($id, [ 'type' => Recherche::TYPE_SQL, 'contenu' => $query, ]); } else { $id = $recherche->add('Recherche SQL du ' . date('d/m/Y H:i:s'), $user->id, $recherche::TYPE_SQL, 'membres', $query); } Utils::redirect('/admin/membres/recherches.php?id=' . $id); } } $tpl->assign('result', $result); $tpl->assign('id', $id); $tpl->display('admin/membres/recherche_sql.tpl'); |
Added src/www/admin/membres/recherches.php version [7efc82999d].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | <?php namespace Garradin; require_once __DIR__ . '/_inc.php'; $recherche = new Recherche; $mode = null; if (qg('edit') || qg('delete')) { $r = $recherche->get(qg('edit') ?: qg('delete')); if (!$r) { throw new UserException('Recherche non trouvée'); } if ($r->id_membre !== null && $r->id_membre != $user->id) { throw new UserException('Recherche privée appartenant à un autre membre.'); } $tpl->assign('recherche', $r); $mode = qg('edit') ? 'edit' : 'delete'; } if ($mode == 'edit' && f('save') && $form->check('edit_recherche_' . $r->id)) { try { $recherche->edit($r->id, [ 'intitule' => f('intitule'), 'id_membre' => f('prive') ? $user->id : null, ]); Utils::redirect('/admin/membres/recherches.php'); } catch (UserException $e) { $form->addError($e->getMessage()); } } elseif ($mode == 'delete' && f('delete') && $form->check('del_recherche_' . $r->id)) { $recherche->remove($r->id); Utils::redirect('/admin/membres/recherches.php'); } $tpl->assign('mode', $mode); if (!$mode) { $tpl->assign('liste', $recherche->getList($user->id, 'membres')); } $tpl->display('admin/membres/recherches.tpl'); |
Modified src/www/admin/static/admin.css from [903a1b66a2] to [c451b4a60c].
1 2 3 4 | @charset "UTF-8"; @font-face { font-family: 'gicon'; | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | @charset "UTF-8"; @font-face { font-family: 'gicon'; src: url('font/garradin.eot?2018'); src: url('font/garradin.eot?2018#iefix') format('embedded-opentype'), url('font/garradin.woff?2018') format('woff'), url('font/garradin.ttf?2018') format('truetype'), url('font/garradin.svg?2018#garradin') format('svg'); font-weight: normal; font-style: normal; } body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, form, fieldset, input, textarea, p, blockquote, th, td, figure, article, aside, section, header, footer { |
︙ | ︙ | |||
185 186 187 188 189 190 191 | color: #090; } span.alert, b.alert { color: #990; } | | | < | > > > > > > > > | | < < | | > > > > | > > > > > | > > > > | > > > > > > > > | 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 | color: #090; } span.alert, b.alert { color: #990; } p.alert, div.alert, p.error, div.error, p.confirm, div.confirm { border: 1px solid #ccc; padding: .5em; margin-bottom: 1em; border-radius: .3em; padding-left: 3em; position: relative; } p.error, div.error { border-color: #c00; background-color: #fcc; } p.confirm, div.confirm { border-color: #0c0; background-color: #cfc; } p.alert, div.alert { border-color: #cc0; background-color: #ffc; } p.confirm::before, div.confirm::before, p.alert::before, div.alert::before, p.error::before, div.error::before { font-family: "gicon"; left: .5em; top: .2em; position: absolute; font-size: 1.5em; text-shadow: 2px 2px 5px #666; } p.confirm::before, div.confirm::before { content: "☑"; color: green; } p.alert::before, div.alert::before { content: "⚠"; color: yellow; } p.error::before, div.error::before { content: "⚠"; color: red; } p.help { margin: 1em; color: #666; } |
︙ | ︙ | |||
274 275 276 277 278 279 280 281 282 283 284 285 286 287 | input[type=text], textarea, input[type=password], input[type=email], input[type=url], input[type=tel], select { padding: 0.2em 0.4em; font-family: Sans-serif; min-width: 20em; max-width: 100%; } select, input[size] { min-width: 0; } input.time { text-align: center; | > > > > | 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 | input[type=text], textarea, input[type=password], input[type=email], input[type=url], input[type=tel], select { padding: 0.2em 0.4em; font-family: Sans-serif; min-width: 20em; max-width: 100%; } input[type=password], input.clearTextPassword { font-family: monospace; } select, input[size] { min-width: 0; } input.time { text-align: center; |
︙ | ︙ | |||
300 301 302 303 304 305 306 307 308 309 310 311 312 313 | transition: opacity .5s ease; } input.resetButton { padding: .1em; margin-left: 1em; } .loader { width: 100%; min-height: 32px; display: block; position: relative; } | > > > > > > > > > > | 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 | transition: opacity .5s ease; } input.resetButton { padding: .1em; margin-left: 1em; } input[type=button].showPassword { margin-left: -2em; margin-right: 1em; background: none; } input[type=button].showPassword:hover { background: none; } .loader { width: 100%; min-height: 32px; display: block; position: relative; } |
︙ | ︙ | |||
405 406 407 408 409 410 411 | float: right; } ul.actions { list-style-type: none; margin: 1em 0; border-bottom: .1em solid #9c4f15; | | > > > > > > > > > | | 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 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 | float: right; } ul.actions { list-style-type: none; margin: 1em 0; border-bottom: .1em solid #9c4f15; border-bottom-color: rgb(var(--gMainColor)); padding: 0 1em; z-index: 100; } ul.actions.sub { margin: -1em 2em 1em 0; padding-top: 1em; border-right: .1em solid #9c4f15; border-right-color: rgb(var(--gMainColor)); border-bottom-right-radius: .5em; } ul.actions li { display: inline-block; margin: 0 0.2em; } ul.actions li a, ul.actions li label { display: inline-block; background: rgb(217, 134, 40); background: rgba(217, 134, 40, .5); background: rgba(var(--gSecondColor), .5); border-radius: .5em .5em 0 0; padding: .1em .5em; color: #000; text-decoration: none; transition: background-color .2s, color .2s; } ul.actions li input { display: none; } ul.actions li.current a, ul.actions li input:checked + label { background: #9c4f15; background: rgb(var(--gMainColor)); color: #fff; color: rgb(var(--gBgColor)); } ul.actions li a:hover, ul.actions li label:hover { color: #fff; background-color: rgb(var(--gMainColor)); text-decoration: underline; border-bottom: none; } h3.warning { margin: 1em; color: red; |
︙ | ︙ | |||
564 565 566 567 568 569 570 571 572 573 574 575 576 577 | } table.search th { background: rgb(217, 134, 40); background: rgba(217, 134, 40, 0.5); background: rgba(var(--gSecondColor), 0.5); } .userOrder .cur { background: rgb(217, 134, 40); background: rgba(var(--gSecondColor), 1.0); color: #fff; color: rgb(var(--gBgColor)); } | > > > > > > > > > > > > > > > > > > > > > > > > > > | 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 | } table.search th { background: rgb(217, 134, 40); background: rgba(217, 134, 40, 0.5); background: rgba(var(--gSecondColor), 0.5); } table.list .disabled { background: #eee; color: #999; } #queryBuilder .column select, #queryBuilderForm .actions select { max-width: 15em; } #queryBuilder table td { vertical-align: top; padding: .1em .2em; } #queryBuilder input[type=button], #queryBuilder .values input { margin: .1em; } #queryBuilderForm .actions label { margin: 0 .5em; } #queryBuilderForm input[type=number] { width: 4em; } .userOrder .cur { background: rgb(217, 134, 40); background: rgba(var(--gSecondColor), 1.0); color: #fff; color: rgb(var(--gBgColor)); } |
︙ | ︙ | |||
676 677 678 679 680 681 682 683 684 685 686 687 688 689 | padding-bottom: .5em; border-bottom: 1pt solid #999; } #rapport h1 { text-align: center; } .icn, .icnl { font-family: "gicon", sans-serif; font-style: normal; font-weight: normal; speak: none; font-variant: normal; | > > > > > > > > > > > > > > > > > > > > > > > > > > > | 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 | padding-bottom: .5em; border-bottom: 1pt solid #999; } #rapport h1 { text-align: center; } h2.ruler { margin: .5em; text-align: center; color: #333; overflow: hidden; } h2.ruler:before, h2.ruler:after { background-color: #000; content: ""; display: inline-block; height: 1px; position: relative; vertical-align: middle; width: 50%; } h2.ruler:before { right: 0.5em; margin-left: -50%; } h2.ruler:after { left: 0.5em; margin-right: -50%; } .icn, .icnl { font-family: "gicon", sans-serif; font-style: normal; font-weight: normal; speak: none; font-variant: normal; |
︙ | ︙ |
Modified src/www/admin/static/font/garradin.css from [2361fa015f] to [d980f71e5b].
1 2 3 4 | @charset "UTF-8"; @font-face { font-family: 'garradin'; | | | > | | | | | > > > > > | > > | > > > | > > > | | | | | | > > < > | > > | > | | | | > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | @charset "UTF-8"; @font-face { font-family: 'garradin'; src: url('../font/garradin.eot?31180986'); src: url('../font/garradin.eot?31180986#iefix') format('embedded-opentype'), url('../font/garradin.woff2?31180986') format('woff2'), url('../font/garradin.woff?31180986') format('woff'), url('../font/garradin.ttf?31180986') format('truetype'), url('../font/garradin.svg?31180986#garradin') format('svg'); font-weight: normal; font-style: normal; } /* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */ /* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */ /* @media screen and (-webkit-min-device-pixel-ratio:0) { @font-face { font-family: 'garradin'; src: url('../font/garradin.svg?31180986#garradin') format('svg'); } } */ [class^="icn-"]:before, [class*=" icn-"]:before { font-family: "garradin"; font-style: normal; font-weight: normal; speak: none; display: inline-block; text-decoration: inherit; width: 1em; margin-right: .2em; text-align: center; /* opacity: .8; */ /* For safety - reset parent styles, that can break glyph codes*/ font-variant: normal; text-transform: none; /* fix buttons height, for twitter bootstrap */ line-height: 1em; /* Animation center compensation - margins should be symmetric */ /* remove if not needed */ margin-left: .2em; /* you can be more comfortable with increased icons size */ /* font-size: 120%; */ /* Font smoothing. That was taken from TWBS */ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; /* Uncomment for 3D effect */ /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */ } .icn-up:before { content: '\2191'; } /* '↑' */ .icn-down:before { content: '\2193'; } /* '↓' */ .icn-download:before { content: '\21d3'; } /* '⇓' */ .icn-home:before { content: '\2302'; } /* '⌂' */ .icn-print:before { content: '\2399'; } /* '⎙' */ .icn-check:before { content: '\2611'; } /* '☑' */ .icn-settings:before { content: '\2638'; } /* '☸' */ .icn-alert:before { content: '\26a0'; } /* '⚠' */ .icn-mail:before { content: '\2709'; } /* '✉' */ .icn-edit:before { content: '\270e'; } /* '✎' */ .icn-delete:before { content: '\2718'; } /* '✘' */ .icn-help:before { content: '\2753'; } /* '❓' */ .icn-plus:before { content: '\2795'; } /* '➕' */ .icn-minus:before { content: '\2796'; } /* '➖' */ .icn-logout:before { content: '\291d'; } /* '⤝' */ .icn-eye-off:before { content: '\292b'; } /* '⤫' */ .icn-menu:before { content: '𝍢'; } /* '\1d362' */ .icn-eye:before { content: '👁'; } /* '\1f441' */ .icn-user:before { content: '👤'; } /* '\1f464' */ .icn-users:before { content: '👪'; } /* '\1f46a' */ .icn-attach:before { content: '📎'; } /* '\1f4ce' */ .icn-search:before { content: '🔍'; } /* '\1f50d' */ .icn-lock:before { content: '🔒'; } /* '\1f512' */ .icn-unlock:before { content: '🔓'; } /* '\1f513' */ |
Modified src/www/admin/static/font/garradin.eot from [7ef839bdc8] to [4de801b16e].
cannot compute difference between binary files
Modified src/www/admin/static/font/garradin.svg from [49157899c4] to [5bcfb6f494].
1 2 3 | <?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg"> | | > | > > > > > > > > | | > | > > > > > > | | < | | > | > | > | > | > | > | > | > | > | > | > | < | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | <?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns="http://www.w3.org/2000/svg"> <metadata>Copyright (C) 2018 by original authors @ fontello.com</metadata> <defs> <font id="garradin" horiz-adv-x="1000" > <font-face font-family="garradin" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" /> <missing-glyph horiz-adv-x="1000" /> <glyph glyph-name="up" unicode="↑" d="M571 171q0-14-10-25t-25-10h-500q-15 0-25 10t-11 25 11 26l250 250q10 10 25 10t25-10l250-250q10-11 10-26z" horiz-adv-x="571.4" /> <glyph glyph-name="down" unicode="↓" d="M571 457q0-14-10-25l-250-250q-11-11-25-11t-25 11l-250 250q-11 11-11 25t11 25 25 11h500q14 0 25-11t10-25z" horiz-adv-x="571.4" /> <glyph glyph-name="download" unicode="⇓" d="M714 100q0 15-10 25t-25 11-26-11-10-25 10-25 26-11 25 11 10 25z m143 0q0 15-10 25t-26 11-25-11-10-25 10-25 25-11 26 11 10 25z m72 125v-179q0-22-16-37t-38-16h-821q-23 0-38 16t-16 37v179q0 22 16 38t38 16h259l75-76q33-32 76-32t76 32l76 76h259q22 0 38-16t16-38z m-182 318q10-23-8-40l-250-250q-10-10-25-10t-25 10l-250 250q-17 17-8 40 10 21 33 21h143v250q0 15 11 25t25 11h143q14 0 25-11t10-25v-250h143q24 0 33-21z" horiz-adv-x="928.6" /> <glyph glyph-name="home" unicode="⌂" d="M786 296v-267q0-15-11-26t-25-10h-214v214h-143v-214h-214q-15 0-25 10t-11 26v267q0 1 0 2t0 2l321 264 321-264q1-1 1-4z m124 39l-34-41q-5-5-12-6h-2q-7 0-12 3l-386 322-386-322q-7-4-13-4-7 2-12 7l-35 41q-4 5-3 13t6 12l401 334q18 15 42 15t43-15l136-114v109q0 8 5 13t13 5h107q8 0 13-5t5-13v-227l122-102q5-5 6-12t-4-13z" horiz-adv-x="928.6" /> <glyph glyph-name="print" unicode="⎙" d="M214-7h500v143h-500v-143z m0 357h500v214h-89q-22 0-38 16t-16 38v89h-357v-357z m643-36q0 15-10 25t-26 11-25-11-10-25 10-25 25-10 26 10 10 25z m72 0v-232q0-7-6-12t-12-6h-125v-89q0-22-16-38t-38-16h-536q-22 0-37 16t-16 38v89h-125q-7 0-13 6t-5 12v232q0 44 32 76t75 31h36v304q0 22 16 38t37 16h375q23 0 50-12t42-26l85-85q15-16 27-43t11-49v-143h35q45 0 76-31t32-76z" horiz-adv-x="928.6" /> <glyph glyph-name="check" unicode="☑" d="M786 331v-177q0-67-47-114t-114-47h-464q-67 0-114 47t-47 114v464q0 66 47 113t114 48h464q35 0 65-14 9-4 10-13 2-10-5-16l-27-28q-6-5-13-5-2 0-5 1-13 3-25 3h-464q-37 0-63-26t-27-63v-464q0-37 27-63t63-27h464q37 0 63 27t26 63v141q0 8 5 13l36 35q6 6 13 6 3 0 7-2 11-4 11-16z m129 273l-455-454q-13-14-31-14t-32 14l-240 240q-14 13-14 31t14 32l61 62q14 13 32 13t32-13l147-147 361 361q13 13 31 13t32-13l62-61q13-14 13-32t-13-32z" horiz-adv-x="928.6" /> <glyph glyph-name="settings" unicode="☸" d="M571 350q0 59-41 101t-101 42-101-42-42-101 42-101 101-42 101 42 41 101z m286 61v-124q0-7-4-13t-11-7l-104-16q-10-30-21-51 19-27 59-77 6-6 6-13t-5-13q-15-21-55-61t-53-39q-7 0-14 5l-77 60q-25-13-51-21-9-76-16-104-4-16-20-16h-124q-8 0-14 5t-6 12l-16 103q-27 9-50 21l-79-60q-6-5-14-5-8 0-14 6-70 64-92 94-4 5-4 13 0 6 5 12 8 12 28 37t30 40q-15 28-23 55l-102 15q-7 1-11 7t-5 13v124q0 7 5 13t10 7l104 16q8 25 22 51-23 32-60 77-6 7-6 14 0 5 5 12 15 20 55 60t53 40q7 0 15-5l77-60q24 13 50 21 9 76 17 104 3 15 20 15h124q7 0 13-4t7-12l15-103q28-9 50-21l80 60q5 5 13 5 7 0 14-5 72-67 92-95 4-5 4-13 0-6-4-12-9-12-29-38t-30-39q14-28 23-55l102-15q7-1 12-7t4-13z" horiz-adv-x="857.1" /> <glyph glyph-name="alert" unicode="⚠" d="M571 83v106q0 8-5 13t-12 5h-108q-7 0-12-5t-5-13v-106q0-8 5-13t12-6h108q7 0 12 6t5 13z m-1 208l10 257q0 6-5 10-7 6-14 6h-122q-7 0-14-6-5-4-5-12l9-255q0-5 6-9t13-3h103q8 0 13 3t6 9z m-7 522l428-786q20-35-1-70-10-17-26-26t-35-10h-858q-18 0-35 10t-26 26q-21 35-1 70l429 786q9 17 26 27t36 10 36-10 27-27z" horiz-adv-x="1000" /> <glyph glyph-name="mail" unicode="✉" d="M1000 454v-443q0-37-26-63t-63-27h-822q-36 0-63 27t-26 63v443q25-28 56-49 202-137 278-192 32-24 51-37t53-27 61-13h2q28 0 61 13t53 27 51 37q95 68 278 192 32 22 56 49z m0 164q0-44-27-84t-68-69q-210-146-262-181-5-4-23-17t-30-22-29-18-33-15-27-5h-2q-12 0-27 5t-33 15-29 18-30 22-23 17q-51 35-147 101t-114 80q-35 23-65 64t-31 77q0 43 23 72t66 29h822q36 0 62-26t27-63z" horiz-adv-x="1000" /> <glyph glyph-name="edit" unicode="✎" d="M203-7l50 51-131 131-51-51v-60h72v-71h60z m291 518q0 12-12 12-5 0-9-4l-303-302q-4-4-4-10 0-12 13-12 5 0 9 4l303 302q3 4 3 10z m-30 107l232-232-464-465h-232v233z m381-54q0-29-20-50l-93-93-232 233 93 92q20 21 50 21 29 0 51-21l131-131q20-22 20-51z" horiz-adv-x="857.1" /> <glyph glyph-name="delete" unicode="✘" d="M724 112q0-22-15-38l-76-76q-16-15-38-15t-38 15l-164 165-164-165q-16-15-38-15t-38 15l-76 76q-16 16-16 38t16 38l164 164-164 164q-16 16-16 38t16 38l76 76q16 16 38 16t38-16l164-164 164 164q16 16 38 16t38-16l76-76q15-15 15-38t-15-38l-164-164 164-164q15-15 15-38z" horiz-adv-x="785.7" /> <glyph glyph-name="help" unicode="❓" d="M393 149v-134q0-9-7-16t-15-6h-134q-9 0-16 6t-7 16v134q0 9 7 16t16 6h134q8 0 15-6t7-16z m176 335q0-30-8-56t-20-43-31-33-32-25-34-19q-23-13-38-37t-15-37q0-10-7-18t-16-9h-134q-8 0-14 10t-6 21v26q0 46 37 87t79 60q33 15 47 32t14 42q0 23-26 41t-60 18q-36 0-60-16-20-14-60-64-7-9-17-9-7 0-14 4l-91 70q-8 6-9 14t3 16q89 148 259 148 45 0 90-17t81-46 59-72 23-88z" horiz-adv-x="571.4" /> <glyph glyph-name="plus" unicode="➕" d="M786 439v-107q0-22-16-38t-38-15h-232v-233q0-22-16-37t-38-16h-107q-22 0-38 16t-15 37v233h-232q-23 0-38 15t-16 38v107q0 23 16 38t38 16h232v232q0 22 15 38t38 16h107q23 0 38-16t16-38v-232h232q22 0 38-16t16-38z" horiz-adv-x="785.7" /> <glyph glyph-name="minus" unicode="➖" d="M786 439v-107q0-22-16-38t-38-15h-678q-23 0-38 15t-16 38v107q0 23 16 38t38 16h678q22 0 38-16t16-38z" horiz-adv-x="785.7" /> <glyph glyph-name="logout" unicode="⤝" d="M857 350q0-87-34-166t-91-137-137-92-166-34-167 34-136 92-92 137-34 166q0 102 45 191t126 151q24 18 54 14t46-28q18-23 14-53t-28-47q-54-41-84-101t-30-127q0-58 22-111t62-91 91-61 111-23 110 23 92 61 61 91 22 111q0 68-30 127t-84 101q-24 18-28 47t14 53q17 24 47 28t53-14q81-61 126-151t45-191z m-357 429v-358q0-29-21-50t-50-21-51 21-21 50v358q0 29 21 50t51 21 50-21 21-50z" horiz-adv-x="857.1" /> <glyph glyph-name="eye-off" unicode="⤫" d="M0 326q6 49 64 110 79 80 176 128 129 61 260 61 29 0 59-2l74 129q10 16 23 18 4 0 8-2l51-32q17-7 2-33l-57-101-47-79-41-72-144-250-41-72-47-80-57-100q-15-25-31-15l-53 31q-15 8 0 33l49 86-8 4q-103 53-176 129-64 72-64 109z m264 0q0-74 47-133l48 84q-9 24-9 49 0 51 34 91t85 50l49 84-18 0q-98 0-167-66t-69-159z m177-295l41 71 18 0q98 0 167 65t69 159q0 74-47 133l63 109q2-2 4-3t4-1q103-52 176-128 64-73 64-110-6-49-64-109-79-80-176-129-129-61-260-61-25 0-59 4z m90 155l110 189q9-25 9-49 0-51-34-90t-85-50z" horiz-adv-x="1000" /> <glyph glyph-name="menu" unicode="𝍢" d="M857 100v-71q0-15-10-25t-26-11h-785q-15 0-25 11t-11 25v71q0 15 11 25t25 11h785q15 0 26-11t10-25z m0 286v-72q0-14-10-25t-26-10h-785q-15 0-25 10t-11 25v72q0 14 11 25t25 10h785q15 0 26-10t10-25z m0 285v-71q0-15-10-25t-26-11h-785q-15 0-25 11t-11 25v71q0 15 11 26t25 10h785q15 0 26-10t10-26z" horiz-adv-x="857.1" /> <glyph glyph-name="eye" unicode="👁" d="M0 350q6 49 64 110 79 80 176 129 129 60 260 60 137-2 260-60 103-53 176-129 64-73 64-110-6-49-64-109-79-80-176-129-129-61-260-61-137 2-260 61-103 53-176 129-64 72-64 109z m264 0q0-94 69-159t167-65 167 65 69 159-69 159-167 66-167-66-69-159z m86 1q0 60 44 102t106 42 106-42 44-102-44-102-106-43-106 43-44 102z" horiz-adv-x="1000" /> <glyph glyph-name="user" unicode="👤" d="M786 66q0-67-41-106t-108-39h-488q-67 0-108 39t-41 106q0 30 2 58t8 61 15 60 24 55 34 45 48 30 62 11q5 0 24-12t41-27 60-27 75-12 74 12 61 27 41 27 24 12q34 0 62-11t48-30 34-45 24-55 15-60 8-61 2-58z m-179 498q0-88-63-151t-151-63-152 63-62 151 62 152 152 63 151-63 63-152z" horiz-adv-x="785.7" /> <glyph glyph-name="users" unicode="👪" d="M331 350q-90-3-148-71h-75q-45 0-77 22t-31 66q0 197 69 197 4 0 25-11t54-24 66-12q38 0 75 13-3-21-3-37 0-78 45-143z m598-356q0-66-41-105t-108-39h-488q-68 0-108 39t-41 105q0 30 2 58t8 61 14 61 24 54 35 45 48 30 62 11q6 0 24-12t41-26 59-27 76-12 75 12 60 27 41 26 23 12q35 0 63-11t47-30 35-45 24-54 15-61 8-61 2-58z m-572 713q0-59-42-101t-101-42-101 42-42 101 42 101 101 42 101-42 42-101z m393-214q0-89-63-152t-151-62-152 62-63 152 63 151 152 63 151-63 63-151z m321-126q0-43-31-66t-77-22h-75q-57 68-147 71 45 65 45 143 0 16-3 37 37-13 74-13 33 0 67 12t54 24 24 11q69 0 69-197z m-71 340q0-59-42-101t-101-42-101 42-42 101 42 101 101 42 101-42 42-101z" horiz-adv-x="1071.4" /> <glyph glyph-name="attach" unicode="📎" d="M783 77q0-65-44-109t-109-44q-75 0-131 55l-434 434q-63 64-63 151 0 88 62 150t150 62q88 0 152-63l338-338q5-5 5-12 0-9-17-26t-26-17q-7 0-13 5l-338 339q-44 43-101 43-59 0-100-42t-40-101q0-58 42-101l433-433q35-35 81-35 36 0 59 23t24 59q0 46-36 81l-324 324q-14 14-33 14-16 0-27-11t-11-27q0-18 14-33l229-228q6-6 6-13 0-9-18-26t-26-17q-7 0-12 5l-229 229q-35 34-35 83 0 46 32 78t77 32q49 0 83-36l325-324q55-54 55-131z" horiz-adv-x="785.7" /> <glyph glyph-name="search" unicode="🔍" d="M643 386q0 103-74 176t-176 74-177-74-73-176 73-177 177-73 176 73 74 177z m286-465q0-29-22-50t-50-21q-30 0-50 21l-191 191q-100-69-223-69-80 0-153 31t-125 84-84 125-31 153 31 152 84 126 125 84 153 31 152-31 126-84 84-126 31-152q0-123-69-223l191-191q21-21 21-51z" horiz-adv-x="928.6" /> <glyph glyph-name="lock" unicode="🔒" d="M179 421h285v108q0 59-42 101t-101 41-101-41-41-101v-108z m464-53v-322q0-22-16-37t-38-16h-535q-23 0-38 16t-16 37v322q0 22 16 38t38 15h17v108q0 102 74 176t176 74 177-74 73-176v-108h18q23 0 38-15t16-38z" horiz-adv-x="642.9" /> <glyph glyph-name="unlock" unicode="🔓" d="M929 529v-143q0-15-11-25t-25-11h-36q-14 0-25 11t-11 25v143q0 59-41 101t-101 41-101-41-42-101v-108h53q23 0 38-15t16-38v-322q0-22-16-37t-38-16h-535q-23 0-38 16t-16 37v322q0 22 16 38t38 15h375v108q0 103 73 176t177 74 176-74 74-176z" horiz-adv-x="928.6" /> </font> </defs> </svg> |
Modified src/www/admin/static/font/garradin.ttf from [4452fdd794] to [2aa8a2bf32].
cannot compute difference between binary files
Modified src/www/admin/static/font/garradin.woff from [c939b61e60] to [ccddd0b63a].
cannot compute difference between binary files
Modified src/www/admin/static/scripts/global.js from [bab9903c66] to [7039561d92].
︙ | ︙ | |||
85 86 87 88 89 90 91 | }; // From KD2fw/js/xhr.js g.load = function(b,d,f,e){var a=new XMLHttpRequest();if(!a||!b)return false;if(a.overrideMimeType)a.overrideMimeType('text/xml');b+=(b.indexOf('?')+1?'&':'?')+(+(new Date));a.onreadystatechange=function(){if(a.readyState!=4)return;if((s=a.status)==200){if(!d)return true;var c=a.responseText;if(f=='json'){return((j=window.JSON)&&j.parse)?j.parse(c):eval('('+c.replace(/[\n\r]/g,'')+')')}d(c)}else if(e){e(s)}};a.open('GET',b,true);a.send(null)}; g.checkUncheck = function() { | | > | < < < | | > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | }; // From KD2fw/js/xhr.js g.load = function(b,d,f,e){var a=new XMLHttpRequest();if(!a||!b)return false;if(a.overrideMimeType)a.overrideMimeType('text/xml');b+=(b.indexOf('?')+1?'&':'?')+(+(new Date));a.onreadystatechange=function(){if(a.readyState!=4)return;if((s=a.status)==200){if(!d)return true;var c=a.responseText;if(f=='json'){return((j=window.JSON)&&j.parse)?j.parse(c):eval('('+c.replace(/[\n\r]/g,'')+')')}d(c)}else if(e){e(s)}};a.open('GET',b,true);a.send(null)}; g.checkUncheck = function() { var elements = this.form.querySelectorAll('input[type=checkbox]'); var el_length = elements.length; var checked = this.checked; for (var i = 0; i < el_length; i++) { var elm = elements[i]; elm.checked = checked; if (elm.onchange && elm.name) { elm.onchange({target: elm}); } } return true; }; g.enhancePasswordField = function (field, repeat_field = null) { var show_password = document.createElement('input'); show_password.type = 'button'; show_password.className = 'icn action showPassword'; show_password.title = 'Voir/cacher le mot de passe'; show_password.value = '👁'; show_password.onclick = function (e) { var pos = field.selectionStart; var hidden = field.type.match(/pass/i); field.type = hidden ? 'text' : 'password'; this.value = !hidden ? '👁' : '⤫'; field.classList.toggle('clearTextPassword'); if (null !== repeat_field) { repeat_field.type = field.type; repeat_field.classList.toggle('clearTextPassword'); } // Remettre le focus sur le champ mot de passe // on ne peut pas vraiment remettre le focus sur le champ // précis qui était utilisé avant de cliquer sur le bouton // car il faudrait enregistrer les actions onfocus de tous // les champs de la page field.focus(); field.selectionStart = field.selectionEnd = pos; }; field.parentNode.insertBefore(show_password, field.nextSibling); }; var dateInputFallback = function () { /* // Firefox dit implémenter date, mais ne l'implémente pas, aucun moyen de détecter ce cas // donc on force l'utilisation du custom datepicker de Garradin… var input = document.createElement('input'); |
︙ | ︙ | |||
137 138 139 140 141 142 143 | { document.body.removeChild(input); }*/ }; g.onload(dateInputFallback); | | > > > | > > > > > > > > > > > > > > > | | | | | | | | | | | | | | | | | > | | | | | | | | | | | | | | | | | | < < | 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 | { document.body.removeChild(input); }*/ }; g.onload(dateInputFallback); if (!document.querySelectorAll) { return; } g.onload(function () { var tableActions = document.querySelectorAll('form table tfoot .actions select'); for (var i = 0; i < tableActions.length; i++) { tableActions[i].onchange = function () { if (!this.form.querySelector('table tbody input[type=checkbox]:checked')) { return !window.alert("Aucune ligne sélectionnée !"); } this.form.submit(); }; } // Ajouter action check/uncheck sur les checkbox de raccourci dans les tableaux var checkTables = document.querySelectorAll('table thead input[type=checkbox], table tfoot input[type=checkbox]'); var l = checkTables.length; for (var i = 0; i < l; i++) { var masterCheck = checkTables[i]; masterCheck.onchange = g.checkUncheck; var parent = masterCheck.parentNode; while (parent.nodeType != Node.ELEMENT_NODE || parent.tagName != 'TABLE') { parent = parent.parentNode; } var checkBoxes = parent.querySelectorAll('tbody tr input[type=checkbox]'); var ll = checkBoxes.length; for (var j = 0; j < ll; j++) { checkBoxes[j].onchange = function (e) { var elm = e.target || this; var checked = elm.checked ? true : false; var parent = elm.parentNode; while (parent.nodeType != Node.ELEMENT_NODE || parent.tagName != 'TR') { parent = parent.parentNode; } if (checked) parent.className = parent.className.replace(/ checked$|$/, ' checked'); else parent.className = parent.className.replace(/ checked/, ''); }; if (checkBoxes[j].checked) { checkBoxes[j].onchange({target: checkBoxes[j]}); } } } }); })(); |
Modified src/www/admin/static/scripts/password.js from [14f90c76a4] to [c16716738c].
1 2 3 4 5 6 7 8 9 | (function () { var strength_elm, match_elm, pw_elm, pw2_elm, suggest_elm; RegExp.quote = function(str) { return (str+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1"); }; window.initPasswordField = function(suggest, password, password2) { | < > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | (function () { var strength_elm, match_elm, pw_elm, pw2_elm, suggest_elm; RegExp.quote = function(str) { return (str+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1"); }; window.initPasswordField = function(suggest, password, password2) { pw_elm = (typeof password == 'string') ? document.getElementById(password) : password; pw2_elm = (typeof password2 == 'string') ? document.getElementById(password2) : password2; suggest_elm = (typeof suggest == 'string') ? document.getElementById(suggest) : suggest; g.enhancePasswordField(pw_elm, pw2_elm); suggest_elm.size = suggest_elm.value.length; suggest_elm.onclick = function () { pw_elm.value = this.value; pw2_elm.value = this.value; this.select(); |
︙ | ︙ |
Added src/www/admin/static/scripts/query_builder.min.js version [6daac3a8d1].
> | 1 | !function(){var e=function(e){this.columns=e};(window.SQLQueryBuilder=e).prototype.loadDefaultOperators=function(){for(var e in this.operators={"= ?":this.__("is equal to"),"!= ?":this.__("is not equal to"),"IN (??)":this.__("is equal to one of"),"NOT IN (??)":this.__("is not equal to one of"),"> ?":this.__("is greater than"),">= ?":this.__("is greater than or equal to"),"< ?":this.__("is less than"),"<= ?":this.__("is less than or equal to"),"BETWEEN ? AND ?":this.__("is between"),"NOT BETWEEN ? AND ?":this.__("is not between"),"IS NULL":this.__("is null"),"IS NOT NULL":this.__("is not null"),"LIKE ?%":this.__("begins with"),"NOT LIKE ?%":this.__("doesn't begin with"),"LIKE %?":this.__("ends with"),"NOT LIKE %?":this.__("doesn't end with"),"LIKE %?%":this.__("contains"),"NOT LIKE %?%":this.__("doesn't contain"),"&":this.__("matches one of"),"= 1":this.__("is true"),"= 0":this.__("is false")},this.types_operators={integer:["= ?","!= ?","IN (??)","NOT IN (??)","> ?",">= ?","< ?","<= ?","BETWEEN ? AND ?","NOT BETWEEN ? AND ?"],enum:["= ?","!= ?","IN (??)","NOT IN (??)"],boolean:["= 1","= 0"],text:["= ?","!= ?","IN (??)","NOT IN (??)","LIKE ?%","NOT LIKE ?%","LIKE %?","NOT LIKE %?","LIKE %?%","NOT LIKE %?%"],bitwise:["&"]},this.types_operators){var t={};for(var i in this.types_operators[e]){var o=this.types_operators[e][i];t[o]=this.operators[o]}this.types_operators[e]=t}this.types_operators.date=JSON.parse(JSON.stringify(this.types_operators.integer)),delete this.types_operators.date["<= ?"],delete this.types_operators.date[">= ?"],this.types_operators.date["< ?"]=this.__("before"),this.types_operators.date["> ?"]=this.__("after"),this.types_operators.datetime=this.types_operators.date},e.prototype.__=function(e){return e},e.prototype.init=function(e){this.parent=e;var t={"":"---"};for(column in this.columns)t[column]=this.columns[column].label;this.columnSelect=this.buildSelect(t)},e.prototype.addGroup=function(t,e){var i=document.createElement("fieldset"),o=document.createElement("legend"),n=this.buildSelect({AND:this.__("Matches ALL of the following conditions:"),OR:this.__("Matches ANY of the following conditions:"),ADD:this.__("Add a new set of conditions below this one"),DEL:this.__("Remove this set of conditions")});n.onfocus=function(){this.oldValue=this.value},n.value=e;var r=this;n.onchange=function(){if("DEL"==this.value){if(1==t.childNodes.length)return void(this.value=this.oldValue);t.removeChild(i)}else if("ADD"==this.value){var e=r.addGroup(t,"AND");r.addRow(e),this.value=this.oldValue}},o.appendChild(n),i.appendChild(o);var s=document.createElement("table");return i.appendChild(s),t.appendChild(i),i},e.prototype.addRow=function(e,t){var i=e.getElementsByTagName("table")[0],o=document.createElement("tr");(s=document.createElement("td")).className="buttons";var n,r=this;(n=this.buildInput("button","+")).onclick=function(){r.addRow(function(e,t){for(;(e=e.parentElement)&&!(e.matches||e.matchesSelector).call(e,t););return e}(this,"fieldset"),this.parentNode.parentNode)},s.appendChild(n),(n=this.buildInput("button","-")).onclick=function(){r.deleteRow(this.parentNode.parentNode)},s.appendChild(n),o.appendChild(s),(s=document.createElement("td")).className="column";var s,a=this.columnSelect.cloneNode(!0);return a.onchange=function(){return r.switchColumn(this)},s.appendChild(a),o.appendChild(s),(s=document.createElement("td")).className="operator",o.appendChild(s),(s=document.createElement("td")).className="values",o.appendChild(s),void 0===t?i.appendChild(o):i.insertBefore(o,t.nextSibling),o},e.prototype.deleteRow=function(e){e.parentNode.childNodes.length<=1||e.parentNode.removeChild(e)},e.prototype.switchColumn=function(e){var t=e.parentNode.parentNode;t.childNodes[2].innerHTML="",t.childNodes[3].innerHTML="",this.addOperator(t,this.columns[e.value])},e.prototype.addOperator=function(e,t){var i=this.types_operators[t.type],o={"":"---"};for(var n in t.null&&(i["IS NULL"]=this.operators["IS NULL"],i["IS NOT NULL"]=this.operators["IS NOT NULL"]),i)o[n]=i[n];var r=this.buildSelect(o),s=this;return r.onchange=function(){return s.switchOperator(this)},e.childNodes[2].appendChild(r),r},e.prototype.switchOperator=function(e,t){var i=e.parentNode.parentNode;i.childNodes[3].innerHTML="";var o=i.childNodes[3],n=i.childNodes[1].firstChild,r=e.value,s=this.columns[n.value];if(r){var a=1,l=!1,d=null,h=r.match(/\?/g);if(h){r.match(/\?\?/)?(a=t?t.length:3,l=!0):1<h.length&&(a=h.length);for(var p=0;p<a;p++)d=this.addMatchField(o,d,s,r),t&&(d.value=t[p]);if(l){(u=this.buildInput("button","-")).onclick=function(){this.parentNode.childNodes.length<=3||(this.parentNode.removeChild(this.previousSibling),this.parentNode.removeChild(this.previousSibling))},o.appendChild(u);var u=this.buildInput("button","+"),c=this;u.onclick=function(){c.addMatchField(o,this.previousSibling.previousSibling,s,r)},o.appendChild(u)}}}},e.prototype.addMatchField=function(e,t,i,o){if("enum"==i.type)var n=this.buildSelect(i.values);else if("bitwise"==i.type){n=document.createElement("span");for(var r in i.values){var s=this.buildInput("checkbox",r),a=document.createElement("label");a.appendChild(s),a.appendChild(document.createTextNode(" "+i.values[r])),n.appendChild(a.cloneNode(!0))}}else n=this.buildInput(i.type,"",i);return n=e.insertBefore(n,t?t.nextSibling:null),t&&e.insertBefore(document.createElement("br"),n),n},e.prototype.buildInput=function(e,t,i){var o=document.createElement("input");return o.type="integer"==e?"number":e,o.value=t,o},e.prototype.buildSelect=function(e){var t=document.createElement("select");for(var i in e){var o=document.createElement("option");o.value=i,o.innerHTML=e[i],t.appendChild(o)}return t},e.prototype.import=function(e){for(var t in e)if(0!=e[t].conditions.length){var i=this.addGroup(this.parent,e[t].operator);for(var o in e[t].conditions){var n=e[t].conditions[o],r=this.addRow(i);r.childNodes[1].firstChild.value=n.column;var s=this.addOperator(r,this.columns[n.column]);s.value=n.operator,this.switchOperator(s,n.values)}}},e.prototype.export=function(){var e=this.parent.querySelectorAll("table"),t=[];for(var i in e)if(e.hasOwnProperty(i)){for(var o=(i=e[i]).rows,n=[],r=0;r<o.length;r++){var s=o[r];if(s.getElementsByTagName("select")[0].value){var a=Array.prototype.slice.call(s.cells[3].querySelectorAll("input, select")).map(function(e){if("button"!=e.type)return e.value}),l={column:s.cells[1].firstChild.value,operator:s.cells[2].firstChild.value,values:a};l.operator&&(l.operator.match(/\?\?/)&&(l.values=l.values.slice(0,-2)),n.push(l))}}t.push({operator:i.parentNode.firstChild.firstChild.value,conditions:n})}return t}}(); |
Modified src/www/admin/static/scripts/wiki_editor.js from [2dad10610c] to [e1b49b3d06].
1 2 3 | (function () { var wiki_id = window.location.search.match(/id=(\d+)/)[1]; | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 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 170 171 | (function () { var wiki_id = window.location.search.match(/id=(\d+)/)[1]; g.onload(function () { g.style('scripts/wiki_editor.css'); g.script('scripts/text_editor.min.js').onload = function () { var t = new textEditor('f_contenu'); t.parent = t.textarea.parentNode; var toolbar = document.createElement('nav'); toolbar.className = 'te'; var toggleFullscreen = function (e) { var classes = t.parent.className.split(' '); for (var i = 0; i < classes.length; i++) { if (classes[i] == 'fullscreen') { classes.splice(i, 1); t.parent.className = classes.join(' '); t.fullscreen = false; return true; } } classes.push('fullscreen'); t.parent.className = classes.join(' '); t.fullscreen = true; return true; }; var openPreview = function () { openIFrame(''); var form = document.createElement('form'); form.appendChild(t.textarea.cloneNode(true)); form.firstChild.value = t.textarea.value; form.target = 'editorFrame'; form.action = g.admin_url + 'wiki/_preview.php?id=' + wiki_id; form.style.display = 'none'; form.method = 'post'; document.body.appendChild(form); form.submit(); //document.body.removeChild(form); }; var openSyntaxHelp = function () { openIFrame(g.admin_url + 'wiki/_syntaxe.html'); }; var openFileInsert = function () { openIFrame(g.admin_url + 'wiki/_fichiers.php?page=' + wiki_id); }; window.te_insertFile = function (file) { var tag = '<<fichier|'+file+'>>'; t.insertAtPosition(t.getSelection().start, tag); closeIFrame(); }; window.te_insertImage = function (file, position, caption) { var tag = '<<image|' + file; if (position) tag += '|' + position; if (caption) tag += '|' + caption; tag += '>>'; t.insertAtPosition(t.getSelection().start, tag); closeIFrame(); }; var openIFrame = function(url) { if (t.iframe && t.iframe.src == t.base_url + url) { t.iframe.className = ''; t.parent.className += ' iframe'; return true; } else if (t.iframe) { t.parent.removeChild(t.iframe); t.iframe = null; } var w = t.textarea.offsetWidth, h = t.textarea.offsetHeight; var iframe = document.createElement('iframe'); iframe.width = w; iframe.height = h; iframe.src = url; iframe.name = 'editorFrame'; iframe.frameborder = '0'; iframe.scrolling = 'yes'; t.parent.appendChild(iframe); t.parent.className += ' iframe'; t.iframe = iframe; }; var closeIFrame = function () { t.parent.className = t.parent.className.replace(/ iframe$/, ''); t.iframe.className = 'hidden'; }; var appendButton = function (name, title, action, altTitle) { var btn = document.createElement('input'); btn.type = 'button'; btn.title = altTitle ? altTitle : title; btn.value = title; btn.className = name; btn.onclick = function () { action.call(); return false; }; toolbar.appendChild(btn); return btn; }; var wrapTags = function (left, right) { t.wrapSelection(t.getSelection(), left, right); return true; }; appendButton('title', "== Titre", function () { wrapTags("== ", ""); } ); appendButton('bold', '**gras**', function () { wrapTags('**', '**'); } ); appendButton('italic', "''italique''", function () { wrapTags("''", "''"); } ); appendButton('link', "[[lien|http://]]", function () { if (url = window.prompt('Adresse URL ?')) wrapTags("[[", "|" + url + ']]'); } ); appendButton('icnl file', "📎", openFileInsert, 'Insérer fichier / image'); appendButton('ext icnl preview', '⎙', openPreview, 'Prévisualiser'); appendButton('ext icnl help', '❓', openSyntaxHelp, 'Aide sur la syntaxe'); appendButton('ext fullscreen', 'Plein écran', toggleFullscreen, 'Plein écran'); appendButton('ext close', 'Fermer', closeIFrame); t.parent.insertBefore(toolbar, t.parent.firstChild); t.shortcuts.push({key: 'F11', callback: toggleFullscreen}); t.shortcuts.push({ctrl: true, key: 'b', callback: function () { return wrapTags('**', '**'); } }); t.shortcuts.push({ctrl: true, key: 'g', callback: function () { return wrapTags('**', '**'); } }); t.shortcuts.push({ctrl: true, key: 'i', callback: function () { return wrapTags("''", "''"); } }); if (window.location.hash.match(/fullscreen/)) { t.toggleFullscreen(); window.location.hash = ''; } }; }); }()); |
Modified src/www/admin/upgrade.php from [4dda8f7462] to [16f61c74de].
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | <?php namespace Garradin; const UPGRADE_PROCESS = true; require_once __DIR__ . '/../../include/init.php'; $config = Config::getInstance(); $v = $config->getVersion(); if (version_compare($v, garradin_version(), '>=')) { throw new UserException("Pas de mise à jour à faire."); } Install::checkAndCreateDirectories(); if (Static_Cache::exists('upgrade')) { $path = Static_Cache::getPath('upgrade'); throw new UserException('Une mise à jour est déjà en cours.' . PHP_EOL . 'Si celle-ci a échouée et que vous voulez ré-essayer, supprimez le fichier suivant:' . PHP_EOL . $path); } Static_Cache::store('upgrade', 'Mise à jour en cours.'); $db = DB::getInstance(); $redirect = true; // Créer une sauvegarde automatique | > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | <?php namespace Garradin; use Garradin\Membres\Session; const UPGRADE_PROCESS = true; require_once __DIR__ . '/../../include/test_required.php'; require_once __DIR__ . '/../../include/init.php'; $config = Config::getInstance(); $v = $config->getVersion(); if (version_compare($v, garradin_version(), '>=')) { throw new UserException("Pas de mise à jour à faire."); } // versions pré-0.7.0: démerdez-vous ! if (!$v || version_compare($v, '0.7.0', '<')) { throw new UserException("Votre version de Garradin est trop ancienne pour être mise à jour. Mettez à jour vers Garradin 0.8.5 avant de faire la mise à jour vers cette version."); } Install::checkAndCreateDirectories(); if (Static_Cache::exists('upgrade')) { $path = Static_Cache::getPath('upgrade'); throw new UserException('Une mise à jour est déjà en cours.' . PHP_EOL . 'Si celle-ci a échouée et que vous voulez ré-essayer, supprimez le fichier suivant:' . PHP_EOL . $path); } // Voir si l'utilisateur est loggé, on le fait ici pour le cas où // il y aurait déjà eu des entêtes envoyés au navigateur plus bas $session = new Session; $user_is_logged = $session->isLogged(true); Static_Cache::store('upgrade', 'Mise à jour en cours.'); $db = DB::getInstance(); $redirect = true; // Créer une sauvegarde automatique |
︙ | ︙ | |||
50 51 52 53 54 55 56 | <div id="loader" class="loader" style="margin: 2em 0; height: 50px;"></div> <script> animatedLoader(document.getElementById("loader"), 5); </script>'; flush(); | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | <div id="loader" class="loader" style="margin: 2em 0; height: 50px;"></div> <script> animatedLoader(document.getElementById("loader"), 5); </script>'; flush(); if (version_compare($v, '0.7.0', '<')) { $db->exec('PRAGMA foreign_keys = OFF; BEGIN;'); // Mise à jour base de données $db->exec(file_get_contents(ROOT . '/include/data/0.7.0.sql')); |
︙ | ︙ | |||
324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 | { $db->begin(); $db->import(ROOT . '/include/data/0.8.4.sql'); $db->commit(); } Utils::clearCaches(); $config->setVersion(garradin_version()); Static_Cache::remove('upgrade'); echo '<h2>Mise à jour terminée.</h2> <p><a href="'.ADMIN_URL.'">Retour</a></p>'; if ($redirect) { echo ' | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 | { $db->begin(); $db->import(ROOT . '/include/data/0.8.4.sql'); $db->commit(); } if (version_compare($v, '0.9.0-rc1', '<')) { $db->exec('PRAGMA foreign_keys = OFF;'); $db->begin(); $db->import(ROOT . '/include/data/0.9.0.sql'); // Correction des ID parents des comptes qui ont été mal renseignés // exemple : compte 512A avec "5" comme parent (c'était permis, // par erreur, par le formulaire d'ajout de compte dans le plan) // Serait probablement possible en 3-4 lignes de SQL avec // WITH RECURSIVE mais c'est au delà de mes compétences $comptes = $db->iterate('SELECT id FROM compta_comptes WHERE parent != length(id) - 1;'); foreach ($comptes as $compte) { $parent = false; $id = $compte->id; while (!$parent && strlen($id)) { // On enlève un caractère à la fin jusqu'à trouver un compte parent correspondant $id = substr($id, 0, -1); $parent = $db->firstColumn('SELECT id FROM compta_comptes WHERE id = ?;', $id); } if (!$parent) { // Situation normalement impossible ! throw new \LogicException(sprintf('Le compte %s est invalide et n\'a pas de compte parent possible !', $compte->id)); } $db->update('compta_comptes', ['parent' => $parent], 'id = :id', ['id' => $compte->id]); } $champs = $config->get('champs_membres'); if ($champs->get('lettre_infos')) { // Ajout d'une recherche avancée en exemple $query = [ 'query' => [[ 'operator' => 'AND', 'conditions' => [ [ 'column' => 'lettre_infos', 'operator' => '= 1', 'values' => [], ], ], ]], 'order' => 'numero', 'desc' => true, 'limit' => '10000', ]; $recherche = new Recherche; $recherche->add('Membres inscrits à la lettre d\'information', null, $recherche::TYPE_JSON, 'membres', $query); } $db->commit(); $config->set('desactiver_site', false); $config->save(); } Utils::clearCaches(); $config->setVersion(garradin_version()); Static_Cache::remove('upgrade'); // Réinstaller les plugins système si nécessaire Plugin::checkAndInstallSystemPlugins(); // Mettre à jour les plugins si nécessaire foreach (Plugin::listInstalled() as $id=>$infos) { // Ne pas tenir compte des plugins dont le code n'est pas dispo if ($infos->disabled) { continue; } $plugin = new Plugin($id); if ($plugin->needUpgrade()) { $plugin->upgrade(); } unset($plugin); } // Forcer à rafraîchir les données de la session si elle existe if ($user_is_logged) { $session->refresh(); } echo '<h2>Mise à jour terminée.</h2> <p><a href="'.ADMIN_URL.'">Retour</a></p>'; if ($redirect) { echo ' |
︙ | ︙ |
Modified src/www/index.php from [36cb4b20f1] to [f59003a96f].
1 2 3 4 5 6 7 8 | <?php namespace Garradin; require __DIR__ . '/_inc.php'; $squelette = new Squelette; $squelette->dispatchURI(); | > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 | <?php namespace Garradin; require __DIR__ . '/_inc.php'; if (Config::getInstance()->get('desactiver_site')) { Utils::redirect(ADMIN_URL); } $squelette = new Squelette; $squelette->dispatchURI(); |