X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;ds=sidebyside;f=index.php;h=d9692927ca292f41a43323ab6713b732b633a7df;hb=05f41b062a76238545ace056fc1cab9acd1deb1a;hp=f182ad2905f1851dae7b30a90dadd639f4e28751;hpb=03cd3750fd26d2667ccdadb55fd4807be34e1d1c;p=github%2Fshaarli%2FShaarli.git diff --git a/index.php b/index.php index f182ad29..d9692927 100644 --- a/index.php +++ b/index.php @@ -1,5 +1,5 @@ publish_update($topic_url); + } +} + // ------------------------------------------------------------------------------------------ // Session management define('INACTIVITY_TIMEOUT',3600); // (in seconds). If the user does not access any page within this time, his/her session is considered expired. @@ -378,13 +396,13 @@ function linkdate2locale($linkdate) } // Parse HTTP response headers and return an associative array. -function http_parse_headers( $headers ) +function http_parse_headers_shaarli( $headers ) { $res=array(); foreach($headers as $header) { $i = strpos($header,': '); - if ($i) + if ($i!==false) { $key=substr($header,0,$i); $value=substr($header,$i+2,strlen($header)-$i-2); @@ -401,7 +419,7 @@ function http_parse_headers( $headers ) [1] = associative array containing HTTP response headers (eg. echo getHTTP($url)[1]['Content-Type']) [2] = data Example: list($httpstatus,$headers,$data) = getHTTP('http://sebauvage.net/'); - if (strpos($httpstatus,'200 OK')) + if (strpos($httpstatus,'200 OK')!==false) echo 'Data type: '.htmlspecialchars($headers['Content-Type']); else echo 'There was an error: '.htmlspecialchars($httpstatus) @@ -415,7 +433,7 @@ function getHTTP($url,$timeout=30) $data=file_get_contents($url,false,$context,-1, 4000000); // We download at most 4 Mb from source. if (!$data) { $lasterror=error_get_last(); return array($lasterror['message'],array(),''); } $httpStatus=$http_response_header[0]; // eg. "HTTP/1.1 200 OK" - $responseHeaders=http_parse_headers($http_response_header); + $responseHeaders=http_parse_headers_shaarli($http_response_header); return array($httpStatus,$responseHeaders,$data); } catch (Exception $e) // getHTTP *can* fail silentely (we don't care if the title cannot be fetched) @@ -428,7 +446,7 @@ function getHTTP($url,$timeout=30) // (Returns an empty string if not found.) function html_extract_title($html) { - return preg_match('!(.*)!is', $html, $matches) ? trim(str_replace("\n",' ', $matches[1])) : '' ; + return preg_match('!(.*?)!is', $html, $matches) ? trim(str_replace("\n",' ', $matches[1])) : '' ; } // ------------------------------------------------------------------------------------------ @@ -574,7 +592,10 @@ class linkdb implements Iterator, Countable, ArrayAccess $s = strtolower($searchterms); foreach($this->links as $l) { - $found=strpos(strtolower($l['title']),$s) || strpos(strtolower($l['description']),$s) || strpos(strtolower($l['url']),$s) || strpos(strtolower($l['tags']),$s); + $found= (strpos(strtolower($l['title']),$s)!==false) + || (strpos(strtolower($l['description']),$s)!==false) + || (strpos(strtolower($l['url']),$s)!==false) + || (strpos(strtolower($l['tags']),$s)!==false); if ($found) $filtered[$l['linkdate']] = $l; } krsort($filtered); @@ -644,16 +665,29 @@ function showRSS() $pageaddr=htmlspecialchars(serverUrl().$_SERVER["SCRIPT_NAME"]); echo ''; echo ''.htmlspecialchars($GLOBALS['title']).''.$pageaddr.''; - echo 'Shared links'.$pageaddr.''."\n\n"; + echo 'Shared linksen-en'.$pageaddr.''."\n\n"; + if (!empty($GLOBALS['config']['PUBSUBHUB_URL'])) + { + echo ''; + echo ''; + echo ''; + echo ''; + } $i=0; $keys=array(); foreach($linksToDisplay as $key=>$value) { $keys[]=$key; } // No, I can't use array_keys(). while ($i<50 && $i'.htmlspecialchars($link['title']).''.htmlspecialchars($link['url']).''.htmlspecialchars($link['url']).''; - if (!$GLOBALS['config']['HIDE_TIMESTAMPS'] || isLoggedIn()) echo ''.htmlspecialchars($rfc822date).''; - echo ''."\n"; + $absurl = htmlspecialchars($link['url']); + if (startsWith($absurl,'?')) $absurl=$pageaddr.$absurl; // make permalink URL absolute + echo ''.htmlspecialchars($link['title']).''.$absurl.''.$absurl.''; + if (!$GLOBALS['config']['HIDE_TIMESTAMPS'] || isLoggedIn()) echo ''.htmlspecialchars($rfc822date)."\n"; + if ($link['tags']!='') // Adding tags to each RSS entry (as mentioned in RSS specification) + { + foreach(explode(' ',$link['tags']) as $tag) { echo ''.htmlspecialchars($tag).''."\n"; } + } + echo ''."\n\n"; $i++; } echo ''; @@ -683,15 +717,29 @@ function showATOM() $link = $linksToDisplay[$keys[$i]]; $iso8601date = linkdate2iso8601($link['linkdate']); $latestDate = max($latestDate,$iso8601date); - $entries.=''.htmlspecialchars($link['title']).''.htmlspecialchars($link['url']).''; + $absurl = htmlspecialchars($link['url']); + if (startsWith($absurl,'?')) $absurl=$pageaddr.$absurl; // make permalink URL absolute + $entries.=''.htmlspecialchars($link['title']).''.$absurl.''; if (!$GLOBALS['config']['HIDE_TIMESTAMPS'] || isLoggedIn()) $entries.=''.htmlspecialchars($iso8601date).''; - $entries.=''.nl2br(htmlspecialchars($link['description'])).''."\n"; + $entries.=''.nl2br(text2clickable(htmlspecialchars($link['description'])))."\n"; + if ($link['tags']!='') // Adding tags to each ATOM entry (as mentioned in ATOM specification) + { + foreach(explode(' ',$link['tags']) as $tag) + { $entries.=''."\n"; } + } + $entries.="\n"; $i++; } $feed=''; $feed.=''.htmlspecialchars($GLOBALS['title']).''; if (!$GLOBALS['config']['HIDE_TIMESTAMPS'] || isLoggedIn()) $feed.=''.htmlspecialchars($latestDate).''; - $feed.=''; + $feed.=''; + if (!empty($GLOBALS['config']['PUBSUBHUB_URL'])) + { + $feed.=''; + $feed.=''; + $feed.=''; + } $feed.=''.htmlspecialchars($pageaddr).''; $feed.=''.htmlspecialchars($pageaddr).''."\n\n"; // Yes, I know I should use a real IRI (RFC3987), but the site URL will do. $feed.=$entries; @@ -738,6 +786,33 @@ function renderPage() exit; } + // -------- Picture wall + if (startswith($_SERVER["QUERY_STRING"],'do=picwall')) + { + // Optionnaly filter the results: + $linksToDisplay=array(); + if (!empty($_GET['searchterm'])) $linksToDisplay = $LINKSDB->filterFulltext($_GET['searchterm']); + elseif (!empty($_GET['searchtags'])) $linksToDisplay = $LINKSDB->filterTags(trim($_GET['searchtags'])); + else $linksToDisplay = $LINKSDB; + $body=''; + + foreach($linksToDisplay as $link) + { + $href='?'.htmlspecialchars(smallhash($link['linkdate']),ENT_QUOTES); + $thumb=thumbnail($link['url'],$href); + if ($thumb!='') + { + $body.='
'.$thumb.''.htmlspecialchars($link['title']).'
'; + + } + } + $body = '
'.$body.'
'; + $data = array('pageheader'=>'
 ','body'=>$body,'onload'=>''); + templatePage($data); + exit; + + } + // -------- Tag cloud if (startswith($_SERVER["QUERY_STRING"],'do=tagcloud')) { @@ -805,15 +880,15 @@ function renderPage() // Show login screen, then redirect to ?post=... if (isset($_GET['post'])) { - header('Location: ?do=login&post='.urlencode($_GET['post']).(isset($_GET['title'])?'&title='.urlencode($_GET['title']):'').(isset($_GET['source'])?'&source='.urlencode($_GET['source']):'')); // Redirect to login page, then back to post link. + header('Location: ?do=login&post='.urlencode($_GET['post']).(!empty($_GET['title'])?'&title='.urlencode($_GET['title']):'').(!empty($_GET['source'])?'&source='.urlencode($_GET['source']):'')); // Redirect to login page, then back to post link. exit; } // Show search form and display list of links. $searchform=<< -
-
+
+
HTML; $data = array('pageheader'=>$searchform,'body'=>templateLinkList(),'onload'=>''); @@ -830,13 +905,13 @@ HTML; // The javascript code for the bookmarklet: $changepwd = ($GLOBALS['config']['OPEN_SHAARLI'] ? '' : 'Change password - Change your password.

' ); $toolbar= <<
+

{$changepwd} Configure your Shaarli - Change Title, timezone...

Rename/delete tags - Rename or delete a tag in all links.

Import - Import Netscape html bookmarks (as exported from Firefox, Chrome, Opera, delicious...)

Export - Export Netscape html bookmarks (which can be imported in Firefox, Chrome, Opera, delicious...)

- Shaare link - Drag this link to your bookmarks toolbar (or right-click it and choose Bookmark This Link....). Then click "Shaare link" button in any page you want to share.

+ Shaare link - Drag this link to your bookmarks toolbar (or right-click it and choose Bookmark This Link....). Then click "Shaare link" button in any page you want to share.

HTML; $data = array('pageheader'=>$toolbar,'body'=>'','onload'=>''); @@ -866,7 +941,7 @@ HTML; { $token = getToken(); $changepwdform= << +
Old password:     New password: @@ -925,7 +1000,7 @@ HTML; { $token = getToken(); $changetagform = << + Tag: @@ -978,7 +1053,7 @@ HTML; if (startswith($_SERVER["QUERY_STRING"],'do=addlink')) { $onload = 'onload="document.addform.post.focus();"'; - $addform= '
'; + $addform= '
'; $data = array('pageheader'=>$addform,'body'=>'','onload'=>$onload); templatePage($data); exit; @@ -995,6 +1070,7 @@ HTML; if ($link['title']=='') $link['title']=$link['url']; // If title is empty, use the URL as title. $LINKSDB[$linkdate] = $link; $LINKSDB->savedb(); // save to disk + pubsubhub(); invalidateCaches(); // If we are called from the bookmarklet, we must close the popup: @@ -1049,9 +1125,9 @@ HTML; $url=$_GET['post']; // We remove the annoying parameters added by FeedBurner and GoogleFeedProxy (?utm_source=...) - $i=strpos($url,'&utm_source='); if ($i) $url=substr($url,0,$i); - $i=strpos($url,'?utm_source='); if ($i) $url=substr($url,0,$i); - $i=strpos($url,'#xtor=RSS-'); if ($i) $url=substr($url,0,$i); + $i=strpos($url,'&utm_source='); if ($i!==false) $url=substr($url,0,$i); + $i=strpos($url,'?utm_source='); if ($i!==false) $url=substr($url,0,$i); + $i=strpos($url,'#xtor=RSS-'); if ($i!==false) $url=substr($url,0,$i); $link_is_new = false; $link = $LINKSDB->getLinkFromUrl($url); // Check if URL is not already in database (in this case, we will edit the existing link) @@ -1067,7 +1143,7 @@ HTML; { list($status,$headers,$data) = getHTTP($url,4); // Short timeout to keep the application responsive. // FIXME: Decode charset according to specified in either 1) HTTP response headers or 2) in html - if (strpos($status,'200 OK')) $title=html_entity_decode(html_extract_title($data),ENT_QUOTES,'UTF-8'); + if (strpos($status,'200 OK')!==false) $title=html_entity_decode(html_extract_title($data),ENT_QUOTES,'UTF-8'); } if ($url=='') $url='?'.smallHash($linkdate); // In case of empty URL, this is just a text (with a link that point to itself) $link = array('linkdate'=>$linkdate,'title'=>$title,'url'=>$url,'description'=>$description,'tags'=>$tags,'private'=>0); @@ -1084,7 +1160,7 @@ HTML; if (empty($_GET['what'])) { $toolbar= <<
+
Export all - Export all links

Export public - Export public links only

Export private - Export private links only

@@ -1146,9 +1222,9 @@ HTML; $maxfilesize=getMaxFileSize(); $onload = 'onload="document.uploadform.filetoupload.focus();"'; $uploadform=<< +
Import Netscape html bookmarks (as exported from Firefox/Chrome/Opera/delicious/diigo...) (Max: {$maxfilesize} bytes). - + @@ -1166,8 +1242,8 @@ HTML; // -------- Otherwise, simply display search form and links: $searchform=<< - -
+
+
HTML; $data = array('pageheader'=>$searchform,'body'=>templateLinkList(),'onload'=>''); @@ -1330,21 +1406,28 @@ function templateLinkList() $i = ($page-1)*$_SESSION['LINKS_PER_PAGE']; // Start index. $end = $i+$_SESSION['LINKS_PER_PAGE']; $redir = empty($GLOBALS['redirector']) ? '' : $GLOBALS['redirector']; // optional redirector URL + $token = ''; if (isLoggedIn()) $token=getToken(); while ($i<$end && $i'; + $classLi = $i%2!=0 ? '' : 'class="publicLinkHightLight"'; + $classprivate = ($link['private']==0 ? $classLi : 'class="private"'); + if (isLoggedIn()) + { + $actions='
'; + $actions.='
'; + $actions.='
'; + } $tags=''; if ($link['tags']!='') { foreach(explode(' ',$link['tags']) as $tag) { $tags.=''.htmlspecialchars($tag).' '; } $tags='
'.$tags.'
'; } - $linklist.='
  • '.thumbnail($link['url']); + $linklist.='
  • '.thumbnail($link['url']).'
    '; $linklist.=' +
  • HTML; $paging = '
    '.$linksperpage.$paging.'
    '; $linklist=''; return $linklist; } -// Returns the HTML code to display a thumbnail for a link. +// Returns the HTML code to display a thumbnail for a link +// with a link to the original URL. // Understands various services (youtube.com...) -function thumbnail($url) +// Input: $url = url for which the thumbnail must be found. +// $href = if provided, this URL will be followed instead of $url +function thumbnail($url,$href=false) { if (!$GLOBALS['config']['ENABLE_THUMBNAILS']) return ''; + if ($href==false) $href=$url; + // For most hosts, the URL of the thumbnail can be easily deduced from the URL of the link. // (eg. http://www.youtube.com/watch?v=spVypYk4kto ---> http://img.youtube.com/vi/spVypYk4kto/default.jpg ) // ^^^^^^^^^^^ ^^^^^^^^^^^ @@ -1383,26 +1471,32 @@ function thumbnail($url) if ($domain=='youtube.com' || $domain=='www.youtube.com') { parse_str(parse_url($url,PHP_URL_QUERY), $params); // Extract video ID and get thumbnail - if (!empty($params['v'])) return '
    '; + if (!empty($params['v'])) return ''; } + if ($domain=='youtu.be') // Youtube short links + { + $path = parse_url($url,PHP_URL_PATH); + return ''; + } if ($domain=='imgur.com') { $path = parse_url($url,PHP_URL_PATH); - if (strpos($path,'/r/')==0) return '
    '; - if (strpos($path,'/gallery/')==0) return '
    '; - if (substr_count($path,'/')==1) return '
    '; + if (startsWith($path,'/a/')) return ''; // Thumbnails for albums are not available. + if (startsWith($path,'/r/')) return ''; + if (startsWith($path,'/gallery/')) return ''; + if (substr_count($path,'/')==1) return ''; } if ($domain=='i.imgur.com') { $pi = pathinfo(parse_url($url,PHP_URL_PATH)); - if (!empty($pi['filename'])) return '
    '; + if (!empty($pi['filename'])) return ''; } if ($domain=='dailymotion.com' || $domain=='www.dailymotion.com') { - if (strpos($url,'dailymotion.com/video/')) + if (strpos($url,'dailymotion.com/video/')!==false) { $thumburl=str_replace('dailymotion.com/video/','dailymotion.com/thumbnail/video/',$url); - return '
    '; + return ''; } } if (endsWith($domain,'.imageshack.us')) @@ -1411,21 +1505,33 @@ function thumbnail($url) if ($ext=='jpg' || $ext=='jpeg' || $ext=='png' || $ext=='gif') { $thumburl = substr($url,0,strlen($url)-strlen($ext)).'th.'.$ext; - return '
    '; + return ''; } } - - + // Some other hosts are SLOW AS HELL and usually require an extra HTTP request to get the thumbnail URL. // So we deport the thumbnail generation in order not to slow down page generation // (and we also cache the thumbnail) if (!$GLOBALS['config']['ENABLE_LOCALCACHE']) return ''; // If local cache is disabled, no thumbnails for services which require the use a local cache. - if ($domain=='flickr.com' || endsWith($domain,'.flickr.com') || $domain=='vimeo.com') + if ($domain=='flickr.com' || endsWith($domain,'.flickr.com') + || $domain=='vimeo.com' + || $domain=='ted.com' || endsWith($domain,'.ted.com') + ) { + if ($domain=='vimeo.com') + { // Make sure this vimeo url points to a video (/xxx... where xxx is numeric) + $path = parse_url($url,PHP_URL_PATH); + if (!preg_match('!/\d+.+?!',$path)) return ''; // This is not a single video URL. + } + if ($domain=='ted.com' || endsWith($domain,'.ted.com')) + { // Make sure this TED url points to a video (/talks/...) + $path = parse_url($url,PHP_URL_PATH); + if ("/talks/" !== substr($path,0,7)) return ''; // This is not a single video URL. + } $sign = hash_hmac('sha256', $url, $GLOBALS['salt']); // We use the salt to sign data (it's random, secret, and specific to each installation) - return '
    '; + return ''; } // For all other, we try to make a thumbnail of links ending with .jpg/jpeg/png/gif @@ -1435,7 +1541,7 @@ function thumbnail($url) if ($ext=='jpg' || $ext=='jpeg' || $ext=='png' || $ext=='gif') { $sign = hash_hmac('sha256', $url, $GLOBALS['salt']); // We use the salt to sign data (it's random, secret, and specific to each installation) - return '
    '; + return ''; } return ''; // No thumbnail. @@ -1487,10 +1593,10 @@ $(document).ready(function() JS; } $feedurl=htmlspecialchars(serverUrl().$_SERVER['SCRIPT_NAME']); - $feedsearch=''; - if (!empty($_GET['searchtags'])) $feedsearch.='&searchtags='.$_GET['searchtags']; - elseif (!empty($_GET['searchterm'])) $feedsearch.='&searchterm='.$_GET['searchterm']; - $filtered_feed= ($feedsearch=='' ? '' : 'Filtered '); + $searchcrits=''; // Search criteria + if (!empty($_GET['searchtags'])) $searchcrits.='&searchtags='.$_GET['searchtags']; + elseif (!empty($_GET['searchterm'])) $searchcrits.='&searchterm='.$_GET['searchterm']; + $filtered_feed= ($searchcrits=='' ? '' : 'Filtered '); $version=shaarli_version; $title = htmlspecialchars( $GLOBALS['title'] ); @@ -1499,22 +1605,23 @@ JS; {$pagetitle} - - + + + {$jsincludes} {$newversion} -