aboutsummaryrefslogtreecommitdiffhomepage
path: root/index.php
diff options
context:
space:
mode:
authorArthurHoaro <arthur@hoa.ro>2016-10-12 13:58:35 +0200
committerArthurHoaro <arthur@hoa.ro>2016-10-12 13:58:35 +0200
commitbc22c9a0acb095970e9494cbe8954f0612e05dc0 (patch)
tree4e3a94b7469f5b2e3eaf946756235730429bf9d4 /index.php
parent890afc32f744859d11b97eb26ed5c030af9b4145 (diff)
parentebd67c6e1b40aebdd3a52285ce9ff9412b2a3038 (diff)
downloadShaarli-bc22c9a0acb095970e9494cbe8954f0612e05dc0.tar.gz
Shaarli-bc22c9a0acb095970e9494cbe8954f0612e05dc0.tar.zst
Shaarli-bc22c9a0acb095970e9494cbe8954f0612e05dc0.zip
Merge tag 'v0.7.0' of github.com:shaarli/Shaarli into stable
Release v0.7.0
Diffstat (limited to 'index.php')
-rw-r--r--index.php665
1 files changed, 166 insertions, 499 deletions
diff --git a/index.php b/index.php
index 850b350e..7465c41f 100644
--- a/index.php
+++ b/index.php
@@ -1,6 +1,6 @@
1<?php 1<?php
2/** 2/**
3 * Shaarli v0.6.5 - Shaare your links... 3 * Shaarli v0.7.0 - Shaare your links...
4 * 4 *
5 * The personal, minimalist, super-fast, no-database Delicious clone. 5 * The personal, minimalist, super-fast, no-database Delicious clone.
6 * 6 *
@@ -100,6 +100,7 @@ $GLOBALS['config']['ENABLE_LOCALCACHE'] = true;
100$GLOBALS['config']['UPDATECHECK_BRANCH'] = 'stable'; 100$GLOBALS['config']['UPDATECHECK_BRANCH'] = 'stable';
101$GLOBALS['config']['UPDATECHECK_INTERVAL'] = 86400; 101$GLOBALS['config']['UPDATECHECK_INTERVAL'] = 86400;
102 102
103$GLOBALS['config']['REDIRECTOR_URLENCODE'] = true;
103 104
104/* 105/*
105 * Plugin configuration 106 * Plugin configuration
@@ -125,7 +126,7 @@ $GLOBALS['config']['PUBSUBHUB_URL'] = '';
125/* 126/*
126 * PHP configuration 127 * PHP configuration
127 */ 128 */
128define('shaarli_version', '0.6.5'); 129define('shaarli_version', '0.7.0');
129 130
130// http://server.com/x/shaarli --> /shaarli/ 131// http://server.com/x/shaarli --> /shaarli/
131define('WEB_PATH', substr($_SERVER["REQUEST_URI"], 0, 1+strrpos($_SERVER["REQUEST_URI"], '/', 0))); 132define('WEB_PATH', substr($_SERVER["REQUEST_URI"], 0, 1+strrpos($_SERVER["REQUEST_URI"], '/', 0)));
@@ -154,11 +155,14 @@ if (is_file($GLOBALS['config']['CONFIG_FILE'])) {
154require_once 'application/ApplicationUtils.php'; 155require_once 'application/ApplicationUtils.php';
155require_once 'application/Cache.php'; 156require_once 'application/Cache.php';
156require_once 'application/CachedPage.php'; 157require_once 'application/CachedPage.php';
158require_once 'application/FeedBuilder.php';
157require_once 'application/FileUtils.php'; 159require_once 'application/FileUtils.php';
158require_once 'application/HttpUtils.php'; 160require_once 'application/HttpUtils.php';
159require_once 'application/LinkDB.php'; 161require_once 'application/LinkDB.php';
160require_once 'application/LinkFilter.php'; 162require_once 'application/LinkFilter.php';
161require_once 'application/LinkUtils.php'; 163require_once 'application/LinkUtils.php';
164require_once 'application/NetscapeBookmarkUtils.php';
165require_once 'application/PageBuilder.php';
162require_once 'application/TimeZone.php'; 166require_once 'application/TimeZone.php';
163require_once 'application/Url.php'; 167require_once 'application/Url.php';
164require_once 'application/Utils.php'; 168require_once 'application/Utils.php';
@@ -483,7 +487,7 @@ if (isset($_POST['login']))
483 if (isset($_POST['returnurl'])) { 487 if (isset($_POST['returnurl'])) {
484 // Prevent loops over login screen. 488 // Prevent loops over login screen.
485 if (strpos($_POST['returnurl'], 'do=login') === false) { 489 if (strpos($_POST['returnurl'], 'do=login') === false) {
486 header('Location: '. escape($_POST['returnurl'])); 490 header('Location: '. generateLocation($_POST['returnurl'], $_SERVER['HTTP_HOST']));
487 exit; 491 exit;
488 } 492 }
489 } 493 }
@@ -492,9 +496,9 @@ if (isset($_POST['login']))
492 else 496 else
493 { 497 {
494 ban_loginFailed(); 498 ban_loginFailed();
495 $redir = ''; 499 $redir = '&username='. $_POST['login'];
496 if (isset($_GET['post'])) { 500 if (isset($_GET['post'])) {
497 $redir = '?post=' . urlencode($_GET['post']); 501 $redir .= '&post=' . urlencode($_GET['post']);
498 foreach (array('description', 'source', 'title') as $param) { 502 foreach (array('description', 'source', 'title') as $param) {
499 if (!empty($_GET[$param])) { 503 if (!empty($_GET[$param])) {
500 $redir .= '&' . $param . '=' . urlencode($_GET[$param]); 504 $redir .= '&' . $param . '=' . urlencode($_GET[$param]);
@@ -560,337 +564,12 @@ function tokenOk($token)
560} 564}
561 565
562// ------------------------------------------------------------------------------------------ 566// ------------------------------------------------------------------------------------------
563/* This class is in charge of building the final page.
564 (This is basically a wrapper around RainTPL which pre-fills some fields.)
565 p = new pageBuilder;
566 p.assign('myfield','myvalue');
567 p.renderPage('mytemplate');
568
569*/
570class pageBuilder
571{
572 private $tpl; // RainTPL template
573
574 function __construct()
575 {
576 $this->tpl = false;
577 }
578
579 /**
580 * Initialize all default tpl tags.
581 */
582 private function initialize()
583 {
584 $this->tpl = new RainTPL;
585
586 try {
587 $version = ApplicationUtils::checkUpdate(
588 shaarli_version,
589 $GLOBALS['config']['UPDATECHECK_FILENAME'],
590 $GLOBALS['config']['UPDATECHECK_INTERVAL'],
591 $GLOBALS['config']['ENABLE_UPDATECHECK'],
592 isLoggedIn(),
593 $GLOBALS['config']['UPDATECHECK_BRANCH']
594 );
595 $this->tpl->assign('newVersion', escape($version));
596 $this->tpl->assign('versionError', '');
597
598 } catch (Exception $exc) {
599 logm($GLOBALS['config']['LOG_FILE'], $_SERVER['REMOTE_ADDR'], $exc->getMessage());
600 $this->tpl->assign('newVersion', '');
601 $this->tpl->assign('versionError', escape($exc->getMessage()));
602 }
603
604 $this->tpl->assign('feedurl', escape(index_url($_SERVER)));
605 $searchcrits = ''; // Search criteria
606 if (!empty($_GET['searchtags'])) {
607 $searchcrits .= '&searchtags=' . urlencode($_GET['searchtags']);
608 }
609 if (!empty($_GET['searchterm'])) {
610 $searchcrits .= '&searchterm=' . urlencode($_GET['searchterm']);
611 }
612 $this->tpl->assign('searchcrits', $searchcrits);
613 $this->tpl->assign('source', index_url($_SERVER));
614 $this->tpl->assign('version', shaarli_version);
615 $this->tpl->assign('scripturl', index_url($_SERVER));
616 $this->tpl->assign('pagetitle', 'Shaarli');
617 $this->tpl->assign('privateonly', !empty($_SESSION['privateonly'])); // Show only private links?
618 if (!empty($GLOBALS['title'])) {
619 $this->tpl->assign('pagetitle', $GLOBALS['title']);
620 }
621 if (!empty($GLOBALS['titleLink'])) {
622 $this->tpl->assign('titleLink', $GLOBALS['titleLink']);
623 }
624 if (!empty($GLOBALS['pagetitle'])) {
625 $this->tpl->assign('pagetitle', $GLOBALS['pagetitle']);
626 }
627 $this->tpl->assign('shaarlititle', empty($GLOBALS['title']) ? 'Shaarli': $GLOBALS['title']);
628 if (!empty($GLOBALS['plugin_errors'])) {
629 $this->tpl->assign('plugin_errors', $GLOBALS['plugin_errors']);
630 }
631 }
632
633 // The following assign() method is basically the same as RainTPL (except that it's lazy)
634 public function assign($what,$where)
635 {
636 if ($this->tpl===false) $this->initialize(); // Lazy initialization
637 $this->tpl->assign($what,$where);
638 }
639
640 // Render a specific page (using a template).
641 // e.g. pb.renderPage('picwall')
642 public function renderPage($page)
643 {
644 if ($this->tpl===false) $this->initialize(); // Lazy initialization
645 $this->tpl->draw($page);
646 }
647
648 /**
649 * Render a 404 page (uses the template : tpl/404.tpl)
650 *
651 * usage : $PAGE->render404('The link was deleted')
652 * @param string $message A messate to display what is not found
653 */
654 public function render404($message='The page you are trying to reach does not exist or has been deleted.') {
655 header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found');
656 $this->tpl->assign('error_message', $message);
657 $this->renderPage('404');
658 }
659}
660
661// ------------------------------------------------------------------------------------------
662// Output the last N links in RSS 2.0 format.
663function showRSS()
664{
665 header('Content-Type: application/rss+xml; charset=utf-8');
666
667 // $usepermalink : If true, use permalink instead of final link.
668 // User just has to add 'permalink' in URL parameters. e.g. http://mysite.com/shaarli/?do=rss&permalinks
669 // Also enabled through a config option
670 $usepermalinks = isset($_GET['permalinks']) || !$GLOBALS['config']['ENABLE_RSS_PERMALINKS'];
671
672 // Cache system
673 $query = $_SERVER["QUERY_STRING"];
674 $cache = new CachedPage(
675 $GLOBALS['config']['PAGECACHE'],
676 page_url($_SERVER),
677 startsWith($query,'do=rss') && !isLoggedIn()
678 );
679 $cached = $cache->cachedVersion();
680 if (! empty($cached)) {
681 echo $cached;
682 exit;
683 }
684
685 // If cached was not found (or not usable), then read the database and build the response:
686 $LINKSDB = new LinkDB(
687 $GLOBALS['config']['DATASTORE'],
688 isLoggedIn(),
689 $GLOBALS['config']['HIDE_PUBLIC_LINKS'],
690 $GLOBALS['redirector']
691 );
692 // Read links from database (and filter private links if user it not logged in).
693
694 // Optionally filter the results:
695 $searchtags = !empty($_GET['searchtags']) ? escape($_GET['searchtags']) : '';
696 $searchterm = !empty($_GET['searchterm']) ? escape($_GET['searchterm']) : '';
697 if (! empty($searchtags) && ! empty($searchterm)) {
698 $linksToDisplay = $LINKSDB->filter(
699 LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT,
700 array($searchtags, $searchterm)
701 );
702 }
703 elseif ($searchtags) {
704 $linksToDisplay = $LINKSDB->filter(LinkFilter::$FILTER_TAG, $searchtags);
705 }
706 elseif ($searchterm) {
707 $linksToDisplay = $LINKSDB->filter(LinkFilter::$FILTER_TEXT, $searchterm);
708 }
709 else {
710 $linksToDisplay = $LINKSDB;
711 }
712
713 $nblinksToDisplay = 50; // Number of links to display.
714 // In URL, you can specificy the number of links. Example: nb=200 or nb=all for all links.
715 if (!empty($_GET['nb'])) {
716 $nblinksToDisplay = $_GET['nb'] == 'all' ? count($linksToDisplay) : max(intval($_GET['nb']), 1);
717 }
718
719 $pageaddr = escape(index_url($_SERVER));
720 echo '<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">';
721 echo '<channel><title>'.$GLOBALS['title'].'</title><link>'.$pageaddr.'</link>';
722 echo '<description>Shared links</description><language>en-en</language><copyright>'.$pageaddr.'</copyright>'."\n\n";
723 if (!empty($GLOBALS['config']['PUBSUBHUB_URL']))
724 {
725 echo '<!-- PubSubHubbub Discovery -->';
726 echo '<link rel="hub" href="'.escape($GLOBALS['config']['PUBSUBHUB_URL']).'" xmlns="http://www.w3.org/2005/Atom" />';
727 echo '<link rel="self" href="'.$pageaddr.'?do=rss" xmlns="http://www.w3.org/2005/Atom" />';
728 echo '<!-- End Of PubSubHubbub Discovery -->';
729 }
730 $i=0;
731 $keys=array(); foreach($linksToDisplay as $key=>$value) { $keys[]=$key; } // No, I can't use array_keys().
732 while ($i<$nblinksToDisplay && $i<count($keys))
733 {
734 $link = $linksToDisplay[$keys[$i]];
735 $guid = $pageaddr.'?'.smallHash($link['linkdate']);
736 $date = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $link['linkdate']);
737 $absurl = $link['url'];
738 if (startsWith($absurl,'?')) $absurl=$pageaddr.$absurl; // make permalink URL absolute
739 if ($usepermalinks===true)
740 echo '<item><title>'.$link['title'].'</title><guid isPermaLink="true">'.$guid.'</guid><link>'.$guid.'</link>';
741 else
742 echo '<item><title>'.$link['title'].'</title><guid isPermaLink="false">'.$guid.'</guid><link>'.$absurl.'</link>';
743 if (!$GLOBALS['config']['HIDE_TIMESTAMPS'] || isLoggedIn()) {
744 echo '<pubDate>'.escape($date->format(DateTime::RSS))."</pubDate>\n";
745 }
746 if ($link['tags']!='') // Adding tags to each RSS entry (as mentioned in RSS specification)
747 {
748 foreach(explode(' ',$link['tags']) as $tag) { echo '<category domain="'.$pageaddr.'">'.$tag.'</category>'."\n"; }
749 }
750
751 // Add permalink in description
752 $descriptionlink = '(<a href="'.$guid.'">Permalink</a>)';
753 // If user wants permalinks first, put the final link in description
754 if ($usepermalinks===true) $descriptionlink = '(<a href="'.$absurl.'">Link</a>)';
755 if (strlen($link['description'])>0) $descriptionlink = '<br>'.$descriptionlink;
756 echo '<description><![CDATA['.
757 format_description($link['description'], $GLOBALS['redirector']) .
758 $descriptionlink . ']]></description>' . "\n</item>\n";
759 $i++;
760 }
761 echo '</channel></rss><!-- Cached version of '.escape(page_url($_SERVER)).' -->';
762
763 $cache->cache(ob_get_contents());
764 ob_end_flush();
765 exit;
766}
767
768// ------------------------------------------------------------------------------------------
769// Output the last N links in ATOM format.
770function showATOM()
771{
772 header('Content-Type: application/atom+xml; charset=utf-8');
773
774 // $usepermalink : If true, use permalink instead of final link.
775 // User just has to add 'permalink' in URL parameters. e.g. http://mysite.com/shaarli/?do=atom&permalinks
776 $usepermalinks = isset($_GET['permalinks']) || !$GLOBALS['config']['ENABLE_RSS_PERMALINKS'];
777
778 // Cache system
779 $query = $_SERVER["QUERY_STRING"];
780 $cache = new CachedPage(
781 $GLOBALS['config']['PAGECACHE'],
782 page_url($_SERVER),
783 startsWith($query,'do=atom') && !isLoggedIn()
784 );
785 $cached = $cache->cachedVersion();
786 if (!empty($cached)) {
787 echo $cached;
788 exit;
789 }
790
791 // If cached was not found (or not usable), then read the database and build the response:
792 // Read links from database (and filter private links if used it not logged in).
793 $LINKSDB = new LinkDB(
794 $GLOBALS['config']['DATASTORE'],
795 isLoggedIn(),
796 $GLOBALS['config']['HIDE_PUBLIC_LINKS'],
797 $GLOBALS['redirector']
798 );
799
800 // Optionally filter the results:
801 $searchtags = !empty($_GET['searchtags']) ? escape($_GET['searchtags']) : '';
802 $searchterm = !empty($_GET['searchterm']) ? escape($_GET['searchterm']) : '';
803 if (! empty($searchtags) && ! empty($searchterm)) {
804 $linksToDisplay = $LINKSDB->filter(
805 LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT,
806 array($searchtags, $searchterm)
807 );
808 }
809 elseif ($searchtags) {
810 $linksToDisplay = $LINKSDB->filter(LinkFilter::$FILTER_TAG, $searchtags);
811 }
812 elseif ($searchterm) {
813 $linksToDisplay = $LINKSDB->filter(LinkFilter::$FILTER_TEXT, $searchterm);
814 }
815 else {
816 $linksToDisplay = $LINKSDB;
817 }
818
819 $nblinksToDisplay = 50; // Number of links to display.
820 // In URL, you can specificy the number of links. Example: nb=200 or nb=all for all links.
821 if (!empty($_GET['nb'])) {
822 $nblinksToDisplay = $_GET['nb']=='all' ? count($linksToDisplay) : max(intval($_GET['nb']), 1);
823 }
824
825 $pageaddr=escape(index_url($_SERVER));
826 $latestDate = '';
827 $entries='';
828 $i=0;
829 $keys=array(); foreach($linksToDisplay as $key=>$value) { $keys[]=$key; } // No, I can't use array_keys().
830 while ($i<$nblinksToDisplay && $i<count($keys))
831 {
832 $link = $linksToDisplay[$keys[$i]];
833 $guid = $pageaddr.'?'.smallHash($link['linkdate']);
834 $date = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $link['linkdate']);
835 $iso8601date = $date->format(DateTime::ISO8601);
836 $latestDate = max($latestDate, $iso8601date);
837 $absurl = $link['url'];
838 if (startsWith($absurl,'?')) $absurl=$pageaddr.$absurl; // make permalink URL absolute
839 $entries.='<entry><title>'.$link['title'].'</title>';
840 if ($usepermalinks===true)
841 $entries.='<link href="'.$guid.'" /><id>'.$guid.'</id>';
842 else
843 $entries.='<link href="'.$absurl.'" /><id>'.$guid.'</id>';
844
845 if (!$GLOBALS['config']['HIDE_TIMESTAMPS'] || isLoggedIn()) {
846 $entries.='<updated>'.escape($iso8601date).'</updated>';
847 }
848
849 // Add permalink in description
850 $descriptionlink = '(<a href="'.$guid.'">Permalink</a>)';
851 // If user wants permalinks first, put the final link in description
852 if ($usepermalinks===true) $descriptionlink = '(<a href="'.$absurl.'">Link</a>)';
853 if (strlen($link['description'])>0) $descriptionlink = '<br>'.$descriptionlink;
854
855 $entries .= '<content type="html"><![CDATA['.
856 format_description($link['description'], $GLOBALS['redirector']) .
857 $descriptionlink . "]]></content>\n";
858 if ($link['tags']!='') // Adding tags to each ATOM entry (as mentioned in ATOM specification)
859 {
860 foreach(explode(' ',$link['tags']) as $tag)
861 { $entries.='<category scheme="'.$pageaddr.'" term="'.$tag.'" />'."\n"; }
862 }
863 $entries.="</entry>\n";
864 $i++;
865 }
866 $feed='<?xml version="1.0" encoding="UTF-8"?><feed xmlns="http://www.w3.org/2005/Atom">';
867 $feed.='<title>'.$GLOBALS['title'].'</title>';
868 if (!$GLOBALS['config']['HIDE_TIMESTAMPS'] || isLoggedIn()) $feed.='<updated>'.escape($latestDate).'</updated>';
869 $feed.='<link rel="self" href="'.escape(server_url($_SERVER).$_SERVER["REQUEST_URI"]).'" />';
870 if (!empty($GLOBALS['config']['PUBSUBHUB_URL']))
871 {
872 $feed.='<!-- PubSubHubbub Discovery -->';
873 $feed.='<link rel="hub" href="'.escape($GLOBALS['config']['PUBSUBHUB_URL']).'" />';
874 $feed.='<!-- End Of PubSubHubbub Discovery -->';
875 }
876 $feed.='<author><name>'.$pageaddr.'</name><uri>'.$pageaddr.'</uri></author>';
877 $feed.='<id>'.$pageaddr.'</id>'."\n\n"; // Yes, I know I should use a real IRI (RFC3987), but the site URL will do.
878 $feed.=$entries;
879 $feed.='</feed><!-- Cached version of '.escape(page_url($_SERVER)).' -->';
880 echo $feed;
881
882 $cache->cache(ob_get_contents());
883 ob_end_flush();
884 exit;
885}
886
887// ------------------------------------------------------------------------------------------
888// Daily RSS feed: 1 RSS entry per day giving all the links on that day. 567// Daily RSS feed: 1 RSS entry per day giving all the links on that day.
889// Gives the last 7 days (which have links). 568// Gives the last 7 days (which have links).
890// This RSS feed cannot be filtered. 569// This RSS feed cannot be filtered.
891function showDailyRSS() { 570function showDailyRSS() {
892 // Cache system 571 // Cache system
893 $query = $_SERVER["QUERY_STRING"]; 572 $query = $_SERVER['QUERY_STRING'];
894 $cache = new CachedPage( 573 $cache = new CachedPage(
895 $GLOBALS['config']['PAGECACHE'], 574 $GLOBALS['config']['PAGECACHE'],
896 page_url($_SERVER), 575 page_url($_SERVER),
@@ -908,7 +587,8 @@ function showDailyRSS() {
908 $GLOBALS['config']['DATASTORE'], 587 $GLOBALS['config']['DATASTORE'],
909 isLoggedIn(), 588 isLoggedIn(),
910 $GLOBALS['config']['HIDE_PUBLIC_LINKS'], 589 $GLOBALS['config']['HIDE_PUBLIC_LINKS'],
911 $GLOBALS['redirector'] 590 $GLOBALS['redirector'],
591 $GLOBALS['config']['REDIRECTOR_URLENCODE']
912 ); 592 );
913 593
914 /* Some Shaarlies may have very few links, so we need to look 594 /* Some Shaarlies may have very few links, so we need to look
@@ -993,16 +673,10 @@ function showDailyRSS() {
993 * Show the 'Daily' page. 673 * Show the 'Daily' page.
994 * 674 *
995 * @param PageBuilder $pageBuilder Template engine wrapper. 675 * @param PageBuilder $pageBuilder Template engine wrapper.
676 * @param LinkDB $LINKSDB LinkDB instance.
996 */ 677 */
997function showDaily($pageBuilder) 678function showDaily($pageBuilder, $LINKSDB)
998{ 679{
999 $LINKSDB = new LinkDB(
1000 $GLOBALS['config']['DATASTORE'],
1001 isLoggedIn(),
1002 $GLOBALS['config']['HIDE_PUBLIC_LINKS'],
1003 $GLOBALS['redirector']
1004 );
1005
1006 $day=Date('Ymd',strtotime('-1 day')); // Yesterday, in format YYYYMMDD. 680 $day=Date('Ymd',strtotime('-1 day')); // Yesterday, in format YYYYMMDD.
1007 if (isset($_GET['day'])) $day=$_GET['day']; 681 if (isset($_GET['day'])) $day=$_GET['day'];
1008 682
@@ -1018,7 +692,7 @@ function showDaily($pageBuilder)
1018 } 692 }
1019 693
1020 try { 694 try {
1021 $linksToDisplay = $LINKSDB->filter(LinkFilter::$FILTER_DAY, $day); 695 $linksToDisplay = $LINKSDB->filterDay($day);
1022 } catch (Exception $exc) { 696 } catch (Exception $exc) {
1023 error_log($exc); 697 error_log($exc);
1024 $linksToDisplay = array(); 698 $linksToDisplay = array();
@@ -1062,7 +736,6 @@ function showDaily($pageBuilder)
1062 $dayDate = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $day.'_000000'); 736 $dayDate = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $day.'_000000');
1063 $data = array( 737 $data = array(
1064 'linksToDisplay' => $linksToDisplay, 738 'linksToDisplay' => $linksToDisplay,
1065 'linkcount' => count($LINKSDB),
1066 'cols' => $columns, 739 'cols' => $columns,
1067 'day' => $dayDate->getTimestamp(), 740 'day' => $dayDate->getTimestamp(),
1068 'previousday' => $previousday, 741 'previousday' => $previousday,
@@ -1094,7 +767,8 @@ function renderPage()
1094 $GLOBALS['config']['DATASTORE'], 767 $GLOBALS['config']['DATASTORE'],
1095 isLoggedIn(), 768 isLoggedIn(),
1096 $GLOBALS['config']['HIDE_PUBLIC_LINKS'], 769 $GLOBALS['config']['HIDE_PUBLIC_LINKS'],
1097 $GLOBALS['redirector'] 770 $GLOBALS['redirector'],
771 $GLOBALS['config']['REDIRECTOR_URLENCODE']
1098 ); 772 );
1099 773
1100 $updater = new Updater( 774 $updater = new Updater(
@@ -1116,7 +790,9 @@ function renderPage()
1116 die($e->getMessage()); 790 die($e->getMessage());
1117 } 791 }
1118 792
1119 $PAGE = new pageBuilder; 793 $PAGE = new PageBuilder();
794 $PAGE->assign('linkcount', count($LINKSDB));
795 $PAGE->assign('privateLinkcount', count_private($LINKSDB));
1120 796
1121 // Determine which page will be rendered. 797 // Determine which page will be rendered.
1122 $query = (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : ''; 798 $query = (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : '';
@@ -1147,12 +823,15 @@ function renderPage()
1147 if ($GLOBALS['config']['OPEN_SHAARLI']) { header('Location: ?'); exit; } // No need to login for open Shaarli 823 if ($GLOBALS['config']['OPEN_SHAARLI']) { header('Location: ?'); exit; } // No need to login for open Shaarli
1148 $token=''; if (ban_canLogin()) $token=getToken(); // Do not waste token generation if not useful. 824 $token=''; if (ban_canLogin()) $token=getToken(); // Do not waste token generation if not useful.
1149 $PAGE->assign('token',$token); 825 $PAGE->assign('token',$token);
826 if (isset($_GET['username'])) {
827 $PAGE->assign('username', escape($_GET['username']));
828 }
1150 $PAGE->assign('returnurl',(isset($_SERVER['HTTP_REFERER']) ? escape($_SERVER['HTTP_REFERER']):'')); 829 $PAGE->assign('returnurl',(isset($_SERVER['HTTP_REFERER']) ? escape($_SERVER['HTTP_REFERER']):''));
1151 $PAGE->renderPage('loginform'); 830 $PAGE->renderPage('loginform');
1152 exit; 831 exit;
1153 } 832 }
1154 // -------- User wants to logout. 833 // -------- User wants to logout.
1155 if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=logout')) 834 if (isset($_SERVER['QUERY_STRING']) && startsWith($_SERVER['QUERY_STRING'], 'do=logout'))
1156 { 835 {
1157 invalidateCaches($GLOBALS['config']['PAGECACHE']); 836 invalidateCaches($GLOBALS['config']['PAGECACHE']);
1158 logout(); 837 logout();
@@ -1164,24 +843,7 @@ function renderPage()
1164 if ($targetPage == Router::$PAGE_PICWALL) 843 if ($targetPage == Router::$PAGE_PICWALL)
1165 { 844 {
1166 // Optionally filter the results: 845 // Optionally filter the results:
1167 $searchtags = !empty($_GET['searchtags']) ? escape($_GET['searchtags']) : ''; 846 $links = $LINKSDB->filterSearch($_GET);
1168 $searchterm = !empty($_GET['searchterm']) ? escape($_GET['searchterm']) : '';
1169 if (! empty($searchtags) && ! empty($searchterm)) {
1170 $links = $LINKSDB->filter(
1171 LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT,
1172 array($searchtags, $searchterm)
1173 );
1174 }
1175 elseif ($searchtags) {
1176 $links = $LINKSDB->filter(LinkFilter::$FILTER_TAG, $searchtags);
1177 }
1178 elseif ($searchterm) {
1179 $links = $LINKSDB->filter(LinkFilter::$FILTER_TEXT, $searchterm);
1180 }
1181 else {
1182 $links = $LINKSDB;
1183 }
1184
1185 $linksToDisplay = array(); 847 $linksToDisplay = array();
1186 848
1187 // Get only links which have a thumbnail. 849 // Get only links which have a thumbnail.
@@ -1197,7 +859,6 @@ function renderPage()
1197 } 859 }
1198 860
1199 $data = array( 861 $data = array(
1200 'linkcount' => count($LINKSDB),
1201 'linksToDisplay' => $linksToDisplay, 862 'linksToDisplay' => $linksToDisplay,
1202 ); 863 );
1203 $pluginManager->executeHooks('render_picwall', $data, array('loggedin' => isLoggedIn())); 864 $pluginManager->executeHooks('render_picwall', $data, array('loggedin' => isLoggedIn()));
@@ -1234,15 +895,19 @@ function renderPage()
1234 return strcasecmp($a, $b); 895 return strcasecmp($a, $b);
1235 }); 896 });
1236 897
1237 $tagList=array(); 898 $tagList = array();
1238 foreach($tags as $key=>$value) 899 foreach($tags as $key => $value) {
1239 // Tag font size scaling: default 15 and 30 logarithm bases affect scaling, 22 and 6 are arbitrary font sizes for max and min sizes. 900 // Tag font size scaling:
1240 { 901 // default 15 and 30 logarithm bases affect scaling,
1241 $tagList[$key] = array('count'=>$value,'size'=>log($value, 15) / log($maxcount, 30) * (22-6) + 6); 902 // 22 and 6 are arbitrary font sizes for max and min sizes.
903 $size = log($value, 15) / log($maxcount, 30) * 2.2 + 0.8;
904 $tagList[$key] = array(
905 'count' => $value,
906 'size' => number_format($size, 2, '.', ''),
907 );
1242 } 908 }
1243 909
1244 $data = array( 910 $data = array(
1245 'linkcount' => count($LINKSDB),
1246 'tags' => $tagList, 911 'tags' => $tagList,
1247 ); 912 );
1248 $pluginManager->executeHooks('render_tagcloud', $data, array('loggedin' => isLoggedIn())); 913 $pluginManager->executeHooks('render_tagcloud', $data, array('loggedin' => isLoggedIn()));
@@ -1257,7 +922,50 @@ function renderPage()
1257 922
1258 // Daily page. 923 // Daily page.
1259 if ($targetPage == Router::$PAGE_DAILY) { 924 if ($targetPage == Router::$PAGE_DAILY) {
1260 showDaily($PAGE); 925 showDaily($PAGE, $LINKSDB);
926 }
927
928 // ATOM and RSS feed.
929 if ($targetPage == Router::$PAGE_FEED_ATOM || $targetPage == Router::$PAGE_FEED_RSS) {
930 $feedType = $targetPage == Router::$PAGE_FEED_RSS ? FeedBuilder::$FEED_RSS : FeedBuilder::$FEED_ATOM;
931 header('Content-Type: application/'. $feedType .'+xml; charset=utf-8');
932
933 // Cache system
934 $query = $_SERVER['QUERY_STRING'];
935 $cache = new CachedPage(
936 $GLOBALS['config']['PAGECACHE'],
937 page_url($_SERVER),
938 startsWith($query,'do='. $targetPage) && !isLoggedIn()
939 );
940 $cached = $cache->cachedVersion();
941 if (!empty($cached)) {
942 echo $cached;
943 exit;
944 }
945
946 // Generate data.
947 $feedGenerator = new FeedBuilder($LINKSDB, $feedType, $_SERVER, $_GET, isLoggedIn());
948 $feedGenerator->setLocale(strtolower(setlocale(LC_COLLATE, 0)));
949 $feedGenerator->setHideDates($GLOBALS['config']['HIDE_TIMESTAMPS'] && !isLoggedIn());
950 $feedGenerator->setUsePermalinks(isset($_GET['permalinks']) || !$GLOBALS['config']['ENABLE_RSS_PERMALINKS']);
951 if (!empty($GLOBALS['config']['PUBSUBHUB_URL'])) {
952 $feedGenerator->setPubsubhubUrl($GLOBALS['config']['PUBSUBHUB_URL']);
953 }
954 $data = $feedGenerator->buildData();
955
956 // Process plugin hook.
957 $pluginManager = PluginManager::getInstance();
958 $pluginManager->executeHooks('render_feed', $data, array(
959 'loggedin' => isLoggedIn(),
960 'target' => $targetPage,
961 ));
962
963 // Render the template.
964 $PAGE->assignAll($data);
965 $PAGE->renderPage('feed.'. $feedType);
966 $cache->cache(ob_get_contents());
967 ob_end_flush();
968 exit;
1261 } 969 }
1262 970
1263 // Display openseach plugin (XML) 971 // Display openseach plugin (XML)
@@ -1372,12 +1080,6 @@ function renderPage()
1372 exit; 1080 exit;
1373 } 1081 }
1374 1082
1375 // Same case as above except that user tried to access ?do=addlink without being logged in
1376 // Note: passing empty parameters makes Shaarli generate default URLs and descriptions.
1377 if (isset($_GET['do']) && $_GET['do'] === 'addlink') {
1378 header('Location: ?do=login&post=');
1379 exit;
1380 }
1381 showLinkList($PAGE, $LINKSDB); 1083 showLinkList($PAGE, $LINKSDB);
1382 if (isset($_GET['edit_link'])) { 1084 if (isset($_GET['edit_link'])) {
1383 header('Location: ?do=login&edit_link='. escape($_GET['edit_link'])); 1085 header('Location: ?do=login&edit_link='. escape($_GET['edit_link']));
@@ -1393,7 +1095,6 @@ function renderPage()
1393 if ($targetPage == Router::$PAGE_TOOLS) 1095 if ($targetPage == Router::$PAGE_TOOLS)
1394 { 1096 {
1395 $data = array( 1097 $data = array(
1396 'linkcount' => count($LINKSDB),
1397 'pageabsaddr' => index_url($_SERVER), 1098 'pageabsaddr' => index_url($_SERVER),
1398 ); 1099 );
1399 $pluginManager->executeHooks('render_tools', $data); 1100 $pluginManager->executeHooks('render_tools', $data);
@@ -1438,7 +1139,6 @@ function renderPage()
1438 } 1139 }
1439 else // show the change password form. 1140 else // show the change password form.
1440 { 1141 {
1441 $PAGE->assign('linkcount',count($LINKSDB));
1442 $PAGE->assign('token',getToken()); 1142 $PAGE->assign('token',getToken());
1443 $PAGE->renderPage('changepassword'); 1143 $PAGE->renderPage('changepassword');
1444 exit; 1144 exit;
@@ -1450,11 +1150,15 @@ function renderPage()
1450 { 1150 {
1451 if (!empty($_POST['title']) ) 1151 if (!empty($_POST['title']) )
1452 { 1152 {
1453 if (!tokenOk($_POST['token'])) die('Wrong token.'); // Go away! 1153 if (!tokenOk($_POST['token'])) {
1154 die('Wrong token.'); // Go away!
1155 }
1454 $tz = 'UTC'; 1156 $tz = 'UTC';
1455 if (!empty($_POST['continent']) && !empty($_POST['city'])) 1157 if (!empty($_POST['continent']) && !empty($_POST['city'])
1456 if (isTimeZoneValid($_POST['continent'],$_POST['city'])) 1158 && isTimeZoneValid($_POST['continent'], $_POST['city'])
1457 $tz = $_POST['continent'].'/'.$_POST['city']; 1159 ) {
1160 $tz = $_POST['continent'] . '/' . $_POST['city'];
1161 }
1458 $GLOBALS['timezone'] = $tz; 1162 $GLOBALS['timezone'] = $tz;
1459 $GLOBALS['title']=$_POST['title']; 1163 $GLOBALS['title']=$_POST['title'];
1460 $GLOBALS['titleLink']=$_POST['titleLink']; 1164 $GLOBALS['titleLink']=$_POST['titleLink'];
@@ -1482,7 +1186,6 @@ function renderPage()
1482 } 1186 }
1483 else // Show the configuration form. 1187 else // Show the configuration form.
1484 { 1188 {
1485 $PAGE->assign('linkcount',count($LINKSDB));
1486 $PAGE->assign('token',getToken()); 1189 $PAGE->assign('token',getToken());
1487 $PAGE->assign('title', empty($GLOBALS['title']) ? '' : $GLOBALS['title'] ); 1190 $PAGE->assign('title', empty($GLOBALS['title']) ? '' : $GLOBALS['title'] );
1488 $PAGE->assign('redirector', empty($GLOBALS['redirector']) ? '' : $GLOBALS['redirector'] ); 1191 $PAGE->assign('redirector', empty($GLOBALS['redirector']) ? '' : $GLOBALS['redirector'] );
@@ -1498,7 +1201,6 @@ function renderPage()
1498 if ($targetPage == Router::$PAGE_CHANGETAG) 1201 if ($targetPage == Router::$PAGE_CHANGETAG)
1499 { 1202 {
1500 if (empty($_POST['fromtag']) || (empty($_POST['totag']) && isset($_POST['renametag']))) { 1203 if (empty($_POST['fromtag']) || (empty($_POST['totag']) && isset($_POST['renametag']))) {
1501 $PAGE->assign('linkcount', count($LINKSDB));
1502 $PAGE->assign('token', getToken()); 1204 $PAGE->assign('token', getToken());
1503 $PAGE->assign('tags', $LINKSDB->allTags()); 1205 $PAGE->assign('tags', $LINKSDB->allTags());
1504 $PAGE->renderPage('changetag'); 1206 $PAGE->renderPage('changetag');
@@ -1511,9 +1213,9 @@ function renderPage()
1511 1213
1512 // Delete a tag: 1214 // Delete a tag:
1513 if (isset($_POST['deletetag']) && !empty($_POST['fromtag'])) { 1215 if (isset($_POST['deletetag']) && !empty($_POST['fromtag'])) {
1514 $needle=trim($_POST['fromtag']); 1216 $needle = trim($_POST['fromtag']);
1515 // True for case-sensitive tag search. 1217 // True for case-sensitive tag search.
1516 $linksToAlter = $LINKSDB->filter(LinkFilter::$FILTER_TAG, $needle, true); 1218 $linksToAlter = $LINKSDB->filterSearch(array('searchtags' => $needle), true);
1517 foreach($linksToAlter as $key=>$value) 1219 foreach($linksToAlter as $key=>$value)
1518 { 1220 {
1519 $tags = explode(' ',trim($value['tags'])); 1221 $tags = explode(' ',trim($value['tags']));
@@ -1528,9 +1230,9 @@ function renderPage()
1528 1230
1529 // Rename a tag: 1231 // Rename a tag:
1530 if (isset($_POST['renametag']) && !empty($_POST['fromtag']) && !empty($_POST['totag'])) { 1232 if (isset($_POST['renametag']) && !empty($_POST['fromtag']) && !empty($_POST['totag'])) {
1531 $needle=trim($_POST['fromtag']); 1233 $needle = trim($_POST['fromtag']);
1532 // True for case-sensitive tag search. 1234 // True for case-sensitive tag search.
1533 $linksToAlter = $LINKSDB->filter(LinkFilter::$FILTER_TAG, $needle, true); 1235 $linksToAlter = $LINKSDB->filterSearch(array('searchtags' => $needle), true);
1534 foreach($linksToAlter as $key=>$value) 1236 foreach($linksToAlter as $key=>$value)
1535 { 1237 {
1536 $tags = explode(' ',trim($value['tags'])); 1238 $tags = explode(' ',trim($value['tags']));
@@ -1547,7 +1249,6 @@ function renderPage()
1547 // -------- User wants to add a link without using the bookmarklet: Show form. 1249 // -------- User wants to add a link without using the bookmarklet: Show form.
1548 if ($targetPage == Router::$PAGE_ADDLINK) 1250 if ($targetPage == Router::$PAGE_ADDLINK)
1549 { 1251 {
1550 $PAGE->assign('linkcount',count($LINKSDB));
1551 $PAGE->renderPage('addlink'); 1252 $PAGE->renderPage('addlink');
1552 exit; 1253 exit;
1553 } 1254 }
@@ -1673,7 +1374,6 @@ function renderPage()
1673 $link = $LINKSDB[$_GET['edit_link']]; // Read database 1374 $link = $LINKSDB[$_GET['edit_link']]; // Read database
1674 if (!$link) { header('Location: ?'); exit; } // Link not found in database. 1375 if (!$link) { header('Location: ?'); exit; } // Link not found in database.
1675 $data = array( 1376 $data = array(
1676 'linkcount' => count($LINKSDB),
1677 'link' => $link, 1377 'link' => $link,
1678 'link_is_new' => false, 1378 'link_is_new' => false,
1679 'token' => getToken(), 1379 'token' => getToken(),
@@ -1692,7 +1392,7 @@ function renderPage()
1692 1392
1693 // -------- User want to post a new link: Display link edit form. 1393 // -------- User want to post a new link: Display link edit form.
1694 if (isset($_GET['post'])) { 1394 if (isset($_GET['post'])) {
1695 $url = cleanup_url(escape($_GET['post'])); 1395 $url = cleanup_url($_GET['post']);
1696 1396
1697 $link_is_new = false; 1397 $link_is_new = false;
1698 // Check if URL is not already in database (in this case, we will edit the existing link) 1398 // Check if URL is not already in database (in this case, we will edit the existing link)
@@ -1717,8 +1417,8 @@ function renderPage()
1717 // Extract title. 1417 // Extract title.
1718 $title = html_extract_title($content); 1418 $title = html_extract_title($content);
1719 // Re-encode title in utf-8 if necessary. 1419 // Re-encode title in utf-8 if necessary.
1720 if (! empty($title) && $charset != 'utf-8') { 1420 if (! empty($title) && strtolower($charset) != 'utf-8') {
1721 $title = mb_convert_encoding($title, $charset, 'utf-8'); 1421 $title = mb_convert_encoding($title, 'utf-8', $charset);
1722 } 1422 }
1723 } 1423 }
1724 } 1424 }
@@ -1727,6 +1427,8 @@ function renderPage()
1727 $url = '?' . smallHash($linkdate); 1427 $url = '?' . smallHash($linkdate);
1728 $title = 'Note: '; 1428 $title = 'Note: ';
1729 } 1429 }
1430 $url = escape($url);
1431 $title = escape($title);
1730 1432
1731 $link = array( 1433 $link = array(
1732 'linkdate' => $linkdate, 1434 'linkdate' => $linkdate,
@@ -1739,7 +1441,6 @@ function renderPage()
1739 } 1441 }
1740 1442
1741 $data = array( 1443 $data = array(
1742 'linkcount' => count($LINKSDB),
1743 'link' => $link, 1444 'link' => $link,
1744 'link_is_new' => $link_is_new, 1445 'link_is_new' => $link_is_new,
1745 'token' => getToken(), // XSRF protection. 1446 'token' => getToken(), // XSRF protection.
@@ -1757,49 +1458,52 @@ function renderPage()
1757 exit; 1458 exit;
1758 } 1459 }
1759 1460
1760 // -------- Export as Netscape Bookmarks HTML file. 1461 if ($targetPage == Router::$PAGE_EXPORT) {
1761 if ($targetPage == Router::$PAGE_EXPORT) 1462 // Export links as a Netscape Bookmarks file
1762 { 1463
1763 if (empty($_GET['what'])) 1464 if (empty($_GET['selection'])) {
1764 {
1765 $PAGE->assign('linkcount',count($LINKSDB));
1766 $PAGE->renderPage('export'); 1465 $PAGE->renderPage('export');
1767 exit; 1466 exit;
1768 } 1467 }
1769 $exportWhat=$_GET['what'];
1770 if (!array_intersect(array('all','public','private'),array($exportWhat))) die('What are you trying to export???');
1771 1468
1772 header('Content-Type: text/html; charset=utf-8'); 1469 // export as bookmarks_(all|private|public)_YYYYmmdd_HHMMSS.html
1773 header('Content-disposition: attachment; filename=bookmarks_'.$exportWhat.'_'.strval(date('Ymd_His')).'.html'); 1470 $selection = $_GET['selection'];
1774 $currentdate=date('Y/m/d H:i:s'); 1471 if (isset($_GET['prepend_note_url'])) {
1775 echo <<<HTML 1472 $prependNoteUrl = $_GET['prepend_note_url'];
1776<!DOCTYPE NETSCAPE-Bookmark-file-1> 1473 } else {
1777<!-- This is an automatically generated file. 1474 $prependNoteUrl = false;
1778 It will be read and overwritten.
1779 DO NOT EDIT! -->
1780<!-- Shaarli {$exportWhat} bookmarks export on {$currentdate} -->
1781<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
1782<TITLE>Bookmarks</TITLE>
1783<H1>Bookmarks</H1>
1784HTML;
1785 foreach($LINKSDB as $link)
1786 {
1787 if ($exportWhat=='all' ||
1788 ($exportWhat=='private' && $link['private']!=0) ||
1789 ($exportWhat=='public' && $link['private']==0))
1790 {
1791 $date = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $link['linkdate']);
1792 echo '<DT><A HREF="'.$link['url'].'" ADD_DATE="'.$date->getTimestamp().'" PRIVATE="'.$link['private'].'"';
1793 if ($link['tags']!='') echo ' TAGS="'.str_replace(' ',',',$link['tags']).'"';
1794 echo '>'.$link['title']."</A>\n";
1795 if ($link['description']!='') echo '<DD>'.$link['description']."\n";
1796 }
1797 } 1475 }
1798 exit; 1476
1477 try {
1478 $PAGE->assign(
1479 'links',
1480 NetscapeBookmarkUtils::filterAndFormat(
1481 $LINKSDB,
1482 $selection,
1483 $prependNoteUrl,
1484 index_url($_SERVER)
1485 )
1486 );
1487 } catch (Exception $exc) {
1488 header('Content-Type: text/plain; charset=utf-8');
1489 echo $exc->getMessage();
1490 exit;
1491 }
1492 $now = new DateTime();
1493 header('Content-Type: text/html; charset=utf-8');
1494 header(
1495 'Content-disposition: attachment; filename=bookmarks_'
1496 .$selection.'_'.$now->format(LinkDB::LINK_DATE_FORMAT).'.html'
1497 );
1498 $PAGE->assign('date', $now->format(DateTime::RFC822));
1499 $PAGE->assign('eol', PHP_EOL);
1500 $PAGE->assign('selection', $selection);
1501 $PAGE->renderPage('export.bookmarks');
1502 exit;
1799 } 1503 }
1800 1504
1801 // -------- User is uploading a file for import 1505 // -------- User is uploading a file for import
1802 if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=upload')) 1506 if (isset($_SERVER['QUERY_STRING']) && startsWith($_SERVER['QUERY_STRING'], 'do=upload'))
1803 { 1507 {
1804 // If file is too big, some form field may be missing. 1508 // If file is too big, some form field may be missing.
1805 if (!isset($_POST['token']) || (!isset($_FILES)) || (isset($_FILES['filetoupload']['size']) && $_FILES['filetoupload']['size']==0)) 1509 if (!isset($_POST['token']) || (!isset($_FILES)) || (isset($_FILES['filetoupload']['size']) && $_FILES['filetoupload']['size']==0))
@@ -1809,14 +1513,13 @@ HTML;
1809 exit; 1513 exit;
1810 } 1514 }
1811 if (!tokenOk($_POST['token'])) die('Wrong token.'); 1515 if (!tokenOk($_POST['token'])) die('Wrong token.');
1812 importFile(); 1516 importFile($LINKSDB);
1813 exit; 1517 exit;
1814 } 1518 }
1815 1519
1816 // -------- Show upload/import dialog: 1520 // -------- Show upload/import dialog:
1817 if ($targetPage == Router::$PAGE_IMPORT) 1521 if ($targetPage == Router::$PAGE_IMPORT)
1818 { 1522 {
1819 $PAGE->assign('linkcount',count($LINKSDB));
1820 $PAGE->assign('token',getToken()); 1523 $PAGE->assign('token',getToken());
1821 $PAGE->assign('maxfilesize',getMaxFileSize()); 1524 $PAGE->assign('maxfilesize',getMaxFileSize());
1822 $PAGE->renderPage('import'); 1525 $PAGE->renderPage('import');
@@ -1878,15 +1581,10 @@ HTML;
1878 1581
1879// ----------------------------------------------------------------------------------------------- 1582// -----------------------------------------------------------------------------------------------
1880// Process the import file form. 1583// Process the import file form.
1881function importFile() 1584function importFile($LINKSDB)
1882{ 1585{
1883 if (!isLoggedIn()) { die('Not allowed.'); } 1586 if (!isLoggedIn()) { die('Not allowed.'); }
1884 $LINKSDB = new LinkDB( 1587
1885 $GLOBALS['config']['DATASTORE'],
1886 isLoggedIn(),
1887 $GLOBALS['config']['HIDE_PUBLIC_LINKS'],
1888 $GLOBALS['redirector']
1889 );
1890 $filename=$_FILES['filetoupload']['name']; 1588 $filename=$_FILES['filetoupload']['name'];
1891 $filesize=$_FILES['filetoupload']['size']; 1589 $filesize=$_FILES['filetoupload']['size'];
1892 $data=file_get_contents($_FILES['filetoupload']['tmp_name']); 1590 $data=file_get_contents($_FILES['filetoupload']['tmp_name']);
@@ -1907,7 +1605,7 @@ function importFile()
1907 { 1605 {
1908 $link = array('linkdate'=>'','title'=>'','url'=>'','description'=>'','tags'=>'','private'=>0); 1606 $link = array('linkdate'=>'','title'=>'','url'=>'','description'=>'','tags'=>'','private'=>0);
1909 $d = explode('<DD>',$html); 1607 $d = explode('<DD>',$html);
1910 if (startswith($d[0],'<A ')) 1608 if (startsWith($d[0], '<A '))
1911 { 1609 {
1912 $link['description'] = (isset($d[1]) ? html_entity_decode(trim($d[1]),ENT_QUOTES,'UTF-8') : ''); // Get description (optional) 1610 $link['description'] = (isset($d[1]) ? html_entity_decode(trim($d[1]),ENT_QUOTES,'UTF-8') : ''); // Get description (optional)
1913 preg_match('!<A .*?>(.*?)</A>!i',$d[0],$matches); $link['title'] = (isset($matches[1]) ? trim($matches[1]) : ''); // Get title 1611 preg_match('!<A .*?>(.*?)</A>!i',$d[0],$matches); $link['title'] = (isset($matches[1]) ? trim($matches[1]) : ''); // Get title
@@ -1966,60 +1664,32 @@ function importFile()
1966 } 1664 }
1967} 1665}
1968 1666
1969// ----------------------------------------------------------------------------------------------- 1667/**
1970// Template for the list of links (<div id="linklist">) 1668 * Template for the list of links (<div id="linklist">)
1971// This function fills all the necessary fields in the $PAGE for the template 'linklist.html' 1669 * This function fills all the necessary fields in the $PAGE for the template 'linklist.html'
1670 *
1671 * @param pageBuilder $PAGE pageBuilder instance.
1672 * @param LinkDB $LINKSDB LinkDB instance.
1673 */
1972function buildLinkList($PAGE,$LINKSDB) 1674function buildLinkList($PAGE,$LINKSDB)
1973{ 1675{
1974 // Filter link database according to parameters. 1676 // Used in templates
1975 $searchtags = !empty($_GET['searchtags']) ? escape($_GET['searchtags']) : ''; 1677 $searchtags = !empty($_GET['searchtags']) ? escape($_GET['searchtags']) : '';
1976 $searchterm = !empty($_GET['searchterm']) ? escape(trim($_GET['searchterm'])) : ''; 1678 $searchterm = !empty($_GET['searchterm']) ? escape($_GET['searchterm']) : '';
1977 $privateonly = !empty($_SESSION['privateonly']) ? true : false;
1978
1979 // Search tags + fullsearch.
1980 if (! empty($searchtags) && ! empty($searchterm)) {
1981 $linksToDisplay = $LINKSDB->filter(
1982 LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT,
1983 array($searchtags, $searchterm),
1984 false,
1985 $privateonly
1986 );
1987 }
1988 // Search by tags.
1989 elseif (! empty($searchtags)) {
1990 $linksToDisplay = $LINKSDB->filter(
1991 LinkFilter::$FILTER_TAG,
1992 $searchtags,
1993 false,
1994 $privateonly
1995 );
1996 }
1997 // Fulltext search.
1998 elseif (! empty($searchterm)) {
1999 $linksToDisplay = $LINKSDB->filter(
2000 LinkFilter::$FILTER_TEXT,
2001 $searchterm,
2002 false,
2003 $privateonly
2004 );
2005 }
2006 // Detect smallHashes in URL.
2007 elseif (! empty($_SERVER['QUERY_STRING'])
2008 && preg_match('/[a-zA-Z0-9-_@]{6}(&.+?)?/', $_SERVER['QUERY_STRING'])
2009 ) {
2010 $linksToDisplay = $LINKSDB->filter(
2011 LinkFilter::$FILTER_HASH,
2012 substr(trim($_SERVER["QUERY_STRING"], '/'), 0, 6)
2013 );
2014 1679
2015 if (count($linksToDisplay) == 0) { 1680 // Smallhash filter
2016 $PAGE->render404('The link you are trying to reach does not exist or has been deleted.'); 1681 if (! empty($_SERVER['QUERY_STRING'])
1682 && preg_match('/^[a-zA-Z0-9-_@]{6}($|&|#)/', $_SERVER['QUERY_STRING'])) {
1683 try {
1684 $linksToDisplay = $LINKSDB->filterHash($_SERVER['QUERY_STRING']);
1685 } catch (LinkNotFoundException $e) {
1686 $PAGE->render404($e->getMessage());
2017 exit; 1687 exit;
2018 } 1688 }
2019 } 1689 } else {
2020 // Otherwise, display without filtering. 1690 // Filter links according search parameters.
2021 else { 1691 $privateonly = !empty($_SESSION['privateonly']);
2022 $linksToDisplay = $LINKSDB->filter('', '', false, $privateonly); 1692 $linksToDisplay = $LINKSDB->filterSearch($_GET, false, $privateonly);
2023 } 1693 }
2024 1694
2025 // ---- Handle paging. 1695 // ---- Handle paging.
@@ -2081,7 +1751,6 @@ function buildLinkList($PAGE,$LINKSDB)
2081 1751
2082 // Fill all template fields. 1752 // Fill all template fields.
2083 $data = array( 1753 $data = array(
2084 'linkcount' => count($LINKSDB),
2085 'previous_page_url' => $previous_page_url, 1754 'previous_page_url' => $previous_page_url,
2086 'next_page_url' => $next_page_url, 1755 'next_page_url' => $next_page_url,
2087 'page_current' => $page, 1756 'page_current' => $page,
@@ -2320,10 +1989,10 @@ function install()
2320 if (!empty($_POST['setlogin']) && !empty($_POST['setpassword'])) 1989 if (!empty($_POST['setlogin']) && !empty($_POST['setpassword']))
2321 { 1990 {
2322 $tz = 'UTC'; 1991 $tz = 'UTC';
2323 if (!empty($_POST['continent']) && !empty($_POST['city'])) { 1992 if (!empty($_POST['continent']) && !empty($_POST['city'])
2324 if (isTimeZoneValid($_POST['continent'], $_POST['city'])) { 1993 && isTimeZoneValid($_POST['continent'], $_POST['city'])
2325 $tz = $_POST['continent'].'/'.$_POST['city']; 1994 ) {
2326 } 1995 $tz = $_POST['continent'].'/'.$_POST['city'];
2327 } 1996 }
2328 $GLOBALS['timezone'] = $tz; 1997 $GLOBALS['timezone'] = $tz;
2329 // Everything is ok, let's create config file. 1998 // Everything is ok, let's create config file.
@@ -2356,7 +2025,7 @@ function install()
2356 $timezone_html = '<tr><td><b>Timezone:</b></td><td>'.$timezone_form.'</td></tr>'; 2025 $timezone_html = '<tr><td><b>Timezone:</b></td><td>'.$timezone_form.'</td></tr>';
2357 } 2026 }
2358 2027
2359 $PAGE = new pageBuilder; 2028 $PAGE = new PageBuilder();
2360 $PAGE->assign('timezone_html',$timezone_html); 2029 $PAGE->assign('timezone_html',$timezone_html);
2361 $PAGE->assign('timezone_js',$timezone_js); 2030 $PAGE->assign('timezone_js',$timezone_js);
2362 $PAGE->renderPage('install'); 2031 $PAGE->renderPage('install');
@@ -2406,7 +2075,7 @@ function genThumbnail()
2406 2075
2407 // Is this a link to an image, or to a flickr page ? 2076 // Is this a link to an image, or to a flickr page ?
2408 $imageurl=''; 2077 $imageurl='';
2409 if (endswith(parse_url($url,PHP_URL_PATH),'.jpg')) 2078 if (endsWith(parse_url($url, PHP_URL_PATH), '.jpg'))
2410 { // This is a direct link to an image. e.g. http://farm1.staticflickr.com/5/5921913_ac83ed27bd_o.jpg 2079 { // This is a direct link to an image. e.g. http://farm1.staticflickr.com/5/5921913_ac83ed27bd_o.jpg
2411 preg_match('!(http://farm\d+\.staticflickr\.com/\d+/\d+_\w+_)\w.jpg!',$url,$matches); 2080 preg_match('!(http://farm\d+\.staticflickr\.com/\d+/\d+_\w+_)\w.jpg!',$url,$matches);
2412 if (!empty($matches[1])) $imageurl=$matches[1].'m.jpg'; 2081 if (!empty($matches[1])) $imageurl=$matches[1].'m.jpg';
@@ -2583,10 +2252,8 @@ function resizeImage($filepath)
2583 return true; 2252 return true;
2584} 2253}
2585 2254
2586if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=genthumbnail')) { genThumbnail(); exit; } // Thumbnail generation/cache does not need the link database. 2255if (isset($_SERVER['QUERY_STRING']) && startsWith($_SERVER['QUERY_STRING'], 'do=genthumbnail')) { genThumbnail(); exit; } // Thumbnail generation/cache does not need the link database.
2587if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=rss')) { showRSS(); exit; } 2256if (isset($_SERVER['QUERY_STRING']) && startsWith($_SERVER['QUERY_STRING'], 'do=dailyrss')) { showDailyRSS(); exit; }
2588if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=atom')) { showATOM(); exit; }
2589if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=dailyrss')) { showDailyRSS(); exit; }
2590if (!isset($_SESSION['LINKS_PER_PAGE'])) $_SESSION['LINKS_PER_PAGE']=$GLOBALS['config']['LINKS_PER_PAGE']; 2257if (!isset($_SESSION['LINKS_PER_PAGE'])) $_SESSION['LINKS_PER_PAGE']=$GLOBALS['config']['LINKS_PER_PAGE'];
2591renderPage(); 2258renderPage();
2592?> 2259?>