From 96834a47b09985e1c82b82857fc108f20e8b8f2b Mon Sep 17 00:00:00 2001 From: tcitworld Date: Fri, 16 May 2014 17:38:19 +0200 Subject: [PATCH 01/34] Added PHPePub --- CREDITS.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CREDITS.md b/CREDITS.md index c892336dc..ffef5b33f 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -9,7 +9,8 @@ wallabag is based on : * Twig http://twig.sensiolabs.org * Flash messages https://github.com/plasticbrain/PHP-Flash-Messages * Pagination https://github.com/daveismyname/pagination +* PHPePub https://github.com/Grandt/PHPePub/ wallabag is developed by Nicolas Lœuillet under the Do What the Fuck You Want to Public License -Contributors : https://github.com/wallabag/wallabag/graphs/contributors \ No newline at end of file +Contributors : https://github.com/wallabag/wallabag/graphs/contributors From 800868e27ea9cb73b889537be6ff35c88fb9e443 Mon Sep 17 00:00:00 2001 From: Maryana Rozhankivska Date: Thu, 24 Jul 2014 17:47:23 +0300 Subject: [PATCH 02/34] security fix --- index.php | 82 +++++++++++++++++++++++++++---------------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/index.php b/index.php index 481841ece..2c532c0ee 100755 --- a/index.php +++ b/index.php @@ -63,54 +63,54 @@ if (! empty($notInstalledMessage)) { # poche actions if (isset($_GET['login'])) { - # hello you + # hello to you $poche->login($referer); -} elseif (isset($_GET['logout'])) { - # see you soon ! - $poche->logout(); -} elseif (isset($_GET['config'])) { - # Update password - $poche->updatePassword(); -} elseif (isset($_GET['newuser'])) { - $poche->createNewUser(); -} elseif (isset($_GET['deluser'])) { - $poche->deleteUser(); -} elseif (isset($_GET['epub'])) { - $poche->createEpub(); -} elseif (isset($_GET['import'])) { - $import = $poche->import(); - $tpl_vars = array_merge($tpl_vars, $import); -} elseif (isset($_GET['download'])) { - Tools::download_db(); -} elseif (isset($_GET['empty-cache'])) { - $poche->emptyCache(); -} elseif (isset($_GET['export'])) { - $poche->export(); -} elseif (isset($_GET['updatetheme'])) { - $poche->updateTheme(); -} elseif (isset($_GET['updatelanguage'])) { - $poche->updateLanguage(); -} elseif (isset($_GET['uploadfile'])) { - $poche->uploadFile(); -} elseif (isset($_GET['feed'])) { - if (isset($_GET['action']) && $_GET['action'] == 'generate') { - $poche->generateToken(); - } - else { - $tag_id = (isset($_GET['tag_id']) ? intval($_GET['tag_id']) : 0); - $poche->generateFeeds($_GET['token'], filter_var($_GET['user_id'],FILTER_SANITIZE_NUMBER_INT), $tag_id, $_GET['type']); - } -} - -elseif (isset($_GET['plainurl']) && !empty($_GET['plainurl'])) { - $plain_url = new Url(base64_encode($_GET['plainurl'])); - $poche->action('add', $plain_url); +} elseif (isset($_GET['feed']) && isset($_GET['user_id'])) { + $tag_id = (isset($_GET['tag_id']) ? intval($_GET['tag_id']) : 0); + $poche->generateFeeds($_GET['token'], filter_var($_GET['user_id'],FILTER_SANITIZE_NUMBER_INT), $tag_id, $_GET['type']); } if (Session::isLogged()) { + + if (isset($_GET['logout'])) { + # see you soon ! + $poche->logout(); + } elseif (isset($_GET['config'])) { + # Update password + $poche->updatePassword(); + } elseif (isset($_GET['newuser'])) { + $poche->createNewUser(); + } elseif (isset($_GET['deluser'])) { + $poche->deleteUser(); + } elseif (isset($_GET['epub'])) { + $poche->createEpub(); + } elseif (isset($_GET['import'])) { + $import = $poche->import(); + $tpl_vars = array_merge($tpl_vars, $import); + } elseif (isset($_GET['download'])) { + Tools::download_db(); + } elseif (isset($_GET['empty-cache'])) { + $poche->emptyCache(); + } elseif (isset($_GET['export'])) { + $poche->export(); + } elseif (isset($_GET['updatetheme'])) { + $poche->updateTheme(); + } elseif (isset($_GET['updatelanguage'])) { + $poche->updateLanguage(); + } elseif (isset($_GET['uploadfile'])) { + $poche->uploadFile(); + } elseif (isset($_GET['feed']) && isset($_GET['action']) && $_GET['action'] == 'generate') { + $poche->generateToken(); + } + elseif (isset($_GET['plainurl']) && !empty($_GET['plainurl'])) { + $plain_url = new Url(base64_encode($_GET['plainurl'])); + $poche->action('add', $plain_url); + } + $poche->action($action, $url, $id); $tpl_file = Tools::getTplFile($view); $tpl_vars = array_merge($tpl_vars, $poche->displayView($view, $id)); + } elseif(isset($_SERVER['PHP_AUTH_USER'])) { if($poche->store->userExists($_SERVER['PHP_AUTH_USER'])) { $poche->login($referer); From 38cf3413dfe156ced4f5f3a8c792cef69e2735f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20L=C5=93uillet?= Date: Thu, 24 Jul 2014 21:41:01 +0200 Subject: [PATCH 03/34] 1.7.2 --- index.php | 68 +++++++++++++++++++++++++++---------------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/index.php b/index.php index 2c532c0ee..b2ab1461f 100755 --- a/index.php +++ b/index.php @@ -8,7 +8,7 @@ * @license http://www.wtfpl.net/ see COPYING file */ -define ('POCHE', '1.7.1'); +define ('POCHE', '1.7.2'); require 'check_setup.php'; require_once 'inc/poche/global.inc.php'; @@ -72,39 +72,39 @@ if (isset($_GET['login'])) { if (Session::isLogged()) { - if (isset($_GET['logout'])) { - # see you soon ! - $poche->logout(); - } elseif (isset($_GET['config'])) { - # Update password - $poche->updatePassword(); - } elseif (isset($_GET['newuser'])) { - $poche->createNewUser(); - } elseif (isset($_GET['deluser'])) { - $poche->deleteUser(); - } elseif (isset($_GET['epub'])) { - $poche->createEpub(); - } elseif (isset($_GET['import'])) { - $import = $poche->import(); - $tpl_vars = array_merge($tpl_vars, $import); - } elseif (isset($_GET['download'])) { - Tools::download_db(); - } elseif (isset($_GET['empty-cache'])) { - $poche->emptyCache(); - } elseif (isset($_GET['export'])) { - $poche->export(); - } elseif (isset($_GET['updatetheme'])) { - $poche->updateTheme(); - } elseif (isset($_GET['updatelanguage'])) { - $poche->updateLanguage(); - } elseif (isset($_GET['uploadfile'])) { - $poche->uploadFile(); - } elseif (isset($_GET['feed']) && isset($_GET['action']) && $_GET['action'] == 'generate') { - $poche->generateToken(); - } - elseif (isset($_GET['plainurl']) && !empty($_GET['plainurl'])) { - $plain_url = new Url(base64_encode($_GET['plainurl'])); - $poche->action('add', $plain_url); + if (isset($_GET['logout'])) { + # see you soon ! + $poche->logout(); + } elseif (isset($_GET['config'])) { + # Update password + $poche->updatePassword(); + } elseif (isset($_GET['newuser'])) { + $poche->createNewUser(); + } elseif (isset($_GET['deluser'])) { + $poche->deleteUser(); + } elseif (isset($_GET['epub'])) { + $poche->createEpub(); + } elseif (isset($_GET['import'])) { + $import = $poche->import(); + $tpl_vars = array_merge($tpl_vars, $import); + } elseif (isset($_GET['download'])) { + Tools::download_db(); + } elseif (isset($_GET['empty-cache'])) { + $poche->emptyCache(); + } elseif (isset($_GET['export'])) { + $poche->export(); + } elseif (isset($_GET['updatetheme'])) { + $poche->updateTheme(); + } elseif (isset($_GET['updatelanguage'])) { + $poche->updateLanguage(); + } elseif (isset($_GET['uploadfile'])) { + $poche->uploadFile(); + } elseif (isset($_GET['feed']) && isset($_GET['action']) && $_GET['action'] == 'generate') { + $poche->generateToken(); + } + elseif (isset($_GET['plainurl']) && !empty($_GET['plainurl'])) { + $plain_url = new Url(base64_encode($_GET['plainurl'])); + $poche->action('add', $plain_url); } $poche->action($action, $url, $id); From 81315897f088105b445c194e7a984662bb208854 Mon Sep 17 00:00:00 2001 From: Jean Baptiste Favre Date: Sun, 21 Dec 2014 22:41:04 +0100 Subject: [PATCH 04/34] Make call to FTRSS silent to avoid warnings which can break import --- inc/poche/Tools.class.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/inc/poche/Tools.class.php b/inc/poche/Tools.class.php index f803e3b57..7ccfc069b 100755 --- a/inc/poche/Tools.class.php +++ b/inc/poche/Tools.class.php @@ -342,7 +342,10 @@ final class Tools return $json; }; - $json = $scope("inc/3rdparty/makefulltextfeed.php", array("url" => $url)); + // Silence $scope function to avoid + // issues with FTRSS when error_reporting is to high + // FTRSS generates PHP warnings which break output + $json = @$scope("inc/3rdparty/makefulltextfeed.php", array("url" => $url)); // Clearing and restoring context foreach ($GLOBALS as $key => $value) { From 37cad52229ac61b13f69440243df54e0e2a4536f Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Mon, 22 Dec 2014 16:26:23 +0100 Subject: [PATCH 05/34] don't call flattr if flattr is disabled --- inc/poche/Poche.class.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/inc/poche/Poche.class.php b/inc/poche/Poche.class.php index 27d6f4a65..a29cb327c 100755 --- a/inc/poche/Poche.class.php +++ b/inc/poche/Poche.class.php @@ -405,9 +405,12 @@ class Poche } # flattr checking - $flattr = new FlattrItem(); - $flattr->checkItem($entry['url'], $entry['id']); - + $flattr = NULL; + if (FLATTR) { + $flattr = new FlattrItem(); + $flattr->checkItem($entry['url'], $entry['id']); + } + # tags $tags = $this->store->retrieveTagsByEntry($entry['id']); @@ -812,4 +815,4 @@ class Poche } -} \ No newline at end of file +} From d4d33a4130490a2b1c6986e664ee7adcf0579eab Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Fri, 26 Dec 2014 10:25:49 +0100 Subject: [PATCH 06/34] deleted (again) courgette --- themes/courgette/config.twig | 127 ----------------------------------- 1 file changed, 127 deletions(-) delete mode 100755 themes/courgette/config.twig diff --git a/themes/courgette/config.twig b/themes/courgette/config.twig deleted file mode 100755 index 6b0fa3081..000000000 --- a/themes/courgette/config.twig +++ /dev/null @@ -1,127 +0,0 @@ -{% extends "layout.twig" %} - -{% block title %}{% trans "config" %}{% endblock %} -{% block menu %} -{% include '_menu.twig' %} -{% endblock %} -{% block content %} -
-

{% trans "Poching a link" %}

-

{% trans "There are several ways to save an article:" %} (?)

- - -

{% trans "Upgrading wallabag" %}

- - -

{% trans "Change your theme" %}

-
-
-
- - -
-
- -
-
- - -
- -

{% trans "Change your password" %}

-
-
-
- - -
-
- - -
-
- -
-
- - -
- -

{% trans "Import" %}

-

{% trans "Please execute the import script locally, it can take a very long time." %}

-

{% trans "More infos in the official doc:" %} wallabag.org

- - -

{% trans "Export your wallabag data" %}

-

{% trans "Click here" %} {% trans "to export your wallabag data." %}

- -

{% trans "Fancy an E-Book ?" %}

-

{% trans "Click to get all your articles in one ebook :" %} -

- -
{% trans "This can take a while and can even fail if you have too many articles, depending on your server configuration." %}

- -

{% trans 'Add user' %}

-

{% trans 'Add a new user :' %}

-
-
-
- - -
-
- - -
-
- -
-
-
- -

{% trans "Delete account" %}

- {% if not only_user %}
-

{% trans "You can delete your account by entering your password and validating." %}
{% trans "Be careful, data will be erased forever (that is a very long time)." %}

-
-
- - -
-
- -
- - {% else %}

{% trans "You are the only user, you cannot delete your own account." %}
- {% trans "To completely remove wallabag, delete the wallabag folder on your web server." %}

{% endif %} -
-{% endblock %} From 30b948e68b53dcb8b79c2aa1b62b992045892e90 Mon Sep 17 00:00:00 2001 From: goofy-bz Date: Fri, 2 Jan 2015 21:13:54 +0100 Subject: [PATCH 07/34] Update fr_FR.utf8.po formulation (trivial) --- locale/fr_FR.utf8/LC_MESSAGES/fr_FR.utf8.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locale/fr_FR.utf8/LC_MESSAGES/fr_FR.utf8.po b/locale/fr_FR.utf8/LC_MESSAGES/fr_FR.utf8.po index 3d031967b..849e66dcc 100644 --- a/locale/fr_FR.utf8/LC_MESSAGES/fr_FR.utf8.po +++ b/locale/fr_FR.utf8/LC_MESSAGES/fr_FR.utf8.po @@ -250,7 +250,7 @@ msgid "" "your config file: IMPORT_LIMIT (how many articles are fetched at once) and " "IMPORT_DELAY (delay between fetch of next batch of articles)." msgstr "" -"Sélectionner le fichier à importer sur votre disque dur, et pressez la " +"Sélectionnez le fichier à importer sur votre disque dur, et pressez la " "bouton « Importer » ci-dessous.
wallabag analysera votre fichier, " "ajoutera toutes les URL trouvées et commencera à télécharger les contenus si " "nécessaire.
Le processus de téléchargement est contrôlé par deux " From 166ff0a0932ede6824a30d553c39ff6dd7dbb0b4 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Sat, 3 Jan 2015 11:40:19 +0100 Subject: [PATCH 08/34] updated french mo file (see #986) --- locale/fr_FR.utf8/LC_MESSAGES/fr_FR.utf8.mo | Bin 21037 -> 21037 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/locale/fr_FR.utf8/LC_MESSAGES/fr_FR.utf8.mo b/locale/fr_FR.utf8/LC_MESSAGES/fr_FR.utf8.mo index eed260b2e0a008835e8fcc661fb8d2035da8dc1b..83f397a05d37afd64e4e148c7340b97ae3144b2e 100644 GIT binary patch delta 16 YcmZ3xgmLW>#tr9f7^^m4u!$7~06;ni3;+NC delta 16 YcmZ3xgmLW>#tr9f7>hPvu!$7~06+={1ONa4 From 8ae45e7fe27ab416cf2a30cd2c319940037b7cbf Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Sat, 3 Jan 2015 13:03:26 +0100 Subject: [PATCH 09/34] fixes #963 and use our own readability.php file for mobiClass --- inc/3rdparty/libraries/MOBIClass/MOBI.php | 4 +- .../readability/JSLikeHTMLElement.php | 110 -- .../MOBIClass/readability/Readability.php | 1069 ----------------- .../libraries/readability/Readability.php | 5 +- inc/3rdparty/makefulltextfeed.php | 2 + 5 files changed, 7 insertions(+), 1183 deletions(-) delete mode 100644 inc/3rdparty/libraries/MOBIClass/readability/JSLikeHTMLElement.php delete mode 100644 inc/3rdparty/libraries/MOBIClass/readability/Readability.php diff --git a/inc/3rdparty/libraries/MOBIClass/MOBI.php b/inc/3rdparty/libraries/MOBIClass/MOBI.php index 17e718c12..df4826b04 100644 --- a/inc/3rdparty/libraries/MOBIClass/MOBI.php +++ b/inc/3rdparty/libraries/MOBIClass/MOBI.php @@ -1,5 +1,5 @@ \ No newline at end of file +?> diff --git a/inc/3rdparty/libraries/MOBIClass/readability/JSLikeHTMLElement.php b/inc/3rdparty/libraries/MOBIClass/readability/JSLikeHTMLElement.php deleted file mode 100644 index 1a8ec88cb..000000000 --- a/inc/3rdparty/libraries/MOBIClass/readability/JSLikeHTMLElement.php +++ /dev/null @@ -1,110 +0,0 @@ -registerNodeClass('DOMElement', 'JSLikeHTMLElement'); -* $doc->loadHTML('

Para 1

Para 2

'); -* $elem = $doc->getElementsByTagName('div')->item(0); -* -* // print innerHTML -* echo $elem->innerHTML; // prints '

Para 1

Para 2

' -* echo "\n\n"; -* -* // set innerHTML -* $elem->innerHTML = 'FiveFilters.org'; -* echo $elem->innerHTML; // prints 'FiveFilters.org' -* echo "\n\n"; -* -* // print document (with our changes) -* echo $doc->saveXML(); -* @endcode -* -* @author Keyvan Minoukadeh - http://www.keyvan.net - keyvan@keyvan.net -* @see http://fivefilters.org (the project this was written for) -*/ -class JSLikeHTMLElement extends DOMElement -{ - /** - * Used for setting innerHTML like it's done in JavaScript: - * @code - * $div->innerHTML = '

Chapter 2

The story begins...

'; - * @endcode - */ - public function __set($name, $value) { - if ($name == 'innerHTML') { - // first, empty the element - for ($x=$this->childNodes->length-1; $x>=0; $x--) { - $this->removeChild($this->childNodes->item($x)); - } - // $value holds our new inner HTML - if ($value != '') { - $f = $this->ownerDocument->createDocumentFragment(); - // appendXML() expects well-formed markup (XHTML) - $result = @$f->appendXML($value); // @ to suppress PHP warnings - if ($result) { - if ($f->hasChildNodes()) $this->appendChild($f); - } else { - // $value is probably ill-formed - $f = new DOMDocument(); - $value = mb_convert_encoding($value, 'HTML-ENTITIES', 'UTF-8'); - // Using will generate a warning, but so will bad HTML - // (and by this point, bad HTML is what we've got). - // We use it (and suppress the warning) because an HTML fragment will - // be wrapped around tags which we don't really want to keep. - // Note: despite the warning, if loadHTML succeeds it will return true. - $result = @$f->loadHTML(''.$value.''); - if ($result) { - $import = $f->getElementsByTagName('htmlfragment')->item(0); - foreach ($import->childNodes as $child) { - $importedNode = $this->ownerDocument->importNode($child, true); - $this->appendChild($importedNode); - } - } else { - // oh well, we tried, we really did. :( - // this element is now empty - } - } - } - } else { - $trace = debug_backtrace(); - trigger_error('Undefined property via __set(): '.$name.' in '.$trace[0]['file'].' on line '.$trace[0]['line'], E_USER_NOTICE); - } - } - - /** - * Used for getting innerHTML like it's done in JavaScript: - * @code - * $string = $div->innerHTML; - * @endcode - */ - public function __get($name) - { - if ($name == 'innerHTML') { - $inner = ''; - foreach ($this->childNodes as $child) { - $inner .= $this->ownerDocument->saveXML($child); - } - return $inner; - } - - $trace = debug_backtrace(); - trigger_error('Undefined property via __get(): '.$name.' in '.$trace[0]['file'].' on line '.$trace[0]['line'], E_USER_NOTICE); - return null; - } - - public function __toString() - { - return '['.$this->tagName.']'; - } -} -?> \ No newline at end of file diff --git a/inc/3rdparty/libraries/MOBIClass/readability/Readability.php b/inc/3rdparty/libraries/MOBIClass/readability/Readability.php deleted file mode 100644 index 915542435..000000000 --- a/inc/3rdparty/libraries/MOBIClass/readability/Readability.php +++ /dev/null @@ -1,1069 +0,0 @@ -init(); -echo $r->articleContent->innerHTML; -*/ - -class Readability -{ - public $version = '1.7.1-without-multi-page'; - public $convertLinksToFootnotes = false; - public $revertForcedParagraphElements = true; - public $articleTitle; - public $articleContent; - public $dom; - public $url = null; // optional - URL where HTML was retrieved - public $debug = false; - protected $body = null; // - protected $bodyCache = null; // Cache the body HTML in case we need to re-use it later - protected $flags = 7; // 1 | 2 | 4; // Start with all flags set. - protected $success = false; // indicates whether we were able to extract or not - - /** - * All of the regular expressions in use within readability. - * Defined up here so we don't instantiate them repeatedly in loops. - **/ - public $regexps = array( - 'unlikelyCandidates' => '/combx|comment|community|disqus|extra|foot|header|menu|remark|rss|shoutbox|sidebar|sponsor|ad-break|agegate|pagination|pager|popup|tweet|twitter/i', - 'okMaybeItsACandidate' => '/and|article|body|column|main|shadow/i', - 'positive' => '/article|body|content|entry|hentry|main|page|pagination|post|text|blog|story/i', - 'negative' => '/combx|comment|com-|contact|foot|footer|footnote|masthead|media|meta|outbrain|promo|related|scroll|shoutbox|sidebar|sponsor|shopping|tags|tool|widget/i', - 'divToPElements' => '/<(a|blockquote|dl|div|img|ol|p|pre|table|ul)/i', - 'replaceBrs' => '/(]*>[ \n\r\t]*){2,}/i', - 'replaceFonts' => '/<(\/?)font[^>]*>/i', - // 'trimRe' => '/^\s+|\s+$/g', // PHP has trim() - 'normalize' => '/\s{2,}/', - 'killBreaks' => '/((\s| ?)*){1,}/', - 'video' => '/http:\/\/(www\.)?(youtube|vimeo)\.com/i', - 'skipFootnoteLink' => '/^\s*(\[?[a-z0-9]{1,2}\]?|^|edit|citation needed)\s*$/i' - ); - - /* constants */ - const FLAG_STRIP_UNLIKELYS = 1; - const FLAG_WEIGHT_CLASSES = 2; - const FLAG_CLEAN_CONDITIONALLY = 4; - - /** - * Create instance of Readability - * @param string UTF-8 encoded string - * @param string (optional) URL associated with HTML (used for footnotes) - */ - function __construct($html, $url=null) - { - /* Turn all double br's into p's */ - /* Note, this is pretty costly as far as processing goes. Maybe optimize later. */ - $html = preg_replace($this->regexps['replaceBrs'], '

', $html); - $html = preg_replace($this->regexps['replaceFonts'], '<$1span>', $html); - $html = mb_convert_encoding($html, 'HTML-ENTITIES', "UTF-8"); - $this->dom = new DOMDocument(); - $this->dom->preserveWhiteSpace = false; - $this->dom->registerNodeClass('DOMElement', 'JSLikeHTMLElement'); - @$this->dom->loadHTML($html); - $this->url = $url; - } - - /** - * Get article title element - * @return DOMElement - */ - public function getTitle() { - return $this->articleTitle; - } - - /** - * Get article content element - * @return DOMElement - */ - public function getContent() { - return $this->articleContent; - } - - /** - * Runs readability. - * - * Workflow: - * 1. Prep the document by removing script tags, css, etc. - * 2. Build readability's DOM tree. - * 3. Grab the article content from the current dom tree. - * 4. Replace the current DOM tree with the new one. - * 5. Read peacefully. - * - * @return boolean true if we found content, false otherwise - **/ - public function init() - { - $this->removeScripts($this->dom); - - // Assume successful outcome - $this->success = true; - - $bodyElems = $this->dom->getElementsByTagName('body'); - if ($bodyElems->length > 0) { - if ($this->bodyCache == null) { - $this->bodyCache = $bodyElems->item(0)->innerHTML; - } - if ($this->body == null) { - $this->body = $bodyElems->item(0); - } - } - - $this->prepDocument(); - - //die($this->dom->documentElement->parentNode->nodeType); - //$this->setInnerHTML($this->dom->documentElement, $this->getInnerHTML($this->dom->documentElement)); - //die($this->getInnerHTML($this->dom->documentElement)); - - /* Build readability's DOM tree */ - $overlay = $this->dom->createElement('div'); - $innerDiv = $this->dom->createElement('div'); - $articleTitle = $this->getArticleTitle(); - $articleContent = $this->grabArticle(); - - if (!$articleContent) { - $this->success = false; - $articleContent = $this->dom->createElement('div'); - $articleContent->setAttribute('id', 'readability-content'); - $articleContent->innerHTML = '

Sorry, Readability was unable to parse this page for content.

'; - } - - $overlay->setAttribute('id', 'readOverlay'); - $innerDiv->setAttribute('id', 'readInner'); - - /* Glue the structure of our document together. */ - $innerDiv->appendChild($articleTitle); - $innerDiv->appendChild($articleContent); - $overlay->appendChild($innerDiv); - - /* Clear the old HTML, insert the new content. */ - $this->body->innerHTML = ''; - $this->body->appendChild($overlay); - //document.body.insertBefore(overlay, document.body.firstChild); - $this->body->removeAttribute('style'); - - $this->postProcessContent($articleContent); - - // Set title and content instance variables - $this->articleTitle = $articleTitle; - $this->articleContent = $articleContent; - - return $this->success; - } - - /** - * Debug - */ - protected function dbg($msg) { - if ($this->debug) echo '* ',$msg, '
', "\n"; - } - - /** - * Run any post-process modifications to article content as necessary. - * - * @param DOMElement - * @return void - */ - public function postProcessContent($articleContent) { - if ($this->convertLinksToFootnotes && !preg_match('/wikipedia\.org/', @$this->url)) { - $this->addFootnotes($articleContent); - } - } - - /** - * Get the article title as an H1. - * - * @return DOMElement - */ - protected function getArticleTitle() { - $curTitle = ''; - $origTitle = ''; - - try { - $curTitle = $origTitle = $this->getInnerText($this->dom->getElementsByTagName('title')->item(0)); - } catch(Exception $e) {} - - if (preg_match('/ [\|\-] /', $curTitle)) - { - $curTitle = preg_replace('/(.*)[\|\-] .*/i', '$1', $origTitle); - - if (count(explode(' ', $curTitle)) < 3) { - $curTitle = preg_replace('/[^\|\-]*[\|\-](.*)/i', '$1', $origTitle); - } - } - else if (strpos($curTitle, ': ') !== false) - { - $curTitle = preg_replace('/.*:(.*)/i', '$1', $origTitle); - - if (count(explode(' ', $curTitle)) < 3) { - $curTitle = preg_replace('/[^:]*[:](.*)/i','$1', $origTitle); - } - } - else if(strlen($curTitle) > 150 || strlen($curTitle) < 15) - { - $hOnes = $this->dom->getElementsByTagName('h1'); - if($hOnes->length == 1) - { - $curTitle = $this->getInnerText($hOnes->item(0)); - } - } - - $curTitle = trim($curTitle); - - if (count(explode(' ', $curTitle)) <= 4) { - $curTitle = $origTitle; - } - - $articleTitle = $this->dom->createElement('h1'); - $articleTitle->innerHTML = $curTitle; - - return $articleTitle; - } - - /** - * Prepare the HTML document for readability to scrape it. - * This includes things like stripping javascript, CSS, and handling terrible markup. - * - * @return void - **/ - protected function prepDocument() { - /** - * In some cases a body element can't be found (if the HTML is totally hosed for example) - * so we create a new body node and append it to the document. - */ - if($this->dom->documentElement == null){ - throw new Exception("No document element"); - } - if ($this->body == null) - { - $this->body = $this->dom->createElement('body'); - $this->dom->documentElement->appendChild($this->body); - } - - $this->body->setAttribute('id', 'readabilityBody'); - - /* Remove all style tags in head */ - $styleTags = $this->dom->getElementsByTagName('style'); - for ($i = $styleTags->length-1; $i >= 0; $i--) - { - $styleTags->item($i)->parentNode->removeChild($styleTags->item($i)); - } - - /* Turn all double br's into p's */ - /* Note, this is pretty costly as far as processing goes. Maybe optimize later. */ - //document.body.innerHTML = document.body.innerHTML.replace(readability.regexps.replaceBrs, '

').replace(readability.regexps.replaceFonts, '<$1span>'); - // We do this in the constructor for PHP as that's when we have raw HTML - before parsing it into a DOM tree. - // Manipulating innerHTML as it's done in JS is not possible in PHP. - } - - /** - * For easier reading, convert this document to have footnotes at the bottom rather than inline links. - * @see http://www.roughtype.com/archives/2010/05/experiments_in.php - * - * @return void - **/ - public function addFootnotes($articleContent) { - $footnotesWrapper = $this->dom->createElement('div'); - $footnotesWrapper->setAttribute('id', 'readability-footnotes'); - $footnotesWrapper->innerHTML = '

References

'; - - $articleFootnotes = $this->dom->createElement('ol'); - $articleFootnotes->setAttribute('id', 'readability-footnotes-list'); - $footnotesWrapper->appendChild($articleFootnotes); - - $articleLinks = $articleContent->getElementsByTagName('a'); - - $linkCount = 0; - for ($i = 0; $i < $articleLinks->length; $i++) - { - $articleLink = $articleLinks->item($i); - $footnoteLink = $articleLink->cloneNode(true); - $refLink = $this->dom->createElement('a'); - $footnote = $this->dom->createElement('li'); - $linkDomain = @parse_url($footnoteLink->getAttribute('href'), PHP_URL_HOST); - if (!$linkDomain && isset($this->url)) $linkDomain = @parse_url($this->url, PHP_URL_HOST); - //linkDomain = footnoteLink.host ? footnoteLink.host : document.location.host, - $linkText = $this->getInnerText($articleLink); - - if ((strpos($articleLink->getAttribute('class'), 'readability-DoNotFootnote') !== false) || preg_match($this->regexps['skipFootnoteLink'], $linkText)) { - continue; - } - - $linkCount++; - - /** Add a superscript reference after the article link */ - $refLink->setAttribute('href', '#readabilityFootnoteLink-' . $linkCount); - $refLink->innerHTML = '[' . $linkCount . ']'; - $refLink->setAttribute('class', 'readability-DoNotFootnote'); - $refLink->setAttribute('style', 'color: inherit;'); - - //TODO: does this work or should we use DOMNode.isSameNode()? - if ($articleLink->parentNode->lastChild == $articleLink) { - $articleLink->parentNode->appendChild($refLink); - } else { - $articleLink->parentNode->insertBefore($refLink, $articleLink->nextSibling); - } - - $articleLink->setAttribute('style', 'color: inherit; text-decoration: none;'); - $articleLink->setAttribute('name', 'readabilityLink-' . $linkCount); - - $footnote->innerHTML = '^ '; - - $footnoteLink->innerHTML = ($footnoteLink->getAttribute('title') != '' ? $footnoteLink->getAttribute('title') : $linkText); - $footnoteLink->setAttribute('name', 'readabilityFootnoteLink-' . $linkCount); - - $footnote->appendChild($footnoteLink); - if ($linkDomain) $footnote->innerHTML = $footnote->innerHTML . ' (' . $linkDomain . ')'; - - $articleFootnotes->appendChild($footnote); - } - - if ($linkCount > 0) { - $articleContent->appendChild($footnotesWrapper); - } - } - - /** - * Reverts P elements with class 'readability-styled' - * to text nodes - which is what they were before. - * - * @param DOMElement - * @return void - */ - function revertReadabilityStyledElements($articleContent) { - $xpath = new DOMXPath($articleContent->ownerDocument); - $elems = $xpath->query('.//p[@class="readability-styled"]', $articleContent); - //$elems = $articleContent->getElementsByTagName('p'); - for ($i = $elems->length-1; $i >= 0; $i--) { - $e = $elems->item($i); - $e->parentNode->replaceChild($articleContent->ownerDocument->createTextNode($e->textContent), $e); - //if ($e->hasAttribute('class') && $e->getAttribute('class') == 'readability-styled') { - // $e->parentNode->replaceChild($this->dom->createTextNode($e->textContent), $e); - //} - } - } - - /** - * Prepare the article node for display. Clean out any inline styles, - * iframes, forms, strip extraneous

tags, etc. - * - * @param DOMElement - * @return void - */ - function prepArticle($articleContent) { - $this->cleanStyles($articleContent); - $this->killBreaks($articleContent); - if ($this->revertForcedParagraphElements) { - $this->revertReadabilityStyledElements($articleContent); - } - - /* Clean out junk from the article content */ - $this->cleanConditionally($articleContent, 'form'); - $this->clean($articleContent, 'object'); - $this->clean($articleContent, 'h1'); - - /** - * If there is only one h2, they are probably using it - * as a header and not a subheader, so remove it since we already have a header. - ***/ - if ($articleContent->getElementsByTagName('h2')->length == 1) { - $this->clean($articleContent, 'h2'); - } - $this->clean($articleContent, 'iframe'); - - $this->cleanHeaders($articleContent); - - /* Do these last as the previous stuff may have removed junk that will affect these */ - $this->cleanConditionally($articleContent, 'table'); - $this->cleanConditionally($articleContent, 'ul'); - $this->cleanConditionally($articleContent, 'div'); - - /* Remove extra paragraphs */ - $articleParagraphs = $articleContent->getElementsByTagName('p'); - for ($i = $articleParagraphs->length-1; $i >= 0; $i--) - { - $imgCount = $articleParagraphs->item($i)->getElementsByTagName('img')->length; - $embedCount = $articleParagraphs->item($i)->getElementsByTagName('embed')->length; - $objectCount = $articleParagraphs->item($i)->getElementsByTagName('object')->length; - - if ($imgCount === 0 && $embedCount === 0 && $objectCount === 0 && $this->getInnerText($articleParagraphs->item($i), false) == '') - { - $articleParagraphs->item($i)->parentNode->removeChild($articleParagraphs->item($i)); - } - } - - try { - $articleContent->innerHTML = preg_replace('/]*>\s*

innerHTML); - //articleContent.innerHTML = articleContent.innerHTML.replace(/]*>\s*

dbg("Cleaning innerHTML of breaks failed. This is an IE strict-block-elements bug. Ignoring.: " . $e); - } - } - - /** - * Initialize a node with the readability object. Also checks the - * className/id for special names to add to its score. - * - * @param Element - * @return void - **/ - protected function initializeNode($node) { - $readability = $this->dom->createAttribute('readability'); - $readability->value = 0; // this is our contentScore - $node->setAttributeNode($readability); - - switch (strtoupper($node->tagName)) { // unsure if strtoupper is needed, but using it just in case - case 'DIV': - $readability->value += 5; - break; - - case 'PRE': - case 'TD': - case 'BLOCKQUOTE': - $readability->value += 3; - break; - - case 'ADDRESS': - case 'OL': - case 'UL': - case 'DL': - case 'DD': - case 'DT': - case 'LI': - case 'FORM': - $readability->value -= 3; - break; - - case 'H1': - case 'H2': - case 'H3': - case 'H4': - case 'H5': - case 'H6': - case 'TH': - $readability->value -= 5; - break; - } - $readability->value += $this->getClassWeight($node); - } - - /*** - * grabArticle - Using a variety of metrics (content score, classname, element types), find the content that is - * most likely to be the stuff a user wants to read. Then return it wrapped up in a div. - * - * @return DOMElement - **/ - protected function grabArticle($page=null) { - $stripUnlikelyCandidates = $this->flagIsActive(self::FLAG_STRIP_UNLIKELYS); - if (!$page) $page = $this->dom; - $allElements = $page->getElementsByTagName('*'); - /** - * First, node prepping. Trash nodes that look cruddy (like ones with the class name "comment", etc), and turn divs - * into P tags where they have been used inappropriately (as in, where they contain no other block level elements.) - * - * Note: Assignment from index for performance. See http://www.peachpit.com/articles/article.aspx?p=31567&seqNum=5 - * TODO: Shouldn't this be a reverse traversal? - **/ - $node = null; - $nodesToScore = array(); - for ($nodeIndex = 0; ($node = $allElements->item($nodeIndex)); $nodeIndex++) { - //for ($nodeIndex=$targetList->length-1; $nodeIndex >= 0; $nodeIndex--) { - //$node = $targetList->item($nodeIndex); - $tagName = strtoupper($node->tagName); - /* Remove unlikely candidates */ - if ($stripUnlikelyCandidates) { - $unlikelyMatchString = $node->getAttribute('class') . $node->getAttribute('id'); - if ( - preg_match($this->regexps['unlikelyCandidates'], $unlikelyMatchString) && - !preg_match($this->regexps['okMaybeItsACandidate'], $unlikelyMatchString) && - $tagName != 'BODY' - ) - { - $this->dbg('Removing unlikely candidate - ' . $unlikelyMatchString); - //$nodesToRemove[] = $node; - $node->parentNode->removeChild($node); - $nodeIndex--; - continue; - } - } - - if ($tagName == 'P' || $tagName == 'TD' || $tagName == 'PRE') { - $nodesToScore[] = $node; - } - - /* Turn all divs that don't have children block level elements into p's */ - if ($tagName == 'DIV') { - if (!preg_match($this->regexps['divToPElements'], $node->innerHTML)) { - //$this->dbg('Altering div to p'); - $newNode = $this->dom->createElement('p'); - try { - $newNode->innerHTML = $node->innerHTML; - //$nodesToReplace[] = array('new'=>$newNode, 'old'=>$node); - $node->parentNode->replaceChild($newNode, $node); - $nodeIndex--; - $nodesToScore[] = $node; // or $newNode? - } - catch(Exception $e) { - $this->dbg('Could not alter div to p, reverting back to div.: ' . $e); - } - } - else - { - /* EXPERIMENTAL */ - // TODO: change these p elements back to text nodes after processing - for ($i = 0, $il = $node->childNodes->length; $i < $il; $i++) { - $childNode = $node->childNodes->item($i); - if ($childNode->nodeType == 3) { // XML_TEXT_NODE - //$this->dbg('replacing text node with a p tag with the same content.'); - $p = $this->dom->createElement('p'); - $p->innerHTML = $childNode->nodeValue; - $p->setAttribute('style', 'display: inline;'); - $p->setAttribute('class', 'readability-styled'); - $childNode->parentNode->replaceChild($p, $childNode); - } - } - } - } - } - - /** - * Loop through all paragraphs, and assign a score to them based on how content-y they look. - * Then add their score to their parent node. - * - * A score is determined by things like number of commas, class names, etc. Maybe eventually link density. - **/ - $candidates = array(); - for ($pt=0; $pt < count($nodesToScore); $pt++) { - $parentNode = $nodesToScore[$pt]->parentNode; - // $grandParentNode = $parentNode ? $parentNode->parentNode : null; - $grandParentNode = !$parentNode ? null : (($parentNode->parentNode instanceof DOMElement) ? $parentNode->parentNode : null); - $innerText = $this->getInnerText($nodesToScore[$pt]); - - if (!$parentNode || !isset($parentNode->tagName)) { - continue; - } - - /* If this paragraph is less than 25 characters, don't even count it. */ - if(strlen($innerText) < 25) { - continue; - } - - /* Initialize readability data for the parent. */ - if (!$parentNode->hasAttribute('readability')) - { - $this->initializeNode($parentNode); - $candidates[] = $parentNode; - } - - /* Initialize readability data for the grandparent. */ - if ($grandParentNode && !$grandParentNode->hasAttribute('readability') && isset($grandParentNode->tagName)) - { - $this->initializeNode($grandParentNode); - $candidates[] = $grandParentNode; - } - - $contentScore = 0; - - /* Add a point for the paragraph itself as a base. */ - $contentScore++; - - /* Add points for any commas within this paragraph */ - $contentScore += count(explode(',', $innerText)); - - /* For every 100 characters in this paragraph, add another point. Up to 3 points. */ - $contentScore += min(floor(strlen($innerText) / 100), 3); - - /* Add the score to the parent. The grandparent gets half. */ - $parentNode->getAttributeNode('readability')->value += $contentScore; - - if ($grandParentNode) { - $grandParentNode->getAttributeNode('readability')->value += $contentScore/2; - } - } - - /** - * After we've calculated scores, loop through all of the possible candidate nodes we found - * and find the one with the highest score. - **/ - $topCandidate = null; - for ($c=0, $cl=count($candidates); $c < $cl; $c++) - { - /** - * Scale the final candidates score based on link density. Good content should have a - * relatively small link density (5% or less) and be mostly unaffected by this operation. - **/ - $readability = $candidates[$c]->getAttributeNode('readability'); - $readability->value = $readability->value * (1-$this->getLinkDensity($candidates[$c])); - - $this->dbg('Candidate: ' . $candidates[$c]->tagName . ' (' . $candidates[$c]->getAttribute('class') . ':' . $candidates[$c]->getAttribute('id') . ') with score ' . $readability->value); - - if (!$topCandidate || $readability->value > (int)$topCandidate->getAttribute('readability')) { - $topCandidate = $candidates[$c]; - } - } - - /** - * If we still have no top candidate, just use the body as a last resort. - * We also have to copy the body node so it is something we can modify. - **/ - if ($topCandidate === null || strtoupper($topCandidate->tagName) == 'BODY') - { - $topCandidate = $this->dom->createElement('div'); - $topCandidate->innerHTML = ($page instanceof DOMDocument) ? $page->saveXML($page->documentElement) : $page->innerHTML; - $page->innerHTML = ''; - $page->appendChild($topCandidate); - $this->initializeNode($topCandidate); - } - - /** - * Now that we have the top candidate, look through its siblings for content that might also be related. - * Things like preambles, content split by ads that we removed, etc. - **/ - $articleContent = $this->dom->createElement('div'); - $articleContent->setAttribute('id', 'readability-content'); - $siblingScoreThreshold = max(10, ((int)$topCandidate->getAttribute('readability')) * 0.2); - $siblingNodes = $topCandidate->parentNode->childNodes; - - for ($s=0, $sl=$siblingNodes->length; $s < $sl; $s++) - { - $siblingNode = $siblingNodes->item($s); - $append = false; - - $this->dbg('Looking at sibling node: ' . $siblingNode->nodeName . (($siblingNode->nodeType === XML_ELEMENT_NODE && $siblingNode->hasAttribute('readability')) ? (' with score ' . $siblingNode->getAttribute('readability')) : '')); - - //dbg('Sibling has score ' . ($siblingNode->readability ? siblingNode.readability.contentScore : 'Unknown')); - - if ($siblingNode === $topCandidate) - // or if ($siblingNode->isSameNode($topCandidate)) - { - $append = true; - } - - $contentBonus = 0; - /* Give a bonus if sibling nodes and top candidates have the example same classname */ - if ($siblingNode->nodeType === XML_ELEMENT_NODE && $siblingNode->getAttribute('class') == $topCandidate->getAttribute('class') && $topCandidate->getAttribute('class') != '') { - $contentBonus += ((int)$topCandidate->getAttribute('readability')) * 0.2; - } - - if ($siblingNode->nodeType === XML_ELEMENT_NODE && $siblingNode->hasAttribute('readability') && (((int)$siblingNode->getAttribute('readability')) + $contentBonus) >= $siblingScoreThreshold) - { - $append = true; - } - - if (strtoupper($siblingNode->nodeName) == 'P') { - $linkDensity = $this->getLinkDensity($siblingNode); - $nodeContent = $this->getInnerText($siblingNode); - $nodeLength = strlen($nodeContent); - - if ($nodeLength > 80 && $linkDensity < 0.25) - { - $append = true; - } - else if ($nodeLength < 80 && $linkDensity === 0 && preg_match('/\.( |$)/', $nodeContent)) - { - $append = true; - } - } - - if ($append) - { - $this->dbg('Appending node: ' . $siblingNode->nodeName); - - $nodeToAppend = null; - $sibNodeName = strtoupper($siblingNode->nodeName); - if ($sibNodeName != 'DIV' && $sibNodeName != 'P') { - /* We have a node that isn't a common block level element, like a form or td tag. Turn it into a div so it doesn't get filtered out later by accident. */ - - $this->dbg('Altering siblingNode of ' . $sibNodeName . ' to div.'); - $nodeToAppend = $this->dom->createElement('div'); - try { - $nodeToAppend->setAttribute('id', $siblingNode->getAttribute('id')); - $nodeToAppend->innerHTML = $siblingNode->innerHTML; - } - catch(Exception $e) - { - $this->dbg('Could not alter siblingNode to div, reverting back to original.'); - $nodeToAppend = $siblingNode; - $s--; - $sl--; - } - } else { - $nodeToAppend = $siblingNode; - $s--; - $sl--; - } - - /* To ensure a node does not interfere with readability styles, remove its classnames */ - $nodeToAppend->removeAttribute('class'); - - /* Append sibling and subtract from our list because it removes the node when you append to another node */ - $articleContent->appendChild($nodeToAppend); - } - } - - /** - * So we have all of the content that we need. Now we clean it up for presentation. - **/ - $this->prepArticle($articleContent); - - /** - * Now that we've gone through the full algorithm, check to see if we got any meaningful content. - * If we didn't, we may need to re-run grabArticle with different flags set. This gives us a higher - * likelihood of finding the content, and the sieve approach gives us a higher likelihood of - * finding the -right- content. - **/ - if (strlen($this->getInnerText($articleContent, false)) < 250) - { - $this->body->innerHTML = $this->bodyCache; - - if ($this->flagIsActive(self::FLAG_STRIP_UNLIKELYS)) { - $this->removeFlag(self::FLAG_STRIP_UNLIKELYS); - return $this->grabArticle($this->body); - } - else if ($this->flagIsActive(self::FLAG_WEIGHT_CLASSES)) { - $this->removeFlag(self::FLAG_WEIGHT_CLASSES); - return $this->grabArticle($this->body); - } - else if ($this->flagIsActive(self::FLAG_CLEAN_CONDITIONALLY)) { - $this->removeFlag(self::FLAG_CLEAN_CONDITIONALLY); - return $this->grabArticle($this->body); - } - else { - return false; - } - } - return $articleContent; - } - - /** - * Remove script tags from document - * - * @param DOMElement - * @return void - */ - public function removeScripts($doc) { - $scripts = $doc->getElementsByTagName('script'); - for($i = $scripts->length-1; $i >= 0; $i--) - { - $scripts->item($i)->parentNode->removeChild($scripts->item($i)); - } - } - - /** - * Get the inner text of a node. - * This also strips out any excess whitespace to be found. - * - * @param DOMElement $ - * @param boolean $normalizeSpaces (default: true) - * @return string - **/ - public function getInnerText($e, $normalizeSpaces=true) { - $textContent = ''; - - if (!isset($e->textContent) || $e->textContent == '') { - return ''; - } - - $textContent = trim($e->textContent); - - if ($normalizeSpaces) { - return preg_replace($this->regexps['normalize'], ' ', $textContent); - } else { - return $textContent; - } - } - - /** - * Get the number of times a string $s appears in the node $e. - * - * @param DOMElement $e - * @param string - what to count. Default is "," - * @return number (integer) - **/ - public function getCharCount($e, $s=',') { - return substr_count($this->getInnerText($e), $s); - } - - /** - * Remove the style attribute on every $e and under. - * - * @param DOMElement $e - * @return void - */ - public function cleanStyles($e) { - $elems = $e->getElementsByTagName('*'); - foreach ($elems as $elem) { - $elem->removeAttribute('style'); - } - } - - /** - * Get the density of links as a percentage of the content - * This is the amount of text that is inside a link divided by the total text in the node. - * - * @param DOMElement $e - * @return number (float) - */ - public function getLinkDensity($e) { - $links = $e->getElementsByTagName('a'); - $textLength = strlen($this->getInnerText($e)); - $linkLength = 0; - for ($i=0, $il=$links->length; $i < $il; $i++) - { - $linkLength += strlen($this->getInnerText($links->item($i))); - } - if ($textLength > 0) { - return $linkLength / $textLength; - } else { - return 0; - } - } - - /** - * Get an elements class/id weight. Uses regular expressions to tell if this - * element looks good or bad. - * - * @param DOMElement $e - * @return number (Integer) - */ - public function getClassWeight($e) { - if(!$this->flagIsActive(self::FLAG_WEIGHT_CLASSES)) { - return 0; - } - - $weight = 0; - - /* Look for a special classname */ - if ($e->hasAttribute('class') && $e->getAttribute('class') != '') - { - if (preg_match($this->regexps['negative'], $e->getAttribute('class'))) { - $weight -= 25; - } - if (preg_match($this->regexps['positive'], $e->getAttribute('class'))) { - $weight += 25; - } - } - - /* Look for a special ID */ - if ($e->hasAttribute('id') && $e->getAttribute('id') != '') - { - if (preg_match($this->regexps['negative'], $e->getAttribute('id'))) { - $weight -= 25; - } - if (preg_match($this->regexps['positive'], $e->getAttribute('id'))) { - $weight += 25; - } - } - return $weight; - } - - /** - * Remove extraneous break tags from a node. - * - * @param DOMElement $node - * @return void - */ - public function killBreaks($node) { - $html = $node->innerHTML; - $html = preg_replace($this->regexps['killBreaks'], '
', $html); - $node->innerHTML = $html; - } - - /** - * Clean a node of all elements of type "tag". - * (Unless it's a youtube/vimeo video. People love movies.) - * - * @param DOMElement $e - * @param string $tag - * @return void - */ - public function clean($e, $tag) { - $targetList = $e->getElementsByTagName($tag); - $isEmbed = ($tag == 'object' || $tag == 'embed'); - - for ($y=$targetList->length-1; $y >= 0; $y--) { - /* Allow youtube and vimeo videos through as people usually want to see those. */ - if ($isEmbed) { - $attributeValues = ''; - for ($i=0, $il=$targetList->item($y)->attributes->length; $i < $il; $i++) { - $attributeValues .= $targetList->item($y)->attributes->item($i)->value . '|'; // DOMAttr? (TODO: test) - } - - /* First, check the elements attributes to see if any of them contain youtube or vimeo */ - if (preg_match($this->regexps['video'], $attributeValues)) { - continue; - } - - /* Then check the elements inside this element for the same. */ - if (preg_match($this->regexps['video'], $targetList->item($y)->innerHTML)) { - continue; - } - } - $targetList->item($y)->parentNode->removeChild($targetList->item($y)); - } - } - - /** - * Clean an element of all tags of type "tag" if they look fishy. - * "Fishy" is an algorithm based on content length, classnames, - * link density, number of images & embeds, etc. - * - * @param DOMElement $e - * @param string $tag - * @return void - */ - public function cleanConditionally($e, $tag) { - if (!$this->flagIsActive(self::FLAG_CLEAN_CONDITIONALLY)) { - return; - } - - $tagsList = $e->getElementsByTagName($tag); - $curTagsLength = $tagsList->length; - - /** - * Gather counts for other typical elements embedded within. - * Traverse backwards so we can remove nodes at the same time without effecting the traversal. - * - * TODO: Consider taking into account original contentScore here. - */ - for ($i=$curTagsLength-1; $i >= 0; $i--) { - $weight = $this->getClassWeight($tagsList->item($i)); - $contentScore = ($tagsList->item($i)->hasAttribute('readability')) ? (int)$tagsList->item($i)->getAttribute('readability') : 0; - - $this->dbg('Cleaning Conditionally ' . $tagsList->item($i)->tagName . ' (' . $tagsList->item($i)->getAttribute('class') . ':' . $tagsList->item($i)->getAttribute('id') . ')' . (($tagsList->item($i)->hasAttribute('readability')) ? (' with score ' . $tagsList->item($i)->getAttribute('readability')) : '')); - - if ($weight + $contentScore < 0) { - $tagsList->item($i)->parentNode->removeChild($tagsList->item($i)); - } - else if ( $this->getCharCount($tagsList->item($i), ',') < 10) { - /** - * If there are not very many commas, and the number of - * non-paragraph elements is more than paragraphs or other ominous signs, remove the element. - **/ - $p = $tagsList->item($i)->getElementsByTagName('p')->length; - $img = $tagsList->item($i)->getElementsByTagName('img')->length; - $li = $tagsList->item($i)->getElementsByTagName('li')->length-100; - $input = $tagsList->item($i)->getElementsByTagName('input')->length; - - $embedCount = 0; - $embeds = $tagsList->item($i)->getElementsByTagName('embed'); - for ($ei=0, $il=$embeds->length; $ei < $il; $ei++) { - if (preg_match($this->regexps['video'], $embeds->item($ei)->getAttribute('src'))) { - $embedCount++; - } - } - - $linkDensity = $this->getLinkDensity($tagsList->item($i)); - $contentLength = strlen($this->getInnerText($tagsList->item($i))); - $toRemove = false; - - if ( $img > $p ) { - $toRemove = true; - } else if ($li > $p && $tag != 'ul' && $tag != 'ol') { - $toRemove = true; - } else if ( $input > floor($p/3) ) { - $toRemove = true; - } else if ($contentLength < 25 && ($img === 0 || $img > 2) ) { - $toRemove = true; - } else if($weight < 25 && $linkDensity > 0.2) { - $toRemove = true; - } else if($weight >= 25 && $linkDensity > 0.5) { - $toRemove = true; - } else if(($embedCount == 1 && $contentLength < 75) || $embedCount > 1) { - $toRemove = true; - } - - if ($toRemove) { - $tagsList->item($i)->parentNode->removeChild($tagsList->item($i)); - } - } - } - } - - /** - * Clean out spurious headers from an Element. Checks things like classnames and link density. - * - * @param DOMElement $e - * @return void - */ - public function cleanHeaders($e) { - for ($headerIndex = 1; $headerIndex < 3; $headerIndex++) { - $headers = $e->getElementsByTagName('h' . $headerIndex); - for ($i=$headers->length-1; $i >=0; $i--) { - if ($this->getClassWeight($headers->item($i)) < 0 || $this->getLinkDensity($headers->item($i)) > 0.33) { - $headers->item($i)->parentNode->removeChild($headers->item($i)); - } - } - } - } - - public function flagIsActive($flag) { - return ($this->flags & $flag) > 0; - } - - public function addFlag($flag) { - $this->flags = $this->flags | $flag; - } - - public function removeFlag($flag) { - $this->flags = $this->flags & ~$flag; - } -} -?> \ No newline at end of file diff --git a/inc/3rdparty/libraries/readability/Readability.php b/inc/3rdparty/libraries/readability/Readability.php index 4fa3ba63d..a30012ced 100755 --- a/inc/3rdparty/libraries/readability/Readability.php +++ b/inc/3rdparty/libraries/readability/Readability.php @@ -46,6 +46,7 @@ // This class allows us to do JavaScript like assignements to innerHTML require_once(dirname(__FILE__).'/JSLikeHTMLElement.php'); +libxml_use_internal_errors(true); // Alternative usage (for testing only!) // uncomment the lines below and call Readability.php in your browser @@ -697,7 +698,7 @@ class Readability $articleContent = $this->dom->createElement('div'); $articleContent->setAttribute('id', 'readability-content'); $siblingScoreThreshold = max(10, ((int)$topCandidate->getAttribute('readability')) * 0.2); - $siblingNodes = $topCandidate->parentNode->childNodes; + $siblingNodes = @$topCandidate->parentNode->childNodes; if (!isset($siblingNodes)) { $siblingNodes = new stdClass; $siblingNodes->length = 0; @@ -1148,4 +1149,4 @@ class Readability } } -?> \ No newline at end of file +?> diff --git a/inc/3rdparty/makefulltextfeed.php b/inc/3rdparty/makefulltextfeed.php index a081f88b2..27a62d732 100755 --- a/inc/3rdparty/makefulltextfeed.php +++ b/inc/3rdparty/makefulltextfeed.php @@ -31,6 +31,8 @@ along with this program. If not, see . //error_reporting(E_ALL ^ E_NOTICE); ini_set("display_errors", 1); @set_time_limit(120); +libxml_use_internal_errors(true); + // Deal with magic quotes if (get_magic_quotes_gpc()) { From c86b40f014848b2f9ccf4dfbead71694a41be569 Mon Sep 17 00:00:00 2001 From: Guillaume Virlet Date: Wed, 14 May 2014 15:45:52 +0200 Subject: [PATCH 10/34] add message in web server log in case of authentication failure to enable the usage of fail2ban on failed login attempts --- inc/poche/Poche.class.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/inc/poche/Poche.class.php b/inc/poche/Poche.class.php index a29cb327c..757669194 100755 --- a/inc/poche/Poche.class.php +++ b/inc/poche/Poche.class.php @@ -543,6 +543,8 @@ class Poche Tools::redirect($referer); } $this->messages->add('e', _('login failed: bad login or password')); + // log login failure in web server log to allow fail2ban usage + error_log('user '.$login.' authentication failure'); Tools::logm('login failed'); Tools::redirect(); } From 7f782e44965b005efe01d347dedd1825872b9345 Mon Sep 17 00:00:00 2001 From: moparisthebest Date: Mon, 12 Jan 2015 18:49:05 -0500 Subject: [PATCH 11/34] Add ability to tag an article on creation --- inc/poche/Poche.class.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/inc/poche/Poche.class.php b/inc/poche/Poche.class.php index a29cb327c..c7c598786 100755 --- a/inc/poche/Poche.class.php +++ b/inc/poche/Poche.class.php @@ -180,6 +180,13 @@ class Poche } } + // if there are tags, add them to the new article + if (isset($_GET['tags'])) { + $_POST['value'] = $_GET['tags']; + $_POST['entry_id'] = $last_id; + $this->action('add_tag', $url); + } + $this->messages->add('s', _('the link has been added successfully')); } else { From 512e5e5bd195ea4547dc7fa29f34a9d205bd7a54 Mon Sep 17 00:00:00 2001 From: moparisthebest Date: Mon, 12 Jan 2015 19:11:45 -0500 Subject: [PATCH 12/34] Add ability to delete all articles matching a search --- inc/poche/Poche.class.php | 31 ++++++++++++++++++++++--------- themes/baggy/home.twig | 4 +++- themes/default/home.twig | 4 +++- 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/inc/poche/Poche.class.php b/inc/poche/Poche.class.php index c7c598786..540aa55e5 100755 --- a/inc/poche/Poche.class.php +++ b/inc/poche/Poche.class.php @@ -201,18 +201,31 @@ class Poche } break; case 'delete': - $msg = 'delete link #' . $id; - if ($this->store->deleteById($id, $this->user->getId())) { - if (DOWNLOAD_PICTURES) { - Picture::removeDirectory(ABS_PATH . $id); + if (isset($_GET['search'])) { + //when we want to apply a delete to a search + $tags = array($_GET['search']); + $allentry_ids = $this->store->search($tags[0], $this->user->getId()); + $entry_ids = array(); + foreach ($allentry_ids as $eachentry) { + $entry_ids[] = $eachentry[0]; } - $this->messages->add('s', _('the link has been deleted successfully')); + } else { // delete a single article + $entry_ids = array($id); } - else { - $this->messages->add('e', _('the link wasn\'t deleted')); - $msg = 'error : can\'t delete link #' . $id; + foreach($entry_ids as $id) { + $msg = 'delete link #' . $id; + if ($this->store->deleteById($id, $this->user->getId())) { + if (DOWNLOAD_PICTURES) { + Picture::removeDirectory(ABS_PATH . $id); + } + $this->messages->add('s', _('the link has been deleted successfully')); + } + else { + $this->messages->add('e', _('the link wasn\'t deleted')); + $msg = 'error : can\'t delete link #' . $id; + } + Tools::logm($msg); } - Tools::logm($msg); Tools::redirect('?'); break; case 'toggle_fav' : diff --git a/themes/baggy/home.twig b/themes/baggy/home.twig index abebe455f..9cd663958 100755 --- a/themes/baggy/home.twig +++ b/themes/baggy/home.twig @@ -59,7 +59,9 @@ {{ block('pager') }} {% if view == 'home' %}{% if nb_results > 1 %}

{% trans "Mark all the entries as read" %}

{% endif %}{% endif %} {% if searchterm is defined %}{% trans "Tag these results as" %} {{ searchterm }}{% endif %}
- + + {% if searchterm is defined %}{% trans "Delete results matching" %} {{ searchterm }}{% endif %}
+ {% if tag %} {% if constant('EPUB') == 1 %}{% trans "Download as ePub3" %}{% endif %} {% if constant('MOBI') == 1 %}{% trans "Download as Mobi" %}{% endif %} diff --git a/themes/default/home.twig b/themes/default/home.twig index c5db58024..88e6a6ea6 100755 --- a/themes/default/home.twig +++ b/themes/default/home.twig @@ -59,7 +59,9 @@ {{ block('pager') }} {% if view == 'home' %}{% if nb_results > 1 %}

{% trans "Mark all the entries as read" %}

{% endif %}{% endif %} {% if searchterm is defined %}{% trans "Tag these results as" %} {{ searchterm }}{% endif %}
- + + {% if searchterm is defined %}{% trans "Delete results matching" %} {{ searchterm }}{% endif %}
+ {% if tag %} {% if constant('EPUB') == 1 %}{% trans "Download as ePub3" %}{% endif %} {% if constant('MOBI') == 1 %}{% trans "Download as Mobi" %}{% endif %} From 13c7f9a462b71e89d5e252b693fc7d00aca249ec Mon Sep 17 00:00:00 2001 From: moparisthebest Date: Mon, 12 Jan 2015 19:52:41 -0500 Subject: [PATCH 13/34] Add ability to mark all articles from a tag as read --- inc/poche/Poche.class.php | 17 +++++++++++++++-- themes/baggy/home.twig | 2 ++ themes/default/home.twig | 4 +++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/inc/poche/Poche.class.php b/inc/poche/Poche.class.php index 540aa55e5..20897c61d 100755 --- a/inc/poche/Poche.class.php +++ b/inc/poche/Poche.class.php @@ -240,8 +240,21 @@ class Poche } break; case 'toggle_archive' : - $this->store->archiveById($id, $this->user->getId()); - Tools::logm('archive link #' . $id); + if (isset($_GET['tag_id'])) { + //when we want to archive a whole tag + $tag_id = $_GET['tag_id']; + $allentry_ids = $this->store->retrieveEntriesByTag($tag_id, $this->user->getId()); + $entry_ids = array(); + foreach ($allentry_ids as $eachentry) { + $entry_ids[] = $eachentry[0]; + } + } else { //archive a single article + $entry_ids = array($id); + } + foreach($entry_ids as $id) { + $this->store->archiveById($id, $this->user->getId()); + Tools::logm('archive link #' . $id); + } if ( Tools::isAjaxRequest() ) { echo 1; exit; diff --git a/themes/baggy/home.twig b/themes/baggy/home.twig index 9cd663958..93515080d 100755 --- a/themes/baggy/home.twig +++ b/themes/baggy/home.twig @@ -62,6 +62,8 @@ {% if searchterm is defined %}{% trans "Delete results matching" %} {{ searchterm }}{% endif %}
+ {% if tag %}{% trans "Mark all articles from this tag as read" %}
{% endif %} + {% if tag %} {% if constant('EPUB') == 1 %}{% trans "Download as ePub3" %}{% endif %} {% if constant('MOBI') == 1 %}{% trans "Download as Mobi" %}{% endif %} diff --git a/themes/default/home.twig b/themes/default/home.twig index 88e6a6ea6..b90005598 100755 --- a/themes/default/home.twig +++ b/themes/default/home.twig @@ -62,6 +62,8 @@ {% if searchterm is defined %}{% trans "Delete results matching" %} {{ searchterm }}{% endif %}
+ {% if tag %}{% trans "Mark all articles from this tag as read" %}
{% endif %} + {% if tag %} {% if constant('EPUB') == 1 %}{% trans "Download as ePub3" %}{% endif %} {% if constant('MOBI') == 1 %}{% trans "Download as Mobi" %}{% endif %} @@ -75,6 +77,6 @@ {% if constant('MOBI') == 1 %}{% trans "Download as Mobi" %}{% endif %} {% if constant('PDF') == 1 %}{% trans "Download as PDF" %}{% endif %} {% endif %} - + {% endif %} {% endblock %} From 7fe8a9adc44a73221959263b08b516ec20bf85a0 Mon Sep 17 00:00:00 2001 From: Vincent Malley Date: Fri, 16 Jan 2015 11:42:39 -0500 Subject: [PATCH 14/34] [RSS] introducing query param 'limit' to restrict the number of items to display in RSS feeds. --- inc/poche/Poche.class.php | 14 ++++++++++---- inc/poche/Routing.class.php | 3 ++- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/inc/poche/Poche.class.php b/inc/poche/Poche.class.php index 20897c61d..6a742019f 100755 --- a/inc/poche/Poche.class.php +++ b/inc/poche/Poche.class.php @@ -784,10 +784,11 @@ class Poche * * @param $token * @param $user_id - * @param $tag_id - * @param string $type + * @param $tag_id if $type is 'tag', the id of the tag to generate feed for + * @param string $type the type of feed to generate + * @param int $limit the maximum number of items (0 means all) */ - public function generateFeeds($token, $user_id, $tag_id, $type = 'home') + public function generateFeeds($token, $user_id, $tag_id, $type = 'home', $limit = 0) { $allowed_types = array('home', 'fav', 'archive', 'tag'); $config = $this->store->getConfigUser($user_id); @@ -814,8 +815,13 @@ class Poche $entries = $this->store->getEntriesByView($type, $user_id); } + // if $limit is set to zero, use all entries + if (0 == $limit) { + $limit = count($entries); + } if (count($entries) > 0) { - foreach ($entries as $entry) { + for ($i = 0; $i < min(count($entries), $limit); $i++) { + $entry = $entries[$i]; $newItem = $feed->createNewItem(); $newItem->setTitle($entry['title']); $newItem->setSource(Tools::getPocheUrl() . '?view=view&id=' . $entry['id']); diff --git a/inc/poche/Routing.class.php b/inc/poche/Routing.class.php index 5acd08ba6..be06a433d 100755 --- a/inc/poche/Routing.class.php +++ b/inc/poche/Routing.class.php @@ -102,7 +102,8 @@ class Routing $this->wallabag->login($this->referer); } elseif (isset($_GET['feed']) && isset($_GET['user_id'])) { $tag_id = (isset($_GET['tag_id']) ? intval($_GET['tag_id']) : 0); - $this->wallabag->generateFeeds($_GET['token'], filter_var($_GET['user_id'],FILTER_SANITIZE_NUMBER_INT), $tag_id, $_GET['type']); + $limit = (isset($_GET['limit']) ? intval($_GET['limit']) : 0); + $this->wallabag->generateFeeds($_GET['token'], filter_var($_GET['user_id'],FILTER_SANITIZE_NUMBER_INT), $tag_id, $_GET['type'], $limit); } //allowed ONLY to logged in user From 4cc328edf08f515de2833f4960b252539ece428f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20L=C5=93uillet?= Date: Fri, 16 Jan 2015 20:35:25 +0100 Subject: [PATCH 15/34] Fixed #993: add wallabag to packagist --- composer.json | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/composer.json b/composer.json index 6c69e48de..0f3750670 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,35 @@ { + "name": "wallabag/wallabag", + "type": "project", + "description": "open source self hostable read-it-later web application", + "keywords": ["read-it-later","read it later"], + "homepage": "https://github.com/wallabag/wallabag", + "license": "MIT", + "authors": [ + { + "name": "Nicolas Lœuillet", + "email": "nicolas@loeuillet.org", + "homepage": "http://www.cdetc.fr", + "role": "Developer" + }, + { + "name": "Thomas Citharel", + "homepage": "http://tcit.fr", + "role": "Developer" + } + ], + "support": { + "email": "hello@wallabag.org", + "issues": "https://github.com/wallabag/wallabag/issues" + }, "require": { "twig/twig": "1.*", "twig/extensions": "1.0.*", "umpirsky/twig-gettext-extractor": "1.1.*" + }, + "autoload": { + "psr-0": { + "Wallabag\\": "src" + } } } \ No newline at end of file From 44f1fef0180eb636648bddf66ec33e81b5b77b71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20L=C5=93uillet?= Date: Fri, 16 Jan 2015 20:45:23 +0100 Subject: [PATCH 16/34] packagist --- composer.json | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/composer.json b/composer.json index 6c69e48de..0f3750670 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,35 @@ { + "name": "wallabag/wallabag", + "type": "project", + "description": "open source self hostable read-it-later web application", + "keywords": ["read-it-later","read it later"], + "homepage": "https://github.com/wallabag/wallabag", + "license": "MIT", + "authors": [ + { + "name": "Nicolas Lœuillet", + "email": "nicolas@loeuillet.org", + "homepage": "http://www.cdetc.fr", + "role": "Developer" + }, + { + "name": "Thomas Citharel", + "homepage": "http://tcit.fr", + "role": "Developer" + } + ], + "support": { + "email": "hello@wallabag.org", + "issues": "https://github.com/wallabag/wallabag/issues" + }, "require": { "twig/twig": "1.*", "twig/extensions": "1.0.*", "umpirsky/twig-gettext-extractor": "1.1.*" + }, + "autoload": { + "psr-0": { + "Wallabag\\": "src" + } } } \ No newline at end of file From 894cd087f41d605f2f093aaad1300825f705e009 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20L=C5=93uillet?= Date: Fri, 16 Jan 2015 20:56:46 +0100 Subject: [PATCH 17/34] remove autoload section in composer.json --- composer.json | 5 ----- 1 file changed, 5 deletions(-) diff --git a/composer.json b/composer.json index 0f3750670..a63f2893f 100644 --- a/composer.json +++ b/composer.json @@ -26,10 +26,5 @@ "twig/twig": "1.*", "twig/extensions": "1.0.*", "umpirsky/twig-gettext-extractor": "1.1.*" - }, - "autoload": { - "psr-0": { - "Wallabag\\": "src" - } } } \ No newline at end of file From 5537bb321626d0c28b48aa8fed050c21d7d00f1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20L=C5=93uillet?= Date: Fri, 16 Jan 2015 21:09:22 +0100 Subject: [PATCH 18/34] remove autoload section in composer.json --- composer.json | 5 ----- 1 file changed, 5 deletions(-) diff --git a/composer.json b/composer.json index 0f3750670..a63f2893f 100644 --- a/composer.json +++ b/composer.json @@ -26,10 +26,5 @@ "twig/twig": "1.*", "twig/extensions": "1.0.*", "umpirsky/twig-gettext-extractor": "1.1.*" - }, - "autoload": { - "psr-0": { - "Wallabag\\": "src" - } } } \ No newline at end of file From 3052cfb7cab3b37e7258f31d18624a9335c0680f Mon Sep 17 00:00:00 2001 From: kaffeeringe Date: Sun, 18 Jan 2015 21:49:05 +0100 Subject: [PATCH 19/34] Add Tags on Import I fixed it! And it works for me. But: I am not too good with programming. So better check the code ;-) --- inc/poche/Poche.class.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/inc/poche/Poche.class.php b/inc/poche/Poche.class.php index 16235474b..01f919d9e 100755 --- a/inc/poche/Poche.class.php +++ b/inc/poche/Poche.class.php @@ -192,6 +192,7 @@ class Poche } else { Tools::redirect('?view=home&closewin=true'); } + return $last_id; break; case 'delete': $msg = 'delete link #' . $id; @@ -625,7 +626,18 @@ class Poche $urlsInserted[] = $url; //add if (isset($record['tags']) && trim($record['tags'])) { - // @TODO: set tags + $tags = explode(' ', $record['tags']); + foreach($tags as $tag) { + $entry_id = $id; + $tag_id = $this->store->retrieveTagByValue($tag); + if ($tag_id) { + $this->store->setTagToEntry($tag_id['id'], $entry_id); + } else { + $this->store->createTag($tag); + $tag_id = $this->store->retrieveTagByValue($tag); + $this->store->setTagToEntry($tag_id['id'], $entry_id); + } + } } } From 1cedeb681f84b2c9b17f4f8b88d4fffabb15d6c8 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Mon, 19 Jan 2015 23:19:09 +0100 Subject: [PATCH 20/34] (kind of) fix for #1011 and little corrections for PDF export --- inc/3rdparty/libraries/tcpdf/tcpdf.php | 10 +++++-- inc/poche/WallabagEBooks.class.php | 38 ++++++++++++++++++++------ 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/inc/3rdparty/libraries/tcpdf/tcpdf.php b/inc/3rdparty/libraries/tcpdf/tcpdf.php index 78694a0e4..70c1747ac 100644 --- a/inc/3rdparty/libraries/tcpdf/tcpdf.php +++ b/inc/3rdparty/libraries/tcpdf/tcpdf.php @@ -2926,12 +2926,18 @@ class TCPDF { */ public function Error($msg) { // unset all class variables + $this->_destroy(true); + throw new Exception('TCPDF ERROR: '.$msg); + /* + + I had problems with the constants for some reason, so here we force + $this->_destroy(true); if (defined('K_TCPDF_THROW_EXCEPTION_ERROR') AND !K_TCPDF_THROW_EXCEPTION_ERROR) { die('TCPDF ERROR: '.$msg); } else { throw new Exception('TCPDF ERROR: '.$msg); - } + }*/ } /** @@ -6915,7 +6921,7 @@ class TCPDF { $ph = $this->getHTMLUnitToUnits($h, 0, $this->pdfunit, true) * $this->imgscale * $this->k; $imsize = array($pw, $ph); } else { - $this->Error('[Image] Unable to get the size of the image: '.$file); + $this->Error('[Image] Unable to fetch image: '.$file); } } // file hash diff --git a/inc/poche/WallabagEBooks.class.php b/inc/poche/WallabagEBooks.class.php index bc40990b1..d31939a1b 100644 --- a/inc/poche/WallabagEBooks.class.php +++ b/inc/poche/WallabagEBooks.class.php @@ -33,7 +33,7 @@ class WallabagEBooks $entry = $this->wallabag->store->retrieveOneById($entryID, $this->wallabag->user->getId()); $this->entries = array($entry); $this->bookTitle = $entry['title']; - $this->bookFileName = substr($this->bookTitle, 0, 200); + $this->bookFileName = str_replace('/', '_', substr($this->bookTitle, 0, 200)); $this->author = preg_replace('#^w{3}.#', '', Tools::getdomain($entry["url"])); # if only one article, set author to domain name (we strip the eventual www part) Tools::logm('Producing ebook from article ' . $this->bookTitle); break; @@ -81,6 +81,9 @@ class WallabagEpub extends WallabagEBooks public function produceEpub() { Tools::logm('Starting to produce ePub 3 file'); + + try { + $content_start = "\n" . "\n" @@ -155,6 +158,11 @@ class WallabagEpub extends WallabagEBooks $book->finalize(); $zipData = $book->sendBook($this->bookFileName); Tools::logm('Ebook produced'); + } + catch (Exception $e) { + Tools::logm('PHPePub has encountered an error : '.$e->getMessage()); + $this->wallabag->messages->add('e', $e->getMessage()); + } } } @@ -167,7 +175,7 @@ class WallabagMobi extends WallabagEBooks public function produceMobi() { - + try { Tools::logm('Starting to produce Mobi file'); $mobi = new MOBI(); $content = new MOBIFile(); @@ -197,6 +205,11 @@ class WallabagMobi extends WallabagEBooks // we offer file to download $mobi->download($this->bookFileName.'.mobi'); Tools::logm('Mobi file produced'); + } + catch (Exception $e) { + Tools::logm('PHPMobi has encountered an error : '.$e->getMessage()); + $this->wallabag->messages->add('e', $e->getMessage()); + } } } @@ -206,15 +219,16 @@ class WallabagPDF extends WallabagEbooks { Tools::logm('Starting to produce PDF file'); - + @define ('K_TCPDF_THROW_EXCEPTION_ERROR', TRUE); + try { $pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false); Tools::logm('Filling metadata for PDF...'); $pdf->SetCreator(PDF_CREATOR); - $pdf->SetAuthor(''); + $pdf->SetAuthor('wallabag'); $pdf->SetTitle($this->bookTitle); - $pdf->SetSubject('TCPDF Tutorial'); - $pdf->SetKeywords('TCPDF, PDF, example, test, guide'); + $pdf->SetSubject('Articles via wallabag'); + $pdf->SetKeywords('wallabag'); Tools::logm('Adding introduction...'); $pdf->AddPage(); @@ -229,18 +243,26 @@ class WallabagPDF extends WallabagEbooks $i = 1; Tools::logm('Adding actual content...'); foreach ($this->entries as $item) { + $tags = $this->wallabag->store->retrieveTagsByEntry($entry['id']); + foreach ($tags as $tag) { + $pdf->SetKeywords($tag['value']); + } $pdf->AddPage(); $html = '

' . $item['title'] . '

'; $html .= $item['content']; $pdf->writeHTMLCell(0, 0, '', '', $html, 0, 1, 0, true, '', true); - $i = $i+1; } // set image scale factor $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO); - + $pdf->Output($this->bookFileName . '.pdf', 'FD'); + } + catch (Exception $e) { + Tools::logm('TCPDF has encountered an error : '.$e->getMessage()); + $this->wallabag->messages->add('e', $e->getMessage()); + } } } From 9a490ad63a08c619bb45ad9bf090790c31ebe92e Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Tue, 20 Jan 2015 00:02:21 +0100 Subject: [PATCH 21/34] from spaces to commas --- inc/poche/Poche.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/poche/Poche.class.php b/inc/poche/Poche.class.php index 5a0edbe41..81a18c860 100755 --- a/inc/poche/Poche.class.php +++ b/inc/poche/Poche.class.php @@ -664,7 +664,7 @@ class Poche $urlsInserted[] = $url; //add if (isset($record['tags']) && trim($record['tags'])) { - $tags = explode(' ', $record['tags']); + $tags = explode(',', $record['tags']); foreach($tags as $tag) { $entry_id = $id; $tag_id = $this->store->retrieveTagByValue($tag); From 64364606dd217017d909c71166c303dd53ff55a9 Mon Sep 17 00:00:00 2001 From: Olivier Mehani Date: Thu, 22 Jan 2015 10:07:46 +1100 Subject: [PATCH 22/34] URL encode 'via @wallabagapp' email body Signed-off-by: Olivier Mehani --- themes/baggy/view.twig | 4 ++-- themes/default/view.twig | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/themes/baggy/view.twig b/themes/baggy/view.twig index 1afd9df6a..5728918f9 100755 --- a/themes/baggy/view.twig +++ b/themes/baggy/view.twig @@ -12,8 +12,8 @@
  • {% trans "Toggle mark as read" %}
  • {% trans "Toggle favorite" %}
  • {% trans "Delete" %}
  • - {% if constant('SHARE_TWITTER') == 1 %}
  • {% endif %} - {% if constant('SHARE_MAIL') == 1 %}
  • {% endif %} + {% if constant('SHARE_TWITTER') == 1 %}
  • {% endif %} + {% if constant('SHARE_MAIL') == 1 %}
  • {% endif %} {% if constant('SHARE_SHAARLI') == 1 %}
  • {% trans "shaarli" %}
  • {% endif %} {% if constant('SHARE_DIASPORA') == 1 %}
  • {% trans "diaspora" %}
  • {% endif %} {% if constant('FLATTR') == 1 %}{% if flattr.status == constant('FLATTRABLE') %}
  • {% trans "flattr" %}
  • {% elseif flattr.status == constant('FLATTRED') %}
  • {% trans "flattr" %} ({{ flattr.numFlattrs }})
  • {% endif %}{% endif %} diff --git a/themes/default/view.twig b/themes/default/view.twig index 8f3a26c3d..9091f98f2 100755 --- a/themes/default/view.twig +++ b/themes/default/view.twig @@ -11,8 +11,8 @@
  • {% trans "Toggle mark as read" %}
  • {% trans "Toggle favorite" %}
  • {% trans "Delete" %}
  • - {% if constant('SHARE_TWITTER') == 1 %}
  • {% endif %} - {% if constant('SHARE_MAIL') == 1 %}
  • {% endif %} + {% if constant('SHARE_TWITTER') == 1 %}
  • {% endif %} + {% if constant('SHARE_MAIL') == 1 %}
  • {% endif %} {% if constant('SHARE_SHAARLI') == 1 %}
  • {% trans "shaarli" %}
  • {% endif %} {% if constant('SHARE_DIASPORA') == 1 %}
  • {% trans "diaspora" %}
  • {% endif %} {% if constant('FLATTR') == 1 %}{% if flattr.status == constant('FLATTRABLE') %}
  • {% trans "flattr" %}
  • {% elseif flattr.status == constant('FLATTRED') %}
  • {% trans "flattr" %}{{ flattr.numFlattrs }}
  • {% endif %}{% endif %} From e56ef774640930a97acebb80bb781307034f1e2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20L=C5=93uillet?= Date: Thu, 22 Jan 2015 06:17:33 +0100 Subject: [PATCH 23/34] Revert "URL encode 'via @wallabagapp' email body" --- themes/baggy/view.twig | 4 ++-- themes/default/view.twig | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/themes/baggy/view.twig b/themes/baggy/view.twig index 5728918f9..1afd9df6a 100755 --- a/themes/baggy/view.twig +++ b/themes/baggy/view.twig @@ -12,8 +12,8 @@
  • {% trans "Toggle mark as read" %}
  • {% trans "Toggle favorite" %}
  • {% trans "Delete" %}
  • - {% if constant('SHARE_TWITTER') == 1 %}
  • {% endif %} - {% if constant('SHARE_MAIL') == 1 %}
  • {% endif %} + {% if constant('SHARE_TWITTER') == 1 %}
  • {% endif %} + {% if constant('SHARE_MAIL') == 1 %}
  • {% endif %} {% if constant('SHARE_SHAARLI') == 1 %}
  • {% trans "shaarli" %}
  • {% endif %} {% if constant('SHARE_DIASPORA') == 1 %}
  • {% trans "diaspora" %}
  • {% endif %} {% if constant('FLATTR') == 1 %}{% if flattr.status == constant('FLATTRABLE') %}
  • {% trans "flattr" %}
  • {% elseif flattr.status == constant('FLATTRED') %}
  • {% trans "flattr" %} ({{ flattr.numFlattrs }})
  • {% endif %}{% endif %} diff --git a/themes/default/view.twig b/themes/default/view.twig index 9091f98f2..8f3a26c3d 100755 --- a/themes/default/view.twig +++ b/themes/default/view.twig @@ -11,8 +11,8 @@
  • {% trans "Toggle mark as read" %}
  • {% trans "Toggle favorite" %}
  • {% trans "Delete" %}
  • - {% if constant('SHARE_TWITTER') == 1 %}
  • {% endif %} - {% if constant('SHARE_MAIL') == 1 %}
  • {% endif %} + {% if constant('SHARE_TWITTER') == 1 %}
  • {% endif %} + {% if constant('SHARE_MAIL') == 1 %}
  • {% endif %} {% if constant('SHARE_SHAARLI') == 1 %}
  • {% trans "shaarli" %}
  • {% endif %} {% if constant('SHARE_DIASPORA') == 1 %}
  • {% trans "diaspora" %}
  • {% endif %} {% if constant('FLATTR') == 1 %}{% if flattr.status == constant('FLATTRABLE') %}
  • {% trans "flattr" %}
  • {% elseif flattr.status == constant('FLATTRED') %}
  • {% trans "flattr" %}{{ flattr.numFlattrs }}
  • {% endif %}{% endif %} From a3a9e75e625b78de371dad2d319ee3a84b7a75c2 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Sat, 24 Jan 2015 14:35:03 +0100 Subject: [PATCH 24/34] correct a bug when email was not sended when creating a new user --- inc/poche/Routing.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/poche/Routing.class.php b/inc/poche/Routing.class.php index be06a433d..a8d00b898 100755 --- a/inc/poche/Routing.class.php +++ b/inc/poche/Routing.class.php @@ -116,7 +116,7 @@ class Routing // update password $this->wallabag->updatePassword($_POST['password'], $_POST['password_repeat']); } elseif (isset($_GET['newuser'])) { - $this->wallabag->createNewUser($_POST['newusername'], $_POST['password4newuser']); + $this->wallabag->createNewUser($_POST['newusername'], $_POST['password4newuser'], $_POST['newuseremail']); } elseif (isset($_GET['deluser'])) { $this->wallabag->deleteUser($_POST['password4deletinguser']); } elseif (isset($_GET['epub'])) { From 444f14063920692163ee321a872debfc48feaada Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Sun, 25 Jan 2015 17:43:58 +0100 Subject: [PATCH 25/34] wow. Many changes to installation script. Much easier. --- install/index.php | 291 ++++++++++++++++- install/wallabag_compatibility_test.php | 396 +----------------------- 2 files changed, 298 insertions(+), 389 deletions(-) diff --git a/install/index.php b/install/index.php index ec5041608..dbfe95391 100755 --- a/install/index.php +++ b/install/index.php @@ -11,6 +11,8 @@ $errors = array(); $successes = array(); +require_once('wallabag_compatibility_test.php'); + /* Function taken from at http://php.net/manual/en/function.rmdir.php#110489 * Idea : nbari at dalmp dot com * Rights unknown @@ -210,6 +212,117 @@ else if (isset($_POST['install'])) { + + + +
    @@ -259,11 +372,8 @@ else if (isset($_POST['install'])) {

    To install wallabag, you just have to fill the following fields. That's all.

    If you need help, you can read the doc: offline documentation and online one (already up-to-date).

    -

    Don't forget to check your server compatibility here.

    -
    -
    - Technical settings - + +
    wallabag needs twig, a template engine (?). Two ways to install it:
    • automatically download and extract vendor.zip into your wallabag folder. @@ -277,6 +387,159 @@ php composer.phar install
    + +

    Server compatibility test (click to view details) : + All good + + Some problems, but it's OK ! + + Bad news : you can't run wallabag +

    + + +
    +
    +

    : Compatibility Test

    + + + + + + + + + + + + + + + + + + + + Enabled' : ' + + + + + + Enabled, and sane' : ' + + + + + + Enabled' : ' + + + + + + Enabled' : ' + + + + + + Enabled' : ' + + + + + + Enabled' : ' + + + + + Enabled' : ' + + + + + + Enabled' : ' + + + + + + Enabled' : ' + + + + + + Enabled' : ' + + + + + + Enabled' : ' + + + + + + Enabled' : ' + + + + + + Enabled' : ' + + + + + + Enabled' : ' + + + + + + Enabled' : ' + + + +
    TestShould BeWhat You HaveWhat it means
    PHP5.3.3 or higherPHP: You are running a supported version of PHP.' : 'PHP: You are running an unsupported version of PHP. ' . $status['app_name'] . ' will not work here.' ;?>
    PDOEnabledDisabled'; ?>PDO: You have PDO support enabled.' : 'PDO: Your PHP installation doesn\'t support PHP PDO. ' . $status['app_name'] . ' will not work here.' ?>
    XMLEnabledDisabled, or broken'; ?>XML: You have XMLReader support or a version of XML support that isn\'t broken installed.' : 'XML: Your PHP installation doesn\'t support XML parsing. ' . $status['app_name'] . ' will not work here.' ?>
    PCREEnabledDisabled'; ?>PCRE: You have PCRE support installed.' : 'PCRE: Your PHP installation doesn\'t support Perl-Compatible Regular Expressions. ' . $status['app_name'] .' will not work here.' ?>
    ZlibEnabledDisabled'; ?>Zlib: You have Zlib enabled. This allows SimplePie to support GZIP-encoded pages.' : 'Zlib: The Zlib extension is not available. SimplePie will ignore any GZIP-encoding, and instead handle pages as uncompressed text.' ?>
    mbstringEnabledDisabled'; ?>mbstring and iconv: You have both mbstring and iconv installed! This will allow to handle the greatest number of languages. + mbstring: mbstring is installed, but iconv is not. + iconv: iconv is installed, but mbstring is not. + mbstring and iconv: You do not have either of the extensions installed. This will significantly impair your ability to read non-English pages, as well as even some English ones. + +
    iconvEnabledDisabled'; ?>
    DOM / XML extensionEnabledDisabled'; ?>DOM/XML: You can parse ini files.' : 'DOM/XML: Your PHP configuration isn\'t standard, you\'re missing PHP-DOM. You may try to install a package or recompile PHP. ' . $status['app_name'] . ' will not work here.'; ?>
    Data filteringEnabledDisabled'; ?>Data filtering: You can use the PHP build-in DOM to operate on XML documents.' : 'Data filtering: Your PHP configuration has the filter extension disabled. ' . $status['app_name'] . ' will not work here.' ?>
    GDEnabledDisabled'; ?>GD: You have GD support installed.' : 'GD: The GD extension is not available. ' . $status['app_name'] . ' will not be able to download pictures locally on your server.' ?>
    TidyEnabledDisabled'; ?>Tidy: You have Tidy support installed.' : 'Tidy: The Tidy extension is not available.' . $status['app_name'] . ' should still work with most pages, but you may experience problems with some. You can install it with sudo apt-get install php5-tidy and then reload Apache sudo service apache2 reload.' ; ?>
    cURLEnabledDisabled'; ?>cURL: You have cURL support installed.' : 'cURL: The cURL extension is not available. SimplePie will use fsockopen() instead.' ?>
    Parse ini fileEnabledDisabled'; ?>Parse ini: You can parse ini files.' : 'Parse ini files function : Bad luck : your webhost has decided to block the use of the parse_ini_file function. ' . $status['app_name'] . ' will not work here.' ?>
    Parallel URL fetchingEnabledDisabled'; ?>Parallel URL fetching: You have HttpRequestPool or curl_multi support installed.' : 'Parallel URL fetching: HttpRequestPool or curl_multi support is not available. ' . $status['app_name'] . ' will use file_get_contents() instead to fetch URLs sequentially rather than in parallel.' ?>
    allow_url_fopenEnabledDisabled'; ?>allow_url_fopen: You have allow_url_fopen enabled.' : 'allow_url_fopen: Your PHP configuration has allow_url_fopen disabled. ' . $status['app_name'] . ' will not work here.' ?>
    gettextEnabledDisabled'; ?>Gettext: You have gettext enabled.' : 'GetText: The gettext extension is not available. The system we use to display wallabag in various languages is not available. ' . $status['app_name'] .' will not work here.' ?>
    +
    + +
    + + +

    Bottom Line: Yes, you can run !

    +

    Your webhost has its act together!

    +

    Note: Passing this test does not guarantee that will run on your webhost — it only ensures that the basic requirements have been addressed. If you experience any problems, please let us know.

    + + +

    Bottom Line: Yes, you can run !

    +

    For most pages, it'll run with no problems. There are certain languages that you might have a hard time with though.

    +

    Note: Passing this test does not guarantee that will run on your webhost — it only ensures that the basic requirements have been addressed. If you experience any problems, please let us know.

    + +

    Bottom Line: We're sorry…

    +

    Your webhost does not support the minimum requirements for . It may be a good idea to contact your webhost and point them to the results of this test. They may be able to enable/install the required components.

    + +
    + +
    +

    This compatibility test has been borrowed (and slightly adapted by fivefilters.org) from the one supplied by SimplePie.org.

    +
    + +
    + + +
    + Technical settings

    Database engine:

      @@ -331,6 +594,19 @@ php composer.phar install $("#mysql_infos").hide(); $("#pg_infos").hide(); + $(".details").hide(); + + + $('.technical').hide(); + + $('.technical').show(); + + $("#install_button").hide(); @@ -370,6 +646,11 @@ php composer.phar install } } }); + + $(".detail").click(function() + { + $('.details').toggle(); + }); diff --git a/install/wallabag_compatibility_test.php b/install/wallabag_compatibility_test.php index 61a8e99f0..8a0656cf8 100644 --- a/install/wallabag_compatibility_test.php +++ b/install/wallabag_compatibility_test.php @@ -8,9 +8,11 @@ * @license http://opensource.org/licenses/MIT see COPYING file */ +function status() { $app_name = 'wallabag'; $php_ok = (function_exists('version_compare') && version_compare(phpversion(), '5.3.3', '>=')); +$pdo_ok = class_exists('PDO'); $pcre_ok = extension_loaded('pcre'); $zlib_ok = extension_loaded('zlib'); $mbstring_ok = extension_loaded('mbstring'); @@ -25,7 +27,6 @@ $filter_ok = extension_loaded('filter'); $gettext_ok = function_exists("gettext"); $gd_ok = extension_loaded('gd'); - if (extension_loaded('xmlreader')) { $xml_ok = true; } elseif (extension_loaded('xml')) { @@ -37,391 +38,18 @@ if (extension_loaded('xmlreader')) { $xml_ok = false; } -header('Content-type: text/html; charset=UTF-8'); +$status = array('app_name' => $app_name, 'php' => $php_ok, 'pdo' => $pdo_ok, 'xml' => $xml_ok, 'pcre' => $pcre_ok, 'zlib' => $zlib_ok, 'mbstring' => $mbstring_ok, 'dom' => $dom_ok, 'iconv' => $iconv_ok, 'tidy' => $tidy_ok, 'curl' => $curl_ok, 'parse_ini' => $parse_ini_ok, 'parallel' => $parallel_ok, 'allow_url_fopen' => $allow_url_fopen_ok, 'filter' => $filter_ok, 'gettext' => $gettext_ok, 'gd' => $gd_ok); -?> - - - -<?php echo $app_name; ?>: Server Compatibility Test - - - - - - - -
      -
      - -
      -

      : Compatibility Test

      - - - - - - - - - - - - - - - - - - Enabled, and sane' : ' - - - - - Enabled' : ' - - - - - - - - Enabled' : ' - - - - - Enabled' : ' - - - - - Enabled' : ' - - - - - Enabled' : ' - - - - - Enabled' : ' - - - - - Enabled' : ' - - - - - Enabled' : ' - - - - - Enabled' : ' - - - - - Enabled' : ' - - -
      TestShould BeWhat You Have
      PHP5.3.3 or higher
      XMLEnabledDisabled, or broken'; ?>
      PCREEnabledDisabled'; ?>
      DOM / XML extensionEnabledDisabled'; ?>
      Data filteringEnabledDisabled'; ?>
      GDEnabledDisabled'; ?>
      TidyEnabledDisabled'; ?>
      cURLEnabledDisabled'; ?>
      Parse ini fileEnabledDisabled'; ?>
      Parallel URL fetchingEnabledDisabled'; ?>
      allow_url_fopenEnabledDisabled'; ?>
      gettextEnabledDisabled'; ?>
      -
      - -
      -

      What does this mean?

      -
        - - -
      1. You have everything you need to run properly! Congratulations!
      2. - - -
      3. PHP: You are running a supported version of PHP. No problems here.
      4. - -
      5. XML: You have XMLReader support or a version of XML support that isn't broken installed. No problems here.
      6. - -
      7. PCRE: You have PCRE support installed. No problems here.
      8. - - -
      9. allow_url_fopen: You have allow_url_fopen enabled. No problems here.
      10. - - -
      11. Gettext: You have gettext enabled. No problems here.
      12. - - -
      13. Parse ini: You can parse ini files. No problems here.
      14. - - -
      15. DOM/XML: You can parse ini files. No problems here.
      16. - - -
      17. Data filtering: You can use the PHP build-in DOM to operate on XML documents. No problems here.
      18. - - -
      19. Zlib: You have Zlib enabled. This allows SimplePie to support GZIP-encoded feeds. No problems here.
      20. - -
      21. Zlib: The Zlib extension is not available. SimplePie will ignore any GZIP-encoding, and instead handle feeds as uncompressed text.
      22. - - - -
      23. mbstring and iconv: You have both mbstring and iconv installed! This will allow to handle the greatest number of languages. No problems here.
      24. - -
      25. mbstring: mbstring is installed, but iconv is not.
      26. - -
      27. iconv: iconv is installed, but mbstring is not.
      28. - -
      29. mbstring and iconv: You do not have either of the extensions installed. This will significantly impair your ability to read non-English feeds, as well as even some English ones.
      30. - - - -
      31. GD: You have GD support installed. No problems here.
      32. - -
      33. GD: The GD extension is not available. will not be able to download pictures locally on your server.
      34. - - - -
      35. Tidy: You have Tidy support installed. No problems here.
      36. - -
      37. Tidy: The Tidy extension is not available. should still work with most feeds, but you may experience problems with some. You can install it with sudo apt-get install php5-tidy and then reload Apache sudo service apache2 reload.
      38. - - - -
      39. cURL: You have cURL support installed. No problems here.
      40. - -
      41. cURL: The cURL extension is not available. SimplePie will use fsockopen() instead.
      42. - - - -
      43. Parallel URL fetching: You have HttpRequestPool or curl_multi support installed. No problems here.
      44. - -
      45. Parallel URL fetching: HttpRequestPool or curl_multi support is not available. will use file_get_contents() instead to fetch URLs sequentially rather than in parallel.
      46. - - - -
      47. Data filtering: Your PHP configuration has the filter extension disabled. will not work here.
      48. - - - -
      49. DOM/XML: Your PHP configuration isn't standard, you're missing PHP-DOM. You may try to install a package or recompile PHP. will not work here.
      50. - - - -
      51. Parse ini files function : Bad luck : your webhost has decided to block the use of the parse_ini_file function. will not work here. - - - -
      52. GetText: The gettext extension is not available. The system we use to display wallabag in various languages is not available. will not work here.
      53. - - - -
      54. allow_url_fopen: Your PHP configuration has allow_url_fopen disabled. will not work here.
      55. - - - -
      56. PCRE: Your PHP installation doesn't support Perl-Compatible Regular Expressions. will not work here.
      57. - - -
      58. XML: Your PHP installation doesn't support XML parsing. will not work here.
      59. - - -
      60. PHP: You are running an unsupported version of PHP. will not work here.
      61. - - -
      -
      - -
      - - -

      Bottom Line: Yes, you can!

      -

      Your webhost has its act together!

      - -

      You can download the latest version of from wallabag.org.

      -

      If you already have done that, you should access the index.php file of your installation to configure and/or start using wallabag

      - -

      You can now return to the installation section.

      - -

      Note: Passing this test does not guarantee that will run on your webhost — it only ensures that the basic requirements have been addressed. If you experience any problems, please let us know.

      - - -

      Bottom Line: Yes, you can!

      -

      For most feeds, it'll run with no problems. There are certain languages that you might have a hard time with though.

      - -

      You can download the latest version of from wallabag.org.

      -

      If you already have done that, you should access the index.php file of your installation to configure and/or start using wallabag

      - -

      You can now return to the installation section.

      - -

      Note: Passing this test does not guarantee that will run on your webhost — it only ensures that the basic requirements have been addressed. If you experience any problems, please let us know.

      - -

      Bottom Line: We're sorry…

      -

      Your webhost does not support the minimum requirements for . It may be a good idea to contact your webhost and point them to the results of this test. They may be able to enable/install the required components.

      - -
      - -
      -

      This compatibility test has been borrowed (and slightly adapted by fivefilters.org) from the one supplied by SimplePie.org.

      -
      - -
      - -
      - - - +?> \ No newline at end of file From c1e90b9e8f2fad19a2dc3b8631cf684fda14eab5 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Sun, 25 Jan 2015 22:42:31 +0100 Subject: [PATCH 26/34] some improvements --- install/index.php | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/install/index.php b/install/index.php index dbfe95391..3231a9449 100755 --- a/install/index.php +++ b/install/index.php @@ -312,13 +312,8 @@ font-weight: bold; .pass{ background-color:#FF9500; } -#detail { -background-color: #000; -font-size:1.2em; -line-height: 1.6; -width: 1.6em; -height: 1.6em; -color:white; +.detail { +cursor: pointer; } @@ -399,6 +394,7 @@ php composer.phar install
      +

      : Compatibility Test

      @@ -513,7 +509,7 @@ php composer.phar install
      - +
      @@ -538,6 +534,7 @@ php composer.phar install
      +
      Technical settings

      @@ -569,7 +566,7 @@ php composer.phar install

    - +
    User settings

    @@ -624,7 +621,7 @@ php composer.phar install $("#mysql_infos").show(); $("#pg_infos").hide(); $("#pdo_sqlite").hide(); - $("#install_button").show(); + $("#install_button").show(); } else { if ( $("#postgres").prop('checked')) { @@ -651,6 +648,7 @@ php composer.phar install { $('.details').toggle(); }); + From 369e00e60baf47170e7438d4518b4b17f82968ab Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Sun, 25 Jan 2015 22:56:11 +0100 Subject: [PATCH 27/34] add a information message to fill all the fields --- install/index.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/install/index.php b/install/index.php index 3231a9449..ec050b4b7 100755 --- a/install/index.php +++ b/install/index.php @@ -547,6 +547,9 @@ php composer.phar install

  • +
    +

    All fields have to be filled.

    +
    • @@ -556,6 +559,9 @@ php composer.phar install
    • +
      +

      All fields have to be filled.

      +
      • @@ -593,6 +599,9 @@ php composer.phar install $(".details").hide(); + $("#pdo_postgres").hide(); + $("#pdo_mysql").hide(); + $('.technical').hide(); @@ -619,20 +628,26 @@ php composer.phar install { if ( $("#mysql").prop('checked')) { $("#mysql_infos").show(); + $("#pdo_mysql").show(); $("#pg_infos").hide(); + $("#pdo_postgres").hide(); $("#pdo_sqlite").hide(); $("#install_button").show(); } else { if ( $("#postgres").prop('checked')) { $("#mysql_infos").hide(); + $("#pdo_mysql").hide(); $("#pg_infos").show(); + $("#pdo_postgres").show(); $("#pdo_sqlite").hide(); $("#install_button").show(); } else { $("#mysql_infos").hide(); $("#pg_infos").hide(); + $("#pdo_postgres").hide(); + $("#pdo_mysql").hide(); $("#pdo_sqlite").show(); From 42ac69337f6538593e4375a38fb410b13c6cb660 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Mon, 26 Jan 2015 00:16:14 +0100 Subject: [PATCH 28/34] fix for spaces in .mobi filenames --- inc/poche/WallabagEBooks.class.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/inc/poche/WallabagEBooks.class.php b/inc/poche/WallabagEBooks.class.php index d31939a1b..afcf4dbf5 100644 --- a/inc/poche/WallabagEBooks.class.php +++ b/inc/poche/WallabagEBooks.class.php @@ -202,6 +202,9 @@ class WallabagMobi extends WallabagEBooks } $mobi->setContentProvider($content); + // we strip spaces because the browser inside Kindle Devices doesn't likes spaces + $this->bookFileName = str_replace(' ', '_', $this->bookFileName); + // we offer file to download $mobi->download($this->bookFileName.'.mobi'); Tools::logm('Mobi file produced'); From 3829c54bc5ceff31cb72e686b3c020ea2ac2a5b2 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Mon, 26 Jan 2015 17:44:52 +0100 Subject: [PATCH 29/34] fix for special caracters in .mobi filenames --- inc/poche/WallabagEBooks.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/inc/poche/WallabagEBooks.class.php b/inc/poche/WallabagEBooks.class.php index afcf4dbf5..558315719 100644 --- a/inc/poche/WallabagEBooks.class.php +++ b/inc/poche/WallabagEBooks.class.php @@ -202,8 +202,8 @@ class WallabagMobi extends WallabagEBooks } $mobi->setContentProvider($content); - // we strip spaces because the browser inside Kindle Devices doesn't likes spaces - $this->bookFileName = str_replace(' ', '_', $this->bookFileName); + // the browser inside Kindle Devices doesn't likes special caracters either, we limit to A-z/0-9 + $this->bookFileName = preg_replace('/[^A-Za-z0-9\-]/', '', $this->bookFileName); // we offer file to download $mobi->download($this->bookFileName.'.mobi'); From ca056e7fd1e2bcc8390aabdc6b4fcb84aeb0d302 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Tue, 27 Jan 2015 00:41:25 +0100 Subject: [PATCH 30/34] changes for 1026 for PDO exceptions --- install/index.php | 238 ++++++++++-------------- install/wallabag_compatibility_test.php | 32 ++++ 2 files changed, 130 insertions(+), 140 deletions(-) diff --git a/install/index.php b/install/index.php index ec050b4b7..77b83c36a 100755 --- a/install/index.php +++ b/install/index.php @@ -13,19 +13,6 @@ $successes = array(); require_once('wallabag_compatibility_test.php'); -/* Function taken from at http://php.net/manual/en/function.rmdir.php#110489 - * Idea : nbari at dalmp dot com - * Rights unknown - * Here in case of .gitignore files - */ -function delTree($dir) { - $files = array_diff(scandir($dir), array('.','..')); - foreach ($files as $file) { - (is_dir("$dir/$file")) ? delTree("$dir/$file") : unlink("$dir/$file"); - } - return rmdir($dir); - } - if (isset($_GET['clean'])) { if (is_dir('install')){ delTree('install'); @@ -60,135 +47,108 @@ if (isset($_POST['download'])) { else if (isset($_POST['install'])) { if (!is_dir('vendor')) { $errors[] = 'You must install twig before.'; - } - else { + } else { $continue = true; - // Create config.inc.php - if (!copy('inc/poche/config.inc.default.php', 'inc/poche/config.inc.php')) { - $errors[] = 'Installation aborted, impossible to create inc/poche/config.inc.php file. Maybe you don\'t have write access to create it.'; - $continue = false; - } - else { - function generate_salt() { - mt_srand(microtime(true)*100000 + memory_get_usage(true)); - return md5(uniqid(mt_rand(), true)); - } + $salt = generate_salt(); + $content = file_get_contents('inc/poche/config.inc.default.php'); - $content = file_get_contents('inc/poche/config.inc.php'); - $salt = generate_salt(); - $content = str_replace("define ('SALT', '');", "define ('SALT', '".$salt."');", $content); - file_put_contents('inc/poche/config.inc.php', $content); - } + // User informations + $username = trim($_POST['username']); + $password = trim($_POST['password']); + $salted_password = sha1($password . $username . $salt); - if ($continue) { + // Database informations + $moreQueries = array(); - // User informations - $username = trim($_POST['username']); - $password = trim($_POST['password']); - $salted_password = sha1($password . $username . $salt); - - // Database informations - $moreQueries = array(); - if ($_POST['db_engine'] == 'sqlite') { - if (!copy('install/poche.sqlite', 'db/poche.sqlite')) { - $errors[] = 'Impossible to create inc/poche/config.inc.php file.'; - $continue = false; - } - else { - $db_path = 'sqlite:' . realpath('') . '/db/poche.sqlite'; - $handle = new PDO($db_path); - $sql_structure = ""; - } + if ($_POST['db_engine'] == 'sqlite') { + if (!copy('install/poche.sqlite', 'db/poche.sqlite')) { + $errors[] = 'Impossible to create the SQLite database file.'; } else { - $content = file_get_contents('inc/poche/config.inc.php'); + $db_path = 'sqlite:' . realpath('') . '/db/poche.sqlite'; + $handle = new PDO($db_path); + $handle->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + $sql_structure = ""; + } + } else { + // MySQL and Postgre + try { - if ($_POST['db_engine'] == 'mysql') { - $db_path = 'mysql:host=' . $_POST['mysql_server'] . ';dbname=' . $_POST['mysql_database'] . ';charset=utf8mb4'; - $content = str_replace("define ('STORAGE_SERVER', 'localhost');", "define ('STORAGE_SERVER', '".$_POST['mysql_server']."');", $content); - $content = str_replace("define ('STORAGE_DB', 'poche');", "define ('STORAGE_DB', '".$_POST['mysql_database']."');", $content); - $content = str_replace("define ('STORAGE_USER', 'poche');", "define ('STORAGE_USER', '".$_POST['mysql_user']."');", $content); - $content = str_replace("define ('STORAGE_PASSWORD', 'poche');", "define ('STORAGE_PASSWORD', '".$_POST['mysql_password']."');", $content); - $handle = new PDO($db_path, $_POST['mysql_user'], $_POST['mysql_password'], array( - PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4', - )); + if ($_POST['db_engine'] == 'mysql') { + $db_path = 'mysql:host=' . $_POST['mysql_server'] . ';dbname=' . $_POST['mysql_database'] . ';charset=utf8mb4'; + $content = str_replace("define ('STORAGE_SERVER', 'localhost');", "define ('STORAGE_SERVER', '".$_POST['mysql_server']."');", $content); + $content = str_replace("define ('STORAGE_DB', 'poche');", "define ('STORAGE_DB', '".$_POST['mysql_database']."');", $content); + $content = str_replace("define ('STORAGE_USER', 'poche');", "define ('STORAGE_USER', '".$_POST['mysql_user']."');", $content); + $content = str_replace("define ('STORAGE_PASSWORD', 'poche');", "define ('STORAGE_PASSWORD', '".$_POST['mysql_password']."');", $content); + $handle = new PDO($db_path, $_POST['mysql_user'], $_POST['mysql_password'], array( + PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4', + )); - $moreQueries[] = "INSERT INTO `entries` (`id`, `title`, `url`, `is_read`, `is_fav`, `content`, `user_id`) VALUES + $moreQueries[] = "INSERT INTO `entries` (`id`, `title`, `url`, `is_read`, `is_fav`, `content`, `user_id`) VALUES (1, 'Framabag, un nouveau service libre et gratuit', 'http://www.framablog.org/index.php/post/2014/02/05/Framabag-service-libre-gratuit-interview-developpeur', 0, 0, 0x0a3c68323e556e6520696e74657276696577206465204e69636f6c61732c20736f6e2064c3a976656c6f70706575722e3c2f68323e0a3c703e3c656d3e496c206e6520766f757320612073c3bb72656d656e742070617320c3a96368617070c3a920717565206e6f74726520636f6e736f6d6d6174696f6e20646520636f6e74656e75732064752057656220657374207465727269626c656d656e74206368726f6e6f706861676520657420706172746963756c69c3a872656d656e7420667275737472616e746520746f757420c3a0206c6120666f6973c2a03a206e6f6e207365756c656d656e74206e6f757320706173736f6e732062656175636f7570202874726f70c2a03f292064652074656d707320656e206c69676e6520c3a0206578706c6f726572206c6573206d696e6573206175726966c3a8726573206465206c6120746f696c652c20792064c3a974656374616e742070c3a970697465732065742066696c6f6e732c206d616973206e6f757320736f6d6d657320737572746f757420636f6e7374616d6d656e7420656e206d616e7175652e204dc3aa6d65207369206e6f7573206e6520736f6d6d6573207061732064616e73206c65207a617070696e67206672c3a96ec3a9746971756520736920666163696c656d656e742064c3a96e6f6e63c3a920706172206c657320646f637465732070737963686f6c6f677565732071756920706f6e74696669656e7420737572206c65732064616e67657273206475206e756dc3a9726971756520706f7572206c6573206a65756e65732063657276656c6c65732c20696c206e6f7573207669656e7420736f7576656e74206c6520676fc3bb7420616d6572206465206ce28099696e6163686576c3a9c2a03a20706173206c652074656d707320646520746f7574206c69726520283c6120687265663d22687474703a2f2f66722e77696b74696f6e6172792e6f72672f77696b692f544c4452223e544c3b44523c2f613e2065737420646576656e75206c6520636c696e2064e28099c593696c206d692d6669677565206d692d72616973696e2064e28099756e652067c3a96ec3a9726174696f6e206465206c65637465757273207072657373c3a973292c207061732074726f70206c652074656d70732064652072c3a9666cc3a963686972206e6f6e20706c75732068c3a96c61732c20706173206c652074656d707320646520737569767265206c6120726962616d62656c6c65206465206c69656e73206173736f6369c3a97320c3a020756e2061727469636c65e280a63c6272202f3e3c2f656d3e3c2f703e0a3c703e3c656d3e506f7572206e6f757320646f6e6e657220626f6e6e6520636f6e736369656e63652c206e6f75732072616e67656f6e73207363727570756c657573656d656e7420756e206d61727175652d7061676520646520706c75732064616e7320756e20736f75732d646f73736965722071756920656e20636f6d706f7274652064c3a96ac3a0203235362c206e6f7573206e6f746f6e7320756e20c3a96cc3a96d656e7420646520706c75732064616e73206c6120746f756a6f757273207269646963756c656d656e74206c6f6e67756520746f75646f756c697374652c2062726566206e6f75732072656d6574746f6e7320c3a020706c757320746172642c2063e280996573742dc3a02d64697265206c6520706c757320736f7576656e742061757820696e74726f757661626c65732063616c656e6465732067726563717565732c206c6520736f696e206465206c69726520767261696d656e7420756e2061727469636c65206a7567c3a920696e74c3a972657373616e742c20646520726567617264657220756e6520766964c3a96f207369676e616cc3a96520706172206c65732072c3a97a6f73736f63696f732c206465206c69726520756e20636861706974726520656e746965722064e28099756e206f75767261676520646973706f6e69626c6520656e206c69676e65e280a63c6272202f3e3c2f656d3e3c2f703e0a3c703e3c656d3e416c6f7273206269656e2073c3bb722c20c3a02064c3a966617574206465206e6f757320646f6e6e657220746f7574206c652074656d70732071756920736572616974206ec3a963657373616972652c2064657320736f6c7574696f6e73206578697374656e7420706f7572206e6f7573207065726d657474726520646520c2abc2a06c69726520706c75732074617264c2a0c2bb20656e20736175766567617264616e74206c65207072c3a9636965757820706f6c6c656e206465206e6f7320627574696e61676573206465207369746520656e20736974652c2065742064e28099656e20666169726520756c74c3a97269657572656d656e7420766f747265206d69656cc2a03b2063e280996573742062656c20657420626f6e206d616973206c65732072756368657320736f6e7420756e207065752064697374616e7465732c20c3a7612073e28099617070656c6c65206c6520636c6f756420286e6f7320616d69732074656368696573206de280996f6e74206269656e206578706c697175c3a9206d616973206ae280996169207365756c656d656e7420636f6d70726973207175652064657320747275637320c3a0206d6f6920736f6e742073757220646573206d616368696e6573206c6f696e7461696e65732c20c3a761206e65206d652072617373757265207061732074726f702920657420656c6c657320736f6e7420736f7576656e742070726f707269c3a97461697265732c206e65206c61697373616e7420656e7472657220717565206c6573203c733e7574696c69736174657572733c2f733e20636f6e736f6d6d61746575727320706179616e74732065742071756920636f6e73656e74656e7420c3a0206c6575727320636f6e646974696f6e732e2053616e7320636f6d70746572207175652064652067726f7320626f7572646f6e73207669656e6e656e742070726f666974657220706c7573206f75206d6f696e73206469736372c3a874656d656e7420646520746f757465732063657320747261636573206465206e6f75732d6dc3aa6d657320717569207065726d657474656e74206465206d6f6ec3a97469736572206e6f7472652070726f66696cc2a03a207369206a6520636f6c6c65637465207375722063657320736572766963657320286e65206c6573206e6f6d6d6f6e73207061732c206a757374656d656e742920756e652073c3a97269652064e2809961727469636c657320737572206ce280996964c3a965206465204e6174757265206368657a2044696465726f742c206a6520726563657672616920646976657273657320736f6c6c696369746174696f6e7320706f757220646576656e697220636c69656e74206465206c6120626f757469717565204e61747572652026616d703b2044c3a9636f75766572746520647520626f756c65766172642044696465726f742e2045742073692064e280996176656e74757265206c65732070726f6772616d6d6573206465206c61204e5341206d6f756c696e656e7420737572206c6520736572766963652c206a6520736572616920706575742dc3aa74726520756e206a6f75722064616e7320756e65206c6973746520646573206d696c6974616e7473206e61747572697374657320696e64c3a973697261626c657320737572206c657320766f6c73206465206c612050616e416d20286a65206e65207361697320706c75732074726f70207369206a6520706c616973616e7465206cc3a02c2066696e616c656d656e74e280a6293c6272202f3e3c2f656d3e3c2f703e0a3c703e3c656d3e4c6120626f6e6e65206964c3a965c2a03a20c2abc2a0736520636f6e7374697475657220756e2072c3a9736572766f697220646520646f63756d656e74732073c3a96c656374696f6e6ec3a97320c3a020706172636f7572697220706c75732074617264c2a0c2bb20617070656c61697420646f6e6320756e6520617574726520626f6e6e65206964c3a9652c2063656c6c652064e2809961766f6972206c6520636f6e7472c3b46c652064652063652072c3a9736572766f69722c206465206e6f74726520636f6c6c656374696f6e20706572736f6e6e656c6c652e2043e28099657374204e69636f6c6173204cc59375696c6c65742c2063692d646573736f757320696e74657276696577c3a92c207175692073e28099792065737420636f6c6cc3a9206176656320756e652062656c6c65206170706c69636174696f6e20617070656cc3a96520657568e280a6206f75692c20617070656cc3a9652057616c6c616261672e3c6272202f3e3c2f656d3e3c2f703e0a3c703e3c656d3e4672616d61736f667420736f757469656e742064e28099617574616e7420706c757320736f6e20696e6974696174697665207175e280993c6120687265663d22687474703a2f2f7777772e6672616d61626c6f672e6f72672f696e6465782e7068702f706f73742f323031342f30312f33312f4765656b74696f6e6e6572642d57616c6c61626167223e6f6e206c7569206120636865726368c3a920646573206d6973c3a872657320706f757220756e6520686973746f697265206465206e6f6d3c2f613e206574207175e28099696c2065737420706f737369626c652064e28099696e7374616c6c657220736f692d6dc3aa6d6520756e6520636f7069652064652057616c6c616261672073757220736f6e2070726f70726520736974652e3c6272202f3e3c2f656d3e3c2f703e0a3c703e3c656d3e4c6520706574697420706c7573206465204672616d61736f66742c2072c3a97365617520746f756a6f7572732064c3a973697265757820646520766f75732070726f706f7365722064657320616c7465726e617469766573206c6962c3a972617472696365732c2063e2809965737420646520766f75732070726f706f736572202873757220696e736372697074696f6e207072c3a9616c61626c652920756e20616363c3a873206175204672616d616261672c2061757472656d656e742064697420766f7472652057616c6c616261672073757220756e2073657276657572204672616d612a2061766563206e6f74726520676172616e74696520646520636f6e666964656e7469616c6974c3a92e20436f6d6d6520706f7572206c65204672616d616e6577732c206e6f757320766f7573206163637565696c6c6f6e7320766f6c6f6e74696572732064616e73206c61206c696d697465206465206e6f732063617061636974c3a9732c20656e20766f757320696e766974616e7420c3a020766f7573206c616e6365722064616e7320766f747265206175746f2d68c3a962657267656d656e742064652057616c6c616261672e3c6272202f3e4365742061727469636c65206573742074726f70206c6f6e67c2a03f204d657474657a2d6c652064616e73203c6120687265663d22687474703a2f2f7777772e6672616d616261672e6f72672f696e6465782e706870223e766f747265204672616d616261673c2f613e20657420686f702e3c6272202f3e3c2f656d3e3c2f703e0a3c703e3c656d3e4672616d61626c6f67c2a03a2053616c7574204e69636f6c6173e280a62054752070657578207465207072c3a973656e74657220627269c3a876656d656e74c2a03f3c6272202f3e3c2f656d3e3c2f703e0a3c703e53616c7574c2a0212044c3a976656c6f70706575722050485020646570756973207175656c7175657320616e6ec3a96573206d61696e74656e616e742028313020616e73292c206ae28099616920766f756c75206d652072656d657474726520c3a0206e697665617520746563686e697175656d656e74207061726c616e742028646570756973203320616e732c206ae28099616920706173206d616c206cc3a26368c3a9206c6520636c6176696572292e20506f7572206d6573206265736f696e7320706572736f732c206ae28099616920646f6e63206372c3a9c3a920756e2070657469742070726f6a657420706f75722072656d706c6163657220756e6520736f6c7574696f6e2070726f707269c3a97461697265206578697374616e74652e2053616e7320617563756e65207072c3a974656e74696f6e2c206ae2809961692068c3a962657267c3a92063652070726f6a6574207375722047697468756220657420636f6d6d652063e28099657374206c61207365756c6520736f6c7574696f6e203c656d3e6f70656e20736f757263653c2f656d3e20646520636520747970652c206c65206e6f6d62726520646520706572736f6e6e657320696e74c3a972657373c3a965732061206175676d656e74c3a920e280a63c2f703e0a3c703e3c656d3e4c6573207574696c6973617465757273206465207365727669636573204672616d61736f6674206e65206c6520736176656e742070617320666f7263c3a96d656e742c206d6169732074752061732064c3a96ac3a020706173206d616c207061727469636970c3a920c3a0206c61204672616d6147616c617869652c206e6f6ec2a03f3c6272202f3e3c2f656d3e3c2f703e0a3c703e456e2065666665742e204ae28099616920636f6d6d656e63c3a920756e20706c7567696e20706f7572204672616d616e6577732c203c6120687265663d2268747470733a2f2f6769746875622e636f6d2f6e69636f736f6d622f74747273732d70757267652d6163636f756e7473223e74747273732d70757267652d6163636f756e74733c2f613e2c20717569207065726d6574206465206e6574746f796572206c61206261736520646520646f6e6ec3a9657320646520636f6d7074657320706c7573207574696c6973c3a9732e204d616973206365203c656d3e706c7567696e3c2f656d3e2061206265736f696e2064e28099c3aa747265207465726d696ec3a920c3a0203130302520706f757220c3aa74726520696e74c3a96772c3a9206175207365696e206465204672616d616e6577732028657420646f6e632064652054696e792054696e7920525353292c207369207175656c7175e28099756e20736f756861697465206de2809961696465722c20696c206ee2809979206120617563756e20736f7563692e3c6272202f3e4ae28099616920617573736920666169742031206f7520322061707061726974696f6e732064616e73206465732074726164756374696f6e7320706f7572204672616d61626c6f672e205269656e2064e2809965787472616f7264696e616972652c206a65206e652073756973207061732062696c696e6775652c20c3a761206d65207065726d6574206465206de28099656e747261c3ae6e65722e3c2f703e0a3c703e3c656d3e5061726c6f6e73206465207375697465206465206365207175692066c3a2636865c2a03a20746f6e206170706c69636174696f6e2057616c6c616261672c20656c6c652073e28099617070656c6c6169742070617320e2809c506f636865e2809d2c206176616e74c2a03f205475206e6f7573207261636f6e746573206ce28099686973746f697265c2a03f3c6272202f3e3c2f656d3e3c2f703e0a3c703e45756820656e20656666657420e280a62044c3a96ac3a02c20706f757271756f69203c656d3e706f6368653c2f656d3ec2a03f20506172636520717565206ce28099756e206465732074726f697320c2abc2a074c3a96e6f7273c2a0c2bb20737572206c65206d61726368c3a92073e28099617070656c6c65203c656d3e506f636b65743c2f656d3e2e20436f6d6d65206d6f6e206170706c69206ee28099c3a9746169742064657374696ec3a965207175e28099c3a0206d6f6e20757361676520706572736f6e6e656c2061752064c3a9706172742c206a65206e65206d6520737569732070617320746f72747572c3a9206269656e206c6f6e6774656d70732e3c2f703e0a3c703e43657420c3a974c3a92c206f6e2061206661696c6c69206368616e676572206465206e6f6d2c207175616e6420696c2079206120657520646520706c757320656e20706c75732064e280997574696c69736174657572732e2045742070756973206f6e2073e28099657374206469742071756520706f6368652c2063e28099c3a97461697420706173206d616c2c20c3a76120736f6e6e616974206269656e206672616ec3a761697320657420707569732061766563206c6573207175656c717565732064697a61696e65732064e280997574696c69736174657572732c206f6e206e652067c3aa6e657261697420706572736f6e6e652e3c2f703e0a3c703e43e280996573742073616e7320636f6d707465722061766563206c657320736f6369c3a974c3a97320616dc3a972696361696e6573206574206c6575722066c3a2636865757365206d616e696520646520766f756c6f697220656e766f796572206c657572732061766f6361747320c3a020746f757420626f7574206465206368616d702e204c65203233206a616e766965722c206ae280996169207265c3a77520756e20656d61696c206465206c61207061727420647520636162696e65742064e2809961766f6361747320646520506f636b6574206d652064656d616e64616e74206465206368616e676572206c65206e6f6d2c206c65206c6f676f2c206465206e6520706c7573207574696c69736572206c65207465726d6520e2809c726561642d69742d6c61746572e2809d2028c2abc2a06c6973657a206c6520706c75732074617264c2a0c2bb29206574206465206e6520706c757320646972652071756520506f636b6574206ee280996573742070617320677261747569742028746f7574206573742070617274692064e280993c6120687265663d2268747470733a2f2f747769747465722e636f6d2f77616c6c616261676170702f7374617475732f343233373836333635393434323235373932223e756e2074776565743c2f613e206fc3b9206a65207175616c6966696520506f636b657420646520c2abc2a06e6f6e2066726565c2a0c2bb20c3a0207361766f6972206e6f6e206c69627265292e20427265662c206dc3aa6d65207369206a652073656d626c6169732064616e73206d6f6e2064726f69742c206ae280996169207175616e64206dc3aa6d652070726973206c612064c3a9636973696f6e206465206368616e676572206465206e6f6d2065742057616c6c6162616720657374206ec3a92c20737569746520617578203c6120687265663d22687474703a2f2f6672616d61646174652e6f72672f73747564732e7068703f736f6e646167653d6c6c6370366f6a70796339706b6c6861223e64697a61696e65732064652070726f706f736974696f6e73206465206e6f6d207265c3a77565733c2f613e2e2043e2809965737420756e206dc3a96c616e676520656e747265206c652077616c6c61627920286465206c612066616d696c6c6520646573206b616e676f75726f75732c207175692073746f636b656e742064616e73206c65757220706f63686520636520717569206c65757220657374206368657229206574203c656d3e6261673c2f656d3e20286c6573207465726d657320736163202f207361636f636865202f2062657361636520736f6e7420c3a96e6f726dc3a96d656e7420726576656e7573292e204d616973206d61696e74656e616e742c206f6e207661206465206ce280996176616e742c20706c75732064652074656d707320c3a020706572647265206176656320c3a7612c206f6e2061206475207061696e20737572206c6120706c616e6368652e3c6272202f3e3c696d67207372633d22687474703a2f2f7777772e6672616d61626c6f672e6f72672f7075626c69632f5f696d672f6672616d61626c6f672f77616c6c6162795f626162792e6a70672220616c743d2277616c6c61627920617665632062c3a962c3a92064616e7320736120706f6368652220636c6173733d22633122207469746c653d2277616c6c61627920617665632062c3a962c3a92064616e7320736120706f63686522202f3e206372c3a96469742070686f746f203c6120687265663d22687474703a2f2f7777772e666c69636b722e636f6d2f70686f746f732f3236373832383634404e30302f353032373230323233342f696e2f70686f746f6c6973742d3845654a35412d6831544c36762d4e454c38312d636e4e6b536f2d39594d3174762d374b636736622d387a70416f612d61315a4c4d4e2d39594d3339722d3768355341442d38456548664c2d3845654677752d647456776e4d2d38756f4d45312d4a457a58652d47713471792d3932564a50522d43786531762d38483344324a2d61315a464e732d395937324b362d38456547784c2d354c353346782d354e6b454e732d3555384354592d354e6b7373682d6e6b6176462d3943726777502d3773644341612d647566324b682d685a65707a792d685a645531652d685a656f66462d685a656b44672d685a656741592d685a654d5a6e2d6a61486741662d3850383744322d354e677152762d6154343851422d685a645634592d685a654336342d45526770732d3556594747642d3556594a42312d354e6b72466b2d364a786837682d3768395075512d4552664d782d6831553169682d683155534278223e57696c6c69616d2057617262793c2f613e20717569206175746f72697365206578706c69636974656d656e7420746f7574652072c3a97574696c69736174696f6e2e3c2f703e0a3c703e3c656d3e426f6e2c20616c6f7273206578706c697175652d6d6f6920636520717565206a65207661697320706f75766f69722066616972652061766563204672616d61626167e280a63c6272202f3e3c2f656d3e3c2f703e0a3c703e416c6f7273204672616d616261672c20c3a761207465207065726d6574206465207465206372c3a9657220756e20636f6d7074652067726174756974656d656e74206574206c696272656d656e7420706f757220706f75766f6972207574696c697365722057616c6c616261672e205365756c6520746f6e206164726573736520656d61696c20657374206ec3a963657373616972652c206f6e207365206368617267652064e28099696e7374616c6c6572206574206465206d657474726520c3a0206a6f75722057616c6c6162616720706f757220746f692e20547520706575782064e2809961696c6c657572732070726f6669746572203c6120687265663d22687474703a2f2f7777772e6672616d61736f66742e6e65742f23746f705067436c6f7564223e64e280996175747265732073657276696365732070726f706f73c3a97320706172204672616d61736f6674206963693c2f613e2e3c2f703e0a3c703ec380206365206a6f75722c20696c207920612038333420636f6d70746573206372c3a9c3a97320737572204672616d616261672e3c2f703e0a3c703e3c656d3e566f7573206176657a20767261696d656e7420636f6ec3a7752063652073657276696365206166696e207175e280996f6e20707569737365206ce280997574696c69736572206176656320756e206d6178696d756d2064e280996f7574696c732c206e6f6ec2a03f3c6272202f3e3c2f656d3e3c2f703e0a3c703e4175746f7572206465206ce280996170706c69636174696f6e207765622c20696c206578697374652064c3a96ac3a020646573206170706c69636174696f6e7320706f757220736d61727470686f6e65732028416e64726f69642065742057696e646f77732050686f6e65292c2064657320657874656e73696f6e732046697265666f7820657420476f6f676c65204368726f6d652e3c2f703e0a3c703e436f6d6d652057616c6c6162616720706f7373c3a864652064657320666c7578205253532c2063e2809965737420666163696c65206465206c697265206c65732061727469636c657320736175766567617264c3a97320737572207361206c697365757365202873692063656c6c652d6369207065726d6574206465206c6972652064657320666c757820525353292e2043616c696272652028c2abc2a06c6f67696369656c206465206c6563747572652c2064652067657374696f6e206465206269626c696f7468c3a87175657320657420646520636f6e76657273696f6e206465206669636869657273206e756dc3a972697175657320646520747970652065626f6f6b206f75206c6976726520c3a96c656374726f6e69717565c2a0c2bb2c6e6f757320646974207562756e74752d66722e6f72672920696e74c3a867726520646570756973207175656c717565732073656d61696e6573206d61696e74656e616e74206c6120706f73736962696c6974c3a92064652072c3a9637570c3a9726572206c65732061727469636c6573206e6f6e206c75732c20707261746971756520706f757220666169726520756e20666963686965722065507562c2a0213c2f703e0a3c703e44e28099617574726573206170706c69636174696f6e7320776562207065726d657474656e74206ce28099696e74c3a967726174696f6e20617665632057616c6c61626167202846726573685253532c204c6565642065742054696e792054696e792052535320706f7572206c657320616772c3a96761746575727320646520666c7578292e204ce2809941504920717569207365726120646973706f6e69626c652064616e73206c612070726f636861696e652076657273696f6e2064652057616c6c61626167207065726d657474726120656e636f726520706c75732064e28099696e74657261637469766974c3a92e3c2f703e0a3c703e3c656d3e5920612d742d696c20756e206d6f6465206465206c65637475726520686f7273206c69676e65206f75206573742d6365207175652063e28099657374207072c3a9767520706f7572206c65732070726f636861696e65732076657273696f6e73c2a03f3c6272202f3e3c2f656d3e3c2f703e0a3c703e496c2079206120756e2070736575646f206d6f646520686f7273206c69676e652c20646973706f6e69626c652061766563206ce280996170706c69636174696f6e20416e64726f69642e204f6e20706575742072c3a9637570c3a9726572202876696120756e20666c75782052535329206c65732061727469636c6573206e6f6e206c757320717565206ce280996f6e206120736175766567617264c3a9732e20556e6520666f69732064c3a9636f6e6e656374c3a92c206f6e207065757420636f6e74696e75657220c3a0206c6972652073757220736f6e20736d61727470686f6e65206f75207361207461626c65747465206c65732061727469636c65732e2050617220636f6e7472652c20696c206d616e7175652064657320666f6e6374696f6e6e616c6974c3a973c2a03a207175616e64207475206d61727175657320756e2061727469636c6520636f6d6d65206c752c206365206ee28099657374207061732073796e6368726f6e6973c3a92061766563206c612076657273696f6e207765622064652057616c6c616261672e204ae28099657370c3a8726520717565206a652073756973207072657371756520636c6169722064616e73206d6573206578706c69636174696f6e732e3c2f703e0a3c703e506f7572206c612076322c20717569206573742064c3a96ac3a020656e20636f7572732064652064c3a976656c6f7070656d656e742c206fc3b9206a652073756973206269656e20616964c3a9207061722056696e63656e74204a6f757373652c206f6e2061757261206c6120706f73736962696c6974c3a92064e2809961766f697220756e2076726169206d6f646520686f7273206c69676e652e3c2f703e0a3c703e3c656d3e416c6f7273207369206f6e2076657574206169646572202f2070617274696369706572202f20747269666f75696c6c6572206c6520636f6465202f20766f757320656e766f79657220646573207265746f7572732c206f6e206661697420636f6d6d656e74c2a03f3c6272202f3e3c2f656d3e3c2f703e0a3c703e4f6e207065757420616964657220646520706c75736965757273206661c3a76f6e73c2a03a3c2f703e0a3c756c3e3c6c693e7574696c697365722077616c6c61626167206574206e6f75732072656d6f6e746572206c65732070726f626cc3a86d65732072656e636f6e7472c3a973c2a03b3c2f6c693e0a3c6c693e706172746963697065722061752064c3a976656c6f7070656d656e74206465206ce280996170706c69636174696f6e2068747470733a2f2f6769746875622e636f6d2f77616c6c616261672f77616c6c616261672053692053696c6578202f2053796d666f6e7932202f2048544d4c35202f206574632e207465207061726c656e742c206ee2809968c3a97369746520706173c2a0213c2f6c693e0a3c6c693e636f6d6d6520746f75742070726f6a65742c206c652067726f7320706f696e74206e6f697220657374206c65206d616e71756520646520646f63756d656e746174696f6e2e203c6120687265663d22687474703a2f2f646f632e77616c6c616261672e6f7267223e456c6c652065737420646973706f206963693c2f613e206d61697320696c206d616e71756520706c65696e2064652063686f73657320657420746f7574206ee280996573742070617320c3a0206a6f7572c2a03b3c2f6c693e0a3c6c693e7061726c65722064652057616c6c61626167206175746f757220646520766f7573c2a03b3c2f6c693e0a3c6c693e696c20657869737465203c6120687265663d2268747470733a2f2f666c617474722e636f6d2f7468696e672f313236353438302f706f6368652d612d726561642d69742d6c617465722d6f70656e2d736f757263652d73797374656d223e756e20636f6d70746520466c617474723c2f613e2e3c2f6c693e0a3c2f756c3e3c703e3c656d3e4c65206d6f74206465206c612066696ee280a63f3c6272202f3e3c2f656d3e3c2f703e0a3c703e4d6572636920c3a0204672616d61736f66742064e280996163637565696c6c697220657420646520736f7574656e69722057616c6c61626167c2a0213c2f703e0a3c703e4c6120726f7574652065737420656e636f7265206269656e206c6f6e67756520706f7572206e6520706c7573207574696c6973657220646520736f6c7574696f6e732070726f707269c3a97461697265732c206d616973206f6e2064657672616974207920617272697665722c206e6f6ec2a03f3c2f703e0a3c703e3c696d67207372633d22687474703a2f2f7777772e6672616d61626c6f672e6f72672f7075626c69632f5f696d672f6672616d61626c6f672f706c65696e4c6573506f636865732e706e672220616c743d226672616d61736f667420706c65696e206c657320706f636865732220636c6173733d22633122207469746c653d226672616d61736f667420706c65696e206c657320706f6368657322202f3e3c6272202f3e3c6120687265663d22687474703a2f2f6672616d616c61622e6f72672f676b6e642d63726561746f722f223e6861636b657a2047c3a967c3a9c2a0213c2f613e3c2f703e0a, 1), (2, 'wallabag/wallabag', 'https://github.com/wallabag/wallabag', 0, 0, 0x3c7370616e20636c6173733d226e616d65223e524541444d452e6d643c2f7370616e3e3c703e77616c6c6162616720697320612073656c6620686f737461626c65206170706c69636174696f6e20616c6c6f77696e6720796f7520746f206e6f74206d69737320616e7920636f6e74656e7420616e796d6f72652e20436c69636b2c20736176652c2072656164206974207768656e20796f752063616e2e20497420657874726163747320636f6e74656e7420736f207468617420796f752063616e2072656164206974207768656e20796f7520686176652074696d652e3c2f703e0a3c703e4d6f726520696e666f726d6174696f6e73206f6e206f757220776562736974653a203c6120687265663d22687474703a2f2f77616c6c616261672e6f7267223e77616c6c616261672e6f72673c2f613e3c2f703e0a3c68323e3c6120636c6173733d22616e63686f722220687265663d2268747470733a2f2f6769746875622e636f6d2f77616c6c616261672f77616c6c61626167236c6963656e7365223e3c2f613e4c6963656e73653c2f68323e0a3c703e436f7079726967687420c2a920323031302d32303134204e69636f6c6173204cc59375696c6c6574203c6120687265663d226d61696c746f3a6e69636f6c6173406c6f6575696c6c65742e6f7267223e6e69636f6c6173406c6f6575696c6c65742e6f72673c2f613e205468697320776f726b20697320667265652e20596f752063616e2072656469737472696275746520697420616e642f6f72206d6f6469667920697420756e64657220746865207465726d73206f662074686520446f205768617420546865204675636b20596f752057616e7420546f205075626c6963204c6963656e73652c2056657273696f6e20322c206173207075626c69736865642062792053616d20486f63657661722e205365652074686520434f5059494e472066696c6520666f72206d6f72652064657461696c732e3c2f703e0a, 1), (3, 'a self hostable application for saving web pages | wallabag', 'https://www.wallabag.org/', 0, 1, 0x0a3c64697620636c6173733d22726f77223e0a3c64697620636c6173733d22636f6c2d6c672d3820636f6c2d6d642d313220636f6c2d78732d313220636f6c2d736d2d3132223e0a3c703e77616c6c616261672028666f726d65726c7920706f636865292069732061203c7374726f6e673e73656c6620686f737461626c65206170706c69636174696f6e20666f7220736176696e67207765622070616765733c2f7374726f6e673e2e20556e6c696b65206f746865722073657276696365732cc2a077616c6c6162616720697320667265652028617320696e2066726565646f6d2920616e64206f70656e20736f757263652e3c2f703e0a3c2f6469763e0a0a3c2f6469763e0a3c64697620636c6173733d22726f77223e0a3c64697620636c6173733d22636f6c2d6c672d3820636f6c2d6d642d313220636f6c2d78732d313220636f6c2d736d2d3132223e0a3c703e576974682074686973206170706c69636174696f6e20796f752077696c6c206e6f74206d69737320636f6e74656e7420616e796d6f72652e203c7374726f6e673e436c69636b2c20736176652c2072656164206974207768656e20796f752077616e743c2f7374726f6e673e2e2049742073617665732074686520636f6e74656e7420796f752073656c65637420736f207468617420796f752063616e2072656164206974207768656e20796f7520686176652074696d652e3c2f703e0a3c2f6469763e0a0a3c2f6469763e0a3c64697620636c6173733d22726f77223e0a3c64697620636c6173733d22636f6c2d6c672d3620636f6c2d6d642d313220636f6c2d78732d313220636f6c2d736d2d3132223e0a3c68323e486f7720697420776f726b733c2f68323e0a3c703e5468616e6b7320746f2074686520626f6f6b6d61726b6c6574206f72203c61207469746c653d22446f776e6c6f6164732220687265663d22687474703a2f2f7777772e77616c6c616261672e6f72672f646f776e6c6f6164732f223e74686972642d7061727479206170706c69636174696f6e733c2f613e2c20796f75207361766520616e2061727469636c6520696e20796f7572c2a077616c6c6162616720746f2072656164206974206c617465722e205468656e2c207768656e20796f75206f70656e20796f75722077616c6c616261672c203c7374726f6e673e796f752063616e20636f6d666f727461626c79207265616420796f75722061727469636c65733c2f7374726f6e673e2e3c2f703e0a3c68323e486f7720746f207573652077616c6c616261673c2f68323e0a3c703e5468657265206172652074776f207761797320746f207573652077616c6c616261673a20796f752063616e203c6120687265663d22687474703a2f2f7777772e77616c6c616261672e6f72672f6672657175656e746c792d61736b65642d7175657374696f6e732f23486f775f63616e5f495f696e7374616c6c5f77616c6c616261675f616e645f776861745f6172655f7468655f726571756972656d656e7473223e696e7374616c6c2069743c2f613ec2a06f6e20796f75722077656220736572766572206f7220796f752063616ec2a03c6120687265663d22687474703a2f2f6170702e696e746865706f6368652e636f6d223e63726561746520616e206163636f756e743c2f613ec2a06174204672616d616261672028776520696e7374616c6c20616e642075706772616465c2a077616c6c6162616720666f7220796f75292e3c2f703e0a3c2f6469763e0a0a3c2f6469763e0a, 1);"; - $moreQueries[] = "INSERT INTO `tags` (`id`, `value`) VALUES (1, 'opensource');"; - $moreQueries[] = "INSERT INTO `tags_entries` (`id`, `entry_id`, `tag_id`) VALUES (1, 2, 1);"; + $moreQueries[] = "INSERT INTO `tags` (`id`, `value`) VALUES (1, 'opensource');"; + $moreQueries[] = "INSERT INTO `tags_entries` (`id`, `entry_id`, `tag_id`) VALUES (1, 2, 1);"; - $sql_structure = file_get_contents('install/mysql.sql'); - } - else if ($_POST['db_engine'] == 'postgres') { - $db_path = 'pgsql:host=' . $_POST['pg_server'] . ';dbname=' . $_POST['pg_database']; - $content = str_replace("define ('STORAGE_SERVER', 'localhost');", "define ('STORAGE_SERVER', '".$_POST['pg_server']."');", $content); - $content = str_replace("define ('STORAGE_DB', 'poche');", "define ('STORAGE_DB', '".$_POST['pg_database']."');", $content); - $content = str_replace("define ('STORAGE_USER', 'poche');", "define ('STORAGE_USER', '".$_POST['pg_user']."');", $content); - $content = str_replace("define ('STORAGE_PASSWORD', 'poche');", "define ('STORAGE_PASSWORD', '".$_POST['pg_password']."');", $content); - $handle = new PDO($db_path, $_POST['pg_user'], $_POST['pg_password']); - - $moreQueries[] = "INSERT INTO entries (title, url, is_read, is_fav, content, user_id) VALUES + $sql_structure = file_get_contents('install/mysql.sql'); + } + else if ($_POST['db_engine'] == 'postgres') { + $db_path = 'pgsql:host=' . $_POST['pg_server'] . ';dbname=' . $_POST['pg_database']; + $content = str_replace("define ('STORAGE_SERVER', 'localhost');", "define ('STORAGE_SERVER', '".$_POST['pg_server']."');", $content); + $content = str_replace("define ('STORAGE_DB', 'poche');", "define ('STORAGE_DB', '".$_POST['pg_database']."');", $content); + $content = str_replace("define ('STORAGE_USER', 'poche');", "define ('STORAGE_USER', '".$_POST['pg_user']."');", $content); + $content = str_replace("define ('STORAGE_PASSWORD', 'poche');", "define ('STORAGE_PASSWORD', '".$_POST['pg_password']."');", $content); + $handle = new PDO($db_path, $_POST['pg_user'], $_POST['pg_password']); + + $moreQueries[] = "INSERT INTO entries (title, url, is_read, is_fav, content, user_id) VALUES ('Framabag, un nouveau service libre et gratuit', 'http://www.framablog.org/index.php/post/2014/02/05/Framabag-service-libre-gratuit-interview-developpeur', false, false, convert_from(decode('3c68323e556e6520696e74657276696577206465204e69636f6c61732c20736f6e2064c3a976656c6f70706575722e3c2f68323e0a3c703e3c656d3e496c206e6520766f757320612073c3bb72656d656e742070617320c3a96368617070c3a920717565206e6f74726520636f6e736f6d6d6174696f6e20646520636f6e74656e75732064752057656220657374207465727269626c656d656e74206368726f6e6f706861676520657420706172746963756c69c3a872656d656e7420667275737472616e746520746f757420c3a0206c6120666f6973c2a03a206e6f6e207365756c656d656e74206e6f757320706173736f6e732062656175636f7570202874726f70c2a03f292064652074656d707320656e206c69676e6520c3a0206578706c6f726572206c6573206d696e6573206175726966c3a8726573206465206c6120746f696c652c20792064c3a974656374616e742070c3a970697465732065742066696c6f6e732c206d616973206e6f757320736f6d6d657320737572746f757420636f6e7374616d6d656e7420656e206d616e7175652e204dc3aa6d65207369206e6f7573206e6520736f6d6d6573207061732064616e73206c65207a617070696e67206672c3a96ec3a9746971756520736920666163696c656d656e742064c3a96e6f6e63c3a920706172206c657320646f637465732070737963686f6c6f677565732071756920706f6e74696669656e7420737572206c65732064616e67657273206475206e756dc3a9726971756520706f7572206c6573206a65756e65732063657276656c6c65732c20696c206e6f7573207669656e7420736f7576656e74206c6520676fc3bb7420616d6572206465206ce28099696e6163686576c3a9c2a03a20706173206c652074656d707320646520746f7574206c69726520283c6120687265663d22687474703a2f2f66722e77696b74696f6e6172792e6f72672f77696b692f544c4452223e544c3b44523c2f613e2065737420646576656e75206c6520636c696e2064e28099c593696c206d692d6669677565206d692d72616973696e2064e28099756e652067c3a96ec3a9726174696f6e206465206c65637465757273207072657373c3a973292c207061732074726f70206c652074656d70732064652072c3a9666cc3a963686972206e6f6e20706c75732068c3a96c61732c20706173206c652074656d707320646520737569767265206c6120726962616d62656c6c65206465206c69656e73206173736f6369c3a97320c3a020756e2061727469636c65e280a63c6272202f3e3c2f656d3e3c2f703e0a3c703e3c656d3e506f7572206e6f757320646f6e6e657220626f6e6e6520636f6e736369656e63652c206e6f75732072616e67656f6e73207363727570756c657573656d656e7420756e206d61727175652d7061676520646520706c75732064616e7320756e20736f75732d646f73736965722071756920656e20636f6d706f7274652064c3a96ac3a0203235362c206e6f7573206e6f746f6e7320756e20c3a96cc3a96d656e7420646520706c75732064616e73206c6120746f756a6f757273207269646963756c656d656e74206c6f6e67756520746f75646f756c697374652c2062726566206e6f75732072656d6574746f6e7320c3a020706c757320746172642c2063e280996573742dc3a02d64697265206c6520706c757320736f7576656e742061757820696e74726f757661626c65732063616c656e6465732067726563717565732c206c6520736f696e206465206c69726520767261696d656e7420756e2061727469636c65206a7567c3a920696e74c3a972657373616e742c20646520726567617264657220756e6520766964c3a96f207369676e616cc3a96520706172206c65732072c3a97a6f73736f63696f732c206465206c69726520756e20636861706974726520656e746965722064e28099756e206f75767261676520646973706f6e69626c6520656e206c69676e65e280a63c6272202f3e3c2f656d3e3c2f703e0a3c703e3c656d3e416c6f7273206269656e2073c3bb722c20c3a02064c3a966617574206465206e6f757320646f6e6e657220746f7574206c652074656d70732071756920736572616974206ec3a963657373616972652c2064657320736f6c7574696f6e73206578697374656e7420706f7572206e6f7573207065726d657474726520646520c2abc2a06c69726520706c75732074617264c2a0c2bb20656e20736175766567617264616e74206c65207072c3a9636965757820706f6c6c656e206465206e6f7320627574696e61676573206465207369746520656e20736974652c2065742064e28099656e20666169726520756c74c3a97269657572656d656e7420766f747265206d69656cc2a03b2063e280996573742062656c20657420626f6e206d616973206c65732072756368657320736f6e7420756e207065752064697374616e7465732c20c3a7612073e28099617070656c6c65206c6520636c6f756420286e6f7320616d69732074656368696573206de280996f6e74206269656e206578706c697175c3a9206d616973206ae280996169207365756c656d656e7420636f6d70726973207175652064657320747275637320c3a0206d6f6920736f6e742073757220646573206d616368696e6573206c6f696e7461696e65732c20c3a761206e65206d652072617373757265207061732074726f702920657420656c6c657320736f6e7420736f7576656e742070726f707269c3a97461697265732c206e65206c61697373616e7420656e7472657220717565206c6573203c733e7574696c69736174657572733c2f733e20636f6e736f6d6d61746575727320706179616e74732065742071756920636f6e73656e74656e7420c3a0206c6575727320636f6e646974696f6e732e2053616e7320636f6d70746572207175652064652067726f7320626f7572646f6e73207669656e6e656e742070726f666974657220706c7573206f75206d6f696e73206469736372c3a874656d656e7420646520746f757465732063657320747261636573206465206e6f75732d6dc3aa6d657320717569207065726d657474656e74206465206d6f6ec3a97469736572206e6f7472652070726f66696cc2a03a207369206a6520636f6c6c65637465207375722063657320736572766963657320286e65206c6573206e6f6d6d6f6e73207061732c206a757374656d656e742920756e652073c3a97269652064e2809961727469636c657320737572206ce280996964c3a965206465204e6174757265206368657a2044696465726f742c206a6520726563657672616920646976657273657320736f6c6c696369746174696f6e7320706f757220646576656e697220636c69656e74206465206c6120626f757469717565204e61747572652026616d703b2044c3a9636f75766572746520647520626f756c65766172642044696465726f742e2045742073692064e280996176656e74757265206c65732070726f6772616d6d6573206465206c61204e5341206d6f756c696e656e7420737572206c6520736572766963652c206a6520736572616920706575742dc3aa74726520756e206a6f75722064616e7320756e65206c6973746520646573206d696c6974616e7473206e61747572697374657320696e64c3a973697261626c657320737572206c657320766f6c73206465206c612050616e416d20286a65206e65207361697320706c75732074726f70207369206a6520706c616973616e7465206cc3a02c2066696e616c656d656e74e280a6293c6272202f3e3c2f656d3e3c2f703e0a3c703e3c656d3e4c6120626f6e6e65206964c3a965c2a03a20c2abc2a0736520636f6e7374697475657220756e2072c3a9736572766f697220646520646f63756d656e74732073c3a96c656374696f6e6ec3a97320c3a020706172636f7572697220706c75732074617264c2a0c2bb20617070656c61697420646f6e6320756e6520617574726520626f6e6e65206964c3a9652c2063656c6c652064e2809961766f6972206c6520636f6e7472c3b46c652064652063652072c3a9736572766f69722c206465206e6f74726520636f6c6c656374696f6e20706572736f6e6e656c6c652e2043e28099657374204e69636f6c6173204cc59375696c6c65742c2063692d646573736f757320696e74657276696577c3a92c207175692073e28099792065737420636f6c6cc3a9206176656320756e652062656c6c65206170706c69636174696f6e20617070656cc3a96520657568e280a6206f75692c20617070656cc3a9652057616c6c616261672e3c6272202f3e3c2f656d3e3c2f703e0a3c703e3c656d3e4672616d61736f667420736f757469656e742064e28099617574616e7420706c757320736f6e20696e6974696174697665207175e280993c6120687265663d22687474703a2f2f7777772e6672616d61626c6f672e6f72672f696e6465782e7068702f706f73742f323031342f30312f33312f4765656b74696f6e6e6572642d57616c6c61626167223e6f6e206c7569206120636865726368c3a920646573206d6973c3a872657320706f757220756e6520686973746f697265206465206e6f6d3c2f613e206574207175e28099696c2065737420706f737369626c652064e28099696e7374616c6c657220736f692d6dc3aa6d6520756e6520636f7069652064652057616c6c616261672073757220736f6e2070726f70726520736974652e3c6272202f3e3c2f656d3e3c2f703e0a3c703e3c656d3e4c6520706574697420706c7573206465204672616d61736f66742c2072c3a97365617520746f756a6f7572732064c3a973697265757820646520766f75732070726f706f7365722064657320616c7465726e617469766573206c6962c3a972617472696365732c2063e2809965737420646520766f75732070726f706f736572202873757220696e736372697074696f6e207072c3a9616c61626c652920756e20616363c3a873206175204672616d616261672c2061757472656d656e742064697420766f7472652057616c6c616261672073757220756e2073657276657572204672616d612a2061766563206e6f74726520676172616e74696520646520636f6e666964656e7469616c6974c3a92e20436f6d6d6520706f7572206c65204672616d616e6577732c206e6f757320766f7573206163637565696c6c6f6e7320766f6c6f6e74696572732064616e73206c61206c696d697465206465206e6f732063617061636974c3a9732c20656e20766f757320696e766974616e7420c3a020766f7573206c616e6365722064616e7320766f747265206175746f2d68c3a962657267656d656e742064652057616c6c616261672e3c6272202f3e4365742061727469636c65206573742074726f70206c6f6e67c2a03f204d657474657a2d6c652064616e73203c6120687265663d22687474703a2f2f7777772e6672616d616261672e6f72672f696e6465782e706870223e766f747265204672616d616261673c2f613e20657420686f702e3c6272202f3e3c2f656d3e3c2f703e0a3c703e3c656d3e4672616d61626c6f67c2a03a2053616c7574204e69636f6c6173e280a62054752070657578207465207072c3a973656e74657220627269c3a876656d656e74c2a03f3c6272202f3e3c2f656d3e3c2f703e0a3c703e53616c7574c2a0212044c3a976656c6f70706575722050485020646570756973207175656c7175657320616e6ec3a96573206d61696e74656e616e742028313020616e73292c206ae28099616920766f756c75206d652072656d657474726520c3a0206e697665617520746563686e697175656d656e74207061726c616e742028646570756973203320616e732c206ae28099616920706173206d616c206cc3a26368c3a9206c6520636c6176696572292e20506f7572206d6573206265736f696e7320706572736f732c206ae28099616920646f6e63206372c3a9c3a920756e2070657469742070726f6a657420706f75722072656d706c6163657220756e6520736f6c7574696f6e2070726f707269c3a97461697265206578697374616e74652e2053616e7320617563756e65207072c3a974656e74696f6e2c206ae2809961692068c3a962657267c3a92063652070726f6a6574207375722047697468756220657420636f6d6d652063e28099657374206c61207365756c6520736f6c7574696f6e203c656d3e6f70656e20736f757263653c2f656d3e20646520636520747970652c206c65206e6f6d62726520646520706572736f6e6e657320696e74c3a972657373c3a965732061206175676d656e74c3a920e280a63c2f703e0a3c703e3c656d3e4c6573207574696c6973617465757273206465207365727669636573204672616d61736f6674206e65206c6520736176656e742070617320666f7263c3a96d656e742c206d6169732074752061732064c3a96ac3a020706173206d616c207061727469636970c3a920c3a0206c61204672616d6147616c617869652c206e6f6ec2a03f3c6272202f3e3c2f656d3e3c2f703e0a3c703e456e2065666665742e204ae28099616920636f6d6d656e63c3a920756e20706c7567696e20706f7572204672616d616e6577732c203c6120687265663d2268747470733a2f2f6769746875622e636f6d2f6e69636f736f6d622f74747273732d70757267652d6163636f756e7473223e74747273732d70757267652d6163636f756e74733c2f613e2c20717569207065726d6574206465206e6574746f796572206c61206261736520646520646f6e6ec3a9657320646520636f6d7074657320706c7573207574696c6973c3a9732e204d616973206365203c656d3e706c7567696e3c2f656d3e2061206265736f696e2064e28099c3aa747265207465726d696ec3a920c3a0203130302520706f757220c3aa74726520696e74c3a96772c3a9206175207365696e206465204672616d616e6577732028657420646f6e632064652054696e792054696e7920525353292c207369207175656c7175e28099756e20736f756861697465206de2809961696465722c20696c206ee2809979206120617563756e20736f7563692e3c6272202f3e4ae28099616920617573736920666169742031206f7520322061707061726974696f6e732064616e73206465732074726164756374696f6e7320706f7572204672616d61626c6f672e205269656e2064e2809965787472616f7264696e616972652c206a65206e652073756973207061732062696c696e6775652c20c3a761206d65207065726d6574206465206de28099656e747261c3ae6e65722e3c2f703e0a3c703e3c656d3e5061726c6f6e73206465207375697465206465206365207175692066c3a2636865c2a03a20746f6e206170706c69636174696f6e2057616c6c616261672c20656c6c652073e28099617070656c6c6169742070617320e2809c506f636865e2809d2c206176616e74c2a03f205475206e6f7573207261636f6e746573206ce28099686973746f697265c2a03f3c6272202f3e3c2f656d3e3c2f703e0a3c703e45756820656e20656666657420e280a62044c3a96ac3a02c20706f757271756f69203c656d3e706f6368653c2f656d3ec2a03f20506172636520717565206ce28099756e206465732074726f697320c2abc2a074c3a96e6f7273c2a0c2bb20737572206c65206d61726368c3a92073e28099617070656c6c65203c656d3e506f636b65743c2f656d3e2e20436f6d6d65206d6f6e206170706c69206ee28099c3a9746169742064657374696ec3a965207175e28099c3a0206d6f6e20757361676520706572736f6e6e656c2061752064c3a9706172742c206a65206e65206d6520737569732070617320746f72747572c3a9206269656e206c6f6e6774656d70732e3c2f703e0a3c703e43657420c3a974c3a92c206f6e2061206661696c6c69206368616e676572206465206e6f6d2c207175616e6420696c2079206120657520646520706c757320656e20706c75732064e280997574696c69736174657572732e2045742070756973206f6e2073e28099657374206469742071756520706f6368652c2063e28099c3a97461697420706173206d616c2c20c3a76120736f6e6e616974206269656e206672616ec3a761697320657420707569732061766563206c6573207175656c717565732064697a61696e65732064e280997574696c69736174657572732c206f6e206e652067c3aa6e657261697420706572736f6e6e652e3c2f703e0a3c703e43e280996573742073616e7320636f6d707465722061766563206c657320736f6369c3a974c3a97320616dc3a972696361696e6573206574206c6575722066c3a2636865757365206d616e696520646520766f756c6f697220656e766f796572206c657572732061766f6361747320c3a020746f757420626f7574206465206368616d702e204c65203233206a616e766965722c206ae280996169207265c3a77520756e20656d61696c206465206c61207061727420647520636162696e65742064e2809961766f6361747320646520506f636b6574206d652064656d616e64616e74206465206368616e676572206c65206e6f6d2c206c65206c6f676f2c206465206e6520706c7573207574696c69736572206c65207465726d6520e2809c726561642d69742d6c61746572e2809d2028c2abc2a06c6973657a206c6520706c75732074617264c2a0c2bb29206574206465206e6520706c757320646972652071756520506f636b6574206ee280996573742070617320677261747569742028746f7574206573742070617274692064e280993c6120687265663d2268747470733a2f2f747769747465722e636f6d2f77616c6c616261676170702f7374617475732f343233373836333635393434323235373932223e756e2074776565743c2f613e206fc3b9206a65207175616c6966696520506f636b657420646520c2abc2a06e6f6e2066726565c2a0c2bb20c3a0207361766f6972206e6f6e206c69627265292e20427265662c206dc3aa6d65207369206a652073656d626c6169732064616e73206d6f6e2064726f69742c206ae280996169207175616e64206dc3aa6d652070726973206c612064c3a9636973696f6e206465206368616e676572206465206e6f6d2065742057616c6c6162616720657374206ec3a92c20737569746520617578203c6120687265663d22687474703a2f2f6672616d61646174652e6f72672f73747564732e7068703f736f6e646167653d6c6c6370366f6a70796339706b6c6861223e64697a61696e65732064652070726f706f736974696f6e73206465206e6f6d207265c3a77565733c2f613e2e2043e2809965737420756e206dc3a96c616e676520656e747265206c652077616c6c61627920286465206c612066616d696c6c6520646573206b616e676f75726f75732c207175692073746f636b656e742064616e73206c65757220706f63686520636520717569206c65757220657374206368657229206574203c656d3e6261673c2f656d3e20286c6573207465726d657320736163202f207361636f636865202f2062657361636520736f6e7420c3a96e6f726dc3a96d656e7420726576656e7573292e204d616973206d61696e74656e616e742c206f6e207661206465206ce280996176616e742c20706c75732064652074656d707320c3a020706572647265206176656320c3a7612c206f6e2061206475207061696e20737572206c6120706c616e6368652e3c6272202f3e3c696d67207372633d22687474703a2f2f7777772e6672616d61626c6f672e6f72672f7075626c69632f5f696d672f6672616d61626c6f672f77616c6c6162795f626162792e6a70672220616c743d2277616c6c61627920617665632062c3a962c3a92064616e7320736120706f6368652220636c6173733d22633122207469746c653d2277616c6c61627920617665632062c3a962c3a92064616e7320736120706f63686522202f3e206372c3a96469742070686f746f203c6120687265663d22687474703a2f2f7777772e666c69636b722e636f6d2f70686f746f732f3236373832383634404e30302f353032373230323233342f696e2f70686f746f6c6973742d3845654a35412d6831544c36762d4e454c38312d636e4e6b536f2d39594d3174762d374b636736622d387a70416f612d61315a4c4d4e2d39594d3339722d3768355341442d38456548664c2d3845654677752d647456776e4d2d38756f4d45312d4a457a58652d47713471792d3932564a50522d43786531762d38483344324a2d61315a464e732d395937324b362d38456547784c2d354c353346782d354e6b454e732d3555384354592d354e6b7373682d6e6b6176462d3943726777502d3773644341612d647566324b682d685a65707a792d685a645531652d685a656f66462d685a656b44672d685a656741592d685a654d5a6e2d6a61486741662d3850383744322d354e677152762d6154343851422d685a645634592d685a654336342d45526770732d3556594747642d3556594a42312d354e6b72466b2d364a786837682d3768395075512d4552664d782d6831553169682d683155534278223e57696c6c69616d2057617262793c2f613e20717569206175746f72697365206578706c69636974656d656e7420746f7574652072c3a97574696c69736174696f6e2e3c2f703e0a3c703e3c656d3e426f6e2c20616c6f7273206578706c697175652d6d6f6920636520717565206a65207661697320706f75766f69722066616972652061766563204672616d61626167e280a63c6272202f3e3c2f656d3e3c2f703e0a3c703e416c6f7273204672616d616261672c20c3a761207465207065726d6574206465207465206372c3a9657220756e20636f6d7074652067726174756974656d656e74206574206c696272656d656e7420706f757220706f75766f6972207574696c697365722057616c6c616261672e205365756c6520746f6e206164726573736520656d61696c20657374206ec3a963657373616972652c206f6e207365206368617267652064e28099696e7374616c6c6572206574206465206d657474726520c3a0206a6f75722057616c6c6162616720706f757220746f692e20547520706575782064e2809961696c6c657572732070726f6669746572203c6120687265663d22687474703a2f2f7777772e6672616d61736f66742e6e65742f23746f705067436c6f7564223e64e280996175747265732073657276696365732070726f706f73c3a97320706172204672616d61736f6674206963693c2f613e2e3c2f703e0a3c703ec380206365206a6f75722c20696c207920612038333420636f6d70746573206372c3a9c3a97320737572204672616d616261672e3c2f703e0a3c703e3c656d3e566f7573206176657a20767261696d656e7420636f6ec3a7752063652073657276696365206166696e207175e280996f6e20707569737365206ce280997574696c69736572206176656320756e206d6178696d756d2064e280996f7574696c732c206e6f6ec2a03f3c6272202f3e3c2f656d3e3c2f703e0a3c703e4175746f7572206465206ce280996170706c69636174696f6e207765622c20696c206578697374652064c3a96ac3a020646573206170706c69636174696f6e7320706f757220736d61727470686f6e65732028416e64726f69642065742057696e646f77732050686f6e65292c2064657320657874656e73696f6e732046697265666f7820657420476f6f676c65204368726f6d652e3c2f703e0a3c703e436f6d6d652057616c6c6162616720706f7373c3a864652064657320666c7578205253532c2063e2809965737420666163696c65206465206c697265206c65732061727469636c657320736175766567617264c3a97320737572207361206c697365757365202873692063656c6c652d6369207065726d6574206465206c6972652064657320666c757820525353292e2043616c696272652028c2abc2a06c6f67696369656c206465206c6563747572652c2064652067657374696f6e206465206269626c696f7468c3a87175657320657420646520636f6e76657273696f6e206465206669636869657273206e756dc3a972697175657320646520747970652065626f6f6b206f75206c6976726520c3a96c656374726f6e69717565c2a0c2bb2c6e6f757320646974207562756e74752d66722e6f72672920696e74c3a867726520646570756973207175656c717565732073656d61696e6573206d61696e74656e616e74206c6120706f73736962696c6974c3a92064652072c3a9637570c3a9726572206c65732061727469636c6573206e6f6e206c75732c20707261746971756520706f757220666169726520756e20666963686965722065507562c2a0213c2f703e0a3c703e44e28099617574726573206170706c69636174696f6e7320776562207065726d657474656e74206ce28099696e74c3a967726174696f6e20617665632057616c6c61626167202846726573685253532c204c6565642065742054696e792054696e792052535320706f7572206c657320616772c3a96761746575727320646520666c7578292e204ce2809941504920717569207365726120646973706f6e69626c652064616e73206c612070726f636861696e652076657273696f6e2064652057616c6c61626167207065726d657474726120656e636f726520706c75732064e28099696e74657261637469766974c3a92e3c2f703e0a3c703e3c656d3e5920612d742d696c20756e206d6f6465206465206c65637475726520686f7273206c69676e65206f75206573742d6365207175652063e28099657374207072c3a9767520706f7572206c65732070726f636861696e65732076657273696f6e73c2a03f3c6272202f3e3c2f656d3e3c2f703e0a3c703e496c2079206120756e2070736575646f206d6f646520686f7273206c69676e652c20646973706f6e69626c652061766563206ce280996170706c69636174696f6e20416e64726f69642e204f6e20706575742072c3a9637570c3a9726572202876696120756e20666c75782052535329206c65732061727469636c6573206e6f6e206c757320717565206ce280996f6e206120736175766567617264c3a9732e20556e6520666f69732064c3a9636f6e6e656374c3a92c206f6e207065757420636f6e74696e75657220c3a0206c6972652073757220736f6e20736d61727470686f6e65206f75207361207461626c65747465206c65732061727469636c65732e2050617220636f6e7472652c20696c206d616e7175652064657320666f6e6374696f6e6e616c6974c3a973c2a03a207175616e64207475206d61727175657320756e2061727469636c6520636f6d6d65206c752c206365206ee28099657374207061732073796e6368726f6e6973c3a92061766563206c612076657273696f6e207765622064652057616c6c616261672e204ae28099657370c3a8726520717565206a652073756973207072657371756520636c6169722064616e73206d6573206578706c69636174696f6e732e3c2f703e0a3c703e506f7572206c612076322c20717569206573742064c3a96ac3a020656e20636f7572732064652064c3a976656c6f7070656d656e742c206fc3b9206a652073756973206269656e20616964c3a9207061722056696e63656e74204a6f757373652c206f6e2061757261206c6120706f73736962696c6974c3a92064e2809961766f697220756e2076726169206d6f646520686f7273206c69676e652e3c2f703e0a3c703e3c656d3e416c6f7273207369206f6e2076657574206169646572202f2070617274696369706572202f20747269666f75696c6c6572206c6520636f6465202f20766f757320656e766f79657220646573207265746f7572732c206f6e206661697420636f6d6d656e74c2a03f3c6272202f3e3c2f656d3e3c2f703e0a3c703e4f6e207065757420616964657220646520706c75736965757273206661c3a76f6e73c2a03a3c2f703e0a3c756c3e3c6c693e7574696c697365722077616c6c61626167206574206e6f75732072656d6f6e746572206c65732070726f626cc3a86d65732072656e636f6e7472c3a973c2a03b3c2f6c693e0a3c6c693e706172746963697065722061752064c3a976656c6f7070656d656e74206465206ce280996170706c69636174696f6e2068747470733a2f2f6769746875622e636f6d2f77616c6c616261672f77616c6c616261672053692053696c6578202f2053796d666f6e7932202f2048544d4c35202f206574632e207465207061726c656e742c206ee2809968c3a97369746520706173c2a0213c2f6c693e0a3c6c693e636f6d6d6520746f75742070726f6a65742c206c652067726f7320706f696e74206e6f697220657374206c65206d616e71756520646520646f63756d656e746174696f6e2e203c6120687265663d22687474703a2f2f646f632e77616c6c616261672e6f7267223e456c6c652065737420646973706f206963693c2f613e206d61697320696c206d616e71756520706c65696e2064652063686f73657320657420746f7574206ee280996573742070617320c3a0206a6f7572c2a03b3c2f6c693e0a3c6c693e7061726c65722064652057616c6c61626167206175746f757220646520766f7573c2a03b3c2f6c693e0a3c6c693e696c20657869737465203c6120687265663d2268747470733a2f2f666c617474722e636f6d2f7468696e672f313236353438302f706f6368652d612d726561642d69742d6c617465722d6f70656e2d736f757263652d73797374656d223e756e20636f6d70746520466c617474723c2f613e2e3c2f6c693e0a3c2f756c3e3c703e3c656d3e4c65206d6f74206465206c612066696ee280a63f3c6272202f3e3c2f656d3e3c2f703e0a3c703e4d6572636920c3a0204672616d61736f66742064e280996163637565696c6c697220657420646520736f7574656e69722057616c6c61626167c2a0213c2f703e0a3c703e4c6120726f7574652065737420656e636f7265206269656e206c6f6e67756520706f7572206e6520706c7573207574696c6973657220646520736f6c7574696f6e732070726f707269c3a97461697265732c206d616973206f6e2064657672616974207920617272697665722c206e6f6ec2a03f3c2f703e0a3c703e3c696d67207372633d22687474703a2f2f7777772e6672616d61626c6f672e6f72672f7075626c69632f5f696d672f6672616d61626c6f672f706c65696e4c6573506f636865732e706e672220616c743d226672616d61736f667420706c65696e206c657320706f636865732220636c6173733d22633122207469746c653d226672616d61736f667420706c65696e206c657320706f6368657322202f3e3c6272202f3e3c6120687265663d22687474703a2f2f6672616d616c61622e6f72672f676b6e642d63726561746f722f223e6861636b657a2047c3a967c3a9c2a0213c2f613e3c2f703e0a', 'hex'), 'UTF8'), 1), ('wallabag/wallabag', 'https://github.com/wallabag/wallabag', false, false, convert_from(decode('3c7370616e20636c6173733d226e616d65223e524541444d452e6d643c2f7370616e3e3c703e77616c6c6162616720697320612073656c6620686f737461626c65206170706c69636174696f6e20616c6c6f77696e6720796f7520746f206e6f74206d69737320616e7920636f6e74656e7420616e796d6f72652e20436c69636b2c20736176652c2072656164206974207768656e20796f752063616e2e20497420657874726163747320636f6e74656e7420736f207468617420796f752063616e2072656164206974207768656e20796f7520686176652074696d652e3c2f703e0a3c703e4d6f726520696e666f726d6174696f6e73206f6e206f757220776562736974653a203c6120687265663d22687474703a2f2f77616c6c616261672e6f7267223e77616c6c616261672e6f72673c2f613e3c2f703e0a3c68323e3c6120636c6173733d22616e63686f722220687265663d2268747470733a2f2f6769746875622e636f6d2f77616c6c616261672f77616c6c61626167236c6963656e7365223e3c2f613e4c6963656e73653c2f68323e0a3c703e436f7079726967687420c2a920323031302d32303134204e69636f6c6173204cc59375696c6c6574203c6120687265663d226d61696c746f3a6e69636f6c6173406c6f6575696c6c65742e6f7267223e6e69636f6c6173406c6f6575696c6c65742e6f72673c2f613e205468697320776f726b20697320667265652e20596f752063616e2072656469737472696275746520697420616e642f6f72206d6f6469667920697420756e64657220746865207465726d73206f662074686520446f205768617420546865204675636b20596f752057616e7420546f205075626c6963204c6963656e73652c2056657273696f6e20322c206173207075626c69736865642062792053616d20486f63657661722e205365652074686520434f5059494e472066696c6520666f72206d6f72652064657461696c732e3c2f703e0a', 'hex'), 'UTF8'), 1), ('a self hostable application for saving web pages | wallabag', 'https://www.wallabag.org/', false, true, convert_from(decode('3c64697620636c6173733d22726f77223e0a3c64697620636c6173733d22636f6c2d6c672d3820636f6c2d6d642d313220636f6c2d78732d313220636f6c2d736d2d3132223e0a3c703e77616c6c616261672028666f726d65726c7920706f636865292069732061203c7374726f6e673e73656c6620686f737461626c65206170706c69636174696f6e20666f7220736176696e67207765622070616765733c2f7374726f6e673e2e20556e6c696b65206f746865722073657276696365732cc2a077616c6c6162616720697320667265652028617320696e2066726565646f6d2920616e64206f70656e20736f757263652e3c2f703e0a3c2f6469763e0a0a3c2f6469763e0a3c64697620636c6173733d22726f77223e0a3c64697620636c6173733d22636f6c2d6c672d3820636f6c2d6d642d313220636f6c2d78732d313220636f6c2d736d2d3132223e0a3c703e576974682074686973206170706c69636174696f6e20796f752077696c6c206e6f74206d69737320636f6e74656e7420616e796d6f72652e203c7374726f6e673e436c69636b2c20736176652c2072656164206974207768656e20796f752077616e743c2f7374726f6e673e2e2049742073617665732074686520636f6e74656e7420796f752073656c65637420736f207468617420796f752063616e2072656164206974207768656e20796f7520686176652074696d652e3c2f703e0a3c2f6469763e0a0a3c2f6469763e0a3c64697620636c6173733d22726f77223e0a3c64697620636c6173733d22636f6c2d6c672d3620636f6c2d6d642d313220636f6c2d78732d313220636f6c2d736d2d3132223e0a3c68323e486f7720697420776f726b733c2f68323e0a3c703e5468616e6b7320746f2074686520626f6f6b6d61726b6c6574206f72203c61207469746c653d22446f776e6c6f6164732220687265663d22687474703a2f2f7777772e77616c6c616261672e6f72672f646f776e6c6f6164732f223e74686972642d7061727479206170706c69636174696f6e733c2f613e2c20796f75207361766520616e2061727469636c6520696e20796f7572c2a077616c6c6162616720746f2072656164206974206c617465722e205468656e2c207768656e20796f75206f70656e20796f75722077616c6c616261672c203c7374726f6e673e796f752063616e20636f6d666f727461626c79207265616420796f75722061727469636c65733c2f7374726f6e673e2e3c2f703e0a3c68323e486f7720746f207573652077616c6c616261673c2f68323e0a3c703e5468657265206172652074776f207761797320746f207573652077616c6c616261673a20796f752063616e203c6120687265663d22687474703a2f2f7777772e77616c6c616261672e6f72672f6672657175656e746c792d61736b65642d7175657374696f6e732f23486f775f63616e5f495f696e7374616c6c5f77616c6c616261675f616e645f776861745f6172655f7468655f726571756972656d656e7473223e696e7374616c6c2069743c2f613ec2a06f6e20796f75722077656220736572766572206f7220796f752063616ec2a03c6120687265663d22687474703a2f2f6170702e696e746865706f6368652e636f6d223e63726561746520616e206163636f756e743c2f613ec2a06174204672616d616261672028776520696e7374616c6c20616e642075706772616465c2a077616c6c6162616720666f7220796f75292e3c2f703e0a3c2f6469763e0a0a3c2f6469763e0a', 'hex'), 'UTF8'), 1)"; - $moreQueries[] = "INSERT INTO tags (value) VALUES ('opensource')"; - $moreQueries[] = "INSERT INTO tags_entries (entry_id, tag_id) VALUES (2, 1)"; + $moreQueries[] = "INSERT INTO tags (value) VALUES ('opensource')"; + $moreQueries[] = "INSERT INTO tags_entries (entry_id, tag_id) VALUES (2, 1)"; - $sql_structure = file_get_contents('install/postgres.sql'); - } - - $content = str_replace("define ('STORAGE', 'sqlite');", "define ('STORAGE', '".$_POST['db_engine']."');", $content); - file_put_contents('inc/poche/config.inc.php', $content); - } - - if ($continue) { - - function executeQuery($handle, $sql, $params) { - try - { - $query = $handle->prepare($sql); - $query->execute($params); - return $query->fetchAll(); - } - catch (Exception $e) - { - return FALSE; - } - } - - if ($_POST['db_engine'] != "sqlite") { - // create database structure - $query = $handle->exec($sql_structure); - } - - // Create user - $handle->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); - - $sql = "INSERT INTO users (username, password, name, email) VALUES (?, ?, ?, '')"; - $params = array($username, $salted_password, $username); - $query = executeQuery($handle, $sql, $params); - - $id_user = (int)$handle->lastInsertId('users_id_seq'); - - $sql = 'INSERT INTO users_config ( user_id, name, value ) VALUES (?, ?, ?)'; - $params = array($id_user, 'pager', '10'); - $query = executeQuery($handle, $sql, $params); - - $sql = 'INSERT INTO users_config ( user_id, name, value ) VALUES (?, ?, ?)'; - $params = array($id_user, 'language', 'en_EN.UTF8'); - $query = executeQuery($handle, $sql, $params); - - foreach ($moreQueries as $query) { - executeQuery($handle, $query, array()); - } - - $successes[] = 'wallabag is now installed. You can now access it !'; + $sql_structure = file_get_contents('install/postgres.sql'); } + // create database structure + $query = $handle->exec($sql_structure); + } catch (PDOException $e) { + $errors[] = $e->getMessage(); + $continue = false; + } } } + if ($continue) { + $sql = "INSERT INTO users (username, password, name, email) VALUES (?, ?, ?, '')"; + $params = array($username, $salted_password, $username); + $query = executeQuery($handle, $sql, $params); + + $id_user = (int)$handle->lastInsertId('users_id_seq'); + + $sql = 'INSERT INTO users_config ( user_id, name, value ) VALUES (?, ?, ?)'; + $params = array($id_user, 'pager', '10'); + $query = executeQuery($handle, $sql, $params); + + $sql = 'INSERT INTO users_config ( user_id, name, value ) VALUES (?, ?, ?)'; + $params = array($id_user, 'language', 'en_EN.UTF8'); + $query = executeQuery($handle, $sql, $params); + + foreach ($moreQueries as $query) { + executeQuery($handle, $query, array()); + } + $successes[] = 'wallabag is now installed. You can now access it !'; + + if (!copy('inc/poche/config.inc.default.php', 'inc/poche/config.inc.php')) { + $errors[] = 'Installation aborted, impossible to create inc/poche/config.inc.php file. Maybe you don\'t have write access to create it.'; + } else { + if ($_POST['db_engine'] != 'sqlite') { + $content = str_replace("define ('STORAGE', 'sqlite');", "define ('STORAGE', '".$_POST['db_engine']."');", $content); + file_put_contents('inc/poche/config.inc.php', $content); + } + $content = str_replace("define ('SALT', '');", "define ('SALT', '".$salt."');", $content); + file_put_contents('inc/poche/config.inc.php', $content); + } +} } ?> @@ -368,21 +328,6 @@ cursor: pointer;

        To install wallabag, you just have to fill the following fields. That's all.

        If you need help, you can read the doc: offline documentation and online one (already up-to-date).

        - -
        wallabag needs twig, a template engine (?). Two ways to install it:
        -
          -
        • automatically download and extract vendor.zip into your wallabag folder. -

          - - Be careful, zip extension is not enabled in your PHP configuration. You'll have to unzip vendor.zip manually. - - This method is mainly recommended if you don't have a dedicated server.
        • -
        • use Composer :
          curl -s http://getcomposer.org/installer | php
          -php composer.phar install
        • -
        -
        - -

        Server compatibility test (click to view details) : All good @@ -532,9 +477,22 @@ php composer.phar install - +


        -
        + +
        wallabag needs twig, a template engine (?). Two ways to install it:
        +
          +
        • automatically download and extract vendor.zip into your wallabag folder. +

          + + Be careful, zip extension is not enabled in your PHP configuration. You'll have to unzip vendor.zip manually. + + This method is mainly recommended if you don't have a dedicated server.
        • +
        • use Composer :
          curl -s http://getcomposer.org/installer | php
          +php composer.phar install
        • +
        +
        +
        Technical settings

        diff --git a/install/wallabag_compatibility_test.php b/install/wallabag_compatibility_test.php index 8a0656cf8..1093b2a33 100644 --- a/install/wallabag_compatibility_test.php +++ b/install/wallabag_compatibility_test.php @@ -52,4 +52,36 @@ function isPassing() { return !in_array(false, $status); } +/* Function taken from at http://php.net/manual/en/function.rmdir.php#110489 + * Idea : nbari at dalmp dot com + * Rights unknown + * Here in case of .gitignore files + */ + +function delTree($dir) { + $files = array_diff(scandir($dir), array('.','..')); + foreach ($files as $file) { + (is_dir("$dir/$file")) ? delTree("$dir/$file") : unlink("$dir/$file"); + } + return rmdir($dir); + } + +function generate_salt() { + mt_srand(microtime(true)*100000 + memory_get_usage(true)); + return md5(uniqid(mt_rand(), true)); +} + +function executeQuery($handle, $sql, $params) { + try + { + $query = $handle->prepare($sql); + $query->execute($params); + return $query->fetchAll(); + } + catch (Exception $e) + { + return FALSE; + } +} + ?> \ No newline at end of file From f8100e0d054ef454f299ee815de545b02ae5ca9d Mon Sep 17 00:00:00 2001 From: Julian Oster Date: Tue, 27 Jan 2015 18:05:44 +0100 Subject: [PATCH 31/34] Update german localisation. --- locale/de_DE.utf8/LC_MESSAGES/de_DE.utf8.mo | Bin 10620 -> 16993 bytes locale/de_DE.utf8/LC_MESSAGES/de_DE.utf8.po | 789 ++++++++++---------- 2 files changed, 383 insertions(+), 406 deletions(-) diff --git a/locale/de_DE.utf8/LC_MESSAGES/de_DE.utf8.mo b/locale/de_DE.utf8/LC_MESSAGES/de_DE.utf8.mo index bd18817fbc80bb572c1e7e0808680b94eaac6af7..3add116cc30a5f98dc4dff0aa1eabc1c451c9c56 100644 GIT binary patch literal 16993 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 J9-8OP{{f7&ZIJ)~ literal 10620 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 diff --git a/locale/de_DE.utf8/LC_MESSAGES/de_DE.utf8.po b/locale/de_DE.utf8/LC_MESSAGES/de_DE.utf8.po index 8b82721d9..478010074 100644 --- a/locale/de_DE.utf8/LC_MESSAGES/de_DE.utf8.po +++ b/locale/de_DE.utf8/LC_MESSAGES/de_DE.utf8.po @@ -1,18 +1,26 @@ msgid "" msgstr "" -"Project-Id-Version: Wallabag\n" +"Project-Id-Version: wallabag\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-03-27 13:41+0100\n" +"POT-Creation-Date: 2014-02-25 15:17+0300\n" "PO-Revision-Date: \n" -"Last-Translator: Kevin Meyer \n" +"Last-Translator: Julian Oster \n" "Language-Team: \n" -"Language: de\n" +"Language: de_DE\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 1.6.4\n" +"X-Generator: Poedit 1.7.3\n" "X-Poedit-Basepath: .\n" -"X-Poedit-SearchPath-0: /Users/kevinmeyer/Dropbox/dev_web/wallabag-dev\n" + +msgid "wallabag, a read it later open source system" +msgstr "wallabag, ein \"Read-it-later\"-Open-Source-System" + +msgid "login failed: user doesn't exist" +msgstr "Anmeldung fehlgeschlagen: Benutzer existiert nicht" + +msgid "return home" +msgstr "Auf Startseite zurückkehren" msgid "config" msgstr "Konfiguration" @@ -21,13 +29,19 @@ msgid "Saving articles" msgstr "Artikel speichern" msgid "There are several ways to save an article:" -msgstr "Es gibt viele Methoden um Artikel zu speichern:" +msgstr "Es gibt mehrere Wege, um einen Artikel zu speichern:" msgid "read the documentation" -msgstr "Die Dokumentation lesen" +msgstr "Dokumentation lesen" msgid "download the extension" -msgstr "installiere die Erweiterung" +msgstr "Erweiterung herunterladen" + +msgid "Firefox Add-On" +msgstr "Firefox-Addon" + +msgid "Chrome Extension" +msgstr "Chrome-Erweiterung" msgid "via F-Droid" msgstr "via F-Droid" @@ -39,16 +53,16 @@ msgid "via Google Play" msgstr "via Google Play" msgid "download the application" -msgstr "lade die App" +msgstr "App herunterladen" msgid "By filling this field" -msgstr "Durch Ausfüllen dieses Feldes" +msgstr "Durch das Ausfüllen dieses Feldes" msgid "bag it!" msgstr "bag it!" msgid "Bookmarklet: drag & drop this link to your bookmarks bar" -msgstr "Bookmarklet: Ziehe diesen Link in deine Lesezeichen-Leiste" +msgstr "Bookmarklet: Ziehe diesen Link in deine Lesezeichen" msgid "Upgrading wallabag" msgstr "wallabag aktualisieren" @@ -57,58 +71,46 @@ msgid "Installed version" msgstr "Installierte Version" msgid "Latest stable version" -msgstr "Neuste stabile Version" +msgstr "Letzte stabile Version" msgid "A more recent stable version is available." -msgstr "Eine neuere stabile Version ist verfügbar." +msgstr "Eine neuere Version ist verfügbar." msgid "You are up to date." -msgstr "Du bist auf den neuesten Stand." - -msgid "Last check:" -msgstr "Zuletzt geprüft:" +msgstr "Du bist auf dem aktuellsten Stand." msgid "Latest dev version" -msgstr "Neuste Entwicklungsversion" +msgstr "Letzte Entwickler-Version" msgid "A more recent development version is available." -msgstr "Eine neuere Entwicklungsversion ist verfügbar." +msgstr "Eine neuere Entwickler-Version ist verfügbar." msgid "You can clear cache to check the latest release." -msgstr "Leere den Cache um die neueste Version zu prüfen." +msgstr "Du kannst den Cache leeren, um nach neueren Versionen zu suchen." msgid "Feeds" msgstr "Feeds" -msgid "" -"Your feed token is currently empty and must first be generated to enable " -"feeds. Click here to generate it." -msgstr "" -"Dein Feed Token ist noch nicht vorhanden und muss zunächst generiert werden, " -"um deine Feeds zu aktivieren. Klicke hier um ihn zu generieren." +msgid "Your feed token is currently empty and must first be generated to enable feeds. Click here to generate it." +msgstr "Dein Feed-Token ist momentan leer und muss generiert werden, um die Feeds zu aktivieren. Klicke hier, um ihn zu erstellen." msgid "Unread feed" -msgstr "Ungelesen Feed" +msgstr "Feed für Ungelesenes" msgid "Favorites feed" -msgstr "Favoriten Feed" +msgstr "Feed für Favoriten" msgid "Archive feed" -msgstr "Archiv Feed" +msgstr "Archiv-Feed" msgid "Your token:" msgstr "Dein Token:" msgid "Your user id:" -msgstr "Deine User ID:" +msgstr "Deine Benutzer-ID:" -msgid "" -"You can regenerate your token: generate!" -"." -msgstr "" -"Hier kannst du dein Token erzeugen: Generieren!." +msgid "You can regenerate your token: generate!." +msgstr "Du kannst deinen Token regenerieren: generieren!." msgid "Change your theme" msgstr "Theme ändern" @@ -138,76 +140,58 @@ msgid "Repeat your new password:" msgstr "Neues Passwort wiederholen:" msgid "Import" -msgstr "Import" +msgstr "Importieren" -msgid "" -"Importing from other services can be quite long, and webservers default " -"configuration often prevents long scripts execution time, so it must be done " -"in multiple parts." +msgid "You can import your Pocket, Readability, Instapaper, Wallabag or any data in appropriate json or html format." +msgstr "Du kannst aus Pocket, Readability, Instapaper, wallabag oder einer beliebigen Datei in angebrachtem JSON- oder HTML-Format importieren." + +msgid "Please execute the import script locally as it can take a very long time." +msgstr "Führe das Import-Skript lokal aus, da der Import sehr lange dauern kann." + +msgid "Please select export file on your computer and press \"Import\" button below. Wallabag will parse your file, insert all URLs and start fetching of articles if required." msgstr "" -"Der Import von anderen Diensten kann sehr lange dauern. Deswegen bricht der " -"Webserver diesen in vielen Konfigurationen ab. Daher muss der Import in " -"mehrere Teile aufgeteilt werden." +"Wähle die Export-Datei auf deinem Computer aus und drücke den \"Import\"-Button unten. Wallabag wird deine Datei durchsuchen, alle URLs in der Datenbank speichern und die Artikel " +"herunterladen, sofern dies erforderlich ist." -msgid "First, select the export file on your computer and upload it." -msgstr "Wähle eine Datei von deinem Computer aus und lade sie hoch." +msgid "You can click here to fetch content for articles with no content." +msgstr "Du kannst hier klicken, um den Inhalt für Artikel ohne Inhalt herunterzuladen." -msgid "File:" -msgstr "Datei:" +msgid "More info in the official documentation:" +msgstr "Mehr Infos in der offiziellen Dokumentation:" -msgid "Upload" -msgstr "Hochladen" - -msgid "Then, click on the right link below." -msgstr "Klicke dann unten auf den entsprechenden Link." +msgid "(?)" +msgstr "(?)" msgid "Import from Pocket" -msgstr "Import aus Pocket" +msgstr "Aus Pocket importieren" #, php-format -msgid "(after uploaded %s file)" -msgstr "(nach Upload der Datei %s)" +msgid "(you must have a %s file on your server)" +msgstr "(du solltest eine %s Datei auf deinem Server haben)" msgid "Import from Readability" -msgstr "Import aus Readability" +msgstr "Aus Readability importieren" msgid "Import from Instapaper" -msgstr "Import aus Instapaper" +msgstr "Aus Instapaper importieren" msgid "Import from wallabag" -msgstr "Import aus Readability" - -msgid "" -"3. Your feed token is currently empty and must first be generated to fetch " -"content. Click here to generate it." -msgstr "" -"3. Dein Feed Token ist noch nicht vorhanden und muss zunächst generiert " -"werden, um Inhalt abrufen zu können. Klicke hier um ihn zu generieren." - -msgid "Finally, you have to fetch content for imported items." -msgstr "Jetzt musst du den Inhalt der importierten Artikel abrufen." - -msgid "Click here" -msgstr "Klicke hier" - -msgid "to fetch content for 10 articles" -msgstr "um den Inhalt von 10 Artikeln abzurufen" - -msgid "" -"If you have console access to your server, you can also create a cron task:" -msgstr "" -"Wenn du Konsolenzugang zu deinem Server hast kannst du auch einen cron " -"erstellen:" +msgstr "Aus wallabag importieren" msgid "Export your wallabag data" -msgstr "Exportieren deine wallabag Daten" +msgstr "Deine wallabag-Daten exportieren" + +msgid "Click here" +msgstr "Hier klicken, " msgid "to download your database." -msgstr "um deine Datenbank herunterzuladen" +msgstr "um die Datenbank herunterzuladen." msgid "to export your wallabag data." -msgstr "um deine Daten aus wallabag zu exportieren." +msgstr "um die wallabag-Daten zu exportieren." + +msgid "Export JSON" +msgstr "JSON exportieren" msgid "Cache" msgstr "Cache" @@ -215,127 +199,289 @@ msgstr "Cache" msgid "to delete cache." msgstr "um den Cache zu löschen." -msgid "Tags" -msgstr "Tags" +msgid "Delete Cache" +msgstr "Cache löschen, " + +msgid "You can enter multiple tags, separated by commas." +msgstr "Du kannst mehrere Schlagworte, getrennt von einem Komma, hinzufügen." + +msgid "Add tags:" +msgstr "Schlagworte hinzufügen:" + +msgid "no tags" +msgstr "keine schlagworte" + +msgid "The tag has been applied successfully" +msgstr "Das Schlagwort wurde erfolgreich übernommen." + +msgid "interview" +msgstr "interview" + +msgid "editorial" +msgstr "editorial" + +msgid "video" +msgstr "video" + +msgid "return to article" +msgstr "zum artikel zurückkehren" + +msgid "plop" +msgstr "plop" + +msgid "You can check your configuration here." +msgstr "Du kannst deine Konfiguration hier überprüfen." + +msgid "favoris" +msgstr "Favoriten" + +msgid "archive" +msgstr "archiv" + +msgid "unread" +msgstr "ungelesen" msgid "by date asc" -msgstr "nach Datum aufsteigend" +msgstr "nach Datum, aufsteigend" msgid "by date" msgstr "nach Datum" msgid "by date desc" -msgstr "nach Datum absteigend" +msgstr "nach Datum, absteigend" msgid "by title asc" -msgstr "nach Titel aufsteigend" +msgstr "nach Titel, aufsteigend" msgid "by title" msgstr "nach Titel" msgid "by title desc" -msgstr "nach Titel absteigend" - -#, fuzzy -msgid "toggle view mode" -msgstr "Favorit" - -msgid "home" -msgstr "Start" - -msgid "favorites" -msgstr "Favoriten" - -msgid "archive" -msgstr "Archiv" - -msgid "tags" -msgstr "Tags" - -msgid "save a link" -msgstr "Speichere einen Link" - -msgid "search" -msgstr "Suche" - -msgid "logout" -msgstr "Logout" - -msgid "return home" -msgstr "Zurück zum Start" - -#, fuzzy -msgid "Search" -msgstr "Archiv" - -msgid "powered by" -msgstr "bereitgestellt von" - -msgid "debug mode is on so cache is off." -msgstr "Debug Modus ist aktiviert, das Caching ist somit deaktiviert" - -msgid "your wallabag version:" -msgstr "Deine wallabag Version" - -msgid "storage:" -msgstr "Speicher:" - -msgid "Save a link" -msgstr "Speichere einen Link" - -msgid "save link!" -msgstr "Link speichern!" - -msgid "unread" -msgstr "ungelesen" +msgstr "nach Titel, absteigend" msgid "Tag" -msgstr "Tag" +msgstr "Schlagwort" msgid "No articles found." msgstr "Keine Artikel gefunden." -msgid "estimated reading time:" -msgstr "geschätzte Lesezeit:" - -msgid "estimated reading time :" -msgstr "geschätzte Lesezeit:" - msgid "Toggle mark as read" -msgstr "Als gelesen markieren" +msgstr "Als gelesen/ungelesen markieren" msgid "toggle favorite" -msgstr "Favorit" +msgstr "favorisieren" msgid "delete" -msgstr "Löschen" +msgstr "löschen" msgid "original" -msgstr "Original" +msgstr "original" -msgid "Mark all the entries as read" -msgstr "Markiere alle als gelesen" +msgid "estimated reading time:" +msgstr "Geschätzte Lesezeit:" + +msgid "mark all the entries as read" +msgstr "Alle Einträge als gelesen markieren" msgid "results" msgstr "Ergebnisse" -msgid "Uh, there is a problem with the cron." -msgstr "Oh, es gab ein Problem mit dem cron." +msgid "installation" +msgstr "installation" + +msgid "install your wallabag" +msgstr "deine wallabag installieren" + +msgid "wallabag is still not installed. Please fill the below form to install it. Don't hesitate to read the documentation on wallabag website." +msgstr "" +"wallabag ist noch nicht installiert. Fülle das untenstehende Formular aus, um wallabag zu installieren. Scheue dich nicht davor, die Dokumentation " +"auf der wallabag-Webseite zur Hilfe zu ziehen." + +msgid "Login" +msgstr "Anmelden" + +msgid "Repeat your password" +msgstr "Passwort wiederholen" + +msgid "Install" +msgstr "Installieren" + +msgid "login to your wallabag" +msgstr "Melde dich in deiner wallabag an" + +msgid "Login to wallabag" +msgstr "In wallabag anmelden" + +msgid "you are in demo mode, some features may be disabled." +msgstr "Du bist im Demo-Modus, einige Features sind möglicherweise deaktiviert." + +msgid "Username" +msgstr "Benutzername" + +msgid "Stay signed in" +msgstr "Angemeldet bleiben" + +msgid "(Do not check on public computers)" +msgstr "(nicht auf öffentlichen Computern ankreuzen)" + +msgid "Sign in" +msgstr "Anmelden" + +msgid "favorites" +msgstr "favoriten" + +msgid "estimated reading time :" +msgstr "Geschätzte Lesezeit:" + +msgid "Mark all the entries as read" +msgstr "Alle Einträge als gelesen markieren" + +msgid "Return home" +msgstr "Zur Startseite zurückkehren" + +msgid "Back to top" +msgstr "Nach oben scrollen" + +msgid "Mark as read" +msgstr "Als gelesen markieren" + +msgid "Favorite" +msgstr "Favorisieren" + +msgid "Toggle favorite" +msgstr "favorisieren" + +msgid "Delete" +msgstr "Löschen" + +msgid "Tweet" +msgstr "Twittern" + +msgid "Email" +msgstr "Email" + +msgid "shaarli" +msgstr "shaarli" + +msgid "flattr" +msgstr "flattr" + +msgid "Does this article appear wrong?" +msgstr "Erscheint dieser Artikel nicht richtig?" + +msgid "tags:" +msgstr "schlagworte:" + +msgid "Edit tags" +msgstr "Schlagworte bearbeiten" + +msgid "save link!" +msgstr "link speichern!" + +msgid "home" +msgstr "start" + +msgid "tags" +msgstr "schlagworte" + +msgid "logout" +msgstr "abmelden" + +msgid "powered by" +msgstr "Angetrieben von" + +msgid "debug mode is on so cache is off." +msgstr "Der Debug-Modus ist aktiviert, also ist der Cache deaktiviert." + +msgid "your wallabag version:" +msgstr "Deine wallabag-Version:" + +msgid "storage:" +msgstr "speicher:" + +msgid "save a link" +msgstr "einen link speichern" + +msgid "back to home" +msgstr "zurück zur startseite" + +msgid "toggle mark as read" +msgstr "als gelesen/ungelesen markieren" + +msgid "tweet" +msgstr "tweet" + +msgid "email" +msgstr "email" + +msgid "this article appears wrong?" +msgstr "dieser artikel erscheint falsch?" + +msgid "No link available here!" +msgstr "Kein Link verfügbar!" + +msgid "Poching a link" +msgstr "Link speichern" + +msgid "by filling this field" +msgstr "mit dem Ausfüllen dieses Feldes" + +msgid "bookmarklet: drag & drop this link to your bookmarks bar" +msgstr "Bookmarklet: Drag & drop diesen Link in deine Lesezeichen" + +msgid "Drag & drop this link to your bookmarks bar:" +msgstr "Drag & drop diesen Link in deine Lesezeichen:" + +msgid "your version" +msgstr "deine Version" + +msgid "latest stable version" +msgstr "letzte stabile Version" + +msgid "a more recent stable version is available." +msgstr "Eine aktuellere Version ist verfügbar." + +msgid "you are up to date." +msgstr "Du bist auf dem aktuellsten Stand." + +msgid "latest dev version" +msgstr "Letzte Entwickler-Version" + +msgid "a more recent development version is available." +msgstr "Eine neuere Entwickler-Version ist verfügbar." + +msgid "Please execute the import script locally, it can take a very long time." +msgstr "Führe das Import-Skript lokal aus, da der Import sehr lange dauern kann." + +msgid "More infos in the official doc:" +msgstr "Mehr Informationen in der offiziellen Dokumentation:" + +msgid "import from Pocket" +msgstr "Aus Pocket importieren" + +msgid "import from Readability" +msgstr "Aus Readability importieren" + +msgid "import from Instapaper" +msgstr "Aus Instapaper importieren" + +msgid "Tags" +msgstr "Schlagworte" msgid "Untitled" -msgstr "Ohne Titel" +msgstr "Untitled" msgid "the link has been added successfully" -msgstr "Speichern des Links erfolgreich" +msgstr "Der Link wurde erfolgreich hinzugefügt" msgid "error during insertion : the link wasn't added" -msgstr "Fehler beim Einfügen: Der Link wurde nicht hinzugefügt" +msgstr "Fehler während des Imports: Der Link wurde nicht hinzugefügt." msgid "the link has been deleted successfully" -msgstr "Löschen des Links erfolgreich" +msgstr "Der Link wurde erfolgreich gelöscht" msgid "the link wasn't deleted" -msgstr "Der Link wurde nicht entfernt" +msgstr "Der Link wurde nicht gelöscht." msgid "Article not found!" msgstr "Artikel nicht gefunden!" @@ -347,24 +493,22 @@ msgid "next" msgstr "nächste" msgid "in demo mode, you can't update your password" -msgstr "im Demo-Modus kann das Passwort nicht geändert werden" +msgstr "Im Demo-Modus kannst du as Kennwort nicht aktualisieren." msgid "your password has been updated" -msgstr "Dein Passwort wurde geändert" +msgstr "Dein Passwort wurde aktualisiert" -msgid "" -"the two fields have to be filled & the password must be the same in the two " -"fields" -msgstr "Beide Felder müssen mit selbem Inhalt ausgefüllt sein" +msgid "the two fields have to be filled & the password must be the same in the two fields" +msgstr "Beide Felder müssen ausgefüllt sein und das gleiche Passwort beinhalten" msgid "still using the \"" msgstr "nutze immernoch die \"" msgid "that theme does not seem to be installed" -msgstr "dieses Theme scheint nicht installiert zu sein" +msgstr "Dieses Theme scheint nicht installiert zu sein." msgid "you have changed your theme preferences" -msgstr "Du hast deine Theme Einstellungen geändert" +msgstr "Du hast deine Theme-Einstellungen geändert" msgid "that language does not seem to be installed" msgstr "Diese Sprache scheint nicht installiert zu sein" @@ -373,286 +517,119 @@ msgid "you have changed your language preferences" msgstr "Du hast deine Spracheinstellungen geändert" msgid "login failed: you have to fill all fields" -msgstr "Anmeldung fehlgeschlagen: Alle Felder müssen ausgefüllt werden" +msgstr "Anmeldung fehlgeschlagen: Du musst alle Felder ausfüllen" msgid "welcome to your wallabag" -msgstr "Willkommen bei deiner wallabag" +msgstr "Willkommen in deiner wallabag" msgid "login failed: bad login or password" -msgstr "Anmeldung fehlgeschlagen: Falscher Benutzername oder Passwort" +msgstr "Anmeldung fehlgeschlagen: Falscher Benutzername oder falsches Passwort" -msgid "" -"import from instapaper completed. You have to execute the cron to fetch " -"content." -msgstr "" -"Import aus Instapaper vollständig. Führe den cronjob aus um den Inhalt " -"abzurufen." +msgid "import from instapaper completed" +msgstr "Import aus Instapaper abgeschlossen" -msgid "" -"import from pocket completed. You have to execute the cron to fetch content." -msgstr "" -"Import aus Pocket vollständig. Führe den cronjob aus um den Inhalt abzurufen." +msgid "import from pocket completed" +msgstr "Import aus Pocket abgeschlossen" -msgid "" -"import from Readability completed. You have to execute the cron to fetch " -"content." -msgstr "" -"Import aus Readability vollständig. Führe den cronjob aus um den Inhalt " -"abzurufen." +msgid "import from Readability completed. " +msgstr "Import aus Readability abgeschlossen." -msgid "" -"import from Poche completed. You have to execute the cron to fetch content." -msgstr "" -"Import aus Poche vollständig. Führe den cronjob aus um den Inhalt abzurufen." +msgid "import from Poche completed. " +msgstr "Import aus wallabag abgeschlossen." msgid "Unknown import provider." -msgstr "Unbekannter Import Anbieter." +msgstr "Unbekannter Import-Provider." + +msgid "Incomplete inc/poche/define.inc.php file, please define \"" +msgstr "Die Datei /inc/poche/define.inc.php ist unvollständig, bitte definiere \"" msgid "Could not find required \"" msgstr "Nicht gefunden: \"" -msgid "File uploaded. You can now execute import." -msgstr "Datei hochgeladen. Du kannst nun importieren." - -msgid "Error while importing file. Do you have access to upload it?" -msgstr "Fehler beim Importieren. Hast du das Recht zum Hochladen?" - -msgid "User with this id (" -msgstr "Nutzer mit dieser id (" - msgid "Uh, there is a problem while generating feeds." -msgstr "Oh, es gab ein Problem beim Erstellen des Feeds." +msgstr "Oh, es gibt ein Problem bei dem Generieren der Feeds." msgid "Cache deleted." -msgstr "Cache gelöscht" +msgstr "Cache geleert." msgid "Oops, it seems you don't have PHP 5." -msgstr "Oops, es scheint als würde PHP 5 fehlen." +msgstr "Ups, es sieht so aus, als ob du nicht PHP 5 hast." -msgid "wallabag, a read it later open source system" -msgstr "wallabag, ein Später-Lesen Open Source System" +msgid "Add user" +msgstr "Benutzer hinzufügen" -msgid "login failed: user doesn't exist" -msgstr "Anmeldung fehlgeschlagen: Benutzer existiert nicht" +msgid "Add a new user :" +msgstr "Neuen Benutzer hinzufügen:" -#~ msgid "You can enter multiple tags, separated by commas." -#~ msgstr "Du kannst mehrere Tags, durch Kommata getrennt, eingeben." +msgid "Login for new user" +msgstr "Benutzername des neuen Benutzers" -#~ msgid "return to article" -#~ msgstr "zurück zum Artikel" +msgid "Password for new user" +msgstr "Passwort des neuen Benutzers" -#, fuzzy -#~ msgid "favoris" -#~ msgstr "Favoriten" +msgid "Email for new user (not required)" +msgstr "E-Mail-Adresse des neuen Benutzers (nicht erforderlich)" -#~ msgid "mark all the entries as read" -#~ msgstr "Markiere alle als gelesen" +msgid "Send" +msgstr "Senden" -#~ msgid "Back to top" -#~ msgstr "Nach Oben" +msgid "Delete account" +msgstr "Account löschen" -#~ msgid "Mark as read" -#~ msgstr "Als gelesen markieren" +msgid "You can delete your account by entering your password and validating." +msgstr "Du kannst deinen Account löschen, indem du dein Kennwort eintippst und validierst." -#~ msgid "Favorite" -#~ msgstr "Favoriten" +msgid "Be careful, data will be erased forever (that is a very long time)." +msgstr "Pass auf, die Daten werden für immer gelöscht werden (eine sehr lange Zeit)." -#~ msgid "Toggle favorite" -#~ msgstr "Favorit" +msgid "Type here your password" +msgstr "Kennwort hier eintippen" -#~ msgid "Delete" -#~ msgstr "Löschen" +msgid "You are the only user, you cannot delete your own account." +msgstr "Du kannst deinen Account nicht löschen, weil du der einzige Benutzer bist." -#~ msgid "Tweet" -#~ msgstr "Twittern" +msgid "To completely remove wallabag, delete the wallabag folder on your web server (and eventual databases)." +msgstr "Um wallabag komplett zu entfernen, lösche den wallabag-Ordner und die Datenbank(en) von deinem Webserver." -#~ msgid "Email" -#~ msgstr "per E-Mail senden" +msgid "Enter your search here" +msgstr "Suchbegriff hier eintippen" -#~ msgid "shaarli" -#~ msgstr "Shaarli" +msgid "Tag these results as" +msgstr "Diese Ergebnisse verschlagworten mit" -#~ msgid "flattr" -#~ msgstr "flattr" +# ebook +msgid "Fancy an E-Book ?" +msgstr "Willst du ein E-Book?" -#~ msgid "Does this article appear wrong?" -#~ msgstr "Erscheint dieser Artikel falsch?" +msgid "Click on this link to get all your articles in one ebook (ePub 3 format)." +msgstr "Klicke auf diesen Link, um alle Artikel in ein E-Book (EPUB 3-Format) zu exportieren." -#~ msgid "Edit tags" -#~ msgstr "Tags bearbeiten" +msgid "This can take a while and can even fail if you have too many articles, depending on your server configuration." +msgstr "Dies kann eine Weile dauern oder sogar fehlschlagen, wenn du zu viele Artikel hast, abhängig von deiner Server-Konfiguration." -#~ msgid "Start typing for auto complete." -#~ msgstr "Beginne zu tippen für die Autovervollständigung." +msgid "Download the articles from this tag in an epub" +msgstr "Die Artikel von diesem Schlagwort als EPUB herunterladen" -#~ msgid "Return home" -#~ msgstr "Zurück zum Start" +msgid "Download the articles from this search in an epub" +msgstr "Alle Artikel aus dieser Suche als EPUB herunterladen" -#~ msgid "tags:" -#~ msgstr "Tags:" - -#~ msgid "login to your wallabag" -#~ msgstr "Bei wallabag anmelden" - -#~ msgid "you are in demo mode, some features may be disabled." -#~ msgstr "" -#~ "Du befindest dich im Demomodus, einige Funktionen könnten deaktiviert " -#~ "sein." - -#~ msgid "Login" -#~ msgstr "Benutzername" - -#~ msgid "Stay signed in" -#~ msgstr "Angemeldet bleiben" - -#~ msgid "(Do not check on public computers)" -#~ msgstr "(nicht auf einem öffentlichen Computer anhaken)" - -#~ msgid "plop" -#~ msgstr "plop" - -#~ msgid "Login to wallabag" -#~ msgstr "Bei wallabag anmelden" - -#~ msgid "Username" -#~ msgstr "Benutzername" - -#~ msgid "Sign in" -#~ msgstr "Einloggen" - -#~ msgid "Enter your search here" -#~ msgstr "Gib hier deine Suchanfrage ein" - -#~ msgid "installation" -#~ msgstr "Installieren" - -#~ msgid "install your wallabag" -#~ msgstr "Installiere deine wallabag" - -#~ msgid "" -#~ "wallabag is still not installed. Please fill the below form to install " -#~ "it. Don't hesitate to read the " -#~ "documentation on wallabag website." -#~ msgstr "" -#~ "wallabag ist noch nicht installiert. Bitte fülle die Felder unten aus, um " -#~ "die Installation durchzuführen. Zögere nicht, die Dokumentation auf der Website von wallabag zu lesen, " -#~ "falls du Probleme haben solltest." - -#~ msgid "Repeat your password" -#~ msgstr "Wiederhole dein Passwort" - -#~ msgid "Install" -#~ msgstr "Installieren" - -#~ msgid "No link available here!" -#~ msgstr "Kein Link verfügbar!" - -#~ msgid "toggle mark as read" -#~ msgstr "Als gelesen markieren" - -#~ msgid "" -#~ "You can check your " -#~ "configuration here." -#~ msgstr "" -#~ "Du kannst deine Konfiguration hier testen." - -#~ msgid "back to home" -#~ msgstr "züruck zur Hauptseite" - -#~ msgid "tweet" -#~ msgstr "Twittern" - -#~ msgid "email" -#~ msgstr "senden per E-Mail" - -#~ msgid "this article appears wrong?" -#~ msgstr "dieser Artikel erscheint falsch?" - -#~ msgid "Poching a link" -#~ msgstr "Poche einen Link" - -#~ msgid "by filling this field" -#~ msgstr "durch das ausfüllen dieses Feldes:" - -#~ msgid "bookmarklet: drag & drop this link to your bookmarks bar" -#~ msgstr "Bookmarklet: Ziehe diesen Link in deine Lesezeichen-Leiste" - -#~ msgid "your version" -#~ msgstr "Deine Version" - -#~ msgid "latest stable version" -#~ msgstr "Neuste stabile Version" - -#~ msgid "a more recent stable version is available." -#~ msgstr "Eine neuere stabile Version ist verfügbar." - -#~ msgid "you are up to date." -#~ msgstr "Du bist auf den neuesten Stand." - -#~ msgid "latest dev version" -#~ msgstr "Neuste Entwicklungsversion" - -#~ msgid "a more recent development version is available." -#~ msgstr "Eine neuere Entwicklungsversion ist verfügbar." - -#~ msgid "" -#~ "Please execute the import script locally, it can take a very long time." -#~ msgstr "" -#~ "Bitte führe das Import Script lokal aus, dies kann eine Weile dauern." - -#~ msgid "More infos in the official doc:" -#~ msgstr "Mehr Informationen in der offiziellen Dokumentation:" - -#~ msgid "import from Pocket" -#~ msgstr "Import aus Pocket" - -#~ msgid "(you must have a %s file on your server)" -#~ msgstr "(du brauchst eine %s Datei auf deinem Server)" - -#~ msgid "import from Readability" -#~ msgstr "Import aus Readability" - -#~ msgid "import from Instapaper" -#~ msgstr "Import aus Instapaper" - -#~ msgid "You can also create a cron task:" -#~ msgstr "Du kannst auch einen cronjob anlegen:" - -#~ msgid "" -#~ "Please execute the import script locally as it can take a very long time." -#~ msgstr "" -#~ "Bitte führe das Import Script lokal aus, da dies eine Weile dauern kann." - -#~ msgid "More info in the official documentation:" -#~ msgstr "Mehr Informationen in der offiziellen Dokumentation:" - -#~ msgid "import from instapaper completed" -#~ msgstr "Import aus Instapaper erfolgreich" - -#~ msgid "import from pocket completed" -#~ msgstr "Import aus Pocket erfolgreich" - -#~ msgid "import from Poche completed. " -#~ msgstr "Import aus Poche erfolgreich" - -#~ msgid "Incomplete inc/poche/define.inc.php file, please define \"" -#~ msgstr "Unvollständige inc/poche/define.inc.php Datei, bitte setze \"" +msgid "Download the articles from this category in an epub" +msgstr "Alle Artikel aus dieser Kategorie als EPUB herunterladen" #~ msgid "poche it!" -#~ msgstr "Poche es!" +#~ msgstr "poche it!" #~ msgid "Updating poche" -#~ msgstr "Poche aktualisieren" +#~ msgstr "Updating poche" #~ msgid "create an issue" -#~ msgstr "ein Ticket erstellen" +#~ msgstr "create an issue" #~ msgid "or" -#~ msgstr "oder" +#~ msgstr "or" #~ msgid "contact us by mail" -#~ msgstr "kontaktieren Sie uns per E-Mail" +#~ msgstr "contact us by mail" #~ msgid "your poche version:" -#~ msgstr "Deine Poche Version" +#~ msgstr "your poche version:" From 22f19b23a6e9400b5776a9a7f0eedb9eb1b5362e Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Sat, 31 Jan 2015 23:35:45 +0100 Subject: [PATCH 32/34] view improvements & check if at least one pdo driver is available --- install/index.php | 60 ++++++++++++++++++------- install/wallabag_compatibility_test.php | 3 +- 2 files changed, 46 insertions(+), 17 deletions(-) diff --git a/install/index.php b/install/index.php index 77b83c36a..54f7f7f2a 100755 --- a/install/index.php +++ b/install/index.php @@ -275,6 +275,27 @@ background-color:#FF9500; .detail { cursor: pointer; } +.compatibity_result { + margin: auto; + max-width: 300px; + min-height: 50px; + line-height: 50px; + text-align: center; +} + +h2, legend { + font-size: 30px; + text-transform: uppercase; + font-family: "PT Sans",sans-serif; +} + +legend:after { + content: ""; + height: 4px; + width: 70px; + background-color: #000; + display: block; +} @@ -328,14 +349,16 @@ cursor: pointer;

        To install wallabag, you just have to fill the following fields. That's all.

        If you need help, you can read the doc: offline documentation and online one (already up-to-date).

        -

        Server compatibility test (click to view details) : - All good - - Some problems, but it's OK ! - - Bad news : you can't run wallabag -

        - +
        +

        Server compatibility test

        + +
        All good
        + +
        Some problems, but it's OK !
        + +
        Bad news : you can't run wallabag
        + +
        @@ -363,6 +386,12 @@ cursor: pointer; Enabled' : 'Disabled'; ?> PDO: You have PDO support enabled.' : 'PDO: Your PHP installation doesn\'t support PHP PDO. ' . $status['app_name'] . ' will not work here.' ?> + + PDO Drivers + One of the PDO drivers must be installed + One driver is enabled' : 'No driver available'; ?> + PDO: You have at least one PDO driver installed.' : 'PDO Drivers: Your PHP installation doesn\'t have any PDO driver installed. ' . $status['app_name'] . ' will not work here.' ?> + XML Enabled @@ -453,8 +482,8 @@ cursor: pointer; +
        -
        @@ -472,12 +501,11 @@ cursor: pointer;
        -
        -

        This compatibility test has been borrowed (and slightly adapted by fivefilters.org) from the one supplied by SimplePie.org.

        +
        +

        This compatibility test has been borrowed (and slightly adapted by fivefilters.org) from the one supplied by SimplePie.org.

        +
        +
        - -
        -
        wallabag needs twig, a template engine (?). Two ways to install it:
        @@ -488,13 +516,13 @@ cursor: pointer; Be careful, zip extension is not enabled in your PHP configuration. You'll have to unzip vendor.zip manually. This method is mainly recommended if you don't have a dedicated server. -
      • use Composer :
        curl -s http://getcomposer.org/installer | php
        +                        
      • use Composer in your wallabag folder :
        curl -s http://getcomposer.org/installer | php
         php composer.phar install
      - Technical settings + Database settings

      Database engine:

        diff --git a/install/wallabag_compatibility_test.php b/install/wallabag_compatibility_test.php index 1093b2a33..3b465851a 100644 --- a/install/wallabag_compatibility_test.php +++ b/install/wallabag_compatibility_test.php @@ -26,6 +26,7 @@ $allow_url_fopen_ok = (bool)ini_get('allow_url_fopen'); $filter_ok = extension_loaded('filter'); $gettext_ok = function_exists("gettext"); $gd_ok = extension_loaded('gd'); +$pdo_drivers_passing = extension_loaded('pdo_sqlite') || extension_loaded('pdo_mysql') || extension_loaded('pdo_pgsql'); if (extension_loaded('xmlreader')) { $xml_ok = true; @@ -38,7 +39,7 @@ if (extension_loaded('xmlreader')) { $xml_ok = false; } -$status = array('app_name' => $app_name, 'php' => $php_ok, 'pdo' => $pdo_ok, 'xml' => $xml_ok, 'pcre' => $pcre_ok, 'zlib' => $zlib_ok, 'mbstring' => $mbstring_ok, 'dom' => $dom_ok, 'iconv' => $iconv_ok, 'tidy' => $tidy_ok, 'curl' => $curl_ok, 'parse_ini' => $parse_ini_ok, 'parallel' => $parallel_ok, 'allow_url_fopen' => $allow_url_fopen_ok, 'filter' => $filter_ok, 'gettext' => $gettext_ok, 'gd' => $gd_ok); +$status = array('app_name' => $app_name, 'php' => $php_ok, 'pdo' => $pdo_ok, 'pdo_drivers_passing' => $pdo_drivers_passing, 'xml' => $xml_ok, 'pcre' => $pcre_ok, 'zlib' => $zlib_ok, 'mbstring' => $mbstring_ok, 'dom' => $dom_ok, 'iconv' => $iconv_ok, 'tidy' => $tidy_ok, 'curl' => $curl_ok, 'parse_ini' => $parse_ini_ok, 'parallel' => $parallel_ok, 'allow_url_fopen' => $allow_url_fopen_ok, 'filter' => $filter_ok, 'gettext' => $gettext_ok, 'gd' => $gd_ok); return $status; } From dd0d7ad9a18cce6424442ac37340ded039f5e0fb Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Sat, 31 Jan 2015 23:44:20 +0100 Subject: [PATCH 33/34] add informations on databases systems --- install/index.php | 43 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/install/index.php b/install/index.php index 77b83c36a..73c594cdc 100755 --- a/install/index.php +++ b/install/index.php @@ -275,6 +275,19 @@ background-color:#FF9500; .detail { cursor: pointer; } +.descriptions { + margin-left: 10%; + position: relative; + top: 50%; +} +.database_inputs { + float: left; + width: 50% +} +.database_info { + width: 100%; + overflow: auto; +} @@ -453,6 +466,7 @@ cursor: pointer; + Close details
        @@ -493,7 +507,8 @@ php composer.phar install
      -
      +
      +
      Technical settings

      Database engine: @@ -530,8 +545,20 @@ php composer.phar install

  • +
    +
    + SQLite is the most simple database system of all three. It is therefore recommended for people who don't want or know how to configure other database systems. +
    +
    + MySQL is one of the most popular database systems. It comes with most shared hosting plans. +
    +
    + PostgreSQL. If you want it, you already know why you want it. +
    +
    +
    -
    +
    User settings

    @@ -553,7 +580,10 @@ php composer.phar install