]> git.immae.eu Git - github/wallabag/wallabag.git/blob - src/Wallabag/Wallabag/Template.php
e8a6daa3b636091e8657dd2323c2744136b48e18
[github/wallabag/wallabag.git] / src / Wallabag / Wallabag / Template.php
1 <?php
2 /**
3 * wallabag, self hostable application allowing you to not miss any content anymore
4 *
5 * @category wallabag
6 * @author Nicolas LÅ“uillet <nicolas@loeuillet.org>
7 * @copyright 2013
8 * @license http://opensource.org/licenses/MIT see COPYING file
9 */
10
11 namespace Wallabag\Wallabag;
12
13 class Template extends Twig_Environment
14 {
15 protected $wallabag;
16
17 private $canRenderTemplates = TRUE;
18 private $currentTheme = '';
19
20 public function __construct(Wallabag $wallabag)
21 {
22 $this->wallabag = $wallabag;
23
24 // Set up theme
25 $pocheUser = Session::getParam('poche_user');
26
27 $themeDirectory = (is_null($pocheUser) ? DEFAULT_THEME : $pocheUser->getConfigValue('theme'));
28
29 if ($themeDirectory === false || !is_dir(THEME . '/' . $themeDirectory)) {
30 $themeDirectory = DEFAULT_THEME;
31 }
32
33 $this->currentTheme = $themeDirectory;
34
35 if ($this->_themeIsInstalled() === array()) {
36 $this->_init();
37 }
38 }
39
40 /**
41 * Returns true if selected theme is installed
42 *
43 * @return bool
44 */
45 private function _themeIsInstalled()
46 {
47 $errors = array();
48
49 // Twig is an absolute requirement for wallabag to function.
50 // Abort immediately if the Composer installer hasn't been run yet
51 if (!$this->canRenderTemplates) {
52 $errors[] = 'Twig does not seem to be installed. Please initialize the Composer installation to automatically fetch dependencies. You can also download <a href="http://wllbg.org/vendor">vendor.zip</a> and extract it in your wallabag folder.';
53 }
54
55 // Check if the selected theme and its requirements are present
56 $theme = $this->getTheme();
57 if ($theme != '' && !is_dir(THEME . '/' . $theme)) {
58 $errors[] = 'The currently selected theme (' . $theme . ') does not seem to be properly installed (Missing directory: ' . THEME . '/' . $theme . ')';
59 $this->canRenderTemplates = FALSE;
60 }
61
62 $themeInfo = $this->getThemeInfo($theme);
63 if (isset($themeInfo['requirements']) && is_array($themeInfo['requirements'])) {
64 foreach ($themeInfo['requirements'] as $requiredTheme) {
65 if (! is_dir(THEME . '/' . $requiredTheme)) {
66 $errors[] = 'The required "' . $requiredTheme . '" theme is missing for the current theme (' . $theme . ')';
67 $this->canRenderTemplates = FALSE;
68 }
69 }
70 }
71
72 $currentErrors = (is_null(Session::getParam('errors'))? array() : Session::getParam('errors'));
73 Session::setParam('errors', array_merge($errors, $currentErrors));
74
75 return $errors;
76 }
77
78 /**
79 * Initialization for templates
80 */
81 private function _init()
82 {
83 $loaderChain = new Twig_Loader_Chain();
84 $theme = $this->getTheme();
85
86 // add the current theme as first to the loader chain
87 // so Twig will look there first for overridden template files
88 try {
89 $loaderChain->addLoader(new Twig_Loader_Filesystem(THEME . '/' . $theme));
90 } catch (Twig_Error_Loader $e) {
91 # @todo isInstalled() should catch this, inject Twig later
92 die('The currently selected theme (' . $theme . ') does not seem to be properly installed (' . THEME . '/' . $theme .' is missing)');
93 }
94
95 // add all required themes to the loader chain
96 $themeInfo = $this->getThemeInfo($theme);
97 if (isset($themeInfo['requirements']) && is_array($themeInfo['requirements'])) {
98 foreach ($themeInfo['requirements'] as $requiredTheme) {
99 try {
100 $loaderChain->addLoader(new Twig_Loader_Filesystem(THEME . '/' . $requiredTheme));
101 } catch (Twig_Error_Loader $e) {
102 # @todo isInstalled() should catch this, inject Twig later
103 die('The required "' . $requiredTheme . '" theme is missing for the current theme (' . $theme . ')');
104 }
105 }
106 }
107
108 if (DEBUG_POCHE) {
109 $twigParams = array();
110 } else {
111 $twigParams = array('cache' => CACHE);
112 }
113
114 parent::__construct($loaderChain, $twigParams);
115
116 //$tpl = new Twig_Environment($loaderChain, $twigParams);
117 $this->addExtension(new Twig_Extensions_Extension_I18n());
118
119 # filter to display domain name of an url
120 $filter = new Twig_SimpleFilter('getDomain', 'Tools::getDomain');
121 $this->addFilter($filter);
122
123 # filter for reading time
124 $filter = new Twig_SimpleFilter('getReadingTime', 'Tools::getReadingTime');
125 $this->addFilter($filter);
126 }
127
128 /**
129 * Returns current theme
130 *
131 * @return string
132 */
133 public function getTheme()
134 {
135 return $this->currentTheme;
136 }
137
138 /**
139 * Provides theme information by parsing theme.ini file if present in the theme's root directory.
140 * In all cases, the following data will be returned:
141 * - name: theme's name, or key if the theme is unnamed,
142 * - current: boolean informing if the theme is the current user theme.
143 *
144 * @param string $theme Theme key (directory name)
145 * @return array|boolean Theme information, or false if the theme doesn't exist.
146 */
147 public function getThemeInfo($theme)
148 {
149 if (!is_dir(THEME . '/' . $theme)) {
150 return false;
151 }
152
153 $themeIniFile = THEME . '/' . $theme . '/theme.ini';
154 $themeInfo = array();
155
156 if (is_file($themeIniFile) && is_readable($themeIniFile)) {
157 $themeInfo = parse_ini_file($themeIniFile);
158 }
159
160 if ($themeInfo === false) {
161 $themeInfo = array();
162 }
163
164 if (!isset($themeInfo['name'])) {
165 $themeInfo['name'] = $theme;
166 }
167
168 $themeInfo['current'] = ($theme === $this->getTheme());
169
170 return $themeInfo;
171 }
172
173 /**
174 * Returns an array with installed themes
175 *
176 * @return array
177 */
178 public function getInstalledThemes()
179 {
180 $handle = opendir(THEME);
181 $themes = array();
182
183 while (($theme = readdir($handle)) !== false) {
184 # Themes are stored in a directory, so all directory names are themes
185 # @todo move theme installation data to database
186 if (!is_dir(THEME . '/' . $theme) || in_array($theme, array('.', '..', '_global'))) {
187 continue;
188 }
189
190 $themes[$theme] = $this->getThemeInfo($theme);
191 }
192
193 ksort($themes);
194
195 return $themes;
196 }
197
198 /**
199 * Update theme for the current user
200 *
201 * @param $newTheme
202 */
203 public function updateTheme($newTheme)
204 {
205 # we are not going to change it to the current theme...
206 if ($newTheme == $this->getTheme()) {
207 $this->wallabag->messages->add('w', _('still using the "' . $this->getTheme() . '" theme!'));
208 Tools::redirect('?view=config');
209 }
210
211 $themes = $this->getInstalledThemes();
212 $actualTheme = false;
213
214 foreach (array_keys($themes) as $theme) {
215 if ($theme == $newTheme) {
216 $actualTheme = true;
217 break;
218 }
219 }
220
221 if (!$actualTheme) {
222 $this->wallabag->messages->add('e', _('that theme does not seem to be installed'));
223 Tools::redirect('?view=config');
224 }
225
226 $this->wallabag->store->updateUserConfig($this->wallabag->user->getId(), 'theme', $newTheme);
227 $this->wallabag->messages->add('s', _('you have changed your theme preferences'));
228
229 $currentConfig = $_SESSION['poche_user']->config;
230 $currentConfig['theme'] = $newTheme;
231
232 $_SESSION['poche_user']->setConfig($currentConfig);
233
234 Tools::emptyCache();
235 Tools::redirect('?view=config');
236 }
237 }