Overview
Comment:Fix dirname/basename locale issues
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | dev
Files: files | file ages | folders
SHA3-256: 3dd4c3e1c419958449d90af142f3c00dec563f30029ec8bddd4dc024a4d7636f
User & Date: bohwaz on 2021-03-30 21:21:46
Other Links: branch diff | manifest | tags
Context
2021-03-30
21:23
Fix session issue check-in: 0efff9c95b user: bohwaz tags: dev
21:21
Fix dirname/basename locale issues check-in: 3dd4c3e1c4 user: bohwaz tags: dev
20:59
Fix skriv rendering for format_skriv check-in: 0917eeafc4 user: bohwaz tags: dev
Changes

Modified src/include/lib/Garradin/Config.php from [bd9116ce79] to [3ee283733a].

198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
		elseif (isset($source['admin_background']) && strlen($source['admin_background'])) {
			$file = Files::get(self::ADMIN_BACKGROUND_FILENAME);

			if ($file) {
				$file->storeFromBase64($source['admin_background']);
			}
			else {
				$file = File::createFromBase64(dirname(self::ADMIN_BACKGROUND_FILENAME), basename(self::ADMIN_BACKGROUND_FILENAME), $source['admin_background']);
			}

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

		parent::importForm($source);
	}







|







198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
		elseif (isset($source['admin_background']) && strlen($source['admin_background'])) {
			$file = Files::get(self::ADMIN_BACKGROUND_FILENAME);

			if ($file) {
				$file->storeFromBase64($source['admin_background']);
			}
			else {
				$file = File::createFromBase64(Utils::dirname(self::ADMIN_BACKGROUND_FILENAME), Utils::basename(self::ADMIN_BACKGROUND_FILENAME), $source['admin_background']);
			}

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

		parent::importForm($source);
	}

Modified src/include/lib/Garradin/DB.php from [d0ee50b78a] to [f7de57d793].

45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
        $this->db->busyTimeout(10 * 1000);

        // Performance enhancement
        // see https://www.cs.utexas.edu/~jaya/slides/apsys17-sqlite-slides.pdf
        // https://ericdraken.com/sqlite-performance-testing/
        $this->exec(sprintf('PRAGMA journal_mode = WAL; PRAGMA synchronous = NORMAL; PRAGMA journal_size_limit = %d;', 32 * 1024 * 1024));

        $this->db->createFunction('dirname', 'dirname');
        $this->db->createFunction('basename', 'basename');
        $this->db->createCollation('NOCASE', [static::class, 'unicodeCaseComparison']);
    }

    static public function unicodeCaseComparison($a, $b): int
    {
        if (function_exists('mb_strtoupper')) {
            $a = mb_strtoupper($a);







|
|







45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
        $this->db->busyTimeout(10 * 1000);

        // Performance enhancement
        // see https://www.cs.utexas.edu/~jaya/slides/apsys17-sqlite-slides.pdf
        // https://ericdraken.com/sqlite-performance-testing/
        $this->exec(sprintf('PRAGMA journal_mode = WAL; PRAGMA synchronous = NORMAL; PRAGMA journal_size_limit = %d;', 32 * 1024 * 1024));

        $this->db->createFunction('dirname', [Utils::class, 'dirname']);
        $this->db->createFunction('basename', [Utils::class, 'basename']);
        $this->db->createCollation('NOCASE', [static::class, 'unicodeCaseComparison']);
    }

    static public function unicodeCaseComparison($a, $b): int
    {
        if (function_exists('mb_strtoupper')) {
            $a = mb_strtoupper($a);

Modified src/include/lib/Garradin/Entities/Files/File.php from [484cde5ea4] to [6c19806068].

360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
...
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495

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

			if (!$exists) {
				try {
					self::createDirectory(dirname($tree) == '.' ? '' : dirname($tree), basename($tree), false);
				}
				catch (ValidationException $e) {
					// Ignore when directory already exists
				}
			}
		}
	}
................................................................................
				return 'Erreur inconnue: ' . $error;
		}
	}

	public function url(bool $download = false): string
	{
		if ($this->context() == self::CONTEXT_WEB) {
			$path = basename(dirname($this->path)) . '/' . basename($this->path);
		}
		else {
			$path = $this->path;
		}


		$url = WWW_URL . $path;







|







 







|







360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
...
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495

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

			if (!$exists) {
				try {
					self::createDirectory(Utils::dirname($tree), Utils::basename($tree), false);
				}
				catch (ValidationException $e) {
					// Ignore when directory already exists
				}
			}
		}
	}
................................................................................
				return 'Erreur inconnue: ' . $error;
		}
	}

	public function url(bool $download = false): string
	{
		if ($this->context() == self::CONTEXT_WEB) {
			$path = Utils::basename(Utils::dirname($this->path)) . '/' . Utils::basename($this->path);
		}
		else {
			$path = $this->path;
		}


		$url = WWW_URL . $path;

Modified src/include/lib/Garradin/Entities/Web/Page.php from [1f96639f44] to [e9e7fc4699].

165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
...
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
...
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
...
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
	{
		$export = $this->export();
		$path = $this->filepath();
		$target = $this->filepath(false);

		// Move parent directory if needed
		if ($path !== $target) {
			$dir = Files::get(dirname($path));
			$dir->rename(dirname($target));
			$this->set('file_path', $target);
			$this->_file = null;
		}

		if (!$this->file()) {
			$file = $this->_file = File::createAndStore(dirname($target), basename($target), null, $export);
			$this->set('modified', new \DateTime);
		}
		elseif ($this->file()->fetch() !== $export) {
			$this->file()->store(null, $this->export());
			$this->set('modified', $this->file()->modified);
		}

................................................................................
		parent::save();

		return true;
	}

	public function delete(): bool
	{
		Files::get(dirname($this->file_path))->delete();
		return parent::delete();
	}

	public function selfCheck(): void
	{
		$db = DB::getInstance();
		$this->assert($this->type === self::TYPE_CATEGORY || $this->type === self::TYPE_PAGE, 'Unknown page type');
................................................................................
			SELECT path, title FROM parents ORDER BY level DESC;';
		return DB::getInstance()->getAssoc($sql, $this->id());
	}

	public function listAttachments(): array
	{
		if (null === $this->_attachments) {
			$list = Files::list(dirname($this->filepath()));

			// Remove the page itself
			$list = array_filter($list, function ($a) {
				return $a->name != $this->_name && $a->type != $a::TYPE_DIRECTORY;
			});

			$this->_attachments = $list;
................................................................................

	static public function fromFile(File $file): self
	{
		$page = new self;

		// Path is relative to web root
		$page->set('file_path', $file->path);
		$page->set('path', substr(dirname($file->path), strlen(File::CONTEXT_WEB . '/')));
		$page->set('uri', basename($page->path));
		$page->set('parent', dirname($page->path) == '.' ? '' : dirname($page->path));

		$page->loadFromFile($file);
		return $page;
	}
}







|
|





|







 







|







 







|







 







|
|
|





165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
...
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
...
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
...
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
	{
		$export = $this->export();
		$path = $this->filepath();
		$target = $this->filepath(false);

		// Move parent directory if needed
		if ($path !== $target) {
			$dir = Files::get(Utils::dirname($path));
			$dir->rename(Utils::dirname($target));
			$this->set('file_path', $target);
			$this->_file = null;
		}

		if (!$this->file()) {
			$file = $this->_file = File::createAndStore(Utils::dirname($target), Utils::basename($target), null, $export);
			$this->set('modified', new \DateTime);
		}
		elseif ($this->file()->fetch() !== $export) {
			$this->file()->store(null, $this->export());
			$this->set('modified', $this->file()->modified);
		}

................................................................................
		parent::save();

		return true;
	}

	public function delete(): bool
	{
		Files::get(Utils::dirname($this->file_path))->delete();
		return parent::delete();
	}

	public function selfCheck(): void
	{
		$db = DB::getInstance();
		$this->assert($this->type === self::TYPE_CATEGORY || $this->type === self::TYPE_PAGE, 'Unknown page type');
................................................................................
			SELECT path, title FROM parents ORDER BY level DESC;';
		return DB::getInstance()->getAssoc($sql, $this->id());
	}

	public function listAttachments(): array
	{
		if (null === $this->_attachments) {
			$list = Files::list(Utils::dirname($this->filepath()));

			// Remove the page itself
			$list = array_filter($list, function ($a) {
				return $a->name != $this->_name && $a->type != $a::TYPE_DIRECTORY;
			});

			$this->_attachments = $list;
................................................................................

	static public function fromFile(File $file): self
	{
		$page = new self;

		// Path is relative to web root
		$page->set('file_path', $file->path);
		$page->set('path', substr(Utils::dirname($file->path), strlen(File::CONTEXT_WEB . '/')));
		$page->set('uri', Utils::basename($page->path));
		$page->set('parent', Utils::dirname($page->path) == '.' ? '' : Utils::dirname($page->path));

		$page->loadFromFile($file);
		return $page;
	}
}

Modified src/include/lib/Garradin/Files/Storage/FileSystem.php from [6719415913] to [41e39a13ce].

155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170



171
172
173
174
175
176
177
		return self::_SplToFile($file);
	}

	static protected function _SplToFile(\SplFileInfo $spl): File
	{
		$path = str_replace(self::_getRoot() . DIRECTORY_SEPARATOR, '', $spl->getPathname());
		$path = str_replace(DIRECTORY_SEPARATOR, '/', $path);
		$parent = dirname($path);

		if ($parent == '.' || !$parent) {
			$parent = '';
		}

		$data = [
			'id'       => null,
			'name'     => $spl->getBasename(),



			'path'     => $path,
			'parent'   => $parent,
			'modified' => new \DateTime('@' . $spl->getMTime()),
			'size'     => $spl->getSize(),
			'type'     => $spl->isDir() ? File::TYPE_DIRECTORY : File::TYPE_FILE,
			'mime'     => mime_content_type($spl->getRealPath()),
		];







|







|
>
>
>







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
		return self::_SplToFile($file);
	}

	static protected function _SplToFile(\SplFileInfo $spl): File
	{
		$path = str_replace(self::_getRoot() . DIRECTORY_SEPARATOR, '', $spl->getPathname());
		$path = str_replace(DIRECTORY_SEPARATOR, '/', $path);
		$parent = Utils::dirname($path);

		if ($parent == '.' || !$parent) {
			$parent = '';
		}

		$data = [
			'id'       => null,
			// may return slash
			// see comments https://www.php.net/manual/fr/splfileinfo.getfilename.php
			// don't use getBasename as it is locale-dependent!
			'name'     => trim($spl->getFilename(), '/'),
			'path'     => $path,
			'parent'   => $parent,
			'modified' => new \DateTime('@' . $spl->getMTime()),
			'size'     => $spl->getSize(),
			'type'     => $spl->isDir() ? File::TYPE_DIRECTORY : File::TYPE_FILE,
			'mime'     => mime_content_type($spl->getRealPath()),
		];

Modified src/include/lib/Garradin/Files/Storage/SQLite.php from [902a317241] to [a974b86035].

122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
...
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
	static public function list(string $path): array
	{
		return EM::getInstance(File::class)->all('SELECT * FROM @TABLE WHERE parent = ? ORDER BY type DESC, name COLLATE NOCASE ASC;', $path);
	}

	static public function exists(string $path): bool
	{
		return DB::getInstance()->test('files', 'path = ? AND name = ?', dirname($path), basename($path));
	}

	static public function delete(File $file): bool
	{
		$db = DB::getInstance();

		$cache_id = 'files.' . $file->pathHash();
................................................................................
		return true;
	}

	static public function move(File $file, string $new_path): bool
	{
		$current_path = $file->path;
		$file->set('path', $new_path);
		$file->set('parent', dirname($new_path));
		$file->set('name', basename($new_path));
		$file->save();

		if ($file->type == File::TYPE_DIRECTORY) {
			// Move sub-directories and sub-files
			DB::getInstance()->preparedQuery('UPDATE files SET parent = ?, path = TRIM(? || \'/\' || name, \'/\') WHERE parent = ?;', $new_path, $new_path, $current_path);
		}








|







 







|
|







122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
...
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
	static public function list(string $path): array
	{
		return EM::getInstance(File::class)->all('SELECT * FROM @TABLE WHERE parent = ? ORDER BY type DESC, name COLLATE NOCASE ASC;', $path);
	}

	static public function exists(string $path): bool
	{
		return DB::getInstance()->test('files', 'path = ? AND name = ?', Utils::dirname($path), Utils::basename($path));
	}

	static public function delete(File $file): bool
	{
		$db = DB::getInstance();

		$cache_id = 'files.' . $file->pathHash();
................................................................................
		return true;
	}

	static public function move(File $file, string $new_path): bool
	{
		$current_path = $file->path;
		$file->set('path', $new_path);
		$file->set('parent', Utils::dirname($new_path));
		$file->set('name', Utils::basename($new_path));
		$file->save();

		if ($file->type == File::TYPE_DIRECTORY) {
			// Move sub-directories and sub-files
			DB::getInstance()->preparedQuery('UPDATE files SET parent = ?, path = TRIM(? || \'/\' || name, \'/\') WHERE parent = ?;', $new_path, $new_path, $current_path);
		}

Modified src/include/lib/Garradin/UserTemplate/Sections.php from [557447232f] to [66f75daf66].

194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
				return null;
			}

			// Store attachments in temp table
			$db = DB::getInstance();
			$db->begin();
			$db->exec('CREATE TEMP TABLE IF NOT EXISTS web_pages_attachments (page_id, path, name, modified, image);');
			$page_file_name = basename($page->file_path);

			foreach ($page->listAttachments() as $file) {
				if ($file->name == $page_file_name || $file->type != File::TYPE_FILE) {
					continue;
				}

				$db->preparedQuery('INSERT OR REPLACE INTO web_pages_attachments VALUES (?, ?, ?, ?, ?);',







|







194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
				return null;
			}

			// Store attachments in temp table
			$db = DB::getInstance();
			$db->begin();
			$db->exec('CREATE TEMP TABLE IF NOT EXISTS web_pages_attachments (page_id, path, name, modified, image);');
			$page_file_name = Utils::basename($page->file_path);

			foreach ($page->listAttachments() as $file) {
				if ($file->name == $page_file_name || $file->type != File::TYPE_FILE) {
					continue;
				}

				$db->preparedQuery('INSERT OR REPLACE INTO web_pages_attachments VALUES (?, ?, ?, ?, ?);',

Modified src/include/lib/Garradin/UserTemplate/UserTemplate.php from [18d9728636] to [8a0473ee5b].

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
			$code = $this->compile($source);
			file_put_contents($tmp_path, $code);

			require $tmp_path;
		}
		catch (Brindille_Exception $e) {
			throw new Brindille_Exception(sprintf("Erreur de syntaxe dans '%s' : %s",
				$this->file ? $this->file->name : basename($this->path),
				$e->getMessage()), 0, $e);
		}
		catch (\Throwable $e) {
			// Don't delete temporary file as it can be used to debug
			throw $e;
		}

		if (!file_exists(dirname($compiled_path))) {
			Utils::safe_mkdir(dirname($compiled_path), 0777, true);
		}

		rename($tmp_path, $compiled_path);
	}

	public function fetch(): string
	{
		ob_start();
		$this->display();
		return ob_get_clean();
	}
}







|







|
|












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
			$code = $this->compile($source);
			file_put_contents($tmp_path, $code);

			require $tmp_path;
		}
		catch (Brindille_Exception $e) {
			throw new Brindille_Exception(sprintf("Erreur de syntaxe dans '%s' : %s",
				$this->file ? $this->file->name : Utils::basename($this->path),
				$e->getMessage()), 0, $e);
		}
		catch (\Throwable $e) {
			// Don't delete temporary file as it can be used to debug
			throw $e;
		}

		if (!file_exists(Utils::dirname($compiled_path))) {
			Utils::safe_mkdir(Utils::dirname($compiled_path), 0777, true);
		}

		rename($tmp_path, $compiled_path);
	}

	public function fetch(): string
	{
		ob_start();
		$this->display();
		return ob_get_clean();
	}
}

Modified src/include/lib/Garradin/Utils.php from [ff79e5d16a] to [d4dc8dfafb].

859
860
861
862
863
864
865
866






















        $str = preg_replace('![^\w\d_-]!i', '-', $str);
        $str = preg_replace('!-{2,}!', '-', $str);
        $str = trim($str, '-');

        return $str;
    }
}




























|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887

        $str = preg_replace('![^\w\d_-]!i', '-', $str);
        $str = preg_replace('!-{2,}!', '-', $str);
        $str = trim($str, '-');

        return $str;
    }

    /**
     * dirname may have undefined behaviour depending on the locale!
     */
    static public function dirname(string $str): string
    {
        $str = str_replace(DIRECTORY_SEPARATOR, '/', $str);
        return substr($str, 0, strrpos($str, '/'));
    }

    /**
     * basename may have undefined behaviour depending on the locale!
     */
    static public function basename(string $str): string
    {
        $str = str_replace(DIRECTORY_SEPARATOR, '/', $str);
        $str = trim($str, '/');
        $str = substr($str, strrpos($str, '/'));
        $str = trim($str, '/');
        return $str;
    }
}

Modified src/include/lib/Garradin/Web/Render/Skriv.php from [980088f618] to [f000051146].

38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
..
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
		// "bla/Image.jpg" in web context or absolute link, eg. "/transactions/2442/42.jpg"
		else {
			return WWW_URL . '/' . ltrim($uri, '/');
		}
	}

	static public function resolveLink(string $uri) {
		if (strpos(basename($uri), '.') === false) {
			$uri .= self::$link_suffix;
		}

		return self::$link_prefix . $uri;
	}

	static public function render(?File $file, ?string $content = null, array $options = []): string
................................................................................
			// Enregistrer d'autres extensions éventuellement
			Plugin::fireSignal('skriv.init', ['skriv' => self::$skriv]);
		}

		$skriv =& self::$skriv;

		if ($file) {
			self::$current_path = dirname($file->path);
			self::$context = strtok(self::$current_path, '/');
			self::$link_suffix = '';

			if (self::$context === File::CONTEXT_WEB) {
				self::$link_prefix = WWW_URL . '/';
				self::$current_path = basename(dirname($file->path));
			}
			else {
				self::$link_prefix = $options['prefix'] ?? sprintf(ADMIN_URL . 'common/files/preview.php?p=%s/', self::$context);
				self::$link_suffix = '.skriv';
			}
		}








|







 







|





|







38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
..
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
		// "bla/Image.jpg" in web context or absolute link, eg. "/transactions/2442/42.jpg"
		else {
			return WWW_URL . '/' . ltrim($uri, '/');
		}
	}

	static public function resolveLink(string $uri) {
		if (strpos(Utils::basename($uri), '.') === false) {
			$uri .= self::$link_suffix;
		}

		return self::$link_prefix . $uri;
	}

	static public function render(?File $file, ?string $content = null, array $options = []): string
................................................................................
			// Enregistrer d'autres extensions éventuellement
			Plugin::fireSignal('skriv.init', ['skriv' => self::$skriv]);
		}

		$skriv =& self::$skriv;

		if ($file) {
			self::$current_path = Utils::dirname($file->path);
			self::$context = strtok(self::$current_path, '/');
			self::$link_suffix = '';

			if (self::$context === File::CONTEXT_WEB) {
				self::$link_prefix = WWW_URL . '/';
				self::$current_path = Utils::basename(Utils::dirname($file->path));
			}
			else {
				self::$link_prefix = $options['prefix'] ?? sprintf(ADMIN_URL . 'common/files/preview.php?p=%s/', self::$context);
				self::$link_suffix = '.skriv';
			}
		}

Modified src/include/lib/Garradin/Web/Web.php from [db08c3433b] to [965b8ef77a].

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
...
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
class Web
{
	static public function search(string $search): array
	{
		$results = Files::search($search, File::CONTEXT_WEB . '%');

		foreach ($results as &$result) {
			$result->uri = dirname(substr($result->path, strlen(File::CONTEXT_WEB) + 1));
			$result->breadcrumbs = [];
			$path = '';

			foreach (explode('/', $result->uri) as $part) {
				$path = trim($path . '/' . $part, '/');
				$result->breadcrumbs[$path] = $part;
			}
................................................................................

	static public function getAttachmentFromURI(string $uri): ?File
	{
		if (strpos($uri, '/') === false) {
			return null;
		}

		$path = DB::getInstance()->firstColumn('SELECT path FROM web_pages WHERE uri = ?;', dirname($uri));

		if (!$path) {
			return null;
		}

		return Files::getFromURI(File::CONTEXT_WEB . '/' . $path . '/' . basename($uri));
	}

	static public function dispatchURI()
	{
		$uri = !empty($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '/';

		if ($pos = strpos($uri, '?')) {







|







 







|





|







20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
...
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
class Web
{
	static public function search(string $search): array
	{
		$results = Files::search($search, File::CONTEXT_WEB . '%');

		foreach ($results as &$result) {
			$result->uri = Utils::dirname(substr($result->path, strlen(File::CONTEXT_WEB) + 1));
			$result->breadcrumbs = [];
			$path = '';

			foreach (explode('/', $result->uri) as $part) {
				$path = trim($path . '/' . $part, '/');
				$result->breadcrumbs[$path] = $part;
			}
................................................................................

	static public function getAttachmentFromURI(string $uri): ?File
	{
		if (strpos($uri, '/') === false) {
			return null;
		}

		$path = DB::getInstance()->firstColumn('SELECT path FROM web_pages WHERE uri = ?;', Utils::dirname($uri));

		if (!$path) {
			return null;
		}

		return Files::getFromURI(File::CONTEXT_WEB . '/' . $path . '/' . Utils::basename($uri));
	}

	static public function dispatchURI()
	{
		$uri = !empty($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '/';

		if ($pos = strpos($uri, '?')) {

Modified src/www/admin/config/index.php from [665271c0ad] to [b8ee1564e9].

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
	'color2'           => ADMIN_COLOR2,
	'garradin_website' => WEBSITE,
]);

$homepage = $config->admin_homepage;

if ($homepage && !Files::get($homepage)) {
	File::createAndStore(dirname($homepage), basename($homepage), null, '');
}

$admin_background = $config->get('admin_background');

$tpl->assign('background_image_current', $admin_background ? WWW_URL . $admin_background : null);
$tpl->assign('background_image_default', ADMIN_BACKGROUND_IMAGE);

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







|









28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
	'color2'           => ADMIN_COLOR2,
	'garradin_website' => WEBSITE,
]);

$homepage = $config->admin_homepage;

if ($homepage && !Files::get($homepage)) {
	File::createAndStore(Utils::dirname($homepage), Utils::basename($homepage), null, '');
}

$admin_background = $config->get('admin_background');

$tpl->assign('background_image_current', $admin_background ? WWW_URL . $admin_background : null);
$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/docs/index.php from [0063270f33] to [c2e76c334f].

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
$can_create = File::checkCreateAccess($path, $session);
$can_upload = $can_create && (($context == File::CONTEXT_DOCUMENTS || $context == File::CONTEXT_SKELETON)
	|| (($context == File::CONTEXT_USER || $context == File::CONTEXT_TRANSACTION) && $context_ref));
$can_mkdir = $can_create && ($context == File::CONTEXT_DOCUMENTS || $context == File::CONTEXT_SKELETON);

$breadcrumbs = Files::getBreadcrumbs($path);

$parent_path = dirname($path);

$quota_used = Files::getUsedQuota();
$quota_max = Files::getQuota();
$quota_left = Files::getRemainingQuota();
$quota_percent = round(($quota_used / $quota_max) * 100);

$tpl->assign(compact('path', 'files', 'can_write', 'can_delete', 'can_mkdir', 'can_upload', 'context', 'context_ref', 'breadcrumbs', 'parent_path', 'quota_used', 'quota_max', 'quota_percent', 'quota_left'));

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







|









32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
$can_create = File::checkCreateAccess($path, $session);
$can_upload = $can_create && (($context == File::CONTEXT_DOCUMENTS || $context == File::CONTEXT_SKELETON)
	|| (($context == File::CONTEXT_USER || $context == File::CONTEXT_TRANSACTION) && $context_ref));
$can_mkdir = $can_create && ($context == File::CONTEXT_DOCUMENTS || $context == File::CONTEXT_SKELETON);

$breadcrumbs = Files::getBreadcrumbs($path);

$parent_path = Utils::dirname($path);

$quota_used = Files::getUsedQuota();
$quota_max = Files::getQuota();
$quota_left = Files::getRemainingQuota();
$quota_percent = round(($quota_used / $quota_max) * 100);

$tpl->assign(compact('path', 'files', 'can_write', 'can_delete', 'can_mkdir', 'can_upload', 'context', 'context_ref', 'breadcrumbs', 'parent_path', 'quota_used', 'quota_max', 'quota_percent', 'quota_left'));

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

Modified src/www/admin/web/_attach.php from [8ef09cfb3d] to [a59c3eef8c].

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46


$form->runIf(f('upload') || f('uploadHelper_mode'), function () use ($page) {
	if (f('uploadHelper_status') > 0) {
		throw new UserException('Un seul fichier peut être envoyé en même temps.');
	}

	$new_file = File::upload(dirname($page->file_path), 'file');

	if (f('uploadHelper_status') !== null)
	{
		$uri = Utils::getSelfURI() . '&sent';
		echo json_encode([
			'redirect'  =>  $uri,
			'callback'  =>  'insertHelper',







|







32
33
34
35
36
37
38
39
40
41
42
43
44
45
46


$form->runIf(f('upload') || f('uploadHelper_mode'), function () use ($page) {
	if (f('uploadHelper_status') > 0) {
		throw new UserException('Un seul fichier peut être envoyé en même temps.');
	}

	$new_file = File::upload(Utils::dirname($page->file_path), 'file');

	if (f('uploadHelper_status') !== null)
	{
		$uri = Utils::getSelfURI() . '&sent';
		echo json_encode([
			'redirect'  =>  $uri,
			'callback'  =>  'insertHelper',