public function remove($id) { $db = DB::getInstance(); $config = Config::getInstance(); if ($id == $config->get('categorie_membres')) { throw new UserException('Il est interdit de supprimer la catégorie définie par défaut dans la configuration.'); } if ($db->simpleQuerySingle('SELECT 1 FROM membres WHERE id_categorie = ?;', false, (int) $id)) { throw new UserException('La catégorie contient encore des membres, il n\'est pas possible de la supprimer.'); } $db->simpleUpdate('wiki_pages', ['droit_lecture' => Wiki::LECTURE_NORMAL, 'droit_ecriture' => Wiki::ECRITURE_NORMAL], 'droit_lecture = ' . (int) $id . ' OR droit_ecriture = ' . (int) $id); return $db->simpleExec('DELETE FROM membres_categories WHERE id = ?;', (int) $id); }
/** * Liste des membres qui sont inscrits à une cotisation * @param integer $id Numéro de la cotisation * @return array Liste des membres */ public function listMembersForCotisation($id, $page = 1, $order = null, $desc = true) { $begin = ($page - 1) * self::ITEMS_PER_PAGE; $db = DB::getInstance(); $champ_id = Config::getInstance()->get('champ_identite'); if (empty($order)) { $order = 'date'; } switch ($order) { case 'date': case 'a_jour': break; case 'identite': $order = 'transliterate_to_ascii(' . $champ_id . ') COLLATE NOCASE'; break; default: $order = 'cm.id_membre'; break; } $desc = $desc ? 'DESC' : 'ASC'; return $db->simpleStatementFetch('SELECT cm.id_membre, cm.date, cm.id, (SELECT ' . $champ_id . ' FROM membres WHERE id = cm.id_membre) AS nom, c.montant, CASE WHEN c.duree IS NOT NULL THEN date(cm.date, \'+\'||c.duree||\' days\') >= date() WHEN c.fin IS NOT NULL THEN c.fin >= date() ELSE 1 END AS a_jour FROM cotisations_membres AS cm INNER JOIN cotisations AS c ON c.id = cm.id_cotisation WHERE cm.id_cotisation = ? GROUP BY cm.id_membre ORDER BY ' . $order . ' ' . $desc . ' LIMIT ?,?;', \SQLITE3_ASSOC, (int) $id, $begin, self::ITEMS_PER_PAGE); }
/** * Lister les membres liés à cette écriture * @param integer $id Numéro d'écriture * @return array Liste des membres liés */ public function listRelatedMembers($id) { $db = DB::getInstance(); $champ_id = Config::getInstance()->get('champ_identite'); return $db->simpleStatementFetch('SELECT id_membre, id_cotisation, m.' . $champ_id . ' AS identite FROM membres_operations AS mo INNER JOIN membres AS m ON mo.id_membre = m.id WHERE mo.id_operation = ?;', \SQLITE3_ASSOC, (int) $id); }
/** * Importer un CSV de la liste des membres depuis un export Garradin * @param string $path Chemin vers le CSV * @return boolean TRUE en cas de succès */ public function fromCSV($path) { if (!file_exists($path) || !is_readable($path)) { throw new \RuntimeException('Fichier inconnu : ' . $path); } $fp = fopen($path, 'r'); if (!$fp) { return false; } $db = DB::getInstance(); $db->exec('BEGIN;'); $membres = new Membres(); // On récupère les champs qu'on peut importer $champs = Config::getInstance()->get('champs_membres')->getAll(); $champs = array_keys($champs); $champs[] = 'date_inscription'; //$champs[] = 'date_connexion'; $champs[] = 'id'; //$champs[] = 'id_categorie'; $line = 0; $delim = Utils::find_csv_delim($fp); while (!feof($fp)) { $row = fgetcsv($fp, 4096, $delim); $line++; if (empty($row)) { continue; } if ($line == 1) { if (is_numeric($row[0])) { throw new UserException('Erreur sur la ligne 1 : devrait contenir l\'en-tête des colonnes.'); } $columns = array_flip($row); continue; } if (count($row) != count($columns)) { $db->exec('ROLLBACK;'); throw new UserException('Erreur sur la ligne ' . $line . ' : le nombre de colonnes est incorrect.'); } $data = []; foreach ($columns as $name => $id) { $name = trim($name); // Champs qui n'existent pas dans le schéma actuel if (!in_array($name, $champs)) { continue; } if (trim($row[$id]) !== '') { $data[$name] = $row[$id]; } } if (!empty($data['id'])) { $id = (int) $data['id']; unset($data['id']); } else { $id = false; } try { if ($id) { $membres->edit($id, $data); } else { $membres->add($data); } } catch (UserException $e) { $db->exec('ROLLBACK;'); throw new UserException('Erreur sur la ligne ' . $line . ' : ' . $e->getMessage()); } } $db->exec('END;'); fclose($fp); return true; }
/** * 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, -- Numéro de catégorie', 'date_connexion TEXT NULL, -- Date de dernière connexion', 'date_inscription TEXT NOT NULL DEFAULT CURRENT_DATE, -- Date d\'inscription']; $create_keys = ['FOREIGN KEY (id_categorie) REFERENCES membres_categories (id)']; // Champs à recopier $copy = ['id', 'id_categorie', 'date_connexion', 'date_inscription']; $anciens_champs = $config->get('champs_membres'); $anciens_champs = is_null($anciens_champs) ? $this->champs : $anciens_champs->getAll(); foreach ($this->champs as $key => $cfg) { if ($cfg['type'] == 'number') { $type = 'FLOAT'; } elseif ($cfg['type'] == 'multiple' || $cfg['type'] == 'checkbox') { $type = 'INTEGER'; } elseif ($cfg['type'] == 'file') { $type = 'BLOB'; } else { $type = 'TEXT'; } $line = $key . ' ' . $type . ','; if (!empty($cfg['title'])) { $line .= ' -- ' . str_replace(["\n", "\r"], '', $cfg['title']); } $create[] = $line; if (array_key_exists($key, $anciens_champs)) { $copy[] = $key; } } $create = array_merge($create, $create_keys); $create = 'CREATE TABLE membres_tmp (' . "\n\t" . implode("\n\t", $create) . "\n);"; $copy = 'INSERT INTO membres_tmp (' . implode(', ', $copy) . ') SELECT ' . implode(', ', $copy) . ' FROM membres;'; $db->exec('PRAGMA foreign_keys = OFF;'); $db->exec('BEGIN;'); $db->exec($create); if ($enable_copy) { $db->exec($copy); } $db->exec('DROP TABLE IF EXISTS membres;'); $db->exec('ALTER TABLE membres_tmp RENAME TO membres;'); $db->exec('CREATE INDEX membres_id_categorie ON membres (id_categorie);'); // Index if ($config->get('champ_identifiant')) { // Mettre les champs identifiant vides à NULL pour pouvoir créer un index unique $db->exec('UPDATE membres SET ' . $config->get('champ_identifiant') . ' = NULL WHERE ' . $config->get('champ_identifiant') . ' = "";'); // Création de l'index unique $db->exec('CREATE UNIQUE INDEX membres_identifiant ON membres (' . $config->get('champ_identifiant') . ');'); } // Création des index pour les champs affichés dans la liste des membres $listed_fields = array_keys($this->getListedFields()); foreach ($listed_fields as $field) { if ($field === $config->get('champ_identifiant')) { // Il y a déjà un index continue; } $db->exec('CREATE INDEX membres_liste_' . $field . ' ON membres (' . $field . ');'); } $db->exec('END;'); $db->exec('PRAGMA foreign_keys = ON;'); $config->set('champs_membres', $this); $config->save(); return true; }