aboutsummaryrefslogtreecommitdiffhomepage
path: root/inc/poche
diff options
context:
space:
mode:
authorNicolas Lœuillet <nicolas@loeuillet.org>2014-05-29 18:54:06 +0200
committerNicolas Lœuillet <nicolas@loeuillet.org>2014-05-29 18:54:06 +0200
commita9f5e572dde4f986a498d2fbe92a38a1b22f9595 (patch)
tree80b5bfc9836ae92cc4929a4d72ae0b2730e568bc /inc/poche
parent96834a47b09985e1c82b82857fc108f20e8b8f2b (diff)
parent8038b38802769031e050c753fc0a388a2276629e (diff)
downloadwallabag-a9f5e572dde4f986a498d2fbe92a38a1b22f9595.tar.gz
wallabag-a9f5e572dde4f986a498d2fbe92a38a1b22f9595.tar.zst
wallabag-a9f5e572dde4f986a498d2fbe92a38a1b22f9595.zip
Merge pull request #712 from wallabag/dev1.7.0
1.7, call me "Premium version"
Diffstat (limited to 'inc/poche')
-rwxr-xr-xinc/poche/Database.class.php60
-rwxr-xr-xinc/poche/Poche.class.php289
-rwxr-xr-xinc/poche/Tools.class.php4
-rwxr-xr-xinc/poche/config.inc.default.php64
-rwxr-xr-xinc/poche/config.inc.php.new59
-rwxr-xr-x[-rw-r--r--]inc/poche/global.inc.php6
-rw-r--r--inc/poche/pochePictures.php58
7 files changed, 427 insertions, 113 deletions
diff --git a/inc/poche/Database.class.php b/inc/poche/Database.class.php
index 036c9d1b..9e901974 100755
--- a/inc/poche/Database.class.php
+++ b/inc/poche/Database.class.php
@@ -33,6 +33,8 @@ class Database {
33 $db_path = 'pgsql:host=' . STORAGE_SERVER . ';dbname=' . STORAGE_DB; 33 $db_path = 'pgsql:host=' . STORAGE_SERVER . ';dbname=' . STORAGE_DB;
34 $this->handle = new PDO($db_path, STORAGE_USER, STORAGE_PASSWORD); 34 $this->handle = new PDO($db_path, STORAGE_USER, STORAGE_PASSWORD);
35 break; 35 break;
36 default:
37 die(STORAGE . ' is not a recognised database system !');
36 } 38 }
37 39
38 $this->handle->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 40 $this->handle->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
@@ -229,12 +231,49 @@ class Database {
229 return FALSE; 231 return FALSE;
230 } 232 }
231 } 233 }
234
235 public function listUsers($username=null) {
236 $sql = 'SELECT count(*) FROM users'.( $username ? ' WHERE username=?' : '');
237 $query = $this->executeQuery($sql, ( $username ? array($username) : array()));
238 list($count) = $query->fetch();
239 return $count;
240 }
241
242 public function getUserPassword($userID) {
243 $sql = "SELECT * FROM users WHERE id=?";
244 $query = $this->executeQuery($sql, array($userID));
245 $password = $query->fetchAll();
246 return isset($password[0]['password']) ? $password[0]['password'] : null;
247 }
248
249 public function deleteUserConfig($userID) {
250 $sql_action = 'DELETE from users_config WHERE user_id=?';
251 $params_action = array($userID);
252 $query = $this->executeQuery($sql_action, $params_action);
253 return $query;
254 }
255
256 public function deleteTagsEntriesAndEntries($userID) {
257 $entries = $this->retrieveAll($userID);
258 foreach($entries as $entryid) {
259 $tags = $this->retrieveTagsByEntry($entryid);
260 foreach($tags as $tag) {
261 $this->removeTagForEntry($entryid,$tags);
262 }
263 $this->deleteById($entryid,$userID);
264 }
265 }
266
267 public function deleteUser($userID) {
268 $sql_action = 'DELETE from users WHERE id=?';
269 $params_action = array($userID);
270 $query = $this->executeQuery($sql_action, $params_action);
271 }
232 272
233 public function updateContentAndTitle($id, $title, $body, $user_id) { 273 public function updateContentAndTitle($id, $title, $body, $user_id) {
234 $sql_action = 'UPDATE entries SET content = ?, title = ? WHERE id=? AND user_id=?'; 274 $sql_action = 'UPDATE entries SET content = ?, title = ? WHERE id=? AND user_id=?';
235 $params_action = array($body, $title, $id, $user_id); 275 $params_action = array($body, $title, $id, $user_id);
236 $query = $this->executeQuery($sql_action, $params_action); 276 $query = $this->executeQuery($sql_action, $params_action);
237
238 return $query; 277 return $query;
239 } 278 }
240 279
@@ -472,6 +511,25 @@ class Database {
472 $query = $this->executeQuery($sql_action, $params_action); 511 $query = $this->executeQuery($sql_action, $params_action);
473 return $query; 512 return $query;
474 } 513 }
514
515 public function cleanUnusedTag($tag_id) {
516 $sql_action = "SELECT tags.* FROM tags JOIN tags_entries ON tags_entries.tag_id=tags.id WHERE tags.id=?";
517 $query = $this->executeQuery($sql_action,array($tag_id));
518 $tagstokeep = $query->fetchAll();
519 $sql_action = "SELECT tags.* FROM tags LEFT JOIN tags_entries ON tags_entries.tag_id=tags.id WHERE tags.id=?";
520 $query = $this->executeQuery($sql_action,array($tag_id));
521 $alltags = $query->fetchAll();
522
523 foreach ($alltags as $tag) {
524 if ($tag && !in_array($tag,$tagstokeep)) {
525 $sql_action = "DELETE FROM tags WHERE id=?";
526 $params_action = array($tag[0]);
527 $this->executeQuery($sql_action, $params_action);
528 return true;
529 }
530 }
531
532 }
475 533
476 public function retrieveTagByValue($value) { 534 public function retrieveTagByValue($value) {
477 $tag = NULL; 535 $tag = NULL;
diff --git a/inc/poche/Poche.class.php b/inc/poche/Poche.class.php
index 811895dc..37cf66a3 100755
--- a/inc/poche/Poche.class.php
+++ b/inc/poche/Poche.class.php
@@ -72,7 +72,7 @@ class Poche
72 72
73 # l10n 73 # l10n
74 $language = $this->user->getConfigValue('language'); 74 $language = $this->user->getConfigValue('language');
75 putenv('LC_ALL=' . $language); 75 @putenv('LC_ALL=' . $language);
76 setlocale(LC_ALL, $language); 76 setlocale(LC_ALL, $language);
77 bindtextdomain($language, LOCALE); 77 bindtextdomain($language, LOCALE);
78 textdomain($language); 78 textdomain($language);
@@ -101,7 +101,7 @@ class Poche
101 101
102 public function configFileIsAvailable() { 102 public function configFileIsAvailable() {
103 if (! self::$configFileAvailable) { 103 if (! self::$configFileAvailable) {
104 $this->notInstalledMessage[] = 'You have to rename inc/poche/config.inc.php.new to inc/poche/config.inc.php.'; 104 $this->notInstalledMessage[] = 'You have to copy (don\'t just rename!) inc/poche/config.inc.default.php to inc/poche/config.inc.php.';
105 105
106 return false; 106 return false;
107 } 107 }
@@ -242,6 +242,58 @@ class Poche
242 $this->tpl->addFilter($filter); 242 $this->tpl->addFilter($filter);
243 } 243 }
244 244
245 public function createNewUser() {
246 if (isset($_GET['newuser'])){
247 if ($_POST['newusername'] != "" && $_POST['password4newuser'] != ""){
248 $newusername = filter_var($_POST['newusername'], FILTER_SANITIZE_STRING);
249 if (!$this->store->userExists($newusername)){
250 if ($this->store->install($newusername, Tools::encodeString($_POST['password4newuser'] . $newusername))) {
251 Tools::logm('The new user '.$newusername.' has been installed');
252 $this->messages->add('s', sprintf(_('The new user %s has been installed. Do you want to <a href="?logout">logout ?</a>'),$newusername));
253 Tools::redirect();
254 }
255 else {
256 Tools::logm('error during adding new user');
257 Tools::redirect();
258 }
259 }
260 else {
261 $this->messages->add('e', sprintf(_('Error : An user with the name %s already exists !'),$newusername));
262 Tools::logm('An user with the name '.$newusername.' already exists !');
263 Tools::redirect();
264 }
265 }
266 }
267 }
268
269 public function deleteUser(){
270 if (isset($_GET['deluser'])){
271 if ($this->store->listUsers() > 1) {
272 if (Tools::encodeString($_POST['password4deletinguser'].$this->user->getUsername()) == $this->store->getUserPassword($this->user->getId())) {
273 $username = $this->user->getUsername();
274 $this->store->deleteUserConfig($this->user->getId());
275 Tools::logm('The configuration for user '. $username .' has been deleted !');
276 $this->store->deleteTagsEntriesAndEntries($this->user->getId());
277 Tools::logm('The entries for user '. $username .' has been deleted !');
278 $this->store->deleteUser($this->user->getId());
279 Tools::logm('User '. $username .' has been completely deleted !');
280 Session::logout();
281 Tools::logm('logout');
282 Tools::redirect();
283 $this->messages->add('s', sprintf(_('User %s has been successfully deleted !'),$newusername));
284 }
285 else {
286 Tools::logm('Bad password !');
287 $this->messages->add('e', _('Error : The password is wrong !'));
288 }
289 }
290 else {
291 Tools::logm('Only user !');
292 $this->messages->add('e', _('Error : You are the only user, you cannot delete your account !'));
293 }
294 }
295 }
296
245 private function install() 297 private function install()
246 { 298 {
247 Tools::logm('poche still not installed'); 299 Tools::logm('poche still not installed');
@@ -434,12 +486,24 @@ class Poche
434 case 'toggle_fav' : 486 case 'toggle_fav' :
435 $this->store->favoriteById($id, $this->user->getId()); 487 $this->store->favoriteById($id, $this->user->getId());
436 Tools::logm('mark as favorite link #' . $id); 488 Tools::logm('mark as favorite link #' . $id);
437 Tools::redirect(); 489 if ( Tools::isAjaxRequest() ) {
490 echo 1;
491 exit;
492 }
493 else {
494 Tools::redirect();
495 }
438 break; 496 break;
439 case 'toggle_archive' : 497 case 'toggle_archive' :
440 $this->store->archiveById($id, $this->user->getId()); 498 $this->store->archiveById($id, $this->user->getId());
441 Tools::logm('archive link #' . $id); 499 Tools::logm('archive link #' . $id);
442 Tools::redirect(); 500 if ( Tools::isAjaxRequest() ) {
501 echo 1;
502 exit;
503 }
504 else {
505 Tools::redirect();
506 }
443 break; 507 break;
444 case 'archive_all' : 508 case 'archive_all' :
445 $this->store->archiveAll($this->user->getId()); 509 $this->store->archiveAll($this->user->getId());
@@ -447,42 +511,55 @@ class Poche
447 Tools::redirect(); 511 Tools::redirect();
448 break; 512 break;
449 case 'add_tag' : 513 case 'add_tag' :
450 $tags = explode(',', $_POST['value']); 514 if (isset($_GET['search'])) {
451 $entry_id = $_POST['entry_id']; 515 //when we want to apply a tag to a search
452 $entry = $this->store->retrieveOneById($entry_id, $this->user->getId()); 516 $tags = array($_GET['search']);
453 if (!$entry) { 517 $allentry_ids = $this->store->search($tags[0], $this->user->getId());
454 $this->messages->add('e', _('Article not found!')); 518 $entry_ids = array();
455 Tools::logm('error : article not found'); 519 foreach ($allentry_ids as $eachentry) {
456 Tools::redirect(); 520 $entry_ids[] = $eachentry[0];
457 } 521 }
458 //get all already set tags to preven duplicates 522 } else { //add a tag to a single article
459 $already_set_tags = array(); 523 $tags = explode(',', $_POST['value']);
460 $entry_tags = $this->store->retrieveTagsByEntry($entry_id); 524 $entry_ids = array($_POST['entry_id']);
461 foreach ($entry_tags as $tag) {
462 $already_set_tags[] = $tag['value'];
463 } 525 }
464 foreach($tags as $key => $tag_value) { 526 foreach($entry_ids as $entry_id) {
465 $value = trim($tag_value); 527 $entry = $this->store->retrieveOneById($entry_id, $this->user->getId());
466 if ($value && !in_array($value, $already_set_tags)) { 528 if (!$entry) {
467 $tag = $this->store->retrieveTagByValue($value); 529 $this->messages->add('e', _('Article not found!'));
468 530 Tools::logm('error : article not found');
469 if (is_null($tag)) { 531 Tools::redirect();
470 # we create the tag 532 }
471 $tag = $this->store->createTag($value); 533 //get all already set tags to preven duplicates
472 $sequence = ''; 534 $already_set_tags = array();
473 if (STORAGE == 'postgres') { 535 $entry_tags = $this->store->retrieveTagsByEntry($entry_id);
474 $sequence = 'tags_id_seq'; 536 foreach ($entry_tags as $tag) {
537 $already_set_tags[] = $tag['value'];
538 }
539 foreach($tags as $key => $tag_value) {
540 $value = trim($tag_value);
541 if ($value && !in_array($value, $already_set_tags)) {
542 $tag = $this->store->retrieveTagByValue($value);
543 if (is_null($tag)) {
544 # we create the tag
545 $tag = $this->store->createTag($value);
546 $sequence = '';
547 if (STORAGE == 'postgres') {
548 $sequence = 'tags_id_seq';
549 }
550 $tag_id = $this->store->getLastId($sequence);
475 } 551 }
476 $tag_id = $this->store->getLastId($sequence); 552 else {
477 } 553 $tag_id = $tag['id'];
478 else { 554 }
479 $tag_id = $tag['id']; 555
480 } 556 # we assign the tag to the article
481 557 $this->store->setTagToEntry($tag_id, $entry_id);
482 # we assign the tag to the article 558 }
483 $this->store->setTagToEntry($tag_id, $entry_id);
484 } 559 }
485 } 560 }
561 $this->messages->add('s', _('The tag has been applied successfully'));
562 Tools::logm('The tag has been applied successfully');
486 Tools::redirect(); 563 Tools::redirect();
487 break; 564 break;
488 case 'remove_tag' : 565 case 'remove_tag' :
@@ -494,6 +571,11 @@ class Poche
494 Tools::redirect(); 571 Tools::redirect();
495 } 572 }
496 $this->store->removeTagForEntry($id, $tag_id); 573 $this->store->removeTagForEntry($id, $tag_id);
574 Tools::logm('tag entry deleted');
575 if ($this->store->cleanUnusedTag($tag_id)) {
576 Tools::logm('tag deleted');
577 }
578 $this->messages->add('s', _('The tag has been successfully deleted'));
497 Tools::redirect(); 579 Tools::redirect();
498 break; 580 break;
499 default: 581 default:
@@ -520,6 +602,7 @@ class Poche
520 $languages = $this->getInstalledLanguages(); 602 $languages = $this->getInstalledLanguages();
521 $token = $this->user->getConfigValue('token'); 603 $token = $this->user->getConfigValue('token');
522 $http_auth = (isset($_SERVER['PHP_AUTH_USER']) || isset($_SERVER['REMOTE_USER'])) ? true : false; 604 $http_auth = (isset($_SERVER['PHP_AUTH_USER']) || isset($_SERVER['REMOTE_USER'])) ? true : false;
605 $only_user = ($this->store->listUsers() > 1) ? false : true;
523 $tpl_vars = array( 606 $tpl_vars = array(
524 'themes' => $themes, 607 'themes' => $themes,
525 'languages' => $languages, 608 'languages' => $languages,
@@ -532,6 +615,7 @@ class Poche
532 'token' => $token, 615 'token' => $token,
533 'user_id' => $this->user->getId(), 616 'user_id' => $this->user->getId(),
534 'http_auth' => $http_auth, 617 'http_auth' => $http_auth,
618 'only_user' => $only_user
535 ); 619 );
536 Tools::logm('config view'); 620 Tools::logm('config view');
537 break; 621 break;
@@ -822,13 +906,6 @@ class Poche
822 */ 906 */
823 public function import() { 907 public function import() {
824 908
825 if (!defined('IMPORT_LIMIT')) {
826 define('IMPORT_LIMIT', 5);
827 }
828 if (!defined('IMPORT_DELAY')) {
829 define('IMPORT_DELAY', 5);
830 }
831
832 if ( isset($_FILES['file']) ) { 909 if ( isset($_FILES['file']) ) {
833 Tools::logm('Import stated: parsing file'); 910 Tools::logm('Import stated: parsing file');
834 911
@@ -1065,11 +1142,127 @@ class Poche
1065 * return new purifier object with actual config 1142 * return new purifier object with actual config
1066 */ 1143 */
1067 protected function getPurifier() { 1144 protected function getPurifier() {
1068 $config = HTMLPurifier_Config::createDefault(); 1145 $config = HTMLPurifier_Config::createDefault();
1069 $config->set('Cache.SerializerPath', CACHE); 1146 $config->set('Cache.SerializerPath', CACHE);
1070 $config->set('HTML.SafeIframe', true); 1147 $config->set('HTML.SafeIframe', true);
1071 $config->set('URI.SafeIframeRegexp', '%^(https?:)?//(www\.youtube(?:-nocookie)?\.com/embed/|player\.vimeo\.com/video/)%'); //allow YouTube and Vimeo$purifier = new HTMLPurifier($config); 1148 //allow YouTube, Vimeo and dailymotion videos
1072 1149 $config->set('URI.SafeIframeRegexp', '%^(https?:)?//(www\.youtube(?:-nocookie)?\.com/embed/|player\.vimeo\.com/video/|www\.dailymotion\.com/embed/video/)%');
1150
1073 return new HTMLPurifier($config); 1151 return new HTMLPurifier($config);
1074 } 1152 }
1153
1154 /**
1155 * handle epub
1156 */
1157 public function createEpub() {
1158
1159 switch ($_GET['method']) {
1160 case 'id':
1161 $entryID = filter_var($_GET['id'],FILTER_SANITIZE_NUMBER_INT);
1162 $entry = $this->store->retrieveOneById($entryID, $this->user->getId());
1163 $entries = array($entry);
1164 $bookTitle = $entry['title'];
1165 $bookFileName = substr($bookTitle, 0, 200);
1166 break;
1167 case 'all':
1168 $entries = $this->store->retrieveAll($this->user->getId());
1169 $bookTitle = sprintf(_('All my articles on '), date(_('d.m.y'))); #translatable because each country has it's own date format system
1170 $bookFileName = _('Allarticles') . date(_('dmY'));
1171 break;
1172 case 'tag':
1173 $tag = filter_var($_GET['tag'],FILTER_SANITIZE_STRING);
1174 $tags_id = $this->store->retrieveAllTags($this->user->getId(),$tag);
1175 $tag_id = $tags_id[0]["id"]; // we take the first result, which is supposed to match perfectly. There must be a workaround.
1176 $entries = $this->store->retrieveEntriesByTag($tag_id,$this->user->getId());
1177 $bookTitle = sprintf(_('Articles tagged %s'),$tag);
1178 $bookFileName = substr(sprintf(_('Tag %s'),$tag), 0, 200);
1179 break;
1180 case 'category':
1181 $category = filter_var($_GET['category'],FILTER_SANITIZE_STRING);
1182 $entries = $this->store->getEntriesByView($category,$this->user->getId());
1183 $bookTitle = sprintf(_('All articles in category %s'), $category);
1184 $bookFileName = substr(sprintf(_('Category %s'),$category), 0, 200);
1185 break;
1186 case 'search':
1187 $search = filter_var($_GET['search'],FILTER_SANITIZE_STRING);
1188 $entries = $this->store->search($search,$this->user->getId());
1189 $bookTitle = sprintf(_('All articles for search %s'), $search);
1190 $bookFileName = substr(sprintf(_('Search %s'), $search), 0, 200);
1191 break;
1192 case 'default':
1193 die(_('Uh, there is a problem while generating epub.'));
1194
1195 }
1196
1197 $content_start =
1198 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
1199 . "<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:epub=\"http://www.idpf.org/2007/ops\">\n"
1200 . "<head>"
1201 . "<meta http-equiv=\"Default-Style\" content=\"text/html; charset=utf-8\" />\n"
1202 . "<title>wallabag articles book</title>\n"
1203 . "</head>\n"
1204 . "<body>\n";
1205
1206 $bookEnd = "</body>\n</html>\n";
1207
1208 $log = new Logger("wallabag", TRUE);
1209 $fileDir = CACHE;
1210
1211
1212 $book = new EPub(EPub::BOOK_VERSION_EPUB3);
1213 $log->logLine("new EPub()");
1214 $log->logLine("EPub class version: " . EPub::VERSION);
1215 $log->logLine("EPub Req. Zip version: " . EPub::REQ_ZIP_VERSION);
1216 $log->logLine("Zip version: " . Zip::VERSION);
1217 $log->logLine("getCurrentServerURL: " . $book->getCurrentServerURL());
1218 $log->logLine("getCurrentPageURL..: " . $book->getCurrentPageURL());
1219
1220 $book->setTitle(_('wallabag\'s articles'));
1221 $book->setIdentifier("http://$_SERVER[HTTP_HOST]", EPub::IDENTIFIER_URI); // Could also be the ISBN number, prefered for published books, or a UUID.
1222 //$book->setLanguage("en"); // Not needed, but included for the example, Language is mandatory, but EPub defaults to "en". Use RFC3066 Language codes, such as "en", "da", "fr" etc.
1223 $book->setDescription(_("Some articles saved on my wallabag"));
1224 $book->setAuthor("wallabag","wallabag");
1225 $book->setPublisher("wallabag","wallabag"); // I hope this is a non existant address :)
1226 $book->setDate(time()); // Strictly not needed as the book date defaults to time().
1227 //$book->setRights("Copyright and licence information specific for the book."); // As this is generated, this _could_ contain the name or licence information of the user who purchased the book, if needed. If this is used that way, the identifier must also be made unique for the book.
1228 $book->setSourceURL("http://$_SERVER[HTTP_HOST]");
1229
1230 $book->addDublinCoreMetadata(DublinCore::CONTRIBUTOR, "PHP");
1231 $book->addDublinCoreMetadata(DublinCore::CONTRIBUTOR, "wallabag");
1232
1233 $cssData = "body {\n margin-left: .5em;\n margin-right: .5em;\n text-align: justify;\n}\n\np {\n font-family: serif;\n font-size: 10pt;\n text-align: justify;\n text-indent: 1em;\n margin-top: 0px;\n margin-bottom: 1ex;\n}\n\nh1, h2 {\n font-family: sans-serif;\n font-style: italic;\n text-align: center;\n background-color: #6b879c;\n color: white;\n width: 100%;\n}\n\nh1 {\n margin-bottom: 2px;\n}\n\nh2 {\n margin-top: -2px;\n margin-bottom: 2px;\n}\n";
1234
1235 $log->logLine("Add Cover");
1236
1237 $fullTitle = "<h1> " . $bookTitle . "</h1>\n";
1238
1239 $book->setCoverImage("Cover.png", file_get_contents("themes/baggy/img/apple-touch-icon-152.png"), "image/png", $fullTitle);
1240
1241 $cover = $content_start . '<div style="text-align:center;"><p>' . _('Produced by wallabag with PHPePub') . '</p><p>'. _('Please open <a href="https://github.com/wallabag/wallabag/issues" >an issue</a> if you have trouble with the display of this E-Book on your device.') . '</p></div>' . $bookEnd;
1242
1243 //$book->addChapter("Table of Contents", "TOC.xhtml", NULL, false, EPub::EXTERNAL_REF_IGNORE);
1244 $book->addChapter("Notices", "Cover2.html", $cover);
1245
1246 $book->buildTOC();
1247
1248 foreach ($entries as $entry) { //set tags as subjects
1249 $tags = $this->store->retrieveTagsByEntry($entry['id']);
1250 foreach ($tags as $tag) {
1251 $book->setSubject($tag['value']);
1252 }
1253
1254 $log->logLine("Set up parameters");
1255
1256 $chapter = $content_start . $entry['content'] . $bookEnd;
1257 $book->addChapter($entry['title'], htmlspecialchars($entry['title']) . ".html", $chapter, true, EPub::EXTERNAL_REF_ADD);
1258 $log->logLine("Added chapter " . $entry['title']);
1259 }
1260
1261 if (DEBUG_POCHE) {
1262 $epuplog = $book->getLog();
1263 $book->addChapter("Log", "Log.html", $content_start . $log->getLog() . "\n</pre>" . $bookEnd); // log generation
1264 }
1265 $book->finalize();
1266 $zipData = $book->sendBook($bookFileName);
1267 }
1075} 1268}
diff --git a/inc/poche/Tools.class.php b/inc/poche/Tools.class.php
index 7f064020..8073a3fe 100755
--- a/inc/poche/Tools.class.php
+++ b/inc/poche/Tools.class.php
@@ -60,6 +60,10 @@ class Tools
60 } 60 }
61 61
62 $host = (isset($_SERVER['HTTP_X_FORWARDED_HOST']) ? $_SERVER['HTTP_X_FORWARDED_HOST'] : (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME'])); 62 $host = (isset($_SERVER['HTTP_X_FORWARDED_HOST']) ? $_SERVER['HTTP_X_FORWARDED_HOST'] : (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME']));
63
64 if (strpos($host, ':') !== false) {
65 $serverport = '';
66 }
63 67
64 return 'http' . ($https ? 's' : '') . '://' 68 return 'http' . ($https ? 's' : '') . '://'
65 . $host . $serverport . $scriptname; 69 . $host . $serverport . $scriptname;
diff --git a/inc/poche/config.inc.default.php b/inc/poche/config.inc.default.php
new file mode 100755
index 00000000..ffcd205d
--- /dev/null
+++ b/inc/poche/config.inc.default.php
@@ -0,0 +1,64 @@
1<?php
2/**
3 * wallabag, self hostable application allowing you to not miss any content anymore
4 *
5 * @category wallabag
6 * @author Nicolas Lœuillet <nicolas@loeuillet.org>
7 * @copyright 2013
8 * @license http://www.wtfpl.net/ see COPYING file
9 */
10
11@define ('SALT', ''); # put a strong string here
12@define ('LANG', 'en_EN.utf8');
13
14@define ('STORAGE', 'sqlite'); # postgres, mysql or sqlite
15
16@define ('STORAGE_SQLITE', ROOT . '/db/poche.sqlite'); # if you are using sqlite, where the database file is located
17
18# only for postgres & mysql
19@define ('STORAGE_SERVER', 'localhost');
20@define ('STORAGE_DB', 'poche');
21@define ('STORAGE_USER', 'poche');
22@define ('STORAGE_PASSWORD', 'poche');
23
24#################################################################################
25# Do not trespass unless you know what you are doing
26#################################################################################
27
28// Change this if not using the standart port for SSL - i.e you server is behind sslh
29@define ('SSL_PORT', 443);
30
31@define ('MODE_DEMO', FALSE);
32@define ('DEBUG_POCHE', FALSE);
33@define ('DOWNLOAD_PICTURES', FALSE); # This can slow down the process of adding articles
34@define ('REGENERATE_PICTURES_QUALITY', 75);
35@define ('CONVERT_LINKS_FOOTNOTES', FALSE);
36@define ('REVERT_FORCED_PARAGRAPH_ELEMENTS', FALSE);
37@define ('SHARE_TWITTER', TRUE);
38@define ('SHARE_MAIL', TRUE);
39@define ('SHARE_SHAARLI', FALSE);
40@define ('SHAARLI_URL', 'http://myshaarliurl.com');
41@define ('FLATTR', TRUE);
42@define ('FLATTR_API', 'https://api.flattr.com/rest/v2/things/lookup/?url=');
43@define ('NOT_FLATTRABLE', '0');
44@define ('FLATTRABLE', '1');
45@define ('FLATTRED', '2');
46// display or not print link in article view
47@define ('SHOW_PRINTLINK', '1');
48// display or not percent of read in article view. Affects only default theme.
49@define ('SHOW_READPERCENT', '1');
50@define ('ABS_PATH', 'assets/');
51
52@define ('DEFAULT_THEME', 'baggy');
53
54@define ('THEME', ROOT . '/themes');
55@define ('LOCALE', ROOT . '/locale');
56@define ('CACHE', ROOT . '/cache');
57
58@define ('PAGINATION', '10');
59
60//limit for download of articles during import
61@define ('IMPORT_LIMIT', 5);
62//delay between downloads (in sec)
63@define ('IMPORT_DELAY', 5);
64
diff --git a/inc/poche/config.inc.php.new b/inc/poche/config.inc.php.new
deleted file mode 100755
index 83b3c4c0..00000000
--- a/inc/poche/config.inc.php.new
+++ /dev/null
@@ -1,59 +0,0 @@
1<?php
2/**
3 * wallabag, self hostable application allowing you to not miss any content anymore
4 *
5 * @category wallabag
6 * @author Nicolas Lœuillet <nicolas@loeuillet.org>
7 * @copyright 2013
8 * @license http://www.wtfpl.net/ see COPYING file
9 */
10
11define ('SALT', ''); # put a strong string here
12define ('LANG', 'en_EN.utf8');
13
14define ('STORAGE', 'sqlite'); # postgres, mysql or sqlite
15
16define ('STORAGE_SQLITE', ROOT . '/db/poche.sqlite'); # if you are using sqlite, where the database file is located
17
18# only for postgres & mysql
19define ('STORAGE_SERVER', 'localhost');
20define ('STORAGE_DB', 'poche');
21define ('STORAGE_USER', 'poche');
22define ('STORAGE_PASSWORD', 'poche');
23
24#################################################################################
25# Do not trespass unless you know what you are doing
26#################################################################################
27
28// Change this if not using the standart port for SSL - i.e you server is behind sslh
29define ('SSL_PORT', 443);
30
31define ('MODE_DEMO', FALSE);
32define ('DEBUG_POCHE', FALSE);
33define ('DOWNLOAD_PICTURES', FALSE);
34define ('CONVERT_LINKS_FOOTNOTES', FALSE);
35define ('REVERT_FORCED_PARAGRAPH_ELEMENTS', FALSE);
36define ('SHARE_TWITTER', TRUE);
37define ('SHARE_MAIL', TRUE);
38define ('SHARE_SHAARLI', FALSE);
39define ('SHAARLI_URL', 'http://myshaarliurl.com');
40define ('FLATTR', TRUE);
41define ('FLATTR_API', 'https://api.flattr.com/rest/v2/things/lookup/?url=');
42define ('NOT_FLATTRABLE', '0');
43define ('FLATTRABLE', '1');
44define ('FLATTRED', '2');
45define ('ABS_PATH', 'assets/');
46
47define ('DEFAULT_THEME', 'baggy');
48
49define ('THEME', ROOT . '/themes');
50define ('LOCALE', ROOT . '/locale');
51define ('CACHE', ROOT . '/cache');
52
53define ('PAGINATION', '10');
54
55//limit for download of articles during import
56define ('IMPORT_LIMIT', 5);
57//delay between downloads (in sec)
58define ('IMPORT_DELAY', 5);
59
diff --git a/inc/poche/global.inc.php b/inc/poche/global.inc.php
index 15091387..8cf86d03 100644..100755
--- a/inc/poche/global.inc.php
+++ b/inc/poche/global.inc.php
@@ -31,6 +31,11 @@ require_once INCLUDES . '/3rdparty/FlattrItem.class.php';
31 31
32require_once INCLUDES . '/3rdparty/htmlpurifier/HTMLPurifier.auto.php'; 32require_once INCLUDES . '/3rdparty/htmlpurifier/HTMLPurifier.auto.php';
33 33
34# epub library
35require_once INCLUDES . '/3rdparty/libraries/PHPePub/Logger.php';
36require_once INCLUDES . '/3rdparty/libraries/PHPePub/EPub.php';
37require_once INCLUDES . '/3rdparty/libraries/PHPePub/EPubChapterSplitter.php';
38
34# Composer its autoloader for automatically loading Twig 39# Composer its autoloader for automatically loading Twig
35if (! file_exists(ROOT . '/vendor/autoload.php')) { 40if (! file_exists(ROOT . '/vendor/autoload.php')) {
36 Poche::$canRenderTemplates = false; 41 Poche::$canRenderTemplates = false;
@@ -43,6 +48,7 @@ if (! file_exists(INCLUDES . '/poche/config.inc.php')) {
43 Poche::$configFileAvailable = false; 48 Poche::$configFileAvailable = false;
44} else { 49} else {
45 require_once INCLUDES . '/poche/config.inc.php'; 50 require_once INCLUDES . '/poche/config.inc.php';
51 require_once INCLUDES . '/poche/config.inc.default.php';
46} 52}
47 53
48if (Poche::$configFileAvailable && DOWNLOAD_PICTURES) { 54if (Poche::$configFileAvailable && DOWNLOAD_PICTURES) {
diff --git a/inc/poche/pochePictures.php b/inc/poche/pochePictures.php
index e4b0b160..7c319a85 100644
--- a/inc/poche/pochePictures.php
+++ b/inc/poche/pochePictures.php
@@ -14,6 +14,7 @@
14function filtre_picture($content, $url, $id) 14function filtre_picture($content, $url, $id)
15{ 15{
16 $matches = array(); 16 $matches = array();
17 $processing_pictures = array(); // list of processing image to avoid processing the same pictures twice
17 preg_match_all('#<\s*(img)[^>]+src="([^"]*)"[^>]*>#Si', $content, $matches, PREG_SET_ORDER); 18 preg_match_all('#<\s*(img)[^>]+src="([^"]*)"[^>]*>#Si', $content, $matches, PREG_SET_ORDER);
18 foreach($matches as $i => $link) { 19 foreach($matches as $i => $link) {
19 $link[1] = trim($link[1]); 20 $link[1] = trim($link[1]);
@@ -22,8 +23,17 @@ function filtre_picture($content, $url, $id)
22 $filename = basename(parse_url($absolute_path, PHP_URL_PATH)); 23 $filename = basename(parse_url($absolute_path, PHP_URL_PATH));
23 $directory = create_assets_directory($id); 24 $directory = create_assets_directory($id);
24 $fullpath = $directory . '/' . $filename; 25 $fullpath = $directory . '/' . $filename;
25 download_pictures($absolute_path, $fullpath); 26
26 $content = str_replace($matches[$i][2], $fullpath, $content); 27 if (in_array($absolute_path, $processing_pictures) === true) {
28 // replace picture's URL only if processing is OK : already processing -> go to next picture
29 continue;
30 }
31
32 if (download_pictures($absolute_path, $fullpath) === true) {
33 $content = str_replace($matches[$i][2], $fullpath, $content);
34 }
35
36 $processing_pictures[] = $absolute_path;
27 } 37 }
28 38
29 } 39 }
@@ -64,17 +74,55 @@ function get_absolute_link($relative_link, $url) {
64 74
65/** 75/**
66 * Téléchargement des images 76 * Téléchargement des images
77 *
78 * @return bool true if the download and processing is OK, false else
67 */ 79 */
68function download_pictures($absolute_path, $fullpath) 80function download_pictures($absolute_path, $fullpath)
69{ 81{
70 $rawdata = Tools::getFile($absolute_path); 82 $rawdata = Tools::getFile($absolute_path);
83 $fullpath = urldecode($fullpath);
71 84
72 if(file_exists($fullpath)) { 85 if(file_exists($fullpath)) {
73 unlink($fullpath); 86 unlink($fullpath);
74 } 87 }
75 $fp = fopen($fullpath, 'x'); 88
76 fwrite($fp, $rawdata); 89 // check extension
77 fclose($fp); 90 $file_ext = strrchr($fullpath, '.');
91 $whitelist = array(".jpg",".jpeg",".gif",".png");
92 if (!(in_array($file_ext, $whitelist))) {
93 Tools::logm('processed image with not allowed extension. Skipping ' . $fullpath);
94 return false;
95 }
96
97 // check headers
98 $imageinfo = getimagesize($absolute_path);
99 if ($imageinfo['mime'] != 'image/gif' && $imageinfo['mime'] != 'image/jpeg'&& $imageinfo['mime'] != 'image/jpg'&& $imageinfo['mime'] != 'image/png') {
100 Tools::logm('processed image with bad header. Skipping ' . $fullpath);
101 return false;
102 }
103
104 // regenerate image
105 $im = imagecreatefromstring($rawdata);
106 if ($im === false) {
107 Tools::logm('error while regenerating image ' . $fullpath);
108 return false;
109 }
110
111 switch ($imageinfo['mime']) {
112 case 'image/gif':
113 $result = imagegif($im, $fullpath);
114 break;
115 case 'image/jpeg':
116 case 'image/jpg':
117 $result = imagejpeg($im, $fullpath, REGENERATE_PICTURES_QUALITY);
118 break;
119 case 'image/png':
120 $result = imagepng($im, $fullpath, ceil(REGENERATE_PICTURES_QUALITY / 100 * 9));
121 break;
122 }
123 imagedestroy($im);
124
125 return $result;
78} 126}
79 127
80/** 128/**