Overview
Comment:Refactor rendering classes to use an abstract parent
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 6d5b0c3e04645bec2827a43efe6bd2d1f6f532420e5c9cc8eca948b37eca630f
User & Date: bohwaz on 2021-05-20 15:58:07
Other Links: manifest | tags
Context
2021-05-20
16:16
Refactor File class to add generic markdown support check-in: da6e8ed150 user: bohwaz tags: trunk, stable
15:58
Refactor rendering classes to use an abstract parent check-in: 6d5b0c3e04 user: bohwaz tags: trunk
11:29
Add french syntax to Skriv extensions, document extensions check-in: 8925851af5 user: bohwaz tags: trunk
Changes

Added src/include/lib/Garradin/Web/Render/AbstractRender.php version [c4980b1d31].























































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<?php

namespace Garradin\Web\Render;

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

use const Garradin\{WWW_URL, ADMIN_URL};

abstract class AbstractRender
{
	protected $current_path;
	protected $context;
	protected $link_prefix;
	protected $link_suffix;

	protected $file;

	public function __construct(?File $file)
	{
		$this->file = $file;

		if ($file) {
			$this->isRelativeTo($file);
		}
	}

	abstract public function render(?string $content = null, array $options = []): string;

	protected function resolveAttachment(string $uri) {
		$prefix = $this->current_path;
		$pos = strpos($uri, '/');

		// "Image.jpg"
		if ($pos === false) {
			return WWW_URL . $prefix . '/' . $uri;
		}
		// "bla/Image.jpg" outside of web context
		elseif ($this->context !== File::CONTEXT_WEB && $pos !== 0) {
			return WWW_URL . $this->context . '/' . $uri;
		}
		// "bla/Image.jpg" in web context or absolute link, eg. "/transactions/2442/42.jpg"
		else {
			return WWW_URL . ltrim($uri, '/');
		}
	}

	protected function resolveLink(string $uri) {
		$first = substr($uri, 0, 1);
		if ($first == '/' || $first == '!') {
			return Utils::getLocalURL($uri);
		}

		if (strpos(Utils::basename($uri), '.') === false) {
			$uri .= $this->link_suffix;
		}

		return $this->link_prefix . $uri;
	}

	public function isRelativeTo(File $file) {
		$this->current_path = Utils::dirname($file->path);
		$this->context = strtok($this->current_path, '/');
		$this->link_suffix = '';

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

Deleted src/include/lib/Garradin/Web/Render/AttachmentAwareTrait.php version [c57a7ae779].

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
50
51
52
53
54
55
56
57
58
59
60
61
62
<?php

namespace Garradin\Web\Render;

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

use const Garradin\{WWW_URL, ADMIN_URL};

trait AttachmentAwareTrait
{
	protected $current_path;
	protected $context;
	protected $link_prefix;
	protected $link_suffix;

	protected function resolveAttachment(string $uri) {
		$prefix = $this->current_path;
		$pos = strpos($uri, '/');

		// "Image.jpg"
		if ($pos === false) {
			return WWW_URL . $prefix . '/' . $uri;
		}
		// "bla/Image.jpg" outside of web context
		elseif ($this->context !== File::CONTEXT_WEB && $pos !== 0) {
			return WWW_URL . $this->context . '/' . $uri;
		}
		// "bla/Image.jpg" in web context or absolute link, eg. "/transactions/2442/42.jpg"
		else {
			return WWW_URL . ltrim($uri, '/');
		}
	}

	protected function resolveLink(string $uri) {
		$first = substr($uri, 0, 1);
		if ($first == '/' || $first == '!') {
			return Utils::getLocalURL($uri);
		}

		if (strpos(Utils::basename($uri), '.') === false) {
			$uri .= $this->link_suffix;
		}

		return $this->link_prefix . $uri;
	}

	public function isRelativeTo(File $file) {
		$this->current_path = Utils::dirname($file->path);
		$this->context = strtok($this->current_path, '/');
		$this->link_suffix = '';

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




























































































































Modified src/include/lib/Garradin/Web/Render/EncryptedSkriv.php from [d0d2a69554] to [ef852896e7].

2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19

namespace Garradin\Web\Render;

use Garradin\Entities\Files\File;
use Garradin\Template;
use const Garradin\ADMIN_URL;

class EncryptedSkriv
{
	public function render(File $file, ?string $content = null): string
	{
		$tpl = Template::getInstance();

		$content = $content ?? $file->fetch();
		$tpl->assign('admin_url', ADMIN_URL);
		$tpl->assign(compact('file', 'content'));
		return $tpl->fetch('common/files/_file_render_encrypted.tpl');
	}
}







|

|


>






2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

namespace Garradin\Web\Render;

use Garradin\Entities\Files\File;
use Garradin\Template;
use const Garradin\ADMIN_URL;

class EncryptedSkriv extends AbstractRender
{
	public function render(?string $content = null, array $options = []): string
	{
		$tpl = Template::getInstance();
		$file = $this->file;
		$content = $content ?? $file->fetch();
		$tpl->assign('admin_url', ADMIN_URL);
		$tpl->assign(compact('file', 'content'));
		return $tpl->fetch('common/files/_file_render_encrypted.tpl');
	}
}

Modified src/include/lib/Garradin/Web/Render/Markdown.php from [e400b010cf] to [b756d5ef2a].

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
use Garradin\Plugin;
use Garradin\Utils;
use Garradin\Files\Files;
use Garradin\UserTemplate\CommonModifiers;

use const Garradin\{ADMIN_URL, WWW_URL};

class Markdown
{
	use AttachmentAwareTrait;

	public function render(?File $file, ?string $content = null, array $options = []): string
	{
		$parsedown = new Parsedown($file);
		$parsedown->setBreaksEnabled(true);
		$parsedown->setUrlsLinked(true);
		$parsedown->setSafeMode(true);

		if ($file) {
			$this->isRelativeTo($file);
		}

		$str = $content ?? $file->fetch();

		$str = $parsedown->text($str);

		$str = CommonModifiers::typo($str);

		$str = preg_replace_callback(';<a href="((?!https?://|\w+:|#).+)">;i', function ($matches) {
			var_dump($matches);
			return sprintf('<a href="%s" target="_parent">', $this->resolveLink($matches[1]));
		}, $str);

		return sprintf('<div class="web-content">%s</div>', $str);
	}
}







|

<
<
|

|




<
<
<
<
|






<






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
use Garradin\Plugin;
use Garradin\Utils;
use Garradin\Files\Files;
use Garradin\UserTemplate\CommonModifiers;

use const Garradin\{ADMIN_URL, WWW_URL};

class Markdown extends AbstractRender
{


	public function render(?string $content = null, array $options = []): string
	{
		$parsedown = new Parsedown($this->file);
		$parsedown->setBreaksEnabled(true);
		$parsedown->setUrlsLinked(true);
		$parsedown->setSafeMode(true);





		$str = $content ?? $this->file->fetch();

		$str = $parsedown->text($str);

		$str = CommonModifiers::typo($str);

		$str = preg_replace_callback(';<a href="((?!https?://|\w+:|#).+)">;i', function ($matches) {

			return sprintf('<a href="%s" target="_parent">', $this->resolveLink($matches[1]));
		}, $str);

		return sprintf('<div class="web-content">%s</div>', $str);
	}
}

Modified src/include/lib/Garradin/Web/Render/Parsedown.php from [e9206e8d80] to [2ee604cfb3].

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

	function __construct(?File $file)
	{
		$this->BlockTypes['<'][] = 'SkrivExtension';
		$this->BlockTypes['['][]= 'TOC';

		parent::__construct();
		$this->skriv = new Skriv;

		if ($file) {
			$this->skriv->isRelativeTo($file);
		}
	}

	protected function blockSkrivExtension(array $line): ?array
	{
		$line = $line['text'];

		if (strpos($line, '<<') === 0 && preg_match('/^<<<?([a-z_]+)((?:(?!>>>?).)*?)(>>>?$|$)/i', trim($line), $match)) {







|
<
<
<
<







21
22
23
24
25
26
27
28




29
30
31
32
33
34
35

	function __construct(?File $file)
	{
		$this->BlockTypes['<'][] = 'SkrivExtension';
		$this->BlockTypes['['][]= 'TOC';

		parent::__construct();
		$this->skriv = new Skriv($file);




	}

	protected function blockSkrivExtension(array $line): ?array
	{
		$line = $line['text'];

		if (strpos($line, '<<') === 0 && preg_match('/^<<<?([a-z_]+)((?:(?!>>>?).)*?)(>>>?$|$)/i', trim($line), $match)) {

Modified src/include/lib/Garradin/Web/Render/Render.php from [c543986709] to [a31683eb85].

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
	const FORMAT_SKRIV = 'skriv';
	const FORMAT_ENCRYPTED = 'skriv/encrypted';
	const FORMAT_MARKDOWN = 'markdown';

	static public function render(string $format, File $file, string $content = null, array $options = [])
	{
		if ($format == self::FORMAT_SKRIV) {
			$r = new Skriv;
		}
		else if ($format == self::FORMAT_ENCRYPTED) {
			$r = new EncryptedSkriv;
		}
		else if ($format == self::FORMAT_MARKDOWN) {
			$r = new Markdown;
		}
		else {
			throw new \LogicException('Invalid format: ' . $format);
		}

		return $r->render($file, $content, $options);
	}
}







|


|


|





|


10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
	const FORMAT_SKRIV = 'skriv';
	const FORMAT_ENCRYPTED = 'skriv/encrypted';
	const FORMAT_MARKDOWN = 'markdown';

	static public function render(string $format, File $file, string $content = null, array $options = [])
	{
		if ($format == self::FORMAT_SKRIV) {
			$r = new Skriv($file);
		}
		else if ($format == self::FORMAT_ENCRYPTED) {
			$r = new EncryptedSkriv($file);
		}
		else if ($format == self::FORMAT_MARKDOWN) {
			$r = new Markdown($file);
		}
		else {
			throw new \LogicException('Invalid format: ' . $format);
		}

		return $r->render($content, $options);
	}
}

Modified src/include/lib/Garradin/Web/Render/Skriv.php from [549431f840] to [c98806af5f].

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
..
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
use Garradin\Plugin;
use Garradin\UserTemplate\CommonModifiers;

use KD2\SkrivLite;

use const Garradin\{ADMIN_URL, WWW_URL};

class Skriv
{
	use AttachmentAwareTrait;

	static protected $skriv;

	public function __construct()
	{
		if (!self::$skriv)

		{
			self::$skriv = new \KD2\SkrivLite;
			self::$skriv->registerExtension('file', [$this, 'SkrivFile']);
			self::$skriv->registerExtension('fichier', [$this, 'SkrivFile']);
			self::$skriv->registerExtension('image', [$this, 'SkrivImage']);

			// Enregistrer d'autres extensions éventuellement
			Plugin::fireSignal('skriv.init', ['skriv' => self::$skriv]);
		}
	}

	public function render(?File $file, ?string $content = null, array $options = []): string
	{
		$skriv =& self::$skriv;

		if ($file) {
			$this->isRelativeTo($file);
		}

		$str = $content ?? $file->fetch();

		$str = preg_replace_callback('/#file:\[([^\]\h]+)\]/', function ($match) {
			return $this->resolveAttachment($match[1]);
		}, $str);

		$str = $skriv->render($str);

................................................................................
		}, $str);

		return sprintf('<div class="web-content">%s</div>', $str);
	}

	public function callExtension(array $match)
	{
		$method = new \ReflectionMethod(self::$skriv, '_callExtension');
		$method->setAccessible(true);
		return $method->invoke(self::$skriv, $match);
	}

	/**
	 * Callback utilisé pour l'extension <<file>> dans le wiki-texte
	 * @param array $args    Arguments passés à l'extension
	 * @param string $content Contenu éventuel (en mode bloc)
	 * @param SkrivLite $skriv   Objet SkrivLite







|

<
<
|

|

<
>
|
|
|
|
|

|
|
|
|
<
|

|

<
<
<
<
|







 







|

|







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
..
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
use Garradin\Plugin;
use Garradin\UserTemplate\CommonModifiers;

use KD2\SkrivLite;

use const Garradin\{ADMIN_URL, WWW_URL};

class Skriv extends AbstractRender
{


	protected $skriv;

	public function __construct(?File $file)
	{

		parent::__construct($file);

		$this->skriv = new SkrivLite;
		$this->skriv->registerExtension('file', [$this, 'SkrivFile']);
		$this->skriv->registerExtension('fichier', [$this, 'SkrivFile']);
		$this->skriv->registerExtension('image', [$this, 'SkrivImage']);

		// Enregistrer d'autres extensions éventuellement
		Plugin::fireSignal('skriv.init', ['skriv' => $this->skriv]);
	}


	public function render(?string $content = null, array $options = []): string
	{
		$skriv =& $this->skriv;





		$str = $content ?? $this->file->fetch();

		$str = preg_replace_callback('/#file:\[([^\]\h]+)\]/', function ($match) {
			return $this->resolveAttachment($match[1]);
		}, $str);

		$str = $skriv->render($str);

................................................................................
		}, $str);

		return sprintf('<div class="web-content">%s</div>', $str);
	}

	public function callExtension(array $match)
	{
		$method = new \ReflectionMethod($this->skriv, '_callExtension');
		$method->setAccessible(true);
		return $method->invoke($this->skriv, $match);
	}

	/**
	 * Callback utilisé pour l'extension <<file>> dans le wiki-texte
	 * @param array $args    Arguments passés à l'extension
	 * @param string $content Contenu éventuel (en mode bloc)
	 * @param SkrivLite $skriv   Objet SkrivLite