]> git.immae.eu Git - github/wallabag/wallabag.git/blobdiff - inc/poche/Template.class.php
WHAT. A. BIG. REFACTOR. + new license (we moved to MIT one)
[github/wallabag/wallabag.git] / inc / poche / Template.class.php
diff --git a/inc/poche/Template.class.php b/inc/poche/Template.class.php
new file mode 100644 (file)
index 0000000..0e09ad6
--- /dev/null
@@ -0,0 +1,236 @@
+<?php
+/**
+ * wallabag, self hostable application allowing you to not miss any content anymore
+ *
+ * @category   wallabag
+ * @author     Nicolas LÅ“uillet <nicolas@loeuillet.org>
+ * @copyright  2013
+ * @license    http://opensource.org/licenses/MIT see COPYING file
+ */
+
+class Template extends Twig_Environment
+{
+    protected $wallabag;
+
+    private $canRenderTemplates = TRUE;
+    private $currentTheme = '';
+
+    public function __construct(Poche $wallabag)
+    {
+        $this->wallabag = $wallabag;
+
+        // Set up theme
+        $pocheUser = Session::getParam('poche_user');
+
+        $themeDirectory = (is_null($pocheUser) ? DEFAULT_THEME : $pocheUser->getConfigValue('theme'));
+
+        if ($themeDirectory === false) {
+            $themeDirectory = DEFAULT_THEME;
+        }
+
+        $this->currentTheme = $themeDirectory;
+
+        if ($this->_themeIsInstalled() === array()) {
+            $this->_init();
+        }
+    }
+
+    /**
+     * Returns true if selected theme is installed
+     *
+     * @return bool
+     */
+    private function _themeIsInstalled()
+    {
+        $errors = array();
+
+        // Twig is an absolute requirement for wallabag to function.
+        // Abort immediately if the Composer installer hasn't been run yet
+        if (!$this->canRenderTemplates) {
+            $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.';
+        }
+
+        // Check if the selected theme and its requirements are present
+        $theme = $this->getTheme();
+        if ($theme != '' && !is_dir(THEME . '/' . $theme)) {
+            $errors[]                   = 'The currently selected theme (' . $theme . ') does not seem to be properly installed (Missing directory: ' . THEME . '/' . $theme . ')';
+            $this->canRenderTemplates   = FALSE;
+        }
+
+        $themeInfo = $this->getThemeInfo($theme);
+        if (isset($themeInfo['requirements']) && is_array($themeInfo['requirements'])) {
+            foreach ($themeInfo['requirements'] as $requiredTheme) {
+                if (! is_dir(THEME . '/' . $requiredTheme)) {
+                    $errors[]                   = 'The required "' . $requiredTheme . '" theme is missing for the current theme (' . $theme . ')';
+                    $this->canRenderTemplates   = FALSE;
+                }
+            }
+        }
+
+        $currentErrors = (is_null(Session::getParam('errors'))? array() : Session::getParam('errors'));
+        Session::setParam('errors', array_merge($errors, $currentErrors));
+
+        return $errors;
+    }
+
+    /**
+     * Initialization for templates
+     */
+    private function _init()
+    {
+        $loaderChain    = new Twig_Loader_Chain();
+        $theme          = $this->getTheme();
+
+        // add the current theme as first to the loader chain
+        // so Twig will look there first for overridden template files
+        try {
+            $loaderChain->addLoader(new Twig_Loader_Filesystem(THEME . '/' . $theme));
+        } catch (Twig_Error_Loader $e) {
+            # @todo isInstalled() should catch this, inject Twig later
+            die('The currently selected theme (' . $theme . ') does not seem to be properly installed (' . THEME . '/' . $theme .' is missing)');
+        }
+
+        // add all required themes to the loader chain
+        $themeInfo = $this->getThemeInfo($theme);
+        if (isset($themeInfo['requirements']) && is_array($themeInfo['requirements'])) {
+            foreach ($themeInfo['requirements'] as $requiredTheme) {
+                try {
+                    $loaderChain->addLoader(new Twig_Loader_Filesystem(THEME . '/' . $requiredTheme));
+                } catch (Twig_Error_Loader $e) {
+                    # @todo isInstalled() should catch this, inject Twig later
+                    die('The required "' . $requiredTheme . '" theme is missing for the current theme (' . $theme . ')');
+                }
+            }
+        }
+
+        if (DEBUG_POCHE) {
+            $twigParams = array();
+        } else {
+            $twigParams = array('cache' => CACHE);
+        }
+
+        parent::__construct($loaderChain, $twigParams);
+
+        //$tpl = new Twig_Environment($loaderChain, $twigParams);
+        $this->addExtension(new Twig_Extensions_Extension_I18n());
+
+        # filter to display domain name of an url
+        $filter = new Twig_SimpleFilter('getDomain', 'Tools::getDomain');
+        $this->addFilter($filter);
+
+        # filter for reading time
+        $filter = new Twig_SimpleFilter('getReadingTime', 'Tools::getReadingTime');
+        $this->addFilter($filter);
+    }
+
+    /**
+     * Returns current theme
+     *
+     * @return string
+     */
+    public function getTheme()
+    {
+        return $this->currentTheme;
+    }
+
+    /**
+     * Provides theme information by parsing theme.ini file if present in the theme's root directory.
+     * In all cases, the following data will be returned:
+     * - name: theme's name, or key if the theme is unnamed,
+     * - current: boolean informing if the theme is the current user theme.
+     *
+     * @param string $theme Theme key (directory name)
+     * @return array|boolean Theme information, or false if the theme doesn't exist.
+     */
+    public function getThemeInfo($theme)
+    {
+        if (!is_dir(THEME . '/' . $theme)) {
+            return false;
+        }
+
+        $themeIniFile   = THEME . '/' . $theme . '/theme.ini';
+        $themeInfo      = array();
+
+        if (is_file($themeIniFile) && is_readable($themeIniFile)) {
+            $themeInfo = parse_ini_file($themeIniFile);
+        }
+
+        if ($themeInfo === false) {
+            $themeInfo = array();
+        }
+
+        if (!isset($themeInfo['name'])) {
+            $themeInfo['name'] = $theme;
+        }
+
+        $themeInfo['current'] = ($theme === $this->getTheme());
+
+        return $themeInfo;
+    }
+
+    /**
+     * Returns an array with installed themes
+     *
+     * @return array
+     */
+    public function getInstalledThemes()
+    {
+        $handle = opendir(THEME);
+        $themes = array();
+
+        while (($theme = readdir($handle)) !== false) {
+            # Themes are stored in a directory, so all directory names are themes
+            # @todo move theme installation data to database
+            if (!is_dir(THEME . '/' . $theme) || in_array($theme, array('.', '..'))) {
+                continue;
+            }
+
+            $themes[$theme] = $this->getThemeInfo($theme);
+        }
+
+        ksort($themes);
+
+        return $themes;
+    }
+
+    /**
+     * Update theme for the current user
+     *
+     * @param $newTheme
+     */
+    public function updateTheme($newTheme)
+    {
+        # we are not going to change it to the current theme...
+        if ($newTheme == $this->getTheme()) {
+            $this->wallabag->messages->add('w', _('still using the "' . $this->getTheme() . '" theme!'));
+            Tools::redirect('?view=config');
+        }
+
+        $themes = $this->getInstalledThemes();
+        $actualTheme = false;
+
+        foreach (array_keys($themes) as $theme) {
+            if ($theme == $newTheme) {
+                $actualTheme = true;
+                break;
+            }
+        }
+
+        if (!$actualTheme) {
+            $this->wallabag->messages->add('e', _('that theme does not seem to be installed'));
+            Tools::redirect('?view=config');
+        }
+
+        $this->wallabag->store->updateUserConfig($this->wallabag->user->getId(), 'theme', $newTheme);
+        $this->wallabag->messages->add('s', _('you have changed your theme preferences'));
+
+        $currentConfig = $_SESSION['poche_user']->config;
+        $currentConfig['theme'] = $newTheme;
+
+        $_SESSION['poche_user']->setConfig($currentConfig);
+
+        $this->wallabag->emptyCache();
+
+        Tools::redirect('?view=config');
+    }
+}
\ No newline at end of file