Overview
Comment:Integrate changes for skeleton edits
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | dev
Files: files | file ages | folders
SHA3-256: ddda7b5850d0cdf08a2cbaab7d12fa7102fd3957759f09ade8b48a678f858ab8
User & Date: bohwaz on 2021-03-02 01:38:54
Other Links: branch diff | manifest | tags
Context
2021-03-02
02:11
Fix sync of files from filesystem check-in: 65f26b0647 user: bohwaz tags: dev
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
Changes

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

320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
	static public function ensureDirectoryExists(string $path): void
	{
		$db = DB::getInstance();
		$parts = explode('/', $path);
		$tree = '';

		foreach ($parts as $part) {
			$tree .= trim($tree . '/' . $part, '/');
			$tree_path = dirname($tree) == '.' ? '' : dirname($tree);
			$tree_name = basename($tree);
			$exists = $db->test(File::TABLE, 'type = ? AND path = ? AND name = ?', self::TYPE_DIRECTORY, $tree_path, $tree_name);

			if (!$exists) {
				try {
					self::createDirectory($tree_path, $tree_name, false);







|







320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
	static public function ensureDirectoryExists(string $path): void
	{
		$db = DB::getInstance();
		$parts = explode('/', $path);
		$tree = '';

		foreach ($parts as $part) {
			$tree = trim($tree . '/' . $part, '/');
			$tree_path = dirname($tree) == '.' ? '' : dirname($tree);
			$tree_name = basename($tree);
			$exists = $db->test(File::TABLE, 'type = ? AND path = ? AND name = ?', self::TYPE_DIRECTORY, $tree_path, $tree_name);

			if (!$exists) {
				try {
					self::createDirectory($tree_path, $tree_name, false);

Modified src/include/lib/Garradin/Files/Files.php from [af6eef26f4] to [e26e126019].

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
		if ($file) {
			Utils::redirect(ADMIN_URL . 'documents/?p=' . $file->path);
		}

		return null;
	}

	static public function list(string $path = null): array
	{
		File::validatePath($path);

		// Update this path
		self::callStorage('sync', $path);

		return EM::getInstance(File::class)->all('SELECT * FROM @TABLE WHERE path = ? ORDER BY type DESC, name COLLATE NOCASE ASC;', $path);







|







30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
		if ($file) {
			Utils::redirect(ADMIN_URL . 'documents/?p=' . $file->path);
		}

		return null;
	}

	static public function list(string $path = ''): array
	{
		File::validatePath($path);

		// Update this path
		self::callStorage('sync', $path);

		return EM::getInstance(File::class)->all('SELECT * FROM @TABLE WHERE path = ? ORDER BY type DESC, name COLLATE NOCASE ASC;', $path);

Modified src/include/lib/Garradin/Web/Skeleton.php from [376165e7c2] to [cabedd0259].

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
	public function raw(): string
	{
		return $this->file ? $this->file->fetch() : file_get_contents($this->defaultPath());
	}

	public function edit(string $content)
	{






		File::createAndStore(File::CONTEXT_SKELETON, $this->name, null, $content);

	}

	public function type(): string
	{
		$name = $this->file->name ?? $this->defaultPath();
		$ext = substr($name, strrpos($name, '.')+1);

		if ($ext == 'css') {
			return 'text/css';
		}
		elseif ($ext == 'html') {
			return 'text/html';
		}
		elseif ($ext == 'js') {
			return 'text/javascript';
		}

		if ($this->file) {
			return $this->file->type;
		}

		$finfo = \finfo_open(\FILEINFO_MIME_TYPE);
		return finfo_file($finfo, $this->defaultPath());

	}

	public function reset()







>
>
>
>
>
>
|
>



















|







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
	public function raw(): string
	{
		return $this->file ? $this->file->fetch() : file_get_contents($this->defaultPath());
	}

	public function edit(string $content)
	{
		$file = Files::get(File::CONTEXT_SKELETON, $this->name);

		if ($file) {
			$file->setContent($content);
		}
		else {
			File::createAndStore(File::CONTEXT_SKELETON, $this->name, null, $content);
		}
	}

	public function type(): string
	{
		$name = $this->file->name ?? $this->defaultPath();
		$ext = substr($name, strrpos($name, '.')+1);

		if ($ext == 'css') {
			return 'text/css';
		}
		elseif ($ext == 'html') {
			return 'text/html';
		}
		elseif ($ext == 'js') {
			return 'text/javascript';
		}

		if ($this->file) {
			return $this->file->type;
  		}

		$finfo = \finfo_open(\FILEINFO_MIME_TYPE);
		return finfo_file($finfo, $this->defaultPath());

	}

	public function reset()
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
		}

		$dir->close();

		$list = Files::list(File::CONTEXT_SKELETON);

		foreach ($list as $file) {




			$sources[$file->name] = $file;
		}

		ksort($sources);

		return $sources;
	}

	static public function upload(string $name, ?string $file): void
	{
		if (empty($_FILES[$file]['tmp_name'])) {
			File::createAndStore($name, File::CONTEXT_SKELETON, null, null, 'À modifier…');
		}
		else {
			$f = File::upload($file, File::CONTEXT_SKELETON, null);

			if ($f->name != $name) {
				$f->importForm(['name' => $name]);
				$f->save();
			}
		}
	}
}







>
>
>
>







|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227















		}

		$dir->close();

		$list = Files::list(File::CONTEXT_SKELETON);

		foreach ($list as $file) {
			if ($file->type != $file::TYPE_FILE) {
				continue;
			}

			$sources[$file->name] = $file;
		}

		ksort($sources);

		return $sources;
	}
}















Modified src/templates/docs/index.tpl from [6d9678f1c0] to [191bc1e014].

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
<?php
use Garradin\Entities\Files\File;
?>
{include file="admin/_head.tpl" title="Documents" current="docs"}

<nav class="tabs">
	<aside>
		{linkbutton shape="search" label="Rechercher" href="search.php"}
	{if $context == File::CONTEXT_DOCUMENTS}
		{linkbutton shape="plus" label="Nouveau répertoire" target="_dialog" href="!docs/new_dir.php?parent=%s"|args:$path}
		{linkbutton shape="plus" label="Nouveau fichier texte" target="_dialog" href="!docs/new_file.php?parent=%s"|args:$path}
		{linkbutton shape="upload" label="Ajouter un fichier" target="_dialog" href="!common/files/upload.php?p=%s"|args:$path}
	{/if}
	</aside>
	<ul>
		<li{if $context == File::CONTEXT_DOCUMENTS} class="current"{/if}><a href="./">Documents</a></li>
		{if $session->canAccess($session::SECTION_ACCOUNTING, $session::ACCESS_ADMIN)}
			<li{if $context == File::CONTEXT_TRANSACTION} class="current"{/if}><a href="./?p=<?=File::CONTEXT_TRANSACTION?>">Fichiers des écritures</a></li>
		{/if}
		{if $session->canAccess($session::SECTION_USERS, $session::ACCESS_ADMIN)}
			<li{if $context == File::CONTEXT_USER} class="current"{/if}><a href="./?p=<?=File::CONTEXT_USER?>">Fichiers des membres</a></li>
		{/if}



	</ul>
</nav>

{if count($files)}
<table class="list">
	<thead>
		<tr>








|
|
|











>
>
>







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
<?php
use Garradin\Entities\Files\File;
?>
{include file="admin/_head.tpl" title="Documents" current="docs"}

<nav class="tabs">
	<aside>
		{linkbutton shape="search" label="Rechercher" href="search.php"}
	{if $context == File::CONTEXT_DOCUMENTS || $context == File::CONTEXT_SKELETON}
		{linkbutton shape="plus" label="Nouveau répertoire" target="_dialog" href="!docs/new_dir.php?p=%s"|args:$path}
		{linkbutton shape="plus" label="Nouveau fichier texte" target="_dialog" href="!docs/new_file.php?p=%s"|args:$path}
		{linkbutton shape="upload" label="Ajouter un fichier" target="_dialog" href="!common/files/upload.php?p=%s"|args:$path}
	{/if}
	</aside>
	<ul>
		<li{if $context == File::CONTEXT_DOCUMENTS} class="current"{/if}><a href="./">Documents</a></li>
		{if $session->canAccess($session::SECTION_ACCOUNTING, $session::ACCESS_ADMIN)}
			<li{if $context == File::CONTEXT_TRANSACTION} class="current"{/if}><a href="./?p=<?=File::CONTEXT_TRANSACTION?>">Fichiers des écritures</a></li>
		{/if}
		{if $session->canAccess($session::SECTION_USERS, $session::ACCESS_ADMIN)}
			<li{if $context == File::CONTEXT_USER} class="current"{/if}><a href="./?p=<?=File::CONTEXT_USER?>">Fichiers des membres</a></li>
		{/if}
		{if $session->canAccess($session::SECTION_WEB, $session::ACCESS_ADMIN)}
			<li{if $context == File::CONTEXT_SKELETON} class="current"{/if}><a href="./?p=<?=File::CONTEXT_SKELETON?>">Squelettes du site web</a></li>
		{/if}
	</ul>
</nav>

{if count($files)}
<table class="list">
	<thead>
		<tr>
100
101
102
103
104
105
106


107
108
109
						{button type="submit" value="OK" shape="right" label="Valider"}
					</noscript>
				{/if}
			</td>
		</tr>
	</tfoot>
</table>


{/if}

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







>
>



103
104
105
106
107
108
109
110
111
112
113
114
						{button type="submit" value="OK" shape="right" label="Valider"}
					</noscript>
				{/if}
			</td>
		</tr>
	</tfoot>
</table>
{else}
	<p class="alert block">Il n'y a aucun fichier dans ce répertoire.</p>
{/if}

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

Modified src/templates/web/config.tpl from [4a8cd02411] to [a25a113f9c].

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
		</table>

		<p class="actions">
			Pour les squelettes sélectionnés&nbsp;:
			<input type="submit" name="reset" value="Réinitialiser" onclick="return confirm('Effacer toute modification locale et restaurer les squelettes d\'installation ?');" />
			{csrf_field key="squelettes"}
		</p>
	</fieldset>
	</form>

	<form method="post" enctype="multipart/form-data">
		<fieldset>
			<legend>Ajouter un nouveau squelette</legend>
			<dl>
				{input type="text" name="name" label="Nom de fichier" required=true}
				{input type="file" name="file" label="Fichier" help="Si aucun fichier n'est sélectionné, un fichier texte vide sera créé"}
			</dl>
			<p class="submit">
				{csrf_field key="skel_upload"}
				{button type="submit" name="upload" label="Ajouter" shape="upload"}

			</p>
		</fieldset>
	</form>

	{literal}
	<script type="text/javascript">
	let f = $('#f_file');
	let n = $('#f_name');
	f.onchange = () => {
		if (!f.files.length) {
			return;
		}

		n.value = f.files[0].name.split(/(\\|\/)/g).pop();
	}
	</script>
	{/literal}
{/if}

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







<
<

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


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



111
112
113
114
115
116
117


118



119






120
121
122
123
124













125
126
127
		</table>

		<p class="actions">
			Pour les squelettes sélectionnés&nbsp;:
			<input type="submit" name="reset" value="Réinitialiser" onclick="return confirm('Effacer toute modification locale et restaurer les squelettes d\'installation ?');" />
			{csrf_field key="squelettes"}
		</p>






		<p>






			{linkbutton href="!docs/?p=skel" label="Gérer les fichiers de squelettes" shape="folder"}
		</p>
	</fieldset>
	</form>














{/if}

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

Modified src/www/admin/common/files/delete.php from [f065ec177f] to [344750af83].

11
12
13
14
15
16
17




18
19
20
21
22
23
24
25
26
27
if (!$file) {
	throw new UserException('Fichier inconnu');
}

if (!$file->checkDeleteAccess($session)) {
    throw new UserException('Vous n\'avez pas le droit de supprimer ce fichier.');
}





$csrf_key = 'file_delete_' . $file->pathHash();

$form->runIf('delete', function () use ($file) {
	$file->delete();
}, $csrf_key, '!');

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

$tpl->display('common/files/delete.tpl');







>
>
>
>










11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
if (!$file) {
	throw new UserException('Fichier inconnu');
}

if (!$file->checkDeleteAccess($session)) {
    throw new UserException('Vous n\'avez pas le droit de supprimer ce fichier.');
}

if ($file->context() == File::CONTEXT_CONFIG) {
	throw new UserException('Vous n\'avez pas le droit de supprimer ce fichier.');
}

$csrf_key = 'file_delete_' . $file->pathHash();

$form->runIf('delete', function () use ($file) {
	$file->delete();
}, $csrf_key, '!');

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

$tpl->display('common/files/delete.tpl');

Modified src/www/admin/docs/_inc.php from [2b0106275a] to [f36ddb9ac0].

1
2
3
4
5
6
7
8
9
<?php

namespace Garradin;

use Garradin\Membres\Session;

require_once __DIR__ . '/../_inc.php';

$session->requireAccess(Session::SECTION_DOCUMENTS, $session::ACCESS_READ);








|
1
2
3
4
5
6
7
8
9
<?php

namespace Garradin;

use Garradin\Membres\Session;

require_once __DIR__ . '/../_inc.php';

$session->requireAccess(Session::SECTION_DOCUMENTS, Session::ACCESS_READ);

Modified src/www/admin/docs/new_dir.php from [e455b186eb] to [e00667d877].

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
<?php

namespace Garradin;

use Garradin\Files\Files;
use Garradin\Entities\Files\File;

require_once __DIR__ . '/_inc.php';

$parent = trim(qg('parent'));

if (!File::checkCreateAccess(File::CONTEXT_DOCUMENTS, $session)) {
	throw new UserException('Vous n\'avez pas le droit de créer de répertoire ici.');
}

$csrf_key = 'create_dir';

$form->runIf('create', function () use ($parent) {
	$name = trim(f('name'));
	File::validatePath($parent . '/' . $name);
	File::createDirectory($path, $name);
}, $csrf_key, '!docs/?p=' . $parent);

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

$tpl->display('docs/new_dir.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
<?php

namespace Garradin;

use Garradin\Files\Files;
use Garradin\Entities\Files\File;

require_once __DIR__ . '/_inc.php';

$parent = trim(qg('p'));

if (!File::checkCreateAccess(File::CONTEXT_DOCUMENTS, $session)) {
	throw new UserException('Vous n\'avez pas le droit de créer de répertoire ici.');
}

$csrf_key = 'create_dir';

$form->runIf('create', function () use ($parent) {
	$name = trim(f('name'));
	File::validatePath($parent . '/' . $name);
	File::createDirectory($parent, $name);
}, $csrf_key, '!docs/?p=' . $parent);

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

$tpl->display('docs/new_dir.tpl');

Modified src/www/admin/docs/new_file.php from [9d133aa2ff] to [b3c87b98b2].

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
$form->runIf('create', function () use ($parent) {
	$name = trim(f('name'));

	if (!strpos($name, '.')) {
		$name .= '.txt';
	}

	$path = trim(File::CONTEXT_DOCUMENTS . '/' . $parent, '/');
	File::validatePath($path . '/' . $name);

	$file = File::createAndStore($path, $name, null, '');
	$file->set('mime', 'text/plain');
	$file->save();
}, $csrf_key, '!docs/?p=' . $parent);

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

$tpl->display('docs/new_file.tpl');







<
|

|







18
19
20
21
22
23
24

25
26
27
28
29
30
31
32
33
34
$form->runIf('create', function () use ($parent) {
	$name = trim(f('name'));

	if (!strpos($name, '.')) {
		$name .= '.txt';
	}


	File::validatePath($parent . '/' . $name);

	$file = File::createAndStore($parent, $name, null, '');
	$file->set('mime', 'text/plain');
	$file->save();
}, $csrf_key, '!docs/?p=' . $parent);

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

$tpl->display('docs/new_file.tpl');

Modified src/www/admin/web/config.php from [829964f01d] to [88ef818b0b].

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
	Utils::redirect(Utils::getSelfURI());
}

$form->runIf('reset', function () {
	Skeleton::resetSelected(f('select'));
}, 'squelettes', Utils::getSelfURI('reset_ok'));

$form->runIf('upload', function () {
	Skeleton::upload(f('name'), 'file');
}, 'skel_upload', Utils::getSelfURI());

if (qg('edit')) {
	$source = trim(qg('edit'));
	$csrf_key = 'edit_skel_' . md5($source);

	$form->runIf('save', function () use ($source) {
		$tpl = new Skeleton($source);
		$tpl->edit(f('content'));







<
<
<
<







20
21
22
23
24
25
26




27
28
29
30
31
32
33
	Utils::redirect(Utils::getSelfURI());
}

$form->runIf('reset', function () {
	Skeleton::resetSelected(f('select'));
}, 'squelettes', Utils::getSelfURI('reset_ok'));





if (qg('edit')) {
	$source = trim(qg('edit'));
	$csrf_key = 'edit_skel_' . md5($source);

	$form->runIf('save', function () use ($source) {
		$tpl = new Skeleton($source);
		$tpl->edit(f('content'));