aboutsummaryrefslogtreecommitdiffhomepage
path: root/inc/poche/Poche.class.php
diff options
context:
space:
mode:
Diffstat (limited to 'inc/poche/Poche.class.php')
-rwxr-xr-xinc/poche/Poche.class.php453
1 files changed, 51 insertions, 402 deletions
diff --git a/inc/poche/Poche.class.php b/inc/poche/Poche.class.php
index 09a9f5ff..bc4320b8 100755
--- a/inc/poche/Poche.class.php
+++ b/inc/poche/Poche.class.php
@@ -5,244 +5,77 @@
5 * @category wallabag 5 * @category wallabag
6 * @author Nicolas Lœuillet <nicolas@loeuillet.org> 6 * @author Nicolas Lœuillet <nicolas@loeuillet.org>
7 * @copyright 2013 7 * @copyright 2013
8 * @license http://www.wtfpl.net/ see COPYING file 8 * @license http://opensource.org/licenses/MIT see COPYING file
9 */ 9 */
10 10
11class Poche 11class Poche
12{ 12{
13 public static $canRenderTemplates = true; 13 /**
14 public static $configFileAvailable = true; 14 * @var User
15 15 */
16 public $user; 16 public $user;
17 /**
18 * @var Database
19 */
17 public $store; 20 public $store;
21 /**
22 * @var Template
23 */
18 public $tpl; 24 public $tpl;
25 /**
26 * @var Language
27 */
28 public $language;
29 /**
30 * @var Routing
31 */
32 public $routing;
33 /**
34 * @var Messages
35 */
19 public $messages; 36 public $messages;
37 /**
38 * @var Paginator
39 */
20 public $pagination; 40 public $pagination;
21 41
22 private $currentTheme = '';
23 private $currentLanguage = '';
24 private $notInstalledMessage = array();
25
26 private $language_names = array(
27 'cs_CZ.utf8' => 'čeština',
28 'de_DE.utf8' => 'German',
29 'en_EN.utf8' => 'English',
30 'es_ES.utf8' => 'Español',
31 'fa_IR.utf8' => 'فارسی',
32 'fr_FR.utf8' => 'Français',
33 'it_IT.utf8' => 'Italiano',
34 'pl_PL.utf8' => 'Polski',
35 'pt_BR.utf8' => 'Português (Brasil)',
36 'ru_RU.utf8' => 'Pусский',
37 'sl_SI.utf8' => 'Slovenščina',
38 'uk_UA.utf8' => 'Українська',
39 );
40 public function __construct() 42 public function __construct()
41 { 43 {
42 if ($this->configFileIsAvailable()) { 44 $this->init();
43 $this->init();
44 }
45
46 if ($this->themeIsInstalled()) {
47 $this->initTpl();
48 }
49
50 if ($this->systemIsInstalled()) {
51 $this->store = new Database();
52 $this->messages = new Messages();
53 # installation
54 if (! $this->store->isInstalled()) {
55 $this->install();
56 }
57 $this->store->checkTags();
58 }
59 } 45 }
60 46
61 private function init() 47 private function init()
62 { 48 {
63 Tools::initPhp(); 49 Tools::initPhp();
64 50
65 if (isset($_SESSION['poche_user']) && $_SESSION['poche_user'] != array()) { 51 $pocheUser = Session::getParam('poche_user');
66 $this->user = $_SESSION['poche_user']; 52
53 if ($pocheUser && $pocheUser != array()) {
54 $this->user = $pocheUser;
67 } else { 55 } else {
68 # fake user, just for install & login screens 56 // fake user, just for install & login screens
69 $this->user = new User(); 57 $this->user = new User();
70 $this->user->setConfig($this->getDefaultConfig()); 58 $this->user->setConfig($this->getDefaultConfig());
71 } 59 }
72 60
73 # l10n 61 $this->pagination = new Paginator($this->user->getConfigValue('pager'), 'p');
74 $language = $this->user->getConfigValue('language'); 62 $this->language = new Language($this);
75 @putenv('LC_ALL=' . $language); 63 $this->tpl = new Template($this);
76 setlocale(LC_ALL, $language); 64 $this->store = new Database();
77 bindtextdomain($language, LOCALE); 65 $this->messages = new Messages();
78 textdomain($language); 66 $this->routing = new Routing($this);
79
80 # Pagination
81 $this->pagination = new Paginator($this->user->getConfigValue('pager'), 'p');
82
83 # Set up theme
84 $themeDirectory = $this->user->getConfigValue('theme');
85
86 if ($themeDirectory === false) {
87 $themeDirectory = DEFAULT_THEME;
88 }
89
90 $this->currentTheme = $themeDirectory;
91
92 # Set up language
93 $languageDirectory = $this->user->getConfigValue('language');
94
95 if ($languageDirectory === false) {
96 $languageDirectory = DEFAULT_THEME;
97 }
98
99 $this->currentLanguage = $languageDirectory;
100 }
101
102 public function configFileIsAvailable() {
103 if (! self::$configFileAvailable) {
104 $this->notInstalledMessage[] = 'You have to copy (don\'t just rename!) inc/poche/config.inc.default.php to inc/poche/config.inc.php.';
105
106 return false;
107 }
108
109 return true;
110 } 67 }
111 68
112 public function themeIsInstalled() { 69 public function run()
113 $passTheme = TRUE; 70 {
114 # Twig is an absolute requirement for Poche to function. Abort immediately if the Composer installer hasn't been run yet 71 $this->routing->run();
115 if (! self::$canRenderTemplates) {
116 $this->notInstalledMessage[] = '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.';
117 $passTheme = FALSE;
118 }
119
120 if (! is_writable(CACHE)) {
121 $this->notInstalledMessage[] = 'You don\'t have write access on cache directory.';
122
123 self::$canRenderTemplates = false;
124
125 $passTheme = FALSE;
126 }
127
128 # Check if the selected theme and its requirements are present
129 $theme = $this->getTheme();
130
131 if ($theme != '' && ! is_dir(THEME . '/' . $theme)) {
132 $this->notInstalledMessage[] = 'The currently selected theme (' . $theme . ') does not seem to be properly installed (Missing directory: ' . THEME . '/' . $theme . ')';
133
134 self::$canRenderTemplates = false;
135
136 $passTheme = FALSE;
137 }
138
139 $themeInfo = $this->getThemeInfo($theme);
140 if (isset($themeInfo['requirements']) && is_array($themeInfo['requirements'])) {
141 foreach ($themeInfo['requirements'] as $requiredTheme) {
142 if (! is_dir(THEME . '/' . $requiredTheme)) {
143 $this->notInstalledMessage[] = 'The required "' . $requiredTheme . '" theme is missing for the current theme (' . $theme . ')';
144
145 self::$canRenderTemplates = false;
146
147 $passTheme = FALSE;
148 }
149 }
150 }
151
152 if (!$passTheme) {
153 return FALSE;
154 }
155
156
157 return true;
158 } 72 }
159 73
160 /** 74 /**
161 * all checks before installation. 75 * Creates a new user
162 * @todo move HTML to template
163 * @return boolean
164 */ 76 */
165 public function systemIsInstalled() 77 public function createNewUser()
166 { 78 {
167 $msg = TRUE;
168
169 $configSalt = defined('SALT') ? constant('SALT') : '';
170
171 if (empty($configSalt)) {
172 $this->notInstalledMessage[] = 'You have not yet filled in the SALT value in the config.inc.php file.';
173 $msg = FALSE;
174 }
175 if (STORAGE == 'sqlite' && ! file_exists(STORAGE_SQLITE)) {
176 Tools::logm('sqlite file doesn\'t exist');
177 $this->notInstalledMessage[] = 'sqlite file doesn\'t exist, you can find it in install folder. Copy it in /db folder.';
178 $msg = FALSE;
179 }
180 if (is_dir(ROOT . '/install') && ! DEBUG_POCHE) {
181 $this->notInstalledMessage[] = 'you have to delete the /install folder before using poche.';
182 $msg = FALSE;
183 }
184 if (STORAGE == 'sqlite' && ! is_writable(STORAGE_SQLITE)) {
185 Tools::logm('you don\'t have write access on sqlite file');
186 $this->notInstalledMessage[] = 'You don\'t have write access on sqlite file.';
187 $msg = FALSE;
188 }
189
190 if (! $msg) {
191 return false;
192 }
193
194 return true;
195 }
196
197 public function getNotInstalledMessage() {
198 return $this->notInstalledMessage;
199 }
200
201 private function initTpl()
202 {
203 $loaderChain = new Twig_Loader_Chain();
204 $theme = $this->getTheme();
205
206 # add the current theme as first to the loader chain so Twig will look there first for overridden template files
207 try {
208 $loaderChain->addLoader(new Twig_Loader_Filesystem(THEME . '/' . $theme));
209 } catch (Twig_Error_Loader $e) {
210 # @todo isInstalled() should catch this, inject Twig later
211 die('The currently selected theme (' . $theme . ') does not seem to be properly installed (' . THEME . '/' . $theme .' is missing)');
212 }
213
214 # add all required themes to the loader chain
215 $themeInfo = $this->getThemeInfo($theme);
216 if (isset($themeInfo['requirements']) && is_array($themeInfo['requirements'])) {
217 foreach ($themeInfo['requirements'] as $requiredTheme) {
218 try {
219 $loaderChain->addLoader(new Twig_Loader_Filesystem(THEME . '/' . $requiredTheme));
220 } catch (Twig_Error_Loader $e) {
221 # @todo isInstalled() should catch this, inject Twig later
222 die('The required "' . $requiredTheme . '" theme is missing for the current theme (' . $theme . ')');
223 }
224 }
225 }
226
227 if (DEBUG_POCHE) {
228 $twigParams = array();
229 } else {
230 $twigParams = array('cache' => CACHE);
231 }
232
233 $this->tpl = new Twig_Environment($loaderChain, $twigParams);
234 $this->tpl->addExtension(new Twig_Extensions_Extension_I18n());
235
236 # filter to display domain name of an url
237 $filter = new Twig_SimpleFilter('getDomain', 'Tools::getDomain');
238 $this->tpl->addFilter($filter);
239
240 # filter for reading time
241 $filter = new Twig_SimpleFilter('getReadingTime', 'Tools::getReadingTime');
242 $this->tpl->addFilter($filter);
243 }
244
245 public function createNewUser() {
246 if (isset($_GET['newuser'])){ 79 if (isset($_GET['newuser'])){
247 if ($_POST['newusername'] != "" && $_POST['password4newuser'] != ""){ 80 if ($_POST['newusername'] != "" && $_POST['password4newuser'] != ""){
248 $newusername = filter_var($_POST['newusername'], FILTER_SANITIZE_STRING); 81 $newusername = filter_var($_POST['newusername'], FILTER_SANITIZE_STRING);
@@ -266,7 +99,11 @@ class Poche
266 } 99 }
267 } 100 }
268 101
269 public function deleteUser(){ 102 /**
103 * Delete an existing user
104 */
105 public function deleteUser()
106 {
270 if (isset($_GET['deluser'])){ 107 if (isset($_GET['deluser'])){
271 if ($this->store->listUsers() > 1) { 108 if ($this->store->listUsers() > 1) {
272 if (Tools::encodeString($_POST['password4deletinguser'].$this->user->getUsername()) == $this->store->getUserPassword($this->user->getId())) { 109 if (Tools::encodeString($_POST['password4deletinguser'].$this->user->getUsername()) == $this->store->getUserPassword($this->user->getId())) {
@@ -294,115 +131,6 @@ class Poche
294 } 131 }
295 } 132 }
296 133
297 private function install()
298 {
299 Tools::logm('poche still not installed');
300 echo $this->tpl->render('install.twig', array(
301 'token' => Session::getToken(),
302 'theme' => $this->getTheme(),
303 'poche_url' => Tools::getPocheUrl()
304 ));
305 if (isset($_GET['install'])) {
306 if (($_POST['password'] == $_POST['password_repeat'])
307 && $_POST['password'] != "" && $_POST['login'] != "") {
308 # let's rock, install poche baby !
309 if ($this->store->install($_POST['login'], Tools::encodeString($_POST['password'] . $_POST['login'])))
310 {
311 Session::logout();
312 Tools::logm('poche is now installed');
313 Tools::redirect();
314 }
315 }
316 else {
317 Tools::logm('error during installation');
318 Tools::redirect();
319 }
320 }
321 exit();
322 }
323
324 public function getTheme() {
325 return $this->currentTheme;
326 }
327
328 /**
329 * Provides theme information by parsing theme.ini file if present in the theme's root directory.
330 * In all cases, the following data will be returned:
331 * - name: theme's name, or key if the theme is unnamed,
332 * - current: boolean informing if the theme is the current user theme.
333 *
334 * @param string $theme Theme key (directory name)
335 * @return array|boolean Theme information, or false if the theme doesn't exist.
336 */
337 public function getThemeInfo($theme) {
338 if (!is_dir(THEME . '/' . $theme)) {
339 return false;
340 }
341
342 $themeIniFile = THEME . '/' . $theme . '/theme.ini';
343 $themeInfo = array();
344
345 if (is_file($themeIniFile) && is_readable($themeIniFile)) {
346 $themeInfo = parse_ini_file($themeIniFile);
347 }
348
349 if ($themeInfo === false) {
350 $themeInfo = array();
351 }
352 if (!isset($themeInfo['name'])) {
353 $themeInfo['name'] = $theme;
354 }
355 $themeInfo['current'] = ($theme === $this->getTheme());
356
357 return $themeInfo;
358 }
359
360 public function getInstalledThemes() {
361 $handle = opendir(THEME);
362 $themes = array();
363
364 while (($theme = readdir($handle)) !== false) {
365 # Themes are stored in a directory, so all directory names are themes
366 # @todo move theme installation data to database
367 if (!is_dir(THEME . '/' . $theme) || in_array($theme, array('.', '..'))) {
368 continue;
369 }
370
371 $themes[$theme] = $this->getThemeInfo($theme);
372 }
373
374 ksort($themes);
375
376 return $themes;
377 }
378
379 public function getLanguage() {
380 return $this->currentLanguage;
381 }
382
383 public function getInstalledLanguages() {
384 $handle = opendir(LOCALE);
385 $languages = array();
386
387 while (($language = readdir($handle)) !== false) {
388 # Languages are stored in a directory, so all directory names are languages
389 # @todo move language installation data to database
390 if (! is_dir(LOCALE . '/' . $language) || in_array($language, array('..', '.', 'tools'))) {
391 continue;
392 }
393
394 $current = false;
395
396 if ($language === $this->getLanguage()) {
397 $current = true;
398 }
399
400 $languages[] = array('name' => (isset($this->language_names[$language]) ? $this->language_names[$language] : $language), 'value' => $language, 'current' => $current);
401 }
402
403 return $languages;
404 }
405
406 public function getDefaultConfig() 134 public function getDefaultConfig()
407 { 135 {
408 return array( 136 return array(
@@ -437,7 +165,7 @@ class Poche
437 if ( $last_id ) { 165 if ( $last_id ) {
438 Tools::logm('add link ' . $url->getUrl()); 166 Tools::logm('add link ' . $url->getUrl());
439 if (DOWNLOAD_PICTURES) { 167 if (DOWNLOAD_PICTURES) {
440 $content = filtre_picture($body, $url->getUrl(), $last_id); 168 $content = Picture::filterPicture($body, $url->getUrl(), $last_id);
441 Tools::logm('updating content article'); 169 Tools::logm('updating content article');
442 $this->store->updateContent($last_id, $content, $this->user->getId()); 170 $this->store->updateContent($last_id, $content, $this->user->getId());
443 } 171 }
@@ -472,7 +200,7 @@ class Poche
472 $msg = 'delete link #' . $id; 200 $msg = 'delete link #' . $id;
473 if ($this->store->deleteById($id, $this->user->getId())) { 201 if ($this->store->deleteById($id, $this->user->getId())) {
474 if (DOWNLOAD_PICTURES) { 202 if (DOWNLOAD_PICTURES) {
475 remove_directory(ABS_PATH . $id); 203 Picture::removeDirectory(ABS_PATH . $id);
476 } 204 }
477 $this->messages->add('s', _('the link has been deleted successfully')); 205 $this->messages->add('s', _('the link has been deleted successfully'));
478 } 206 }
@@ -598,8 +326,8 @@ class Poche
598 $check_time_prod = date('d-M-Y H:i', $prod_infos[1]); 326 $check_time_prod = date('d-M-Y H:i', $prod_infos[1]);
599 $compare_dev = version_compare(POCHE, $dev); 327 $compare_dev = version_compare(POCHE, $dev);
600 $compare_prod = version_compare(POCHE, $prod); 328 $compare_prod = version_compare(POCHE, $prod);
601 $themes = $this->getInstalledThemes(); 329 $themes = $this->tpl->getInstalledThemes();
602 $languages = $this->getInstalledLanguages(); 330 $languages = $this->language->getInstalledLanguages();
603 $token = $this->user->getConfigValue('token'); 331 $token = $this->user->getConfigValue('token');
604 $http_auth = (isset($_SERVER['PHP_AUTH_USER']) || isset($_SERVER['REMOTE_USER'])) ? true : false; 332 $http_auth = (isset($_SERVER['PHP_AUTH_USER']) || isset($_SERVER['REMOTE_USER'])) ? true : false;
605 $only_user = ($this->store->listUsers() > 1) ? false : true; 333 $only_user = ($this->store->listUsers() > 1) ? false : true;
@@ -703,7 +431,7 @@ class Poche
703 'listmode' => (isset($_COOKIE['listmode']) ? true : false), 431 'listmode' => (isset($_COOKIE['listmode']) ? true : false),
704 ); 432 );
705 433
706 //if id is given - we retrive entries by tag: id is tag id 434 //if id is given - we retrieve entries by tag: id is tag id
707 if ($id) { 435 if ($id) {
708 $tpl_vars['tag'] = $this->store->retrieveTag($id, $this->user->getId()); 436 $tpl_vars['tag'] = $this->store->retrieveTag($id, $this->user->getId());
709 $tpl_vars['id'] = intval($id); 437 $tpl_vars['id'] = intval($id);
@@ -757,85 +485,6 @@ class Poche
757 } 485 }
758 } 486 }
759 487
760 public function updateTheme()
761 {
762 # no data
763 if (empty($_POST['theme'])) {
764 }
765
766 # we are not going to change it to the current theme...
767 if ($_POST['theme'] == $this->getTheme()) {
768 $this->messages->add('w', _('still using the "' . $this->getTheme() . '" theme!'));
769 Tools::redirect('?view=config');
770 }
771
772 $themes = $this->getInstalledThemes();
773 $actualTheme = false;
774
775 foreach (array_keys($themes) as $theme) {
776 if ($theme == $_POST['theme']) {
777 $actualTheme = true;
778 break;
779 }
780 }
781
782 if (! $actualTheme) {
783 $this->messages->add('e', _('that theme does not seem to be installed'));
784 Tools::redirect('?view=config');
785 }
786
787 $this->store->updateUserConfig($this->user->getId(), 'theme', $_POST['theme']);
788 $this->messages->add('s', _('you have changed your theme preferences'));
789
790 $currentConfig = $_SESSION['poche_user']->config;
791 $currentConfig['theme'] = $_POST['theme'];
792
793 $_SESSION['poche_user']->setConfig($currentConfig);
794
795 $this->emptyCache();
796
797 Tools::redirect('?view=config');
798 }
799
800 public function updateLanguage()
801 {
802 # no data
803 if (empty($_POST['language'])) {
804 }
805
806 # we are not going to change it to the current language...
807 if ($_POST['language'] == $this->getLanguage()) {
808 $this->messages->add('w', _('still using the "' . $this->getLanguage() . '" language!'));
809 Tools::redirect('?view=config');
810 }
811
812 $languages = $this->getInstalledLanguages();
813 $actualLanguage = false;
814
815 foreach ($languages as $language) {
816 if ($language['value'] == $_POST['language']) {
817 $actualLanguage = true;
818 break;
819 }
820 }
821
822 if (! $actualLanguage) {
823 $this->messages->add('e', _('that language does not seem to be installed'));
824 Tools::redirect('?view=config');
825 }
826
827 $this->store->updateUserConfig($this->user->getId(), 'language', $_POST['language']);
828 $this->messages->add('s', _('you have changed your language preferences'));
829
830 $currentConfig = $_SESSION['poche_user']->config;
831 $currentConfig['language'] = $_POST['language'];
832
833 $_SESSION['poche_user']->setConfig($currentConfig);
834
835 $this->emptyCache();
836
837 Tools::redirect('?view=config');
838 }
839 /** 488 /**
840 * get credentials from differents sources 489 * get credentials from differents sources
841 * it redirects the user to the $referer link 490 * it redirects the user to the $referer link