Index: src/VERSION
==================================================================
--- src/VERSION
+++ src/VERSION
@@ -1,1 +1,1 @@
-0.8.5
+0.9.0
Index: src/config.dist.php
==================================================================
--- src/config.dist.php
+++ src/config.dist.php
@@ -236,18 +236,18 @@
* Défaut : STARTTLS
*/
const SMTP_SECURITY = 'STARTTLS';
/**
- * Forcer la valeur de l'expéditeur des emails
- *
- * false, null ou vide = désactivé
- * chaîne = adresse email qui sera utilisé dans le champ From
- * des emails envoyés
- *
- * Utile pour les services d'envoi SMTP tiers comme Amazon SES.
- * Si activé le "From" sera : "Nom de l'association" 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 !
- {if $ok == 'config'}La configuration a bien été enregistrée.
- {elseif $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 date-du-jour.avant_restauration.sqlite, sinon vous pouvez l'effacer.
- {if $ok_code & Garradin\Sauvegarde::NOT_AN_ADMIN}
-
- Vous n'êtes pas administrateur dans cette sauvegarde. 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}
- La configuration a bien été enregistrée. 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 !
+ {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 {$now_date}.avant_restauration.sqlite, sinon vous pouvez l'effacer.
+ {if $ok_code & Garradin\Sauvegarde::NOT_AN_ADMIN}
+
+ Vous n'êtes pas administrateur dans cette sauvegarde. 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}
+
+ {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 date-du-jour.avant_restauration.sqlite, sinon vous pouvez l'effacer.
+ {if $ok_code & Garradin\Sauvegarde::NOT_AN_ADMIN}
+
+ Vous n'êtes pas administrateur dans cette sauvegarde. 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}
+ La remise à zéro a été effectuée. Une sauvegarde a également été créée.|<\/ul>/', '', $str);
$str = preg_replace('/(\V*?)<\/a>/', '[[$2 | $1]]', $str);
return $str;
}
- static public function mail($to, $subject, $content, array $headers = [], $pgp_key = null)
- {
- // Création du contenu du message
- $content = wordwrap($content);
- $content = trim($content);
-
- $content = preg_replace("#(?get('email_asso');
-
- if (empty($headers['From']))
- {
- if (FORCE_EMAIL_FROM)
- {
- $headers['Reply-To'] = !empty($headers['From']) ? $headers['From'] : $config->get('email_asso');
- $headers['From'] = sprintf('"%s" <%s>', sprintf('=?UTF-8?B?%s?=', base64_encode($config->get('nom_asso'))), FORCE_EMAIL_FROM);
- $headers['Return-Path'] = FORCE_EMAIL_FROM;
- }
- else
- {
- $headers['From'] = sprintf('"%s" <%s>', sprintf('=?UTF-8?B?%s?=', base64_encode($config->get('nom_asso'))), $config->get('email_asso'));
- }
- }
-
- $headers['MIME-Version'] = '1.0';
- $headers['Content-type'] = 'text/plain; charset=UTF-8';
-
- $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 ($pgp_key)
- {
- $content = Security::encryptWithPublicKey($pgp_key, $content);
- }
-
- if (!is_array($to))
- {
- $to = [$to];
- }
-
- foreach ($to as $recipient)
- {
- // Ne pas envoyer de mail à des adresses invalides
- if (!SMTP::checkEmailIsValid($recipient, false))
- {
- continue;
- }
-
- if (!self::_sendMail($recipient, $subject, $content, $headers))
- {
- throw new \RuntimeException('Impossible d\'envoyer l\'email');
- }
- }
-
- return true;
- }
-
- static protected function _sendMail($to, $subject, $content, array $headers)
- {
- 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);
- }
- }
-
static public function clearCaches($path = false)
{
if (!$path)
{
self::clearCaches('compiled');
@@ -741,6 +651,87 @@
$field = strtr($field, ['"' => '""', "\r\n" => "\n"]);
});
return sprintf("\"%s\"\r\n", implode('","', $row));
}
+
+ static public function sendEmail($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);
+ }
+
+ // Tentative d'envoi du message en utilisant un plugin
+ $email_sent_via_plugin = Plugin::fireSignal('email.envoi', compact($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($recipient, $subject, $content, $id_membre, $pgp_key);
+ }
+
+ return true;
+ }
+
+ static public function mail($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("#(?get('nom_asso'), $subject);
+
+ $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';
+
+ $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);
+ }
+ }
}
Index: src/templates/admin/_head.tpl
==================================================================
--- src/templates/admin/_head.tpl
+++ src/templates/admin/_head.tpl
@@ -68,11 +68,10 @@
{if $session->canAccess('membres', Garradin\Membres::DROIT_ECRITURE)}
+
+
+{include file="admin/_foot.tpl"}
ADDED src/templates/admin/config/categories/modifier.tpl
Index: src/templates/admin/config/categories/modifier.tpl
==================================================================
--- src/templates/admin/config/categories/modifier.tpl
+++ src/templates/admin/config/categories/modifier.tpl
@@ -0,0 +1,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}
+
+
+
+{include file="admin/_foot.tpl"}
ADDED src/templates/admin/config/categories/supprimer.tpl
Index: src/templates/admin/config/categories/supprimer.tpl
==================================================================
--- src/templates/admin/config/categories/supprimer.tpl
+++ src/templates/admin/config/categories/supprimer.tpl
@@ -0,0 +1,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}
+
+
+
+{include file="admin/_foot.tpl"}
DELETED src/templates/admin/config/donnees.tpl
Index: src/templates/admin/config/donnees.tpl
==================================================================
--- src/templates/admin/config/donnees.tpl
+++ src/templates/admin/config/donnees.tpl
@@ -1,153 +0,0 @@
-{include file="admin/_head.tpl" title="Données — Sauvegarde et restauration" current="config"}
-
-{include file="admin/config/_menu.tpl" current="donnees"}
-
-{form_errors}
-
-{if $code == Garradin\Sauvegarde::INTEGRITY_FAIL && Garradin\ALLOW_MODIFIED_IMPORT}
-
{/if}
Index: src/templates/admin/config/_menu.tpl
==================================================================
--- src/templates/admin/config/_menu.tpl
+++ src/templates/admin/config/_menu.tpl
@@ -1,8 +1,8 @@
ADDED src/templates/admin/config/categories/index.tpl
Index: src/templates/admin/config/categories/index.tpl
==================================================================
--- src/templates/admin/config/categories/index.tpl
+++ src/templates/admin/config/categories/index.tpl
@@ -0,0 +1,50 @@
+{include file="admin/_head.tpl" title="Catégories de membres" current="config"}
+
+{include file="admin/config/_menu.tpl" current="categories"}
+
+
+
+
+
+Nom
+ Membres
+ Droits
+
+
+
+ {foreach from=$liste item="cat"}
+
+
+ {/foreach}
+
+{$cat.nom}
+ {$cat.nombre}
+
+ {format_droits droits=$cat}
+
+
+ 👪
+ ✎
+ {if $cat.id != $user.id_categorie}
+ ✘
+ {/if}
+
+
+
ADDED src/templates/admin/config/donnees/automatique.tpl
Index: src/templates/admin/config/donnees/automatique.tpl
==================================================================
--- src/templates/admin/config/donnees/automatique.tpl
+++ src/templates/admin/config/donnees/automatique.tpl
@@ -0,0 +1,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'}
+
La configuration a bien été enregistrée.
Index: src/templates/admin/config/site.tpl ================================================================== --- src/templates/admin/config/site.tpl +++ src/templates/admin/config/site.tpl @@ -2,11 +2,22 @@ {form_errors} {include file="admin/config/_menu.tpl" current="site"} -{if isset($edit)} +{if $config.desactiver_site} +Le site public est désactivé, les visiteurs sont redirigés automatiquement vers la page de connexion.
+ +{/if} {foreach from=$champs key="c" item="champ"} @@ -67,11 +63,11 @@ {if $c == $config.champ_identite}{/if} {/foreach} | 👤 - ✎ + {if $session->canAccess('membres', Garradin\Membres::DROIT_ECRITURE)}✎{/if} |
- Aucun membre trouvé. -
- {/if} - -Membre | -- - - {foreach from=$liste item="membre"} - |
---|---|
{$membre.identite} | -- {if !empty($membre.email)}Envoyer un message{/if} - | -
- Aucun membre trouvé. -
- {/if} -{/if} +{else} ++ Aucun membre trouvé. +
+{/if} + + {include file="admin/_foot.tpl"} Index: src/templates/admin/membres/message.tpl ================================================================== --- src/templates/admin/membres/message.tpl +++ src/templates/admin/membres/message.tpl @@ -6,13 +6,10 @@{/if} + {if $session->canAccess('membres', Garradin\Membres::DROIT_ADMIN)} | {/if} {foreach from=$champs_entete key="c" item="cfg"} {if $champ == $c} | {$cfg.title} | {else}{$cfg.title} | @@ -84,89 +83,41 @@{$membre->$c|raw|display_champ_membre:$cfg} | {/if} {/foreach}👤 + {if $session->canAccess('membres', Garradin\Membres::DROIT_ECRITURE)} ✎ + {/if} | {/foreach}
---|
- +
Pour les membres cochés : {csrf_field key="membres_action"}
{/if} - {elseif $recherche != ''} +{elseif $recherche != ''} +Aucun membre trouvé.
- {/if} - -Membre | -- - - {foreach from=$liste item="membre"} - |
---|---|
{$membre.identite} | -- {if !empty($membre.email)}Envoyer un message{/if} - | -
- Aucun membre trouvé. -
- {/if} + +{/if} + +{if $session->canAccess('membres', Garradin\Membres::DROIT_ECRITURE)} + {/if} - {include file="admin/_foot.tpl"} Index: src/templates/error.tpl ================================================================== --- src/templates/error.tpl +++ src/templates/error.tpl @@ -1,10 +1,10 @@ -{$error|escape|nl2br}
Index: src/www/admin/_inc.php ================================================================== --- src/www/admin/_inc.php +++ src/www/admin/_inc.php @@ -68,12 +68,15 @@ $user = $session->getUser(); $tpl->assign('user', $user); $tpl->assign('current', ''); - $tpl->assign('plugins_menu', Plugin::listMenu()); - if ($session->canAccess('membres', Membres::DROIT_ACCES)) + if ($session->get('plugins_menu') === null) { - $tpl->assign('nb_membres', (new Membres)->countAllButHidden()); + // 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')); } ADDED src/www/admin/config/categories/index.php Index: src/www/admin/config/categories/index.php ================================================================== --- src/www/admin/config/categories/index.php +++ src/www/admin/config/categories/index.php @@ -0,0 +1,26 @@ +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 Index: src/www/admin/config/categories/modifier.php ================================================================== --- src/www/admin/config/categories/modifier.php +++ src/www/admin/config/categories/modifier.php @@ -0,0 +1,90 @@ + '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 Index: src/www/admin/config/categories/supprimer.php ================================================================== --- src/www/admin/config/categories/supprimer.php +++ src/www/admin/config/categories/supprimer.php @@ -0,0 +1,43 @@ + '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 Index: src/www/admin/config/donnees.php ================================================================== --- src/www/admin/config/donnees.php +++ src/www/admin/config/donnees.php @@ -1,113 +0,0 @@ -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.php?ok=config'); - } catch (UserException $e) { - $form->addError($e->getMessage()); - } - } -} -elseif (f('create')) -{ - $form->check('backup_create'); - - if (!$form->hasErrors()) - { - try { - $s->create(); - Utils::redirect(ADMIN_URL . 'config/donnees.php?ok=create'); - } catch (UserException $e) { - $form->addError($e->getMessage()); - } - } -} -elseif (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')) -{ - $form->check('backup_manage'); - - if (!$form->hasErrors()) - { - try { - $r = $s->restoreFromLocal(f('file')); - Utils::redirect(ADMIN_URL . 'config/donnees.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.php?ok=remove'); - } catch (UserException $e) { - $form->addError($e->getMessage()); - } - } -} -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.php?ok=restore&code=' . (int)$r); - } catch (UserException $e) { - $form->addError($e->getMessage()); - $code = $e->getCode(); - } - } -} - -$tpl->assign('code', $code); -$tpl->assign('ok_code', qg('code')); -$tpl->assign('ok', qg('ok')); -$tpl->assign('liste', $s->getList()); -$tpl->assign('max_file_size', Utils::getMaxUploadSize()); - -$tpl->assign('db_size', $s->getDBSize()); -$tpl->assign('files_size', $s->getDBFilesSize()); - -$tpl->display('admin/config/donnees.tpl'); ADDED src/www/admin/config/donnees/automatique.php Index: src/www/admin/config/donnees/automatique.php ================================================================== --- src/www/admin/config/donnees/automatique.php +++ src/www/admin/config/donnees/automatique.php @@ -0,0 +1,34 @@ +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 Index: src/www/admin/config/donnees/import.php ================================================================== --- src/www/admin/config/donnees/import.php +++ src/www/admin/config/donnees/import.php @@ -0,0 +1,6 @@ +display('admin/config/donnees/import.tpl'); ADDED src/www/admin/config/donnees/index.php Index: src/www/admin/config/donnees/index.php ================================================================== --- src/www/admin/config/donnees/index.php +++ src/www/admin/config/donnees/index.php @@ -0,0 +1,51 @@ +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 Index: src/www/admin/config/donnees/local.php ================================================================== --- src/www/admin/config/donnees/local.php +++ src/www/admin/config/donnees/local.php @@ -0,0 +1,56 @@ +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('code', $code); +$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 Index: src/www/admin/config/donnees/reset.php ================================================================== --- src/www/admin/config/donnees/reset.php +++ src/www/admin/config/donnees/reset.php @@ -0,0 +1,25 @@ +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 Index: src/www/admin/config/import.php ================================================================== --- src/www/admin/config/import.php +++ src/www/admin/config/import.php @@ -1,6 +0,0 @@ -display('admin/config/import.tpl'); Index: src/www/admin/config/site.php ================================================================== --- src/www/admin/config/site.php +++ src/www/admin/config/site.php @@ -1,24 +1,21 @@ check('config_site')) -{ - try { - $config->set('champs_obligatoires', f('champs_obligatoires')); - $config->set('champs_modifiables_membre', f('champs_modifiables_membre')); - $config->set('categorie_membres', f('categorie_membres')); - $config->save(); - - Utils::redirect(ADMIN_URL . 'config/site.php?ok'); - } - catch (UserException $e) - { - $form->addError($e->getMessage()); - } +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 { Index: src/www/admin/index.php ================================================================== --- src/www/admin/index.php +++ src/www/admin/index.php @@ -27,10 +27,12 @@ { $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à DELETED src/www/admin/membres/categories/index.php Index: src/www/admin/membres/categories/index.php ================================================================== --- src/www/admin/membres/categories/index.php +++ src/www/admin/membres/categories/index.php @@ -1,28 +0,0 @@ -requireAccess('membres', Membres::DROIT_ADMIN); - -$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 . 'membres/categories/'); - } -} - -$tpl->assign('liste', $cats->listCompleteWithStats()); - -$tpl->display('admin/membres/categories/index.tpl'); DELETED src/www/admin/membres/categories/modifier.php Index: src/www/admin/membres/categories/modifier.php ================================================================== --- src/www/admin/membres/categories/modifier.php +++ src/www/admin/membres/categories/modifier.php @@ -1,94 +0,0 @@ -requireAccess('membres', Membres::DROIT_ADMIN); - -$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'), - 'description' => f('description'), - '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; - $data['droit_membres'] = 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 . 'membres/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', $membres); - -$tpl->display('admin/membres/categories/modifier.tpl'); DELETED src/www/admin/membres/categories/supprimer.php Index: src/www/admin/membres/categories/supprimer.php ================================================================== --- src/www/admin/membres/categories/supprimer.php +++ src/www/admin/membres/categories/supprimer.php @@ -1,45 +0,0 @@ -requireAccess('membres', Membres::DROIT_ADMIN); - -$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 . 'membres/categories/'); - } - catch (UserException $e) - { - $form->addError($e->getMessage()); - } - } -} - -$tpl->assign('cat', $cat); - -$tpl->display('admin/membres/categories/supprimer.tpl'); Index: src/www/admin/membres/cotisations.php ================================================================== --- src/www/admin/membres/cotisations.php +++ src/www/admin/membres/cotisations.php @@ -1,12 +1,10 @@ requireAccess('membres', Membres::DROIT_ECRITURE); - qv(['id' => 'required|numeric']); $id = (int) qg('id'); $membre = $membres->get($id); Index: src/www/admin/membres/fiche.php ================================================================== --- src/www/admin/membres/fiche.php +++ src/www/admin/membres/fiche.php @@ -1,12 +1,10 @@ requireAccess('membres', Membres::DROIT_ECRITURE); - qv(['id' => 'required|numeric']); $id = (int) qg('id'); $membre = $membres->get($id); Index: src/www/admin/membres/index.php ================================================================== --- src/www/admin/membres/index.php +++ src/www/admin/membres/index.php @@ -1,86 +1,73 @@ search($config->get('champ_identite'), $recherche); - $tpl->assign('liste', $result); - $tpl->assign('recherche', $recherche); -} -else -{ - $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); - -} +$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'); Index: src/www/admin/membres/recherche.php ================================================================== --- src/www/admin/membres/recherche.php +++ src/www/admin/membres/recherche.php @@ -1,12 +1,10 @@ requireAccess('membres', Membres::DROIT_ECRITURE); - $recherche = trim(qg('r')); $champ = trim(qg('c')); $champs = $config->get('champs_membres'); Index: src/www/admin/static/admin.css ================================================================== --- src/www/admin/static/admin.css +++ src/www/admin/static/admin.css @@ -407,14 +407,22 @@ ul.actions { list-style-type: none; margin: 1em 0; border-bottom: .1em solid #9c4f15; - border-bottom: .1em solid rgb(var(--gMainColor)); + 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; } @@ -426,10 +434,11 @@ 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; } @@ -441,11 +450,11 @@ color: rgb(var(--gBgColor)); } ul.actions li a:hover, ul.actions li label:hover { color: #fff; - color: rgb(var(--gBgColor)); + background-color: rgb(var(--gMainColor)); text-decoration: underline; border-bottom: none; } h3.warning { Index: src/www/admin/upgrade.php ================================================================== --- src/www/admin/upgrade.php +++ src/www/admin/upgrade.php @@ -1,7 +1,10 @@ import(ROOT . '/include/data/0.8.4.sql'); $db->commit(); } + +if (version_compare($v, '0.9.0', '<')) +{ + $db->exec('PRAGMA foreign_keys = OFF;'); + $db->begin(); + + $db->import(ROOT . '/include/data/0.9.0.sql'); + + $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) +{ + $plugin = new Plugin($id); + + if ($plugin->needUpgrade()) + { + $plugin->upgrade(); + } + + unset($plugin); +} + +// Forcer à rafraîchir les données de la session si elle existe +$session = new Session; + +if ($session->isLogged()) +{ + $session->refresh(); +} echo '