aboutsummaryrefslogtreecommitdiffhomepage
path: root/index.php
diff options
context:
space:
mode:
Diffstat (limited to 'index.php')
-rw-r--r--index.php317
1 files changed, 95 insertions, 222 deletions
diff --git a/index.php b/index.php
index dfc00fbd..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)));
@@ -160,6 +161,8 @@ require_once 'application/HttpUtils.php';
160require_once 'application/LinkDB.php'; 161require_once 'application/LinkDB.php';
161require_once 'application/LinkFilter.php'; 162require_once 'application/LinkFilter.php';
162require_once 'application/LinkUtils.php'; 163require_once 'application/LinkUtils.php';
164require_once 'application/NetscapeBookmarkUtils.php';
165require_once 'application/PageBuilder.php';
163require_once 'application/TimeZone.php'; 166require_once 'application/TimeZone.php';
164require_once 'application/Url.php'; 167require_once 'application/Url.php';
165require_once 'application/Utils.php'; 168require_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*/
571class 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.
689function showDailyRSS() { 570function 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 */
795function showDaily($pageBuilder) 678function 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>
1608HTML;
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.
1705function importFile() 1584function 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
2382if (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.
2383if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=dailyrss')) { showDailyRSS(); exit; } 2256if (isset($_SERVER['QUERY_STRING']) && startsWith($_SERVER['QUERY_STRING'], 'do=dailyrss')) { showDailyRSS(); exit; }
2384if (!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'];
2385renderPage(); 2258renderPage();
2386?> 2259?>