Overview
Comment:Only show first image of a field in users list
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | dev
Files: files | file ages | folders
SHA3-256: 9cbed54da9cdb006afeca7aa8ed7eccc06a81a18aa5d0ad72c06300d877e17a4
User & Date: bohwaz on 2023-03-29 17:20:16
Other Links: branch diff | manifest | tags
Context
2023-03-29
20:37
Fix error display for module check-in: 4383a59e9c user: bohwaz tags: dev
17:20
Only show first image of a field in users list check-in: 9cbed54da9 user: bohwaz tags: dev
16:58
Fix [7982be95bd] allow people to edit their own files check-in: 0bbf008811 user: bohwaz tags: dev
Changes

Modified src/include/lib/Garradin/Entities/Files/File.php from [b30d4ce2b3] to [6a7b6b1ecf].

621
622
623
624
625
626
627



628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648



649
650
651
652
653
654
655
656
			$size .= 'px';
		}

		$size = isset(self::ALLOWED_THUMB_SIZES[$size]) ? $size : key(self::ALLOWED_THUMB_SIZES);
		return sprintf('%s?%dpx', $this->url(), $size);
	}




	public function link(Session $session, ?string $thumb = null, bool $allow_edit = false)
	{
		if ($thumb == 'auto') {
			if ($this->isImage()) {
				$thumb = '150px';
			}
			else {
				$thumb = 'icon';
			}
		}

		if ($thumb == 'icon') {
			$label = sprintf('<span data-icon="%s"></span>', Utils::iconUnicode($this->iconShape()));
		}
		elseif ($thumb) {
			$label = sprintf('<img src="%s" alt="%s" />', htmlspecialchars($this->thumb_url($thumb)), htmlspecialchars($this->name));
		}
		else {
			$label = preg_replace('/[_.-]/', '&shy;$0', htmlspecialchars($this->name));
		}




		if ($allow_edit && $this->canWrite($session) && $this->editorType()) {
			$attrs = sprintf('href="%s" target="_dialog" data-dialog-class="fullscreen"',
				Utils::getLocalURL('!common/files/edit.php?p=') . rawurlencode($this->path));
		}
		elseif ($this->canPreview($session)) {
			$attrs = sprintf('href="%s" target="_dialog" data-mime="%s"',
				Utils::getLocalURL('!common/files/preview.php?p=') . rawurlencode($this->path),
				$this->mime);







>
>
>
|




















>
>
>
|







621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
			$size .= 'px';
		}

		$size = isset(self::ALLOWED_THUMB_SIZES[$size]) ? $size : key(self::ALLOWED_THUMB_SIZES);
		return sprintf('%s?%dpx', $this->url(), $size);
	}

	/**
	 * Return a HTML link to the file
	 */
	public function link(Session $session, ?string $thumb = null, bool $allow_edit = false, ?string $url = null)
	{
		if ($thumb == 'auto') {
			if ($this->isImage()) {
				$thumb = '150px';
			}
			else {
				$thumb = 'icon';
			}
		}

		if ($thumb == 'icon') {
			$label = sprintf('<span data-icon="%s"></span>', Utils::iconUnicode($this->iconShape()));
		}
		elseif ($thumb) {
			$label = sprintf('<img src="%s" alt="%s" />', htmlspecialchars($this->thumb_url($thumb)), htmlspecialchars($this->name));
		}
		else {
			$label = preg_replace('/[_.-]/', '&shy;$0', htmlspecialchars($this->name));
		}

		if ($url) {
			$attrs = sprintf('href="%s"', Utils::getLocalURL($url));
		}
		elseif ($allow_edit && $this->canWrite($session) && $this->editorType()) {
			$attrs = sprintf('href="%s" target="_dialog" data-dialog-class="fullscreen"',
				Utils::getLocalURL('!common/files/edit.php?p=') . rawurlencode($this->path));
		}
		elseif ($this->canPreview($session)) {
			$attrs = sprintf('href="%s" target="_dialog" data-mime="%s"',
				Utils::getLocalURL('!common/files/preview.php?p=') . rawurlencode($this->path),
				$this->mime);

Modified src/include/lib/Garradin/Entities/Users/User.php from [e06cd81d9d] to [5727eb3736].

177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
			$user = $session->getUser();

			if ($user->id == $this->id) {
				throw new UserException('Il n\'est pas possible de supprimer son propre compte. Merci de demander à un autre administrateur de le faire.');
			}
		}

		Files::delete($this->attachementsDirectory());

		return parent::delete();
	}

	public function asArray(bool $for_database = false): array
	{
		$out = parent::asArray($for_database);







|







177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
			$user = $session->getUser();

			if ($user->id == $this->id) {
				throw new UserException('Il n\'est pas possible de supprimer son propre compte. Merci de demander à un autre administrateur de le faire.');
			}
		}

		Files::delete($this->attachmentsDirectory());

		return parent::delete();
	}

	public function asArray(bool $for_database = false): array
	{
		$out = parent::asArray($for_database);
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
	}

	public function category(): Category
	{
		return Categories::get($this->id_category);
	}

	public function attachementsDirectory(): string
	{
		return File::CONTEXT_USER . '/' . $this->id();
	}

	public function listFiles(): array
	{
		$files = [];

		foreach (Files::listForContext(File::CONTEXT_USER, (string) $this->id()) as $dir) {
			foreach (Files::list($dir->path) as $file) {
				$files[] = $file;
			}
		}

		return $files;
	}

	public function number(): ?string
	{
		$field = DynamicFields::getNumberField();
		return $this->$field;
	}







|




|

<
|
<
<
<
<
<
<
<







242
243
244
245
246
247
248
249
250
251
252
253
254
255

256







257
258
259
260
261
262
263
	}

	public function category(): Category
	{
		return Categories::get($this->id_category);
	}

	public function attachmentsDirectory(): string
	{
		return File::CONTEXT_USER . '/' . $this->id();
	}

	public function listFiles(string $field_name = null): array
	{

		return Files::listForUser($this->id, $field_name);







	}

	public function number(): ?string
	{
		$field = DynamicFields::getNumberField();
		return $this->$field;
	}

Modified src/include/lib/Garradin/Files/Files.php from [0438ab857a] to [db2648d315].

1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
<?php

namespace Garradin\Files;

use Garradin\Static_Cache;
use Garradin\Config;
use Garradin\DB;
use Garradin\Plugins;
use Garradin\Utils;
use Garradin\UserException;
use Garradin\ValidationException;

use Garradin\Users\Session;
use Garradin\Entities\Files\File;
use Garradin\Entities\Web\Page;

use KD2\DB\EntityManager as EM;
use KD2\ZipWriter;












>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php

namespace Garradin\Files;

use Garradin\Static_Cache;
use Garradin\Config;
use Garradin\DB;
use Garradin\Plugins;
use Garradin\Utils;
use Garradin\UserException;
use Garradin\ValidationException;
use Garradin\Users\DynamicFields;
use Garradin\Users\Session;
use Garradin\Entities\Files\File;
use Garradin\Entities\Web\Page;

use KD2\DB\EntityManager as EM;
use KD2\ZipWriter;

63
64
65
66
67
68
69



















70
71
72
73
74
75
76
	static public function buildUserPermissions(Session $s): array
	{
		$is_admin = $s->canAccess($s::SECTION_CONFIG, $s::ACCESS_ADMIN);

		$p = [];

		if ($s->isLogged() && $id = $s::getUserId()) {



















			// The user can always access his own profile files
			$p[File::CONTEXT_USER . '/' . $s::getUserId() . '/'] = [
				'mkdir' => false,
				'move' => false,
				'create' => false,
				'read' => true,
				'write' => false,







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







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
	static public function buildUserPermissions(Session $s): array
	{
		$is_admin = $s->canAccess($s::SECTION_CONFIG, $s::ACCESS_ADMIN);

		$p = [];

		if ($s->isLogged() && $id = $s::getUserId()) {
			$list = DynamicFields::getInstance()->fieldsByType('file');

			// Add permissions for each field
			foreach ($list as $name => $field) {
				if (!$field->write_access) {
					continue;
				}

				$p[File::CONTEXT_USER . '/' . $s::getUserId() . '/' . $name . '/'] = [
					'mkdir' => false,
					'move' => false,
					'create' => true,
					'read' => true,
					'write' => true,
					'delete' => false,
					'share' => false,
				];
			}

			// The user can always access his own profile files
			$p[File::CONTEXT_USER . '/' . $s::getUserId() . '/'] = [
				'mkdir' => false,
				'move' => false,
				'create' => false,
				'read' => true,
				'write' => false,
260
261
262
263
264
265
266




















267
268
269
270
271
272
273
			return [$dir];
		}

		// Update this path
		return self::callStorage('list', $parent);
	}





















	/**
	 * Returns a list of files or directories matching a glob pattern
	 * only * and ? characters are supported in pattern
	 */
	static public function glob(string $pattern): array
	{
		return self::callStorage('glob', $pattern);







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







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
			return [$dir];
		}

		// Update this path
		return self::callStorage('list', $parent);
	}


	static public function listForUser(int $id, string $field_name = null): array
	{
		$files = [];
		$path = (string) $id;

		if ($field_name) {
			$path .= '/' . $field_name;
			return self::listForContext(File::CONTEXT_USER, $path);
		}

		foreach (self::listForContext(File::CONTEXT_USER, $path) as $dir) {
			foreach (Files::list($dir->path) as $file) {
				$files[] = $file;
			}
		}

		return $files;
	}

	/**
	 * Returns a list of files or directories matching a glob pattern
	 * only * and ? characters are supported in pattern
	 */
	static public function glob(string $pattern): array
	{
		return self::callStorage('glob', $pattern);

Modified src/include/lib/Garradin/Template.php from [1f5a88a96f] to [53daeee6f6].

330
331
332
333
334
335
336











337
338
339
340
341
342
343

		if (!$field) {
			return htmlspecialchars((string)$v);
		}

		if ($field->type == 'checkbox') {
			return $v ? 'Oui' : 'Non';











		}

		if (empty($v)) {
			return '';
		}

		switch ($field->type)







>
>
>
>
>
>
>
>
>
>
>







330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354

		if (!$field) {
			return htmlspecialchars((string)$v);
		}

		if ($field->type == 'checkbox') {
			return $v ? 'Oui' : 'Non';
		}
		elseif ($field->type == 'file' && isset($params['thumb_url'])) {
			$session = Session::getInstance();

			foreach (Files::listForUser($params['user_id'], $field->name) as $file) {
				return '<aside class="file">'
					. $file->link($session, 'auto', false, $params['thumb_url'])
					. '</aside>';
			}

			return '';
		}

		if (empty($v)) {
			return '';
		}

		switch ($field->type)

Modified src/include/lib/Garradin/Users/Users.php from [7bbdca6b68] to [199ace5aa6].

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
	{
		$df = DynamicFields::getInstance();

		$columns = [
			'_user_id' => [
				'select' => 'id',
			],



			'number' => [
				'label' => 'Num.',
				'select' => $df->getNumberField(),
			],
			'identity' => [
				'label' => $df->getNameLabel(),
				'select' => $df->getNameFieldsSQL(),
			]
		];

		$fields = $df->getListedFields();

		foreach ($fields as $key => $config) {
			if (isset($columns[$key])) {

				continue;
			}

			$columns[$key] = [
				'label' => $config->label,
			];
		}







		$tables = User::TABLE;

		if (!$id_category) {
			$conditions = sprintf('id_category IN (SELECT id FROM users_categories WHERE hidden = 0)');
		}
		elseif ($id_category > 0) {







>
>
>













|
>







>
>
>
>
>
>







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
	{
		$df = DynamicFields::getInstance();

		$columns = [
			'_user_id' => [
				'select' => 'id',
			],
		];

		$default_columns = [
			'number' => [
				'label' => 'Num.',
				'select' => $df->getNumberField(),
			],
			'identity' => [
				'label' => $df->getNameLabel(),
				'select' => $df->getNameFieldsSQL(),
			]
		];

		$fields = $df->getListedFields();

		foreach ($fields as $key => $config) {
			if (isset($default_columns[$key])) {
				$columns[$key] = $default_columns[$key];
				continue;
			}

			$columns[$key] = [
				'label' => $config->label,
			];
		}

		foreach ($default_columns as $key => $config) {
			if (!isset($columns[$key])) {
				$columns[$key] = $config;
			}
		}

		$tables = User::TABLE;

		if (!$id_category) {
			$conditions = sprintf('id_category IN (SELECT id FROM users_categories WHERE hidden = 0)');
		}
		elseif ($id_category > 0) {

Modified src/templates/common/files/_context_list.tpl from [90604d5c96] to [e91bcdce79].

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
	&& Entities\Files\File::canCreate($path . '/')) {
	$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}

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







|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
	&& Entities\Files\File::canCreate($path . '/')) {
	$can_upload = true;
}

?>

{if $can_upload}
<p>
	{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"}
	<?php

Modified src/templates/users/_details.tpl from [a690b32c88] to [7024578010].

1
2
3
4
5
6
7
8
9
10
11
12
<?php
use Garradin\Users\DynamicFields as DF;
assert(isset($user, $show_message_button));

$user_files_path = $user->attachementsDirectory();

$id_fields = DF::getNameFields();
$email_button = 0;
$fields = DF::getInstance()->all();
?>

<dl class="describe">




|







1
2
3
4
5
6
7
8
9
10
11
12
<?php
use Garradin\Users\DynamicFields as DF;
assert(isset($user, $show_message_button));

$user_files_path = $user->attachmentsDirectory();

$id_fields = DF::getNameFields();
$email_button = 0;
$fields = DF::getInstance()->all();
?>

<dl class="describe">
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
			{foreach from=$field.options key="b" item="name"}
				{if (int)$value & (0x01 << (int)$b)}
					<li>{$name}</li>
				{/if}
			{/foreach}
			</ul>
		{else}
			{display_dynamic_field field=$field value=$value}
		{/if}
	</dd>
		{if $field.type == 'email' && $value && ($email = Email\Emails::getEmail($value))}
		<dt>Statut e-mail</dt>
		<dd>
			{if $email.optout}
				<b class="alert">{icon shape="alert"}</b> Ne souhaite plus recevoir de messages







|







47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
			{foreach from=$field.options key="b" item="name"}
				{if (int)$value & (0x01 << (int)$b)}
					<li>{$name}</li>
				{/if}
			{/foreach}
			</ul>
		{else}
			{display_dynamic_field field=$field value=$value user_id=$user.id}
		{/if}
	</dd>
		{if $field.type == 'email' && $value && ($email = Email\Emails::getEmail($value))}
		<dt>Statut e-mail</dt>
		<dd>
			{if $email.optout}
				<b class="alert">{icon shape="alert"}</b> Ne souhaite plus recevoir de messages

Modified src/templates/users/index.tpl from [bc4f7eb5ae] to [5c1fa09b67].

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
	<fieldset>
		<legend>Rechercher un membre</legend>
		<input type="text" name="qt" value="" placeholder="Nom, numéro, ou adresse e-mail" />
		{button type="submit" name="" label="Chercher" shape="search"}
	</fieldset>
</form>

<form method="post" action="action.php" class="memberList">

{if $list->count()}
	{$list->getHTMLPagination()|raw}

	{include file="common/dynamic_list_head.tpl" check=$can_edit}

	{foreach from=$list->iterate() item="row"}







|







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
	<fieldset>
		<legend>Rechercher un membre</legend>
		<input type="text" name="qt" value="" placeholder="Nom, numéro, ou adresse e-mail" />
		{button type="submit" name="" label="Chercher" shape="search"}
	</fieldset>
</form>

<form method="post" action="action.php" class="users-list">

{if $list->count()}
	{$list->getHTMLPagination()|raw}

	{include file="common/dynamic_list_head.tpl" check=$can_edit}

	{foreach from=$list->iterate() item="row"}
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
					<td class="num">
						{link href="details.php?id=%d"|args:$row._user_id label=$value}
					</td>
				{elseif $key == 'identity'}
					<th>{link href="details.php?id=%d"|args:$row._user_id label=$value}</th>
				{else}
					<td>
						{display_dynamic_field key=$key value=$value}
					</td>
				{/if}
			{/foreach}

			<td class="actions">
				{linkbutton label="Fiche membre" shape="user" href="details.php?id=%d"|args:$row._user_id}
				{if $session->canAccess($session::SECTION_USERS, $session::ACCESS_WRITE)}







|







46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
					<td class="num">
						{link href="details.php?id=%d"|args:$row._user_id label=$value}
					</td>
				{elseif $key == 'identity'}
					<th>{link href="details.php?id=%d"|args:$row._user_id label=$value}</th>
				{else}
					<td>
						{display_dynamic_field key=$key value=$value user_id=$row._user_id thumb_url="details.php?id=%d"|args:$row._user_id}
					</td>
				{/if}
			{/foreach}

			<td class="actions">
				{linkbutton label="Fiche membre" shape="user" href="details.php?id=%d"|args:$row._user_id}
				{if $session->canAccess($session::SECTION_USERS, $session::ACCESS_WRITE)}

Modified src/www/admin/static/styles/02-common.css from [667ab000c3] to [c1bc2bcc1b].

268
269
270
271
272
273
274
275
276
277




278
279
280
281
282
283
284
.shortForms {
    display: flex;
    justify-content: space-between;
    flex-direction: row;
    text-align: center;
}

.memberList {
    clear: both;
}





.pagination {
    clear: both;
    list-style-type: none;
    padding: 0.4em 0;
    text-align: center;
}







|


>
>
>
>







268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
.shortForms {
    display: flex;
    justify-content: space-between;
    flex-direction: row;
    text-align: center;
}

.users-list {
    clear: both;
}

.users-list td .file img {
    max-height: 80px;
}

.pagination {
    clear: both;
    list-style-type: none;
    padding: 0.4em 0;
    text-align: center;
}