aboutsummaryrefslogtreecommitdiffhomepage
path: root/index.php
diff options
context:
space:
mode:
Diffstat (limited to 'index.php')
-rw-r--r--index.php67
1 files changed, 34 insertions, 33 deletions
diff --git a/index.php b/index.php
index 38958a79..47293240 100644
--- a/index.php
+++ b/index.php
@@ -89,7 +89,7 @@ header("Cache-Control: post-check=0, pre-check=0", false);
89header("Pragma: no-cache"); 89header("Pragma: no-cache");
90 90
91// Directories creations (Note that your web host may require different rights than 705.) 91// Directories creations (Note that your web host may require different rights than 705.)
92if (!is_writable(realpath(dirname(__FILE__)))) die('<pre>ERROR: Shaarli does not have the right to write in its own directory ('.realpath(dirname(__FILE__)).').</pre>'); 92if (!is_writable(realpath(dirname(__FILE__)))) die('<pre>ERROR: Shaarli does not have the right to write in its own directory.</pre>');
93 93
94// Handling of old config file which do not have the new parameters. 94// Handling of old config file which do not have the new parameters.
95if (empty($GLOBALS['title'])) $GLOBALS['title']='Shared links on '.htmlspecialchars(indexUrl()); 95if (empty($GLOBALS['title'])) $GLOBALS['title']='Shared links on '.htmlspecialchars(indexUrl());
@@ -118,7 +118,7 @@ function checkphpversion()
118 if (version_compare(PHP_VERSION, '5.1.0') < 0) 118 if (version_compare(PHP_VERSION, '5.1.0') < 0)
119 { 119 {
120 header('Content-Type: text/plain; charset=utf-8'); 120 header('Content-Type: text/plain; charset=utf-8');
121 echo 'Your server supports PHP '.PHP_VERSION.'. Shaarli requires at least php 5.1.0, and thus cannot run. Sorry.'; 121 echo 'Your PHP version is obsolete! Shaarli requires at least php 5.1.0, and thus cannot run. Sorry. Your PHP version has known security vulnerabilities and should be updated as soon as possible.';
122 exit; 122 exit;
123 } 123 }
124} 124}
@@ -430,7 +430,7 @@ if (isset($_POST['login']))
430 ban_loginFailed(); 430 ban_loginFailed();
431 $redir = ''; 431 $redir = '';
432 if (isset($_GET['post'])) { $redir = '&post='.urlencode($_GET['post']).(!empty($_GET['title'])?'&title='.urlencode($_GET['title']):'').(!empty($_GET['description'])?'&description='.urlencode($_GET['description']):'').(!empty($_GET['source'])?'&source='.urlencode($_GET['source']):''); } 432 if (isset($_GET['post'])) { $redir = '&post='.urlencode($_GET['post']).(!empty($_GET['title'])?'&title='.urlencode($_GET['title']):'').(!empty($_GET['description'])?'&description='.urlencode($_GET['description']):'').(!empty($_GET['source'])?'&source='.urlencode($_GET['source']):''); }
433 echo '<script language="JavaScript">alert("Wrong login/password.");document.location=\'?do=login'.$redir.'\';</script>'; // Redirect to login screen. 433 echo '<script>alert("Wrong login/password.");document.location=\'?do=login'.$redir.'\';</script>'; // Redirect to login screen.
434 exit; 434 exit;
435 } 435 }
436} 436}
@@ -794,14 +794,16 @@ class linkdb implements Iterator, Countable, ArrayAccess
794 { 794 {
795 // FIXME: explode(' ',$searchterms) and perform a AND search. 795 // FIXME: explode(' ',$searchterms) and perform a AND search.
796 // FIXME: accept double-quotes to search for a string "as is"? 796 // FIXME: accept double-quotes to search for a string "as is"?
797 // Using mb_convert_case($val, MB_CASE_LOWER, 'UTF-8') allows us to perform searches on
798 // Unicode text. See https://github.com/shaarli/Shaarli/issues/75 for examples.
797 $filtered=array(); 799 $filtered=array();
798 $s = strtolower($searchterms); 800 $s = mb_convert_case($searchterms, MB_CASE_LOWER, 'UTF-8');
799 foreach($this->links as $l) 801 foreach($this->links as $l)
800 { 802 {
801 $found= (strpos(strtolower($l['title']),$s)!==false) 803 $found= (strpos(mb_convert_case($l['title'], MB_CASE_LOWER, 'UTF-8'),$s) !== false)
802 || (strpos(strtolower($l['description']),$s)!==false) 804 || (strpos(mb_convert_case($l['description'], MB_CASE_LOWER, 'UTF-8'),$s) !== false)
803 || (strpos(strtolower($l['url']),$s)!==false) 805 || (strpos(mb_convert_case($l['url'], MB_CASE_LOWER, 'UTF-8'),$s) !== false)
804 || (strpos(strtolower($l['tags']),$s)!==false); 806 || (strpos(mb_convert_case($l['tags'], MB_CASE_LOWER, 'UTF-8'),$s) !== false);
805 if ($found) $filtered[$l['linkdate']] = $l; 807 if ($found) $filtered[$l['linkdate']] = $l;
806 } 808 }
807 krsort($filtered); 809 krsort($filtered);
@@ -813,12 +815,14 @@ class linkdb implements Iterator, Countable, ArrayAccess
813 // e.g. print_r($mydb->filterTags('linux programming')); 815 // e.g. print_r($mydb->filterTags('linux programming'));
814 public function filterTags($tags,$casesensitive=false) 816 public function filterTags($tags,$casesensitive=false)
815 { 817 {
816 $t = str_replace(',',' ',($casesensitive?$tags:strtolower($tags))); 818 // Same as above, we use UTF-8 conversion to handle various graphemes (i.e. cyrillic, or greek)
819 // TODO: is $casesensitive ever true ?
820 $t = str_replace(',',' ',($casesensitive?$tags:mb_convert_case($tags, MB_CASE_LOWER, 'UTF-8')));
817 $searchtags=explode(' ',$t); 821 $searchtags=explode(' ',$t);
818 $filtered=array(); 822 $filtered=array();
819 foreach($this->links as $l) 823 foreach($this->links as $l)
820 { 824 {
821 $linktags = explode(' ',($casesensitive?$l['tags']:strtolower($l['tags']))); 825 $linktags = explode(' ',($casesensitive?$l['tags']:mb_convert_case($l['tags'], MB_CASE_LOWER, 'UTF-8')));
822 if (count(array_intersect($linktags,$searchtags)) == count($searchtags)) 826 if (count(array_intersect($linktags,$searchtags)) == count($searchtags))
823 $filtered[$l['linkdate']] = $l; 827 $filtered[$l['linkdate']] = $l;
824 } 828 }
@@ -1147,6 +1151,7 @@ function showDaily()
1147 $linksToDisplay[$key]['taglist']=$taglist; 1151 $linksToDisplay[$key]['taglist']=$taglist;
1148 $linksToDisplay[$key]['formatedDescription']=nl2br(keepMultipleSpaces(text2clickable(htmlspecialchars($link['description'])))); 1152 $linksToDisplay[$key]['formatedDescription']=nl2br(keepMultipleSpaces(text2clickable(htmlspecialchars($link['description']))));
1149 $linksToDisplay[$key]['thumbnail'] = thumbnail($link['url']); 1153 $linksToDisplay[$key]['thumbnail'] = thumbnail($link['url']);
1154 $linksToDisplay[$key]['localdate'] = linkdate2locale($link['linkdate']);
1150 } 1155 }
1151 1156
1152 /* We need to spread the articles on 3 columns. 1157 /* We need to spread the articles on 3 columns.
@@ -1173,10 +1178,7 @@ function showDaily()
1173 $PAGE = new pageBuilder; 1178 $PAGE = new pageBuilder;
1174 $PAGE->assign('linksToDisplay',$linksToDisplay); 1179 $PAGE->assign('linksToDisplay',$linksToDisplay);
1175 $PAGE->assign('linkcount',count($LINKSDB)); 1180 $PAGE->assign('linkcount',count($LINKSDB));
1176 $PAGE->assign('col1',$columns[0]); 1181 $PAGE->assign('cols', $columns);
1177 $PAGE->assign('col1',$columns[0]);
1178 $PAGE->assign('col2',$columns[1]);
1179 $PAGE->assign('col3',$columns[2]);
1180 $PAGE->assign('day',utf8_encode(strftime('%A %d, %B %Y',linkdate2timestamp($day.'_000000')))); 1182 $PAGE->assign('day',utf8_encode(strftime('%A %d, %B %Y',linkdate2timestamp($day.'_000000'))));
1181 $PAGE->assign('previousday',$previousday); 1183 $PAGE->assign('previousday',$previousday);
1182 $PAGE->assign('nextday',$nextday); 1184 $PAGE->assign('nextday',$nextday);
@@ -1251,8 +1253,9 @@ function renderPage()
1251 ksort($tags); 1253 ksort($tags);
1252 $tagList=array(); 1254 $tagList=array();
1253 foreach($tags as $key=>$value) 1255 foreach($tags as $key=>$value)
1256 // Tag font size scaling: default 15 and 30 logarithm bases affect scaling, 22 and 6 are arbitrary font sizes for max and min sizes.
1254 { 1257 {
1255 $tagList[$key] = array('count'=>$value,'size'=>max(40*$value/$maxcount,8)); 1258 $tagList[$key] = array('count'=>$value,'size'=>log($value, 15) / log($maxcount, 30) * (22-6) + 6);
1256 } 1259 }
1257 $PAGE = new pageBuilder; 1260 $PAGE = new pageBuilder;
1258 $PAGE->assign('linkcount',count($LINKSDB)); 1261 $PAGE->assign('linkcount',count($LINKSDB));
@@ -1385,12 +1388,12 @@ function renderPage()
1385 1388
1386 // Make sure old password is correct. 1389 // Make sure old password is correct.
1387 $oldhash = sha1($_POST['oldpassword'].$GLOBALS['login'].$GLOBALS['salt']); 1390 $oldhash = sha1($_POST['oldpassword'].$GLOBALS['login'].$GLOBALS['salt']);
1388 if ($oldhash!=$GLOBALS['hash']) { echo '<script language="JavaScript">alert("The old password is not correct.");document.location=\'?do=changepasswd\';</script>'; exit; } 1391 if ($oldhash!=$GLOBALS['hash']) { echo '<script>alert("The old password is not correct.");document.location=\'?do=changepasswd\';</script>'; exit; }
1389 // Save new password 1392 // Save new password
1390 $GLOBALS['salt'] = sha1(uniqid('',true).'_'.mt_rand()); // Salt renders rainbow-tables attacks useless. 1393 $GLOBALS['salt'] = sha1(uniqid('',true).'_'.mt_rand()); // Salt renders rainbow-tables attacks useless.
1391 $GLOBALS['hash'] = sha1($_POST['setpassword'].$GLOBALS['login'].$GLOBALS['salt']); 1394 $GLOBALS['hash'] = sha1($_POST['setpassword'].$GLOBALS['login'].$GLOBALS['salt']);
1392 writeConfig(); 1395 writeConfig();
1393 echo '<script language="JavaScript">alert("Your password has been changed.");document.location=\'?do=tools\';</script>'; 1396 echo '<script>alert("Your password has been changed.");document.location=\'?do=tools\';</script>';
1394 exit; 1397 exit;
1395 } 1398 }
1396 else // show the change password form. 1399 else // show the change password form.
@@ -1421,7 +1424,7 @@ function renderPage()
1421 $GLOBALS['disablejquery']=!empty($_POST['disablejquery']); 1424 $GLOBALS['disablejquery']=!empty($_POST['disablejquery']);
1422 $GLOBALS['privateLinkByDefault']=!empty($_POST['privateLinkByDefault']); 1425 $GLOBALS['privateLinkByDefault']=!empty($_POST['privateLinkByDefault']);
1423 writeConfig(); 1426 writeConfig();
1424 echo '<script language="JavaScript">alert("Configuration was saved.");document.location=\'?do=tools\';</script>'; 1427 echo '<script>alert("Configuration was saved.");document.location=\'?do=tools\';</script>';
1425 exit; 1428 exit;
1426 } 1429 }
1427 else // Show the configuration form. 1430 else // Show the configuration form.
@@ -1465,7 +1468,7 @@ function renderPage()
1465 $LINKSDB[$key]=$value; 1468 $LINKSDB[$key]=$value;
1466 } 1469 }
1467 $LINKSDB->savedb(); // Save to disk. 1470 $LINKSDB->savedb(); // Save to disk.
1468 echo '<script language="JavaScript">alert("Tag was removed from '.count($linksToAlter).' links.");document.location=\'?\';</script>'; 1471 echo '<script>alert("Tag was removed from '.count($linksToAlter).' links.");document.location=\'?\';</script>';
1469 exit; 1472 exit;
1470 } 1473 }
1471 1474
@@ -1482,7 +1485,7 @@ function renderPage()
1482 $LINKSDB[$key]=$value; 1485 $LINKSDB[$key]=$value;
1483 } 1486 }
1484 $LINKSDB->savedb(); // Save to disk. 1487 $LINKSDB->savedb(); // Save to disk.
1485 echo '<script language="JavaScript">alert("Tag was renamed in '.count($linksToAlter).' links.");document.location=\'?searchtags='.urlencode($_POST['totag']).'\';</script>'; 1488 echo '<script>alert("Tag was renamed in '.count($linksToAlter).' links.");document.location=\'?searchtags='.urlencode($_POST['totag']).'\';</script>';
1486 exit; 1489 exit;
1487 } 1490 }
1488 } 1491 }
@@ -1513,7 +1516,7 @@ function renderPage()
1513 pubsubhub(); 1516 pubsubhub();
1514 1517
1515 // If we are called from the bookmarklet, we must close the popup: 1518 // If we are called from the bookmarklet, we must close the popup:
1516 if (isset($_GET['source']) && $_GET['source']=='bookmarklet') { echo '<script language="JavaScript">self.close();</script>'; exit; } 1519 if (isset($_GET['source']) && $_GET['source']=='bookmarklet') { echo '<script>self.close();</script>'; exit; }
1517 $returnurl = ( isset($_POST['returnurl']) ? $_POST['returnurl'] : '?' ); 1520 $returnurl = ( isset($_POST['returnurl']) ? $_POST['returnurl'] : '?' );
1518 $returnurl .= '#'.smallHash($linkdate); // Scroll to the link which has been edited. 1521 $returnurl .= '#'.smallHash($linkdate); // Scroll to the link which has been edited.
1519 header('Location: '.$returnurl); // After saving the link, redirect to the page the user was on. 1522 header('Location: '.$returnurl); // After saving the link, redirect to the page the user was on.
@@ -1524,7 +1527,7 @@ function renderPage()
1524 if (isset($_POST['cancel_edit'])) 1527 if (isset($_POST['cancel_edit']))
1525 { 1528 {
1526 // If we are called from the bookmarklet, we must close the popup: 1529 // If we are called from the bookmarklet, we must close the popup:
1527 if (isset($_GET['source']) && $_GET['source']=='bookmarklet') { echo '<script language="JavaScript">self.close();</script>'; exit; } 1530 if (isset($_GET['source']) && $_GET['source']=='bookmarklet') { echo '<script>self.close();</script>'; exit; }
1528 $returnurl = ( isset($_POST['returnurl']) ? $_POST['returnurl'] : '?' ); 1531 $returnurl = ( isset($_POST['returnurl']) ? $_POST['returnurl'] : '?' );
1529 $returnurl .= '#'.smallHash($_POST['lf_linkdate']); // Scroll to the link which has been edited. 1532 $returnurl .= '#'.smallHash($_POST['lf_linkdate']); // Scroll to the link which has been edited.
1530 header('Location: '.$returnurl); // After canceling, redirect to the page the user was on. 1533 header('Location: '.$returnurl); // After canceling, redirect to the page the user was on.
@@ -1543,10 +1546,8 @@ function renderPage()
1543 $LINKSDB->savedb(); // save to disk 1546 $LINKSDB->savedb(); // save to disk
1544 1547
1545 // If we are called from the bookmarklet, we must close the popup: 1548 // If we are called from the bookmarklet, we must close the popup:
1546 if (isset($_GET['source']) && $_GET['source']=='bookmarklet') { echo '<script language="JavaScript">self.close();</script>'; exit; } 1549 if (isset($_GET['source']) && $_GET['source']=='bookmarklet') { echo '<script>self.close();</script>'; exit; }
1547 $returnurl = ( isset($_POST['returnurl']) ? $_POST['returnurl'] : '?' ); 1550 header('Location: ?'); // After deleting the link, redirect to the home page.
1548 if ($returnurl=='?') { $returnurl = (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '?'); }
1549 header('Location: '.$returnurl); // After deleting the link, redirect to the page the user was on.
1550 exit; 1551 exit;
1551 } 1552 }
1552 1553
@@ -1681,7 +1682,7 @@ HTML;
1681 if (!isset($_POST['token']) || (!isset($_FILES)) || (isset($_FILES['filetoupload']['size']) && $_FILES['filetoupload']['size']==0)) 1682 if (!isset($_POST['token']) || (!isset($_FILES)) || (isset($_FILES['filetoupload']['size']) && $_FILES['filetoupload']['size']==0))
1682 { 1683 {
1683 $returnurl = ( empty($_SERVER['HTTP_REFERER']) ? '?' : $_SERVER['HTTP_REFERER'] ); 1684 $returnurl = ( empty($_SERVER['HTTP_REFERER']) ? '?' : $_SERVER['HTTP_REFERER'] );
1684 echo '<script language="JavaScript">alert("The file you are trying to upload is probably bigger than what this webserver can accept ('.getMaxFileSize().' bytes). Please upload in smaller chunks.");document.location=\''.htmlspecialchars($returnurl).'\';</script>'; 1685 echo '<script>alert("The file you are trying to upload is probably bigger than what this webserver can accept ('.getMaxFileSize().' bytes). Please upload in smaller chunks.");document.location=\''.htmlspecialchars($returnurl).'\';</script>';
1685 exit; 1686 exit;
1686 } 1687 }
1687 if (!tokenOk($_POST['token'])) die('Wrong token.'); 1688 if (!tokenOk($_POST['token'])) die('Wrong token.');
@@ -1785,11 +1786,11 @@ function importFile()
1785 } 1786 }
1786 $LINKSDB->savedb(); 1787 $LINKSDB->savedb();
1787 1788
1788 echo '<script language="JavaScript">alert("File '.json_encode($filename).' ('.$filesize.' bytes) was successfully processed: '.$import_count.' links imported.");document.location=\'?\';</script>'; 1789 echo '<script>alert("File '.json_encode($filename).' ('.$filesize.' bytes) was successfully processed: '.$import_count.' links imported.");document.location=\'?\';</script>';
1789 } 1790 }
1790 else 1791 else
1791 { 1792 {
1792 echo '<script language="JavaScript">alert("File '.json_encode($filename).' ('.$filesize.' bytes) has an unknown file format. Nothing was imported.");document.location=\'?\';</script>'; 1793 echo '<script>alert("File '.json_encode($filename).' ('.$filesize.' bytes) has an unknown file format. Nothing was imported.");document.location=\'?\';</script>';
1793 } 1794 }
1794} 1795}
1795 1796
@@ -2123,13 +2124,13 @@ function install()
2123 $GLOBALS['hash'] = sha1($_POST['setpassword'].$GLOBALS['login'].$GLOBALS['salt']); 2124 $GLOBALS['hash'] = sha1($_POST['setpassword'].$GLOBALS['login'].$GLOBALS['salt']);
2124 $GLOBALS['title'] = (empty($_POST['title']) ? 'Shared links on '.htmlspecialchars(indexUrl()) : $_POST['title'] ); 2125 $GLOBALS['title'] = (empty($_POST['title']) ? 'Shared links on '.htmlspecialchars(indexUrl()) : $_POST['title'] );
2125 writeConfig(); 2126 writeConfig();
2126 echo '<script language="JavaScript">alert("Shaarli is now configured. Please enter your login/password and start shaaring your links!");document.location=\'?do=login\';</script>'; 2127 echo '<script>alert("Shaarli is now configured. Please enter your login/password and start shaaring your links!");document.location=\'?do=login\';</script>';
2127 exit; 2128 exit;
2128 } 2129 }
2129 2130
2130 // Display config form: 2131 // Display config form:
2131 list($timezone_form,$timezone_js) = templateTZform(); 2132 list($timezone_form,$timezone_js) = templateTZform();
2132 $timezone_html=''; if ($timezone_form!='') $timezone_html='<tr><td valign="top"><b>Timezone:</b></td><td>'.$timezone_form.'</td></tr>'; 2133 $timezone_html=''; if ($timezone_form!='') $timezone_html='<tr><td><b>Timezone:</b></td><td>'.$timezone_form.'</td></tr>';
2133 2134
2134 $PAGE = new pageBuilder; 2135 $PAGE = new pageBuilder;
2135 $PAGE->assign('timezone_html',$timezone_html); 2136 $PAGE->assign('timezone_html',$timezone_html);
@@ -2177,7 +2178,7 @@ function templateTZform($ptz=false)
2177 $cities_html = $cities[$pcontinent]; 2178 $cities_html = $cities[$pcontinent];
2178 $timezone_form = "Continent: <select name=\"continent\" id=\"continent\" onChange=\"onChangecontinent();\">${continents_html}</select>"; 2179 $timezone_form = "Continent: <select name=\"continent\" id=\"continent\" onChange=\"onChangecontinent();\">${continents_html}</select>";
2179 $timezone_form .= "&nbsp;&nbsp;&nbsp;&nbsp;City: <select name=\"city\" id=\"city\">${cities[$pcontinent]}</select><br />"; 2180 $timezone_form .= "&nbsp;&nbsp;&nbsp;&nbsp;City: <select name=\"city\" id=\"city\">${cities[$pcontinent]}</select><br />";
2180 $timezone_js = "<script language=\"JavaScript\">"; 2181 $timezone_js = "<script>";
2181 $timezone_js .= "function onChangecontinent(){document.getElementById(\"city\").innerHTML = citiescontinent[document.getElementById(\"continent\").value];}"; 2182 $timezone_js .= "function onChangecontinent(){document.getElementById(\"city\").innerHTML = citiescontinent[document.getElementById(\"continent\").value];}";
2182 $timezone_js .= "var citiescontinent = ".json_encode($cities).";" ; 2183 $timezone_js .= "var citiescontinent = ".json_encode($cities).";" ;
2183 $timezone_js .= "</script>" ; 2184 $timezone_js .= "</script>" ;
@@ -2292,7 +2293,7 @@ function writeConfig()
2292 $config .= ' ?>'; 2293 $config .= ' ?>';
2293 if (!file_put_contents($GLOBALS['config']['CONFIG_FILE'],$config) || strcmp(file_get_contents($GLOBALS['config']['CONFIG_FILE']),$config)!=0) 2294 if (!file_put_contents($GLOBALS['config']['CONFIG_FILE'],$config) || strcmp(file_get_contents($GLOBALS['config']['CONFIG_FILE']),$config)!=0)
2294 { 2295 {
2295 echo '<script language="JavaScript">alert("Shaarli could not create the config file. Please make sure Shaarli has the right to write in the folder is it installed in.");document.location=\'?\';</script>'; 2296 echo '<script>alert("Shaarli could not create the config file. Please make sure Shaarli has the right to write in the folder is it installed in.");document.location=\'?\';</script>';
2296 exit; 2297 exit;
2297 } 2298 }
2298} 2299}