diff options
Diffstat (limited to 'application/render')
-rw-r--r-- | application/render/PageBuilder.php | 94 | ||||
-rw-r--r-- | application/render/PageCacheManager.php | 60 | ||||
-rw-r--r-- | application/render/TemplatePage.php | 33 |
3 files changed, 153 insertions, 34 deletions
diff --git a/application/render/PageBuilder.php b/application/render/PageBuilder.php index 3f86fc26..41b357dd 100644 --- a/application/render/PageBuilder.php +++ b/application/render/PageBuilder.php | |||
@@ -3,10 +3,12 @@ | |||
3 | namespace Shaarli\Render; | 3 | namespace Shaarli\Render; |
4 | 4 | ||
5 | use Exception; | 5 | use Exception; |
6 | use exceptions\MissingBasePathException; | ||
6 | use RainTPL; | 7 | use RainTPL; |
7 | use Shaarli\ApplicationUtils; | 8 | use Shaarli\ApplicationUtils; |
8 | use Shaarli\Bookmark\LinkDB; | 9 | use Shaarli\Bookmark\BookmarkServiceInterface; |
9 | use Shaarli\Config\ConfigManager; | 10 | use Shaarli\Config\ConfigManager; |
11 | use Shaarli\Security\SessionManager; | ||
10 | use Shaarli\Thumbnailer; | 12 | use Shaarli\Thumbnailer; |
11 | 13 | ||
12 | /** | 14 | /** |
@@ -34,9 +36,9 @@ class PageBuilder | |||
34 | protected $session; | 36 | protected $session; |
35 | 37 | ||
36 | /** | 38 | /** |
37 | * @var LinkDB $linkDB instance. | 39 | * @var BookmarkServiceInterface $bookmarkService instance. |
38 | */ | 40 | */ |
39 | protected $linkDB; | 41 | protected $bookmarkService; |
40 | 42 | ||
41 | /** | 43 | /** |
42 | * @var null|string XSRF token | 44 | * @var null|string XSRF token |
@@ -52,23 +54,32 @@ class PageBuilder | |||
52 | * PageBuilder constructor. | 54 | * PageBuilder constructor. |
53 | * $tpl is initialized at false for lazy loading. | 55 | * $tpl is initialized at false for lazy loading. |
54 | * | 56 | * |
55 | * @param ConfigManager $conf Configuration Manager instance (reference). | 57 | * @param ConfigManager $conf Configuration Manager instance (reference). |
56 | * @param array $session $_SESSION array | 58 | * @param array $session $_SESSION array |
57 | * @param LinkDB $linkDB instance. | 59 | * @param BookmarkServiceInterface $linkDB instance. |
58 | * @param string $token Session token | 60 | * @param string $token Session token |
59 | * @param bool $isLoggedIn | 61 | * @param bool $isLoggedIn |
60 | */ | 62 | */ |
61 | public function __construct(&$conf, $session, $linkDB = null, $token = null, $isLoggedIn = false) | 63 | public function __construct(&$conf, $session, $linkDB = null, $token = null, $isLoggedIn = false) |
62 | { | 64 | { |
63 | $this->tpl = false; | 65 | $this->tpl = false; |
64 | $this->conf = $conf; | 66 | $this->conf = $conf; |
65 | $this->session = $session; | 67 | $this->session = $session; |
66 | $this->linkDB = $linkDB; | 68 | $this->bookmarkService = $linkDB; |
67 | $this->token = $token; | 69 | $this->token = $token; |
68 | $this->isLoggedIn = $isLoggedIn; | 70 | $this->isLoggedIn = $isLoggedIn; |
69 | } | 71 | } |
70 | 72 | ||
71 | /** | 73 | /** |
74 | * Reset current state of template rendering. | ||
75 | * Mostly useful for error handling. We remove everything, and display the error template. | ||
76 | */ | ||
77 | public function reset(): void | ||
78 | { | ||
79 | $this->tpl = false; | ||
80 | } | ||
81 | |||
82 | /** | ||
72 | * Initialize all default tpl tags. | 83 | * Initialize all default tpl tags. |
73 | */ | 84 | */ |
74 | private function initialize() | 85 | private function initialize() |
@@ -125,8 +136,8 @@ class PageBuilder | |||
125 | 136 | ||
126 | $this->tpl->assign('language', $this->conf->get('translation.language')); | 137 | $this->tpl->assign('language', $this->conf->get('translation.language')); |
127 | 138 | ||
128 | if ($this->linkDB !== null) { | 139 | if ($this->bookmarkService !== null) { |
129 | $this->tpl->assign('tags', $this->linkDB->linksCountPerTag()); | 140 | $this->tpl->assign('tags', escape($this->bookmarkService->bookmarksCountPerTag())); |
130 | } | 141 | } |
131 | 142 | ||
132 | $this->tpl->assign( | 143 | $this->tpl->assign( |
@@ -136,16 +147,43 @@ class PageBuilder | |||
136 | $this->tpl->assign('thumbnails_width', $this->conf->get('thumbnails.width')); | 147 | $this->tpl->assign('thumbnails_width', $this->conf->get('thumbnails.width')); |
137 | $this->tpl->assign('thumbnails_height', $this->conf->get('thumbnails.height')); | 148 | $this->tpl->assign('thumbnails_height', $this->conf->get('thumbnails.height')); |
138 | 149 | ||
139 | if (!empty($_SESSION['warnings'])) { | 150 | $this->tpl->assign('formatter', $this->conf->get('formatter', 'default')); |
140 | $this->tpl->assign('global_warnings', $_SESSION['warnings']); | 151 | |
141 | unset($_SESSION['warnings']); | 152 | $this->tpl->assign('links_per_page', $this->session['LINKS_PER_PAGE']); |
142 | } | ||
143 | 153 | ||
144 | // To be removed with a proper theme configuration. | 154 | // To be removed with a proper theme configuration. |
145 | $this->tpl->assign('conf', $this->conf); | 155 | $this->tpl->assign('conf', $this->conf); |
146 | } | 156 | } |
147 | 157 | ||
148 | /** | 158 | /** |
159 | * Affect variable after controller processing. | ||
160 | * Used for alert messages. | ||
161 | */ | ||
162 | protected function finalize(string $basePath): void | ||
163 | { | ||
164 | // TODO: use the SessionManager | ||
165 | $messageKeys = [ | ||
166 | SessionManager::KEY_SUCCESS_MESSAGES, | ||
167 | SessionManager::KEY_WARNING_MESSAGES, | ||
168 | SessionManager::KEY_ERROR_MESSAGES | ||
169 | ]; | ||
170 | foreach ($messageKeys as $messageKey) { | ||
171 | if (!empty($_SESSION[$messageKey])) { | ||
172 | $this->tpl->assign('global_' . $messageKey, $_SESSION[$messageKey]); | ||
173 | unset($_SESSION[$messageKey]); | ||
174 | } | ||
175 | } | ||
176 | |||
177 | $this->assign('base_path', $basePath); | ||
178 | $this->assign( | ||
179 | 'asset_path', | ||
180 | $basePath . '/' . | ||
181 | rtrim($this->conf->get('resource.raintpl_tpl', 'tpl'), '/') . '/' . | ||
182 | $this->conf->get('resource.theme', 'default') | ||
183 | ); | ||
184 | } | ||
185 | |||
186 | /** | ||
149 | * The following assign() method is basically the same as RainTPL (except lazy loading) | 187 | * The following assign() method is basically the same as RainTPL (except lazy loading) |
150 | * | 188 | * |
151 | * @param string $placeholder Template placeholder. | 189 | * @param string $placeholder Template placeholder. |
@@ -183,33 +221,21 @@ class PageBuilder | |||
183 | } | 221 | } |
184 | 222 | ||
185 | /** | 223 | /** |
186 | * Render a specific page (using a template file). | 224 | * Render a specific page as string (using a template file). |
187 | * e.g. $pb->renderPage('picwall'); | 225 | * e.g. $pb->render('picwall'); |
188 | * | 226 | * |
189 | * @param string $page Template filename (without extension). | 227 | * @param string $page Template filename (without extension). |
228 | * | ||
229 | * @return string Processed template content | ||
190 | */ | 230 | */ |
191 | public function renderPage($page) | 231 | public function render(string $page, string $basePath): string |
192 | { | 232 | { |
193 | if ($this->tpl === false) { | 233 | if ($this->tpl === false) { |
194 | $this->initialize(); | 234 | $this->initialize(); |
195 | } | 235 | } |
196 | 236 | ||
197 | $this->tpl->draw($page); | 237 | $this->finalize($basePath); |
198 | } | ||
199 | 238 | ||
200 | /** | 239 | return $this->tpl->draw($page, true); |
201 | * Render a 404 page (uses the template : tpl/404.tpl) | ||
202 | * usage: $PAGE->render404('The link was deleted') | ||
203 | * | ||
204 | * @param string $message A message to display what is not found | ||
205 | */ | ||
206 | public function render404($message = '') | ||
207 | { | ||
208 | if (empty($message)) { | ||
209 | $message = t('The page you are trying to reach does not exist or has been deleted.'); | ||
210 | } | ||
211 | header($_SERVER['SERVER_PROTOCOL'] . ' ' . t('404 Not Found')); | ||
212 | $this->tpl->assign('error_message', $message); | ||
213 | $this->renderPage('404'); | ||
214 | } | 240 | } |
215 | } | 241 | } |
diff --git a/application/render/PageCacheManager.php b/application/render/PageCacheManager.php new file mode 100644 index 00000000..97805c35 --- /dev/null +++ b/application/render/PageCacheManager.php | |||
@@ -0,0 +1,60 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Shaarli\Render; | ||
4 | |||
5 | use Shaarli\Feed\CachedPage; | ||
6 | |||
7 | /** | ||
8 | * Cache utilities | ||
9 | */ | ||
10 | class PageCacheManager | ||
11 | { | ||
12 | /** @var string Cache directory */ | ||
13 | protected $pageCacheDir; | ||
14 | |||
15 | /** @var bool */ | ||
16 | protected $isLoggedIn; | ||
17 | |||
18 | public function __construct(string $pageCacheDir, bool $isLoggedIn) | ||
19 | { | ||
20 | $this->pageCacheDir = $pageCacheDir; | ||
21 | $this->isLoggedIn = $isLoggedIn; | ||
22 | } | ||
23 | |||
24 | /** | ||
25 | * Purges all cached pages | ||
26 | * | ||
27 | * @return string|null an error string if the directory is missing | ||
28 | */ | ||
29 | public function purgeCachedPages(): ?string | ||
30 | { | ||
31 | if (!is_dir($this->pageCacheDir)) { | ||
32 | $error = sprintf(t('Cannot purge %s: no directory'), $this->pageCacheDir); | ||
33 | error_log($error); | ||
34 | |||
35 | return $error; | ||
36 | } | ||
37 | |||
38 | array_map('unlink', glob($this->pageCacheDir . '/*.cache')); | ||
39 | |||
40 | return null; | ||
41 | } | ||
42 | |||
43 | /** | ||
44 | * Invalidates caches when the database is changed or the user logs out. | ||
45 | */ | ||
46 | public function invalidateCaches(): void | ||
47 | { | ||
48 | // Purge page cache shared by sessions. | ||
49 | $this->purgeCachedPages(); | ||
50 | } | ||
51 | |||
52 | public function getCachePage(string $pageUrl): CachedPage | ||
53 | { | ||
54 | return new CachedPage( | ||
55 | $this->pageCacheDir, | ||
56 | $pageUrl, | ||
57 | false === $this->isLoggedIn | ||
58 | ); | ||
59 | } | ||
60 | } | ||
diff --git a/application/render/TemplatePage.php b/application/render/TemplatePage.php new file mode 100644 index 00000000..8af8228a --- /dev/null +++ b/application/render/TemplatePage.php | |||
@@ -0,0 +1,33 @@ | |||
1 | <?php | ||
2 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Shaarli\Render; | ||
6 | |||
7 | interface TemplatePage | ||
8 | { | ||
9 | public const ERROR_404 = '404'; | ||
10 | public const ADDLINK = 'addlink'; | ||
11 | public const CHANGE_PASSWORD = 'changepassword'; | ||
12 | public const CHANGE_TAG = 'changetag'; | ||
13 | public const CONFIGURE = 'configure'; | ||
14 | public const DAILY = 'daily'; | ||
15 | public const DAILY_RSS = 'dailyrss'; | ||
16 | public const EDIT_LINK = 'editlink'; | ||
17 | public const ERROR = 'error'; | ||
18 | public const EXPORT = 'export'; | ||
19 | public const NETSCAPE_EXPORT_BOOKMARKS = 'export.bookmarks'; | ||
20 | public const FEED_ATOM = 'feed.atom'; | ||
21 | public const FEED_RSS = 'feed.rss'; | ||
22 | public const IMPORT = 'import'; | ||
23 | public const INSTALL = 'install'; | ||
24 | public const LINKLIST = 'linklist'; | ||
25 | public const LOGIN = 'loginform'; | ||
26 | public const OPEN_SEARCH = 'opensearch'; | ||
27 | public const PICTURE_WALL = 'picwall'; | ||
28 | public const PLUGINS_ADMIN = 'pluginsadmin'; | ||
29 | public const TAG_CLOUD = 'tag.cloud'; | ||
30 | public const TAG_LIST = 'tag.list'; | ||
31 | public const THUMBNAILS = 'thumbnails'; | ||
32 | public const TOOLS = 'tools'; | ||
33 | } | ||