aboutsummaryrefslogtreecommitdiffhomepage
path: root/inc/poche/Poche.class.php
diff options
context:
space:
mode:
authorNicolas Lœuillet <nicolas@loeuillet.org>2014-07-12 19:01:11 +0200
committerNicolas Lœuillet <nicolas@loeuillet.org>2014-07-12 19:01:11 +0200
commit2f26729c841a68669a1baf799091cb2c6c9f585a (patch)
treee1e388bb73c7533aad85bf1f672f867b62b247e4 /inc/poche/Poche.class.php
parentb6a3c8866a4cb88b009e7ba45c5e223e0fdae188 (diff)
downloadwallabag-2f26729c841a68669a1baf799091cb2c6c9f585a.tar.gz
wallabag-2f26729c841a68669a1baf799091cb2c6c9f585a.tar.zst
wallabag-2f26729c841a68669a1baf799091cb2c6c9f585a.zip
Refactor
Diffstat (limited to 'inc/poche/Poche.class.php')
-rwxr-xr-xinc/poche/Poche.class.php507
1 files changed, 198 insertions, 309 deletions
diff --git a/inc/poche/Poche.class.php b/inc/poche/Poche.class.php
index bc4320b8..a49413f2 100755
--- a/inc/poche/Poche.class.php
+++ b/inc/poche/Poche.class.php
@@ -74,61 +74,57 @@ class Poche
74 /** 74 /**
75 * Creates a new user 75 * Creates a new user
76 */ 76 */
77 public function createNewUser() 77 public function createNewUser($username, $password)
78 { 78 {
79 if (isset($_GET['newuser'])){ 79 if (!empty($username) && !empty($password)){
80 if ($_POST['newusername'] != "" && $_POST['password4newuser'] != ""){ 80 $newUsername = filter_var($username, FILTER_SANITIZE_STRING);
81 $newusername = filter_var($_POST['newusername'], FILTER_SANITIZE_STRING); 81 if (!$this->store->userExists($newUsername)){
82 if (!$this->store->userExists($newusername)){ 82 if ($this->store->install($newUsername, Tools::encodeString($password . $newUsername))) {
83 if ($this->store->install($newusername, Tools::encodeString($_POST['password4newuser'] . $newusername))) { 83 Tools::logm('The new user ' . $newUsername . ' has been installed');
84 Tools::logm('The new user '.$newusername.' has been installed'); 84 $this->messages->add('s', sprintf(_('The new user %s has been installed. Do you want to <a href="?logout">logout ?</a>'), $newUsername));
85 $this->messages->add('s', sprintf(_('The new user %s has been installed. Do you want to <a href="?logout">logout ?</a>'),$newusername)); 85 Tools::redirect();
86 Tools::redirect();
87 }
88 else {
89 Tools::logm('error during adding new user');
90 Tools::redirect();
91 }
92 } 86 }
93 else { 87 else {
94 $this->messages->add('e', sprintf(_('Error : An user with the name %s already exists !'),$newusername)); 88 Tools::logm('error during adding new user');
95 Tools::logm('An user with the name '.$newusername.' already exists !');
96 Tools::redirect(); 89 Tools::redirect();
97 } 90 }
98 } 91 }
92 else {
93 $this->messages->add('e', sprintf(_('Error : An user with the name %s already exists !'), $newUsername));
94 Tools::logm('An user with the name ' . $newUsername . ' already exists !');
95 Tools::redirect();
96 }
99 } 97 }
100 } 98 }
101 99
102 /** 100 /**
103 * Delete an existing user 101 * Delete an existing user
104 */ 102 */
105 public function deleteUser() 103 public function deleteUser($password)
106 { 104 {
107 if (isset($_GET['deluser'])){ 105 if ($this->store->listUsers() > 1) {
108 if ($this->store->listUsers() > 1) { 106 if (Tools::encodeString($password . $this->user->getUsername()) == $this->store->getUserPassword($this->user->getId())) {
109 if (Tools::encodeString($_POST['password4deletinguser'].$this->user->getUsername()) == $this->store->getUserPassword($this->user->getId())) { 107 $username = $this->user->getUsername();
110 $username = $this->user->getUsername(); 108 $this->store->deleteUserConfig($this->user->getId());
111 $this->store->deleteUserConfig($this->user->getId()); 109 Tools::logm('The configuration for user '. $username .' has been deleted !');
112 Tools::logm('The configuration for user '. $username .' has been deleted !'); 110 $this->store->deleteTagsEntriesAndEntries($this->user->getId());
113 $this->store->deleteTagsEntriesAndEntries($this->user->getId()); 111 Tools::logm('The entries for user '. $username .' has been deleted !');
114 Tools::logm('The entries for user '. $username .' has been deleted !'); 112 $this->store->deleteUser($this->user->getId());
115 $this->store->deleteUser($this->user->getId()); 113 Tools::logm('User '. $username .' has been completely deleted !');
116 Tools::logm('User '. $username .' has been completely deleted !'); 114 Session::logout();
117 Session::logout(); 115 Tools::logm('logout');
118 Tools::logm('logout'); 116 Tools::redirect();
119 Tools::redirect(); 117 $this->messages->add('s', sprintf(_('User %s has been successfully deleted !'), $username));
120 $this->messages->add('s', sprintf(_('User %s has been successfully deleted !'),$newusername));
121 }
122 else {
123 Tools::logm('Bad password !');
124 $this->messages->add('e', _('Error : The password is wrong !'));
125 }
126 } 118 }
127 else { 119 else {
128 Tools::logm('Only user !'); 120 Tools::logm('Bad password !');
129 $this->messages->add('e', _('Error : You are the only user, you cannot delete your account !')); 121 $this->messages->add('e', _('Error : The password is wrong !'));
130 } 122 }
131 } 123 }
124 else {
125 Tools::logm('Only user !');
126 $this->messages->add('e', _('Error : You are the only user, you cannot delete your account !'));
127 }
132 } 128 }
133 129
134 public function getDefaultConfig() 130 public function getDefaultConfig()
@@ -153,7 +149,7 @@ class Poche
153 $body = $content['rss']['channel']['item']['description']; 149 $body = $content['rss']['channel']['item']['description'];
154 150
155 // clean content from prevent xss attack 151 // clean content from prevent xss attack
156 $purifier = $this->getPurifier(); 152 $purifier = $this->_getPurifier();
157 $title = $purifier->purify($title); 153 $title = $purifier->purify($title);
158 $body = $purifier->purify($body); 154 $body = $purifier->purify($body);
159 155
@@ -318,10 +314,10 @@ class Poche
318 switch ($view) 314 switch ($view)
319 { 315 {
320 case 'config': 316 case 'config':
321 $dev_infos = $this->getPocheVersion('dev'); 317 $dev_infos = $this->_getPocheVersion('dev');
322 $dev = trim($dev_infos[0]); 318 $dev = trim($dev_infos[0]);
323 $check_time_dev = date('d-M-Y H:i', $dev_infos[1]); 319 $check_time_dev = date('d-M-Y H:i', $dev_infos[1]);
324 $prod_infos = $this->getPocheVersion('prod'); 320 $prod_infos = $this->_getPocheVersion('prod');
325 $prod = trim($prod_infos[0]); 321 $prod = trim($prod_infos[0]);
326 $check_time_prod = date('d-M-Y H:i', $prod_infos[1]); 322 $check_time_prod = date('d-M-Y H:i', $prod_infos[1]);
327 $compare_dev = version_compare(POCHE, $dev); 323 $compare_dev = version_compare(POCHE, $dev);
@@ -461,7 +457,7 @@ class Poche
461 * @todo set the new password in function header like this updatePassword($newPassword) 457 * @todo set the new password in function header like this updatePassword($newPassword)
462 * @return boolean 458 * @return boolean
463 */ 459 */
464 public function updatePassword() 460 public function updatePassword($password, $confirmPassword)
465 { 461 {
466 if (MODE_DEMO) { 462 if (MODE_DEMO) {
467 $this->messages->add('i', _('in demo mode, you can\'t update your password')); 463 $this->messages->add('i', _('in demo mode, you can\'t update your password'));
@@ -469,10 +465,10 @@ class Poche
469 Tools::redirect('?view=config'); 465 Tools::redirect('?view=config');
470 } 466 }
471 else { 467 else {
472 if (isset($_POST['password']) && isset($_POST['password_repeat'])) { 468 if (isset($password) && isset($confirmPassword)) {
473 if ($_POST['password'] == $_POST['password_repeat'] && $_POST['password'] != "") { 469 if ($password == $confirmPassword && !empty($password)) {
474 $this->messages->add('s', _('your password has been updated')); 470 $this->messages->add('s', _('your password has been updated'));
475 $this->store->updatePassword($this->user->getId(), Tools::encodeString($_POST['password'] . $this->user->getUsername())); 471 $this->store->updatePassword($this->user->getId(), Tools::encodeString($password . $this->user->getUsername()));
476 Session::logout(); 472 Session::logout();
477 Tools::logm('password updated'); 473 Tools::logm('password updated');
478 Tools::redirect(); 474 Tools::redirect();
@@ -486,22 +482,24 @@ class Poche
486 } 482 }
487 483
488 /** 484 /**
489 * get credentials from differents sources 485 * Get credentials from differents sources
490 * it redirects the user to the $referer link 486 * It redirects the user to the $referer link
487 *
491 * @return array 488 * @return array
492 */ 489 */
493 private function credentials() { 490 private function credentials()
494 if(isset($_SERVER['PHP_AUTH_USER'])) { 491 {
495 return array($_SERVER['PHP_AUTH_USER'],'php_auth',true); 492 if (isset($_SERVER['PHP_AUTH_USER'])) {
493 return array($_SERVER['PHP_AUTH_USER'], 'php_auth', true);
496 } 494 }
497 if(!empty($_POST['login']) && !empty($_POST['password'])) { 495 if (!empty($_POST['login']) && !empty($_POST['password'])) {
498 return array($_POST['login'],$_POST['password'],false); 496 return array($_POST['login'], $_POST['password'], false);
499 } 497 }
500 if(isset($_SERVER['REMOTE_USER'])) { 498 if (isset($_SERVER['REMOTE_USER'])) {
501 return array($_SERVER['REMOTE_USER'],'http_auth',true); 499 return array($_SERVER['REMOTE_USER'], 'http_auth', true);
502 } 500 }
503 501
504 return array(false,false,false); 502 return array(false, false, false);
505 } 503 }
506 504
507 /** 505 /**
@@ -550,129 +548,148 @@ class Poche
550 } 548 }
551 549
552 /** 550 /**
553 * import datas into your poche 551 * import datas into your wallabag
554 * @return boolean 552 * @return boolean
555 */ 553 */
556 public function import() { 554 public function import()
557 555 {
558 if ( isset($_FILES['file']) ) { 556 if (isset($_FILES['file'])) {
559 Tools::logm('Import stated: parsing file'); 557 Tools::logm('Import stated: parsing file');
560 558
561 // assume, that file is in json format 559 // assume, that file is in json format
562 $str_data = file_get_contents($_FILES['file']['tmp_name']); 560
563 $data = json_decode($str_data, true); 561 $str_data = file_get_contents($_FILES['file']['tmp_name']);
564 562 $data = json_decode($str_data, true);
565 if ( $data === null ) { 563 if ($data === null) {
566 //not json - assume html 564
567 $html = new simple_html_dom(); 565 // not json - assume html
568 $html->load_file($_FILES['file']['tmp_name']); 566
569 $data = array(); 567 $html = new simple_html_dom();
570 $read = 0; 568 $html->load_file($_FILES['file']['tmp_name']);
571 foreach (array('ol','ul') as $list) { 569 $data = array();
572 foreach ($html->find($list) as $ul) { 570 $read = 0;
573 foreach ($ul->find('li') as $li) { 571 foreach(array('ol','ul') as $list) {
574 $tmpEntry = array(); 572 foreach($html->find($list) as $ul) {
575 $a = $li->find('a'); 573 foreach($ul->find('li') as $li) {
576 $tmpEntry['url'] = $a[0]->href; 574 $tmpEntry = array();
577 $tmpEntry['tags'] = $a[0]->tags; 575 $a = $li->find('a');
578 $tmpEntry['is_read'] = $read; 576 $tmpEntry['url'] = $a[0]->href;
579 if ($tmpEntry['url']) { 577 $tmpEntry['tags'] = $a[0]->tags;
580 $data[] = $tmpEntry; 578 $tmpEntry['is_read'] = $read;
581 } 579 if ($tmpEntry['url']) {
582 } 580 $data[] = $tmpEntry;
583 # the second <ol/ul> is for read links 581 }
584 $read = ((sizeof($data) && $read)?0:1); 582 }
583
584 // the second <ol/ul> is for read links
585
586 $read = ((sizeof($data) && $read) ? 0 : 1);
587 }
588 }
585 } 589 }
586 }
587 }
588 590
589 //for readability structure 591 // for readability structure
590 foreach ($data as $record) { 592
591 if (is_array($record)) { 593 foreach($data as $record) {
592 $data[] = $record; 594 if (is_array($record)) {
593 foreach ($record as $record2) { 595 $data[] = $record;
594 if (is_array($record2)) { 596 foreach($record as $record2) {
595 $data[] = $record2; 597 if (is_array($record2)) {
596 } 598 $data[] = $record2;
599 }
600 }
601 }
597 } 602 }
598 }
599 }
600 603
601 $urlsInserted = array(); //urls of articles inserted 604 $urlsInserted = array(); //urls of articles inserted
602 foreach ($data as $record) { 605 foreach($data as $record) {
603 $url = trim( isset($record['article__url']) ? $record['article__url'] : (isset($record['url']) ? $record['url'] : '') ); 606 $url = trim(isset($record['article__url']) ? $record['article__url'] : (isset($record['url']) ? $record['url'] : ''));
604 if ( $url and !in_array($url, $urlsInserted) ) { 607 if ($url and !in_array($url, $urlsInserted)) {
605 $title = (isset($record['title']) ? $record['title'] : _('Untitled - Import - ').'</a> <a href="./?import">'._('click to finish import').'</a><a>'); 608 $title = (isset($record['title']) ? $record['title'] : _('Untitled - Import - ') . '</a> <a href="./?import">' . _('click to finish import') . '</a><a>');
606 $body = (isset($record['content']) ? $record['content'] : ''); 609 $body = (isset($record['content']) ? $record['content'] : '');
607 $isRead = (isset($record['is_read']) ? intval($record['is_read']) : (isset($record['archive'])?intval($record['archive']):0)); 610 $isRead = (isset($record['is_read']) ? intval($record['is_read']) : (isset($record['archive']) ? intval($record['archive']) : 0));
608 $isFavorite = (isset($record['is_fav']) ? intval($record['is_fav']) : (isset($record['favorite'])?intval($record['favorite']):0) ); 611 $isFavorite = (isset($record['is_fav']) ? intval($record['is_fav']) : (isset($record['favorite']) ? intval($record['favorite']) : 0));
609 //insert new record 612
610 $id = $this->store->add($url, $title, $body, $this->user->getId(), $isFavorite, $isRead); 613 // insert new record
611 if ( $id ) { 614
612 $urlsInserted[] = $url; //add 615 $id = $this->store->add($url, $title, $body, $this->user->getId() , $isFavorite, $isRead);
613 616 if ($id) {
614 if ( isset($record['tags']) && trim($record['tags']) ) { 617 $urlsInserted[] = $url; //add
615 //@TODO: set tags 618 if (isset($record['tags']) && trim($record['tags'])) {
616 619
617 } 620 // @TODO: set tags
621
622 }
623 }
624 }
618 } 625 }
619 }
620 }
621 626
622 $i = sizeof($urlsInserted); 627 $i = sizeof($urlsInserted);
623 if ( $i > 0 ) { 628 if ($i > 0) {
624 $this->messages->add('s', _('Articles inserted: ').$i._('. Please note, that some may be marked as "read".')); 629 $this->messages->add('s', _('Articles inserted: ') . $i . _('. Please note, that some may be marked as "read".'));
630 }
631
632 Tools::logm('Import of articles finished: ' . $i . ' articles added (w/o content if not provided).');
625 } 633 }
626 Tools::logm('Import of articles finished: '.$i.' articles added (w/o content if not provided).');
627 }
628 //file parsing finished here
629 634
630 //now download article contents if any 635 // file parsing finished here
636 // now download article contents if any
637 // check if we need to download any content
631 638
632 //check if we need to download any content 639 $recordsDownloadRequired = $this->store->retrieveUnfetchedEntriesCount($this->user->getId());
633 $recordsDownloadRequired = $this->store->retrieveUnfetchedEntriesCount($this->user->getId()); 640
634 if ( $recordsDownloadRequired == 0 ) { 641 if ($recordsDownloadRequired == 0) {
635 //nothing to download
636 $this->messages->add('s', _('Import finished.'));
637 Tools::logm('Import finished completely');
638 Tools::redirect();
639 }
640 else {
641 //if just inserted - don't download anything, download will start in next reload
642 if ( !isset($_FILES['file']) ) {
643 //download next batch
644 Tools::logm('Fetching next batch of articles...');
645 $items = $this->store->retrieveUnfetchedEntries($this->user->getId(), IMPORT_LIMIT);
646 642
647 $purifier = $this->getPurifier(); 643 // nothing to download
648 644
649 foreach ($items as $item) { 645 $this->messages->add('s', _('Import finished.'));
650 $url = new Url(base64_encode($item['url'])); 646 Tools::logm('Import finished completely');
651 Tools::logm('Fetching article '.$item['id']); 647 Tools::redirect();
652 $content = Tools::getPageContent($url); 648 }
649 else {
653 650
654 $title = (($content['rss']['channel']['item']['title'] != '') ? $content['rss']['channel']['item']['title'] : _('Untitled')); 651 // if just inserted - don't download anything, download will start in next reload
655 $body = (($content['rss']['channel']['item']['description'] != '') ? $content['rss']['channel']['item']['description'] : _('Undefined'));
656 652
657 //clean content to prevent xss attack 653 if (!isset($_FILES['file'])) {
658 $title = $purifier->purify($title);
659 $body = $purifier->purify($body);
660 654
661 $this->store->updateContentAndTitle($item['id'], $title, $body, $this->user->getId()); 655 // download next batch
662 Tools::logm('Article '.$item['id'].' updated.');
663 }
664 656
657 Tools::logm('Fetching next batch of articles...');
658 $items = $this->store->retrieveUnfetchedEntries($this->user->getId() , IMPORT_LIMIT);
659 $purifier = $this->_getPurifier();
660 foreach($items as $item) {
661 $url = new Url(base64_encode($item['url']));
662 Tools::logm('Fetching article ' . $item['id']);
663 $content = Tools::getPageContent($url);
664 $title = (($content['rss']['channel']['item']['title'] != '') ? $content['rss']['channel']['item']['title'] : _('Untitled'));
665 $body = (($content['rss']['channel']['item']['description'] != '') ? $content['rss']['channel']['item']['description'] : _('Undefined'));
666
667 // clean content to prevent xss attack
668
669 $title = $purifier->purify($title);
670 $body = $purifier->purify($body);
671 $this->store->updateContentAndTitle($item['id'], $title, $body, $this->user->getId());
672 Tools::logm('Article ' . $item['id'] . ' updated.');
673 }
674 }
665 } 675 }
666 }
667 676
668 return array('includeImport'=>true, 'import'=>array('recordsDownloadRequired'=>$recordsDownloadRequired, 'recordsUnderDownload'=> IMPORT_LIMIT, 'delay'=> IMPORT_DELAY * 1000) ); 677 return array(
678 'includeImport' => true,
679 'import' => array(
680 'recordsDownloadRequired' => $recordsDownloadRequired,
681 'recordsUnderDownload' => IMPORT_LIMIT,
682 'delay' => IMPORT_DELAY * 1000
683 )
684 );
669 } 685 }
670 686
671 /** 687 /**
672 * export poche entries in json 688 * export poche entries in json
673 * @return json all poche entries 689 * @return json all poche entries
674 */ 690 */
675 public function export() { 691 public function export()
692 {
676 $filename = "wallabag-export-".$this->user->getId()."-".date("Y-m-d").".json"; 693 $filename = "wallabag-export-".$this->user->getId()."-".date("Y-m-d").".json";
677 header('Content-Disposition: attachment; filename='.$filename); 694 header('Content-Disposition: attachment; filename='.$filename);
678 695
@@ -688,7 +705,7 @@ class Poche
688 * @param string $which 'prod' or 'dev' 705 * @param string $which 'prod' or 'dev'
689 * @return string latest $which version 706 * @return string latest $which version
690 */ 707 */
691 private function getPocheVersion($which = 'prod') { 708 private function _getPocheVersion($which = 'prod') {
692 $cache_file = CACHE . '/' . $which; 709 $cache_file = CACHE . '/' . $which;
693 $check_time = time(); 710 $check_time = time();
694 711
@@ -703,29 +720,27 @@ class Poche
703 return array($version, $check_time); 720 return array($version, $check_time);
704 } 721 }
705 722
706 public function generateToken() 723 /**
724 * Update token for current user
725 */
726 public function updateToken()
707 { 727 {
708 if (ini_get('open_basedir') === '') { 728 $token = Tools::generateToken();
709 if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { 729 $this->store->updateUserConfig($this->user->getId(), 'token', $token);
710 echo 'This is a server using Windows!'; 730 $currentConfig = $_SESSION['poche_user']->config;
711 // alternative to /dev/urandom for Windows 731 $currentConfig['token'] = $token;
712 $token = substr(base64_encode(uniqid(mt_rand(), true)), 0, 20); 732 $_SESSION['poche_user']->setConfig($currentConfig);
713 } else { 733 Tools::redirect();
714 $token = substr(base64_encode(file_get_contents('/dev/urandom', false, null, 0, 20)), 0, 15);
715 }
716 }
717 else {
718 $token = substr(base64_encode(uniqid(mt_rand(), true)), 0, 20);
719 }
720
721 $token = str_replace('+', '', $token);
722 $this->store->updateUserConfig($this->user->getId(), 'token', $token);
723 $currentConfig = $_SESSION['poche_user']->config;
724 $currentConfig['token'] = $token;
725 $_SESSION['poche_user']->setConfig($currentConfig);
726 Tools::redirect();
727 } 734 }
728 735
736 /**
737 * Generate RSS feeds for current user
738 *
739 * @param $token
740 * @param $user_id
741 * @param $tag_id
742 * @param string $type
743 */
729 public function generateFeeds($token, $user_id, $tag_id, $type = 'home') 744 public function generateFeeds($token, $user_id, $tag_id, $type = 'home')
730 { 745 {
731 $allowed_types = array('home', 'fav', 'archive', 'tag'); 746 $allowed_types = array('home', 'fav', 'archive', 'tag');
@@ -738,7 +753,6 @@ class Poche
738 if (!in_array($type, $allowed_types) || $token != $config['token']) { 753 if (!in_array($type, $allowed_types) || $token != $config['token']) {
739 die(_('Uh, there is a problem while generating feeds.')); 754 die(_('Uh, there is a problem while generating feeds.'));
740 } 755 }
741 // Check the token
742 756
743 $feed = new FeedWriter(RSS2); 757 $feed = new FeedWriter(RSS2);
744 $feed->setTitle('wallabag — ' . $type . ' feed'); 758 $feed->setTitle('wallabag — ' . $type . ' feed');
@@ -770,147 +784,22 @@ class Poche
770 exit; 784 exit;
771 } 785 }
772 786
773 public function emptyCache() {
774 $files = new RecursiveIteratorIterator(
775 new RecursiveDirectoryIterator(CACHE, RecursiveDirectoryIterator::SKIP_DOTS),
776 RecursiveIteratorIterator::CHILD_FIRST
777 );
778
779 foreach ($files as $fileinfo) {
780 $todo = ($fileinfo->isDir() ? 'rmdir' : 'unlink');
781 $todo($fileinfo->getRealPath());
782 }
783 787
784 Tools::logm('empty cache');
785 $this->messages->add('s', _('Cache deleted.'));
786 Tools::redirect();
787 }
788 788
789 /** 789 /**
790 * return new purifier object with actual config 790 * Returns new purifier object with actual config
791 */ 791 */
792 protected function getPurifier() { 792 private function _getPurifier()
793 $config = HTMLPurifier_Config::createDefault(); 793 {
794 $config->set('Cache.SerializerPath', CACHE); 794 $config = HTMLPurifier_Config::createDefault();
795 $config->set('HTML.SafeIframe', true); 795 $config->set('Cache.SerializerPath', CACHE);
796 $config->set('HTML.SafeIframe', true);
796 797
797 //allow YouTube, Vimeo and dailymotion videos 798 //allow YouTube, Vimeo and dailymotion videos
798 $config->set('URI.SafeIframeRegexp', '%^(https?:)?//(www\.youtube(?:-nocookie)?\.com/embed/|player\.vimeo\.com/video/|www\.dailymotion\.com/embed/video/)%'); 799 $config->set('URI.SafeIframeRegexp', '%^(https?:)?//(www\.youtube(?:-nocookie)?\.com/embed/|player\.vimeo\.com/video/|www\.dailymotion\.com/embed/video/)%');
799 800
800 return new HTMLPurifier($config); 801 return new HTMLPurifier($config);
801 } 802 }
802 803
803 /**
804 * handle epub
805 */
806 public function createEpub() {
807
808 switch ($_GET['method']) {
809 case 'id':
810 $entryID = filter_var($_GET['id'],FILTER_SANITIZE_NUMBER_INT);
811 $entry = $this->store->retrieveOneById($entryID, $this->user->getId());
812 $entries = array($entry);
813 $bookTitle = $entry['title'];
814 $bookFileName = substr($bookTitle, 0, 200);
815 break;
816 case 'all':
817 $entries = $this->store->retrieveAll($this->user->getId());
818 $bookTitle = sprintf(_('All my articles on '), date(_('d.m.y'))); #translatable because each country has it's own date format system
819 $bookFileName = _('Allarticles') . date(_('dmY'));
820 break;
821 case 'tag':
822 $tag = filter_var($_GET['tag'],FILTER_SANITIZE_STRING);
823 $tags_id = $this->store->retrieveAllTags($this->user->getId(),$tag);
824 $tag_id = $tags_id[0]["id"]; // we take the first result, which is supposed to match perfectly. There must be a workaround.
825 $entries = $this->store->retrieveEntriesByTag($tag_id,$this->user->getId());
826 $bookTitle = sprintf(_('Articles tagged %s'),$tag);
827 $bookFileName = substr(sprintf(_('Tag %s'),$tag), 0, 200);
828 break;
829 case 'category':
830 $category = filter_var($_GET['category'],FILTER_SANITIZE_STRING);
831 $entries = $this->store->getEntriesByView($category,$this->user->getId());
832 $bookTitle = sprintf(_('All articles in category %s'), $category);
833 $bookFileName = substr(sprintf(_('Category %s'),$category), 0, 200);
834 break;
835 case 'search':
836 $search = filter_var($_GET['search'],FILTER_SANITIZE_STRING);
837 $entries = $this->store->search($search,$this->user->getId());
838 $bookTitle = sprintf(_('All articles for search %s'), $search);
839 $bookFileName = substr(sprintf(_('Search %s'), $search), 0, 200);
840 break;
841 case 'default':
842 die(_('Uh, there is a problem while generating epub.'));
843
844 }
845
846 $content_start =
847 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
848 . "<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:epub=\"http://www.idpf.org/2007/ops\">\n"
849 . "<head>"
850 . "<meta http-equiv=\"Default-Style\" content=\"text/html; charset=utf-8\" />\n"
851 . "<title>wallabag articles book</title>\n"
852 . "</head>\n"
853 . "<body>\n";
854
855 $bookEnd = "</body>\n</html>\n";
856
857 $log = new Logger("wallabag", TRUE);
858 $fileDir = CACHE;
859
860 $book = new EPub(EPub::BOOK_VERSION_EPUB3, DEBUG_POCHE);
861 $log->logLine("new EPub()");
862 $log->logLine("EPub class version: " . EPub::VERSION);
863 $log->logLine("EPub Req. Zip version: " . EPub::REQ_ZIP_VERSION);
864 $log->logLine("Zip version: " . Zip::VERSION);
865 $log->logLine("getCurrentServerURL: " . $book->getCurrentServerURL());
866 $log->logLine("getCurrentPageURL..: " . $book->getCurrentPageURL());
867
868 $book->setTitle(_('wallabag\'s articles'));
869 $book->setIdentifier("http://$_SERVER[HTTP_HOST]", EPub::IDENTIFIER_URI); // Could also be the ISBN number, prefered for published books, or a UUID.
870 //$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.
871 $book->setDescription(_("Some articles saved on my wallabag"));
872 $book->setAuthor("wallabag","wallabag");
873 $book->setPublisher("wallabag","wallabag"); // I hope this is a non existant address :)
874 $book->setDate(time()); // Strictly not needed as the book date defaults to time().
875 //$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.
876 $book->setSourceURL("http://$_SERVER[HTTP_HOST]");
877
878 $book->addDublinCoreMetadata(DublinCore::CONTRIBUTOR, "PHP");
879 $book->addDublinCoreMetadata(DublinCore::CONTRIBUTOR, "wallabag");
880
881 $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";
882
883 $log->logLine("Add Cover");
884 804
885 $fullTitle = "<h1> " . $bookTitle . "</h1>\n";
886
887 $book->setCoverImage("Cover.png", file_get_contents("themes/baggy/img/apple-touch-icon-152.png"), "image/png", $fullTitle);
888
889 $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;
890
891 //$book->addChapter("Table of Contents", "TOC.xhtml", NULL, false, EPub::EXTERNAL_REF_IGNORE);
892 $book->addChapter("Notices", "Cover2.html", $cover);
893
894 $book->buildTOC();
895
896 foreach ($entries as $entry) { //set tags as subjects
897 $tags = $this->store->retrieveTagsByEntry($entry['id']);
898 foreach ($tags as $tag) {
899 $book->setSubject($tag['value']);
900 }
901
902 $log->logLine("Set up parameters");
903
904 $chapter = $content_start . $entry['content'] . $bookEnd;
905 $book->addChapter($entry['title'], htmlspecialchars($entry['title']) . ".html", $chapter, true, EPub::EXTERNAL_REF_ADD);
906 $log->logLine("Added chapter " . $entry['title']);
907 }
908
909 if (DEBUG_POCHE) {
910 $epuplog = $book->getLog();
911 $book->addChapter("Log", "Log.html", $content_start . $log->getLog() . "\n</pre>" . $bookEnd); // log generation
912 }
913 $book->finalize();
914 $zipData = $book->sendBook($bookFileName);
915 }
916} 805}