Comment: | Merges multiples de corrections dans la branche stable |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | stable | 0.5.9 |
Files: | files | file ages | folders |
SHA1: |
3d710711d820774b664df421ec849c9d |
User & Date: | bohwaz on 2013-09-29 11:27:52 |
Other Links: | manifest | tags |
2013-09-29
| ||
11:50 | Correction pour les sous-appels de la fonction + suppression bidouille instructions sqlite3 check-in: fc0e512052 user: bohwaz tags: stable, 0.5.9 | |
11:27 | Merges multiples de corrections dans la branche stable check-in: 3d710711d8 user: bohwaz tags: stable, 0.5.9 | |
11:17 | Mieux restreindre les noms des champs : pas de majuscules check-in: 5fc9f56a92 user: bohwaz tags: trunk | |
11:17 | Fix [0d764c31f3b0032f00d8f5b541df8f212fac78f8] : toujours utiliser bindvalue pour les paramètres check-in: b5d1b8123b user: bohwaz tags: trunk | |
10:07 | Amélioration ergonomie power-users : possibilité de modifier le champ date sans passer par le calendrier check-in: fbc4d45632 user: bohwaz tags: trunk | |
2013-09-18
| ||
16:57 | ne pas inclure les champs non-éditables/privés dans la vérification pour "mes infos" check-in: 62f1bacccf user: bohwaz tags: trunk | |
16:34 |
| |
16:19 | Correction champs non modifiables qui étaient quand même transmis et donc vérifiés check-in: eb6acee70d user: bohwaz tags: trunk | |
16:14 | Correction "mes infos" : le javascript pour input type=date n'était pas chargé check-in: 07b472ca62 user: bohwaz tags: trunk | |
2013-09-15
| ||
12:34 | Merge: Bugfix: comptes dupliqués si credit ET debit sont != de 0, corrigé avec un SUM+GROUP BY, probablement pas très élégant + Correction format monnaie mal affiché check-in: b64cb36115 user: bohwaz tags: stable, 0.5.8 | |
Modified VERSION from [a3a33376d7] to [6f628ed9b2].
|
| | | 1 | 0.5.9 |
Modified include/class.champs_membres.php from [1616424ebd] to [ca2a050e2f].
︙ | ︙ | |||
275 276 277 278 279 280 281 282 283 284 285 286 287 288 | * Ajouter un nouveau champ * @param string $name Nom du champ * @param array $config Configuration du champ * @return boolean true */ public function add($name, $config) { $this->_checkField($name, $config); $this->champs[$name] = $config; return true; } | > > > > > | 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 | * Ajouter un nouveau champ * @param string $name Nom du champ * @param array $config Configuration du champ * @return boolean true */ public function add($name, $config) { if (!preg_match('!^[a-z0-9]+(_[a-z0-9]+)*$!', $name)) { throw new UserException('Le nom du champ est invalide : ne sont acceptés que des lettres minuscules et chiffres.'); } $this->_checkField($name, $config); $this->champs[$name] = $config; return true; } |
︙ | ︙ |
Modified include/class.db.php from [ef3d2d44df] to [5164eaa4a3].
︙ | ︙ | |||
52 53 54 55 56 57 58 59 60 61 62 63 64 65 | if ($create) { $flags |= SQLITE3_OPEN_CREATE; } parent::__construct(GARRADIN_DB_FILE, $flags); // Activer les contraintes des foreign keys $this->exec('PRAGMA foreign_keys = ON;'); $this->createFunction('transliterate_to_ascii', array('Garradin\utils', 'transliterateToAscii')); $this->createFunction('base64', 'base64_encode'); $this->createFunction('rank', array($this, 'sql_rank')); | > > | 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | if ($create) { $flags |= SQLITE3_OPEN_CREATE; } parent::__construct(GARRADIN_DB_FILE, $flags); $this->enableExceptions(true); // Activer les contraintes des foreign keys $this->exec('PRAGMA foreign_keys = ON;'); $this->createFunction('transliterate_to_ascii', array('Garradin\utils', 'transliterateToAscii')); $this->createFunction('base64', 'base64_encode'); $this->createFunction('rank', array($this, 'sql_rank')); |
︙ | ︙ | |||
167 168 169 170 171 172 173 | } public function simpleStatement($query, $args = array()) { $statement = $this->prepare($query); $nb = $statement->paramCount(); | < < < < < < | < < < < < < < < < < < | | | > > > | > > > > > > > > > > > > > > > > > > > | 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 | } public function simpleStatement($query, $args = array()) { $statement = $this->prepare($query); $nb = $statement->paramCount(); if (!empty($args)) { if (count($args) != $nb) { throw new \LengthException('Only '.count($args).' arguments, but '.$nb.' are required by query.'); } reset($args); if (is_int(key($args))) { foreach ($args as $i=>$arg) { $statement->bindValue((int)$i+1, $arg, $this->_getArgType($arg, $i+1)); } } else { foreach ($args as $key=>$value) { if (is_int($key)) { throw new \InvalidArgumentException(__FUNCTION__ . ' requires argument to be a named-associative array, but key '.$key.' is an integer.'); } $statement->bindValue(':'.$key, $value, $this->_getArgType($value, $key)); } } } try { return $statement->execute(); } catch (\Exception $e) { throw new \Exception($e->getMessage() . "\n" . $query); } } public function simpleStatementFetch($query, $mode = SQLITE3_BOTH) { if ($mode != SQLITE3_BOTH && $mode != SQLITE3_ASSOC && $mode != SQLITE3_NUM) { throw new \InvalidArgumentException('Mode argument should be either SQLITE3_BOTH, SQLITE3_ASSOC or SQLITE3_NUM.'); |
︙ | ︙ | |||
248 249 250 251 252 253 254 255 | case SQLITE3_TEXT: return '\'' . $this->escapeString($value) . '\''; case SQLITE3_INSTRUCTION: return (string) $value; } } /** | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | | < | < < | | | < < | > | | < < < | | | < > < < | | 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 | case SQLITE3_TEXT: return '\'' . $this->escapeString($value) . '\''; case SQLITE3_INSTRUCTION: return (string) $value; } } /** * Simple INSERT query */ public function simpleInsert($table, $fields) { $fields_names = array_keys($fields); return $this->simpleStatement('INSERT INTO '.$table.' ('.implode(', ', $fields_names).') VALUES (:'.implode(', :', $fields_names).');', $fields); } public function simpleUpdate($table, $fields, $where) { $query = 'UPDATE '.$table.' SET '; foreach ($fields as $key=>$value) { $query .= $key . ' = :'.$key.', '; } $query = substr($query, 0, -2); $query .= ' WHERE '.$where.';'; return $this->simpleStatement($query, $fields); } /** * Formats and escapes a statement and then returns the result of exec() */ public function simpleExec($query) { return $this->simpleStatement($query, array_slice(func_get_args(), 1)); } public function simpleQuerySingle($query, $all_columns = false) { $res = $this->simpleStatement($query, array_slice(func_get_args(), 2)); $row = $res->fetchArray($all_columns ? SQLITE3_ASSOC : SQLITE3_NUM); if (!$all_columns) { if (isset($row[0])) return $row[0]; return false; } else { return $row; } } public function queryFetch($query, $mode = SQLITE3_BOTH) { return $this->_fetchResult($this->query($query), $mode); } |
︙ | ︙ |
Modified include/class.membres.php from [ff3b0c8181] to [d08935a6ae].
︙ | ︙ | |||
37 38 39 40 41 42 43 | protected function _sessionStart($force = false) { if (!isset($_SESSION) && ($force || isset($_COOKIE[session_name()]))) { session_start(); } | < < < < < < < < < < | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | protected function _sessionStart($force = false) { if (!isset($_SESSION) && ($force || isset($_COOKIE[session_name()]))) { session_start(); } return true; } public function keepSessionAlive() { $this->_sessionStart(true); } |
︙ | ︙ | |||
235 236 237 238 239 240 241 | } return utils::mail($dest, $sujet, $message, array('From' => $from)); } // Gestion des données /////////////////////////////////////////////////////// | | > > > > > > | > | | 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 | } return utils::mail($dest, $sujet, $message, array('From' => $from)); } // Gestion des données /////////////////////////////////////////////////////// public function _checkFields(&$data, $check_editable = true, $check_password = true) { $champs = Config::getInstance()->get('champs_membres'); foreach ($champs->getAll() as $key=>$config) { if (!$check_editable && (!empty($config['private']) || empty($config['editable']))) { unset($data[$key]); continue; } if (!isset($data[$key]) || (!is_array($data[$key]) && trim($data[$key]) == '') || (is_array($data[$key]) && empty($data[$key]))) { if (!empty($config['mandatory']) && ($check_password || $key != 'passe')) { throw new UserException('Le champ "' . $config['title'] . '" doit obligatoirement être renseigné.'); } elseif (!empty($config['mandatory'])) { continue; } |
︙ | ︙ | |||
328 329 330 331 332 333 334 | { throw new UserException('Le mot de passe doit faire au moins 5 caractères.'); } return true; } | | | | 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 | { throw new UserException('Le mot de passe doit faire au moins 5 caractères.'); } return true; } public function add($data = array()) { $this->_checkFields($data); $db = DB::getInstance(); if (!empty($data['email']) && $db->simpleQuerySingle('SELECT 1 FROM membres WHERE email = ? LIMIT 1;', false, $data['email'])) { throw new UserException('Cette adresse e-mail est déjà utilisée par un autre membre, il faut en choisir une autre.'); } |
︙ | ︙ | |||
357 358 359 360 361 362 363 | $data['id_categorie'] = Config::getInstance()->get('categorie_membres'); } $db->simpleInsert('membres', $data); return $db->lastInsertRowId(); } | | | | 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 | $data['id_categorie'] = Config::getInstance()->get('categorie_membres'); } $db->simpleInsert('membres', $data); return $db->lastInsertRowId(); } public function edit($id, $data = array(), $check_editable = true) { $db = DB::getInstance(); if (isset($data['id']) && ($data['id'] == $id || empty($data['id']))) { unset($data['id']); } $this->_checkFields($data, $check_editable, false); if (!empty($data['email']) && $db->simpleQuerySingle('SELECT 1 FROM membres WHERE email = ? AND id != ? LIMIT 1;', false, $data['email'], (int)$id)) { throw new UserException('Cette adresse e-mail est déjà utilisée par un autre membre, il faut en choisir une autre.'); } |
︙ | ︙ |
Modified include/data/champs_membres.ini from [5dac66666b] to [c3b46c317e].
︙ | ︙ | |||
123 124 125 126 127 128 129 | editable = true [notes] type = textarea title = "Notes" editable = false private = true | < < < < < < < | 123 124 125 126 127 128 129 | editable = true [notes] type = textarea title = "Notes" editable = false private = true |
Modified templates/admin/membres/ajouter.tpl from [dcd2170a7b] to [81028f0bc4].
︙ | ︙ | |||
8 9 10 11 12 13 14 | <form method="post" action="{$self_url|escape}"> <fieldset> <legend>Informations personnelles</legend> <dl> {foreach from=$champs item="champ" key="nom"} | | | < < | 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 | <form method="post" action="{$self_url|escape}"> <fieldset> <legend>Informations personnelles</legend> <dl> {foreach from=$champs item="champ" key="nom"} {html_champ_membre config=$champ name=$nom} {/foreach} </dl> </fieldset> <fieldset> <legend>Connexion</legend> <dl> <dt><label for="f_passe">Mot de passe</label>{if $champs.passe.mandatory} <b title="(Champ obligatoire)">obligatoire</b>{/if}</dt> <dd class="help"> Pas d'idée ? Voici une suggestion choisie au hasard : <tt title="Cliquer pour utiliser cette suggestion comme mot de passe" onclick="fillPassword(this);">{$passphrase|escape}</tt> </dd> <dd><input type="password" name="passe" id="f_passe" value="{form_field name=passe}" /></dd> <dt><label for="f_repasse">Encore le mot de passe</label> (vérification)</dt> <dd><input type="password" name="repasse" id="f_repasse" value="{form_field name=repasse}" /></dd> </dl> </fieldset> {if $user.droits.membres == Garradin\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> |
︙ | ︙ |
Modified templates/admin/membres/modifier.tpl from [2bf0b6d82e] to [db1056f78d].
︙ | ︙ | |||
12 13 14 15 16 17 18 | <legend>Informations personnelles</legend> <dl> {if $user.droits.membres == Garradin\Membres::DROIT_ADMIN} <dt><label for="f_id">Numéro de membre</label> <b title="(Champ obligatoire)">obligatoire</b></dt> <dd><input type="text" name="id" id="f_id" value="{form_field data=$membre name=id}" /></dd> {/if} {foreach from=$champs item="champ" key="nom"} | | | < < | 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 | <legend>Informations personnelles</legend> <dl> {if $user.droits.membres == Garradin\Membres::DROIT_ADMIN} <dt><label for="f_id">Numéro de membre</label> <b title="(Champ obligatoire)">obligatoire</b></dt> <dd><input type="text" name="id" id="f_id" value="{form_field data=$membre name=id}" /></dd> {/if} {foreach from=$champs item="champ" key="nom"} {html_champ_membre config=$champ name=$nom data=$membre} {/foreach} </dl> </fieldset> <fieldset> <legend>{if $membre.passe}Changer le mot de passe{else}Choisir un mot de passe{/if}</legend> <dl> {if $membre.passe} <dd>Ce membre a déjà un mot de passe, mais vous pouvez le changer si besoin.</dd> {else} <dd>Ce membre n'a pas encore de mot de passe et ne peut donc se connecter.</dd> {/if} <dt><label for="f_passe">Nouveau mot de passe</label>{if $champs.passe.mandatory} <b title="(Champ obligatoire)">obligatoire</b>{/if}</dt> <dd class="help"> Pas d'idée ? Voici une suggestion choisie au hasard : <tt title="Cliquer pour utiliser cette suggestion comme mot de passe" onclick="fillPassword(this);">{$passphrase|escape}</tt> </dd> <dd><input type="password" name="passe" id="f_passe" value="{form_field name=passe}" /></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="repasse" id="f_repasse" value="{form_field name=repasse}" /></dd> </dl> </fieldset> {if $user.droits.membres == Garradin\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> |
︙ | ︙ |
Modified www/admin/membres/ajouter.php from [29152d95e3] to [33afea54dd].
︙ | ︙ | |||
39 40 41 42 43 44 45 | $data = array('id_categorie' => $id_categorie); foreach ($champs->getAll() as $key=>$dismiss) { $data[$key] = utils::post($key); } | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | $data = array('id_categorie' => $id_categorie); foreach ($champs->getAll() as $key=>$dismiss) { $data[$key] = utils::post($key); } $id = $membres->add($data); utils::redirect('/admin/membres/fiche.php?id='.(int)$id); } catch (UserException $e) { $error = $e->getMessage(); } |
︙ | ︙ |
Modified www/admin/membres/modifier.php from [703c696499] to [aac2e3e942].
︙ | ︙ | |||
48 49 50 51 52 53 54 | else { try { $data = array(); foreach ($champs->getAll() as $key=>$config) { | < < < < < < | | 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | else { try { $data = array(); foreach ($champs->getAll() as $key=>$config) { $data[$key] = utils::post($key); } if ($user['droits']['membres'] == Membres::DROIT_ADMIN) { $data['id_categorie'] = utils::post('id_categorie'); $data['id'] = utils::post('id'); } $membres->edit($id, $data); utils::redirect('/admin/membres/fiche.php?id='.(int)$id); } catch (UserException $e) { $error = $e->getMessage(); } |
︙ | ︙ |
Modified www/admin/mes_infos.php from [e52bd07e77] to [0c7b4daab6].
︙ | ︙ | |||
24 25 26 27 28 29 30 31 32 33 | } else { try { $data = array(); foreach ($config->get('champs_membres')->getAll() as $key=>$c) { $data[$key] = utils::post($key); } | > > | > | > > | 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 | } else { try { $data = array(); foreach ($config->get('champs_membres')->getAll() as $key=>$c) { if (!empty($c['editable'])) { $data[$key] = utils::post($key); } } $membres->edit($membre['id'], $data, false); $membres->updateSessionData(); utils::redirect('/admin/'); } catch (UserException $e) { $error = $e->getMessage(); } } } $tpl->assign('error', $error); $tpl->assign('passphrase', utils::suggestPassword()); $tpl->assign('champs', $config->get('champs_membres')->getAll()); $tpl->assign('membre', $membre); $tpl->assign('custom_js', array('datepickr.js')); $tpl->display('admin/mes_infos.tpl'); ?> |
Modified www/admin/static/datepickr.js from [ac4e850f0a] to [0eef8662ba].
︙ | ︙ | |||
419 420 421 422 423 424 425 | for (i = 0; i < inputs.length; i++) { if (inputs[i].getAttribute('type') == 'date' && (inputs[i].type == 'text' || window.webkitConvertPointFromNodeToPage)) { inputs[i].setAttribute('type', 'text'); new datepickr(inputs[i], config_fr); | | | 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 | for (i = 0; i < inputs.length; i++) { if (inputs[i].getAttribute('type') == 'date' && (inputs[i].type == 'text' || window.webkitConvertPointFromNodeToPage)) { inputs[i].setAttribute('type', 'text'); new datepickr(inputs[i], config_fr); inputs[i].setAttribute('pattern', '[0-9]{4}-[0-9]{2}-[0-9]{2}'); enabled = true; } } if (enabled) { var scripts = document.head.getElementsByTagName('script'); |
︙ | ︙ |