Overview
Comment:Début des champs modifiables et personnalisables
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: b8cd499be09eb53dd5a1cc26ab0c7d55be189ab8
User & Date: bohwaz on 2012-12-23 12:51:32
Other Links: manifest | tags
Context
2012-12-23
13:10
Gestion à l'upgrade/install check-in: 911be190ea user: bohwaz tags: trunk
12:51
Début des champs modifiables et personnalisables check-in: b8cd499be0 user: bohwaz tags: trunk
04:14
Version 0.4.5 check-in: bfc7ed2ec9 user: bohwaz tags: trunk
Changes

Added include/class.champs_membres.php version [9192892681].



































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
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
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
<?php

namespace Garradin;

class Champs_Membres
{
	protected $champs = null;

	protected $types = array(
		'email'		=>	'Adresse E-Mail',
		'url'		=>	'Adresse URL',
		'checkbox'	=>	'Case à cocher',
		'multiple'	=>	'Combinaison de cases à cocher',
		'date'		=>	'Date',
		'datetime'	=>	'Date et heure',
		'file'		=>	'Fichier',
		'number'	=>	'Numéro',
		'tel'		=>	'Numéro de téléphone',
		'select'	=>	'Sélecteur de choix',
		'country'	=>	'Sélecteur de pays',
		'text'		=>	'Texte',
		'textarea'	=>	'Texte multi-lignes',
	);

	public function __toString()
	{
		return json_encode($this->champs);
	}

	static public function import()
	{
		$json = file_get_contents(GARRADIN_ROOT . '/include/data/champs_membres.json');
		$json = preg_replace('!/[*].*?[*]/!s', '', $json);
		$champs = new Champs_Membres($json);

		$config = Config::getInstance();
		$config->set('champs_membres', $champs);
		$config->save();
	}

	public function __construct($champs)
	{
		if ($champs instanceOf Champs_Membres)
		{
			$this->champs = $champs->getAll();
		}
		else
		{
			$this->champs = json_decode((string)$champs, true);
		}
	}

	public function getTypes()
	{
		return $this->types;
	}

	public function get($key)
	{
		return $this->champs[$key];
	}

	public function getAll()
	{
		return $this->champs;
	}

    public function setAll($champs)
    {
        if (!array_key_exists('email', $champs))
        {
            throw new UserException('Le champ E-Mail ne peut être supprimé des fiches membres.');
        }

        foreach ($champs as $key=>$config)
        {
        	if (empty($config['type']) || !array_key_exists($config['type'], $this->types))
	    	{
	    		throw new UserException('Le champ '.$key.' doit être d\'un type connu.');
	    	}

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

        $this->champs = $champs;

        return true;
    }

    public function diff()
    {
    	$db = DB::getInstance();
    	//$config
    }

    public function save()
    {
    	$db = DB::getInstance();
    	$config = Config::getInstance();

    	// Champs à créer
    	$create = array(
    		'id INTEGER PRIMARY KEY, -- Numéro attribué automatiquement',
    		'id_categorie INTEGER NOT NULL, -- Numéro de catégorie',
    		'passe TEXT NULL, -- Mot de passe',
    	);

    	// Champs à recopier
    	$copy = array(
    		'id',
    		'id_categorie',
    		'passe'
    	);

    	$anciens_champs = $config->get('champs_membres')->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';

    		$create[] = $key . ' ' . $type . ' ' . ', -- ' . str_replace(array("\n", "\r"), '', $cfg['title']);

    		if (array_key_exists($key, $anciens_champs))
    		{
    			$copy[] = $key;
    		}
    	}

    	$last = count($create) - 1;
    	$create[$last] = str_replace(',', '', $create[$last]);

    	$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; BEGIN;');
    	$db->exec($create);
    	$db->exec($copy);
    	$db->exec('DROP TABLE membres; ALTER TABLE membres_tmp RENAME TO membres;');
    	$db->exec('END; PRAGMA foreign_keys = ON;');

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

    	return true;
    }
}

?>

Modified include/class.config.php from [4f8bb78056] to [011a7bee42].

4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
..
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
78
79
..
99
100
101
102
103
104
105




106
107
108
109
110
111
112
...
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
...
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
323
324

class Config
{
    protected $fields_types = null;
    protected $config = null;
    protected $modified = array();

    protected $allowed_fields_membres = array('nom', 'passe', 'email', 'adresse', 'code_postal',
        'ville', 'pays', 'telephone', 'date_naissance', 'notes');

    static protected $_instance = null;

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

................................................................................
    protected function __construct()
    {
        $string = '';
        $int = 0;
        $float = 0.0;
        $array = array();
        $bool = false;


        $this->fields_types = array(
            'nom_asso'              =>  $string,
            'adresse_asso'          =>  $string,
            'email_asso'            =>  $string,
            'site_asso'             =>  $string,

            'monnaie'               =>  $string,
            'pays'                  =>  $string,



            'email_envoi_automatique'=> $string,

            'champs_obligatoires'   =>  $array,
            'categorie_membres'     =>  $int,

            'categorie_dons'        =>  $int,
            'categorie_cotisations' =>  $int,

            'champs_modifiables_membre' =>  $array,

            'accueil_wiki'          =>  $string,
            'accueil_connexion'     =>  $string,

            'version'               =>  $string,
        );

        $db = DB::getInstance();
................................................................................

        $this->config = $db->simpleStatementFetchAssoc('SELECT cle, valeur FROM config ORDER BY cle;');

        foreach ($this->config as $key=>&$value)
        {
            if (!array_key_exists($key, $this->fields_types))
            {
                throw new \OutOfBoundsException('Le champ "'.$key.'" est inconnu.');

            }

            if (is_array($this->fields_types[$key]))
            {
                $value = explode(',', $value);
            }




            else
            {
                settype($value, gettype($this->fields_types[$key]));
            }
        }
    }

................................................................................
        {
            $value = $this->config[$key];

            if (is_array($value))
            {
                $value = implode(',', $value);
            }





            $db->simpleExec('INSERT OR REPLACE INTO config (cle, valeur) VALUES (?, ?);',
                $key, $value);
        }

        $db->exec('END;');

................................................................................
            {
                if (!filter_var($value, FILTER_VALIDATE_EMAIL))
                {
                    throw new UserException('Adresse e-mail invalide.');
                }
                break;
            }
            case 'champs_obligatoires':
            {
                foreach ($value as $name)
                {
                    if (!in_array($name, $this->allowed_fields_membres))
                    {
                        throw new UserException('Le champ \''.$name.'\' ne peut pas être rendu obligatoire.');
                    }
                }
                break;
            }
            case 'champs_modifiables_membre':
            {
                foreach ($value as $name)
                {
                    if (!in_array($name, $this->allowed_fields_membres))
                    {
                        throw new UserException('Le champ \''.$name.'\' ne peut pas être rendu modifiable par le membre.');
                    }
                }
                break;
            }
            case 'categorie_cotisations':
            case 'categorie_dons':
            {
                return false;
................................................................................
        return $this->fields_types;
    }

    public function getConfig()
    {
        return $this->config;
    }

    public function getChampsMembres()
    {
        $out = $this->allowed_fields_membres;
        $out = array_flip($out);

        foreach ($out as $key=>&$value)
        {
            if ($key == 'passe')
                $value = 'Mot de passe';
            elseif ($key == 'email')
                $value = 'Adresse E-Mail';
            elseif ($key == 'adresse')
                $value = 'Adresse postale';
            elseif ($key == 'code_postal')
                $value = 'Code postal';
            elseif ($key == 'ville')
                $value = 'Ville';
            elseif ($key == 'pays')
                $value = 'Pays';
            elseif ($key == 'telephone')
                $value = 'Numéro de téléphone';
            elseif ($key == 'date_naissance')
                $value = 'Date de naissance';
            elseif ($key == 'notes')
                $value = 'Notes';
            elseif ($key == 'nom')
                $value = 'Prénom et nom';
            else
                $value = key;
        }

        return $out;
    }
}

?>







<
<
<







 







>










>
>


<





<
<







 







|
>






>
>
>
>







 







>
>
>
>







 







|

|

|
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







|
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

4
5
6
7
8
9
10



11
12
13
14
15
16
17
..
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
78
79
80
81
...
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
...
205
206
207
208
209
210
211
212
213
214
215
216














217
218
219
220
221
222
223
...
273
274
275
276
277
278
279
280

281

































282

class Config
{
    protected $fields_types = null;
    protected $config = null;
    protected $modified = array();




    static protected $_instance = null;

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

................................................................................
    protected function __construct()
    {
        $string = '';
        $int = 0;
        $float = 0.0;
        $array = array();
        $bool = false;
        $object = new \stdClass;

        $this->fields_types = array(
            'nom_asso'              =>  $string,
            'adresse_asso'          =>  $string,
            'email_asso'            =>  $string,
            'site_asso'             =>  $string,

            'monnaie'               =>  $string,
            'pays'                  =>  $string,

            'champs_membres'        =>  $object,

            'email_envoi_automatique'=> $string,


            'categorie_membres'     =>  $int,

            'categorie_dons'        =>  $int,
            'categorie_cotisations' =>  $int,



            'accueil_wiki'          =>  $string,
            'accueil_connexion'     =>  $string,

            'version'               =>  $string,
        );

        $db = DB::getInstance();
................................................................................

        $this->config = $db->simpleStatementFetchAssoc('SELECT cle, valeur FROM config ORDER BY cle;');

        foreach ($this->config as $key=>&$value)
        {
            if (!array_key_exists($key, $this->fields_types))
            {
                // Ancienne clé de config qui n'est plus utilisée
                continue;
            }

            if (is_array($this->fields_types[$key]))
            {
                $value = explode(',', $value);
            }
            elseif ($key == 'champs_membres')
            {
                $value = new Champs_Membres((string)$value);
            }
            else
            {
                settype($value, gettype($this->fields_types[$key]));
            }
        }
    }

................................................................................
        {
            $value = $this->config[$key];

            if (is_array($value))
            {
                $value = implode(',', $value);
            }
            elseif (is_object($value))
            {
                $value = (string) $value;
            }

            $db->simpleExec('INSERT OR REPLACE INTO config (cle, valeur) VALUES (?, ?);',
                $key, $value);
        }

        $db->exec('END;');

................................................................................
            {
                if (!filter_var($value, FILTER_VALIDATE_EMAIL))
                {
                    throw new UserException('Adresse e-mail invalide.');
                }
                break;
            }
            case 'champs_membres':
            {
                if (!($value instanceOf Champs_Membres))
                {
                    throw new \UnexpectedValueException('$value doit être de type Champs_Membres');














                }
                break;
            }
            case 'categorie_cotisations':
            case 'categorie_dons':
            {
                return false;
................................................................................
        return $this->fields_types;
    }

    public function getConfig()
    {
        return $this->config;
    }
}



































?>

Added include/data/champs_membres.json version [f5459a8c5a].

























































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
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
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
/*
	Descriptif :
	--

	type: (défaut: text)
		tous les types gérés par input type de HTML5
		+ country = sélecteur de pays
		+ checkbox = case à cocher
		+ multiple = multiples cases à cocher (jusqu'à 32, binaire)
		+ select = un choix parmis plusieurs
	value: (défaut: vide)
		valeur du champ par défaut, ou plusieurs valeurs pour select/multiple
	editable: (défaut: true)
		true = modifiable par le membre
		false = modifiable uniquement par un admin
	mandatory: (défaut: false)
		true = obligatoire
		false = facultatif
	title: (obligatoire)
		Titre du champ
	help: (facultatif)
		Texte d'aide sur les fiches membres
	private: (défaut: false)
		true = non visible par le membre lui-même
		false = visible par le membre
 */
{
	"nom":
	{
		"type": "text",
		"title": "Nom & prénom",
		"enabled": true,
		"editable": true,
		"mandatory": true
	},
	"email":
	{
		"type": "email",
		"title": "Adresse E-Mail",
		"enabled": true,
		"editable": true,
		"mandatory": true
	},
	"adresse":
	{
		"type": "textarea",
		"title": "Adresse postale (rue, numéro, immeuble, etc.)",
		"enabled": true,
		"editable": true,
		"mandatory": false
	},
	"code_postal":
	{
		"type": "text",
		"title": "Code postal",
		"enabled": true,
		"editable": true,
		"mandatory": false
	},
	"ville":
	{
		"type": "text",
		"title": "Ville",
		"enabled": true,
		"editable": true,
		"mandatory": false
	},
	"pays":
	{
		"type": "country",
		"title": "Pays",
		"enabled": true,
		"editable": true,
		"mandatory": true
	},
	"telephone":
	{
		"type": "tel",
		"title": "Numéro de téléphone",
		"enabled": true,
		"editable": true,
		"mandatory": false
	},
	"lettre_infos":
	{
		"type": "checkbox",
		"title": "Inscription à la lettre d'informations",
		"enabled": true,
		"editable": true,
		"mandatory": false
	}
}

Added include/data/champs_membres_supplementaires.json version [51a7dc1249].





























































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{
	"groupe_travail":
	{
		"type": "multiple",
		"title": "Groupe de travail",
		"editable": false,
		"mandatory": false,
		"values": [
			"Télécom",
			"Trésorerie",
			"Relations publiques",
			"Organisation d'événements"
		]
	},
	"date_naissance":
	{
		"type": "date",
		"title": "Date de naissance",
		"editable": true,
		"mandatory": false
	},
	"notes":
	{
		"type": "textarea",
		"title": "Notes",
		"editable": false,
		"mandatory": false,
		"private": true
	}
}

Modified include/init.php from [633742bb37] to [72f2f3a279].

73
74
75
76
77
78
79



80
81
82
83
84
85
86
87
    $path = (!empty($path[0]) && $path[0] != '/') ? '/' . $path : $path;
    $path = (substr($path, -1) != '/') ? $path . '/' : $path;
    define('WWW_URI', $path);
}

if (!defined('WWW_URL'))
{



    define('WWW_URL', 'http' . (!empty($_SERVER['HTTPS']) ? 's' : '') . '://' . $_SERVER['HTTP_HOST'] . WWW_URI);
}

/*
 * Gestion des erreurs et exceptions
 */

class UserException extends \LogicException







>
>
>
|







73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
    $path = (!empty($path[0]) && $path[0] != '/') ? '/' . $path : $path;
    $path = (substr($path, -1) != '/') ? $path . '/' : $path;
    define('WWW_URI', $path);
}

if (!defined('WWW_URL'))
{
    $host = isset($_SERVER['HTTP_HOST']) 
        ? $_SERVER['HTTP_HOST'] 
        : (isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : 'localhost');
    define('WWW_URL', 'http' . (!empty($_SERVER['HTTPS']) ? 's' : '') . '://' . $host . WWW_URI);
}

/*
 * Gestion des erreurs et exceptions
 */

class UserException extends \LogicException

Modified templates/admin/config/index.tpl from [df0ace960c] to [5ad6698fd9].

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
..
76
77
78
79
80
81
82














83
84
85
86
87
88
89
90
        {$error|escape}
    </p>
    {/if}
{/if}

<ul class="actions">
    <li class="current"><a href="{$www_url}admin/config/">Général</a></li>
    <li><a href="{$www_url}admin/config/membres.php">Membres</a></li>
    <li><a href="{$www_url}admin/config/site.php">Site public</a></li>
</ul>

<form method="post" action="{$self_url|escape}">

    <fieldset>
        <legend>Garradin</legend>
................................................................................
            <dt><label for="f_accueil_connexion">Page d'accueil à la connexion</label> 
                <b title="(Champ obligatoire)">obligatoire</b></dt>
            <dd>Indiquer ici l'adresse unique de la page qui sera affichée à la connexion d'un membre.</dd>
            <dd><input type="text" name="accueil_connexion" id="f_accueil_connexion" value="{form_field data=$config name=accueil_connexion}" /></dd>
        </dl>
    </fieldset>















    <p class="submit">
        {csrf_field key="config"}
        <input type="submit" name="save" value="Enregistrer &rarr;" />
    </p>

</form>

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







|







 







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








10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
..
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
101
102
103
104
        {$error|escape}
    </p>
    {/if}
{/if}

<ul class="actions">
    <li class="current"><a href="{$www_url}admin/config/">Général</a></li>
    <li><a href="{$www_url}admin/config/membres.php">Fiche membres</a></li>
    <li><a href="{$www_url}admin/config/site.php">Site public</a></li>
</ul>

<form method="post" action="{$self_url|escape}">

    <fieldset>
        <legend>Garradin</legend>
................................................................................
            <dt><label for="f_accueil_connexion">Page d'accueil à la connexion</label> 
                <b title="(Champ obligatoire)">obligatoire</b></dt>
            <dd>Indiquer ici l'adresse unique de la page qui sera affichée à la connexion d'un membre.</dd>
            <dd><input type="text" name="accueil_connexion" id="f_accueil_connexion" value="{form_field data=$config name=accueil_connexion}" /></dd>
        </dl>
    </fieldset>

    <fieldset>
        <legend>Catégories par défaut</legend>
        <dl>
            <dt><label for="f_categorie_membres">Catégorie par défaut des nouveaux membres</label> <b title="(Champ obligatoire)">obligatoire</b></dt>
            <dd>
                <select name="categorie_membres" id="f_categorie_membres">
                {foreach from=$membres_cats key="id" item="nom"}
                    <option value="{$id|escape}"{if $config.categorie_membres == $id} selected="selected"{/if}>{$nom|escape}</option>
                {/foreach}
                </select>
            </dd>
        </dl>
    </fieldset>

    <p class="submit">
        {csrf_field key="config"}
        <input type="submit" name="save" value="Enregistrer &rarr;" />
    </p>

</form>

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

Modified templates/admin/config/membres.tpl from [e062325209] to [65f3f24440].

1
2
3
4
5
6
7
8
..
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







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
{include file="admin/_head.tpl" title="Configuration" current="config"}

{if $error}
    {if $error == 'OK'}
    <p class="confirm">
        La configuration a bien été enregistrée.
    </p>
    {else}
................................................................................
        {$error|escape}
    </p>
    {/if}
{/if}

<ul class="actions">
    <li><a href="{$www_url}admin/config/">Général</a></li>
    <li class="current"><a href="{$www_url}admin/config/membres.php">Membres</a></li>
    <li><a href="{$www_url}admin/config/site.php">Site public</a></li>
</ul>

<form method="post" action="{$self_url|escape}">






    <fieldset>
        <legend>Champs des données membres</legend>

        <dl>
            <dt><label for="f_champs_obligatoires_nom">Champs obligatoires</label></dt>
            <dd>
            {foreach from=$champs_membres key="champ" item="nom"}
                <input type="checkbox" name="champs_obligatoires[]"
                    id="f_champs_obligatoires_{$champ|escape}"
                    value="{$champ|escape}"
                    {if $champ == 'nom'}checked="checked" disabled="disabled"
                    {elseif in_array($champ, $config.champs_obligatoires)}checked="checked"
                    {/if}
                    />
                <label for="f_champs_obligatoires_{$champ|escape}">{$nom|escape}</label>
                {if $champ == 'nom'}<small>(non désactivable)</small>{/if}
                <br />
            {/foreach}
            </dd>


            <dt><label for="f_champs_modifiables_membre_nom">Champs modifiables par le membre</label></dt>







            <dd>
            {foreach from=$champs_membres key="champ" item="nom"}
                <input type="checkbox" name="champs_modifiables_membre[]"
                    id="f_champs_modifiables_membre_{$champ|escape}"
                    value="{$champ|escape}"
                    {if in_array($champ, $config.champs_modifiables_membre)}checked="checked"
                    {/if}
                    />
                <label for="f_champs_modifiables_membre_{$champ|escape}">{$nom|escape}</label><br />


            {/foreach}

            </dd>










        </dl>
    </fieldset>



    <fieldset>
        <legend>Catégories par défaut</legend>

        <dl>
            <dt><label for="f_categorie_membres">Catégorie par défaut des nouveaux membres</label> <b title="(Champ obligatoire)">obligatoire</b></dt>

            <dd>
                <select name="categorie_membres" id="f_categorie_membres">
                {foreach from=$membres_cats key="id" item="nom"}
                    <option value="{$id|escape}"{if $config.categorie_membres == $id} selected="selected"{/if}>{$nom|escape}</option>







                {/foreach}
                </select>

            </dd>










        </dl>
    </fieldset>



    <p class="submit">
        {csrf_field key="config_membres"}
        <input type="submit" name="save" value="Enregistrer &rarr;" />

    </p>

</form>







































































































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







 







|





>
>
>
>
>

<
>

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

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

>
>
>
>
>
>
>
>
>
>



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




>




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

1
2
3
4
5
6
7
8
..
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
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
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
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
{include file="admin/_head.tpl" title="Configuration — Fiche membres" current="config"}

{if $error}
    {if $error == 'OK'}
    <p class="confirm">
        La configuration a bien été enregistrée.
    </p>
    {else}
................................................................................
        {$error|escape}
    </p>
    {/if}
{/if}

<ul class="actions">
    <li><a href="{$www_url}admin/config/">Général</a></li>
    <li class="current"><a href="{$www_url}admin/config/membres.php">Fiche membres</a></li>
    <li><a href="{$www_url}admin/config/site.php">Site public</a></li>
</ul>

<form method="post" action="{$self_url|escape}">

    <p class="help">
        Cette page vous permet de personnaliser les fiches d'information des membres de l'association.<br />
        <strong>Attention :</strong> Les champs supprimés de la fiche seront effacés de toutes les fiches de tous les membres, et les données qu'ils contenaient seront perdues.
    </p>

    <fieldset>

        <legend>Champs non-personnalisables</legend>
        <dl>





            <dt>Numéro unique</dt>
            <dd>Ce numéro identifie de manière unique chacun des membres. 
                Il est incrémenté à chaque nouveau membre ajouté.</dd>
            <dt>Catégorie</dt>
            <dd>Identifie la catégorie du membre.</dd>
            <dt>Mot de passe</dt>
            <dd>Le mot de passe permet de se connecter à l'administration de Garradin.</dd>


        </dl>
    </fieldset>

    <fieldset>
        <legend>Ajouter un champ pré-défini</legend>
    </fieldset>

    <fieldset>
        <legend>Ajouter un champ personnalisé</legend>
        <dl>
            <dt><label for="f_type">Type</label></dt>
            <dd>







                <select name="new[type]" id="f_type">
                    {foreach from=$types key="type" value="name"}
                    <option value="{$type|escape}"{if (!empty($new.type) && $new.type == $type) || (empty($new.type) && $type == 'text')} selected="selected"{/if}>{$name|escape}</option>
                    {/foreach}
                </select>
            </dd>
            <dt><label for="f_title">Titre</label> <b title="(Champ obligatoire)">obligatoire</b></dt>
            <dd><input type="text" name="new[title]" id="f_title" value="{form_field data=$new name=title}" size="60" /></dd>
            <dt><label for="f_help">Aide</label></dt>
            <dd><input type="text" name="new[help]" id="f_help" value="{form_field data=$new name=help}" size="100" /></dd>
            <dt><label><input type="checkbox" name="new[editable]" value="1" {form_field data=$new name=editable checked="1"} /> Modifiable par les membres</label></dt>
            <dd class="help">Si coché, les membres pourront changer cette information depuis leur espace personnel.</dd>
            <dt><label><input type="checkbox" name="new[mandatory]" value="1" {form_field data=$new name=mandatory checked="1"} /> Champ obligatoire</label></dt>
            <dd class="help">Si coché, ce champ ne pourra rester vide.</dd>
            <dt><label><input type="checkbox" name="new[private]" value="1" {form_field data=$new name=private checked="1"} /> Champ privé</label></dt>
            <dd class="help">Si coché, ce champ ne sera visible et modifiable que par les personnes pouvant gérer les membres, mais pas les membres eux-même.</dd>
        </dl>
    </fieldset>

    <div id="orderFields">
        {foreach from=$champs item="champ" key="nom"}
        <fieldset>

            <legend>{$nom|escape}</legend>
            <dl>

                <dt><label for="f_{$nom|escape}_type">Type</label></dt>
                <dd>



                    {if $nom == 'email'}
                        <input type="hidden" name="champs[{$nom|escape}][type]" value="{$champ.type|escape}" />
                        Adresse E-Mail (non modifiable)
                    {else}
                        <select name="champs[{$nom|escape}][type]" id="f_{$nom|escape}_type">
                            {foreach from=$types key="type" value="name"}
                            <option value="{$type|escape}"{if (!empty($champ.type) && $champ.type == $type)} selected="selected"{/if}>{$name|escape}</option>
                            {/foreach}
                        </select>
                    {/if}
                </dd>
                <dt><label for="f_{$nom|escape}_title">Titre</label> <b title="(Champ obligatoire)">obligatoire</b></dt>
                <dd><input type="text" name="champs[{$nom|escape}][title]" id="f_{$nom|escape}_title" value="{form_field data=$champs[$nom] name=title}" size="60" /></dd>
                <dt><label for="f_{$nom|escape}_help">Aide</label></dt>
                <dd><input type="text" name="champs[{$nom|escape}][help]" id="f_{$nom|escape}_help" value="{form_field data=$champs[$nom] name=help}" size="100" /></dd>
                <dt><label><input type="checkbox" name="champs[{$nom|escape}][editable]" value="1" {form_field data=$champs[$nom] name=editable checked="1"} /> Modifiable par les membres</label></dt>
                <dd class="help">Si coché, les membres pourront changer cette information depuis leur espace personnel.</dd>
                <dt><label><input type="checkbox" name="champs[{$nom|escape}][mandatory]" value="1" {form_field data=$champs[$nom] name=mandatory checked="1"} /> Champ obligatoire</label></dt>
                <dd class="help">Si coché, ce champ ne pourra rester vide.</dd>
                <dt><label><input type="checkbox" name="champs[{$nom|escape}][private]" value="1" {form_field data=$champs[$nom] name=private checked="1"} /> Champ privé</label></dt>
                <dd class="help">Si coché, ce champ ne sera visible et modifiable que par les personnes pouvant gérer les membres, mais pas les membres eux-même.</dd>
            </dl>
        </fieldset>
        {/foreach}
    </div>

    <p class="submit">
        {csrf_field key="config_membres"}
        <input type="submit" name="save" value="Enregistrer &rarr;" />
        (un récapitulatif sera présenté et une confirmation sera demandée)
    </p>

</form>

<script type="text/javascript">
{literal}
(function () {
    if (!document.querySelector || !document.querySelectorAll)
    {
        return false;
    }

    var fields = document.querySelectorAll('#orderFields fieldset');

    for (i = 0; i < fields.length; i++)
    {
        var field = fields[i];
        field.querySelector('dl').style.display = 'none';

        var legend = field.querySelector('legend');

        legend.onclick = function () {
            var content = this.parentNode.querySelector('dl');
            if (content.style.display.toLowerCase() == 'none')
                content.style.display = 'block';
            else
                content.style.display = 'none';
        }

        legend.className = 'interactive';
        legend.title = 'Cliquer pour modifier ce champ';

        var actions = document.createElement('div');
        actions.className = 'actions';
        field.appendChild(actions);

        var up = document.createElement('span');
        up.className = 'icn up';
        up.innerHTML = '&uarr;';
        up.title = 'Déplacer vers le haut';
        up.onclick = function (e) {
            var field = this.parentNode.parentNode;
            var p = field.previousSibling;
            while (p.nodeType == 3) { p = p.previousSibling; }
            field.parentNode.insertBefore(field, p);
            return false;
        };
        actions.appendChild(up);

        var down = document.createElement('span');
        down.className = 'icn down';
        down.innerHTML = '&darr;';
        down.title = 'Déplacer vers le bas';
        down.onclick = function (e) {
            var field = this.parentNode.parentNode;
            var p = field.nextSibling;

            if (!p.nextSibling)
            {
                field.parentNode.appendChild(field);
            }
            else
            {
                while (p.nodeType == 3) { p = p.nextSibling; }
                p = p.nextSibling;
                while (p.nodeType == 3) { p = p.nextSibling; }
                field.parentNode.insertBefore(field, p);
            }
            return false;
        };
        actions.appendChild(down);

        var rem = document.createElement('span');
        rem.className = 'icn remove';
        rem.innerHTML = '&#10005;';
        rem.title = 'Enlever ce champ de la fiche';
        rem.onclick = function (e) {
            if (!window.confirm('Êtes-vous sûr de supprimer ce champ des fiches de membre ?'))
            {
                return false;
            }

            var field = this.parentNode.parentNode;
            field.parentNode.removeChild(field);
            return false;
        };
        actions.appendChild(rem);

        var edit = document.createElement('span');
        edit.className = 'icn edit';
        edit.innerHTML = '&#x270e;';
        edit.title = 'Modifier ce champ';
        edit.onclick = function (e) {
            var content = this.parentNode.parentNode.querySelector('dl');
            if (content.style.display.toLowerCase() == 'none')
                content.style.display = 'block';
            else
                content.style.display = 'none';
            return false;
        };
        actions.appendChild(edit);
    }
}());
{/literal}
</script>

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

Modified www/admin/config/index.php from [468c346e92] to [62753fd222].

27
28
29
30
31
32
33

34
35
36
37
38
39
40
..
47
48
49
50
51
52
53



54
55
56
            $config->set('nom_asso', utils::post('nom_asso'));
            $config->set('email_asso', utils::post('email_asso'));
            $config->set('adresse_asso', utils::post('adresse_asso'));
            $config->set('site_asso', utils::post('site_asso'));
            $config->set('email_envoi_automatique', utils::post('email_envoi_automatique'));
            $config->set('accueil_wiki', utils::post('accueil_wiki'));
            $config->set('accueil_connexion', utils::post('accueil_connexion'));


            $config->set('pays', utils::post('pays'));
            $config->set('monnaie', utils::post('monnaie'));

            $config->save();

            utils::redirect('/admin/config/?ok');
................................................................................
}

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

$tpl->assign('garradin_version', garradin_version() . ' [' . garradin_manifest() . ']');
$tpl->assign('pays', utils::getCountryList());




$tpl->display('admin/config/index.tpl');

?>







>







 







>
>
>



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
..
48
49
50
51
52
53
54
55
56
57
58
59
60
            $config->set('nom_asso', utils::post('nom_asso'));
            $config->set('email_asso', utils::post('email_asso'));
            $config->set('adresse_asso', utils::post('adresse_asso'));
            $config->set('site_asso', utils::post('site_asso'));
            $config->set('email_envoi_automatique', utils::post('email_envoi_automatique'));
            $config->set('accueil_wiki', utils::post('accueil_wiki'));
            $config->set('accueil_connexion', utils::post('accueil_connexion'));
            $config->set('categorie_membres', utils::post('categorie_membres'));

            $config->set('pays', utils::post('pays'));
            $config->set('monnaie', utils::post('monnaie'));

            $config->save();

            utils::redirect('/admin/config/?ok');
................................................................................
}

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

$tpl->assign('garradin_version', garradin_version() . ' [' . garradin_manifest() . ']');
$tpl->assign('pays', utils::getCountryList());

$cats = new Membres_Categories;
$tpl->assign('membres_cats', $cats->listSimple());

$tpl->display('admin/config/index.tpl');

?>

Modified www/admin/config/membres.php from [29f5a4b562] to [86c2b807a2].

5
6
7
8
9
10
11

12
13
14
15
16
17
18
..
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

if ($user['droits']['config'] < Membres::DROIT_ADMIN)
{
    throw new UserException("Vous n'avez pas le droit d'accéder à cette page.");
}

$error = false;


if (isset($_GET['ok']))
{
    $error = 'OK';
}

if (!empty($_POST['save']))
................................................................................
    if (!utils::CSRF_check('config_membres'))
    {
        $error = 'Une erreur est survenue, merci de renvoyer le formulaire.';
    }
    else
    {
        try {
            $config->set('champs_obligatoires', utils::post('champs_obligatoires'));
            $config->set('champs_modifiables_membre', utils::post('champs_modifiables_membre'));
            $config->set('categorie_membres', utils::post('categorie_membres'));
            $config->save();

            utils::redirect('/admin/config/membres.php?ok');
        }
        catch (UserException $e)
        {
            $error = $e->getMessage();
        }
    }
}

$cats = new Membres_Categories;
$tpl->assign('membres_cats', $cats->listSimple());


$tpl->assign('champs_membres', $config->getChampsMembres());


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








$tpl->display('admin/config/membres.tpl');

?>







>







 







|
<
<
|










|
<
|
>
|
>
>


>
>
>
>
>
>
>



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
..
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

if ($user['droits']['config'] < Membres::DROIT_ADMIN)
{
    throw new UserException("Vous n'avez pas le droit d'accéder à cette page.");
}

$error = false;
$champs = new Champs_Membres($config->get('champs_membres'));

if (isset($_GET['ok']))
{
    $error = 'OK';
}

if (!empty($_POST['save']))
................................................................................
    if (!utils::CSRF_check('config_membres'))
    {
        $error = 'Une erreur est survenue, merci de renvoyer le formulaire.';
    }
    else
    {
        try {
            $champs->setAll(utils::post('champs'));


            $champs->save();

            utils::redirect('/admin/config/membres.php?ok');
        }
        catch (UserException $e)
        {
            $error = $e->getMessage();
        }
    }
}

function tpl_get_type($type)

{
    global $types;
    return $types[$type];
}

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

$types = $champs->getTypes();

$tpl->assign('champs', utils::post('champs') ?: $config->get('champs_membres')->getAll());
$tpl->assign('types', $types);
$tpl->assign('new', utils::post('new'));

$tpl->register_modifier('get_type', 'Garradin\tpl_get_type');
$tpl->display('admin/config/membres.tpl');

?>

Modified www/admin/static/admin.css from [e3591ee22e] to [10128f42ff].

420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
...
913
914
915
916
917
918
919

























920
921
922
923
924
925
926
#rapport h1 {
    text-align: center;
}

.actions .icn {
    text-decoration: none;
    border-radius: 1em;
    width: 16px;
    display: inline-block;
    text-align: center;
    font-size: 1.2em;
    line-height: .8em;
    vertical-align: middle;
    padding: .1em;
}

.actions .icn:hover {
    color: darkred;
    background: #ff9;
}

................................................................................
    width: 20%;
    float: right;
    margin: .5em;
    border: .1em solid #ccc;
    background: #eee;
    padding: .5em;
}


























@media print {
    body {
        background: #fff;
    }
    .header .menu {
        display: none;







|





|







 







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







420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
...
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
#rapport h1 {
    text-align: center;
}

.actions .icn {
    text-decoration: none;
    border-radius: 1em;
    width: 1.2em;
    display: inline-block;
    text-align: center;
    font-size: 1.2em;
    line-height: .8em;
    vertical-align: middle;
    padding: .2em;
}

.actions .icn:hover {
    color: darkred;
    background: #ff9;
}

................................................................................
    width: 20%;
    float: right;
    margin: .5em;
    border: .1em solid #ccc;
    background: #eee;
    padding: .5em;
}

#orderFields fieldset {
    position: relative;
    min-height: 2em;
}

#orderFields fieldset .actions {
    display: block;
    position: absolute;
    top: 1em;
    right: 1em;
}

#orderFields fieldset:nth-child(1) .actions .up, #orderFields fieldset:nth-last-child(1) .actions .down {
    display: none;
}

#orderFields fieldset .actions .icn {
    cursor: pointer;
}

#orderFields fieldset .interactive:hover {
    cursor: pointer;
    text-decoration: underline;
}

@media print {
    body {
        background: #fff;
    }
    .header .menu {
        display: none;

Modified www/admin/upgrade.php from [7b1cbd85b6] to [7e21d1bf49].

16
17
18
19
20
21
22

23
24
25
26
27
28
29
..
78
79
80
81
82
83
84















85
86
87
88
89
90
91




92
93
94
95
96
97

98

if (version_compare($v, garradin_version(), '>='))
{
    throw new UserException("Pas de mise à jour à faire.");
}

$db = DB::getInstance();


echo '<!DOCTYPE html>
<meta charset="utf-8" />
<h3>Mise à jour de Garradin '.$config->getVersion().' vers la version '.garradin_version().'...</h3>';

flush();

................................................................................
                .   "Utilisez le menu à gauche pour accéder aux différentes rubriques.",
        ));
    }

    $config->set('accueil_connexion', $page);
    $config->save();
}
















utils::clearCaches();

$config->setVersion(garradin_version());

echo '<h4>Mise à jour terminée.</h4>
<p><a href="'.WWW_URL.'admin/">Retour</a></p>




<script type="text/javascript">
window.setTimeout(function () { 
    window.location.href = "'.WWW_URL.'admin/"; 
}, 1000);
</script>';


?>







>







 







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






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

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
..
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119

if (version_compare($v, garradin_version(), '>='))
{
    throw new UserException("Pas de mise à jour à faire.");
}

$db = DB::getInstance();
$redirect = true;

echo '<!DOCTYPE html>
<meta charset="utf-8" />
<h3>Mise à jour de Garradin '.$config->getVersion().' vers la version '.garradin_version().'...</h3>';

flush();

................................................................................
                .   "Utilisez le menu à gauche pour accéder aux différentes rubriques.",
        ));
    }

    $config->set('accueil_connexion', $page);
    $config->save();
}

if (version_compare($v, '0.5.0', '<'))
{
    // Récupération de l'ancienne config
    $champs_modifiables_membre = $db->querySingle('SELECT valeur FROM config WHERE cle = "champs_modifiables_membre";');
    $champs_modifiables_membre = explode($champs_modifiables_membre);

    $champs_obligatoires = $db->querySingle('SELECT valeur FROM config WHERE cle = "champs_obligatoires";');
    $champs_obligatoires = explode($champs_obligatoires);

    // Application à la nouvelle config (TODO)

    // Suppression de l'ancienne config
    $db->exec('DELETE FROM config WHERE cle IN ("champs_obligatoires", "champs_modifiables_membre");');
}

utils::clearCaches();

$config->setVersion(garradin_version());

echo '<h4>Mise à jour terminée.</h4>
<p><a href="'.WWW_URL.'admin/">Retour</a></p>';

if ($redirect)
{
    echo '
    <script type="text/javascript">
    window.setTimeout(function () { 
        window.location.href = "'.WWW_URL.'admin/"; 
    }, 1000);
    </script>';
}

?>