Overview
Comment:Fix [4cd80507894e50f6], add ability to change files from user edit
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | dev
Files: files | file ages | folders
SHA3-256: 198c3b0d10ee83e4355d97dd631a3c1bb611087eced6b964233a72f3af64a0b1
User & Date: bohwaz on 2021-04-05 22:17:52
Other Links: branch diff | manifest | tags
Context
2021-04-05
22:30
New release check-in: cfffd78f12 user: bohwaz tags: dev, 1.1.0-rc1
22:17
Fix [4cd80507894e50f6], add ability to change files from user edit check-in: 198c3b0d10 user: bohwaz tags: dev
21:30
Fix keep alive, fix [7d1ab532b109a467477a542c0de38bc7e12fb14c] check-in: 1e3fd4e542 user: bohwaz tags: dev
Changes

Modified src/include/lib/Garradin/Entities/Files/File.php from [e0bd62a4f2] to [1cfc3e1511].

853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
	static public function filterName(string $name): string
	{
		return preg_replace('/[^\w\d\p{L}_. -]+/iu', '-', $name);
	}

	static public function validateFileName(string $name): void
	{
		if (substr($name[0], 0, 1)) {
			throw new ValidationException('Le nom de fichier ne peut commencer par un point');
		}

		if (strpos($name, "\0") !== false) {
			throw new ValidationException('Nom de fichier invalide');
		}








|







853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
	static public function filterName(string $name): string
	{
		return preg_replace('/[^\w\d\p{L}_. -]+/iu', '-', $name);
	}

	static public function validateFileName(string $name): void
	{
		if (substr($name[0], 0, 1) === '.') {
			throw new ValidationException('Le nom de fichier ne peut commencer par un point');
		}

		if (strpos($name, "\0") !== false) {
			throw new ValidationException('Nom de fichier invalide');
		}

Modified src/include/lib/Garradin/Membres/Champs.php from [9c3a83a513] to [8b03eb3d59].

235
236
237
238
239
240
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
                continue;
            }

            return $key;
        }
    }

    public function getValidationRules($mode = 'edit')
    {
        assert(in_array($mode, ['edit', 'create', 'user_edit']));

        $all_rules = [];

        foreach ($this->champs as $name => $config)
        {
            if (empty($config->editable) && $mode == 'user_edit')
            {
                $all_rules[$name] = 'absent';
                break;
            }

            $rules = [];

            if (!empty($config->mandatory) && !($name == 'passe' && $mode != 'create'))
            {
                $rules[] = 'required';
            }

            if ($config->type == 'email')
            {
                $rules[] = 'email';
            }
            elseif ($config->type == 'url')
            {
                $rules[] = 'url';
            }
            elseif ($config->type == 'date')
            {
                $rules[] = 'date_format:Y-m-d';
            }
            elseif ($config->type == 'date')
            {
                $rules[] = 'date_format:Y-m-d H\:i';
            }
            elseif ($config->type == 'number' || $config->type == 'multiple')
            {
                $rules[] = 'numeric';
            }
            elseif ($config->type == 'checkbox')
            {
                $rules[] = 'boolean';
            }

            if ($name == 'passe')
            {
                $rules[] = 'min:6';
            }

            if (isset($config->rules))
            {
                $rules[] = $config->rules;
            }

            if (count($rules))
            {
                $all_rules[$name] = implode('|', $rules);
            }
        }

        return $all_rules;
    }

    /**
     * Vérifie la cohérence et la présence des bons éléments pour un champ
     * @param  string $name     Nom du champ
     * @param  array $config    Configuration du champ
     * @return boolean true
     */
    protected function _checkField($name, \stdClass &$config)







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







235
236
237
238
239
240
241

































































242
243
244
245
246
247
248
                continue;
            }

            return $key;
        }
    }


































































    /**
     * Vérifie la cohérence et la présence des bons éléments pour un champ
     * @param  string $name     Nom du champ
     * @param  array $config    Configuration du champ
     * @return boolean true
     */
    protected function _checkField($name, \stdClass &$config)

Modified src/templates/acc/transactions/details.tpl from [799aae9d5a] to [0098f837e0].

115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
				{/if}
			</td>
		</tr>
		{/foreach}
	</tbody>
</table>

{if $can_upload || count($files)}
<div class="attachments">
	<h3 class="ruler">Fichiers joints</h3>
	{include file="common/files/_context_list.tpl" files=$files can_upload=$can_upload path=$file_parent}
</div>
{/if}

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







|


|




115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
				{/if}
			</td>
		</tr>
		{/foreach}
	</tbody>
</table>

{if $files_edit || count($files)}
<div class="attachments">
	<h3 class="ruler">Fichiers joints</h3>
	{include file="common/files/_context_list.tpl" files=$files edit=$files_edit path=$file_parent}
</div>
{/if}

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

Added src/templates/admin/membres/_details.tpl version [2d17bd544c].



































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
<?php
assert(isset($data, $champs, $show_message_button));
$user_files_path = (new Membres)->getAttachementsDirectory($data->id);
?>

<dl class="describe">
	{foreach from=$champs key="c" item="c_config"}
	<dt>{$c_config.title}</dt>
	<dd>
		{if $c_config.type == 'checkbox'}
			{if $data->$c}Oui{else}Non{/if}
		{elseif $c_config.type == 'file'}
			<?php
			$edit = ($c_config->editable || $mode == 'edit');
			?>
			{include file="common/files/_context_list.tpl" limit=1 path="%s/%s"|args:$user_files_path,$c}
		{elseif empty($data->$c)}
			<em>(Non renseigné)</em>
		{elseif $c == $c_config.champ_identite}
			<strong>{$data->$c}</strong>
		{elseif $c_config.type == 'email'}
			<a href="mailto:{$data->$c|escape:'url'}">{$data->$c}</a>
			{if $c == 'email' && $show_message_button}
				{linkbutton href="!membres/message.php?id=%d"|args:$data.id label="Envoyer un message" shape="mail"}
			{/if}
		{elseif $c_config.type == 'tel'}
			<a href="tel:{$data->$c}">{$data->$c|format_tel}</a>
		{elseif $c_config.type == 'country'}
			{$data->$c|get_country_name}
		{elseif $c_config.type == 'date'}
			{$data->$c|date_short}
		{elseif $c_config.type == 'datetime'}
			{$data->$c|date}
		{elseif $c_config.type == 'password'}
			*******
		{elseif $c_config.type == 'multiple'}
			<ul>
			{foreach from=$c_config.options key="b" item="name"}
				{if $data->$c & (0x01 << $b)}
					<li>{$name}</li>
				{/if}
			{/foreach}
			</ul>
		{else}
			{$data->$c|escape|rtrim|nl2br}
		{/if}
	</dd>
	{/foreach}
</dl>

Modified src/templates/admin/membres/fiche.tpl from [cd708e950f] to [9b1d3c68ff].

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
					(<b class="icn">🔓</b> sans second facteur)
				{/if}
		{/if}
		</dd>
	</dl>
</aside>

<dl class="describe">
    {foreach from=$champs key="c" item="c_config"}
    <dt>{$c_config.title}</dt>
    <dd>
        {if $c_config.type == 'checkbox'}
            {if $membre->$c}Oui{else}Non{/if}
        {elseif $c_config.type == 'file'}
            {include file="common/files/_context_list.tpl" limit=1 path="%s/%s"|args:$user_files_path,$c}
        {elseif empty($membre->$c)}
            <em>(Non renseigné)</em>
        {elseif $c == $c_config.champ_identite}
            <strong>{$membre->$c}</strong>
        {elseif $c_config.type == 'email'}
            <a href="mailto:{$membre->$c|escape:'url'}">{$membre->$c}</a>
            {if $c == 'email'}
                {linkbutton href="!membres/message.php?id=%d"|args:$membre.id label="Envoyer un message" shape="mail"}
            {/if}
        {elseif $c_config.type == 'tel'}
            <a href="tel:{$membre->$c}">{$membre->$c|format_tel}</a>
        {elseif $c_config.type == 'country'}
            {$membre->$c|get_country_name}
        {elseif $c_config.type == 'date'}
            {$membre->$c|date_short}
        {elseif $c_config.type == 'datetime'}
            {$membre->$c|date}
        {elseif $c_config.type == 'password'}
            *******
        {elseif $c_config.type == 'multiple'}
            <ul>
            {foreach from=$c_config.options key="b" item="name"}
                {if $membre->$c & (0x01 << $b)}
                    <li>{$name}</li>
                {/if}
            {/foreach}
            </ul>
        {else}
            {$membre->$c|escape|rtrim|nl2br}
        {/if}
    </dd>
    {/foreach}
</dl>

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







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


67
68
69
70
71
72
73
74








































75
76
					(<b class="icn">🔓</b> sans second facteur)
				{/if}
		{/if}
		</dd>
	</dl>
</aside>

{include file="admin/membres/_details.tpl" champs=$champs data=$membre show_message_button=true mode="edit"}









































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

Modified src/templates/admin/mes_infos.tpl from [acc847c498] to [9470f7e272].

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
<nav class="tabs">
    <ul>
        <li class="current"><a href="{$admin_url}mes_infos.php">Mes informations personnelles</a></li>
        <li><a href="{$admin_url}mes_infos_securite.php">Mot de passe et options de sécurité</a></li>
    </ul>
</nav>

{form_errors membre=1}

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

    <fieldset>
        <legend>Informations personnelles</legend>
        <dl>
            {foreach from=$champs item="champ" key="nom"}
            {if empty($champ.private) && $nom != 'passe'}
                {html_champ_membre config=$champ name=$nom data=$membre user_mode=true}
            {/if}
            {/foreach}

        </dl>
    </fieldset>

    <fieldset>
        <legend>Changer mon mot de passe</legend>
            <p><a href="{$admin_url}mes_infos_securite.php">Modifier mon mot de passe ou autres informations de sécurité.</a></p>
    </fieldset>

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

</form>


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







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

<
>


3
4
5
6
7
8
9
10





11





12
13










14
15

16
17
18
<nav class="tabs">
    <ul>
        <li class="current"><a href="{$admin_url}mes_infos.php">Mes informations personnelles</a></li>
        <li><a href="{$admin_url}mes_infos_securite.php">Mot de passe et options de sécurité</a></li>
    </ul>
</nav>

<dl class="describe">





    <dd>





        {linkbutton href="mes_infos_modifier.php" label="Modifier mes informations" shape="edit"}
    </dd>










</dl>


{include file="admin/membres/_details.tpl" champs=$champs data=$data show_message_button=false mode="user"}

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

Added src/templates/admin/mes_infos_modifier.tpl version [a8c6d019fb].











































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
{include file="admin/_head.tpl" title="Mes informations personnelles" current="mes_infos"}

<nav class="tabs">
	<ul>
		<li class="current"><a href="{$admin_url}mes_infos.php">Mes informations personnelles</a></li>
		<li><a href="{$admin_url}mes_infos_securite.php">Mot de passe et options de sécurité</a></li>
	</ul>
</nav>

{form_errors membre=1}

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

	<fieldset>
		<legend>Informations personnelles</legend>
		<dl>
			{foreach from=$champs item="champ" key="nom"}
			{if empty($champ.private) && $nom != 'passe'}
				{html_champ_membre config=$champ name=$nom data=$data user_mode=true}
			{/if}
			{/foreach}
		</dl>
	</fieldset>

	<fieldset>
		<legend>Changer mon mot de passe</legend>
		<p><a href="{$admin_url}mes_infos_securite.php">Modifier mon mot de passe ou autres informations de sécurité.</a></p>
	</fieldset>

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

</form>

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

Modified src/templates/common/files/_context_list.tpl from [7492d35a51] to [9143e41708].

1
2
3
4
5





6


7

8
9
10
11
12
13
14
..
28
29
30
31
32
33
34
35
36
37
38




39
40
<?php
assert(isset($path) || isset($can_upload, $files, $path));

if (!isset($files, $can_upload)) {
	$files = Files\Files::list($path);





	$can_upload = (!isset($limit) || count($files) < $limit) && Entities\Files\File::checkCreateAccess($path, $session);


}

?>

{if $can_upload}
<p class="actions">
	{linkbutton shape="upload" href="!common/files/upload.php?p=%s"|args:$path target="_dialog" label="Ajouter un fichier"}
</p>
{/if}
................................................................................
				</figcaption>
			</figure>
		{else}
			<a target="_blank" href="{$file->url()}">{$file.name}</a>
			<small>({$file.mime}, {$file.size|size_in_bytes})</small>
		{/if}
		{linkbutton shape="download" href=$file->url(true) target="_blank" label="Télécharger"}
		{if $file->checkDeleteAccess($session)}
			{linkbutton shape="delete" target="_dialog" href="!common/files/delete.php?p=%s"|args:$file.path label="Supprimer"}
		{/if}
	</aside>




{/foreach}
</div>

|

|

>
>
>
>
>
|
>
>

>







 







|



>
>
>
>


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<?php
assert(isset($path, $edit));

if (!isset($files)) {
	$files = Files\Files::list($path);
}

$can_upload = false;

if ($edit
	&& Entities\Files\File::checkCreateAccess($path, $session)
	&& (!isset($limit) || count($files) < $limit)) {
	$can_upload = true;
}

?>

{if $can_upload}
<p class="actions">
	{linkbutton shape="upload" href="!common/files/upload.php?p=%s"|args:$path target="_dialog" label="Ajouter un fichier"}
</p>
{/if}
................................................................................
				</figcaption>
			</figure>
		{else}
			<a target="_blank" href="{$file->url()}">{$file.name}</a>
			<small>({$file.mime}, {$file.size|size_in_bytes})</small>
		{/if}
		{linkbutton shape="download" href=$file->url(true) target="_blank" label="Télécharger"}
		{if $edit && $file->checkDeleteAccess($session)}
			{linkbutton shape="delete" target="_dialog" href="!common/files/delete.php?p=%s"|args:$file.path label="Supprimer"}
		{/if}
	</aside>
{foreachelse}
	{if !$can_upload}
		<em>--</em>
	{/if}
{/foreach}
</div>

Modified src/www/admin/acc/transactions/details.php from [392d0a8bfa] to [4fb5b3b805].

20
21
22
23
24
25
26
27
28
29
30
31

$tpl->assign(compact('transaction', 'csrf_key'));

$tpl->assign('files', $transaction->listFiles());
$tpl->assign('tr_year', $transaction->year());
$tpl->assign('creator_name', $transaction->id_creator ? (new Membres)->getNom($transaction->id_creator) : null);

$tpl->assign('can_upload', $session->canAccess($session::SECTION_ACCOUNTING, $session::ACCESS_WRITE));
$tpl->assign('file_parent', $transaction->getAttachementsDirectory());
$tpl->assign('related_users', $transaction->listLinkedUsers());

$tpl->display('acc/transactions/details.tpl');







|




20
21
22
23
24
25
26
27
28
29
30
31

$tpl->assign(compact('transaction', 'csrf_key'));

$tpl->assign('files', $transaction->listFiles());
$tpl->assign('tr_year', $transaction->year());
$tpl->assign('creator_name', $transaction->id_creator ? (new Membres)->getNom($transaction->id_creator) : null);

$tpl->assign('files_edit', $session->canAccess($session::SECTION_ACCOUNTING, $session::ACCESS_WRITE));
$tpl->assign('file_parent', $transaction->getAttachementsDirectory());
$tpl->assign('related_users', $transaction->listLinkedUsers());

$tpl->display('acc/transactions/details.tpl');

Modified src/www/admin/membres/fiche.php from [143e0f77e2] to [4096d65e9e].

28
29
30
31
32
33
34
35
36
37

if ($session->canAccess($session::SECTION_ACCOUNTING, $session::ACCESS_READ)) {
	$tpl->assign('transactions_linked', Transactions::countForUser($membre->id));
	$tpl->assign('transactions_created', Transactions::countForCreator($membre->id));
}

$tpl->assign('membre', $membre);
$tpl->assign('user_files_path', $membres->getAttachementsDirectory($membre->id));

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







<


28
29
30
31
32
33
34

35
36

if ($session->canAccess($session::SECTION_ACCOUNTING, $session::ACCESS_READ)) {
	$tpl->assign('transactions_linked', Transactions::countForUser($membre->id));
	$tpl->assign('transactions_created', Transactions::countForCreator($membre->id));
}

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


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

Modified src/www/admin/mes_infos.php from [3bfc6b66d5] to [56acaec485].

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

require_once __DIR__ . '/_inc.php';


$champs = $config->get('champs_membres');

if (f('save'))

{
    $form->check('edit_me', $champs->getValidationRules('user_edit'));

    if (!$form->hasErrors())
    {
        try {
            $data = [];

            foreach ($champs->getAll() as $key=>$c)
            {
                if (!empty($c->editable))
                {
                    $data[$key] = f($key);
                }
            }

            if (isset($data[$config->get('champ_identifiant')]) && !trim($data[$config->get('champ_identifiant')]) && $session->canAccess($session::SECTION_CONFIG, $session::ACCESS_ADMIN)) {
                throw new UserException("Le champ identifiant ne peut être vide pour un administrateur, sinon vous ne pourriez plus vous connecter.");
            }

            $session->editUser($data);

            Utils::redirect(ADMIN_URL);
        }
        catch (UserException $e)
        {
            $form->addError($e->getMessage());
        }
    }
}

$tpl->assign('champs', $champs->getAll());

$tpl->assign('membre', $session->getUser());

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





>
|

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

1
2
3
4
5
6
7
8

9
10


































11
<?php
namespace Garradin;

require_once __DIR__ . '/_inc.php';

$data = $session->getUser();
$champs = Config::getInstance()->get('champs_membres')->getList();


$tpl->assign(compact('champs', 'data'));



































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

Added src/www/admin/mes_infos_modifier.php version [37640b7c31].































































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

require_once __DIR__ . '/_inc.php';

$csrf_key = 'edit_my_info';

$form->runIf('save', function () use ($session) {
	$data = [];
	$config = Config::getInstance();
	$champs = Config::getInstance()->get('champs_membres');

	foreach ($champs->getAll() as $key=>$c) {
		if (!empty($c->editable)) {
			$data[$key] = f($key);
		}
	}

	if (isset($data[$config->get('champ_identifiant')]) && !trim($data[$config->get('champ_identifiant')]) && $session->canAccess($session::SECTION_CONFIG, $session::ACCESS_ADMIN)) {
		throw new UserException("Le champ identifiant ne peut être vide pour un administrateur, sinon vous ne pourriez plus vous connecter.");
	}

	$session->editUser($data);
}, $csrf_key, '!mes_infos.php');

$data = $session->getUser();
$champs = Config::getInstance()->get('champs_membres')->getAll();

$tpl->assign(compact('csrf_key', 'champs', 'data'));

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