diff options
-rw-r--r-- | images/logo.png | bin | 6253 -> 5456 bytes | |||
-rw-r--r-- | index.php | 65 |
2 files changed, 47 insertions, 18 deletions
diff --git a/images/logo.png b/images/logo.png index 20989288..f8b0c94f 100644 --- a/images/logo.png +++ b/images/logo.png | |||
Binary files differ | |||
@@ -41,7 +41,7 @@ define('PHPSUFFIX',' */ ?>'); // Suffix to encapsulate data in php code. | |||
41 | // Force cookie path (but do not change lifetime) | 41 | // Force cookie path (but do not change lifetime) |
42 | $cookie=session_get_cookie_params(); | 42 | $cookie=session_get_cookie_params(); |
43 | $cookiedir = ''; if(dirname($_SERVER['SCRIPT_NAME'])!='/') $cookiedir=dirname($_SERVER["SCRIPT_NAME"]).'/'; | 43 | $cookiedir = ''; if(dirname($_SERVER['SCRIPT_NAME'])!='/') $cookiedir=dirname($_SERVER["SCRIPT_NAME"]).'/'; |
44 | session_set_cookie_params($cookie['lifetime'],$cookiedir,$_SERVER['SERVER_NAME']); // Set default cookie expiration and path. | 44 | session_set_cookie_params($cookie['lifetime'],$cookiedir,$_SERVER['HTTP_HOST']); // Set default cookie expiration and path. |
45 | 45 | ||
46 | // Set session parameters on server side. | 46 | // Set session parameters on server side. |
47 | define('INACTIVITY_TIMEOUT',3600); // (in seconds). If the user does not access any page within this time, his/her session is considered expired. | 47 | define('INACTIVITY_TIMEOUT',3600); // (in seconds). If the user does not access any page within this time, his/her session is considered expired. |
@@ -89,7 +89,7 @@ if (!is_dir($GLOBALS['config']['DATADIR'])) { mkdir($GLOBALS['config']['DATADIR' | |||
89 | if (!is_dir('tmp')) { mkdir('tmp',0705); chmod('tmp',0705); } // For RainTPL temporary files. | 89 | if (!is_dir('tmp')) { mkdir('tmp',0705); chmod('tmp',0705); } // For RainTPL temporary files. |
90 | if (!is_file($GLOBALS['config']['DATADIR'].'/.htaccess')) { file_put_contents($GLOBALS['config']['DATADIR'].'/.htaccess',"Allow from none\nDeny from all\n"); } // Protect data files. | 90 | if (!is_file($GLOBALS['config']['DATADIR'].'/.htaccess')) { file_put_contents($GLOBALS['config']['DATADIR'].'/.htaccess',"Allow from none\nDeny from all\n"); } // Protect data files. |
91 | // Second check to see if Shaarli can write in its directory, because on some hosts is_writable() is not reliable. | 91 | // Second check to see if Shaarli can write in its directory, because on some hosts is_writable() is not reliable. |
92 | if (!is_file($GLOBALS['config']['DATADIR'].'/.htaccess')) die('<pre>ERROR: Shaarli does not have the right to write in its own directory ('.realpath(dirname(__FILE__)).').</pre>'); | 92 | if (!is_file($GLOBALS['config']['DATADIR'].'/.htaccess')) die('<pre>ERROR: Shaarli does not have the right to write in its data directory ('.realpath($GLOBALS['config']['DATADIR']).').</pre>'); |
93 | if ($GLOBALS['config']['ENABLE_LOCALCACHE']) | 93 | if ($GLOBALS['config']['ENABLE_LOCALCACHE']) |
94 | { | 94 | { |
95 | if (!is_dir($GLOBALS['config']['CACHEDIR'])) { mkdir($GLOBALS['config']['CACHEDIR'],0705); chmod($GLOBALS['config']['CACHEDIR'],0705); } | 95 | if (!is_dir($GLOBALS['config']['CACHEDIR'])) { mkdir($GLOBALS['config']['CACHEDIR'],0705); chmod($GLOBALS['config']['CACHEDIR'],0705); } |
@@ -400,14 +400,14 @@ if (isset($_POST['login'])) | |||
400 | $_SESSION['expires_on']=time()+$_SESSION['longlastingsession']; // Set session expiration on server-side. | 400 | $_SESSION['expires_on']=time()+$_SESSION['longlastingsession']; // Set session expiration on server-side. |
401 | 401 | ||
402 | $cookiedir = ''; if(dirname($_SERVER['SCRIPT_NAME'])!='/') $cookiedir=dirname($_SERVER["SCRIPT_NAME"]).'/'; | 402 | $cookiedir = ''; if(dirname($_SERVER['SCRIPT_NAME'])!='/') $cookiedir=dirname($_SERVER["SCRIPT_NAME"]).'/'; |
403 | session_set_cookie_params($_SESSION['longlastingsession'],$cookiedir,$_SERVER['SERVER_NAME']); // Set session cookie expiration on client side | 403 | session_set_cookie_params($_SESSION['longlastingsession'],$cookiedir,$_SERVER['HTTP_HOST']); // Set session cookie expiration on client side |
404 | // Note: Never forget the trailing slash on the cookie path ! | 404 | // Note: Never forget the trailing slash on the cookie path ! |
405 | session_regenerate_id(true); // Send cookie with new expiration date to browser. | 405 | session_regenerate_id(true); // Send cookie with new expiration date to browser. |
406 | } | 406 | } |
407 | else // Standard session expiration (=when browser closes) | 407 | else // Standard session expiration (=when browser closes) |
408 | { | 408 | { |
409 | $cookiedir = ''; if(dirname($_SERVER['SCRIPT_NAME'])!='/') $cookiedir=dirname($_SERVER["SCRIPT_NAME"]).'/'; | 409 | $cookiedir = ''; if(dirname($_SERVER['SCRIPT_NAME'])!='/') $cookiedir=dirname($_SERVER["SCRIPT_NAME"]).'/'; |
410 | session_set_cookie_params(0,$cookiedir,$_SERVER['SERVER_NAME']); // 0 means "When browser closes" | 410 | session_set_cookie_params(0,$cookiedir,$_SERVER['HTTP_HOST']); // 0 means "When browser closes" |
411 | session_regenerate_id(true); | 411 | session_regenerate_id(true); |
412 | } | 412 | } |
413 | // Optional redirect after login: | 413 | // Optional redirect after login: |
@@ -439,7 +439,7 @@ function serverUrl() | |||
439 | { | 439 | { |
440 | $https = (!empty($_SERVER['HTTPS']) && (strtolower($_SERVER['HTTPS'])=='on')) || $_SERVER["SERVER_PORT"]=='443'; // HTTPS detection. | 440 | $https = (!empty($_SERVER['HTTPS']) && (strtolower($_SERVER['HTTPS'])=='on')) || $_SERVER["SERVER_PORT"]=='443'; // HTTPS detection. |
441 | $serverport = ($_SERVER["SERVER_PORT"]=='80' || ($https && $_SERVER["SERVER_PORT"]=='443') ? '' : ':'.$_SERVER["SERVER_PORT"]); | 441 | $serverport = ($_SERVER["SERVER_PORT"]=='80' || ($https && $_SERVER["SERVER_PORT"]=='443') ? '' : ':'.$_SERVER["SERVER_PORT"]); |
442 | return 'http'.($https?'s':'').'://'.$_SERVER["SERVER_NAME"].$serverport; | 442 | return 'http'.($https?'s':'').'://'.$_SERVER['HTTP_HOST'].$serverport; |
443 | } | 443 | } |
444 | 444 | ||
445 | // Returns the absolute URL of current script, without the query. | 445 | // Returns the absolute URL of current script, without the query. |
@@ -566,7 +566,7 @@ function getHTTP($url,$timeout=30) | |||
566 | { | 566 | { |
567 | try | 567 | try |
568 | { | 568 | { |
569 | $options = array('http'=>array('method'=>'GET','timeout' => $timeout)); // Force network timeout | 569 | $options = array('http'=>array('method'=>'GET','timeout' => $timeout, 'user_agent' => 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:23.0) Gecko/20100101 Firefox/23.0')); // Force network timeout |
570 | $context = stream_context_create($options); | 570 | $context = stream_context_create($options); |
571 | $data=file_get_contents($url,false,$context,-1, 4000000); // We download at most 4 Mb from source. | 571 | $data=file_get_contents($url,false,$context,-1, 4000000); // We download at most 4 Mb from source. |
572 | if (!$data) { return array('HTTP Error',array(),''); } | 572 | if (!$data) { return array('HTTP Error',array(),''); } |
@@ -876,7 +876,7 @@ class linkdb implements Iterator, Countable, ArrayAccess | |||
876 | } | 876 | } |
877 | 877 | ||
878 | // ------------------------------------------------------------------------------------------ | 878 | // ------------------------------------------------------------------------------------------ |
879 | // Ouput the last 50 links in RSS 2.0 format. | 879 | // Ouput the last N links in RSS 2.0 format. |
880 | function showRSS() | 880 | function showRSS() |
881 | { | 881 | { |
882 | header('Content-Type: application/rss+xml; charset=utf-8'); | 882 | header('Content-Type: application/rss+xml; charset=utf-8'); |
@@ -898,6 +898,7 @@ function showRSS() | |||
898 | if (!empty($_GET['searchterm'])) $linksToDisplay = $LINKSDB->filterFulltext($_GET['searchterm']); | 898 | if (!empty($_GET['searchterm'])) $linksToDisplay = $LINKSDB->filterFulltext($_GET['searchterm']); |
899 | elseif (!empty($_GET['searchtags'])) $linksToDisplay = $LINKSDB->filterTags(trim($_GET['searchtags'])); | 899 | elseif (!empty($_GET['searchtags'])) $linksToDisplay = $LINKSDB->filterTags(trim($_GET['searchtags'])); |
900 | else $linksToDisplay = $LINKSDB; | 900 | else $linksToDisplay = $LINKSDB; |
901 | $nblinksToDisplay = !empty($_GET['nb']) ? max($_GET['nb'] + 0, 1) : 50; | ||
901 | 902 | ||
902 | $pageaddr=htmlspecialchars(indexUrl()); | 903 | $pageaddr=htmlspecialchars(indexUrl()); |
903 | echo '<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">'; | 904 | echo '<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">'; |
@@ -912,7 +913,7 @@ function showRSS() | |||
912 | } | 913 | } |
913 | $i=0; | 914 | $i=0; |
914 | $keys=array(); foreach($linksToDisplay as $key=>$value) { $keys[]=$key; } // No, I can't use array_keys(). | 915 | $keys=array(); foreach($linksToDisplay as $key=>$value) { $keys[]=$key; } // No, I can't use array_keys(). |
915 | while ($i<50 && $i<count($keys)) | 916 | while ($i<$nblinksToDisplay && $i<count($keys)) |
916 | { | 917 | { |
917 | $link = $linksToDisplay[$keys[$i]]; | 918 | $link = $linksToDisplay[$keys[$i]]; |
918 | $guid = $pageaddr.'?'.smallHash($link['linkdate']); | 919 | $guid = $pageaddr.'?'.smallHash($link['linkdate']); |
@@ -945,7 +946,7 @@ function showRSS() | |||
945 | } | 946 | } |
946 | 947 | ||
947 | // ------------------------------------------------------------------------------------------ | 948 | // ------------------------------------------------------------------------------------------ |
948 | // Ouput the last 50 links in ATOM format. | 949 | // Ouput the last N links in ATOM format. |
949 | function showATOM() | 950 | function showATOM() |
950 | { | 951 | { |
951 | header('Content-Type: application/atom+xml; charset=utf-8'); | 952 | header('Content-Type: application/atom+xml; charset=utf-8'); |
@@ -968,13 +969,14 @@ function showATOM() | |||
968 | if (!empty($_GET['searchterm'])) $linksToDisplay = $LINKSDB->filterFulltext($_GET['searchterm']); | 969 | if (!empty($_GET['searchterm'])) $linksToDisplay = $LINKSDB->filterFulltext($_GET['searchterm']); |
969 | elseif (!empty($_GET['searchtags'])) $linksToDisplay = $LINKSDB->filterTags(trim($_GET['searchtags'])); | 970 | elseif (!empty($_GET['searchtags'])) $linksToDisplay = $LINKSDB->filterTags(trim($_GET['searchtags'])); |
970 | else $linksToDisplay = $LINKSDB; | 971 | else $linksToDisplay = $LINKSDB; |
972 | $nblinksToDisplay = !empty($_GET['nb']) ? max($_GET['nb'] + 0, 1) : 50; | ||
971 | 973 | ||
972 | $pageaddr=htmlspecialchars(indexUrl()); | 974 | $pageaddr=htmlspecialchars(indexUrl()); |
973 | $latestDate = ''; | 975 | $latestDate = ''; |
974 | $entries=''; | 976 | $entries=''; |
975 | $i=0; | 977 | $i=0; |
976 | $keys=array(); foreach($linksToDisplay as $key=>$value) { $keys[]=$key; } // No, I can't use array_keys(). | 978 | $keys=array(); foreach($linksToDisplay as $key=>$value) { $keys[]=$key; } // No, I can't use array_keys(). |
977 | while ($i<50 && $i<count($keys)) | 979 | while ($i<$nblinksToDisplay && $i<count($keys)) |
978 | { | 980 | { |
979 | $link = $linksToDisplay[$keys[$i]]; | 981 | $link = $linksToDisplay[$keys[$i]]; |
980 | $guid = $pageaddr.'?'.smallHash($link['linkdate']); | 982 | $guid = $pageaddr.'?'.smallHash($link['linkdate']); |
@@ -1279,7 +1281,7 @@ function renderPage() | |||
1279 | if (is_numeric($_GET['linksperpage'])) { $_SESSION['LINKS_PER_PAGE']=abs(intval($_GET['linksperpage'])); } | 1281 | if (is_numeric($_GET['linksperpage'])) { $_SESSION['LINKS_PER_PAGE']=abs(intval($_GET['linksperpage'])); } |
1280 | // Make sure the referer is from Shaarli itself. | 1282 | // Make sure the referer is from Shaarli itself. |
1281 | $referer = '?'; | 1283 | $referer = '?'; |
1282 | if (!empty($_SERVER['HTTP_REFERER']) && strcmp(parse_url($_SERVER['HTTP_REFERER'],PHP_URL_HOST),$_SERVER['SERVER_NAME'])==0) | 1284 | if (!empty($_SERVER['HTTP_REFERER']) && strcmp(parse_url($_SERVER['HTTP_REFERER'],PHP_URL_HOST),$_SERVER['HTTP_HOST'])==0) |
1283 | $referer = $_SERVER['HTTP_REFERER']; | 1285 | $referer = $_SERVER['HTTP_REFERER']; |
1284 | header('Location: '.$referer); | 1286 | header('Location: '.$referer); |
1285 | exit; | 1287 | exit; |
@@ -1298,7 +1300,7 @@ function renderPage() | |||
1298 | } | 1300 | } |
1299 | // Make sure the referer is from Shaarli itself. | 1301 | // Make sure the referer is from Shaarli itself. |
1300 | $referer = '?'; | 1302 | $referer = '?'; |
1301 | if (!empty($_SERVER['HTTP_REFERER']) && strcmp(parse_url($_SERVER['HTTP_REFERER'],PHP_URL_HOST),$_SERVER['SERVER_NAME'])==0) | 1303 | if (!empty($_SERVER['HTTP_REFERER']) && strcmp(parse_url($_SERVER['HTTP_REFERER'],PHP_URL_HOST),$_SERVER['HTTP_HOST'])==0) |
1302 | $referer = $_SERVER['HTTP_REFERER']; | 1304 | $referer = $_SERVER['HTTP_REFERER']; |
1303 | header('Location: '.$referer); | 1305 | header('Location: '.$referer); |
1304 | exit; | 1306 | exit; |
@@ -1538,18 +1540,41 @@ function renderPage() | |||
1538 | $link_is_new = true; // This is a new link | 1540 | $link_is_new = true; // This is a new link |
1539 | $linkdate = strval(date('Ymd_His')); | 1541 | $linkdate = strval(date('Ymd_His')); |
1540 | $title = (empty($_GET['title']) ? '' : $_GET['title'] ); // Get title if it was provided in URL (by the bookmarklet). | 1542 | $title = (empty($_GET['title']) ? '' : $_GET['title'] ); // Get title if it was provided in URL (by the bookmarklet). |
1541 | $description=''; $tags=''; $private=0; | 1543 | $description = (empty($_GET['description']) ? '' : $_GET['description'] )."\n"; // Get description if it was provided in URL (by the bookmarklet). [Bronco added that] |
1544 | $tags = (empty($_GET['tags']) ? '' : $_GET['tags'] ); // Get tags if it was provided in URL | ||
1545 | $private = (!empty($_GET['private']) && $_GET['private'] === "1" ? 1 : 0); // Get private if it was provided in URL | ||
1542 | if (($url!='') && parse_url($url,PHP_URL_SCHEME)=='') $url = 'http://'.$url; | 1546 | if (($url!='') && parse_url($url,PHP_URL_SCHEME)=='') $url = 'http://'.$url; |
1543 | // If this is an HTTP link, we try go get the page to extact the title (otherwise we will to straight to the edit form.) | 1547 | // If this is an HTTP link, we try go get the page to extact the title (otherwise we will to straight to the edit form.) |
1544 | if (empty($title) && parse_url($url,PHP_URL_SCHEME)=='http') | 1548 | if (empty($title) && parse_url($url,PHP_URL_SCHEME)=='http') |
1545 | { | 1549 | { |
1546 | list($status,$headers,$data) = getHTTP($url,4); // Short timeout to keep the application responsive. | 1550 | list($status,$headers,$data) = getHTTP($url,4); // Short timeout to keep the application responsive. |
1547 | // FIXME: Decode charset according to specified in either 1) HTTP response headers or 2) <head> in html | 1551 | // FIXME: Decode charset according to specified in either 1) HTTP response headers or 2) <head> in html |
1548 | if (strpos($status,'200 OK')!==false) $title=html_entity_decode(html_extract_title($data),ENT_QUOTES,'UTF-8'); | 1552 | if (strpos($status,'200 OK')!==false) |
1549 | 1553 | { | |
1554 | // Look for charset in html header. | ||
1555 | preg_match('#<meta .*charset=.*>#Usi', $data, $meta); | ||
1556 | |||
1557 | // If found, extract encoding. | ||
1558 | if (!empty($meta[0])) | ||
1559 | { | ||
1560 | // Get encoding specified in header. | ||
1561 | preg_match('#charset="?(.*)"#si', $meta[0], $enc); | ||
1562 | // If charset not found, use utf-8. | ||
1563 | $html_charset = (!empty($enc[1])) ? strtolower($enc[1]) : 'utf-8'; | ||
1564 | } | ||
1565 | else { $html_charset = 'utf-8'; } | ||
1566 | |||
1567 | // Extract title | ||
1568 | $title = html_extract_title($data); | ||
1569 | if (!empty($title)) | ||
1570 | { | ||
1571 | // Re-encode title in utf-8 if necessary. | ||
1572 | $title = ($html_charset == 'iso-8859-1') ? utf8_encode($title) : $title; | ||
1573 | } | ||
1574 | } | ||
1550 | } | 1575 | } |
1551 | if ($url=='') $url='?'.smallHash($linkdate); // In case of empty URL, this is just a text (with a link that point to itself) | 1576 | if ($url=='') $url='?'.smallHash($linkdate); // In case of empty URL, this is just a text (with a link that point to itself) |
1552 | $link = array('linkdate'=>$linkdate,'title'=>$title,'url'=>$url,'description'=>$description,'tags'=>$tags,'private'=>0); | 1577 | $link = array('linkdate'=>$linkdate,'title'=>$title,'url'=>$url,'description'=>$description,'tags'=>$tags,'private'=>$private); |
1553 | } | 1578 | } |
1554 | 1579 | ||
1555 | $PAGE = new pageBuilder; | 1580 | $PAGE = new pageBuilder; |
@@ -1674,7 +1699,11 @@ function importFile() | |||
1674 | { | 1699 | { |
1675 | $attr=$m[1]; $value=$m[2]; | 1700 | $attr=$m[1]; $value=$m[2]; |
1676 | if ($attr=='HREF') $link['url']=html_entity_decode($value,ENT_QUOTES,'UTF-8'); | 1701 | if ($attr=='HREF') $link['url']=html_entity_decode($value,ENT_QUOTES,'UTF-8'); |
1677 | elseif ($attr=='ADD_DATE') $raw_add_date=intval($value); | 1702 | elseif ($attr=='ADD_DATE') |
1703 | { | ||
1704 | $raw_add_date=intval($value); | ||
1705 | if ($raw_add_date>30000000000) $raw_add_date/=1000; //If larger than year 2920, then was likely stored in milliseconds instead of seconds | ||
1706 | } | ||
1678 | elseif ($attr=='PRIVATE') $link['private']=($value=='0'?0:1); | 1707 | elseif ($attr=='PRIVATE') $link['private']=($value=='0'?0:1); |
1679 | elseif ($attr=='TAGS') $link['tags']=html_entity_decode(str_replace(',',' ',$value),ENT_QUOTES,'UTF-8'); | 1708 | elseif ($attr=='TAGS') $link['tags']=html_entity_decode(str_replace(',',' ',$value),ENT_QUOTES,'UTF-8'); |
1680 | } | 1709 | } |
@@ -2009,7 +2038,7 @@ function lazyThumbnail($url,$href=false) | |||
2009 | function install() | 2038 | function install() |
2010 | { | 2039 | { |
2011 | // On free.fr host, make sure the /sessions directory exists, otherwise login will not work. | 2040 | // On free.fr host, make sure the /sessions directory exists, otherwise login will not work. |
2012 | if (endsWith($_SERVER['SERVER_NAME'],'.free.fr') && !is_dir($_SERVER['DOCUMENT_ROOT'].'/sessions')) mkdir($_SERVER['DOCUMENT_ROOT'].'/sessions',0705); | 2041 | if (endsWith($_SERVER['HTTP_HOST'],'.free.fr') && !is_dir($_SERVER['DOCUMENT_ROOT'].'/sessions')) mkdir($_SERVER['DOCUMENT_ROOT'].'/sessions',0705); |
2013 | 2042 | ||
2014 | 2043 | ||
2015 | // This part makes sure sessions works correctly. | 2044 | // This part makes sure sessions works correctly. |