<?php
-// Shaarli 0.5.0 - Shaare your links...
+// Shaarli 0.5.1 - Shaare your links...
// The personal, minimalist, super-fast, no-database Delicious clone. By sebsauvage.net
// http://sebsauvage.net/wiki/doku.php?id=php:shaarli
// Licence: http://www.opensource.org/licenses/zlib-license.php
// Requires: PHP 5.3.x
// -----------------------------------------------------------------------------------------------
-// NEVER TRUST IN PHP.INI
-// Some hosts do not define a default timezone in php.ini,
-// so we have to do this for avoid the strict standard error.
-date_default_timezone_set('UTC');
+
+// Set 'UTC' as the default timezone if it is not defined in php.ini
+// See http://php.net/manual/en/datetime.configuration.php#ini.date.timezone
+if (date_default_timezone_get() == '') {
+ date_default_timezone_set('UTC');
+}
// -----------------------------------------------------------------------------------------------
// Hardcoded parameter (These parameters can be overwritten by editing the file /data/config.php)
$GLOBALS['config']['ENABLE_RSS_PERMALINKS'] = true; // Enable RSS permalinks by default. This corresponds to the default behavior of shaarli before this was added as an option.
$GLOBALS['config']['HIDE_PUBLIC_LINKS'] = false;
// -----------------------------------------------------------------------------------------------
-define('shaarli_version','0.5.0');
+define('shaarli_version','0.5.1');
// http://server.com/x/shaarli --> /shaarli/
define('WEB_PATH', substr($_SERVER["REQUEST_URI"], 0, 1+strrpos($_SERVER["REQUEST_URI"], '/', 0)));
}
// Shaarli library
+require_once 'application/Cache.php';
+require_once 'application/CachedPage.php';
require_once 'application/LinkDB.php';
require_once 'application/TimeZone.php';
+require_once 'application/Url.php';
require_once 'application/Utils.php';
require_once 'application/Config.php';
}
-// -----------------------------------------------------------------------------------------------
-// Simple cache system (mainly for the RSS/ATOM feeds).
-
-class pageCache
-{
- private $url; // Full URL of the page to cache (typically the value returned by pageUrl())
- private $shouldBeCached; // boolean: Should this url be cached?
- private $filename; // Name of the cache file for this url.
-
- /*
- $url = URL (typically the value returned by pageUrl())
- $shouldBeCached = boolean. If false, the cache will be disabled.
- */
- public function __construct($url,$shouldBeCached)
- {
- $this->url = $url;
- $this->filename = $GLOBALS['config']['PAGECACHE'].'/'.sha1($url).'.cache';
- $this->shouldBeCached = $shouldBeCached;
- }
-
- // If the page should be cached and a cached version exists,
- // returns the cached version (otherwise, return null).
- public function cachedVersion()
- {
- if (!$this->shouldBeCached) return null;
- if (is_file($this->filename)) { return file_get_contents($this->filename); exit; }
- return null;
- }
-
- // Put a page in the cache.
- public function cache($page)
- {
- if (!$this->shouldBeCached) return;
- file_put_contents($this->filename,$page);
- }
-
- // Purge the whole cache.
- // (call with pageCache::purgeCache())
- public static function purgeCache()
- {
- if (is_dir($GLOBALS['config']['PAGECACHE']))
- {
- $handler = opendir($GLOBALS['config']['PAGECACHE']);
- if ($handler!==false)
- {
- while (($filename = readdir($handler))!==false)
- {
- if (endsWith($filename,'.cache')) { unlink($GLOBALS['config']['PAGECACHE'].'/'.$filename); }
- }
- closedir($handler);
- }
- }
- }
-
-}
-
-
// -----------------------------------------------------------------------------------------------
// Log to text file
function logm($message)
session_set_cookie_params(0,$cookiedir,$_SERVER['SERVER_NAME']); // 0 means "When browser closes"
session_regenerate_id(true);
}
+
// Optional redirect after login:
- if (isset($_GET['post'])) { header('Location: ?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']):'')); exit; }
- if (isset($_POST['returnurl']))
- {
- if (endsWith($_POST['returnurl'],'?do=login')) { header('Location: ?'); exit; } // Prevent loops over login screen.
- header('Location: '.$_POST['returnurl']); exit;
+ if (isset($_GET['post'])) {
+ $uri = '?post='. urlencode($_GET['post']);
+ foreach (array('description', 'source', 'title') as $param) {
+ if (!empty($_GET[$param])) {
+ $uri .= '&'.$param.'='.urlencode($_GET[$param]);
+ }
+ }
+ header('Location: '. $uri);
+ exit;
+ }
+
+ if (isset($_GET['edit_link'])) {
+ header('Location: ?edit_link='. escape($_GET['edit_link']));
+ exit;
+ }
+
+ if (isset($_POST['returnurl'])) {
+ // Prevent loops over login screen.
+ if (strpos($_POST['returnurl'], 'do=login') === false) {
+ header('Location: '. escape($_POST['returnurl']));
+ exit;
+ }
}
header('Location: ?'); exit;
}
{
ban_loginFailed();
$redir = '';
- 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']):''); }
+ if (isset($_GET['post'])) {
+ $redir = '?post=' . urlencode($_GET['post']);
+ foreach (array('description', 'source', 'title') as $param) {
+ if (!empty($_GET[$param])) {
+ $redir .= '&' . $param . '=' . urlencode($_GET[$param]);
+ }
+ }
+ }
echo '<script>alert("Wrong login/password.");document.location=\'?do=login'.$redir.'\';</script>'; // Redirect to login screen.
exit;
}
// Cache system
$query = $_SERVER["QUERY_STRING"];
- $cache = new pageCache(pageUrl(),startsWith($query,'do=rss') && !isLoggedIn());
- $cached = $cache->cachedVersion(); if (!empty($cached)) { echo $cached; exit; }
+ $cache = new CachedPage(
+ $GLOBALS['config']['PAGECACHE'],
+ pageUrl(),
+ startsWith($query,'do=rss') && !isLoggedIn()
+ );
+ $cached = $cache->cachedVersion();
+ if (! empty($cached)) {
+ echo $cached;
+ exit;
+ }
// If cached was not found (or not usable), then read the database and build the response:
$LINKSDB = new LinkDB(
// Cache system
$query = $_SERVER["QUERY_STRING"];
- $cache = new pageCache(pageUrl(),startsWith($query,'do=atom') && !isLoggedIn());
- $cached = $cache->cachedVersion(); if (!empty($cached)) { echo $cached; exit; }
- // If cached was not found (or not usable), then read the database and build the response:
+ $cache = new CachedPage(
+ $GLOBALS['config']['PAGECACHE'],
+ pageUrl(),
+ startsWith($query,'do=atom') && !isLoggedIn()
+ );
+ $cached = $cache->cachedVersion();
+ if (!empty($cached)) {
+ echo $cached;
+ exit;
+ }
-// Read links from database (and filter private links if used it not logged in).
+ // If cached was not found (or not usable), then read the database and build the response:
+ // 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'],
function showDailyRSS() {
// Cache system
$query = $_SERVER["QUERY_STRING"];
- $cache = new pageCache(pageUrl(), startsWith($query, 'do=dailyrss') && !isLoggedIn());
+ $cache = new CachedPage(
+ $GLOBALS['config']['PAGECACHE'],
+ pageUrl(),
+ startsWith($query,'do=dailyrss') && !isLoggedIn()
+ );
$cached = $cache->cachedVersion();
if (!empty($cached)) {
echo $cached;
// -------- User wants to logout.
if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=logout'))
{
- invalidateCaches();
+ invalidateCaches($GLOBALS['config']['PAGECACHE']);
logout();
header('Location: ?');
exit;
exit;
}
+ if (isset($_GET['edit_link'])) {
+ header('Location: ?do=login&edit_link='. escape($_GET['edit_link']));
+ exit;
+ }
+
$PAGE = new pageBuilder;
buildLinkList($PAGE,$LINKSDB); // Compute list of links to display
$PAGE->renderPage('linklist');
$value['tags']=trim(implode(' ',$tags));
$LINKSDB[$key]=$value;
}
- $LINKSDB->savedb(); // Save to disk.
+ $LINKSDB->savedb($GLOBALS['config']['PAGECACHE']); // Save to disk.
echo '<script>alert("Tag was removed from '.count($linksToAlter).' links.");document.location=\'?\';</script>';
exit;
}
$value['tags']=trim(implode(' ',$tags));
$LINKSDB[$key]=$value;
}
- $LINKSDB->savedb(); // Save to disk.
+ $LINKSDB->savedb($GLOBALS['config']['PAGECACHE']); // Save to disk.
echo '<script>alert("Tag was renamed in '.count($linksToAlter).' links.");document.location=\'?searchtags='.urlencode($_POST['totag']).'\';</script>';
exit;
}
'linkdate'=>$linkdate,'tags'=>str_replace(',',' ',$tags));
if ($link['title']=='') $link['title']=$link['url']; // If title is empty, use the URL as title.
$LINKSDB[$linkdate] = $link;
- $LINKSDB->savedb(); // Save to disk.
+ $LINKSDB->savedb($GLOBALS['config']['PAGECACHE']); // Save to disk.
pubsubhub();
// If we are called from the bookmarklet, we must close the popup:
// - we are protected from XSRF by the token.
$linkdate=$_POST['lf_linkdate'];
unset($LINKSDB[$linkdate]);
- $LINKSDB->savedb(); // save to disk
+ $LINKSDB->savedb($GLOBALS['config']['PAGECACHE']); // save to disk
// If we are called from the bookmarklet, we must close the popup:
if (isset($_GET['source']) && ($_GET['source']=='bookmarklet' || $_GET['source']=='firefoxsocialapi')) { echo '<script>self.close();</script>'; exit; }
}
// -------- User want to post a new link: Display link edit form.
- if (isset($_GET['post']))
- {
- $url=$_GET['post'];
-
-
- // We remove the annoying parameters added by FeedBurner, GoogleFeedProxy, Facebook...
- $annoyingpatterns = array('/[\?&]utm_source=[^&]*/',
- '/[\?&]utm_campaign=[^&]*/',
- '/[\?&]utm_medium=[^&]*/',
- '/#xtor=RSS-[^&]*/',
- '/[\?&]fb_[^&]*/',
- '/[\?&]__scoop[^&]*/',
- '/#tk\.rss_all\?/',
- '/[\?&]action_ref_map=[^&]*/',
- '/[\?&]action_type_map=[^&]*/',
- '/[\?&]action_object_map=[^&]*/',
- '/[\?&]utm_content=[^&]*/',
- '/[\?&]fb=[^&]*/',
- '/[\?&]xtor=[^&]*/'
- );
- foreach($annoyingpatterns as $pattern)
- {
- $url = preg_replace($pattern, "", $url);
- }
+ if (isset($_GET['post'])) {
+ $url = new Url($_GET['post']);
+ $url->cleanup();
$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)
}
}
}
- $LINKSDB->savedb();
+ $LINKSDB->savedb($GLOBALS['config']['PAGECACHE']);
echo '<script>alert("File '.json_encode($filename).' ('.$filesize.' bytes) was successfully processed: '.$import_count.' links imported.");document.location=\'?\';</script>';
}
return true;
}
-// Invalidate caches when the database is changed or the user logs out.
-// (e.g. tags cache).
-function invalidateCaches()
-{
- unset($_SESSION['tags']); // Purge cache attached to session.
- pageCache::purgeCache(); // Purge page cache shared by sessions.
-}
-
try {
mergeDeprecatedConfig($GLOBALS, isLoggedIn());
} catch(Exception $e) {