diff options
Diffstat (limited to 'index.php')
-rw-r--r-- | index.php | 317 |
1 files changed, 95 insertions, 222 deletions
@@ -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 | */ |
128 | define('shaarli_version', '0.6.5'); | 129 | define('shaarli_version', '0.7.0'); |
129 | 130 | ||
130 | // http://server.com/x/shaarli --> /shaarli/ | 131 | // http://server.com/x/shaarli --> /shaarli/ |
131 | define('WEB_PATH', substr($_SERVER["REQUEST_URI"], 0, 1+strrpos($_SERVER["REQUEST_URI"], '/', 0))); | 132 | define('WEB_PATH', substr($_SERVER["REQUEST_URI"], 0, 1+strrpos($_SERVER["REQUEST_URI"], '/', 0))); |
@@ -160,6 +161,8 @@ require_once 'application/HttpUtils.php'; | |||
160 | require_once 'application/LinkDB.php'; | 161 | require_once 'application/LinkDB.php'; |
161 | require_once 'application/LinkFilter.php'; | 162 | require_once 'application/LinkFilter.php'; |
162 | require_once 'application/LinkUtils.php'; | 163 | require_once 'application/LinkUtils.php'; |
164 | require_once 'application/NetscapeBookmarkUtils.php'; | ||
165 | require_once 'application/PageBuilder.php'; | ||
163 | require_once 'application/TimeZone.php'; | 166 | require_once 'application/TimeZone.php'; |
164 | require_once 'application/Url.php'; | 167 | require_once 'application/Url.php'; |
165 | require_once 'application/Utils.php'; | 168 | require_once 'application/Utils.php'; |
@@ -493,9 +496,9 @@ if (isset($_POST['login'])) | |||
493 | else | 496 | else |
494 | { | 497 | { |
495 | ban_loginFailed(); | 498 | ban_loginFailed(); |
496 | $redir = ''; | 499 | $redir = '&username='. $_POST['login']; |
497 | if (isset($_GET['post'])) { | 500 | if (isset($_GET['post'])) { |
498 | $redir = '?post=' . urlencode($_GET['post']); | 501 | $redir .= '&post=' . urlencode($_GET['post']); |
499 | foreach (array('description', 'source', 'title') as $param) { | 502 | foreach (array('description', 'source', 'title') as $param) { |
500 | if (!empty($_GET[$param])) { | 503 | if (!empty($_GET[$param])) { |
501 | $redir .= '&' . $param . '=' . urlencode($_GET[$param]); | 504 | $redir .= '&' . $param . '=' . urlencode($_GET[$param]); |
@@ -561,134 +564,12 @@ function tokenOk($token) | |||
561 | } | 564 | } |
562 | 565 | ||
563 | // ------------------------------------------------------------------------------------------ | 566 | // ------------------------------------------------------------------------------------------ |
564 | /* This class is in charge of building the final page. | ||
565 | (This is basically a wrapper around RainTPL which pre-fills some fields.) | ||
566 | p = new pageBuilder; | ||
567 | p.assign('myfield','myvalue'); | ||
568 | p.renderPage('mytemplate'); | ||
569 | |||
570 | */ | ||
571 | class pageBuilder | ||
572 | { | ||
573 | private $tpl; // RainTPL template | ||
574 | |||
575 | function __construct() | ||
576 | { | ||
577 | $this->tpl = false; | ||
578 | } | ||
579 | |||
580 | /** | ||
581 | * Initialize all default tpl tags. | ||
582 | */ | ||
583 | private function initialize() | ||
584 | { | ||
585 | $this->tpl = new RainTPL; | ||
586 | |||
587 | try { | ||
588 | $version = ApplicationUtils::checkUpdate( | ||
589 | shaarli_version, | ||
590 | $GLOBALS['config']['UPDATECHECK_FILENAME'], | ||
591 | $GLOBALS['config']['UPDATECHECK_INTERVAL'], | ||
592 | $GLOBALS['config']['ENABLE_UPDATECHECK'], | ||
593 | isLoggedIn(), | ||
594 | $GLOBALS['config']['UPDATECHECK_BRANCH'] | ||
595 | ); | ||
596 | $this->tpl->assign('newVersion', escape($version)); | ||
597 | $this->tpl->assign('versionError', ''); | ||
598 | |||
599 | } catch (Exception $exc) { | ||
600 | logm($GLOBALS['config']['LOG_FILE'], $_SERVER['REMOTE_ADDR'], $exc->getMessage()); | ||
601 | $this->tpl->assign('newVersion', ''); | ||
602 | $this->tpl->assign('versionError', escape($exc->getMessage())); | ||
603 | } | ||
604 | |||
605 | $this->tpl->assign('feedurl', escape(index_url($_SERVER))); | ||
606 | $searchcrits = ''; // Search criteria | ||
607 | if (!empty($_GET['searchtags'])) { | ||
608 | $searchcrits .= '&searchtags=' . urlencode($_GET['searchtags']); | ||
609 | } | ||
610 | if (!empty($_GET['searchterm'])) { | ||
611 | $searchcrits .= '&searchterm=' . urlencode($_GET['searchterm']); | ||
612 | } | ||
613 | $this->tpl->assign('searchcrits', $searchcrits); | ||
614 | $this->tpl->assign('source', index_url($_SERVER)); | ||
615 | $this->tpl->assign('version', shaarli_version); | ||
616 | $this->tpl->assign('scripturl', index_url($_SERVER)); | ||
617 | $this->tpl->assign('pagetitle', 'Shaarli'); | ||
618 | $this->tpl->assign('privateonly', !empty($_SESSION['privateonly'])); // Show only private links? | ||
619 | if (!empty($GLOBALS['title'])) { | ||
620 | $this->tpl->assign('pagetitle', $GLOBALS['title']); | ||
621 | } | ||
622 | if (!empty($GLOBALS['titleLink'])) { | ||
623 | $this->tpl->assign('titleLink', $GLOBALS['titleLink']); | ||
624 | } | ||
625 | if (!empty($GLOBALS['pagetitle'])) { | ||
626 | $this->tpl->assign('pagetitle', $GLOBALS['pagetitle']); | ||
627 | } | ||
628 | $this->tpl->assign('shaarlititle', empty($GLOBALS['title']) ? 'Shaarli': $GLOBALS['title']); | ||
629 | if (!empty($GLOBALS['plugin_errors'])) { | ||
630 | $this->tpl->assign('plugin_errors', $GLOBALS['plugin_errors']); | ||
631 | } | ||
632 | } | ||
633 | |||
634 | // The following assign() method is basically the same as RainTPL (except that it's lazy) | ||
635 | public function assign($what,$where) | ||
636 | { | ||
637 | if ($this->tpl===false) $this->initialize(); // Lazy initialization | ||
638 | $this->tpl->assign($what,$where); | ||
639 | } | ||
640 | |||
641 | /** | ||
642 | * Assign an array of data to the template builder. | ||
643 | * | ||
644 | * @param array $data Data to assign. | ||
645 | * | ||
646 | * @return false if invalid data. | ||
647 | */ | ||
648 | public function assignAll($data) | ||
649 | { | ||
650 | // Lazy initialization | ||
651 | if ($this->tpl === false) { | ||
652 | $this->initialize(); | ||
653 | } | ||
654 | |||
655 | if (empty($data) || !is_array($data)){ | ||
656 | return false; | ||
657 | } | ||
658 | |||
659 | foreach ($data as $key => $value) { | ||
660 | $this->assign($key, $value); | ||
661 | } | ||
662 | } | ||
663 | |||
664 | // Render a specific page (using a template). | ||
665 | // e.g. pb.renderPage('picwall') | ||
666 | public function renderPage($page) | ||
667 | { | ||
668 | if ($this->tpl===false) $this->initialize(); // Lazy initialization | ||
669 | $this->tpl->draw($page); | ||
670 | } | ||
671 | |||
672 | /** | ||
673 | * Render a 404 page (uses the template : tpl/404.tpl) | ||
674 | * | ||
675 | * usage : $PAGE->render404('The link was deleted') | ||
676 | * @param string $message A messate to display what is not found | ||
677 | */ | ||
678 | public function render404($message='The page you are trying to reach does not exist or has been deleted.') { | ||
679 | header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found'); | ||
680 | $this->tpl->assign('error_message', $message); | ||
681 | $this->renderPage('404'); | ||
682 | } | ||
683 | } | ||
684 | |||
685 | // ------------------------------------------------------------------------------------------ | ||
686 | // 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. |
687 | // Gives the last 7 days (which have links). | 568 | // Gives the last 7 days (which have links). |
688 | // This RSS feed cannot be filtered. | 569 | // This RSS feed cannot be filtered. |
689 | function showDailyRSS() { | 570 | function showDailyRSS() { |
690 | // Cache system | 571 | // Cache system |
691 | $query = $_SERVER["QUERY_STRING"]; | 572 | $query = $_SERVER['QUERY_STRING']; |
692 | $cache = new CachedPage( | 573 | $cache = new CachedPage( |
693 | $GLOBALS['config']['PAGECACHE'], | 574 | $GLOBALS['config']['PAGECACHE'], |
694 | page_url($_SERVER), | 575 | page_url($_SERVER), |
@@ -706,7 +587,8 @@ function showDailyRSS() { | |||
706 | $GLOBALS['config']['DATASTORE'], | 587 | $GLOBALS['config']['DATASTORE'], |
707 | isLoggedIn(), | 588 | isLoggedIn(), |
708 | $GLOBALS['config']['HIDE_PUBLIC_LINKS'], | 589 | $GLOBALS['config']['HIDE_PUBLIC_LINKS'], |
709 | $GLOBALS['redirector'] | 590 | $GLOBALS['redirector'], |
591 | $GLOBALS['config']['REDIRECTOR_URLENCODE'] | ||
710 | ); | 592 | ); |
711 | 593 | ||
712 | /* 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 |
@@ -791,16 +673,10 @@ function showDailyRSS() { | |||
791 | * Show the 'Daily' page. | 673 | * Show the 'Daily' page. |
792 | * | 674 | * |
793 | * @param PageBuilder $pageBuilder Template engine wrapper. | 675 | * @param PageBuilder $pageBuilder Template engine wrapper. |
676 | * @param LinkDB $LINKSDB LinkDB instance. | ||
794 | */ | 677 | */ |
795 | function showDaily($pageBuilder) | 678 | function showDaily($pageBuilder, $LINKSDB) |
796 | { | 679 | { |
797 | $LINKSDB = new LinkDB( | ||
798 | $GLOBALS['config']['DATASTORE'], | ||
799 | isLoggedIn(), | ||
800 | $GLOBALS['config']['HIDE_PUBLIC_LINKS'], | ||
801 | $GLOBALS['redirector'] | ||
802 | ); | ||
803 | |||
804 | $day=Date('Ymd',strtotime('-1 day')); // Yesterday, in format YYYYMMDD. | 680 | $day=Date('Ymd',strtotime('-1 day')); // Yesterday, in format YYYYMMDD. |
805 | if (isset($_GET['day'])) $day=$_GET['day']; | 681 | if (isset($_GET['day'])) $day=$_GET['day']; |
806 | 682 | ||
@@ -860,7 +736,6 @@ function showDaily($pageBuilder) | |||
860 | $dayDate = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $day.'_000000'); | 736 | $dayDate = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $day.'_000000'); |
861 | $data = array( | 737 | $data = array( |
862 | 'linksToDisplay' => $linksToDisplay, | 738 | 'linksToDisplay' => $linksToDisplay, |
863 | 'linkcount' => count($LINKSDB), | ||
864 | 'cols' => $columns, | 739 | 'cols' => $columns, |
865 | 'day' => $dayDate->getTimestamp(), | 740 | 'day' => $dayDate->getTimestamp(), |
866 | 'previousday' => $previousday, | 741 | 'previousday' => $previousday, |
@@ -892,7 +767,8 @@ function renderPage() | |||
892 | $GLOBALS['config']['DATASTORE'], | 767 | $GLOBALS['config']['DATASTORE'], |
893 | isLoggedIn(), | 768 | isLoggedIn(), |
894 | $GLOBALS['config']['HIDE_PUBLIC_LINKS'], | 769 | $GLOBALS['config']['HIDE_PUBLIC_LINKS'], |
895 | $GLOBALS['redirector'] | 770 | $GLOBALS['redirector'], |
771 | $GLOBALS['config']['REDIRECTOR_URLENCODE'] | ||
896 | ); | 772 | ); |
897 | 773 | ||
898 | $updater = new Updater( | 774 | $updater = new Updater( |
@@ -914,7 +790,9 @@ function renderPage() | |||
914 | die($e->getMessage()); | 790 | die($e->getMessage()); |
915 | } | 791 | } |
916 | 792 | ||
917 | $PAGE = new pageBuilder; | 793 | $PAGE = new PageBuilder(); |
794 | $PAGE->assign('linkcount', count($LINKSDB)); | ||
795 | $PAGE->assign('privateLinkcount', count_private($LINKSDB)); | ||
918 | 796 | ||
919 | // Determine which page will be rendered. | 797 | // Determine which page will be rendered. |
920 | $query = (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : ''; | 798 | $query = (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : ''; |
@@ -945,12 +823,15 @@ function renderPage() | |||
945 | 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 |
946 | $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. |
947 | $PAGE->assign('token',$token); | 825 | $PAGE->assign('token',$token); |
826 | if (isset($_GET['username'])) { | ||
827 | $PAGE->assign('username', escape($_GET['username'])); | ||
828 | } | ||
948 | $PAGE->assign('returnurl',(isset($_SERVER['HTTP_REFERER']) ? escape($_SERVER['HTTP_REFERER']):'')); | 829 | $PAGE->assign('returnurl',(isset($_SERVER['HTTP_REFERER']) ? escape($_SERVER['HTTP_REFERER']):'')); |
949 | $PAGE->renderPage('loginform'); | 830 | $PAGE->renderPage('loginform'); |
950 | exit; | 831 | exit; |
951 | } | 832 | } |
952 | // -------- User wants to logout. | 833 | // -------- User wants to logout. |
953 | if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=logout')) | 834 | if (isset($_SERVER['QUERY_STRING']) && startsWith($_SERVER['QUERY_STRING'], 'do=logout')) |
954 | { | 835 | { |
955 | invalidateCaches($GLOBALS['config']['PAGECACHE']); | 836 | invalidateCaches($GLOBALS['config']['PAGECACHE']); |
956 | logout(); | 837 | logout(); |
@@ -978,7 +859,6 @@ function renderPage() | |||
978 | } | 859 | } |
979 | 860 | ||
980 | $data = array( | 861 | $data = array( |
981 | 'linkcount' => count($LINKSDB), | ||
982 | 'linksToDisplay' => $linksToDisplay, | 862 | 'linksToDisplay' => $linksToDisplay, |
983 | ); | 863 | ); |
984 | $pluginManager->executeHooks('render_picwall', $data, array('loggedin' => isLoggedIn())); | 864 | $pluginManager->executeHooks('render_picwall', $data, array('loggedin' => isLoggedIn())); |
@@ -1015,15 +895,19 @@ function renderPage() | |||
1015 | return strcasecmp($a, $b); | 895 | return strcasecmp($a, $b); |
1016 | }); | 896 | }); |
1017 | 897 | ||
1018 | $tagList=array(); | 898 | $tagList = array(); |
1019 | foreach($tags as $key=>$value) | 899 | foreach($tags as $key => $value) { |
1020 | // 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: |
1021 | { | 901 | // default 15 and 30 logarithm bases affect scaling, |
1022 | $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 | ); | ||
1023 | } | 908 | } |
1024 | 909 | ||
1025 | $data = array( | 910 | $data = array( |
1026 | 'linkcount' => count($LINKSDB), | ||
1027 | 'tags' => $tagList, | 911 | 'tags' => $tagList, |
1028 | ); | 912 | ); |
1029 | $pluginManager->executeHooks('render_tagcloud', $data, array('loggedin' => isLoggedIn())); | 913 | $pluginManager->executeHooks('render_tagcloud', $data, array('loggedin' => isLoggedIn())); |
@@ -1038,7 +922,7 @@ function renderPage() | |||
1038 | 922 | ||
1039 | // Daily page. | 923 | // Daily page. |
1040 | if ($targetPage == Router::$PAGE_DAILY) { | 924 | if ($targetPage == Router::$PAGE_DAILY) { |
1041 | showDaily($PAGE); | 925 | showDaily($PAGE, $LINKSDB); |
1042 | } | 926 | } |
1043 | 927 | ||
1044 | // ATOM and RSS feed. | 928 | // ATOM and RSS feed. |
@@ -1196,12 +1080,6 @@ function renderPage() | |||
1196 | exit; | 1080 | exit; |
1197 | } | 1081 | } |
1198 | 1082 | ||
1199 | // Same case as above except that user tried to access ?do=addlink without being logged in | ||
1200 | // Note: passing empty parameters makes Shaarli generate default URLs and descriptions. | ||
1201 | if (isset($_GET['do']) && $_GET['do'] === 'addlink') { | ||
1202 | header('Location: ?do=login&post='); | ||
1203 | exit; | ||
1204 | } | ||
1205 | showLinkList($PAGE, $LINKSDB); | 1083 | showLinkList($PAGE, $LINKSDB); |
1206 | if (isset($_GET['edit_link'])) { | 1084 | if (isset($_GET['edit_link'])) { |
1207 | header('Location: ?do=login&edit_link='. escape($_GET['edit_link'])); | 1085 | header('Location: ?do=login&edit_link='. escape($_GET['edit_link'])); |
@@ -1217,7 +1095,6 @@ function renderPage() | |||
1217 | if ($targetPage == Router::$PAGE_TOOLS) | 1095 | if ($targetPage == Router::$PAGE_TOOLS) |
1218 | { | 1096 | { |
1219 | $data = array( | 1097 | $data = array( |
1220 | 'linkcount' => count($LINKSDB), | ||
1221 | 'pageabsaddr' => index_url($_SERVER), | 1098 | 'pageabsaddr' => index_url($_SERVER), |
1222 | ); | 1099 | ); |
1223 | $pluginManager->executeHooks('render_tools', $data); | 1100 | $pluginManager->executeHooks('render_tools', $data); |
@@ -1262,7 +1139,6 @@ function renderPage() | |||
1262 | } | 1139 | } |
1263 | else // show the change password form. | 1140 | else // show the change password form. |
1264 | { | 1141 | { |
1265 | $PAGE->assign('linkcount',count($LINKSDB)); | ||
1266 | $PAGE->assign('token',getToken()); | 1142 | $PAGE->assign('token',getToken()); |
1267 | $PAGE->renderPage('changepassword'); | 1143 | $PAGE->renderPage('changepassword'); |
1268 | exit; | 1144 | exit; |
@@ -1274,11 +1150,15 @@ function renderPage() | |||
1274 | { | 1150 | { |
1275 | if (!empty($_POST['title']) ) | 1151 | if (!empty($_POST['title']) ) |
1276 | { | 1152 | { |
1277 | if (!tokenOk($_POST['token'])) die('Wrong token.'); // Go away! | 1153 | if (!tokenOk($_POST['token'])) { |
1154 | die('Wrong token.'); // Go away! | ||
1155 | } | ||
1278 | $tz = 'UTC'; | 1156 | $tz = 'UTC'; |
1279 | if (!empty($_POST['continent']) && !empty($_POST['city'])) | 1157 | if (!empty($_POST['continent']) && !empty($_POST['city']) |
1280 | if (isTimeZoneValid($_POST['continent'],$_POST['city'])) | 1158 | && isTimeZoneValid($_POST['continent'], $_POST['city']) |
1281 | $tz = $_POST['continent'].'/'.$_POST['city']; | 1159 | ) { |
1160 | $tz = $_POST['continent'] . '/' . $_POST['city']; | ||
1161 | } | ||
1282 | $GLOBALS['timezone'] = $tz; | 1162 | $GLOBALS['timezone'] = $tz; |
1283 | $GLOBALS['title']=$_POST['title']; | 1163 | $GLOBALS['title']=$_POST['title']; |
1284 | $GLOBALS['titleLink']=$_POST['titleLink']; | 1164 | $GLOBALS['titleLink']=$_POST['titleLink']; |
@@ -1306,7 +1186,6 @@ function renderPage() | |||
1306 | } | 1186 | } |
1307 | else // Show the configuration form. | 1187 | else // Show the configuration form. |
1308 | { | 1188 | { |
1309 | $PAGE->assign('linkcount',count($LINKSDB)); | ||
1310 | $PAGE->assign('token',getToken()); | 1189 | $PAGE->assign('token',getToken()); |
1311 | $PAGE->assign('title', empty($GLOBALS['title']) ? '' : $GLOBALS['title'] ); | 1190 | $PAGE->assign('title', empty($GLOBALS['title']) ? '' : $GLOBALS['title'] ); |
1312 | $PAGE->assign('redirector', empty($GLOBALS['redirector']) ? '' : $GLOBALS['redirector'] ); | 1191 | $PAGE->assign('redirector', empty($GLOBALS['redirector']) ? '' : $GLOBALS['redirector'] ); |
@@ -1322,7 +1201,6 @@ function renderPage() | |||
1322 | if ($targetPage == Router::$PAGE_CHANGETAG) | 1201 | if ($targetPage == Router::$PAGE_CHANGETAG) |
1323 | { | 1202 | { |
1324 | if (empty($_POST['fromtag']) || (empty($_POST['totag']) && isset($_POST['renametag']))) { | 1203 | if (empty($_POST['fromtag']) || (empty($_POST['totag']) && isset($_POST['renametag']))) { |
1325 | $PAGE->assign('linkcount', count($LINKSDB)); | ||
1326 | $PAGE->assign('token', getToken()); | 1204 | $PAGE->assign('token', getToken()); |
1327 | $PAGE->assign('tags', $LINKSDB->allTags()); | 1205 | $PAGE->assign('tags', $LINKSDB->allTags()); |
1328 | $PAGE->renderPage('changetag'); | 1206 | $PAGE->renderPage('changetag'); |
@@ -1371,7 +1249,6 @@ function renderPage() | |||
1371 | // -------- 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. |
1372 | if ($targetPage == Router::$PAGE_ADDLINK) | 1250 | if ($targetPage == Router::$PAGE_ADDLINK) |
1373 | { | 1251 | { |
1374 | $PAGE->assign('linkcount',count($LINKSDB)); | ||
1375 | $PAGE->renderPage('addlink'); | 1252 | $PAGE->renderPage('addlink'); |
1376 | exit; | 1253 | exit; |
1377 | } | 1254 | } |
@@ -1497,7 +1374,6 @@ function renderPage() | |||
1497 | $link = $LINKSDB[$_GET['edit_link']]; // Read database | 1374 | $link = $LINKSDB[$_GET['edit_link']]; // Read database |
1498 | if (!$link) { header('Location: ?'); exit; } // Link not found in database. | 1375 | if (!$link) { header('Location: ?'); exit; } // Link not found in database. |
1499 | $data = array( | 1376 | $data = array( |
1500 | 'linkcount' => count($LINKSDB), | ||
1501 | 'link' => $link, | 1377 | 'link' => $link, |
1502 | 'link_is_new' => false, | 1378 | 'link_is_new' => false, |
1503 | 'token' => getToken(), | 1379 | 'token' => getToken(), |
@@ -1516,7 +1392,7 @@ function renderPage() | |||
1516 | 1392 | ||
1517 | // -------- User want to post a new link: Display link edit form. | 1393 | // -------- User want to post a new link: Display link edit form. |
1518 | if (isset($_GET['post'])) { | 1394 | if (isset($_GET['post'])) { |
1519 | $url = cleanup_url(escape($_GET['post'])); | 1395 | $url = cleanup_url($_GET['post']); |
1520 | 1396 | ||
1521 | $link_is_new = false; | 1397 | $link_is_new = false; |
1522 | // 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) |
@@ -1541,8 +1417,8 @@ function renderPage() | |||
1541 | // Extract title. | 1417 | // Extract title. |
1542 | $title = html_extract_title($content); | 1418 | $title = html_extract_title($content); |
1543 | // Re-encode title in utf-8 if necessary. | 1419 | // Re-encode title in utf-8 if necessary. |
1544 | if (! empty($title) && $charset != 'utf-8') { | 1420 | if (! empty($title) && strtolower($charset) != 'utf-8') { |
1545 | $title = mb_convert_encoding($title, $charset, 'utf-8'); | 1421 | $title = mb_convert_encoding($title, 'utf-8', $charset); |
1546 | } | 1422 | } |
1547 | } | 1423 | } |
1548 | } | 1424 | } |
@@ -1551,6 +1427,8 @@ function renderPage() | |||
1551 | $url = '?' . smallHash($linkdate); | 1427 | $url = '?' . smallHash($linkdate); |
1552 | $title = 'Note: '; | 1428 | $title = 'Note: '; |
1553 | } | 1429 | } |
1430 | $url = escape($url); | ||
1431 | $title = escape($title); | ||
1554 | 1432 | ||
1555 | $link = array( | 1433 | $link = array( |
1556 | 'linkdate' => $linkdate, | 1434 | 'linkdate' => $linkdate, |
@@ -1563,7 +1441,6 @@ function renderPage() | |||
1563 | } | 1441 | } |
1564 | 1442 | ||
1565 | $data = array( | 1443 | $data = array( |
1566 | 'linkcount' => count($LINKSDB), | ||
1567 | 'link' => $link, | 1444 | 'link' => $link, |
1568 | 'link_is_new' => $link_is_new, | 1445 | 'link_is_new' => $link_is_new, |
1569 | 'token' => getToken(), // XSRF protection. | 1446 | 'token' => getToken(), // XSRF protection. |
@@ -1581,49 +1458,52 @@ function renderPage() | |||
1581 | exit; | 1458 | exit; |
1582 | } | 1459 | } |
1583 | 1460 | ||
1584 | // -------- Export as Netscape Bookmarks HTML file. | 1461 | if ($targetPage == Router::$PAGE_EXPORT) { |
1585 | if ($targetPage == Router::$PAGE_EXPORT) | 1462 | // Export links as a Netscape Bookmarks file |
1586 | { | 1463 | |
1587 | if (empty($_GET['what'])) | 1464 | if (empty($_GET['selection'])) { |
1588 | { | ||
1589 | $PAGE->assign('linkcount',count($LINKSDB)); | ||
1590 | $PAGE->renderPage('export'); | 1465 | $PAGE->renderPage('export'); |
1591 | exit; | 1466 | exit; |
1592 | } | 1467 | } |
1593 | $exportWhat=$_GET['what']; | ||
1594 | if (!array_intersect(array('all','public','private'),array($exportWhat))) die('What are you trying to export???'); | ||
1595 | 1468 | ||
1596 | header('Content-Type: text/html; charset=utf-8'); | 1469 | // export as bookmarks_(all|private|public)_YYYYmmdd_HHMMSS.html |
1597 | header('Content-disposition: attachment; filename=bookmarks_'.$exportWhat.'_'.strval(date('Ymd_His')).'.html'); | 1470 | $selection = $_GET['selection']; |
1598 | $currentdate=date('Y/m/d H:i:s'); | 1471 | if (isset($_GET['prepend_note_url'])) { |
1599 | echo <<<HTML | 1472 | $prependNoteUrl = $_GET['prepend_note_url']; |
1600 | <!DOCTYPE NETSCAPE-Bookmark-file-1> | 1473 | } else { |
1601 | <!-- This is an automatically generated file. | 1474 | $prependNoteUrl = false; |
1602 | It will be read and overwritten. | ||
1603 | DO NOT EDIT! --> | ||
1604 | <!-- Shaarli {$exportWhat} bookmarks export on {$currentdate} --> | ||
1605 | <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8"> | ||
1606 | <TITLE>Bookmarks</TITLE> | ||
1607 | <H1>Bookmarks</H1> | ||
1608 | HTML; | ||
1609 | foreach($LINKSDB as $link) | ||
1610 | { | ||
1611 | if ($exportWhat=='all' || | ||
1612 | ($exportWhat=='private' && $link['private']!=0) || | ||
1613 | ($exportWhat=='public' && $link['private']==0)) | ||
1614 | { | ||
1615 | $date = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $link['linkdate']); | ||
1616 | echo '<DT><A HREF="'.$link['url'].'" ADD_DATE="'.$date->getTimestamp().'" PRIVATE="'.$link['private'].'"'; | ||
1617 | if ($link['tags']!='') echo ' TAGS="'.str_replace(' ',',',$link['tags']).'"'; | ||
1618 | echo '>'.$link['title']."</A>\n"; | ||
1619 | if ($link['description']!='') echo '<DD>'.$link['description']."\n"; | ||
1620 | } | ||
1621 | } | 1475 | } |
1622 | 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; | ||
1623 | } | 1503 | } |
1624 | 1504 | ||
1625 | // -------- User is uploading a file for import | 1505 | // -------- User is uploading a file for import |
1626 | if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=upload')) | 1506 | if (isset($_SERVER['QUERY_STRING']) && startsWith($_SERVER['QUERY_STRING'], 'do=upload')) |
1627 | { | 1507 | { |
1628 | // If file is too big, some form field may be missing. | 1508 | // If file is too big, some form field may be missing. |
1629 | 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)) |
@@ -1633,14 +1513,13 @@ HTML; | |||
1633 | exit; | 1513 | exit; |
1634 | } | 1514 | } |
1635 | if (!tokenOk($_POST['token'])) die('Wrong token.'); | 1515 | if (!tokenOk($_POST['token'])) die('Wrong token.'); |
1636 | importFile(); | 1516 | importFile($LINKSDB); |
1637 | exit; | 1517 | exit; |
1638 | } | 1518 | } |
1639 | 1519 | ||
1640 | // -------- Show upload/import dialog: | 1520 | // -------- Show upload/import dialog: |
1641 | if ($targetPage == Router::$PAGE_IMPORT) | 1521 | if ($targetPage == Router::$PAGE_IMPORT) |
1642 | { | 1522 | { |
1643 | $PAGE->assign('linkcount',count($LINKSDB)); | ||
1644 | $PAGE->assign('token',getToken()); | 1523 | $PAGE->assign('token',getToken()); |
1645 | $PAGE->assign('maxfilesize',getMaxFileSize()); | 1524 | $PAGE->assign('maxfilesize',getMaxFileSize()); |
1646 | $PAGE->renderPage('import'); | 1525 | $PAGE->renderPage('import'); |
@@ -1702,15 +1581,10 @@ HTML; | |||
1702 | 1581 | ||
1703 | // ----------------------------------------------------------------------------------------------- | 1582 | // ----------------------------------------------------------------------------------------------- |
1704 | // Process the import file form. | 1583 | // Process the import file form. |
1705 | function importFile() | 1584 | function importFile($LINKSDB) |
1706 | { | 1585 | { |
1707 | if (!isLoggedIn()) { die('Not allowed.'); } | 1586 | if (!isLoggedIn()) { die('Not allowed.'); } |
1708 | $LINKSDB = new LinkDB( | 1587 | |
1709 | $GLOBALS['config']['DATASTORE'], | ||
1710 | isLoggedIn(), | ||
1711 | $GLOBALS['config']['HIDE_PUBLIC_LINKS'], | ||
1712 | $GLOBALS['redirector'] | ||
1713 | ); | ||
1714 | $filename=$_FILES['filetoupload']['name']; | 1588 | $filename=$_FILES['filetoupload']['name']; |
1715 | $filesize=$_FILES['filetoupload']['size']; | 1589 | $filesize=$_FILES['filetoupload']['size']; |
1716 | $data=file_get_contents($_FILES['filetoupload']['tmp_name']); | 1590 | $data=file_get_contents($_FILES['filetoupload']['tmp_name']); |
@@ -1731,7 +1605,7 @@ function importFile() | |||
1731 | { | 1605 | { |
1732 | $link = array('linkdate'=>'','title'=>'','url'=>'','description'=>'','tags'=>'','private'=>0); | 1606 | $link = array('linkdate'=>'','title'=>'','url'=>'','description'=>'','tags'=>'','private'=>0); |
1733 | $d = explode('<DD>',$html); | 1607 | $d = explode('<DD>',$html); |
1734 | if (startswith($d[0],'<A ')) | 1608 | if (startsWith($d[0], '<A ')) |
1735 | { | 1609 | { |
1736 | $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) |
1737 | 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 |
@@ -1877,7 +1751,6 @@ function buildLinkList($PAGE,$LINKSDB) | |||
1877 | 1751 | ||
1878 | // Fill all template fields. | 1752 | // Fill all template fields. |
1879 | $data = array( | 1753 | $data = array( |
1880 | 'linkcount' => count($LINKSDB), | ||
1881 | 'previous_page_url' => $previous_page_url, | 1754 | 'previous_page_url' => $previous_page_url, |
1882 | 'next_page_url' => $next_page_url, | 1755 | 'next_page_url' => $next_page_url, |
1883 | 'page_current' => $page, | 1756 | 'page_current' => $page, |
@@ -2116,10 +1989,10 @@ function install() | |||
2116 | if (!empty($_POST['setlogin']) && !empty($_POST['setpassword'])) | 1989 | if (!empty($_POST['setlogin']) && !empty($_POST['setpassword'])) |
2117 | { | 1990 | { |
2118 | $tz = 'UTC'; | 1991 | $tz = 'UTC'; |
2119 | if (!empty($_POST['continent']) && !empty($_POST['city'])) { | 1992 | if (!empty($_POST['continent']) && !empty($_POST['city']) |
2120 | if (isTimeZoneValid($_POST['continent'], $_POST['city'])) { | 1993 | && isTimeZoneValid($_POST['continent'], $_POST['city']) |
2121 | $tz = $_POST['continent'].'/'.$_POST['city']; | 1994 | ) { |
2122 | } | 1995 | $tz = $_POST['continent'].'/'.$_POST['city']; |
2123 | } | 1996 | } |
2124 | $GLOBALS['timezone'] = $tz; | 1997 | $GLOBALS['timezone'] = $tz; |
2125 | // Everything is ok, let's create config file. | 1998 | // Everything is ok, let's create config file. |
@@ -2152,7 +2025,7 @@ function install() | |||
2152 | $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>'; |
2153 | } | 2026 | } |
2154 | 2027 | ||
2155 | $PAGE = new pageBuilder; | 2028 | $PAGE = new PageBuilder(); |
2156 | $PAGE->assign('timezone_html',$timezone_html); | 2029 | $PAGE->assign('timezone_html',$timezone_html); |
2157 | $PAGE->assign('timezone_js',$timezone_js); | 2030 | $PAGE->assign('timezone_js',$timezone_js); |
2158 | $PAGE->renderPage('install'); | 2031 | $PAGE->renderPage('install'); |
@@ -2202,7 +2075,7 @@ function genThumbnail() | |||
2202 | 2075 | ||
2203 | // 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 ? |
2204 | $imageurl=''; | 2077 | $imageurl=''; |
2205 | if (endswith(parse_url($url,PHP_URL_PATH),'.jpg')) | 2078 | if (endsWith(parse_url($url, PHP_URL_PATH), '.jpg')) |
2206 | { // 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 |
2207 | 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); |
2208 | if (!empty($matches[1])) $imageurl=$matches[1].'m.jpg'; | 2081 | if (!empty($matches[1])) $imageurl=$matches[1].'m.jpg'; |
@@ -2379,8 +2252,8 @@ function resizeImage($filepath) | |||
2379 | return true; | 2252 | return true; |
2380 | } | 2253 | } |
2381 | 2254 | ||
2382 | if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=genthumbnail')) { genThumbnail(); exit; } // Thumbnail generation/cache does not need the link database. | 2255 | if (isset($_SERVER['QUERY_STRING']) && startsWith($_SERVER['QUERY_STRING'], 'do=genthumbnail')) { genThumbnail(); exit; } // Thumbnail generation/cache does not need the link database. |
2383 | if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=dailyrss')) { showDailyRSS(); exit; } | 2256 | if (isset($_SERVER['QUERY_STRING']) && startsWith($_SERVER['QUERY_STRING'], 'do=dailyrss')) { showDailyRSS(); exit; } |
2384 | if (!isset($_SESSION['LINKS_PER_PAGE'])) $_SESSION['LINKS_PER_PAGE']=$GLOBALS['config']['LINKS_PER_PAGE']; | 2257 | if (!isset($_SESSION['LINKS_PER_PAGE'])) $_SESSION['LINKS_PER_PAGE']=$GLOBALS['config']['LINKS_PER_PAGE']; |
2385 | renderPage(); | 2258 | renderPage(); |
2386 | ?> | 2259 | ?> |