Overview
Comment:Rewrite configuration, fix file handling
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | dev
Files: files | file ages | folders
SHA3-256: c4d4b327a98abc64241d6ed28c3643bc0046f11609541f7338c7d99e9b72157b
User & Date: bohwaz on 2021-01-23 01:18:26
Other Links: branch diff | manifest | tags
Context
2021-01-23
15:26
Fix file size, add vacuum before dump and backup check-in: f3e645f083 user: bohwaz tags: dev
01:18
Rewrite configuration, fix file handling check-in: c4d4b327a9 user: bohwaz tags: dev
2021-01-22
18:45
Update config check-in: fdc5ab12d1 user: bohwaz tags: dev
Changes

Modified src/include/lib/Garradin/Config.php from [49e9073bd2] to [7ddf77dab7].

70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
		'couleur1'              => '?string',
		'couleur2'              => '?string',
		'image_fond'            => '?Garradin\Entities\Files\File',

		'desactiver_site'       => 'bool',
	];

	protected $_modified;

	static protected $_instance = null;

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







|







70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
		'couleur1'              => '?string',
		'couleur2'              => '?string',
		'image_fond'            => '?Garradin\Entities\Files\File',

		'desactiver_site'       => 'bool',
	];

	protected $_deleted_files = [];

	static protected $_instance = null;

	static public function getInstance()
	{
		return self::$_instance ?: self::$_instance = new self;
	}
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
			}
		}

		$this->load($config);

		$this->champs_membres = new Membres\Champs((string)$this->champs_membres);
	}














	public function save(): bool
	{
		if (!count($this->_modified)) {
			return true;
		}



		$values = [];
		$db = DB::getInstance();

		foreach ($this->_modified as $key => $modified) {
			$value = $this->$key;

			if ($this->_types[$key] == File::class && null === $value && $this->$key !== null) {
				$this->$key->delete();
			}
			elseif ($this->_types[$key] == File::class && null !== $value) {
				$value = $value->id();
			}
			else if ($this->_types[$key] == Champs::class) {
				$value = $value->toString();
			}

			$values[$key] = $value;
		}

		unset($value, $key, $modified);

		$db->begin();

		foreach ($this->_modified as $key=>$modified)
		{
			$value = $this->get($key);

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




				$value = (string) $value;

			}

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

		if (!empty($this->_modified['champ_identifiant']))
		{
			// Mettre les champs identifiant vides à NULL pour pouvoir créer un index unique
			$db->exec('UPDATE membres SET '.$this->get('champ_identifiant').' = NULL
				WHERE '.$this->get('champ_identifiant').' = "";');

			// Création de l'index unique
			$db->exec('DROP INDEX IF EXISTS membres_identifiant;');
			$db->exec('CREATE UNIQUE INDEX membres_identifiant ON membres ('.$this->get('champ_identifiant').');');
		}







		$db->commit();

		$this->_modified = [];

		return true;
	}







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






>
>







|
<
<
<

















|
<


|
<
>
>
>
>
|
>
















>
>
>
>
>
>







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
			}
		}

		$this->load($config);

		$this->champs_membres = new Membres\Champs((string)$this->champs_membres);
	}

	public function set(string $key, $value, bool $loose = false, bool $check_for_changes = true)
	{
		// Append to deleted files queue if it's set to null
		if (isset($this->_types[$key])
			&& substr($this->_types[$key], -strlen(File::class)) == File::class
			&& $value === null
			&& $this->$key !== null) {
			$this->_deleted_files[] = $this->$key;
		}

		parent::set($key, $value, $loose, $check_for_changes);
	}

	public function save(): bool
	{
		if (!count($this->_modified)) {
			return true;
		}

		$this->selfCheck();

		$values = [];
		$db = DB::getInstance();

		foreach ($this->_modified as $key => $modified) {
			$value = $this->$key;

			if ($this->_types[$key] == File::class && null !== $value) {



				$value = $value->id();
			}
			else if ($this->_types[$key] == Champs::class) {
				$value = $value->toString();
			}

			$values[$key] = $value;
		}

		unset($value, $key, $modified);

		$db->begin();

		foreach ($this->_modified as $key=>$modified)
		{
			$value = $this->get($key);

			if (is_array($value)) {

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

				if ($value instanceof File) {
					$value = $value->id();
				}
				else {
					$value = (string) $value;
				}
			}

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

		if (!empty($this->_modified['champ_identifiant']))
		{
			// Mettre les champs identifiant vides à NULL pour pouvoir créer un index unique
			$db->exec('UPDATE membres SET '.$this->get('champ_identifiant').' = NULL
				WHERE '.$this->get('champ_identifiant').' = "";');

			// Création de l'index unique
			$db->exec('DROP INDEX IF EXISTS membres_identifiant;');
			$db->exec('CREATE UNIQUE INDEX membres_identifiant ON membres ('.$this->get('champ_identifiant').');');
		}

		foreach ($this->_deleted_files as $file) {
			$file->delete();
		}

		Files::deleteOrphanFiles();

		$db->commit();

		$this->_modified = [];

		return true;
	}
202
203
204
205
206
207
208
209
210











211
212
213
214
215
216
217
		if (!isset($source['couleur1'], $source['couleur2'])
			|| ($source['couleur1'] == ADMIN_COLOR1 && $source['couleur2'] == ADMIN_COLOR2))
		{
			$source['couleur1'] = null;
			$source['couleur2'] = null;
		}

		if (trim($source['image_fond']) == '') {
			$source['image_fond'] = null;











		}

		parent::importForm($source);
	}

	public function getVersion(): string
	{







|

>
>
>
>
>
>
>
>
>
>
>







223
224
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
		if (!isset($source['couleur1'], $source['couleur2'])
			|| ($source['couleur1'] == ADMIN_COLOR1 && $source['couleur2'] == ADMIN_COLOR2))
		{
			$source['couleur1'] = null;
			$source['couleur2'] = null;
		}

		if (isset($source['image_fond']) && trim($source['image_fond']) == 'RESET') {
			$source['image_fond'] = null;
		}
		elseif (isset($source['image_fond']) && strlen($source['image_fond'])) {
			if ($this->image_fond) {
				$this->image_fond->storeFromBase64($source['image_fond']);
				$this->image_fond->save();
			}
			else {
				$this->set('image_fond', File::createFromBase64('image_fond.png', $source['image_fond'], File::CONTEXT_CONFIG, 'image_fond'));
			}

			unset($source['image_fond']);
		}

		parent::importForm($source);
	}

	public function getVersion(): string
	{
248
249
250
251
252
253
254

255
256
257
258
259
260
261
	}

	public function selfCheck(): void
	{
		$this->assert(trim($this->nom_asso) != '', 'Le nom de l\'association ne peut rester vide.');
		$this->assert(trim($this->monnaie) != '', 'La monnaie ne peut rester vide.');
		$this->assert(trim($this->pays) != '' && Utils::getCountryName($this->pays), 'Le pays ne peut rester vide.');

		$this->assert(trim($this->email_asso) != '' && SMTP::checkEmailIsValid($this->email_asso, false), 'L\'adresse e-mail de l\'association est  invalide.');
		$this->assert(null === $this->admin_homepage || $this->admin_homepage instanceof File, 'Page d\'accueil invalide');
		$this->assert($this->champs_membres instanceof Champs, 'Objet champs membres invalide');

		$champs = $this->champs_membres;

		$this->assert(!empty($champs->get($this->champ_identite)), sprintf('Le champ spécifié pour identité, "%s" n\'existe pas', $this->champ_identite));







>







280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
	}

	public function selfCheck(): void
	{
		$this->assert(trim($this->nom_asso) != '', 'Le nom de l\'association ne peut rester vide.');
		$this->assert(trim($this->monnaie) != '', 'La monnaie ne peut rester vide.');
		$this->assert(trim($this->pays) != '' && Utils::getCountryName($this->pays), 'Le pays ne peut rester vide.');
		$this->assert(null === $this->site_asso || filter_var($this->site_asso, FILTER_VALIDATE_URL), 'L\'adresse URL du site web est invalide.');
		$this->assert(trim($this->email_asso) != '' && SMTP::checkEmailIsValid($this->email_asso, false), 'L\'adresse e-mail de l\'association est  invalide.');
		$this->assert(null === $this->admin_homepage || $this->admin_homepage instanceof File, 'Page d\'accueil invalide');
		$this->assert($this->champs_membres instanceof Champs, 'Objet champs membres invalide');

		$champs = $this->champs_membres;

		$this->assert(!empty($champs->get($this->champ_identite)), sprintf('Le champ spécifié pour identité, "%s" n\'existe pas', $this->champ_identite));

Modified src/include/lib/Garradin/Entities/Files/File.php from [e860f082ac] to [63c202a387].

247
248
249
250
251
252
253
254
255
256
257
258






259
260
261
262
263
264
265

	/**
	 * Upload de fichier à partir d'une chaîne en base64
	 * @param  string $name
	 * @param  string $content
	 * @return File
	 */
	static public function storeFromBase64(string $name, string $encoded_content, int $context, $context_ref = null): self
	{
		$content = base64_decode($encoded_content);
		return self::create($name, $context, $context_ref, null, $content);
	}







	/**
	 * Upload du fichier par POST
	 */
	static public function upload(string $key, int $context, $context_ref = null): self
	{
		if (!isset($_FILES[$key]) || !is_array($_FILES[$key])) {







|




>
>
>
>
>
>







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

	/**
	 * Upload de fichier à partir d'une chaîne en base64
	 * @param  string $name
	 * @param  string $content
	 * @return File
	 */
	static public function createFromBase64(string $name, string $encoded_content, int $context, $context_ref = null): self
	{
		$content = base64_decode($encoded_content);
		return self::create($name, $context, $context_ref, null, $content);
	}

	public function storeFromBase64(string $encoded_content): self
	{
		$content = base64_decode($encoded_content);
		return $this->store(null, $content);
	}

	/**
	 * Upload du fichier par POST
	 */
	static public function upload(string $key, int $context, $context_ref = null): self
	{
		if (!isset($_FILES[$key]) || !is_array($_FILES[$key])) {

Modified src/include/lib/Garradin/Files/Files.php from [e5d5ae14d0] to [098bdb1126].

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
			case File::CONTEXT_TRANSACTION:
				return 'acc_transactions c ON c.id = f.context_ref';
			case File::CONTEXT_USER:
				return 'membres c ON c.id = f.context_ref';
			case File::CONTEXT_FILE:
				return 'files c ON c.id = f.context_ref';
			case File::CONTEXT_CONFIG:
				return 'config c ON c.cle = f.context_ref';
			case File::CONTEXT_WEB:
			case File::CONTEXT_DOCUMENTS:
			case File::CONTEXT_SKELETON:
			default:
				return null;
		}
	}

	/**
	 * Remove any files from a specific context where the linked context reference is not valid anymore
	 * This is when eg. a transaction has been deleted but not its linked files
	 */
	static public function deleteOrphanFiles(): void
	{
		static $contexts = [File::CONTEXT_FILE, File::CONTEXT_USER, File::CONTEXT_TRANSACTION, File::CONTEXT_CONFIG];

		$db = DB::getInstance();

		foreach ($contexts as $context) {
			$sql = sprintf('SELECT f.* FROM files f LEFT JOIN %s WHERE f.context = %d AND c.id IS NULL;', self::getContextJoinClause($context), $context);

			foreach ($db->iterate($sql) as $file) {
				$f = new Fichiers($file->id, (array) $file);
				$f->delete();
			}
		}

		// Remove any left-overs
		$db->exec('DELETE FROM files_contents WHERE hash NOT IN (SELECT DISTINCT hash FROM files);');
	}

	static public function deleteLinkedFiles(int $context, $value): void
	{
		if (null === $value) {
			throw new \InvalidArgumentException('value argument cannot be null');
		}







|
















|


|

|
<
|




|







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
			case File::CONTEXT_TRANSACTION:
				return 'acc_transactions c ON c.id = f.context_ref';
			case File::CONTEXT_USER:
				return 'membres c ON c.id = f.context_ref';
			case File::CONTEXT_FILE:
				return 'files c ON c.id = f.context_ref';
			case File::CONTEXT_CONFIG:
				return 'config c ON c.cle = f.context_ref AND c.valeur = f.id';
			case File::CONTEXT_WEB:
			case File::CONTEXT_DOCUMENTS:
			case File::CONTEXT_SKELETON:
			default:
				return null;
		}
	}

	/**
	 * Remove any files from a specific context where the linked context reference is not valid anymore
	 * This is when eg. a transaction has been deleted but not its linked files
	 */
	static public function deleteOrphanFiles(): void
	{
		static $contexts = [File::CONTEXT_FILE, File::CONTEXT_USER, File::CONTEXT_TRANSACTION, File::CONTEXT_CONFIG];

		$em = EM::getInstance(File::class);

		foreach ($contexts as $context) {
			$sql = sprintf('SELECT f.* FROM files f LEFT JOIN %s WHERE f.context = %d AND %s IS NULL;', self::getContextJoinClause($context), $context, $context == File::CONTEXT_CONFIG ? 'c.cle' : 'c.id');

			foreach ($em->iterate($sql) as $file) {

				$file->delete();
			}
		}

		// Remove any left-overs
		DB::getInstance()->exec('DELETE FROM files_contents WHERE hash NOT IN (SELECT DISTINCT hash FROM files);');
	}

	static public function deleteLinkedFiles(int $context, $value): void
	{
		if (null === $value) {
			throw new \InvalidArgumentException('value argument cannot be null');
		}

Modified src/include/lib/Garradin/Membres/Champs.php from [5d64a9e45c] to [e72b0a0eac].

173
174
175
176
177
178
179















180
181
182
183
184
185
186
    public function getList()
    {
        $champs = clone $this->champs;
        unset($champs->passe);

        return $champs;
    }
















    public function getMultiples()
    {
        $out = [];

        foreach ($this->champs as $id => $champ) {
            if ($champ->type == 'multiple') {







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







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
    public function getList()
    {
        $champs = clone $this->champs;
        unset($champs->passe);

        return $champs;
    }

    public function listAssocNames()
    {
        $out = [];

        foreach ($this->champs as $key => $config) {
            if ($key == 'passe') {
                continue;
            }

            $out[$key] = $config->title;
        }

        return $out;
    }

    public function getMultiples()
    {
        $out = [];

        foreach ($this->champs as $id => $champ) {
            if ($champ->type == 'multiple') {

Modified src/templates/admin/config/index.tpl from [6ad64a2f62] to [4a6507bc05].

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

	<fieldset>
		<legend>Informations sur l'association</legend>
		<dl>
			{input type="text" name="nom_asso" required=true source=$config label="Nom"}
			{input type="email" name="email_asso" required=true source=$config label="Adresse e-mail de contact"}
			{input type="textarea" name="adresse_asso" source=$config label="Adresse postale"}

			{input type="url" name="site_asso" source=$config label="Site web" help="Si vous n'utilisez pas la fonctionnalité site web de Garradin"}
		</dl>
	</fieldset>

	<fieldset>
		<legend>Localisation</legend>
		<dl>
			{input type="text" name="monnaie" required=true source=$config label="Monnaie" help="Inscrire ici la devise utilisée : €, CHF, XPF, etc."}
			{input type="select" name="pays" required=true source=$config label="Pays" options=$countries}
		</dl>
	</fieldset>

	<fieldset>
		<legend>Membres</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" required="required" id="f_categorie_membres">
				{foreach from=$membres_cats key="id" item="nom"}
					<option value="{$id}"{if $config.categorie_membres == $id} selected="selected"{/if}>{$nom}</option>
				{/foreach}
				</select>
			</dd>
			<dt><label for="f_champ_identite">Champ utilisé pour définir l'identité des membres</label> <b title="(Champ obligatoire)">obligatoire</b></dt>
			<dd class="help">Ce champ des fiches membres sera utilisé comme identité du membre dans les emails, les fiches, les pages, etc.</dd>
			<dd>
				<select name="champ_identite" required="required" id="f_champ_identite">
					{foreach from=$champs key="c" item="champ"}
						<option value="{$c}" {form_field selected=$c name="champ_identite" source=$config}>{$champ.title}</option>
					{/foreach}
				</select>
			</dd>
			<dt><label for="f_champ_identifiant">Champ utilisé comme identifiant de connexion</label> <b title="(Champ obligatoire)">obligatoire</b></dt>
			<dd class="help">Ce champ des fiches membres sera utilisé en guise d'identifiant pour se connecter à Garradin. Pour cela le champ doit être unique (pas de doublons).</dd>
			<dd>
				<select name="champ_identifiant" required="required" id="f_champ_identifiant">
					{foreach from=$champs key="c" item="champ"}
						<option value="{$c}" {form_field selected=$c name="champ_identifiant" source=$config}>{$champ.title}</option>
					{/foreach}
				</select>
			</dd>

		</dl>
	</fieldset>

	<fieldset>
		<legend>Personnalisation</legend>
		<dl>
			{*input type="file_editor" name="admin_homepage" source=$config label="Texte de la page d'accueil" help="Ce contenu sera affiché à la connexion d'un membre, ou en cliquant sur l'onglet 'Accueil' du menu de gauche"*}
			{input type="color" pattern="#[a-f0-9]{6}" title="Couleur au format hexadécimal" default=ADMIN_COLOR1 source=$config name="couleur1" label="Couleur primaire" placeholder=ADMIN_COLOR1}
			{input type="color" pattern="#[a-f0-9]{6}" title="Couleur au format hexadécimal" default=ADMIN_COLOR2 source=$config name="couleur2" label="Couleur secondaire" placeholder=ADMIN_COLOR2}
			{input type="file" label="Image de fond" name="background" help="Il est conseillé d'utiliser une image en noir et blanc avec un fond blanc pour un meilleur rendu. Dimensions recommandées : 380x200" accept="image/*,*.jpeg,*.jpg,*.png,*.gif"}
		</dl>
		<input type="hidden" name="image_fond" id="f_image_fond" data-source="{$background_image_source}" data-default="{$background_image_default}" value="{$background_image_current}" />
	</fieldset>

	<p class="submit">
		{csrf_field key="config"}
		{button type="submit" name="save" label="Enregistrer" shape="right" class="main"}
	</p>

</form>

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







>







|







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






|
|
|


|










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

	<fieldset>
		<legend>Informations sur l'association</legend>
		<dl>
			{input type="text" name="nom_asso" required=true source=$config label="Nom"}
			{input type="email" name="email_asso" required=true source=$config label="Adresse e-mail de contact"}
			{input type="textarea" name="adresse_asso" source=$config label="Adresse postale"}
			{input type="tel" name="telephone_asso" source=$config label="Numéro de téléphone"}
			{input type="url" name="site_asso" source=$config label="Site web" help="Si vous n'utilisez pas la fonctionnalité site web de Garradin"}
		</dl>
	</fieldset>

	<fieldset>
		<legend>Localisation</legend>
		<dl>
			{input type="text" name="monnaie" required=true source=$config label="Monnaie" help="Inscrire ici la devise utilisée : €, CHF, XPF, etc." size="3"}
			{input type="select" name="pays" required=true source=$config label="Pays" options=$countries}
		</dl>
	</fieldset>

	<fieldset>
		<legend>Membres</legend>
		<dl>
			{input type="select" name="categorie_membres" source=$config options=$membres_cats required=true label="Catégorie par défaut des nouveaux membres"}







			{input type="select" name="champ_identite" source=$config options=$champs required=true label="Champ utilisé pour définir l'identité des membres" help="Ce champ des fiches membres sera utilisé comme identité du membre dans les emails, les fiches, les pages, etc."}

















			{input type="select" name="champ_identifiant" source=$config options=$champs required=true label="Champ utilisé comme identifiant de connexion" help="Ce champ des fiches membres sera utilisé comme identifiant pour se connecter à Garradin. Ce champ doit être unique (il ne peut pas contenir deux membres ayant la même valeur dans ce champ)."}
		</dl>
	</fieldset>

	<fieldset>
		<legend>Personnalisation</legend>
		<dl>
			{* FIXME TODO input type="file_editor" name="admin_homepage" source=$config label="Texte de la page d'accueil" help="Ce contenu sera affiché à la connexion d'un membre, ou en cliquant sur l'onglet 'Accueil' du menu de gauche"*}
			{input type="color" pattern="#[a-f0-9]{6}" title="Couleur au format hexadécimal" default=$color1 source=$config name="couleur1" label="Couleur primaire" placeholder=$color1}
			{input type="color" pattern="#[a-f0-9]{6}" title="Couleur au format hexadécimal" default=$color2 source=$config name="couleur2" label="Couleur secondaire" placeholder=$color2}
			{input type="file" label="Image de fond" name="background" help="Il est conseillé d'utiliser une image en noir et blanc avec un fond blanc pour un meilleur rendu. Dimensions recommandées : 380x200" accept="image/*,*.jpeg,*.jpg,*.png,*.gif"}
		</dl>
		<input type="hidden" name="image_fond" id="f_image_fond" data-current="{$background_image_current}" data-default="{$background_image_default}" value="{$_POST.image_fond}" />
	</fieldset>

	<p class="submit">
		{csrf_field key="config"}
		{button type="submit" name="save" label="Enregistrer" shape="right" class="main"}
	</p>

</form>

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

Modified src/www/admin/config/index.php from [ce5e7b3d8f] to [6f9f6922dc].

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
<?php
namespace Garradin;

require_once __DIR__ . '/_inc.php';

$config = Config::getInstance();

$form->runIf('save', function () use ($config) {
	$config->importForm();
	$config->save();
}, 'config', Utils::getSelfURI('ok'));

$server_time = time();

$tpl->assign('garradin_version', garradin_version() . ' [' . (garradin_manifest() ?: 'release') . ']');

$tpl->assign('new_version', ENABLE_TECH_DETAILS ? Utils::getLatestVersion() : null);
$tpl->assign('php_version', phpversion());
$tpl->assign('has_gpg_support', \KD2\Security::canUseEncryption());
$tpl->assign('server_time', $server_time);

$v = \SQLite3::version();
$tpl->assign('sqlite_version', $v['versionString']);

$tpl->assign('countries', Utils::getCountryList());

$cats = new Membres\Categories;
$tpl->assign('membres_cats', $cats->listSimple());

$tpl->assign('champs', $config->get('champs_membres')->getList());

$tpl->assign('couleur1', $config->get('couleur1') ?: ADMIN_COLOR1);
$tpl->assign('couleur2', $config->get('couleur2') ?: ADMIN_COLOR2);


$image_fond = $config->get('image_fond') ? $config->get('image_fond')->url() : ADMIN_BACKGROUND_IMAGE;

$tpl->assign('background_image_source', $image_fond);
$tpl->assign('background_image_current', f('image_fond') ?: $image_fond);
$tpl->assign('background_image_default', ADMIN_BACKGROUND_IMAGE);

$tpl->assign('custom_js', ['color_helper.js']);
$tpl->display('admin/config/index.tpl');










|

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

|

<
|




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
<?php
namespace Garradin;

require_once __DIR__ . '/_inc.php';

$config = Config::getInstance();

$form->runIf('save', function () use ($config) {
	$config->importForm();
	$config->save();
}, 'config', Utils::getSelfURI(['ok' => '']));


$tpl->assign([
	'garradin_version' => garradin_version() . ' [' . (garradin_manifest() ?: 'release') . ']',

	'new_version'      => ENABLE_TECH_DETAILS ? Utils::getLatestVersion() : null,
	'php_version'      => phpversion(),
	'has_gpg_support'  => \KD2\Security::canUseEncryption(),
	'server_time'      => time(),

	'sqlite_version'   => \SQLite3::version()['versionString'],


	'countries'        => Utils::getCountryList(),

	'membres_cats'     => (new Membres\Categories)->listSimple(),


	'champs'           => $config->get('champs_membres')->listAssocNames(),
	'color1'           => ADMIN_COLOR1,

	'color2'           => ADMIN_COLOR2,
]);

$image_fond = $config->get('image_fond') ? $config->get('image_fond')->url() : null;


$tpl->assign('background_image_current', $image_fond);
$tpl->assign('background_image_default', ADMIN_BACKGROUND_IMAGE);

$tpl->assign('custom_js', ['color_helper.js']);
$tpl->display('admin/config/index.tpl');

Modified src/www/admin/static/scripts/color_helper.js from [97e321468f] to [c434b78aa4].

34
35
36
37
38
39
40
41


42
43
44
45
46
47
48
		applyColors();
		return new_color;
	}

	function applyColors()
	{
		let input = $('#f_couleur2');
		var color = colorToRGB(input.value, 'gSecondColor');



		var img = new Image;
		img.crossOrigin = "Anonymous";

		img.onload = function() {
			var canvas = document.createElement('canvas');
			var ctx = canvas.getContext('2d');







|
>
>







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
		applyColors();
		return new_color;
	}

	function applyColors()
	{
		let input = $('#f_couleur2');
		let color = colorToRGB(input.value, 'gSecondColor');
		let color1 = $('#f_couleur1'), color2 = $('#f_couleur2');
		let default_colors = color1.value == color1.placeholder && color2.value == color2.placeholder;

		var img = new Image;
		img.crossOrigin = "Anonymous";

		img.onload = function() {
			var canvas = document.createElement('canvas');
			var ctx = canvas.getContext('2d');
73
74
75
76
77
78
79






80
81
82
83
84
85
86
87
88
89
90
91
			delete canvas;
			delete ctx;
			delete img;
		};

		var bg = $('#f_image_fond');







		if (bg.value) {
			img.src = 'data:image/png;base64,' + bg.value;
		}
		else if (bg.dataset.source) {
			img.src = 'data:image/png;base64,' + bg.dataset.source;
		}
		else {
			img.src = bg.dataset.default;
		}
	}

	/**







>
>
>
>
>
>
|


|
|







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
			delete canvas;
			delete ctx;
			delete img;
		};

		var bg = $('#f_image_fond');

		if (bg.value == 'RESET' && default_colors) {
			document.documentElement.style.setProperty('--gBgImage', 'url("' + bg.dataset.default + '")');
		}
		else if (bg.value == 'RESET') {
			img.src = bg.dataset.default;
		}
		else if (bg.value) {
			img.src = 'data:image/png;base64,' + bg.value;
		}
		else if (bg.dataset.current) {
			img.src = bg.dataset.current;
		}
		else {
			img.src = bg.dataset.default;
		}
	}

	/**
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213

		var reset_btn = document.createElement('button');
		reset_btn.className = 'resetButton icn-btn';
		reset_btn.type = 'button';
		reset_btn.innerHTML = 'RàZ';

		reset_btn.onclick = () => {
			$('#f_image_fond').dataset.source = '';
			$('#f_image_fond').value = '';
			bg.disabled = false;

			applyColors();
		};

		bg.parentNode.insertBefore(reset_btn, bg.nextSibling);
	});
})();







|
|








205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221

		var reset_btn = document.createElement('button');
		reset_btn.className = 'resetButton icn-btn';
		reset_btn.type = 'button';
		reset_btn.innerHTML = 'RàZ';

		reset_btn.onclick = () => {
			$('#f_image_fond').dataset.current = '';
			$('#f_image_fond').value = 'RESET';
			bg.disabled = false;

			applyColors();
		};

		bg.parentNode.insertBefore(reset_btn, bg.nextSibling);
	});
})();