diff options
author | Nicolas LÅ“uillet <nicolas.loeuillet@gmail.com> | 2013-09-20 10:21:39 +0200 |
---|---|---|
committer | Nicolas LÅ“uillet <nicolas.loeuillet@gmail.com> | 2013-09-20 10:21:39 +0200 |
commit | 00dbaf90bc44ef3ed0abaebb15307756e054a027 (patch) | |
tree | b3391178b65147d025a8ae01e2c97044c9298189 /inc/poche/Poche.class.php | |
parent | 705250b93dc71ae91d3c305b51e7a20611873805 (diff) | |
download | wallabag-00dbaf90bc44ef3ed0abaebb15307756e054a027.tar.gz wallabag-00dbaf90bc44ef3ed0abaebb15307756e054a027.tar.zst wallabag-00dbaf90bc44ef3ed0abaebb15307756e054a027.zip |
merge #224
Diffstat (limited to 'inc/poche/Poche.class.php')
-rw-r--r-- | inc/poche/Poche.class.php | 293 |
1 files changed, 232 insertions, 61 deletions
diff --git a/inc/poche/Poche.class.php b/inc/poche/Poche.class.php index 8770c7f7..67fbd529 100644 --- a/inc/poche/Poche.class.php +++ b/inc/poche/Poche.class.php | |||
@@ -10,77 +10,200 @@ | |||
10 | 10 | ||
11 | class Poche | 11 | class Poche |
12 | { | 12 | { |
13 | public static $canRenderTemplates = true; | ||
14 | public static $configFileAvailable = true; | ||
15 | |||
13 | public $user; | 16 | public $user; |
14 | public $store; | 17 | public $store; |
15 | public $tpl; | 18 | public $tpl; |
16 | public $messages; | 19 | public $messages; |
17 | public $pagination; | 20 | public $pagination; |
18 | 21 | ||
19 | function __construct() | 22 | private $currentTheme = ''; |
23 | private $notInstalledMessage = ''; | ||
24 | |||
25 | # @todo make this dynamic (actually install themes and save them in the database including author information et cetera) | ||
26 | private $installedThemes = array( | ||
27 | 'default' => array('requires' => array()), | ||
28 | 'dark' => array('requires' => array('default')), | ||
29 | 'dmagenta' => array('requires' => array('default')), | ||
30 | 'solarized' => array('requires' => array('default')), | ||
31 | 'solarized-dark' => array('requires' => array('default')) | ||
32 | ); | ||
33 | |||
34 | public function __construct() | ||
20 | { | 35 | { |
36 | if (! $this->configFileIsAvailable()) { | ||
37 | return; | ||
38 | } | ||
39 | |||
40 | $this->init(); | ||
41 | |||
42 | if (! $this->themeIsInstalled()) { | ||
43 | return; | ||
44 | } | ||
45 | |||
21 | $this->initTpl(); | 46 | $this->initTpl(); |
22 | if (!$this->checkBeforeInstall()) { | 47 | |
23 | exit; | 48 | if (! $this->systemIsInstalled()) { |
49 | return; | ||
24 | } | 50 | } |
51 | |||
25 | $this->store = new Database(); | 52 | $this->store = new Database(); |
26 | $this->init(); | ||
27 | $this->messages = new Messages(); | 53 | $this->messages = new Messages(); |
28 | 54 | ||
29 | # installation | 55 | # installation |
30 | if(!$this->store->isInstalled()) | 56 | if (! $this->store->isInstalled()) { |
31 | { | ||
32 | $this->install(); | 57 | $this->install(); |
33 | } | 58 | } |
34 | } | 59 | } |
60 | |||
61 | private function init() | ||
62 | { | ||
63 | Tools::initPhp(); | ||
64 | Session::$sessionName = 'poche'; | ||
65 | Session::init(); | ||
66 | |||
67 | if (isset($_SESSION['poche_user']) && $_SESSION['poche_user'] != array()) { | ||
68 | $this->user = $_SESSION['poche_user']; | ||
69 | } else { | ||
70 | # fake user, just for install & login screens | ||
71 | $this->user = new User(); | ||
72 | $this->user->setConfig($this->getDefaultConfig()); | ||
73 | } | ||
74 | |||
75 | # l10n | ||
76 | $language = $this->user->getConfigValue('language'); | ||
77 | putenv('LC_ALL=' . $language); | ||
78 | setlocale(LC_ALL, $language); | ||
79 | bindtextdomain($language, LOCALE); | ||
80 | textdomain($language); | ||
81 | |||
82 | # Pagination | ||
83 | $this->pagination = new Paginator($this->user->getConfigValue('pager'), 'p'); | ||
84 | |||
85 | # Set up theme | ||
86 | $themeDirectory = $this->user->getConfigValue('theme'); | ||
87 | |||
88 | if ($themeDirectory === false) { | ||
89 | $themeDirectory = DEFAULT_THEME; | ||
90 | } | ||
91 | |||
92 | $this->currentTheme = $themeDirectory; | ||
93 | } | ||
94 | |||
95 | public function configFileIsAvailable() { | ||
96 | if (! self::$configFileAvailable) { | ||
97 | $this->notInstalledMessage = 'You have to rename <strong>inc/poche/config.inc.php.new</strong> to <strong>inc/poche/config.inc.php</strong>.'; | ||
98 | |||
99 | return false; | ||
100 | } | ||
35 | 101 | ||
102 | return true; | ||
103 | } | ||
104 | |||
105 | public function themeIsInstalled() { | ||
106 | # Twig is an absolute requirement for Poche to function. Abort immediately if the Composer installer hasn't been run yet | ||
107 | if (! self::$canRenderTemplates) { | ||
108 | $this->notInstalledMessage = 'Twig does not seem to be installed. Please initialize the Composer installation to automatically fetch dependencies. Have a look at <a href="http://inthepoche.com/?pages/Documentation">the documentation.</a>'; | ||
109 | |||
110 | return false; | ||
111 | } | ||
112 | |||
113 | # Check if the selected theme and its requirements are present | ||
114 | if (! is_dir(THEME . '/' . $this->getTheme())) { | ||
115 | $this->notInstalledMessage = 'The currently selected theme (' . $this->getTheme() . ') does not seem to be properly installed (Missing directory: ' . THEME . '/' . $this->getTheme() . ')'; | ||
116 | |||
117 | self::$canRenderTemplates = false; | ||
118 | |||
119 | return false; | ||
120 | } | ||
121 | |||
122 | foreach ($this->installedThemes[$this->getTheme()]['requires'] as $requiredTheme) { | ||
123 | if (! is_dir(THEME . '/' . $requiredTheme)) { | ||
124 | $this->notInstalledMessage = 'The required "' . $requiredTheme . '" theme is missing for the current theme (' . $this->getTheme() . ')'; | ||
125 | |||
126 | self::$canRenderTemplates = false; | ||
127 | |||
128 | return false; | ||
129 | } | ||
130 | } | ||
131 | |||
132 | return true; | ||
133 | } | ||
134 | |||
36 | /** | 135 | /** |
37 | * all checks before installation. | 136 | * all checks before installation. |
137 | * @todo move HTML to template | ||
38 | * @return boolean | 138 | * @return boolean |
39 | */ | 139 | */ |
40 | private function checkBeforeInstall() | 140 | public function systemIsInstalled() |
41 | { | 141 | { |
42 | $msg = ''; | 142 | $msg = ''; |
43 | $allIsGood = TRUE; | 143 | |
44 | 144 | $configSalt = defined('SALT') ? constant('SALT') : ''; | |
45 | if (!is_writable(CACHE)) { | 145 | |
146 | if (empty($configSalt)) { | ||
147 | $msg = '<h1>error</h1><p>You have not yet filled in the SALT value in the config.inc.php file.</p>'; | ||
148 | } else if (! is_writable(CACHE)) { | ||
46 | Tools::logm('you don\'t have write access on cache directory'); | 149 | Tools::logm('you don\'t have write access on cache directory'); |
47 | die('You don\'t have write access on cache directory.'); | 150 | $msg = '<h1>error</h1><p>You don\'t have write access on cache directory.</p>'; |
48 | } | 151 | } else if (STORAGE == 'sqlite' && ! file_exists(STORAGE_SQLITE)) { |
49 | else if (file_exists('./install/update.php') && !DEBUG_POCHE) { | 152 | Tools::logm('sqlite file doesn\'t exist'); |
153 | $msg = '<h1>error</h1><p>sqlite file doesn\'t exist, you can find it in install folder.</p>'; | ||
154 | } else if (file_exists(ROOT . '/install/update.php') && ! DEBUG_POCHE) { | ||
50 | $msg = '<h1>setup</h1><p><strong>It\'s your first time here?</strong> Please copy /install/poche.sqlite in db folder. Then, delete install folder.<br /><strong>If you have already installed poche</strong>, an update is needed <a href="install/update.php">by clicking here</a>.</p>'; | 155 | $msg = '<h1>setup</h1><p><strong>It\'s your first time here?</strong> Please copy /install/poche.sqlite in db folder. Then, delete install folder.<br /><strong>If you have already installed poche</strong>, an update is needed <a href="install/update.php">by clicking here</a>.</p>'; |
51 | $allIsGood = FALSE; | 156 | } else if (is_dir(ROOT . '/install') && ! DEBUG_POCHE) { |
52 | } | ||
53 | else if (file_exists('./install') && !DEBUG_POCHE) { | ||
54 | $msg = '<h1>setup</h1><p><strong>If you want to update your poche</strong>, you just have to delete /install folder. <br /><strong>To install your poche with sqlite</strong>, copy /install/poche.sqlite in /db and delete the folder /install. you have to delete the /install folder before using poche.</p>'; | 157 | $msg = '<h1>setup</h1><p><strong>If you want to update your poche</strong>, you just have to delete /install folder. <br /><strong>To install your poche with sqlite</strong>, copy /install/poche.sqlite in /db and delete the folder /install. you have to delete the /install folder before using poche.</p>'; |
55 | $allIsGood = FALSE; | 158 | } else if (STORAGE == 'sqlite' && ! is_writable(STORAGE_SQLITE)) { |
56 | } | ||
57 | else if (STORAGE == 'sqlite' && !is_writable(STORAGE_SQLITE)) { | ||
58 | Tools::logm('you don\'t have write access on sqlite file'); | 159 | Tools::logm('you don\'t have write access on sqlite file'); |
59 | $msg = '<h1>error</h1><p>You don\'t have write access on sqlite file.</p>'; | 160 | $msg = '<h1>error</h1><p>You don\'t have write access on sqlite file.</p>'; |
60 | $allIsGood = FALSE; | ||
61 | } | 161 | } |
62 | 162 | ||
63 | if (!$allIsGood) { | 163 | if (! empty($msg)) { |
64 | echo $this->tpl->render('error.twig', array( | 164 | $this->notInstalledMessage = $msg; |
65 | 'msg' => $msg | 165 | |
66 | )); | 166 | return false; |
67 | } | 167 | } |
68 | 168 | ||
69 | return $allIsGood; | 169 | return true; |
170 | } | ||
171 | |||
172 | public function getNotInstalledMessage() { | ||
173 | return $this->notInstalledMessage; | ||
70 | } | 174 | } |
71 | 175 | ||
72 | private function initTpl() | 176 | private function initTpl() |
73 | { | 177 | { |
74 | # template engine | 178 | $loaderChain = new Twig_Loader_Chain(); |
75 | $loader = new Twig_Loader_Filesystem(TPL); | 179 | |
180 | # add the current theme as first to the loader chain so Twig will look there first for overridden template files | ||
181 | try { | ||
182 | $loaderChain->addLoader(new Twig_Loader_Filesystem(THEME . '/' . $this->getTheme())); | ||
183 | } catch (Twig_Error_Loader $e) { | ||
184 | # @todo isInstalled() should catch this, inject Twig later | ||
185 | die('The currently selected theme (' . $this->getTheme() . ') does not seem to be properly installed (' . THEME . '/' . $this->getTheme() .' is missing)'); | ||
186 | } | ||
187 | |||
188 | # add all required themes to the loader chain | ||
189 | foreach ($this->installedThemes[$this->getTheme()]['requires'] as $requiredTheme) { | ||
190 | try { | ||
191 | $loaderChain->addLoader(new Twig_Loader_Filesystem(THEME . '/' . DEFAULT_THEME)); | ||
192 | } catch (Twig_Error_Loader $e) { | ||
193 | # @todo isInstalled() should catch this, inject Twig later | ||
194 | die('The required "' . $requiredTheme . '" theme is missing for the current theme (' . $this->getTheme() . ')'); | ||
195 | } | ||
196 | } | ||
197 | |||
76 | if (DEBUG_POCHE) { | 198 | if (DEBUG_POCHE) { |
77 | $twig_params = array(); | 199 | $twig_params = array(); |
78 | } | 200 | } else { |
79 | else { | ||
80 | $twig_params = array('cache' => CACHE); | 201 | $twig_params = array('cache' => CACHE); |
81 | } | 202 | } |
82 | $this->tpl = new Twig_Environment($loader, $twig_params); | 203 | |
204 | $this->tpl = new Twig_Environment($loaderChain, $twig_params); | ||
83 | $this->tpl->addExtension(new Twig_Extensions_Extension_I18n()); | 205 | $this->tpl->addExtension(new Twig_Extensions_Extension_I18n()); |
206 | |||
84 | # filter to display domain name of an url | 207 | # filter to display domain name of an url |
85 | $filter = new Twig_SimpleFilter('getDomain', 'Tools::getDomain'); | 208 | $filter = new Twig_SimpleFilter('getDomain', 'Tools::getDomain'); |
86 | $this->tpl->addFilter($filter); | 209 | $this->tpl->addFilter($filter); |
@@ -88,39 +211,19 @@ class Poche | |||
88 | # filter for reading time | 211 | # filter for reading time |
89 | $filter = new Twig_SimpleFilter('getReadingTime', 'Tools::getReadingTime'); | 212 | $filter = new Twig_SimpleFilter('getReadingTime', 'Tools::getReadingTime'); |
90 | $this->tpl->addFilter($filter); | 213 | $this->tpl->addFilter($filter); |
91 | } | 214 | |
92 | 215 | # filter for simple filenames in config view | |
93 | private function init() | 216 | $filter = new Twig_SimpleFilter('getPrettyFilename', function($string) { return str_replace(ROOT, '', $string); }); |
94 | { | 217 | $this->tpl->addFilter($filter); |
95 | Tools::initPhp(); | ||
96 | Session::$sessionName = 'poche'; | ||
97 | Session::init(); | ||
98 | |||
99 | if (isset($_SESSION['poche_user']) && $_SESSION['poche_user'] != array()) { | ||
100 | $this->user = $_SESSION['poche_user']; | ||
101 | } | ||
102 | else { | ||
103 | # fake user, just for install & login screens | ||
104 | $this->user = new User(); | ||
105 | $this->user->setConfig($this->getDefaultConfig()); | ||
106 | } | ||
107 | |||
108 | # l10n | ||
109 | $language = $this->user->getConfigValue('language'); | ||
110 | putenv('LC_ALL=' . $language); | ||
111 | setlocale(LC_ALL, $language); | ||
112 | bindtextdomain($language, LOCALE); | ||
113 | textdomain($language); | ||
114 | |||
115 | # Pagination | ||
116 | $this->pagination = new Paginator($this->user->getConfigValue('pager'), 'p'); | ||
117 | } | 218 | } |
118 | 219 | ||
119 | private function install() | 220 | private function install() |
120 | { | 221 | { |
121 | Tools::logm('poche still not installed'); | 222 | Tools::logm('poche still not installed'); |
122 | echo $this->tpl->render('install.twig', array( | 223 | echo $this->tpl->render('install.twig', array( |
123 | 'token' => Session::getToken() | 224 | 'token' => Session::getToken(), |
225 | 'theme' => $this->getTheme(), | ||
226 | 'poche_url' => Tools::getPocheUrl() | ||
124 | )); | 227 | )); |
125 | if (isset($_GET['install'])) { | 228 | if (isset($_GET['install'])) { |
126 | if (($_POST['password'] == $_POST['password_repeat']) | 229 | if (($_POST['password'] == $_POST['password_repeat']) |
@@ -140,13 +243,41 @@ class Poche | |||
140 | } | 243 | } |
141 | exit(); | 244 | exit(); |
142 | } | 245 | } |
246 | |||
247 | public function getTheme() { | ||
248 | return $this->currentTheme; | ||
249 | } | ||
250 | |||
251 | public function getInstalledThemes() { | ||
252 | $handle = opendir(THEME); | ||
253 | $themes = array(); | ||
254 | |||
255 | while (($theme = readdir($handle)) !== false) { | ||
256 | # Themes are stored in a directory, so all directory names are themes | ||
257 | # @todo move theme installation data to database | ||
258 | if (! is_dir(THEME . '/' . $theme) || in_array($theme, array('..', '.'))) { | ||
259 | continue; | ||
260 | } | ||
261 | |||
262 | $current = false; | ||
263 | |||
264 | if ($theme === $this->getTheme()) { | ||
265 | $current = true; | ||
266 | } | ||
267 | |||
268 | $themes[] = array('name' => $theme, 'current' => $current); | ||
269 | } | ||
270 | |||
271 | return $themes; | ||
272 | } | ||
143 | 273 | ||
144 | public function getDefaultConfig() | 274 | public function getDefaultConfig() |
145 | { | 275 | { |
146 | return array( | 276 | return array( |
147 | 'pager' => PAGINATION, | 277 | 'pager' => PAGINATION, |
148 | 'language' => LANG, | 278 | 'language' => LANG, |
149 | ); | 279 | 'theme' => DEFAULT_THEME |
280 | ); | ||
150 | } | 281 | } |
151 | 282 | ||
152 | /** | 283 | /** |
@@ -231,7 +362,9 @@ class Poche | |||
231 | $prod = $this->getPocheVersion('prod'); | 362 | $prod = $this->getPocheVersion('prod'); |
232 | $compare_dev = version_compare(POCHE_VERSION, $dev); | 363 | $compare_dev = version_compare(POCHE_VERSION, $dev); |
233 | $compare_prod = version_compare(POCHE_VERSION, $prod); | 364 | $compare_prod = version_compare(POCHE_VERSION, $prod); |
365 | $themes = $this->getInstalledThemes(); | ||
234 | $tpl_vars = array( | 366 | $tpl_vars = array( |
367 | 'themes' => $themes, | ||
235 | 'dev' => $dev, | 368 | 'dev' => $dev, |
236 | 'prod' => $prod, | 369 | 'prod' => $prod, |
237 | 'compare_dev' => $compare_dev, | 370 | 'compare_dev' => $compare_dev, |
@@ -316,6 +449,44 @@ class Poche | |||
316 | } | 449 | } |
317 | } | 450 | } |
318 | } | 451 | } |
452 | |||
453 | public function updateTheme() | ||
454 | { | ||
455 | # no data | ||
456 | if (empty($_POST['theme'])) { | ||
457 | } | ||
458 | |||
459 | # we are not going to change it to the current theme... | ||
460 | if ($_POST['theme'] == $this->getTheme()) { | ||
461 | $this->messages->add('w', _('still using the "' . $this->getTheme() . '" theme!')); | ||
462 | Tools::redirect('?view=config'); | ||
463 | } | ||
464 | |||
465 | $themes = $this->getInstalledThemes(); | ||
466 | $actualTheme = false; | ||
467 | |||
468 | foreach ($themes as $theme) { | ||
469 | if ($theme['name'] == $_POST['theme']) { | ||
470 | $actualTheme = true; | ||
471 | break; | ||
472 | } | ||
473 | } | ||
474 | |||
475 | if (! $actualTheme) { | ||
476 | $this->messages->add('e', _('that theme does not seem to be installed')); | ||
477 | Tools::redirect('?view=config'); | ||
478 | } | ||
479 | |||
480 | $this->store->updateUserConfig($this->user->getId(), 'theme', $_POST['theme']); | ||
481 | $this->messages->add('s', _('you have changed your theme preferences')); | ||
482 | |||
483 | $currentConfig = $_SESSION['poche_user']->config; | ||
484 | $currentConfig['theme'] = $_POST['theme']; | ||
485 | |||
486 | $_SESSION['poche_user']->setConfig($currentConfig); | ||
487 | |||
488 | Tools::redirect('?view=config'); | ||
489 | } | ||
319 | 490 | ||
320 | /** | 491 | /** |
321 | * checks if login & password are correct and save the user in session. | 492 | * checks if login & password are correct and save the user in session. |