diff options
-rw-r--r-- | index.php | 202 | ||||
-rw-r--r-- | shaarli.css | 2 |
2 files changed, 162 insertions, 42 deletions
@@ -1,5 +1,5 @@ | |||
1 | <?php | 1 | <?php |
2 | // Shaarli 0.0.17 beta - Shaare your links... | 2 | // Shaarli 0.0.18 beta - Shaare your links... |
3 | // The personal, minimalist, super-fast, no-database delicious clone. By sebsauvage.net | 3 | // The personal, minimalist, super-fast, no-database delicious clone. By sebsauvage.net |
4 | // http://sebsauvage.net/wiki/doku.php?id=php:shaarli | 4 | // http://sebsauvage.net/wiki/doku.php?id=php:shaarli |
5 | // Licence: http://www.opensource.org/licenses/zlib-license.php | 5 | // Licence: http://www.opensource.org/licenses/zlib-license.php |
@@ -47,11 +47,14 @@ header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); | |||
47 | header("Cache-Control: no-store, no-cache, must-revalidate"); | 47 | header("Cache-Control: no-store, no-cache, must-revalidate"); |
48 | header("Cache-Control: post-check=0, pre-check=0", false); | 48 | header("Cache-Control: post-check=0, pre-check=0", false); |
49 | header("Pragma: no-cache"); | 49 | header("Pragma: no-cache"); |
50 | define('shaarli_version','0.0.17 beta'); | 50 | define('shaarli_version','0.0.18 beta'); |
51 | if (!is_dir(DATADIR)) { mkdir(DATADIR,0705); chmod(DATADIR,0705); } | 51 | if (!is_dir(DATADIR)) { mkdir(DATADIR,0705); chmod(DATADIR,0705); } |
52 | if (!is_file(DATADIR.'/.htaccess')) { file_put_contents(DATADIR.'/.htaccess',"Allow from none\nDeny from all\n"); } // Protect data files. | 52 | if (!is_file(DATADIR.'/.htaccess')) { file_put_contents(DATADIR.'/.htaccess',"Allow from none\nDeny from all\n"); } // Protect data files. |
53 | if (!is_file(CONFIG_FILE)) install(); | 53 | if (!is_file(CONFIG_FILE)) install(); |
54 | require CONFIG_FILE; // Read login/password hash into $GLOBALS. | 54 | require CONFIG_FILE; // Read login/password hash into $GLOBALS. |
55 | // Small protection against dodgy config files: | ||
56 | if (empty($GLOBALS['title'])) $GLOBALS['title']='Shared links on '.htmlspecialchars(serverUrl().$_SERVER['SCRIPT_NAME']); | ||
57 | if (empty($GLOBALS['timezone'])) $GLOBALS['timezone']=date_default_timezone_get(); | ||
55 | autoLocale(); // Sniff browser language and set date format accordingly. | 58 | autoLocale(); // Sniff browser language and set date format accordingly. |
56 | header('Content-Type: text/html; charset=utf-8'); // We use UTF-8 for proper international characters handling. | 59 | header('Content-Type: text/html; charset=utf-8'); // We use UTF-8 for proper international characters handling. |
57 | $LINKSDB=false; | 60 | $LINKSDB=false; |
@@ -163,7 +166,7 @@ function isLoggedIn() | |||
163 | } | 166 | } |
164 | 167 | ||
165 | // Force logout. | 168 | // Force logout. |
166 | function logout() { unset($_SESSION['uid']); unset($_SESSION['ip']); unset($_SESSION['username']);} | 169 | function logout() { if (isset($_SESSION)) { unset($_SESSION['uid']); unset($_SESSION['ip']); unset($_SESSION['username']);} } |
167 | 170 | ||
168 | 171 | ||
169 | // ------------------------------------------------------------------------------------------ | 172 | // ------------------------------------------------------------------------------------------ |
@@ -567,7 +570,7 @@ function showRSS() | |||
567 | header('Content-Type: application/xhtml+xml; charset=utf-8'); | 570 | header('Content-Type: application/xhtml+xml; charset=utf-8'); |
568 | $pageaddr=htmlspecialchars(serverUrl().$_SERVER["SCRIPT_NAME"]); | 571 | $pageaddr=htmlspecialchars(serverUrl().$_SERVER["SCRIPT_NAME"]); |
569 | echo '<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">'; | 572 | echo '<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">'; |
570 | echo '<channel><title>Shared links on '.$pageaddr.'</title><link>'.$pageaddr.'</link>'; | 573 | echo '<channel><title>'.htmlspecialchars($GLOBALS['title']).'</title><link>'.$pageaddr.'</link>'; |
571 | echo '<description>Shared links</description><language></language><copyright>'.$pageaddr.'</copyright>'."\n\n"; | 574 | echo '<description>Shared links</description><language></language><copyright>'.$pageaddr.'</copyright>'."\n\n"; |
572 | $i=0; | 575 | $i=0; |
573 | $keys=array(); foreach($linksToDisplay as $key=>$value) { $keys[]=$key; } // No, I can't use array_keys(). | 576 | $keys=array(); foreach($linksToDisplay as $key=>$value) { $keys[]=$key; } // No, I can't use array_keys(). |
@@ -577,7 +580,7 @@ function showRSS() | |||
577 | $rfc822date = linkdate2rfc822($link['linkdate']); | 580 | $rfc822date = linkdate2rfc822($link['linkdate']); |
578 | echo '<item><title>'.htmlspecialchars($link['title']).'</title><guid>'.htmlspecialchars($link['url']).'</guid><link>'.htmlspecialchars($link['url']).'</link>'; | 581 | echo '<item><title>'.htmlspecialchars($link['title']).'</title><guid>'.htmlspecialchars($link['url']).'</guid><link>'.htmlspecialchars($link['url']).'</link>'; |
579 | if (!HIDE_TIMESTAMPS || isLoggedIn()) echo '<pubDate>'.htmlspecialchars($rfc822date).'</pubDate>'; | 582 | if (!HIDE_TIMESTAMPS || isLoggedIn()) echo '<pubDate>'.htmlspecialchars($rfc822date).'</pubDate>'; |
580 | echo '<description><![CDATA['.htmlspecialchars($link['description']).']]></description></item>'."\n"; | 583 | echo '<description><![CDATA['.nl2br(htmlspecialchars($link['description'])).']]></description></item>'."\n"; |
581 | $i++; | 584 | $i++; |
582 | } | 585 | } |
583 | echo '</channel></rss>'; | 586 | echo '</channel></rss>'; |
@@ -703,7 +706,7 @@ HTML; | |||
703 | $onload = 'onload="document.searchform.searchterm.focus();"'; | 706 | $onload = 'onload="document.searchform.searchterm.focus();"'; |
704 | $data = array('pageheader'=>$searchform,'body'=>templateLinkList(),'onload'=>$onload); | 707 | $data = array('pageheader'=>$searchform,'body'=>templateLinkList(),'onload'=>$onload); |
705 | templatePage($data); | 708 | templatePage($data); |
706 | exit; // Never remove this one ! | 709 | exit; // Never remove this one ! All operations below are reserved for logged in user. |
707 | } | 710 | } |
708 | 711 | ||
709 | // -------- All other functions are reserved for the registered user: | 712 | // -------- All other functions are reserved for the registered user: |
@@ -717,6 +720,7 @@ HTML; | |||
717 | $toolbar= <<<HTML | 720 | $toolbar= <<<HTML |
718 | <div id="headerform"><br> | 721 | <div id="headerform"><br> |
719 | {$changepwd} | 722 | {$changepwd} |
723 | <a href="?do=configure"><b>Configure your Shaarli</b></a> - Change Title, timezone...<br><br> | ||
720 | <a href="?do=changetag"><b>Rename/delete tags</b></a> - Rename or delete a tag in all links.<br><br> | 724 | <a href="?do=changetag"><b>Rename/delete tags</b></a> - Rename or delete a tag in all links.<br><br> |
721 | <a href="?do=import"><b>Import</b></a> - Import Netscape html bookmarks (as exported from Firefox, Chrome, Opera, delicious...)<br><br> | 725 | <a href="?do=import"><b>Import</b></a> - Import Netscape html bookmarks (as exported from Firefox, Chrome, Opera, delicious...)<br><br> |
722 | <a href="?do=export"><b>Export</b></a> - Export Netscape html bookmarks (which can be imported in Firefox, Chrome, Opera, delicious...)<br><br> | 726 | <a href="?do=export"><b>Export</b></a> - Export Netscape html bookmarks (which can be imported in Firefox, Chrome, Opera, delicious...)<br><br> |
@@ -739,16 +743,10 @@ HTML; | |||
739 | // Make sure old password is correct. | 743 | // Make sure old password is correct. |
740 | $oldhash = sha1($_POST['oldpassword'].$GLOBALS['login'].$GLOBALS['salt']); | 744 | $oldhash = sha1($_POST['oldpassword'].$GLOBALS['login'].$GLOBALS['salt']); |
741 | if ($oldhash!=$GLOBALS['hash']) { echo '<script language="JavaScript">alert("The old password is not correct.");document.location=\'?do=changepasswd\';</script>'; exit; } | 745 | if ($oldhash!=$GLOBALS['hash']) { echo '<script language="JavaScript">alert("The old password is not correct.");document.location=\'?do=changepasswd\';</script>'; exit; } |
742 | |||
743 | // Save new password | 746 | // Save new password |
744 | $salt=sha1(uniqid('',true).'_'.mt_rand()); // Salt renders rainbow-tables attacks useless. | 747 | $GLOBALS['salt'] = sha1(uniqid('',true).'_'.mt_rand()); // Salt renders rainbow-tables attacks useless. |
745 | $hash = sha1($_POST['setpassword'].$GLOBALS['login'].$salt); | 748 | $GLOBALS['hash'] = sha1($_POST['setpassword'].$GLOBALS['login'].$GLOBALS['salt']); |
746 | $config='<?php $GLOBALS[\'login\']='.var_export($GLOBALS['login'],true).'; $GLOBALS[\'hash\']='.var_export($hash,true).'; $GLOBALS[\'salt\']='.var_export($salt,true).'; date_default_timezone_set('.var_export(date_default_timezone_get(),true).'); ?>'; | 749 | writeConfig(); |
747 | if (!file_put_contents(CONFIG_FILE,$config) || strcmp(file_get_contents(CONFIG_FILE),$config)!=0) | ||
748 | { | ||
749 | 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>'; | ||
750 | exit; | ||
751 | } | ||
752 | echo '<script language="JavaScript">alert("Your password has been changed.");document.location=\'?do=tools\';</script>'; | 750 | echo '<script language="JavaScript">alert("Your password has been changed.");document.location=\'?do=tools\';</script>'; |
753 | exit; | 751 | exit; |
754 | } | 752 | } |
@@ -767,6 +765,43 @@ HTML; | |||
767 | exit; | 765 | exit; |
768 | } | 766 | } |
769 | } | 767 | } |
768 | |||
769 | // -------- User wants to change configuration | ||
770 | if (startswith($_SERVER["QUERY_STRING"],'do=configure')) | ||
771 | { | ||
772 | if (!empty($_POST['title']) ) | ||
773 | { | ||
774 | if (!tokenOk($_POST['token'])) die('Wrong token.'); // Go away ! | ||
775 | $tz = 'UTC'; | ||
776 | if (!empty($_POST['continent']) && !empty($_POST['city'])) | ||
777 | if (isTZvalid($_POST['continent'],$_POST['city'])) | ||
778 | $tz = $_POST['continent'].'/'.$_POST['city']; | ||
779 | $GLOBALS['timezone'] = $tz; | ||
780 | $GLOBALS['title']=$_POST['title']; | ||
781 | writeConfig(); | ||
782 | echo '<script language="JavaScript">alert("Configuration was saved.");document.location=\'?do=tools\';</script>'; | ||
783 | exit; | ||
784 | } | ||
785 | else | ||
786 | { | ||
787 | $token = getToken(); | ||
788 | $title = htmlspecialchars( empty($GLOBALS['title']) ? '' : $GLOBALS['title'] , ENT_QUOTES); | ||
789 | list($timezone_form,$timezone_js) = templateTZform($GLOBALS['timezone']); | ||
790 | $timezone_html=''; if ($timezone_form!='') $timezone_html='<tr><td valign="top"><b>Timezone:</b></td><td>'.$timezone_form.'</td></tr>'; | ||
791 | $changepwdform= <<<HTML | ||
792 | ${timezone_js}<form method="POST" action="" name="configform" id="configform"><input type="hidden" name="token" value="{$token}"> | ||
793 | <table border="0" cellpadding="20"> | ||
794 | <tr><td><b>Page title:</b></td><td><input type="text" name="title" id="title" size="50" value="{$title}"></td></tr> | ||
795 | {$timezone_html} | ||
796 | <tr><td></td><td align="right"><input type="submit" name="Save" value="Save config" class="bigbutton"></td></tr> | ||
797 | </table> | ||
798 | </form> | ||
799 | HTML; | ||
800 | $data = array('pageheader'=>$changepwdform,'body'=>'','onload'=>'onload="document.configform.title.focus();"'); | ||
801 | templatePage($data); | ||
802 | exit; | ||
803 | } | ||
804 | } | ||
770 | 805 | ||
771 | // -------- User wants to rename a tag or delete it | 806 | // -------- User wants to rename a tag or delete it |
772 | if (startswith($_SERVER["QUERY_STRING"],'do=changetag')) | 807 | if (startswith($_SERVER["QUERY_STRING"],'do=changetag')) |
@@ -838,9 +873,10 @@ HTML; | |||
838 | if (isset($_POST['save_edit'])) | 873 | if (isset($_POST['save_edit'])) |
839 | { | 874 | { |
840 | if (!tokenOk($_POST['token'])) die('Wrong token.'); // Go away ! | 875 | if (!tokenOk($_POST['token'])) die('Wrong token.'); // Go away ! |
876 | $tags = trim(preg_replace('/\s\s+/',' ', $_POST['lf_tags'])); // Remove multiple spaces. | ||
841 | $linkdate=$_POST['lf_linkdate']; | 877 | $linkdate=$_POST['lf_linkdate']; |
842 | $link = array('title'=>trim($_POST['lf_title']),'url'=>trim($_POST['lf_url']),'description'=>trim($_POST['lf_description']),'private'=>(isset($_POST['lf_private']) ? 1 : 0), | 878 | $link = array('title'=>trim($_POST['lf_title']),'url'=>trim($_POST['lf_url']),'description'=>trim($_POST['lf_description']),'private'=>(isset($_POST['lf_private']) ? 1 : 0), |
843 | 'linkdate'=>$linkdate,'tags'=>trim($_POST['lf_tags'])); | 879 | 'linkdate'=>$linkdate,'tags'=>$tags); |
844 | if ($link['title']=='') $link['title']=$link['url']; // If title is empty, use the URL as title. | 880 | if ($link['title']=='') $link['title']=$link['url']; // If title is empty, use the URL as title. |
845 | $LINKSDB[$linkdate] = $link; | 881 | $LINKSDB[$linkdate] = $link; |
846 | $LINKSDB->savedb(); // save to disk | 882 | $LINKSDB->savedb(); // save to disk |
@@ -1252,17 +1288,18 @@ JS; | |||
1252 | if (!empty($_GET['searchtags'])) $feedurl.='&searchtags='.$_GET['searchtags']; | 1288 | if (!empty($_GET['searchtags'])) $feedurl.='&searchtags='.$_GET['searchtags']; |
1253 | elseif (!empty($_GET['searchterm'])) $feedurl.='&searchterm='.$_GET['searchterm']; | 1289 | elseif (!empty($_GET['searchterm'])) $feedurl.='&searchterm='.$_GET['searchterm']; |
1254 | 1290 | ||
1291 | $title = htmlspecialchars( $GLOBALS['title'] ); | ||
1255 | echo <<<HTML | 1292 | echo <<<HTML |
1256 | <html> | 1293 | <html> |
1257 | <head> | 1294 | <head> |
1258 | <title>{$open}Shaarli - Let's shaare your links...</title> | 1295 | <title>{$title}</title> |
1259 | <link rel="alternate" type="application/rss+xml" href="{$feedurl}" /> | 1296 | <link rel="alternate" type="application/rss+xml" href="{$feedurl}" /> |
1260 | <link type="text/css" rel="stylesheet" href="shaarli.css" /> | 1297 | <link type="text/css" rel="stylesheet" href="shaarli.css" /> |
1261 | {$jsincludes} | 1298 | {$jsincludes} |
1262 | </head> | 1299 | </head> |
1263 | <body {$data['onload']}>{$newversion} | 1300 | <body {$data['onload']}>{$newversion} |
1264 | <div id="pageheader"><div style="float:right; font-style:italic; color:#bbb; text-align:right; padding:0 5 0 0;">Shaare your links...<br>{$linkcount} links</div> | 1301 | <div id="pageheader"><div style="float:right; font-style:italic; color:#bbb; text-align:right; padding:0 5 0 0;">Shaare your links...<br>{$linkcount} links</div> |
1265 | <b><i>{$open}Shaarli {$shaarli_version}</i></b> - <a href="?">Home</a> {$menu} <a href="{$feedurl}" style="padding-left:30px;">RSS Feed</a> | 1302 | <b><i>{$title}</i></b> - <a href="?">Home</a> {$menu} <a href="{$feedurl}" style="padding-left:30px;">RSS Feed</a> |
1266 | <a href="?do=tagcloud">Tag cloud</a> | 1303 | <a href="?do=tagcloud">Tag cloud</a> |
1267 | {$data['pageheader']} | 1304 | {$data['pageheader']} |
1268 | </div> | 1305 | </div> |
@@ -1285,39 +1322,104 @@ function install() | |||
1285 | 1322 | ||
1286 | if (!empty($_POST['setlogin']) && !empty($_POST['setpassword'])) | 1323 | if (!empty($_POST['setlogin']) && !empty($_POST['setpassword'])) |
1287 | { | 1324 | { |
1288 | $tz=(empty($_POST['settimezone']) ? 'UTC':$_POST['settimezone']); | 1325 | $tz = 'UTC'; |
1326 | if (!empty($_POST['continent']) && !empty($_POST['city'])) | ||
1327 | if (isTZvalid($_POST['continent'],$_POST['city'])) | ||
1328 | $tz = $_POST['continent'].'/'.$_POST['city']; | ||
1329 | $GLOBALS['timezone'] = $tz; | ||
1289 | // Everything is ok, let's create config file. | 1330 | // Everything is ok, let's create config file. |
1290 | $salt=sha1(uniqid('',true).'_'.mt_rand()); // Salt renders rainbow-tables attacks useless. | 1331 | $GLOBALS['login'] = $_POST['setlogin']; |
1291 | $hash = sha1($_POST['setpassword'].$_POST['setlogin'].$salt); | 1332 | $GLOBALS['salt'] = sha1(uniqid('',true).'_'.mt_rand()); // Salt renders rainbow-tables attacks useless. |
1292 | $config='<?php $GLOBALS[\'login\']='.var_export($_POST['setlogin'],true).'; $GLOBALS[\'hash\']='.var_export($hash,true).'; $GLOBALS[\'salt\']='.var_export($salt,true).'; date_default_timezone_set('.var_export($tz,true).'); ?>'; | 1333 | $GLOBALS['hash'] = sha1($_POST['setpassword'].$GLOBALS['login'].$GLOBALS['salt']); |
1293 | if (!file_put_contents(CONFIG_FILE,$config) || strcmp(file_get_contents(CONFIG_FILE),$config)!=0) | 1334 | $GLOBALS['title'] = (empty($_POST['title']) ? 'Shared links on '.htmlspecialchars(serverUrl().$_SERVER['SCRIPT_NAME']) : $_POST['title'] ); |
1294 | { | 1335 | writeConfig(); |
1295 | 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>'; | ||
1296 | exit; | ||
1297 | } | ||
1298 | echo '<script language="JavaScript">alert("Shaarli is now configured. Please enter your login/password and start shaaring your links !");document.location=\'?do=login\';</script>'; | 1336 | echo '<script language="JavaScript">alert("Shaarli is now configured. Please enter your login/password and start shaaring your links !");document.location=\'?do=login\';</script>'; |
1299 | exit; | 1337 | exit; |
1300 | } | ||
1301 | // Display config form: | ||
1302 | $timezoneselect=''; | ||
1303 | if (function_exists('timezone_identifiers_list')) // because of old php version (5.1) which can be found on free.fr | ||
1304 | { | ||
1305 | $timezones=''; | ||
1306 | foreach(timezone_identifiers_list() as $tz) $timezones.='<option value="'.htmlspecialchars($tz).'">'.htmlspecialchars($tz)."</option>\n"; | ||
1307 | $timezoneselect='Timezone: <select name="settimezone"><option value="" selected>(please select:)</option>'.$timezones.'</select><br><br>'; | ||
1308 | } | 1338 | } |
1339 | |||
1340 | // Display config form: | ||
1341 | list($timezone_form,$timezone_js) = templateTZform(); | ||
1342 | $timezone_html=''; if ($timezone_form!='') $timezone_html='<tr><td valign="top"><b>Timezone:</b></td><td>'.$timezone_form.'</td></tr>'; | ||
1309 | echo <<<HTML | 1343 | echo <<<HTML |
1310 | <html><head><title>Shaarli - Configuration</title><link type="text/css" rel="stylesheet" href="shaarli.css" /></head> | 1344 | <html><head><title>Shaarli - Configuration</title><link type="text/css" rel="stylesheet" href="shaarli.css" />${timezone_js}</head> |
1311 | <body onload="document.configform.setlogin.focus();" style="padding:20px;"><h1>Shaarli - Shaare your links...</h1> | 1345 | <body onload="document.installform.setlogin.focus();" style="padding:20px;"><h1>Shaarli - Shaare your links...</h1> |
1312 | It looks like it's the first time you run Shaarli. Please chose a login/password and a timezone:<br> | 1346 | It looks like it's the first time you run Shaarli. Please configure it:<br> |
1313 | <form method="POST" action="" name="configform" style="border:1px solid black; padding:10 10 10 10;"> | 1347 | <form method="POST" action="" name="installform" id="installform" style="border:1px solid black; padding:10 10 10 10;"> |
1314 | Login: <input type="text" name="setlogin"><br><br>Password: <input type="password" name="setpassword"><br><br> | 1348 | <table border="0" cellpadding="20"> |
1315 | {$timezoneselect} | 1349 | <tr><td><b>Login:</b></td><td><input type="text" name="setlogin" size="30"></td></tr> |
1316 | <input type="submit" name="Save" value="Save config" class="bigbutton"></form></body></html> | 1350 | <tr><td><b>Password:</b></td><td><input type="password" name="setpassword" size="30"></td></tr> |
1351 | {$timezone_html} | ||
1352 | <tr><td><b>Page title:</b></td><td><input type="text" name="title" size="30"></td></tr> | ||
1353 | <tr><td></td><td align="right"><input type="submit" name="Save" value="Save config" class="bigbutton"></td></tr> | ||
1354 | </table> | ||
1355 | </form></body></html> | ||
1317 | HTML; | 1356 | HTML; |
1318 | exit; | 1357 | exit; |
1319 | } | 1358 | } |
1320 | 1359 | ||
1360 | // Generates the timezone selection form and javascript. | ||
1361 | // Input: (optional) current timezone (can be 'UTC/UTC'). It will be pre-selected. | ||
1362 | // Output: array(html,js) | ||
1363 | // Example: list($htmlform,$js) = templateTZform('Europe/Paris'); // Europe/Paris pre-selected. | ||
1364 | // Returns array('','') if server does not support timezones list. (eg. php 5.1 on free.fr) | ||
1365 | function templateTZform($ptz=false) | ||
1366 | { | ||
1367 | if (function_exists('timezone_identifiers_list')) // because of old php version (5.1) which can be found on free.fr | ||
1368 | { | ||
1369 | // Try to split the provided timezone. | ||
1370 | if ($ptz==false) { $l=timezone_identifiers_list(); $ptz=$l[0]; } | ||
1371 | $spos=strpos($ptz,'/'); $pcontinent=substr($ptz,0,$spos); $pcity=substr($ptz,$spos+1); | ||
1372 | |||
1373 | // Display config form: | ||
1374 | $timezone_form = ''; | ||
1375 | $timezone_js = ''; | ||
1376 | // The list is in the forme "Europe/Paris", "America/Argentina/Buenos_Aires"... | ||
1377 | // We split the list in continents/cities. | ||
1378 | $continents = array(); | ||
1379 | $cities = array(); | ||
1380 | foreach(timezone_identifiers_list() as $tz) | ||
1381 | { | ||
1382 | if ($tz=='UTC') $tz='UTC/UTC'; | ||
1383 | $spos = strpos($tz,'/'); | ||
1384 | if ($spos) | ||
1385 | { | ||
1386 | $continent=substr($tz,0,$spos); $city=substr($tz,$spos+1); | ||
1387 | $continents[$continent]=1; | ||
1388 | if (!isset($cities[$continent])) $cities[$continent]=array(); | ||
1389 | $cities[$continent].='<option value="'.$city.'"'.($pcity==$city?'selected':'').'>'.$city.'</option>'; | ||
1390 | } | ||
1391 | } | ||
1392 | $continents_html = ''; | ||
1393 | $continents = array_keys($continents); | ||
1394 | foreach($continents as $continent) | ||
1395 | $continents_html.='<option value="'.$continent.'"'.($pcontinent==$continent?'selected':'').'>'.$continent.'</option>'; | ||
1396 | $cities_html = $cities[$pcontinent]; | ||
1397 | $timezone_form = "Continent: <select name=\"continent\" id=\"continent\" onChange=\"onChangecontinent();\">${continents_html}</select><br /><br />"; | ||
1398 | $timezone_form .= "City: <select name=\"city\" id=\"city\">${cities[$pcontinent]}</select><br /><br />"; | ||
1399 | $timezone_js = "<script language=\"JavaScript\">"; | ||
1400 | $timezone_js .= "function onChangecontinent(){document.getElementById(\"city\").innerHTML = citiescontinent[document.getElementById(\"continent\").value];}"; | ||
1401 | $timezone_js .= "var citiescontinent = ".json_encode($cities).";" ; | ||
1402 | $timezone_js .= "</script>" ; | ||
1403 | return array($timezone_form,$timezone_js); | ||
1404 | } | ||
1405 | return array('',''); | ||
1406 | } | ||
1407 | |||
1408 | // Tells if a timezone is valid or not. | ||
1409 | // If not valid, returns false. | ||
1410 | // If system does not support timezone list, returns false. | ||
1411 | function isTZvalid($continent,$city) | ||
1412 | { | ||
1413 | $tz = $continent.'/'.$city; | ||
1414 | if (function_exists('timezone_identifiers_list')) // because of old php version (5.1) which can be found on free.fr | ||
1415 | { | ||
1416 | if (in_array($tz, timezone_identifiers_list())) // it's a valid timezone ? | ||
1417 | return true; | ||
1418 | } | ||
1419 | return false; | ||
1420 | } | ||
1421 | |||
1422 | |||
1321 | // Webservices (for use with jQuery/jQueryUI) | 1423 | // Webservices (for use with jQuery/jQueryUI) |
1322 | // eg. index.php?ws=tags&term=minecr | 1424 | // eg. index.php?ws=tags&term=minecr |
1323 | function processWS() | 1425 | function processWS() |
@@ -1357,6 +1459,22 @@ function processWS() | |||
1357 | } | 1459 | } |
1358 | } | 1460 | } |
1359 | 1461 | ||
1462 | // Re-write configuration file according to globals. | ||
1463 | // Requires some $GLOBALS to be set (login,hash,salt,title). | ||
1464 | // If the config file cannot be saved, an error message is dislayed and the user is redirected to "Tools" menu. | ||
1465 | // (otherwise, the function simply returns.) | ||
1466 | function writeConfig() | ||
1467 | { | ||
1468 | if (is_file(CONFIG_FILE) && !isLoggedIn()) die('You are not authorized to alter config.'); // Only logged in user can alter config. | ||
1469 | $config='<?php $GLOBALS[\'login\']='.var_export($GLOBALS['login'],true).'; $GLOBALS[\'hash\']='.var_export($GLOBALS['hash'],true).'; $GLOBALS[\'salt\']='.var_export($GLOBALS['salt'],true).'; '; | ||
1470 | $config .='$GLOBALS[\'timezone\']='.var_export($GLOBALS['timezone'],true).'; date_default_timezone_set('.var_export($GLOBALS['timezone'],true).'); $GLOBALS[\'title\']='.var_export($GLOBALS['title'],true).'; ?>'; | ||
1471 | if (!file_put_contents(CONFIG_FILE,$config) || strcmp(file_get_contents(CONFIG_FILE),$config)!=0) | ||
1472 | { | ||
1473 | 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>'; | ||
1474 | exit; | ||
1475 | } | ||
1476 | } | ||
1477 | |||
1360 | // Invalidate caches when the database is changed or the user logs out. | 1478 | // Invalidate caches when the database is changed or the user logs out. |
1361 | // (eg. tags cache). | 1479 | // (eg. tags cache). |
1362 | function invalidateCaches() | 1480 | function invalidateCaches() |
diff --git a/shaarli.css b/shaarli.css index 8dd8b14a..5a977439 100644 --- a/shaarli.css +++ b/shaarli.css | |||
@@ -61,6 +61,8 @@ border-bottom:1px solid #aaa; border-right:1px solid #aaa; } | |||
61 | #newversion { background-color: #FFFFA0; color:#000; position:absolute; top:0;right:0; padding:2 7 2 7; font-size:9pt;} | 61 | #newversion { background-color: #FFFFA0; color:#000; position:absolute; top:0;right:0; padding:2 7 2 7; font-size:9pt;} |
62 | #cloudtag { padding-left:10%; padding-right:10%; } | 62 | #cloudtag { padding-left:10%; padding-right:10%; } |
63 | #cloudtag a { color:black; text-decoration:none; } | 63 | #cloudtag a { color:black; text-decoration:none; } |
64 | #installform td { font-size: 10pt; padding:10 5 10 5; } | ||
65 | #configform td { color:#ccc; font-size: 10pt; padding:10 5 10 5; } | ||
64 | 66 | ||
65 | /* Minimal customisation for jQuery widgets */ | 67 | /* Minimal customisation for jQuery widgets */ |
66 | .ui-autocomplete { background-color:#fff; padding-left:5px;} | 68 | .ui-autocomplete { background-color:#fff; padding-left:5px;} |