<?php
-// Shaarli 0.0.45beta - 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.1.x (but autocomplete fields will only work if you have PHP 5.2.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');
+/**
+ * Shaarli v0.5.4 - Shaare your links...
+ *
+ * The personal, minimalist, super-fast, no-database Delicious clone.
+ *
+ * Friendly fork by the Shaarli community:
+ * - https://github.com/shaarli/Shaarli
+ *
+ * Original project by sebsauvage.net:
+ * - http://sebsauvage.net/wiki/doku.php?id=php:shaarli
+ * - https://github.com/sebsauvage/Shaarli
+ *
+ * Licence: http://www.opensource.org/licenses/zlib-license.php
+ *
+ * Requires: PHP 5.3.x
+ */
+
+// 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 creating the file /data/options.php)
+// Hardcoded parameter (These parameters can be overwritten by editing the file /data/config.php)
+// You should not touch any code below (or at your own risks!)
$GLOBALS['config']['DATADIR'] = 'data'; // Data subdirectory
$GLOBALS['config']['CONFIG_FILE'] = $GLOBALS['config']['DATADIR'].'/config.php'; // Configuration file (user login/password)
$GLOBALS['config']['DATASTORE'] = $GLOBALS['config']['DATADIR'].'/datastore.php'; // Data storage file.
$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;
// -----------------------------------------------------------------------------------------------
-// You should not touch below (or at your own risks!)
-// Optional config file.
-if (is_file($GLOBALS['config']['DATADIR'].'/options.php')) require($GLOBALS['config']['DATADIR'].'/options.php');
-
-define('shaarli_version','0.0.45beta');
+define('shaarli_version', '0.5.4');
// http://server.com/x/shaarli --> /shaarli/
define('WEB_PATH', substr($_SERVER["REQUEST_URI"], 0, 1+strrpos($_SERVER["REQUEST_URI"], '/', 0)));
-// Force cookie path (but do not change lifetime)
-$cookie=session_get_cookie_params();
-$cookiedir = ''; if(dirname($_SERVER['SCRIPT_NAME'])!='/') $cookiedir=dirname($_SERVER["SCRIPT_NAME"]).'/';
-session_set_cookie_params($cookie['lifetime'],$cookiedir,$_SERVER['SERVER_NAME']); // Set default cookie expiration and path.
-
-// Set session parameters on server side.
-define('INACTIVITY_TIMEOUT',3600); // (in seconds). If the user does not access any page within this time, his/her session is considered expired.
-ini_set('session.use_cookies', 1); // Use cookies to store session.
-ini_set('session.use_only_cookies', 1); // Force cookies for session (phpsessionID forbidden in URL).
-ini_set('session.use_trans_sid', false); // Prevent PHP form using sessionID in URL if cookies are disabled.
-session_name('shaarli');
-if (session_id() == '') session_start(); // Start session if needed (Some server auto-start sessions).
-
// 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).
ini_set('post_max_size', '16M');
ini_set('upload_max_filesize', '16M');
-checkphpversion();
error_reporting(E_ALL^E_WARNING); // See all error except warnings.
//error_reporting(-1); // See all errors (for debugging only)
+// User configuration
+if (is_file($GLOBALS['config']['CONFIG_FILE'])) {
+ require_once $GLOBALS['config']['CONFIG_FILE'];
+}
+
// Shaarli library
+require_once 'application/Cache.php';
+require_once 'application/CachedPage.php';
+require_once 'application/HttpUtils.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';
+
+// Ensure the PHP version is supported
+try {
+ checkPHPVersion('5.3', PHP_VERSION);
+} catch(Exception $e) {
+ header('Content-Type: text/plain; charset=utf-8');
+ echo $e->getMessage();
+ exit;
+}
+
+// Force cookie path (but do not change lifetime)
+$cookie = session_get_cookie_params();
+$cookiedir = '';
+if (dirname($_SERVER['SCRIPT_NAME']) != '/') {
+ $cookiedir = dirname($_SERVER["SCRIPT_NAME"]).'/';
+}
+// Set default cookie expiration and path.
+session_set_cookie_params($cookie['lifetime'], $cookiedir, $_SERVER['SERVER_NAME']);
+// Set session parameters on server side.
+// If the user does not access any page within this time, his/her session is considered expired.
+define('INACTIVITY_TIMEOUT', 3600); // in seconds.
+// Use cookies to store session.
+ini_set('session.use_cookies', 1);
+// Force cookies for session (phpsessionID forbidden in URL).
+ini_set('session.use_only_cookies', 1);
+// Prevent PHP form using sessionID in URL if cookies are disabled.
+ini_set('session.use_trans_sid', false);
+
+session_name('shaarli');
+// Start session if needed (Some server auto-start sessions).
+if (session_id() == '') {
+ session_start();
+}
+
+// Regenerate session ID if invalid or not defined in cookie.
+if (isset($_COOKIE['shaarli']) && !is_session_id_valid($_COOKIE['shaarli'])) {
+ session_regenerate_id(true);
+ $_COOKIE['shaarli'] = session_id();
+}
include "inc/rain.tpl.class.php"; //include Rain TPL
raintpl::$tpl_dir = $GLOBALS['config']['RAINTPL_TPL']; // template directory
if (!is_writable(realpath(dirname(__FILE__)))) die('<pre>ERROR: Shaarli does not have the right to write in its own directory.</pre>');
// Handling of old config file which do not have the new parameters.
-if (empty($GLOBALS['title'])) $GLOBALS['title']='Shared links on '.escape(indexUrl());
+if (empty($GLOBALS['title'])) $GLOBALS['title']='Shared links on '.escape(index_url($_SERVER));
if (empty($GLOBALS['timezone'])) $GLOBALS['timezone']=date_default_timezone_get();
if (empty($GLOBALS['redirector'])) $GLOBALS['redirector']='';
if (empty($GLOBALS['disablesessionprotection'])) $GLOBALS['disablesessionprotection']=false;
-if (empty($GLOBALS['disablejquery'])) $GLOBALS['disablejquery']=false;
if (empty($GLOBALS['privateLinkByDefault'])) $GLOBALS['privateLinkByDefault']=false;
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'])) install();
+if (! is_file($GLOBALS['config']['CONFIG_FILE'])) {
+ install();
+}
-require $GLOBALS['config']['CONFIG_FILE']; // Read login/password hash into $GLOBALS.
$GLOBALS['title'] = !empty($GLOBALS['title']) ? escape($GLOBALS['title']) : '';
$GLOBALS['titleLink'] = !empty($GLOBALS['titleLink']) ? escape($GLOBALS['titleLink']) : '';
$GLOBALS['redirector'] = !empty($GLOBALS['redirector']) ? escape($GLOBALS['redirector']) : '';
return $userIsLoggedIn;
}
-//==================================================================================================
$userIsLoggedIn = setup_login_state();
-//==================================================================================================
-//==================================================================================================
-
-// Check PHP version
-function checkphpversion()
-{
- if (version_compare(PHP_VERSION, '5.1.0') < 0)
- {
- header('Content-Type: text/plain; charset=utf-8');
- echo 'Your PHP version is obsolete! Shaarli requires at least php 5.1.0, and thus cannot run. Sorry. Your PHP version has known security vulnerabilities and should be updated as soon as possible.';
- exit;
- }
-}
// Checks if an update is available for Shaarli.
// (at most once a day, and only for registered user.)
// Get latest version number at most once a day.
if (!is_file($GLOBALS['config']['UPDATECHECK_FILENAME']) || (filemtime($GLOBALS['config']['UPDATECHECK_FILENAME'])<time()-($GLOBALS['config']['UPDATECHECK_INTERVAL'])))
{
- $version=shaarli_version;
- list($httpstatus,$headers,$data) = getHTTP('https://raw.githubusercontent.com/shaarli/Shaarli/master/shaarli_version.php',2);
- if (strpos($httpstatus,'200 OK')!==false) $version=str_replace(' */ ?>','',str_replace('<?php /* ','',$data));
+ $version = shaarli_version;
+ list($headers, $data) = get_http_url('https://raw.githubusercontent.com/shaarli/Shaarli/master/shaarli_version.php', 2);
+ if (strpos($headers[0], '200 OK') !== false) {
+ $version = str_replace(' */ ?>', '', str_replace('<?php /* ', '', $data));
+ }
// If failed, never mind. We don't want to bother the user with that.
file_put_contents($GLOBALS['config']['UPDATECHECK_FILENAME'],$version); // touch file date
}
}
-// -----------------------------------------------------------------------------------------------
-// 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)
{
$p = new Publisher($GLOBALS['config']['PUBSUBHUB_URL']);
$topic_url = array (
- indexUrl().'?do=atom',
- indexUrl().'?do=rss'
+ index_url($_SERVER).'?do=atom',
+ index_url($_SERVER).'?do=rss'
);
$p->publish_update($topic_url);
}
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;
}
// ------------------------------------------------------------------------------------------
// Misc utility functions:
-// Returns the server URL (including port and http/https), without path.
-// e.g. "http://myserver.com:8080"
-// You can append $_SERVER['SCRIPT_NAME'] to get the current script URL.
-function serverUrl()
-{
- $https = (!empty($_SERVER['HTTPS']) && (strtolower($_SERVER['HTTPS'])=='on')) || $_SERVER["SERVER_PORT"]=='443'; // HTTPS detection.
- $serverport = ($_SERVER["SERVER_PORT"]=='80' || ($https && $_SERVER["SERVER_PORT"]=='443') ? '' : ':'.$_SERVER["SERVER_PORT"]);
- return 'http'.($https?'s':'').'://'.$_SERVER['SERVER_NAME'].$serverport;
-}
-
-// Returns the absolute URL of current script, without the query.
-// (e.g. http://sebsauvage.net/links/)
-function indexUrl()
-{
- $scriptname = $_SERVER["SCRIPT_NAME"];
- // If the script is named 'index.php', we remove it (for better looking URLs,
- // e.g. http://mysite.com/shaarli/?abcde instead of http://mysite.com/shaarli/index.php?abcde)
- if (endswith($scriptname,'index.php')) $scriptname = substr($scriptname,0,strlen($scriptname)-9);
- return serverUrl() . $scriptname;
-}
-
-// Returns the absolute URL of current script, WITH the query.
-// (e.g. http://sebsauvage.net/links/?toto=titi&spamspamspam=humbug)
-function pageUrl()
-{
- return indexUrl().(!empty($_SERVER["QUERY_STRING"]) ? '?'.$_SERVER["QUERY_STRING"] : '');
-}
-
// Convert post_max_size/upload_max_filesize (e.g. '16M') parameters to bytes.
function return_bytes($val)
{
return date('c',linkdate2timestamp($linkdate)); // 'c' is for ISO 8601 date format.
}
-// Parse HTTP response headers and return an associative array.
-function http_parse_headers_shaarli( $headers )
-{
- $res=array();
- foreach($headers as $header)
- {
- $i = strpos($header,': ');
- if ($i!==false)
- {
- $key=substr($header,0,$i);
- $value=substr($header,$i+2,strlen($header)-$i-2);
- $res[$key]=$value;
- }
- }
- return $res;
-}
-
-/* GET an URL.
- Input: $url : URL to get (http://...)
- $timeout : Network timeout (will wait this many seconds for an anwser before giving up).
- Output: An array. [0] = HTTP status message (e.g. "HTTP/1.1 200 OK") or error message
- [1] = associative array containing HTTP response headers (e.g. echo getHTTP($url)[1]['Content-Type'])
- [2] = data
- Example: list($httpstatus,$headers,$data) = getHTTP('http://sebauvage.net/');
- if (strpos($httpstatus,'200 OK')!==false)
- echo 'Data type: '.htmlspecialchars($headers['Content-Type']);
- else
- echo 'There was an error: '.htmlspecialchars($httpstatus)
-*/
-function getHTTP($url,$timeout=30)
-{
- try
- {
- $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
- $context = stream_context_create($options);
- $data=file_get_contents($url,false,$context,-1, 4000000); // We download at most 4 Mb from source.
- if (!$data) { return array('HTTP Error',array(),''); }
- $httpStatus=$http_response_header[0]; // e.g. "HTTP/1.1 200 OK"
- $responseHeaders=http_parse_headers_shaarli($http_response_header);
- return array($httpStatus,$responseHeaders,$data);
- }
- catch (Exception $e) // getHTTP *can* fail silently (we don't care if the title cannot be fetched)
- {
- return array($e->getMessage(),'','');
- }
-}
-
// Extract title from an HTML document.
// (Returns an empty string if not found.)
function html_extract_title($html)
{
$this->tpl = new RainTPL;
$this->tpl->assign('newversion',escape(checkUpdate()));
- $this->tpl->assign('feedurl',escape(indexUrl()));
+ $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',indexUrl());
+ $this->tpl->assign('source',index_url($_SERVER));
$this->tpl->assign('version',shaarli_version);
- $this->tpl->assign('scripturl',indexUrl());
+ $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']);
// 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'],
+ page_url($_SERVER),
+ 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(
$nblinksToDisplay = $_GET['nb']=='all' ? count($linksToDisplay) : max($_GET['nb']+0,1) ;
}
- $pageaddr=escape(indexUrl());
+ $pageaddr=escape(index_url($_SERVER));
echo '<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">';
echo '<channel><title>'.$GLOBALS['title'].'</title><link>'.$pageaddr.'</link>';
echo '<description>Shared links</description><language>en-en</language><copyright>'.$pageaddr.'</copyright>'."\n\n";
echo '<description><![CDATA['.nl2br(keepMultipleSpaces(text2clickable($link['description']))).$descriptionlink.']]></description>'."\n</item>\n";
$i++;
}
- echo '</channel></rss><!-- Cached version of '.escape(pageUrl()).' -->';
+ echo '</channel></rss><!-- Cached version of '.escape(page_url($_SERVER)).' -->';
$cache->cache(ob_get_contents());
ob_end_flush();
// 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'],
+ page_url($_SERVER),
+ 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'],
$nblinksToDisplay = $_GET['nb']=='all' ? count($linksToDisplay) : max($_GET['nb']+0,1) ;
}
- $pageaddr=escape(indexUrl());
+ $pageaddr=escape(index_url($_SERVER));
$latestDate = '';
$entries='';
$i=0;
$feed='<?xml version="1.0" encoding="UTF-8"?><feed xmlns="http://www.w3.org/2005/Atom">';
$feed.='<title>'.$GLOBALS['title'].'</title>';
if (!$GLOBALS['config']['HIDE_TIMESTAMPS'] || isLoggedIn()) $feed.='<updated>'.escape($latestDate).'</updated>';
- $feed.='<link rel="self" href="'.escape(serverUrl().$_SERVER["REQUEST_URI"]).'" />';
+ $feed.='<link rel="self" href="'.escape(server_url($_SERVER).$_SERVER["REQUEST_URI"]).'" />';
if (!empty($GLOBALS['config']['PUBSUBHUB_URL']))
{
$feed.='<!-- PubSubHubbub Discovery -->';
$feed.='<author><name>'.$pageaddr.'</name><uri>'.$pageaddr.'</uri></author>';
$feed.='<id>'.$pageaddr.'</id>'."\n\n"; // Yes, I know I should use a real IRI (RFC3987), but the site URL will do.
$feed.=$entries;
- $feed.='</feed><!-- Cached version of '.escape(pageUrl()).' -->';
+ $feed.='</feed><!-- Cached version of '.escape(page_url($_SERVER)).' -->';
echo $feed;
$cache->cache(ob_get_contents());
// Daily RSS feed: 1 RSS entry per day giving all the links on that day.
// Gives the last 7 days (which have links).
// This RSS feed cannot be filtered.
-function showDailyRSS()
-{
+function showDailyRSS() {
// Cache system
$query = $_SERVER["QUERY_STRING"];
- $cache = new pageCache(pageUrl(),startsWith($query,'do=dailyrss') && !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'],
+ page_url($_SERVER),
+ startsWith($query,'do=dailyrss') && !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'],
/* Some Shaarlies may have very few links, so we need to look
back in time (rsort()) until we have enough days ($nb_of_days).
*/
- $linkdates=array(); foreach($LINKSDB as $linkdate=>$value) { $linkdates[]=$linkdate; }
+ $linkdates = array();
+ foreach ($LINKSDB as $linkdate => $value) {
+ $linkdates[] = $linkdate;
+ }
rsort($linkdates);
- $nb_of_days=7; // We take 7 days.
- $today=Date('Ymd');
- $days=array();
- foreach($linkdates as $linkdate)
- {
- $day=substr($linkdate,0,8); // Extract day (without time)
- if (strcmp($day,$today)<0)
- {
- if (empty($days[$day])) $days[$day]=array();
- $days[$day][]=$linkdate;
+ $nb_of_days = 7; // We take 7 days.
+ $today = Date('Ymd');
+ $days = array();
+
+ foreach ($linkdates as $linkdate) {
+ $day = substr($linkdate, 0, 8); // Extract day (without time)
+ if (strcmp($day,$today) < 0) {
+ if (empty($days[$day])) {
+ $days[$day] = array();
+ }
+ $days[$day][] = $linkdate;
+ }
+
+ if (count($days) > $nb_of_days) {
+ break; // Have we collected enough days?
}
- if (count($days)>$nb_of_days) break; // Have we collected enough days?
}
// Build the RSS feed.
header('Content-Type: application/rss+xml; charset=utf-8');
- $pageaddr=escape(indexUrl());
+ $pageaddr = escape(index_url($_SERVER));
echo '<?xml version="1.0" encoding="UTF-8"?><rss version="2.0">';
- echo '<channel><title>Daily - '.$GLOBALS['title'].'</title><link>'.$pageaddr.'</link>';
- echo '<description>Daily shared links</description><language>en-en</language><copyright>'.$pageaddr.'</copyright>'."\n";
-
- foreach($days as $day=>$linkdates) // For each day.
- {
- $daydate = utf8_encode(strftime('%A %d, %B %Y',linkdate2timestamp($day.'_000000'))); // Full text date
+ echo '<channel>';
+ echo '<title>Daily - '. $GLOBALS['title'] . '</title>';
+ echo '<link>'. $pageaddr .'</link>';
+ echo '<description>Daily shared links</description>';
+ echo '<language>en-en</language>';
+ echo '<copyright>'. $pageaddr .'</copyright>'. PHP_EOL;
+
+ // For each day.
+ foreach ($days as $day => $linkdates) {
+ $daydate = linkdate2timestamp($day.'_000000'); // Full text date
$rfc822date = linkdate2rfc822($day.'_000000');
- $absurl=escape(indexUrl().'?do=daily&day='.$day); // Absolute URL of the corresponding "Daily" page.
- echo '<item><title>'.$GLOBALS['title'].' - '.$daydate.'</title><guid>'.$absurl.'</guid><link>'.$absurl.'</link>';
- echo '<pubDate>'.escape($rfc822date)."</pubDate>";
+ $absurl = escape(index_url($_SERVER).'?do=daily&day='.$day); // Absolute URL of the corresponding "Daily" page.
// Build the HTML body of this RSS entry.
- $html='';
- $href='';
- $links=array();
+ $html = '';
+ $href = '';
+ $links = array();
+
// We pre-format some fields for proper output.
- foreach($linkdates as $linkdate)
- {
+ foreach ($linkdates as $linkdate) {
$l = $LINKSDB[$linkdate];
- $l['formatedDescription']=nl2br(keepMultipleSpaces(text2clickable($l['description'])));
+ $l['formatedDescription'] = nl2br(keepMultipleSpaces(text2clickable($l['description'])));
$l['thumbnail'] = thumbnail($l['url']);
$l['timestamp'] = linkdate2timestamp($l['linkdate']);
- if (startsWith($l['url'],'?')) $l['url']=indexUrl().$l['url']; // make permalink URL absolute
- $links[$linkdate]=$l;
+ if (startsWith($l['url'], '?')) {
+ $l['url'] = index_url($_SERVER) . $l['url']; // make permalink URL absolute
+ }
+ $links[$linkdate] = $l;
}
+
// Then build the HTML for this day:
$tpl = new RainTPL;
- $tpl->assign('links',$links);
- $html = $tpl->draw('dailyrss',$return_string=true);
- echo "\n";
- echo '<description><![CDATA['.$html.']]></description>'."\n</item>\n\n";
+ $tpl->assign('title', $GLOBALS['title']);
+ $tpl->assign('daydate', $daydate);
+ $tpl->assign('absurl', $absurl);
+ $tpl->assign('links', $links);
+ $tpl->assign('rfc822date', escape($rfc822date));
+ $html = $tpl->draw('dailyrss', $return_string=true);
+ echo $html . PHP_EOL;
}
- echo '</channel></rss><!-- Cached version of '.escape(pageUrl()).' -->';
+ echo '</channel></rss><!-- Cached version of '. escape(page_url($_SERVER)) .' -->';
$cache->cache(ob_get_contents());
ob_end_flush();
$linksToDisplay = $LINKSDB->filterDay($day);
} catch (Exception $exc) {
error_log($exc);
- $linksToDisplay = [];
+ $linksToDisplay = array();
}
// We pre-format some fields for proper output.
// -------- User wants to logout.
if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=logout'))
{
- invalidateCaches();
+ invalidateCaches($GLOBALS['config']['PAGECACHE']);
logout();
header('Location: ?');
exit;
// Check if this tag is already in the search query and ignore it if it is.
// Each tag is always separated by a space
- $current_tags = explode(' ', $params['searchtags']);
+ if (isset($params['searchtags'])) {
+ $current_tags = explode(' ', $params['searchtags']);
+ } else {
+ $current_tags = array();
+ }
$addtag = true;
foreach ($current_tags as $value) {
if ($value === $_GET['addtag']) {
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');
{
$PAGE = new pageBuilder;
$PAGE->assign('linkcount',count($LINKSDB));
- $PAGE->assign('pageabsaddr',indexUrl());
+ $PAGE->assign('pageabsaddr',index_url($_SERVER));
$PAGE->renderPage('tools');
exit;
}
// Save new password
$GLOBALS['salt'] = sha1(uniqid('',true).'_'.mt_rand()); // Salt renders rainbow-tables attacks useless.
$GLOBALS['hash'] = sha1($_POST['setpassword'].$GLOBALS['login'].$GLOBALS['salt']);
- writeConfig();
+ try {
+ writeConfig($GLOBALS, isLoggedIn());
+ }
+ catch(Exception $e) {
+ error_log(
+ 'ERROR while writing config file after changing password.' . PHP_EOL .
+ $e->getMessage()
+ );
+
+ // TODO: do not handle exceptions/errors in JS.
+ echo '<script>alert("'. $e->getMessage() .'");document.location=\'?do=tools\';</script>';
+ exit;
+ }
echo '<script>alert("Your password has been changed.");document.location=\'?do=tools\';</script>';
exit;
}
if (!tokenOk($_POST['token'])) die('Wrong token.'); // Go away!
$tz = 'UTC';
if (!empty($_POST['continent']) && !empty($_POST['city']))
- if (isTZvalid($_POST['continent'],$_POST['city']))
+ if (isTimeZoneValid($_POST['continent'],$_POST['city']))
$tz = $_POST['continent'].'/'.$_POST['city'];
$GLOBALS['timezone'] = $tz;
$GLOBALS['title']=$_POST['title'];
$GLOBALS['titleLink']=$_POST['titleLink'];
$GLOBALS['redirector']=$_POST['redirector'];
$GLOBALS['disablesessionprotection']=!empty($_POST['disablesessionprotection']);
- $GLOBALS['disablejquery']=!empty($_POST['disablejquery']);
$GLOBALS['privateLinkByDefault']=!empty($_POST['privateLinkByDefault']);
$GLOBALS['config']['ENABLE_RSS_PERMALINKS']= !empty($_POST['enableRssPermalinks']);
$GLOBALS['config']['ENABLE_UPDATECHECK'] = !empty($_POST['updateCheck']);
$GLOBALS['config']['HIDE_PUBLIC_LINKS'] = !empty($_POST['hidePublicLinks']);
- writeConfig();
+ try {
+ writeConfig($GLOBALS, isLoggedIn());
+ }
+ catch(Exception $e) {
+ error_log(
+ 'ERROR while writing config file after configuration update.' . PHP_EOL .
+ $e->getMessage()
+ );
+
+ // TODO: do not handle exceptions/errors in JS.
+ echo '<script>alert("'. $e->getMessage() .'");document.location=\'?do=tools\';</script>';
+ exit;
+ }
echo '<script>alert("Configuration was saved.");document.location=\'?do=tools\';</script>';
exit;
}
$PAGE->assign('token',getToken());
$PAGE->assign('title', empty($GLOBALS['title']) ? '' : $GLOBALS['title'] );
$PAGE->assign('redirector', empty($GLOBALS['redirector']) ? '' : $GLOBALS['redirector'] );
- list($timezone_form,$timezone_js) = templateTZform($GLOBALS['timezone']);
- $PAGE->assign('timezone_form',$timezone_form); // FIXME: Put entire tz form generation in template?
+ list($timezone_form, $timezone_js) = generateTimeZoneForm($GLOBALS['timezone']);
+ $PAGE->assign('timezone_form', $timezone_form);
$PAGE->assign('timezone_js',$timezone_js);
$PAGE->renderPage('configure');
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 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;
}
{
if (!tokenOk($_POST['token'])) die('Wrong token.'); // Go away!
$tags = trim(preg_replace('/\s\s+/',' ', $_POST['lf_tags'])); // Remove multiple spaces.
+ $tags = implode(' ', array_unique(explode(' ', $tags))); // Remove duplicates.
$linkdate=$_POST['lf_linkdate'];
$url = trim($_POST['lf_url']);
if (!startsWith($url,'http:') && !startsWith($url,'https:') && !startsWith($url,'ftp:') && !startsWith($url,'magnet:') && !startsWith($url,'?') && !startsWith($url,'javascript:'))
'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 = cleanup_url($_GET['post']);
$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)
+ // Check if URL is not already in database (in this case, we will edit the existing link)
+ $link = $LINKSDB->getLinkFromUrl($url);
if (!$link)
{
- $link_is_new = true; // This is a new link
+ $link_is_new = true;
$linkdate = strval(date('Ymd_His'));
- $title = (empty($_GET['title']) ? '' : $_GET['title'] ); // Get title if it was provided in URL (by the bookmarklet).
- $description = (empty($_GET['description']) ? '' : $_GET['description']); // Get description if it was provided in URL (by the bookmarklet). [Bronco added that]
- $tags = (empty($_GET['tags']) ? '' : $_GET['tags'] ); // Get tags if it was provided in URL
- $private = (!empty($_GET['private']) && $_GET['private'] === "1" ? 1 : 0); // Get private if it was provided in URL
- if (($url!='') && parse_url($url,PHP_URL_SCHEME)=='') $url = 'http://'.$url;
- // If this is an HTTP link, we try go get the page to extract the title (otherwise we will to straight to the edit form.)
- if (empty($title) && parse_url($url,PHP_URL_SCHEME)=='http')
- {
- list($status,$headers,$data) = getHTTP($url,4); // Short timeout to keep the application responsive.
+ // Get title if it was provided in URL (by the bookmarklet).
+ $title = (empty($_GET['title']) ? '' : $_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);
+ // 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
+ list($headers, $data) = get_http_url($url, 4);
// FIXME: Decode charset according to specified in either 1) HTTP response headers or 2) <head> in html
- if (strpos($status,'200 OK')!==false)
- {
- // Look for charset in html header.
- preg_match('#<meta .*charset=.*>#Usi', $data, $meta);
-
- // If found, extract encoding.
- if (!empty($meta[0]))
- {
- // Get encoding specified in header.
- preg_match('#charset="?(.*)"#si', $meta[0], $enc);
- // If charset not found, use utf-8.
- $html_charset = (!empty($enc[1])) ? strtolower($enc[1]) : 'utf-8';
- }
- else { $html_charset = 'utf-8'; }
-
- // Extract title
- $title = html_extract_title($data);
- if (!empty($title))
- {
- // Re-encode title in utf-8 if necessary.
- $title = ($html_charset == 'iso-8859-1') ? utf8_encode($title) : $title;
- }
- }
+ if (strpos($headers[0], '200 OK') !== false) {
+ // Look for charset in html header.
+ preg_match('#<meta .*charset=.*>#Usi', $data, $meta);
+
+ // If found, extract encoding.
+ if (!empty($meta[0])) {
+ // Get encoding specified in header.
+ preg_match('#charset="?(.*)"#si', $meta[0], $enc);
+ // If charset not found, use utf-8.
+ $html_charset = (!empty($enc[1])) ? strtolower($enc[1]) : 'utf-8';
+ }
+ else {
+ $html_charset = 'utf-8';
+ }
+
+ // Extract title
+ $title = html_extract_title($data);
+ if (!empty($title)) {
+ // Re-encode title in utf-8 if necessary.
+ $title = ($html_charset == 'iso-8859-1') ? utf8_encode($title) : $title;
+ }
+ }
}
- if ($url=='') // In case of empty URL, this is just a text (with a link that points to itself)
- {
- $url='?'.smallHash($linkdate);
- $title='Note: ';
+ if ($url == '') {
+ $url = '?' . smallHash($linkdate);
+ $title = 'Note: ';
}
- $link = array('linkdate'=>$linkdate,'title'=>$title,'url'=>$url,'description'=>$description,'tags'=>$tags,'private'=>$private);
+ $link = array(
+ 'linkdate' => $linkdate,
+ 'title' => $title,
+ 'url' => $url,
+ 'description' => $description,
+ 'tags' => $tags,
+ 'private' => $private
+ );
}
$PAGE = new pageBuilder;
}
}
}
- $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>';
}
{
header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
echo '<h1>404 Not found.</h1>Oh crap. The link you are trying to reach does not exist or has been deleted.';
- echo '<br>You would mind <a href="?">clicking here</a>?';
+ echo '<br>Would you mind <a href="?">clicking here</a>?';
exit;
}
$search_type='permalink';
if ($link["url"][0] === '?' && // Check for both signs of a note: starting with ? and 7 chars long. I doubt that you'll post any links that look like this.
strlen($link["url"]) === 7) {
- $link["url"] = indexUrl() . $link["url"];
+ $link["url"] = index_url($_SERVER) . $link["url"];
}
$linkDisp[$keys[$i]] = $link;
if ("/talks/" !== substr($path,0,7)) return array(); // 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 array('src'=>indexUrl().'?do=genthumbnail&hmac='.$sign.'&url='.urlencode($url),
+ return array('src'=>index_url($_SERVER).'?do=genthumbnail&hmac='.$sign.'&url='.urlencode($url),
'href'=>$href,'width'=>'120','style'=>'height:auto;','alt'=>'thumbnail');
}
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 array('src'=>indexUrl().'?do=genthumbnail&hmac='.$sign.'&url='.urlencode($url),
+ return array('src'=>index_url($_SERVER).'?do=genthumbnail&hmac='.$sign.'&url='.urlencode($url),
'href'=>$href,'width'=>'120','style'=>'height:auto;','alt'=>'thumbnail');
}
return array(); // No thumbnail.
if (!isset($_SESSION['session_tested']))
{ // Step 1 : Try to store data in session and reload page.
$_SESSION['session_tested'] = 'Working'; // Try to set a variable in session.
- header('Location: '.indexUrl().'?test_session'); // Redirect to check stored data.
+ header('Location: '.index_url($_SERVER).'?test_session'); // Redirect to check stored data.
}
if (isset($_GET['test_session']))
{ // Step 3: Sessions are OK. Remove test parameter from URL.
- header('Location: '.indexUrl());
+ header('Location: '.index_url($_SERVER));
}
if (!empty($_POST['setlogin']) && !empty($_POST['setpassword']))
{
$tz = 'UTC';
- if (!empty($_POST['continent']) && !empty($_POST['city']))
- if (isTZvalid($_POST['continent'],$_POST['city']))
+ if (!empty($_POST['continent']) && !empty($_POST['city'])) {
+ if (isTimeZoneValid($_POST['continent'], $_POST['city'])) {
$tz = $_POST['continent'].'/'.$_POST['city'];
+ }
+ }
$GLOBALS['timezone'] = $tz;
// Everything is ok, let's create config file.
$GLOBALS['login'] = $_POST['setlogin'];
$GLOBALS['salt'] = sha1(uniqid('',true).'_'.mt_rand()); // Salt renders rainbow-tables attacks useless.
$GLOBALS['hash'] = sha1($_POST['setpassword'].$GLOBALS['login'].$GLOBALS['salt']);
- $GLOBALS['title'] = (empty($_POST['title']) ? 'Shared links on '.escape(indexUrl()) : $_POST['title'] );
+ $GLOBALS['title'] = (empty($_POST['title']) ? 'Shared links on '.escape(index_url($_SERVER)) : $_POST['title'] );
$GLOBALS['config']['ENABLE_UPDATECHECK'] = !empty($_POST['updateCheck']);
- writeConfig();
+ try {
+ writeConfig($GLOBALS, isLoggedIn());
+ }
+ catch(Exception $e) {
+ error_log(
+ 'ERROR while writing config file after installation.' . PHP_EOL .
+ $e->getMessage()
+ );
+
+ // TODO: do not handle exceptions/errors in JS.
+ echo '<script>alert("'. $e->getMessage() .'");document.location=\'?\';</script>';
+ exit;
+ }
echo '<script>alert("Shaarli is now configured. Please enter your login/password and start shaaring your links!");document.location=\'?do=login\';</script>';
exit;
}
// Display config form:
- list($timezone_form,$timezone_js) = templateTZform();
- $timezone_html=''; if ($timezone_form!='') $timezone_html='<tr><td><b>Timezone:</b></td><td>'.$timezone_form.'</td></tr>';
+ list($timezone_form, $timezone_js) = generateTimeZoneForm();
+ $timezone_html = '';
+ if ($timezone_form != '') {
+ $timezone_html = '<tr><td><b>Timezone:</b></td><td>'.$timezone_form.'</td></tr>';
+ }
$PAGE = new pageBuilder;
$PAGE->assign('timezone_html',$timezone_html);
exit;
}
-// Generates the timezone selection form and JavaScript.
-// Input: (optional) current timezone (can be 'UTC/UTC'). It will be pre-selected.
-// Output: array(html,js)
-// Example: list($htmlform,$js) = templateTZform('Europe/Paris'); // Europe/Paris pre-selected.
-// Returns array('','') if server does not support timezones list. (e.g. PHP 5.1 on free.fr)
-function templateTZform($ptz=false)
-{
- if (function_exists('timezone_identifiers_list')) // because of old PHP version (5.1) which can be found on free.fr
- {
- // Try to split the provided timezone.
- if ($ptz==false) { $l=timezone_identifiers_list(); $ptz=$l[0]; }
- $spos=strpos($ptz,'/'); $pcontinent=substr($ptz,0,$spos); $pcity=substr($ptz,$spos+1);
-
- // Display config form:
- $timezone_form = '';
- $timezone_js = '';
- // The list is in the form "Europe/Paris", "America/Argentina/Buenos_Aires"...
- // We split the list in continents/cities.
- $continents = array();
- $cities = array();
- foreach(timezone_identifiers_list() as $tz)
- {
- if ($tz=='UTC') $tz='UTC/UTC';
- $spos = strpos($tz,'/');
- if ($spos!==false)
- {
- $continent=substr($tz,0,$spos); $city=substr($tz,$spos+1);
- $continents[$continent]=1;
- if (!isset($cities[$continent])) $cities[$continent]='';
- $cities[$continent].='<option value="'.$city.'"'.($pcity==$city?' selected':'').'>'.$city.'</option>';
- }
- }
- $continents_html = '';
- $continents = array_keys($continents);
- foreach($continents as $continent)
- $continents_html.='<option value="'.$continent.'"'.($pcontinent==$continent?' selected':'').'>'.$continent.'</option>';
- $cities_html = $cities[$pcontinent];
- $timezone_form = "Continent: <select name=\"continent\" id=\"continent\" onChange=\"onChangecontinent();\">${continents_html}</select>";
- $timezone_form .= " City: <select name=\"city\" id=\"city\">${cities[$pcontinent]}</select><br />";
- $timezone_js = "<script>";
- $timezone_js .= "function onChangecontinent(){document.getElementById(\"city\").innerHTML = citiescontinent[document.getElementById(\"continent\").value];}";
- $timezone_js .= "var citiescontinent = ".json_encode($cities).";" ;
- $timezone_js .= "</script>" ;
- return array($timezone_form,$timezone_js);
- }
- return array('','');
-}
-
-// Tells if a timezone is valid or not.
-// If not valid, returns false.
-// If system does not support timezone list, returns false.
-function isTZvalid($continent,$city)
-{
- $tz = $continent.'/'.$city;
- if (function_exists('timezone_identifiers_list')) // because of old PHP version (5.1) which can be found on free.fr
- {
- if (in_array($tz, timezone_identifiers_list())) // it's a valid timezone?
- return true;
- }
- return false;
-}
if (!function_exists('json_encode')) {
function json_encode($data) {
switch ($type = gettype($data)) {
}
}
-// Re-write configuration file according to globals.
-// Requires some $GLOBALS to be set (login,hash,salt,title).
-// If the config file cannot be saved, an error message is displayed and the user is redirected to "Tools" menu.
-// (otherwise, the function simply returns.)
-function writeConfig()
-{
- if (is_file($GLOBALS['config']['CONFIG_FILE']) && !isLoggedIn()) die('You are not authorized to alter config.'); // Only logged in user can alter config.
- $config='<?php $GLOBALS[\'login\']='.var_export($GLOBALS['login'],true).'; $GLOBALS[\'hash\']='.var_export($GLOBALS['hash'],true).'; $GLOBALS[\'salt\']='.var_export($GLOBALS['salt'],true).'; ';
- $config .='$GLOBALS[\'timezone\']='.var_export($GLOBALS['timezone'],true).'; date_default_timezone_set('.var_export($GLOBALS['timezone'],true).'); $GLOBALS[\'title\']='.var_export($GLOBALS['title'],true).';';
- $config .= '$GLOBALS[\'titleLink\']='.var_export($GLOBALS['titleLink'],true).'; ';
- $config .= '$GLOBALS[\'redirector\']='.var_export($GLOBALS['redirector'],true).'; ';
- $config .= '$GLOBALS[\'disablesessionprotection\']='.var_export($GLOBALS['disablesessionprotection'],true).'; ';
- $config .= '$GLOBALS[\'disablejquery\']='.var_export($GLOBALS['disablejquery'],true).'; ';
- $config .= '$GLOBALS[\'privateLinkByDefault\']='.var_export($GLOBALS['privateLinkByDefault'],true).'; ';
- $config .= '$GLOBALS[\'config\'][\'ENABLE_RSS_PERMALINKS\']='.var_export($GLOBALS['config']['ENABLE_RSS_PERMALINKS'], true).'; ';
- $config .= '$GLOBALS[\'config\'][\'ENABLE_UPDATECHECK\']='.var_export($GLOBALS['config']['ENABLE_UPDATECHECK'], true).'; ';
- $config .= '$GLOBALS[\'config\'][\'HIDE_PUBLIC_LINKS\']='.var_export($GLOBALS['config']['HIDE_PUBLIC_LINKS'], true).'; ';
- $config .= ' ?>';
- if (!file_put_contents($GLOBALS['config']['CONFIG_FILE'],$config) || strcmp(file_get_contents($GLOBALS['config']['CONFIG_FILE']),$config)!=0)
- {
- echo '<script>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>';
- exit;
- }
-}
+
/* 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.
}
else // This is a flickr page (html)
{
- list($httpstatus,$headers,$data) = getHTTP($url,20); // Get the flickr html page.
- if (strpos($httpstatus,'200 OK')!==false)
+ // Get the flickr html page.
+ list($headers, $data) = get_http_url($url, 20);
+ if (strpos($headers[0], '200 OK') !== false)
{
// flickr now nicely provides the URL of the thumbnail in each flickr page.
preg_match('!<link rel=\"image_src\" href=\"(.+?)\"!',$data,$matches);
if ($imageurl!='')
{ // Let's download the image.
- list($httpstatus,$headers,$data) = getHTTP($imageurl,10); // Image is 240x120, so 10 seconds to download should be enough.
- if (strpos($httpstatus,'200 OK')!==false)
- {
+ // Image is 240x120, so 10 seconds to download should be enough.
+ list($headers, $data) = get_http_url($imageurl, 10);
+ if (strpos($headers[0], '200 OK') !== false) {
file_put_contents($GLOBALS['config']['CACHEDIR'].'/'.$thumbname,$data); // Save image to cache.
header('Content-Type: image/jpeg');
echo $data;
// This is more complex: we have to perform a HTTP request, then parse the result.
// Maybe we should deport this to JavaScript ? Example: http://stackoverflow.com/questions/1361149/get-img-thumbnails-from-vimeo/4285098#4285098
$vid = substr(parse_url($url,PHP_URL_PATH),1);
- list($httpstatus,$headers,$data) = getHTTP('https://vimeo.com/api/v2/video/'.escape($vid).'.php',5);
- if (strpos($httpstatus,'200 OK')!==false)
- {
+ list($headers, $data) = get_http_url('https://vimeo.com/api/v2/video/'.escape($vid).'.php', 5);
+ if (strpos($headers[0], '200 OK') !== false) {
$t = unserialize($data);
$imageurl = $t[0]['thumbnail_medium'];
// Then we download the image and serve it to our client.
- list($httpstatus,$headers,$data) = getHTTP($imageurl,10);
- if (strpos($httpstatus,'200 OK')!==false)
- {
+ list($headers, $data) = get_http_url($imageurl, 10);
+ if (strpos($headers[0], '200 OK') !== false) {
file_put_contents($GLOBALS['config']['CACHEDIR'].'/'.$thumbname,$data); // Save image to cache.
header('Content-Type: image/jpeg');
echo $data;
// The thumbnail for TED talks is located in the <link rel="image_src" [...]> tag on that page
// http://www.ted.com/talks/mikko_hypponen_fighting_viruses_defending_the_net.html
// <link rel="image_src" href="http://images.ted.com/images/ted/28bced335898ba54d4441809c5b1112ffaf36781_389x292.jpg" />
- list($httpstatus,$headers,$data) = getHTTP($url,5);
- if (strpos($httpstatus,'200 OK')!==false)
- {
+ list($headers, $data) = get_http_url($url, 5);
+ if (strpos($headers[0], '200 OK') !== false) {
// Extract the link to the thumbnail
preg_match('!link rel="image_src" href="(http://images.ted.com/images/ted/.+_\d+x\d+\.jpg)"!',$data,$matches);
if (!empty($matches[1]))
{ // Let's download the image.
$imageurl=$matches[1];
- list($httpstatus,$headers,$data) = getHTTP($imageurl,20); // No control on image size, so wait long enough.
- if (strpos($httpstatus,'200 OK')!==false)
- {
+ // No control on image size, so wait long enough
+ list($headers, $data) = get_http_url($imageurl, 20);
+ if (strpos($headers[0], '200 OK') !== false) {
$filepath=$GLOBALS['config']['CACHEDIR'].'/'.$thumbname;
file_put_contents($filepath,$data); // Save image to cache.
if (resizeImage($filepath))
// There is no thumbnail available for xkcd comics, so download the whole image and resize it.
// http://xkcd.com/327/
// <img src="http://imgs.xkcd.com/comics/exploits_of_a_mom.png" title="<BLABLA>" alt="<BLABLA>" />
- list($httpstatus,$headers,$data) = getHTTP($url,5);
- if (strpos($httpstatus,'200 OK')!==false)
- {
+ list($headers, $data) = get_http_url($url, 5);
+ if (strpos($headers[0], '200 OK') !== false) {
// Extract the link to the thumbnail
preg_match('!<img src="(http://imgs.xkcd.com/comics/.*)" title="[^s]!',$data,$matches);
if (!empty($matches[1]))
{ // Let's download the image.
$imageurl=$matches[1];
- list($httpstatus,$headers,$data) = getHTTP($imageurl,20); // No control on image size, so wait long enough.
- if (strpos($httpstatus,'200 OK')!==false)
- {
+ // No control on image size, so wait long enough
+ list($headers, $data) = get_http_url($imageurl, 20);
+ if (strpos($headers[0], '200 OK') !== false) {
$filepath=$GLOBALS['config']['CACHEDIR'].'/'.$thumbname;
file_put_contents($filepath,$data); // Save image to cache.
if (resizeImage($filepath))
else
{
// For all other domains, we try to download the image and make a thumbnail.
- list($httpstatus,$headers,$data) = getHTTP($url,30); // We allow 30 seconds max to download (and downloads are limited to 4 Mb)
- if (strpos($httpstatus,'200 OK')!==false)
- {
+ // We allow 30 seconds max to download (and downloads are limited to 4 Mb)
+ list($headers, $data) = get_http_url($url, 30);
+ if (strpos($headers[0], '200 OK') !== false) {
$filepath=$GLOBALS['config']['CACHEDIR'].'/'.$thumbname;
file_put_contents($filepath,$data); // Save image to cache.
if (resizeImage($filepath))
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) {
+ error_log(
+ 'ERROR while merging deprecated options.php file.' . PHP_EOL .
+ $e->getMessage()
+ );
}
if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=genthumbnail')) { genThumbnail(); exit; } // Thumbnail generation/cache does not need the link database.