X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;ds=sidebyside;f=index.php;h=2815f02e5e40e93f946051a2580da138f0744ca4;hb=refs%2Fpull%2F424%2Fhead;hp=c82735ca4e8f3147789d2fc816db0fc677b4c501;hpb=6fc14d530369740d27d6bd641369d4f5f5f04080;p=github%2Fshaarli%2FShaarli.git diff --git a/index.php b/index.php old mode 100755 new mode 100644 index c82735ca..2815f02e --- a/index.php +++ b/index.php @@ -1,6 +1,6 @@ /shaarli/ define('WEB_PATH', substr($_SERVER["REQUEST_URI"], 0, 1+strrpos($_SERVER["REQUEST_URI"], '/', 0))); -// PHP Settings -ini_set('max_input_time','60'); // High execution time in case of problematic imports/exports. -ini_set('memory_limit', '128M'); // Try to set max upload file size and read (May not work on some hosts). +// High execution time in case of problematic imports/exports. +ini_set('max_input_time','60'); + +// Try to set max upload file size and read +ini_set('memory_limit', '128M'); ini_set('post_max_size', '16M'); ini_set('upload_max_filesize', '16M'); -error_reporting(E_ALL^E_WARNING); // See all error except warnings. -//error_reporting(-1); // See all errors (for debugging only) -// User configuration +// See all error except warnings +error_reporting(E_ALL^E_WARNING); +// See all errors (for debugging only) +//error_reporting(-1); + +/* + * User configuration + */ if (is_file($GLOBALS['config']['CONFIG_FILE'])) { require_once $GLOBALS['config']['CONFIG_FILE']; } // Shaarli library +require_once 'application/ApplicationUtils.php'; require_once 'application/Cache.php'; require_once 'application/CachedPage.php'; +require_once 'application/FileUtils.php'; require_once 'application/HttpUtils.php'; require_once 'application/LinkDB.php'; +require_once 'application/LinkFilter.php'; require_once 'application/TimeZone.php'; require_once 'application/Url.php'; require_once 'application/Utils.php'; @@ -89,10 +161,10 @@ require_once 'application/Router.php'; // Ensure the PHP version is supported try { - checkPHPVersion('5.3', PHP_VERSION); -} catch(Exception $e) { + ApplicationUtils::checkPHPVersion('5.3', PHP_VERSION); +} catch(Exception $exc) { header('Content-Type: text/plain; charset=utf-8'); - echo $e->getMessage(); + echo $exc->getMessage(); exit; } @@ -151,9 +223,6 @@ header("Cache-Control: no-store, no-cache, must-revalidate"); header("Cache-Control: post-check=0, pre-check=0", false); header("Pragma: no-cache"); -// Directories creations (Note that your web host may require different rights than 705.) -if (!is_writable(realpath(dirname(__FILE__)))) die('
ERROR: Shaarli does not have the right to write in its own directory.
'); - // Handling of old config file which do not have the new parameters. if (empty($GLOBALS['title'])) $GLOBALS['title']='Shared links on '.escape(index_url($_SERVER)); if (empty($GLOBALS['timezone'])) $GLOBALS['timezone']=date_default_timezone_get(); @@ -163,8 +232,24 @@ if (empty($GLOBALS['privateLinkByDefault'])) $GLOBALS['privateLinkByDefault']=fa if (empty($GLOBALS['titleLink'])) $GLOBALS['titleLink']='?'; // I really need to rewrite Shaarli with a proper configuation manager. -// Run config screen if first run: if (! is_file($GLOBALS['config']['CONFIG_FILE'])) { + // Ensure Shaarli has proper access to its resources + $errors = ApplicationUtils::checkResourcePermissions($GLOBALS['config']); + + if ($errors != array()) { + $message = '

Insufficient permissions:

'; + + header('Content-Type: text/html; charset=utf-8'); + echo $message; + exit; + } + + // Display the installation form if no existing config is found install(); } @@ -183,11 +268,11 @@ header('Content-Type: text/html; charset=utf-8'); // We use UTF-8 for proper int //================================================================================================== function setup_login_state() { - $userIsLoggedIn = false; // By default, we do not consider the user as logged in; - $loginFailure = false; // If set to true, every attempt to authenticate the user will fail. This indicates that an important condition isn't met. if ($GLOBALS['config']['OPEN_SHAARLI']) { - $userIsLoggedIn = true; + return true; } + $userIsLoggedIn = false; // By default, we do not consider the user as logged in; + $loginFailure = false; // If set to true, every attempt to authenticate the user will fail. This indicates that an important condition isn't met. if (!isset($GLOBALS['login'])) { $userIsLoggedIn = false; // Shaarli is not configured yet. $loginFailure = true; @@ -222,56 +307,15 @@ function setup_login_state() { } $userIsLoggedIn = setup_login_state(); -// Checks if an update is available for Shaarli. -// (at most once a day, and only for registered user.) -// Output: '' = no new version. -// other= the available version. -function checkUpdate() -{ - if (!isLoggedIn()) return ''; // Do not check versions for visitors. - if (empty($GLOBALS['config']['ENABLE_UPDATECHECK'])) return ''; // Do not check if the user doesn't want to. - - // Get latest version number at most once a day. - if (!is_file($GLOBALS['config']['UPDATECHECK_FILENAME']) || (filemtime($GLOBALS['config']['UPDATECHECK_FILENAME'])', '', str_replace('$1',$url); -} - -// This function inserts   where relevant so that multiple spaces are properly displayed in HTML -// even in the absence of
  (This is used in description to keep text formatting)
-function keepMultipleSpaces($text)
-{
-    return str_replace('  ','  ',$text);
-
-}
 // ------------------------------------------------------------------------------------------
 // Sniff browser language to display dates in the right format automatically.
 // (Note that is may not work on your server if the corresponding local is not installed.)
@@ -580,28 +624,61 @@ class pageBuilder
 
     function __construct()
     {
-        $this->tpl=false;
+        $this->tpl = false;
     }
 
+    /**
+     * Initialize all default tpl tags.
+     */
     private function initialize()
     {
         $this->tpl = new RainTPL;
-        $this->tpl->assign('newversion',escape(checkUpdate()));
-        $this->tpl->assign('feedurl',escape(index_url($_SERVER)));
-        $searchcrits=''; // Search criteria
-        if (!empty($_GET['searchtags'])) $searchcrits.='&searchtags='.urlencode($_GET['searchtags']);
-        elseif (!empty($_GET['searchterm'])) $searchcrits.='&searchterm='.urlencode($_GET['searchterm']);
-        $this->tpl->assign('searchcrits',$searchcrits);
-        $this->tpl->assign('source',index_url($_SERVER));
-        $this->tpl->assign('version',shaarli_version);
-        $this->tpl->assign('scripturl',index_url($_SERVER));
-        $this->tpl->assign('pagetitle','Shaarli');
-        $this->tpl->assign('privateonly',!empty($_SESSION['privateonly'])); // Show only private links?
-        if (!empty($GLOBALS['title'])) $this->tpl->assign('pagetitle',$GLOBALS['title']);
-        if (!empty($GLOBALS['titleLink'])) $this->tpl->assign('titleLink',$GLOBALS['titleLink']);
-        if (!empty($GLOBALS['pagetitle'])) $this->tpl->assign('pagetitle',$GLOBALS['pagetitle']);
-        $this->tpl->assign('shaarlititle',empty($GLOBALS['title']) ? 'Shaarli': $GLOBALS['title'] );
-        return;
+
+        try {
+            $version = ApplicationUtils::checkUpdate(
+                shaarli_version,
+                $GLOBALS['config']['UPDATECHECK_FILENAME'],
+                $GLOBALS['config']['UPDATECHECK_INTERVAL'],
+                $GLOBALS['config']['ENABLE_UPDATECHECK'],
+                isLoggedIn(),
+                $GLOBALS['config']['UPDATECHECK_BRANCH']
+            );
+            $this->tpl->assign('newVersion', escape($version));
+            $this->tpl->assign('versionError', '');
+
+        } catch (Exception $exc) {
+            logm($exc->getMessage());
+            $this->tpl->assign('newVersion', '');
+            $this->tpl->assign('versionError', escape($exc->getMessage()));
+        }
+
+        $this->tpl->assign('feedurl', escape(index_url($_SERVER)));
+        $searchcrits = ''; // Search criteria
+        if (!empty($_GET['searchtags'])) {
+            $searchcrits .= '&searchtags=' . urlencode($_GET['searchtags']);
+        }
+        elseif (!empty($_GET['searchterm'])) {
+            $searchcrits .= '&searchterm=' . urlencode($_GET['searchterm']);
+        }
+        $this->tpl->assign('searchcrits', $searchcrits);
+        $this->tpl->assign('source', index_url($_SERVER));
+        $this->tpl->assign('version', shaarli_version);
+        $this->tpl->assign('scripturl', index_url($_SERVER));
+        $this->tpl->assign('pagetitle', 'Shaarli');
+        $this->tpl->assign('privateonly', !empty($_SESSION['privateonly'])); // Show only private links?
+        if (!empty($GLOBALS['title'])) {
+            $this->tpl->assign('pagetitle', $GLOBALS['title']);
+        }
+        if (!empty($GLOBALS['titleLink'])) {
+            $this->tpl->assign('titleLink', $GLOBALS['titleLink']);
+        }
+        if (!empty($GLOBALS['pagetitle'])) {
+            $this->tpl->assign('pagetitle', $GLOBALS['pagetitle']);
+        }
+        $this->tpl->assign('shaarlititle', empty($GLOBALS['title']) ? 'Shaarli': $GLOBALS['title']);
+        if (!empty($GLOBALS['plugin_errors'])) {
+            $this->tpl->assign('plugin_errors', $GLOBALS['plugin_errors']);
+        }
     }
 
     // The following assign() method is basically the same as RainTPL (except that it's lazy)
@@ -647,24 +724,30 @@ function showRSS()
     // If cached was not found (or not usable), then read the database and build the response:
     $LINKSDB = new LinkDB(
         $GLOBALS['config']['DATASTORE'],
-        isLoggedIn() || $GLOBALS['config']['OPEN_SHAARLI'],
-        $GLOBALS['config']['HIDE_PUBLIC_LINKS']
+        isLoggedIn(),
+        $GLOBALS['config']['HIDE_PUBLIC_LINKS'],
+        $GLOBALS['redirector']
     );
     // Read links from database (and filter private links if user it not logged in).
 
     // Optionally filter the results:
-    $linksToDisplay=array();
-    if (!empty($_GET['searchterm'])) $linksToDisplay = $LINKSDB->filterFulltext($_GET['searchterm']);
-    else if (!empty($_GET['searchtags']))   $linksToDisplay = $LINKSDB->filterTags(trim($_GET['searchtags']));
-    else $linksToDisplay = $LINKSDB;
+    if (!empty($_GET['searchterm'])) {
+        $linksToDisplay = $LINKSDB->filter(LinkFilter::$FILTER_TEXT, $_GET['searchterm']);
+    }
+    elseif (!empty($_GET['searchtags'])) {
+        $linksToDisplay = $LINKSDB->filter(LinkFilter::$FILTER_TAG, trim($_GET['searchtags']));
+    }
+    else {
+        $linksToDisplay = $LINKSDB;
+    }
 
     $nblinksToDisplay = 50;  // Number of links to display.
-    if (!empty($_GET['nb']))  // In URL, you can specificy the number of links. Example: nb=200 or nb=all for all links.
-    {
-        $nblinksToDisplay = $_GET['nb']=='all' ? count($linksToDisplay) : max($_GET['nb']+0,1) ;
+    // In URL, you can specificy the number of links. Example: nb=200 or nb=all for all links.
+    if (!empty($_GET['nb'])) {
+        $nblinksToDisplay = $_GET['nb'] == 'all' ? count($linksToDisplay) : max(intval($_GET['nb']), 1);
     }
 
-    $pageaddr=escape(index_url($_SERVER));
+    $pageaddr = escape(index_url($_SERVER));
     echo '';
     echo ''.$GLOBALS['title'].''.$pageaddr.'';
     echo 'Shared linksen-en'.$pageaddr.''."\n\n";
@@ -699,7 +782,9 @@ function showRSS()
         // If user wants permalinks first, put the final link in description
         if ($usepermalinks===true) $descriptionlink = '(Link)';
         if (strlen($link['description'])>0) $descriptionlink = '
'.$descriptionlink; - echo ''."\n\n"; + echo '' . "\n\n"; $i++; } echo '
'; @@ -736,20 +821,26 @@ function showATOM() // Read links from database (and filter private links if used it not logged in). $LINKSDB = new LinkDB( $GLOBALS['config']['DATASTORE'], - isLoggedIn() || $GLOBALS['config']['OPEN_SHAARLI'], - $GLOBALS['config']['HIDE_PUBLIC_LINKS'] + isLoggedIn(), + $GLOBALS['config']['HIDE_PUBLIC_LINKS'], + $GLOBALS['redirector'] ); // Optionally filter the results: - $linksToDisplay=array(); - if (!empty($_GET['searchterm'])) $linksToDisplay = $LINKSDB->filterFulltext($_GET['searchterm']); - else if (!empty($_GET['searchtags'])) $linksToDisplay = $LINKSDB->filterTags(trim($_GET['searchtags'])); - else $linksToDisplay = $LINKSDB; + if (!empty($_GET['searchterm'])) { + $linksToDisplay = $LINKSDB->filter(LinkFilter::$FILTER_TEXT, $_GET['searchterm']); + } + else if (!empty($_GET['searchtags'])) { + $linksToDisplay = $LINKSDB->filter(LinkFilter::$FILTER_TAG, trim($_GET['searchtags'])); + } + else { + $linksToDisplay = $LINKSDB; + } $nblinksToDisplay = 50; // Number of links to display. - if (!empty($_GET['nb'])) // In URL, you can specificy the number of links. Example: nb=200 or nb=all for all links. - { - $nblinksToDisplay = $_GET['nb']=='all' ? count($linksToDisplay) : max($_GET['nb']+0,1) ; + // In URL, you can specificy the number of links. Example: nb=200 or nb=all for all links. + if (!empty($_GET['nb'])) { + $nblinksToDisplay = $_GET['nb']=='all' ? count($linksToDisplay) : max(intval($_GET['nb']), 1); } $pageaddr=escape(index_url($_SERVER)); @@ -778,7 +869,9 @@ function showATOM() if ($usepermalinks===true) $descriptionlink = '(Link)'; if (strlen($link['description'])>0) $descriptionlink = '
'.$descriptionlink; - $entries.='\n"; + $entries .= '\n"; if ($link['tags']!='') // Adding tags to each ATOM entry (as mentioned in ATOM specification) { foreach(explode(' ',$link['tags']) as $tag) @@ -830,8 +923,9 @@ function showDailyRSS() { // Read links from database (and filter private links if used it not logged in). $LINKSDB = new LinkDB( $GLOBALS['config']['DATASTORE'], - isLoggedIn() || $GLOBALS['config']['OPEN_SHAARLI'], - $GLOBALS['config']['HIDE_PUBLIC_LINKS'] + isLoggedIn(), + $GLOBALS['config']['HIDE_PUBLIC_LINKS'], + $GLOBALS['redirector'] ); /* Some Shaarlies may have very few links, so we need to look @@ -885,7 +979,7 @@ function showDailyRSS() { // We pre-format some fields for proper output. foreach ($linkdates as $linkdate) { $l = $LINKSDB[$linkdate]; - $l['formatedDescription'] = nl2br(keepMultipleSpaces(text2clickable($l['description']))); + $l['formatedDescription'] = format_description($l['description'], $GLOBALS['redirector']); $l['thumbnail'] = thumbnail($l['url']); $l['timestamp'] = linkdate2timestamp($l['linkdate']); if (startsWith($l['url'], '?')) { @@ -912,13 +1006,18 @@ function showDailyRSS() { exit; } -// "Daily" page. -function showDaily() +/** + * Show the 'Daily' page. + * + * @param PageBuilder $pageBuilder Template engine wrapper. + */ +function showDaily($pageBuilder) { $LINKSDB = new LinkDB( $GLOBALS['config']['DATASTORE'], - isLoggedIn() || $GLOBALS['config']['OPEN_SHAARLI'], - $GLOBALS['config']['HIDE_PUBLIC_LINKS'] + isLoggedIn(), + $GLOBALS['config']['HIDE_PUBLIC_LINKS'], + $GLOBALS['redirector'] ); $day=Date('Ymd',strtotime('-1 day')); // Yesterday, in format YYYYMMDD. @@ -936,7 +1035,7 @@ function showDaily() } try { - $linksToDisplay = $LINKSDB->filterDay($day); + $linksToDisplay = $LINKSDB->filter(LinkFilter::$FILTER_DAY, $day); } catch (Exception $exc) { error_log($exc); $linksToDisplay = array(); @@ -949,7 +1048,7 @@ function showDaily() $taglist = explode(' ',$link['tags']); uasort($taglist, 'strcasecmp'); $linksToDisplay[$key]['taglist']=$taglist; - $linksToDisplay[$key]['formatedDescription']=nl2br(keepMultipleSpaces(text2clickable($link['description']))); + $linksToDisplay[$key]['formatedDescription'] = format_description($link['description'], $GLOBALS['redirector']); $linksToDisplay[$key]['thumbnail'] = thumbnail($link['url']); $linksToDisplay[$key]['timestamp'] = linkdate2timestamp($link['linkdate']); } @@ -975,7 +1074,7 @@ function showDaily() array_push($columns[$index],$link); // Put entry in this column. $fill[$index]+=$length; } - $PAGE = new pageBuilder; + $data = array( 'linksToDisplay' => $linksToDisplay, 'linkcount' => count($LINKSDB), @@ -988,10 +1087,10 @@ function showDaily() $pluginManager->executeHooks('render_daily', $data, array('loggedin' => isLoggedIn())); foreach ($data as $key => $value) { - $PAGE->assign($key, $value); + $pageBuilder->assign($key, $value); } - $PAGE->renderPage('daily'); + $pageBuilder->renderPage('daily'); exit; } @@ -1008,8 +1107,9 @@ function renderPage() { $LINKSDB = new LinkDB( $GLOBALS['config']['DATASTORE'], - isLoggedIn() || $GLOBALS['config']['OPEN_SHAARLI'], - $GLOBALS['config']['HIDE_PUBLIC_LINKS'] + isLoggedIn(), + $GLOBALS['config']['HIDE_PUBLIC_LINKS'], + $GLOBALS['redirector'] ); $PAGE = new pageBuilder; @@ -1060,13 +1160,17 @@ function renderPage() if ($targetPage == Router::$PAGE_PICWALL) { // Optionally filter the results: - $links=array(); - if (!empty($_GET['searchterm'])) $links = $LINKSDB->filterFulltext($_GET['searchterm']); - elseif (!empty($_GET['searchtags'])) $links = $LINKSDB->filterTags(trim($_GET['searchtags'])); - else $links = $LINKSDB; + if (!empty($_GET['searchterm'])) { + $links = $LINKSDB->filter(LinkFilter::$FILTER_TEXT, $_GET['searchterm']); + } + elseif (! empty($_GET['searchtags'])) { + $links = $LINKSDB->filter(LinkFilter::$FILTER_TAG, trim($_GET['searchtags'])); + } + else { + $links = $LINKSDB; + } - $body=''; - $linksToDisplay=array(); + $linksToDisplay = array(); // Get only links which have a thumbnail. foreach($links as $link) @@ -1124,6 +1228,19 @@ function renderPage() exit; } + // Daily page. + if ($targetPage == Router::$PAGE_DAILY) { + showDaily($PAGE); + } + + // Display openseach plugin (XML) + if ($targetPage == Router::$PAGE_OPENSEARCH) { + header('Content-Type: application/xml; charset=utf-8'); + $PAGE->assign('serverurl', index_url($_SERVER)); + $PAGE->renderPage('opensearch'); + exit; + } + // -------- User clicks on a tag in a link: The tag is added to the list of searched tags (searchtags=...) if (isset($_GET['addtag'])) { @@ -1180,13 +1297,15 @@ function renderPage() } if (isset($params['searchtags'])) { - $tags = explode(' ',$params['searchtags']); - $tags=array_diff($tags, array($_GET['removetag'])); // Remove value from array $tags. - if (count($tags)==0) { + $tags = explode(' ', $params['searchtags']); + // Remove value from array $tags. + $tags = array_diff($tags, array($_GET['removetag'])); + $params['searchtags'] = implode(' ',$tags); + + if (empty($params['searchtags'])) { unset($params['searchtags']); - } else { - $params['searchtags'] = implode(' ',$tags); } + unset($params['page']); // We also remove page (keeping the same page has no sense, since the results are different) } header('Location: ?'.http_build_query($params)); @@ -1365,7 +1484,8 @@ function renderPage() if (!empty($_POST['deletetag']) && !empty($_POST['fromtag'])) { $needle=trim($_POST['fromtag']); - $linksToAlter = $LINKSDB->filterTags($needle,true); // True for case-sensitive tag search. + // True for case-sensitive tag search. + $linksToAlter = $LINKSDB->filter(LinkFilter::$FILTER_TAG, $needle, true); foreach($linksToAlter as $key=>$value) { $tags = explode(' ',trim($value['tags'])); @@ -1373,7 +1493,7 @@ function renderPage() $value['tags']=trim(implode(' ',$tags)); $LINKSDB[$key]=$value; } - $LINKSDB->savedb($GLOBALS['config']['PAGECACHE']); // Save to disk. + $LINKSDB->savedb($GLOBALS['config']['PAGECACHE']); echo ''; exit; } @@ -1382,7 +1502,8 @@ function renderPage() if (!empty($_POST['renametag']) && !empty($_POST['fromtag']) && !empty($_POST['totag'])) { $needle=trim($_POST['fromtag']); - $linksToAlter = $LINKSDB->filterTags($needle,true); // true for case-sensitive tag search. + // True for case-sensitive tag search. + $linksToAlter = $LINKSDB->filter(LinkFilter::$FILTER_TAG, $needle, true); foreach($linksToAlter as $key=>$value) { $tags = explode(' ',trim($value['tags'])); @@ -1425,10 +1546,14 @@ function renderPage() pubsubhub(); // If we are called from the bookmarklet, we must close the popup: - if (isset($_GET['source']) && ($_GET['source']=='bookmarklet' || $_GET['source']=='firefoxsocialapi')) { echo ''; exit; } - $returnurl = ( !empty($_POST['returnurl']) ? escape($_POST['returnurl']) : '?' ); - $returnurl .= '#'.smallHash($_POST['lf_linkdate']); // Scroll to the link which has been edited. + if (isset($_GET['source']) && ($_GET['source']=='bookmarklet' || $_GET['source']=='firefoxsocialapi')) { + echo ''; + exit; + } + + $returnurl = !empty($_POST['returnurl']) ? escape($_POST['returnurl']): '?'; $location = generateLocation($returnurl, $_SERVER['HTTP_HOST'], array('addlink', 'post', 'edit_link')); + $location .= '#'.smallHash($_POST['lf_linkdate']); // Scroll to the link which has been edited. header('Location: '. $location); // After saving the link, redirect to the page the user was on. exit; } @@ -1527,11 +1652,11 @@ function renderPage() $link_is_new = true; $linkdate = strval(date('Ymd_His')); // Get title if it was provided in URL (by the bookmarklet). - $title = (empty($_GET['title']) ? '' : $_GET['title'] ); + $title = empty($_GET['title']) ? '' : escape($_GET['title']); // Get description if it was provided in URL (by the bookmarklet). [Bronco added that] - $description = (empty($_GET['description']) ? '' : $_GET['description']); - $tags = (empty($_GET['tags']) ? '' : $_GET['tags'] ); - $private = (!empty($_GET['private']) && $_GET['private'] === "1" ? 1 : 0); + $description = empty($_GET['description']) ? '' : escape($_GET['description']); + $tags = empty($_GET['tags']) ? '' : escape($_GET['tags']); + $private = !empty($_GET['private']) && $_GET['private'] === "1" ? 1 : 0; // If this is an HTTP(S) link, we try go get the page to extract the title (otherwise we will to straight to the edit form.) if (empty($title) && strpos(get_url_scheme($url), 'http') !== false) { // Short timeout to keep the application responsive @@ -1667,11 +1792,12 @@ HTML; // Process the import file form. function importFile() { - if (!(isLoggedIn() || $GLOBALS['config']['OPEN_SHAARLI'])) { die('Not allowed.'); } + if (!isLoggedIn()) { die('Not allowed.'); } $LINKSDB = new LinkDB( $GLOBALS['config']['DATASTORE'], - isLoggedIn() || $GLOBALS['config']['OPEN_SHAARLI'], - $GLOBALS['config']['HIDE_PUBLIC_LINKS'] + isLoggedIn(), + $GLOBALS['config']['HIDE_PUBLIC_LINKS'], + $GLOBALS['redirector'] ); $filename=$_FILES['filetoupload']['name']; $filesize=$_FILES['filetoupload']['size']; @@ -1758,82 +1884,78 @@ function importFile() function buildLinkList($PAGE,$LINKSDB) { // ---- Filter link database according to parameters - $linksToDisplay=array(); - $search_type=''; - $search_crits=''; - if (isset($_GET['searchterm'])) // Fulltext search - { - $linksToDisplay = $LINKSDB->filterFulltext(trim($_GET['searchterm'])); - $search_crits=escape(trim($_GET['searchterm'])); - $search_type='fulltext'; - } - elseif (isset($_GET['searchtags'])) // Search by tag - { - $linksToDisplay = $LINKSDB->filterTags(trim($_GET['searchtags'])); - $search_crits=explode(' ',escape(trim($_GET['searchtags']))); - $search_type='tags'; - } - elseif (isset($_SERVER['QUERY_STRING']) && preg_match('/[a-zA-Z0-9-_@]{6}(&.+?)?/',$_SERVER['QUERY_STRING'])) // Detect smallHashes in URL - { - $linksToDisplay = $LINKSDB->filterSmallHash(substr(trim($_SERVER["QUERY_STRING"], '/'),0,6)); - if (count($linksToDisplay)==0) - { - header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found"); - echo '

404 Not found.

Oh crap. The link you are trying to reach does not exist or has been deleted.'; + $search_type = ''; + $search_crits = ''; + $privateonly = !empty($_SESSION['privateonly']) ? true : false; + + // Fulltext search + if (isset($_GET['searchterm'])) { + $search_crits = escape(trim($_GET['searchterm'])); + $search_type = LinkFilter::$FILTER_TEXT; + $linksToDisplay = $LINKSDB->filter($search_type, $search_crits, false, $privateonly); + } + // Search by tag + elseif (isset($_GET['searchtags'])) { + $search_crits = explode(' ', escape(trim($_GET['searchtags']))); + $search_type = LinkFilter::$FILTER_TAG; + $linksToDisplay = $LINKSDB->filter($search_type, $search_crits, false, $privateonly); + } + // Detect smallHashes in URL. + elseif (isset($_SERVER['QUERY_STRING']) + && preg_match('/[a-zA-Z0-9-_@]{6}(&.+?)?/', $_SERVER['QUERY_STRING'])) { + $search_type = LinkFilter::$FILTER_HASH; + $search_crits = substr(trim($_SERVER["QUERY_STRING"], '/'), 0, 6); + $linksToDisplay = $LINKSDB->filter($search_type, $search_crits); + + if (count($linksToDisplay) == 0) { + header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found'); + echo '

404 Not found.

Oh crap. + The link you are trying to reach does not exist or has been deleted.'; echo '
Would you mind clicking here?'; exit; } - $search_type='permalink'; } - else - $linksToDisplay = $LINKSDB; // Otherwise, display without filtering. - - - // Option: Show only private links - if (!empty($_SESSION['privateonly'])) - { - $tmp = array(); - foreach($linksToDisplay as $linkdate=>$link) - { - if ($link['private']!=0) $tmp[$linkdate]=$link; - } - $linksToDisplay=$tmp; + // Otherwise, display without filtering. + else { + $linksToDisplay = $LINKSDB->filter('', '', false, $privateonly); } // ---- Handle paging. - /* Can someone explain to me why you get the following error when using array_keys() on an object which implements the interface ArrayAccess??? - "Warning: array_keys() expects parameter 1 to be array, object given in ... " - If my class implements ArrayAccess, why won't array_keys() accept it ? ( $keys=array_keys($linksToDisplay); ) - */ - $keys=array(); foreach($linksToDisplay as $key=>$value) { $keys[]=$key; } // Stupid and ugly. Thanks PHP. + $keys = array(); + foreach ($linksToDisplay as $key => $value) { + $keys[] = $key; + } // If there is only a single link, we change on-the-fly the title of the page. - if (count($linksToDisplay)==1) $GLOBALS['pagetitle'] = $linksToDisplay[$keys[0]]['title'].' - '.$GLOBALS['title']; + if (count($linksToDisplay) == 1) { + $GLOBALS['pagetitle'] = $linksToDisplay[$keys[0]]['title'].' - '.$GLOBALS['title']; + } // Select articles according to paging. - $pagecount = ceil(count($keys)/$_SESSION['LINKS_PER_PAGE']); - $pagecount = ($pagecount==0 ? 1 : $pagecount); - $page=( empty($_GET['page']) ? 1 : intval($_GET['page'])); - $page = ( $page<1 ? 1 : $page ); - $page = ( $page>$pagecount ? $pagecount : $page ); - $i = ($page-1)*$_SESSION['LINKS_PER_PAGE']; // Start index. - $end = $i+$_SESSION['LINKS_PER_PAGE']; - $linkDisp=array(); // Links to display + $pagecount = ceil(count($keys) / $_SESSION['LINKS_PER_PAGE']); + $pagecount = $pagecount == 0 ? 1 : $pagecount; + $page= empty($_GET['page']) ? 1 : intval($_GET['page']); + $page = $page < 1 ? 1 : $page; + $page = $page > $pagecount ? $pagecount : $page; + // Start index. + $i = ($page-1) * $_SESSION['LINKS_PER_PAGE']; + $end = $i + $_SESSION['LINKS_PER_PAGE']; + $linkDisp = array(); while ($i<$end && $i1) $next_page_url='?page='.($page-1).$searchterm.$searchtags; + $searchterm = empty($_GET['searchterm']) ? '' : '&searchterm=' . $_GET['searchterm']; + $searchtags = empty($_GET['searchtags']) ? '' : '&searchtags=' . $_GET['searchtags']; + $previous_page_url = ''; + if ($i != count($keys)) { + $previous_page_url = '?page=' . ($page+1) . $searchterm . $searchtags; + } + $next_page_url=''; + if ($page>1) { + $next_page_url = '?page=' . ($page-1) . $searchterm . $searchtags; + } - $token = ''; if (isLoggedIn()) $token=getToken(); + $token = ''; + if (isLoggedIn()) { + $token = getToken(); + } // Fill all template fields. $data = array( @@ -1864,6 +1994,10 @@ function buildLinkList($PAGE,$LINKSDB) 'links' => $linkDisp, 'tags' => $LINKSDB->allTags(), ); + // FIXME! temporary fix - see #399. + if (!empty($GLOBALS['pagetitle']) && count($linkDisp) == 1) { + $data['pagetitle'] = $GLOBALS['pagetitle']; + } $pluginManager = PluginManager::getInstance(); $pluginManager->executeHooks('render_linklist', $data, array('loggedin' => isLoggedIn())); @@ -2129,45 +2263,6 @@ function install() exit; } -if (!function_exists('json_encode')) { - function json_encode($data) { - switch ($type = gettype($data)) { - case 'NULL': - return 'null'; - case 'boolean': - return ($data ? 'true' : 'false'); - case 'integer': - case 'double': - case 'float': - return $data; - case 'string': - return '"' . addslashes($data) . '"'; - case 'object': - $data = get_object_vars($data); - case 'array': - $output_index_count = 0; - $output_indexed = array(); - $output_associative = array(); - foreach ($data as $key => $value) { - $output_indexed[] = json_encode($value); - $output_associative[] = json_encode($key) . ':' . json_encode($value); - if ($output_index_count !== NULL && $output_index_count++ !== $key) { - $output_index_count = NULL; - } - } - if ($output_index_count !== NULL) { - return '[' . implode(',', $output_indexed) . ']'; - } else { - return '{' . implode(',', $output_associative) . '}'; - } - default: - return ''; // Not supported - } - } -} - - - /* Because some f*cking services like flickr require an extra HTTP request to get the thumbnail URL, I have deported the thumbnail URL code generation here, otherwise this would slow down page generation. The following function takes the URL a link (e.g. a flickr page) and return the proper thumbnail. @@ -2397,7 +2492,6 @@ if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=g if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=rss')) { showRSS(); exit; } if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=atom')) { showATOM(); exit; } if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=dailyrss')) { showDailyRSS(); exit; } -if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=daily')) { showDaily(); exit; } if (!isset($_SESSION['LINKS_PER_PAGE'])) $_SESSION['LINKS_PER_PAGE']=$GLOBALS['config']['LINKS_PER_PAGE']; renderPage(); ?>