Overview
Comment:Implement support for files in user details
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | dev
Files: files | file ages | folders
SHA3-256: 90818b0261185c69535731d23c42f91f9373f1d5442d1550ecb05bdcd13c283c
User & Date: bohwaz on 2021-03-01 20:09:48
Other Links: branch diff | manifest | tags
Context
2021-03-02
01:38
Integrate changes for skeleton edits check-in: ddda7b5850 user: bohwaz tags: dev
2021-03-01
20:09
Implement support for files in user details check-in: 90818b0261 user: bohwaz tags: dev
19:32
Fix directory creation check-in: bf585217f2 user: bohwaz tags: dev
Changes

Modified src/include/data/champs_membres.ini from [f5ad8e1d8e] to [adac130192].

131
132
133
134
135
136
137






editable = true

[notes]
type = textarea
title = "Notes"
editable = false
private = true













>
>
>
>
>
>
131
132
133
134
135
136
137
138
139
140
141
142
143
editable = true

[notes]
type = textarea
title = "Notes"
editable = false
private = true

[photo]
type = file
title = "Photo"
editable = false
private = false

Modified src/include/lib/Garradin/Config.php from [e3dead6a86] to [e66ef3a5ba].

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
	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));
		$this->assert(!empty($champs->get($this->champ_identifiant)), sprintf('Le champ spécifié pour identifiant, "%s" n\'existe pas', $this->champ_identifiant));

		$db = DB::getInstance();
		$sql = sprintf('SELECT (COUNT(DISTINCT %s) = COUNT(*)) FROM membres WHERE %1$s IS NOT NULL AND %1$s != \'\';', $this->champ_identifiant);
		$is_unique = $db->firstColumn($sql);

		$this->assert($is_unique, sprintf('Le champ "%s" comporte des doublons et ne peut donc pas servir comme identifiant unique de connexion.', $this->champ_identifiant));

		$this->assert($db->test('users_categories', 'id = ?', $this->categorie_membres), 'Catégorie de membres inconnue');
	}

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







|















|
<
<
<
<
<
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288





	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(strlen($this->admin_homepage) > 0, '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));
		$this->assert(!empty($champs->get($this->champ_identifiant)), sprintf('Le champ spécifié pour identifiant, "%s" n\'existe pas', $this->champ_identifiant));

		$db = DB::getInstance();
		$sql = sprintf('SELECT (COUNT(DISTINCT %s) = COUNT(*)) FROM membres WHERE %1$s IS NOT NULL AND %1$s != \'\';', $this->champ_identifiant);
		$is_unique = $db->firstColumn($sql);

		$this->assert($is_unique, sprintf('Le champ "%s" comporte des doublons et ne peut donc pas servir comme identifiant unique de connexion.', $this->champ_identifiant));

		$this->assert($db->test('users_categories', 'id = ?', $this->categorie_membres), 'Catégorie de membres inconnue');
	}
}





Modified src/include/lib/Garradin/Entities/Files/File.php from [3acca35d13] to [138dc225b0].

665
666
667
668
669
670
671

672
673
674
675
676
677
678
	{
		// Web pages and config files are always public
		if ($this->isPublic()) {
			return true;
		}

		$context = $this->context();


		if (null === $session) {
			return false;
		}

		if ($context == self::CONTEXT_TRANSACTION && $session->canAccess($session::SECTION_ACCOUNTING, $session::ACCESS_READ)) {
			return true;







>







665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
	{
		// Web pages and config files are always public
		if ($this->isPublic()) {
			return true;
		}

		$context = $this->context();
		$ref = strtok(substr($this->pathname(), strpos($this->pathname(), '/')), '/');

		if (null === $session) {
			return false;
		}

		if ($context == self::CONTEXT_TRANSACTION && $session->canAccess($session::SECTION_ACCOUNTING, $session::ACCESS_READ)) {
			return true;

Modified src/include/lib/Garradin/UserTemplate/CommonModifiers.php from [3d0edb4ff5] to [505d9f8c59].

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
		}

		return sprintf('<b class="money">%s</b>', Utils::money_format($number, ',', '&nbsp;', $hide_empty));
	}

	static public function money_currency($number, bool $hide_empty = true): string
	{
		$out = $this->htmlMoney($number, $hide_empty);

		if ($out !== '') {
			$out .= '&nbsp;' . Config::getInstance()->get('monnaie');
		}

		return $out;
	}







|







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
		}

		return sprintf('<b class="money">%s</b>', Utils::money_format($number, ',', '&nbsp;', $hide_empty));
	}

	static public function money_currency($number, bool $hide_empty = true): string
	{
		$out = self::money($number, $hide_empty);

		if ($out !== '') {
			$out .= '&nbsp;' . Config::getInstance()->get('monnaie');
		}

		return $out;
	}

Modified src/templates/acc/transactions/details.tpl from [361a38a61b] to [799aae9d5a].

118
119
120
121
122
123
124
125
126
127
128
129
		{/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 parent_path=$file_parent}
</div>
{/if}

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







|




118
119
120
121
122
123
124
125
126
127
128
129
		{/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"}

Modified src/templates/admin/config/membres.tpl from [563b1fbac5] to [d986be9230].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{include file="admin/_head.tpl" current="config" custom_css=['config.css']}

{include file="admin/config/_menu.tpl" current="fiches_membres"}

{if isset($status) && $status == 'OK'}
    <p class="block confirm">
        La configuration a bien été enregistrée.
    </p>
{elseif isset($status) && $status == 'ADDED'}
    <p class="block alert">
        Le champ a été ajouté à la fin de la liste. Pour sauvegarder les modifications de la fiche membre cliquer sur le bouton «&nbsp;Enregistrer&nbsp;» en base de page.
    </p>
{/if}

{form_errors}

{if $review}
    <p class="help">










|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{include file="admin/_head.tpl" current="config" custom_css=['config.css']}

{include file="admin/config/_menu.tpl" current="fiches_membres"}

{if isset($status) && $status == 'OK'}
    <p class="block confirm">
        La configuration a bien été enregistrée.
    </p>
{elseif isset($status) && $status == 'ADDED'}
    <p class="block alert">
        Le champ a été ajouté à la fin de la liste. Pour vérifier et sauvegarder les modifications de la fiche membre cliquer sur le bouton «&nbsp;rifier les changements&nbsp;» en base de page.
    </p>
{/if}

{form_errors}

{if $review}
    <p class="help">

Modified src/templates/admin/membres/fiche.tpl from [119c83684f] to [cd708e950f].

74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
<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'}
            <?php
            $files = $membre->$c ? [$membre->$c] : [];
            $can_upload = !count($files) && $session->canAccess($session::SECTION_USERS, $session::ACCESS_WRITE);
            ?>
            {include file="common/files/_context_list.tpl" files=$files can_upload=$can_upload parent_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'}







<
<
<
<
|







74
75
76
77
78
79
80




81
82
83
84
85
86
87
88
<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'}

Modified src/templates/common/files/_context_list.tpl from [81e19c0583] to [5d888c46cc].










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









{if !empty($can_upload) && !empty($parent_path)}
<p class="actions">
	{linkbutton shape="upload" href="!common/files/upload.php?p=%s"|args:$parent_path target="_dialog" label="Ajouter un fichier"}
</p>
{/if}

<div class="files-list">
	{foreach from=$files item="file"}



	<aside class="file">
		{if $file.image}
			<figure>
				<a target="_blank" href="{$file->url()}"><img src="{$file->thumb_url()}" alt="" /></a>
				<figcaption>
					<a target="_blank" href="{$file->url()}">{$file.name}</a>
					<small>({$file.mime}, {$file.size|size_in_bytes})</small>
				</figcaption>
			</figure>
		{else}
			<a target="_blank" href="{$file->url()}">{$file.name}</a>
			<small>({$file.type}, {$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
23
24
25
26
27
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}

<div class="files-list">
{foreach from=$files item="file"}
	{if !$file->checkReadAccess($session)}
		<?php break; ?>
	{/if}
	<aside class="file">
		{if $file.image}
			<figure>
				<a target="_blank" href="{$file->url()}"><img src="{$file->thumb_url()}" alt="" /></a>
				<figcaption>
					<a target="_blank" href="{$file->url()}">{$file.name}</a>
					<small>({$file.mime}, {$file.size|size_in_bytes})</small>
				</figcaption>
			</figure>
		{else}
			<a target="_blank" href="{$file->url()}">{$file.name}</a>
			<small>({$file.type}, {$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>

Modified src/templates/common/files/upload.tpl from [de47c74320] to [7265a3906f].

1


2
3
4
5
6
7
8
{include file="admin/_head.tpl" title="Envoi de fichier"}



<form method="post" action="{$self_url}" enctype="multipart/form-data" data-focus="1">
	<fieldset>
		<legend>Téléverser un fichier</legend>
		<dl>
			{input type="file" name="file" required="required" label="Fichier à envoyer"}
		</dl>

>
>







1
2
3
4
5
6
7
8
9
10
{include file="admin/_head.tpl" title="Envoi de fichier"}

{form_errors}

<form method="post" action="{$self_url}" enctype="multipart/form-data" data-focus="1">
	<fieldset>
		<legend>Téléverser un fichier</legend>
		<dl>
			{input type="file" name="file" required="required" label="Fichier à envoyer"}
		</dl>

Modified src/www/admin/_inc.php from [938f84908a] to [6413c8a1fb].

45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
$form = new Form;
$tpl->assign_by_ref('form', $form);

$session = Session::getInstance();
$config = Config::getInstance();

$tpl->assign('session', $session);
$tpl->assign('config', $config->getConfig());

if (!defined('Garradin\LOGIN_PROCESS'))
{
    if (!$session->isLogged())
    {
        if ($session->isOTPRequired())
        {







|







45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
$form = new Form;
$tpl->assign_by_ref('form', $form);

$session = Session::getInstance();
$config = Config::getInstance();

$tpl->assign('session', $session);
$tpl->assign('config', $config);

if (!defined('Garradin\LOGIN_PROCESS'))
{
    if (!$session->isLogged())
    {
        if ($session->isOTPRequired())
        {