Overview
Comment:Correction de bugs en pagaille pour les champs membres + gestion dynamique des options pour select et multiple
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 9dbb21bd788315f2c41bd4903f522ac382cc091c
User & Date: bohwaz on 2013-01-31 16:25:50
Other Links: manifest | tags
Context
2013-01-31
16:33
Ne pas faire de recherche quand on ne cherche rien + utilisation correcte de trim grumpf check-in: 6fc285dd46 user: bohwaz tags: trunk
16:25
Correction de bugs en pagaille pour les champs membres + gestion dynamique des options pour select et multiple check-in: 9dbb21bd78 user: bohwaz tags: trunk
2013-01-30
17:01
Affichage du champ correctement plutôt que de manière brute dans les listes check-in: 84bf6d7579 user: bohwaz tags: trunk
Changes

Modified include/class.champs_membres.php from [2773639a9f] to [65d032fca6].

241
242
243
244
245
246
247
248





249
250
251
252
253
254
255
        if ($name == 'email' && $config['type'] != 'email')
        {
            throw new UserException('Le champ email ne peut être d\'un type différent de email.');
        }

        if ($name == 'passe' && $config['type'] != 'password')
        {
            throw new UserException('Le champ mot de passe ne peut être d\'un type différent de email.');





        }

        if (!array_key_exists('editable', $config))
        {
            $config['editable'] = false;
        }








|
>
>
>
>
>







241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
        if ($name == 'email' && $config['type'] != 'email')
        {
            throw new UserException('Le champ email ne peut être d\'un type différent de email.');
        }

        if ($name == 'passe' && $config['type'] != 'password')
        {
            throw new UserException('Le champ mot de passe ne peut être d\'un type différent de mot de passe.');
        }

        if (($config['type'] == 'multiple' || $config['type'] == 'select') && empty($config['options']))
        {
            throw new UserException('Le champ "'.$name.'" nécessite de comporter au moins une option possible.');
        }

        if (!array_key_exists('editable', $config))
        {
            $config['editable'] = false;
        }

335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
    {
    	$db = DB::getInstance();
    	//$config
    }

    /**
     * Enregistre les changements de champs en base de données
     * @param  boolean $copy Recopier les anciennes champs dans les nouveaux ?
     * @return boolean true
     */
    public function save($copy = true)
    {
    	$db = DB::getInstance();
    	$config = Config::getInstance();

    	// Champs à créer
    	$create = array(
    		'id INTEGER PRIMARY KEY, -- Numéro attribué automatiquement',







|


|







340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
    {
    	$db = DB::getInstance();
    	//$config
    }

    /**
     * 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 = array(
    		'id INTEGER PRIMARY KEY, -- Numéro attribué automatiquement',
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
    	$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 ($copy) {
    		$db->exec($copy);
    	}
    	
    	$db->exec('DROP TABLE membres;');
    	$db->exec('ALTER TABLE membres_tmp RENAME TO membres;');
        $db->exec('CREATE INDEX membres_id_categorie ON membres (id_categorie);'); // Index
    	$db->exec('END;');
    	$db->exec('PRAGMA foreign_keys = ON;');

    	$config->set('champs_membres', $this);
    	$config->save();

    	return true;
    }
}

?>







|



|













410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
    	$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
    	$db->exec('END;');
    	$db->exec('PRAGMA foreign_keys = ON;');

    	$config->set('champs_membres', $this);
    	$config->save();

    	return true;
    }
}

?>

Modified include/class.db.php from [f7a224e087] to [ef3d2d44df].

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
61
62
63
64
65
66
67
68
69
70
71

class DB extends \SQLite3
{
    static protected $_instance = null;

    protected $_running_sum = 0.0;

    static public function getInstance()
    {
        return self::$_instance ?: self::$_instance = new DB;
    }

    private function __clone()
    {
    }

    public function __construct()
    {

        $exists = file_exists(GARRADIN_DB_FILE) ? true : false;





        parent::__construct(GARRADIN_DB_FILE, SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE);

        // Activer les contraintes des foreign keys
        $this->exec('PRAGMA foreign_keys = ON;');

        if (!$exists)
        {
            $this->exec('BEGIN;');
            $this->exec(file_get_contents(GARRADIN_DB_SCHEMA));
            $this->exec('END;');
        }

        $this->createFunction('transliterate_to_ascii', array('Garradin\utils', 'transliterateToAscii'));
        $this->createFunction('base64', 'base64_encode');
        $this->createFunction('rank', array($this, 'sql_rank'));
        $this->createFunction('running_sum', array($this, 'sql_running_sum'));
    }

    public function sql_running_sum($data)







|

|






|

>
|
>
|
>
>
>
|




<
<
<
<
<
<
<







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
61
62







63
64
65
66
67
68
69

class DB extends \SQLite3
{
    static protected $_instance = null;

    protected $_running_sum = 0.0;

    static public function getInstance($create = false)
    {
        return self::$_instance ?: self::$_instance = new DB($create);
    }

    private function __clone()
    {
    }

    public function __construct($create = false)
    {
        $flags = SQLITE3_OPEN_READWRITE;

        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'));
        $this->createFunction('running_sum', array($this, 'sql_running_sum'));
    }

    public function sql_running_sum($data)

Modified include/class.membres.php from [8772e65aac] to [f7d52f6be3].

61
62
63
64
65
66
67
68
69
70
71
72
73
74
75

    public function login($email, $passe)
    {
        if (!filter_var($email, FILTER_VALIDATE_EMAIL))
            return false;

        $db = DB::getInstance();
        $r = $db->simpleQuerySingle('SELECT * FROM membres WHERE email = ? LIMIT 1;', true, trim($email));

        if (empty($r))
            return false;

        if (!$this->_checkPassword(trim($passe), $r['passe']))
            return false;








|







61
62
63
64
65
66
67
68
69
70
71
72
73
74
75

    public function login($email, $passe)
    {
        if (!filter_var($email, FILTER_VALIDATE_EMAIL))
            return false;

        $db = DB::getInstance();
        $r = $db->simpleQuerySingle('SELECT *, strftime(\'%s\', date_cotisation) AS date_cotisation FROM membres WHERE email = ? LIMIT 1;', true, trim($email));

        if (empty($r))
            return false;

        if (!$this->_checkPassword(trim($passe), $r['passe']))
            return false;

241
242
243
244
245
246
247


248
249
250
251

252

253
254
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

    public function _checkFields(&$data, $check_mandatory = true)
    {
        $champs = Config::getInstance()->get('champs_membres');

        foreach ($champs->getAll() as $key=>$config)
        {


            if (!empty($config['mandatory']) && (!isset($data[$key]) || !trim($data[$key])))
            {
                if ($check_mandatory)
                    throw new UserException('Le champ "' . $config['title'] . '" doit obligatoirement être renseigné.');

                else

                    continue;
            }




            if ($config['type'] == 'email' && !filter_var($data[$key], FILTER_VALIDATE_EMAIL))
            {
                throw new UserException('Adresse e-mail invalide dans le champ "' . $config['title'] . '".');
            }
            elseif ($config['type'] == 'url' && !filter_var($data[$key], FILTER_VALIDATE_URL))
            {
                throw new UserException('Adresse URL invalide dans le champ "' . $config['title'] . '".');
            }
            elseif ($config['type'] == 'tel')
            {
                $data[$key] = preg_replace('![^\d\+]!', '', $data[$key]);
            }
            elseif ($config['type'] == 'country')
            {
                $data[$key] = strtoupper(substr($data[$key], 0, 2));
            }
            elseif ($config['type'] == 'checkbox')
            {
                $data[$key] = empty($data[$key]) ? 0 : 1;
            }
            elseif ($config['type'] == 'number')
            {
                if (empty($data[$key]))
                {
                    $data[$key] = 0;
                }

                if (!is_numeric($data[$key]))
                    throw new UserException('Le champ "' . $config['title'] . '" doit contenir un chiffre.');
            }
            elseif ($config['type'] == 'select' && !in_array($data[$key], $config['options']))
            {
                throw new UserException('Le champ "' . $config['title'] . '" ne correspond pas à un des choix proposés.');
            }
            elseif ($config['type'] == 'multiple')
            {
                if (empty($data[$key]) || !is_array($data[$key]))
                {
                    $data[$key] = 0;
                    continue;
                }

                $binary = 0;

                foreach ($data[$key] as $k => $v)
                {
                    if (array_key_exists($k, $config['options']) && !empty($v))
                    {
                        $binary |= 0x01 << $k;
                    }
                }

                $data[$key] = $binary;

            }
        }

        if (!empty($data['code_postal']))
        {
            if (!empty($data['pays']) && $data['pays'] == 'FR' && !preg_match('!^\d{5}$!', $data['code_postal']))
            {







>
>
|
|
<

>
|
>

|
|
>
>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|

|

|
|
|
|
|
|
|

|
>







241
242
243
244
245
246
247
248
249
250
251

252
253
254
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
316
317
318
319
320
321
322

    public function _checkFields(&$data, $check_mandatory = true)
    {
        $champs = Config::getInstance()->get('champs_membres');

        foreach ($champs->getAll() as $key=>$config)
        {
            if (!isset($data[$key]) || empty($data[$key]) || (!is_array($data[$key]) && !trim($data[$key])))
            {
                if (!empty($config['mandatory']) && $check_mandatory)
                {

                    throw new UserException('Le champ "' . $config['title'] . '" doit obligatoirement être renseigné.');
                }
                elseif (!empty($config['mandatory']))
                {
                    continue;
                }
            }

            if (isset($data[$key]))
            {
                if ($config['type'] == 'email' && !filter_var($data[$key], FILTER_VALIDATE_EMAIL))
                {
                    throw new UserException('Adresse e-mail invalide dans le champ "' . $config['title'] . '".');
                }
                elseif ($config['type'] == 'url' && !filter_var($data[$key], FILTER_VALIDATE_URL))
                {
                    throw new UserException('Adresse URL invalide dans le champ "' . $config['title'] . '".');
                }
                elseif ($config['type'] == 'tel')
                {
                    $data[$key] = preg_replace('![^\d\+]!', '', $data[$key]);
                }
                elseif ($config['type'] == 'country')
                {
                    $data[$key] = strtoupper(substr($data[$key], 0, 2));
                }
                elseif ($config['type'] == 'checkbox')
                {
                    $data[$key] = empty($data[$key]) ? 0 : 1;
                }
                elseif ($config['type'] == 'number')
                {
                    if (empty($data[$key]))
                    {
                        $data[$key] = 0;
                    }

                    if (!is_numeric($data[$key]))
                        throw new UserException('Le champ "' . $config['title'] . '" doit contenir un chiffre.');
                }
                elseif ($config['type'] == 'select' && !in_array($data[$key], $config['options']))
                {
                    throw new UserException('Le champ "' . $config['title'] . '" ne correspond pas à un des choix proposés.');
                }
                elseif ($config['type'] == 'multiple')
                {
                    if (empty($data[$key]) || !is_array($data[$key]))
                    {
                        $data[$key] = 0;
                        continue;
                    }

                    $binary = 0;

                    foreach ($data[$key] as $k => $v)
                    {
                        if (array_key_exists($k, $config['options']) && !empty($v))
                        {
                            $binary |= 0x01 << $k;
                        }
                    }

                    $data[$key] = $binary;
                }
            }
        }

        if (!empty($data['code_postal']))
        {
            if (!empty($data['pays']) && $data['pays'] == 'FR' && !preg_match('!^\d{5}$!', $data['code_postal']))
            {
408
409
410
411
412
413
414
415

416
417
418
419
420
421
422
    }

    public function get($id)
    {
        $db = DB::getInstance();
        return $db->simpleQuerySingle('SELECT *,
            strftime(\'%s\', date_cotisation) AS date_cotisation,
            strftime(\'%s\', date_inscription) AS date_inscription

            FROM membres WHERE id = ? LIMIT 1;', true, (int)$id);
    }

    public function delete($ids)
    {
        if (!is_array($ids))
        {







|
>







415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
    }

    public function get($id)
    {
        $db = DB::getInstance();
        return $db->simpleQuerySingle('SELECT *,
            strftime(\'%s\', date_cotisation) AS date_cotisation,
            strftime(\'%s\', date_inscription) AS date_inscription,
            strftime(\'%s\', date_connexion) AS date_connexion
            FROM membres WHERE id = ? LIMIT 1;', true, (int)$id);
    }

    public function delete($ids)
    {
        if (!is_array($ids))
        {

Modified include/data/schema.sql from [97f6a904bb] to [7f4e107406].

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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77

CREATE TABLE membres_categories
-- Catégories de membres
(
    id INTEGER PRIMARY KEY,
    nom TEXT,
    description TEXT,


    droit_wiki INT DEFAULT 1,
    droit_membres INT DEFAULT 1,
    droit_compta INT DEFAULT 1,
    droit_inscription INT DEFAULT 0,
    droit_connexion INT DEFAULT 1,
    droit_config INT DEFAULT 0,
    cacher INT DEFAULT 0,

    id_transaction_obligatoire INTEGER NULL,

    FOREIGN KEY (id_transaction_obligatoire) REFERENCES transactions (id)
);


-- Membres de l'asso

-- Voir class.champs_membres.php

-- Paiements possibles
CREATE TABLE transactions
(
    id INTEGER PRIMARY KEY,
    id_categorie_compta INTEGER NULL, -- NULL si le type n'est pas associé automatiquement à la compta

    intitule TEXT NOT NULL,
    description TEXT NOT NULL,
    montant REAL NOT NULL,

    duree INTEGER NULL,
    debut TEXT NULL,
    fin TEXT NULL,

    rappel_expiration INTEGER NULL DEFAULT 0, -- 1 si envoi de rappel avant expiration

    FOREIGN KEY (id_categorie_compta) REFERENCES compta_categories (id)
);

-- Paiements enregistrés
CREATE TABLE membres_transactions
(
    id_membre INTEGER NOT NULL,
    id_transaction INTEGER NOT NULL,
    id_operation INTEGER NULL,

    libelle TEXT NULL,

    date TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
    montant REAL NOT NULL,

    FOREIGN KEY (id_membre) REFERENCES membres (id),
    FOREIGN KEY (id_transaction) REFERENCES transactions (id),
    FOREIGN KEY (id_operation) REFERENCES compta_journal (id)
);

--
-- WIKI
--

CREATE TABLE wiki_pages
-- Pages du wiki







|
>






|
<
<
<
<




>
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







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

CREATE TABLE membres_categories
-- Catégories de membres
(
    id INTEGER PRIMARY KEY,
    nom TEXT,
    description TEXT,
    montant_cotisation REAL,
    duree_cotisation INTEGER DEFAULT 12, -- En mois
    droit_wiki INT DEFAULT 1,
    droit_membres INT DEFAULT 1,
    droit_compta INT DEFAULT 1,
    droit_inscription INT DEFAULT 0,
    droit_connexion INT DEFAULT 1,
    droit_config INT DEFAULT 0,
    cacher INT DEFAULT 0




);


-- Membres de l'asso
-- Table dynamique générée par l'application
-- voir class.champs_membres.php





































--
-- WIKI
--

CREATE TABLE wiki_pages
-- Pages du wiki

Modified include/lib.template.php from [841646802c] to [1298a5c695].

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

        $this->assign('is_logged', false);
    }
}

$tpl = Template::getInstance();

$tpl->assign('config', Config::getInstance()->getConfig());

function tpl_csrf_field($params)
{
    $name = utils::CSRF_field_name($params['key']);
    $value = utils::CSRF_create($params['key']);

    return '<input type="hidden" name="'.$name.'" value="'.$value.'" />';
}







<
<







35
36
37
38
39
40
41


42
43
44
45
46
47
48

        $this->assign('is_logged', false);
    }
}

$tpl = Template::getInstance();



function tpl_csrf_field($params)
{
    $name = utils::CSRF_field_name($params['key']);
    $value = utils::CSRF_create($params['key']);

    return '<input type="hidden" name="'.$name.'" value="'.$value.'" />';
}
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
    elseif ($type == 'multiple')
    {
        foreach ($config['options'] as $k=>$v)
        {
            $b = 0x01 << (int)$k;
            $field .= '<label><input type="checkbox" name="' 
                . htmlspecialchars($params['name'], ENT_QUOTES, 'UTF-8') . '[' . (int)$k . ']" value="1" '
                . (($value & $b) ? 'checked="checked"' : '') . ' /> ' 
                . htmlspecialchars($v, ENT_QUOTES, 'UTF-8') . '</label><br />';
        }
    }
    elseif ($type == 'textarea')
    {
        $field .= '<textarea ' . $attributes . 'cols="30" rows="5">' . $value . '</textarea>';
    }







|







428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
    elseif ($type == 'multiple')
    {
        foreach ($config['options'] as $k=>$v)
        {
            $b = 0x01 << (int)$k;
            $field .= '<label><input type="checkbox" name="' 
                . htmlspecialchars($params['name'], ENT_QUOTES, 'UTF-8') . '[' . (int)$k . ']" value="1" '
                . (($value & $b) ? 'checked="checked"' : '') . ' ' . $attributes . '/> ' 
                . htmlspecialchars($v, ENT_QUOTES, 'UTF-8') . '</label><br />';
        }
    }
    elseif ($type == 'textarea')
    {
        $field .= '<textarea ' . $attributes . 'cols="30" rows="5">' . $value . '</textarea>';
    }

Modified templates/admin/config/membres.tpl from [f5d0be5f0d] to [eb401f2a70].

89
90
91
92
93
94
95

96
97
98
99
100
101
102
    </fieldset>

    {if !empty($presets)}
    <fieldset>
        <legend>Ajouter un champ pré-défini</legend>
        <p>
            <select name="preset">

                {foreach from=$presets key="name" item="preset"}
                <option value="{$name|escape}">{$name|escape} &mdash; {$preset.title|escape}</option>
                {/foreach}
            </select>
            <input type="submit" name="add" value="Ajouter ce champ à la fiche membre" />
        </p>
    </fieldset>







>







89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
    </fieldset>

    {if !empty($presets)}
    <fieldset>
        <legend>Ajouter un champ pré-défini</legend>
        <p>
            <select name="preset">
                <option></option>
                {foreach from=$presets key="name" item="preset"}
                <option value="{$name|escape}">{$name|escape} &mdash; {$preset.title|escape}</option>
                {/foreach}
            </select>
            <input type="submit" name="add" value="Ajouter ce champ à la fiche membre" />
        </p>
    </fieldset>
144
145
146
147
148
149
150


151
152
153
154
155
156
157
158
159
160
161

162
163
164
165
166
167
168
                    <dt><label>Options disponibles</label></dt>
                    {if $champ.type == 'multiple'}
                        <dd class="help">Attention changer l'ordre des options peut avoir des effets indésirables.</dd>
                    {else}
                        <dd class="help">Attention renommer ou supprimer une option n'affecte pas ce qui a déjà
                            été enregistré dans les fiches des membres.</dd>
                    {/if}


                    {if !empty($champ.options)}
                        {foreach from=$champ.options key="key" item="opt"}
                            <dd>{if $champ.type == 'multiple'}{math a=$key equation="a+1"}. {/if}<input type="text" name="champs[{$nom|escape}][options][{$key|escape}]" value="{$opt|escape}" size="50" /></dd>
                        {/foreach}
                        {assign var="more" value=$champ.options|@count}
                    {else}
                        {assign var="more" value=0}
                    {/if}
                    {if $champ.type == 'select' || $more < 32}
                        <dd>{if $champ.type == 'multiple'}{math a=$more equation="a+1"}. {/if}<input type="text" name="champs[{$nom|escape}][options][{$more|escape}]" value="" size="50" /></dd>
                    {/if}

                {/if}
                <dt><label for="f_list_row">Numéro de colonne dans la liste des membres</label></dt>
                <dd class="help">Laisser vide ou indiquer le chiffre zéro pour que ce champ n'apparaisse pas dans la liste des membres. Inscrire un chiffre entre 1 et 10 pour indiquer l'ordre d'affichage du champ dans le tableau de la liste des membres.</dd>
                <dd><input type="number" id="f_list_row" name="champs[{$nom|escape}][list_row]" min="0" max="10" value="{form_field data=$champs[$nom] name=list_row}" /></dd>
            </dl>
        </fieldset>
        {/foreach}







>
>
|
|
|
|
<
<
<
|
|
|
|
>







145
146
147
148
149
150
151
152
153
154
155
156
157



158
159
160
161
162
163
164
165
166
167
168
169
                    <dt><label>Options disponibles</label></dt>
                    {if $champ.type == 'multiple'}
                        <dd class="help">Attention changer l'ordre des options peut avoir des effets indésirables.</dd>
                    {else}
                        <dd class="help">Attention renommer ou supprimer une option n'affecte pas ce qui a déjà
                            été enregistré dans les fiches des membres.</dd>
                    {/if}
                    <dd>
                        <{if $champ.type == 'multiple'}ol{else}ul{/if} class="options">
                        {if !empty($champ.options)}
                            {foreach from=$champ.options key="key" item="opt"}
                                <li><input type="text" name="champs[{$nom|escape}][options][]" value="{$opt|escape}" size="50" /></li>
                            {/foreach}



                        {/if}
                        {if $champ.type == 'select' || empty($champ.options) || count($champ.options) < 32}
                            <li><input type="text" name="champs[{$nom|escape}][options][]" value="" size="50" /></li>
                        {/if}
                    </dd>
                {/if}
                <dt><label for="f_list_row">Numéro de colonne dans la liste des membres</label></dt>
                <dd class="help">Laisser vide ou indiquer le chiffre zéro pour que ce champ n'apparaisse pas dans la liste des membres. Inscrire un chiffre entre 1 et 10 pour indiquer l'ordre d'affichage du champ dans le tableau de la liste des membres.</dd>
                <dd><input type="number" id="f_list_row" name="champs[{$nom|escape}][list_row]" min="0" max="10" value="{form_field data=$champs[$nom] name=list_row}" /></dd>
            </dl>
        </fieldset>
        {/foreach}
285
286
287
288
289
290
291



















































292
293
294
295
296
297
298
            if (content.style.display.toLowerCase() == 'none')
                content.style.display = 'block';
            else
                content.style.display = 'none';
            return false;
        };
        actions.appendChild(edit);



















































    }
}());
{/literal}
</script>
{/if}

{include file="admin/_foot.tpl"}







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
            if (content.style.display.toLowerCase() == 'none')
                content.style.display = 'block';
            else
                content.style.display = 'none';
            return false;
        };
        actions.appendChild(edit);

        if (field.querySelector('.options'))
        {
            var options = field.querySelectorAll('.options li');
            var options_nb = options.length;

            if (options[0].parentNode.tagName.toLowerCase() == 'ul')
            {
                // champ select
                for (j = 0; j < options_nb; j++)
                {
                    var remove = document.createElement('input');
                    remove.type = 'button';
                    remove.className = 'icn';
                    remove.value = '-';
                    remove.title = 'Enlever cette option';
                    remove.onclick = function (e) {
                        var p = this.parentNode;
                        p.parentNode.removeChild(p);
                    };
                    options[j].appendChild(remove);
                }
            }

            var add = document.createElement('input');
            add.type = 'button';
            add.className = 'icn add';
            add.value = '+';
            add.title = 'Ajouter une option';
            add.onclick = function (e) {
                var p = this.parentNode.parentNode;
                var options = p.querySelectorAll('li');
                var new_option = this.parentNode.cloneNode(true);
                var btn = new_option.querySelector('input.add');
                new_option.getElementsByTagName('input')[0].value = '';

                if (options.length >= 30)
                {
                    new_option.removeChild(btn);
                }
                else
                {
                    btn.onclick = this.onclick;
                }

                p.appendChild(new_option);
                this.parentNode.removeChild(this);
            };

            options[options_nb - 1].appendChild(add);
        }
    }
}());
{/literal}
</script>
{/if}

{include file="admin/_foot.tpl"}

Modified templates/admin/membres/fiche.tpl from [ac17437d3f] to [54cbbe580a].

34
35
36
37
38
39
40




41
42
43
44
45
46
47
            <a href="mailto:{$membre[$c]|escape}">{$membre[$c]|escape}</a>
        {elseif $config.type == 'tel'}
            <a href="tel:{$membre[$c]|escape}">{$membre[$c]|escape|format_tel}</a>
        {elseif $config.type == 'country'}
            {$membre[$c]|get_country_name|escape}
        {elseif $config.type == 'date' || $config.type == 'datetime'}
            {$membre[$c]|format_sqlite_date_to_french}




        {elseif $config.type == 'multiple'}
            <ul>
            {foreach from=$config.options key="b" item="name"}
                {if $membre[$c] & (0x01 << $b)}
                    <li>{$name|escape}</li>
                {/if}
            {/foreach}







>
>
>
>







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
            <a href="mailto:{$membre[$c]|escape}">{$membre[$c]|escape}</a>
        {elseif $config.type == 'tel'}
            <a href="tel:{$membre[$c]|escape}">{$membre[$c]|escape|format_tel}</a>
        {elseif $config.type == 'country'}
            {$membre[$c]|get_country_name|escape}
        {elseif $config.type == 'date' || $config.type == 'datetime'}
            {$membre[$c]|format_sqlite_date_to_french}
        {elseif $c == 'passe'}
            Oui
        {elseif $config.type == 'password'}
            *******
        {elseif $config.type == 'multiple'}
            <ul>
            {foreach from=$config.options key="b" item="name"}
                {if $membre[$c] & (0x01 << $b)}
                    <li>{$name|escape}</li>
                {/if}
            {/foreach}

Modified www/admin/_inc.php from [b7b4d15400] to [1249a3443e].

12
13
14
15
16
17
18

19
20
21
22
23
24
25
26
27
28
29
30
31
if (!defined('GARRADIN_LOGIN_PROCESS'))
{
    if (!$membres->isLogged())
    {
        utils::redirect('/admin/login.php');
    }


    $tpl->assign('is_logged', true);
    $tpl->assign('user', $membres->getLoggedUser());
    $user = $membres->getLoggedUser();

    $tpl->assign('current', '');

    if ($user['droits']['membres'] >= Membres::DROIT_ACCES)
    {
        $tpl->assign('nb_membres', $membres->countAllButHidden());
    }
}

?>







>













12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
if (!defined('GARRADIN_LOGIN_PROCESS'))
{
    if (!$membres->isLogged())
    {
        utils::redirect('/admin/login.php');
    }

    $tpl->assign('config', Config::getInstance()->getConfig());
    $tpl->assign('is_logged', true);
    $tpl->assign('user', $membres->getLoggedUser());
    $user = $membres->getLoggedUser();

    $tpl->assign('current', '');

    if ($user['droits']['membres'] >= Membres::DROIT_ACCES)
    {
        $tpl->assign('nb_membres', $membres->countAllButHidden());
    }
}

?>

Modified www/admin/config/membres.php from [314afb4bc4] to [b2a837546b].

88
89
90
91
92
93
94





95
96
97
98
99
100
101

                    $config = array(
                        'type'  =>  utils::post('new_type'),
                        'title' =>  utils::post('new_title'),
                        'editable'  =>  true,
                        'mandatory' =>  false,
                    );






                    $champs->add($new, $config);
                }

                $membres->sessionStore('champs_membres', (string) $champs);

                utils::redirect('/admin/config/membres.php?added');







>
>
>
>
>







88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106

                    $config = array(
                        'type'  =>  utils::post('new_type'),
                        'title' =>  utils::post('new_title'),
                        'editable'  =>  true,
                        'mandatory' =>  false,
                    );

                    if ($config['type'] == 'select' || $config['type'] == 'multiple')
                    {
                        $config['options'] = array('Première option');
                    }

                    $champs->add($new, $config);
                }

                $membres->sessionStore('champs_membres', (string) $champs);

                utils::redirect('/admin/config/membres.php?added');

Modified www/admin/install.php from [36b266b4e9] to [84f0fd717b].

66
67
68
69
70
71
72







73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
        elseif (utils::post('passe_membre') != utils::post('repasse_membre'))
        {
            $error = 'La vérification ne correspond pas au mot de passe.';
        }
        else
        {
            try {







                // Configuration de base
                $config = Config::getInstance();
                $config->set('nom_asso', utils::post('nom_asso'));
                $config->set('adresse_asso', utils::post('adresse_asso'));
                $config->set('email_asso', utils::post('email_asso'));
                $config->set('site_asso', utils::post('site_asso'));
                $config->set('monnaie', '€');
                $config->set('pays', 'FR');
                $config->set('email_envoi_automatique', utils::post('email_asso'));
                $config->setVersion(garradin_version());

                $champs = Champs_Membres::import();
                $champs->save(false); // Pas de copie car pas de table membres existante

                $config->set('champs_membres', $champs);

                // Création catégories
                $cats = new Membres_Categories;
                $id = $cats->add(array(
                    'nom' => 'Membres actifs',
                    'montant_cotisation' => 10));
                $config->set('categorie_membres', $id);








>
>
>
>
>
>
>











|


<
<







66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93


94
95
96
97
98
99
100
        elseif (utils::post('passe_membre') != utils::post('repasse_membre'))
        {
            $error = 'La vérification ne correspond pas au mot de passe.';
        }
        else
        {
            try {
                $db = DB::getInstance(true);

                // Création de la base de données
                $db->exec('BEGIN;');
                $db->exec(file_get_contents(GARRADIN_DB_SCHEMA));
                $db->exec('END;');

                // Configuration de base
                $config = Config::getInstance();
                $config->set('nom_asso', utils::post('nom_asso'));
                $config->set('adresse_asso', utils::post('adresse_asso'));
                $config->set('email_asso', utils::post('email_asso'));
                $config->set('site_asso', utils::post('site_asso'));
                $config->set('monnaie', '€');
                $config->set('pays', 'FR');
                $config->set('email_envoi_automatique', utils::post('email_asso'));
                $config->setVersion(garradin_version());

                $champs = Champs_Membres::importInstall();
                $champs->save(false); // Pas de copie car pas de table membres existante



                // Création catégories
                $cats = new Membres_Categories;
                $id = $cats->add(array(
                    'nom' => 'Membres actifs',
                    'montant_cotisation' => 10));
                $config->set('categorie_membres', $id);

Modified www/admin/static/admin.css from [40aa565543] to [d685a74b7c].

153
154
155
156
157
158
159




160
161
162
163
164
165
166
fieldset dl dd.tip {
    color: #666;
}

fieldset dl dd {
    padding: 0.2em 0.5em 0.2em 1em;
}





input[type=text], textarea, input[type=password], input[type=email],
input[type=url], input[type=tel], select {
    padding: 0.2em 0.4em;
    font-family: Sans-serif;
    min-width: 20em;
}







>
>
>
>







153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
fieldset dl dd.tip {
    color: #666;
}

fieldset dl dd {
    padding: 0.2em 0.5em 0.2em 1em;
}

fieldset dl dd ol, fieldset dl dd ul {
    margin-left: 1.5em;
}

input[type=text], textarea, input[type=password], input[type=email],
input[type=url], input[type=tel], select {
    padding: 0.2em 0.4em;
    font-family: Sans-serif;
    min-width: 20em;
}
180
181
182
183
184
185
186







187
188
189
190
191
192
193
    min-width: 2em;
}

input[type=submit], input[type=button] {
    padding: 0.3em;
    cursor: pointer;
}








select.large {
    width: 95%;
}

select.large optgroup.niveau_1 {
    background: #333;







>
>
>
>
>
>
>







184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
    min-width: 2em;
}

input[type=submit], input[type=button] {
    padding: 0.3em;
    cursor: pointer;
}

input[type=button].icn {
    font-size: 1.2em;
    font-weight: bold;
    padding: 0 0.3em;
    font-family: "Courier New", Courier, monospace;
}

select.large {
    width: 95%;
}

select.large optgroup.niveau_1 {
    background: #333;