7 protected $champs = null;
10 'email' => 'Adresse E-Mail',
11 'url' => 'Adresse URL',
12 'checkbox' => 'Case à cocher',
14 'datetime' => 'Date et heure',
15 //'file' => 'Fichier',
16 'password' => 'Mot de passe',
18 'tel' => 'Numéro de téléphone',
19 'select' => 'Sélecteur à choix unique',
20 'multiple' => 'Sélecteur à choix multiple',
21 'country' => 'Sélecteur de pays',
23 'textarea' => 'Texte multi-lignes',
26 protected $text_types = [
36 protected $config_fields = [
47 static protected $presets = null;
49 public function __toString()
51 return utils
::write_ini_string($this->champs
);
54 public function toString()
56 return utils
::write_ini_string($this->champs
);
59 static public function importInstall()
61 $champs = parse_ini_file(ROOT
. '/include/data/champs_membres.ini', true);
62 $champs = array_filter($champs, function ($row) { return !empty($row['install']); });
63 return new Champs_Membres($champs);
66 static public function importPresets()
68 if (is_null(self
::$presets))
70 self
::$presets = parse_ini_file(ROOT
. '/include/data/champs_membres.ini', true);
73 return self
::$presets;
76 static public function listUnusedPresets(Champs_Membres
$champs)
78 return array_diff_key(self
::importPresets(), $champs->getAll());
81 public function __construct($champs)
83 if ($champs instanceOf Champs_Membres
)
85 $this->champs
= $champs->getAll();
87 elseif (is_array($champs))
89 foreach ($champs as $key=>&$config)
91 $this->_checkField($key, $config);
94 $this->champs
= $champs;
98 $champs = parse_ini_string((string)$champs, true);
100 foreach ($champs as $key=>&$config)
102 $this->_checkField($key, $config);
105 $this->champs
= $champs;
109 public function getTypes()
114 public function get($champ, $key = null)
118 return ['title' => 'Numéro unique', 'type' => 'number'];
121 if (!array_key_exists($champ, $this->champs
))
126 if (array_key_exists($key, $this->champs
[$champ]))
127 return $this->champs
[$champ][$key];
132 return $this->champs
[$champ];
135 public function isText($champ)
137 if (!array_key_exists($champ, $this->champs
))
140 if (in_array($this->champs
[$champ]['type'], $this->text_types
))
146 public function getAll()
148 $this->champs
['passe']['title'] = 'Mot de passe';
149 return $this->champs
;
152 public function getList()
154 $champs = $this->champs
;
155 unset($champs['passe']);
159 public function getFirst()
161 reset($this->champs
);
162 return key($this->champs
);
165 public function getListedFields()
167 $champs = $this->champs
;
169 $champs = array_filter($champs, function ($a) {
170 return empty($a['list_row']) ?
false : true;
173 uasort($champs, function ($a, $b) {
174 if ($a['list_row'] == $b['list_row'])
177 return ($a['list_row'] > $b['list_row']) ?
1 : -1;
184 * Vérifie la cohérence et la présence des bons éléments pour un champ
185 * @param string $name Nom du champ
186 * @param array $config Configuration du champ
187 * @return boolean true
189 protected function _checkField($name, &$config)
191 if (!preg_match('!^\w+(_\w+)*$!', $name))
193 throw new UserException('Le nom du champ est invalide.');
196 foreach ($config as $key=>&$value)
198 // Champ install non pris en compte
199 if ($key == 'install')
201 unset($config[$key]);
205 if (!in_array($key, $this->config_fields
))
207 throw new \
BadMethodCallException('Champ '.$key.' non valide.');
210 if ($key == 'editable' ||
$key == 'private' ||
$key == 'mandatory')
212 $value = (bool) (int) $value;
214 elseif ($key == 'list_row')
216 $value = (int) $value;
218 elseif ($key == 'help' ||
$key == 'title')
220 $value = trim((string) $value);
222 elseif ($key == 'options')
224 $value = (array) $value;
226 foreach ($value as $option_key=>$option_value)
228 if (trim($option_value) == '')
230 unset($value[$option_key]);
236 if (empty($config['title']) && $name != 'passe')
238 throw new UserException('Champ "'.$name.'" : Le titre est obligatoire.');
241 if (empty($config['type']) ||
!array_key_exists($config['type'], $this->types
))
243 throw new UserException('Champ "'.$name.'" : Le type est vide ou non valide.');
246 if ($name == 'email' && $config['type'] != 'email')
248 throw new UserException('Le champ email ne peut être d\'un type différent de email.');
251 if ($name == 'passe' && $config['type'] != 'password')
253 throw new UserException('Le champ mot de passe ne peut être d\'un type différent de mot de passe.');
256 if (($config['type'] == 'multiple' ||
$config['type'] == 'select') && empty($config['options']))
258 throw new UserException('Le champ "'.$name.'" nécessite de comporter au moins une option possible.');
261 if (!array_key_exists('editable', $config))
263 $config['editable'] = false;
266 if (!array_key_exists('mandatory', $config))
268 $config['mandatory'] = false;
271 if (!array_key_exists('private', $config))
273 $config['private'] = false;
280 * Ajouter un nouveau champ
281 * @param string $name Nom du champ
282 * @param array $config Configuration du champ
283 * @return boolean true
285 public function add($name, $config)
287 if (!preg_match('!^[a-z0-9]+(_[a-z0-9]+)*$!', $name))
289 throw new UserException('Le nom du champ est invalide : ne sont acceptés que des lettres minuscules et chiffres.');
292 $this->_checkField($name, $config);
294 $this->champs
[$name] = $config;
300 * Modifie un champ particulier
301 * @param string $champ Nom du champ
302 * @param string $key Nom de la clé à modifier
303 * @param mixed $value Valeur à affecter
304 * @return boolean true
306 public function set($champ, $key, $value)
308 if (!isset($this->champs
[$champ]))
310 throw new \
LogicException('Champ "'.$champ.'" inconnu.');
314 $config = $this->champs
[$champ];
315 $config[$key] = $value;
316 $this->_checkField($champ, $config);
318 $this->champs
[$champ] = $config;
323 * Modifie les champs en interne en vérifiant que tout va bien
324 * @param array $champs Liste des champs
325 * @return boolean true
327 public function setAll($champs)
329 if (!array_key_exists('email', $champs))
331 throw new UserException('Le champ E-Mail ne peut être supprimé des fiches membres.');
334 if (!array_key_exists('passe', $champs))
336 throw new UserException('Le champ Mot de passe ne peut être supprimé des fiches membres.');
339 $config = Config
::getInstance();
341 if (!array_key_exists($config->get('champ_identite'), $champs))
343 throw new UserException('Le champ '.$config->get('champ_identite')
344 .' est défini comme identité des membres et ne peut donc être supprimé des fiches membres.');
347 if (!array_key_exists($config->get('champ_identifiant'), $champs))
349 throw new UserException('Le champ '.$config->get('champ_identifiant')
350 .' est défini comme identifiant à la connexion et ne peut donc être supprimé des fiches membres.');
353 foreach ($champs as $name=>&$config)
355 $this->_checkField($name, $config);
358 $this->champs
= $champs;
364 * Enregistre les changements de champs en base de données
365 * @param boolean $enable_copy Recopier les anciennes champs dans les nouveaux ?
366 * @return boolean true
368 public function save($enable_copy = true)
370 $db = DB
::getInstance();
371 $config = Config
::getInstance();
375 'id INTEGER PRIMARY KEY, -- Numéro attribué automatiquement',
376 'id_categorie INTEGER NOT NULL, -- Numéro de catégorie',
377 'date_connexion TEXT NULL, -- Date de dernière connexion',
378 'date_inscription TEXT NOT NULL DEFAULT CURRENT_DATE, -- Date d\'inscription',
382 'FOREIGN KEY (id_categorie) REFERENCES membres_categories (id)'
393 $anciens_champs = $config->get('champs_membres');
394 $anciens_champs = is_null($anciens_champs) ?
$this->champs
: $anciens_champs->getAll();
396 foreach ($this->champs
as $key=>$cfg)
398 if ($cfg['type'] == 'number')
400 elseif ($cfg['type'] == 'multiple' ||
$cfg['type'] == 'checkbox')
402 elseif ($cfg['type'] == 'file')
407 $line = $key . ' ' . $type . ',';
409 if (!empty($cfg['title']))
411 $line .= ' -- ' . str_replace(["\n", "\r"], '', $cfg['title']);
416 if (array_key_exists($key, $anciens_champs))
422 $create = array_merge($create, $create_keys);
424 $create = 'CREATE TABLE membres_tmp (' . "\n\t" . implode("\n\t", $create) . "\n);";
425 $copy = 'INSERT INTO membres_tmp (' . implode(', ', $copy) . ') SELECT ' . implode(', ', $copy) . ' FROM membres;';
427 $db->exec('PRAGMA foreign_keys = OFF;');
435 $db->exec('DROP TABLE IF EXISTS membres;');
436 $db->exec('ALTER TABLE membres_tmp RENAME TO membres;');
437 $db->exec('CREATE INDEX membres_id_categorie ON membres (id_categorie);'); // Index
439 if ($config->get('champ_identifiant'))
441 // Mettre les champs identifiant vides à NULL pour pouvoir créer un index unique
442 $db->exec('UPDATE membres SET '.$config->get('champ_identifiant').' = NULL
443 WHERE '.$config->get('champ_identifiant').' = "";');
445 // Création de l'index unique
446 $db->exec('CREATE UNIQUE INDEX membres_identifiant ON membres ('.$config->get('champ_identifiant').');');
449 // Création des index pour les champs affichés dans la liste des membres
450 $listed_fields = array_keys($this->getListedFields());
451 foreach ($listed_fields as $field)
453 if ($field === $config->get('champ_identifiant'))
455 // Il y a déjà un index
459 $db->exec('CREATE INDEX membres_liste_' . $field . ' ON membres (' . $field . ');');
463 $db->exec('PRAGMA foreign_keys = ON;');
465 $config->set('champs_membres', $this);