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