diff --git a/CHANGES.md b/CHANGES.md index 9bb3aa19..be6d381b 100755 --- a/CHANGES.md +++ b/CHANGES.md @@ -13,11 +13,13 @@ - Approbation des commentaires ## version 10.3.02 -- Correction : +- Corrections : - Icône de pied de page github manquante. + - Mauvaise redirection après changement de mot de passe d'un membre. - Modifications : - Nouvelles images de captcha. - Option de configuration, captcha demandé à la connexion. + - Module User : importation d'un liste d'utilisateur dans un fichier plat (CSV). ## version 10.3.01 - Corrections : diff --git a/core/module/user/ressource/.htaccess b/core/module/user/ressource/.htaccess new file mode 100644 index 00000000..e8a0ad3a --- /dev/null +++ b/core/module/user/ressource/.htaccess @@ -0,0 +1,8 @@ +# Bloque l'accès aux données +Order deny,allow +Deny from all +# Sauf l'accès au modèle csv + +Order Allow,Deny + Allow from all + \ No newline at end of file diff --git a/core/module/user/ressource/template.csv b/core/module/user/ressource/template.csv new file mode 100644 index 00000000..ff495590 --- /dev/null +++ b/core/module/user/ressource/template.csv @@ -0,0 +1,2 @@ +id;nom;prenom;email;groupe +jbon;Bon;Jean;jean.bon@email.fr;1 diff --git a/core/module/user/user.php b/core/module/user/user.php index 5fdadf42..74e12281 100644 --- a/core/module/user/user.php +++ b/core/module/user/user.php @@ -17,11 +17,12 @@ class user extends common { public static $actions = [ 'add' => self::GROUP_ADMIN, 'delete' => self::GROUP_ADMIN, - 'edit' => self::GROUP_MEMBER, - 'forgot' => self::GROUP_VISITOR, + 'import' => self::GROUP_ADMIN, 'index' => self::GROUP_ADMIN, - 'login' => self::GROUP_VISITOR, + 'edit' => self::GROUP_MEMBER, 'logout' => self::GROUP_MEMBER, + 'forgot' => self::GROUP_VISITOR, + 'login' => self::GROUP_VISITOR, 'reset' => self::GROUP_VISITOR ]; @@ -39,6 +40,12 @@ class user extends common { public static $userLongtime = false; + public static $separators = [ + ';' => ';', + ',' => ',', + ':' => ':' + ]; + /** * Ajout */ @@ -73,6 +80,11 @@ class user extends common { 'lastname' => $userLastname, 'mail' => $userMail, 'password' => $this->getInput('userAddPassword', helper::FILTER_PASSWORD, true), + "connectFail" => null, + "connectTimeout" => null, + "accessUrl" => null, + "accessTimer" => null, + "accessCsrf" => null ] ]); @@ -85,7 +97,6 @@ class user extends common { 'Bonjour ' . $userFirstname . ' ' . $userLastname . ',

' . 'Un administrateur vous a créé un compte sur le site ' . $this->getData(['config', 'title']) . '. Vous trouverez ci-dessous les détails de votre compte.

' . 'Identifiant du compte : ' . $this->getInput('userAddId') . '
' . - 'Mot de passe du compte : ' . $this->getInput('userAddPassword') . '

' . 'Nous ne conservons pas les mots de passe, en conséquence nous vous conseillons de conserver ce message tant que vous ne vous êtes pas connecté. Vous pourrez modifier votre mot de passe après votre première connexion.', null ); @@ -355,8 +366,9 @@ class user extends common { if($this->isPost()) { // Check la captcha if( + $this->getData(['config','connect','captcha']) //$this->getInput('userLoginCaptcha', helper::FILTER_INT) !== $this->getInput('userLoginCaptchaFirstNumber', helper::FILTER_INT) + $this->getInput('userLoginCaptchaSecondNumber', helper::FILTER_INT)) - password_verify($this->getInput('userLoginCaptcha', helper::FILTER_INT), $this->getInput('userLoginCaptchaResult') ) === false ) + AND password_verify($this->getInput('userLoginCaptcha', helper::FILTER_INT), $this->getInput('userLoginCaptchaResult') ) === false ) { self::$inputNotices['userLoginCaptcha'] = 'Incorrect'; } @@ -434,7 +446,7 @@ class user extends common { // Valeurs en sortie $this->addOutput([ 'notification' => 'Connexion réussie', - 'redirect' => helper::baseUrl() . str_replace('_', '/', str_replace('__', '#', $this->getUrl(2))), + 'redirect' => helper::baseUrl(), 'state' => true ]); } @@ -550,9 +562,115 @@ class user extends common { } // Valeurs en sortie $this->addOutput([ - 'title' => 'Réinitialisation du mot de passe', + 'display' => self::DISPLAY_LAYOUT_LIGHT, + 'title' => 'Réinitialisation de votre mot de passe', 'view' => 'reset' ]); } } + + /** + * Importation CSV d'utilisateurs + */ + public function import() { + // Soumission du formulaire + $notification = ''; + $success = true; + if($this->isPost()) { + // Lecture du CSV et construction du tableau + $file = $this->getInput('userImportCSVFile',helper::FILTER_STRING_SHORT, true); + $filePath = self::FILE_DIR . 'source/' . $file; + if ($file AND file_exists($filePath)) { + $rows = array_map(function($row) { return str_getcsv($row, $this->getInput('userImportSeparator') ); }, file($filePath)); + $header = array_shift($rows); + $csv = array(); + foreach($rows as $row) { + $csv[] = array_combine($header, $row); + } + // Stockage des données + foreach($csv as $item ) { + + // N'insére que les utilisateurs dont l'id n'existe pas + // Vérifier la présence des champs + if( array_key_exists('id', $item) + AND array_key_exists('prenom',$item) + AND array_key_exists('nom',$item) + AND array_key_exists('groupe',$item) + AND array_key_exists('email',$item) + AND !$this->getData(['user',helper::filter($item['id'] , helper::FILTER_ID)]) + ) + { + // Nettoyage de l'identifiant + $userId = helper::filter($item['id'] , helper::FILTER_ID); + // Enregistre le user + $this->setData([ + 'user', + $userId, [ + 'firstname' => $item['prenom'], + 'forgot' => 0, + 'group' => (int) $item['groupe'], + 'lastname' => $item['nom'], + 'mail' => $item['email'], + 'pseudo' => $item['prenom'], + 'signature' => 1, // Pseudo + 'password' => uniqid(), // A modifier à la première connexion + "connectFail" => null, + "connectTimeout" => null, + "accessUrl" => null, + "accessTimer" => null, + "accessCsrf" => null + ]]); + + // Icône de notification + $item['notification'] = template::ico('check'); + // Envoi du mail + if ($this->getInput('userImportNotification',helper::FILTER_BOOLEAN) === true) { + $sent = $this->sendMail( + $item['email'], + 'Compte créé sur ' . $this->getData(['config', 'title']), + 'Bonjour ' . $item['prenom'] . ' ' . $item['nom'] . ',

' . + 'Un administrateur vous a créé un compte sur le site ' . $this->getData(['config', 'title']) . '. Vous trouverez ci-dessous les détails de votre compte.

' . + 'Identifiant du compte : ' . $userId . '
' . + 'Un mot de passe provisoire vous été attribué, à la première connexion cliquez sur Mot de passe Oublié.' + ); + if ($sent === true) { + // Mail envoyé changement de l'icône + $item['notification'] = template::ico('comment') ; + } + } + } else { + $item['notification'] = template::ico('cancel'); + } + // Création du tableau de confirmation + self::$users[] = [ + $userId, + $item['nom'], + $item['prenom'], + self::$groups[$item['groupe']], + $item['prenom'], + $item['email'], + $item['notification'] + ]; + } + if (empty(self::$users)) { + $notification = 'Rien à importer' ; + $success = false; + } else { + $notification = 'Importation effectuée' ; + $success = true; + } + } else { + $notification = 'Erreur de lecture, vérifiez les permissions'; + $success = false; + } + } + // Valeurs en sortie + $this->addOutput([ + 'title' => 'Importation', + 'view' => 'import', + 'notification' => $notification, + 'state' => $success + ]); + } + } diff --git a/core/module/user/view/forgot/forgot.php b/core/module/user/view/forgot/forgot.php index 76931e3e..29dc17e8 100644 --- a/core/module/user/view/forgot/forgot.php +++ b/core/module/user/view/forgot/forgot.php @@ -5,7 +5,6 @@
'buttonGrey', 'href' => helper::baseUrl() . 'user/login/' . $this->getUrl(2), 'ico' => 'left', 'value' => 'Retour' diff --git a/core/module/user/view/import/import.css b/core/module/user/view/import/import.css new file mode 100644 index 00000000..2aa6edae --- /dev/null +++ b/core/module/user/view/import/import.css @@ -0,0 +1,16 @@ +/** + * This file is part of Zwii. + * + * For full copyright and license information, please see the LICENSE + * file that was distributed with this source code. + * + * @author Rémi Jean + * @copyright Copyright (C) 2008-2018, Rémi Jean + * @author Frédéric Tempez + * @copyright Copyright (C) 2018-2020, Frédéric Tempez + * @license GNU General Public License, version 3 + * @link http://zwiicms.fr/ + */ + + +@import url("site/data/admin.css"); \ No newline at end of file diff --git a/core/module/user/view/import/import.php b/core/module/user/view/import/import.php new file mode 100644 index 00000000..7364775b --- /dev/null +++ b/core/module/user/view/import/import.php @@ -0,0 +1,62 @@ + +
+
+ 'buttonGrey', + 'href' => helper::baseUrl() . 'user', + 'ico' => 'left', + 'value' => 'Retour' + ]); ?> +
+
+ 'Importer' + ]); ?> +
+
+
+
+
+

Importation de fichier plat CSV

+
+
+ 'Liste d\'utilisateurs :' + ]); ?> +
+
+ 'Séparateur' + ]); ?> +
+
+
+
+ false + ]); ?> +
+
+
+
+

Aide :

+
+
+

Les en-têtes obligatoires sont : id, nom, prenom, email et groupe + ( 1 : membre - 2 : éditeur - 3 : administrateur ) +

Voir ce modèle à compléter avec un tableur. + Enregistrement au format CSV, séparateur ; ou , ou :

+
+
+
+
+
+ + + +
+
+ Compte créé | Compte créé et notifié | Erreur +
+
+ \ No newline at end of file diff --git a/core/module/user/view/index/index.php b/core/module/user/view/index/index.php index 351e095d..483ad22c 100644 --- a/core/module/user/view/index/index.php +++ b/core/module/user/view/index/index.php @@ -7,7 +7,14 @@ 'value' => 'Accueil' ]); ?>
-
+
+ helper::baseUrl() . 'user/import', + 'ico' => 'plus', + 'value' => 'Importation' + ]); ?> +
+
helper::baseUrl() . 'user/add', 'ico' => 'plus', diff --git a/core/vendor/filemanager/config/config.php b/core/vendor/filemanager/config/config.php index 29537313..73e03b8b 100644 --- a/core/vendor/filemanager/config/config.php +++ b/core/vendor/filemanager/config/config.php @@ -119,7 +119,7 @@ $config = array( | If you want to be forced to assign the extension starting from the mime type | */ - 'mime_extension_rename' => true, + 'mime_extension_rename' => false, /* diff --git a/module/blog/view/article/article.php b/module/blog/view/article/article.php index 0e2d0291..b8217051 100644 --- a/module/blog/view/article/article.php +++ b/module/blog/view/article/article.php @@ -1,5 +1,5 @@
-
+