<?php
/**
- * Shaarli v0.6.3 - Shaare your links...
+ * Shaarli v0.6.5 - Shaare your links...
*
* The personal, minimalist, super-fast, no-database Delicious clone.
*
/*
* PHP configuration
*/
-define('shaarli_version', '0.6.3');
+define('shaarli_version', '0.6.5');
// http://server.com/x/shaarli --> /shaarli/
define('WEB_PATH', substr($_SERVER["REQUEST_URI"], 0, 1+strrpos($_SERVER["REQUEST_URI"], '/', 0)));
require_once 'application/ApplicationUtils.php';
require_once 'application/Cache.php';
require_once 'application/CachedPage.php';
+require_once 'application/FeedBuilder.php';
require_once 'application/FileUtils.php';
require_once 'application/HttpUtils.php';
require_once 'application/LinkDB.php';
// a token depending of deployment salt, user password, and the current ip
define('STAY_SIGNED_IN_TOKEN', sha1($GLOBALS['hash'].$_SERVER["REMOTE_ADDR"].$GLOBALS['salt']));
-autoLocale($_SERVER['HTTP_ACCEPT_LANGUAGE']); // Sniff browser language and set date format accordingly.
+// Sniff browser language and set date format accordingly.
+if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
+ autoLocale($_SERVER['HTTP_ACCEPT_LANGUAGE']);
+}
header('Content-Type: text/html; charset=utf-8'); // We use UTF-8 for proper international characters handling.
//==================================================================================================
$this->tpl->assign($what,$where);
}
+ /**
+ * Assign an array of data to the template builder.
+ *
+ * @param array $data Data to assign.
+ *
+ * @return false if invalid data.
+ */
+ public function assignAll($data)
+ {
+ // Lazy initialization
+ if ($this->tpl === false) {
+ $this->initialize();
+ }
+
+ if (empty($data) || !is_array($data)){
+ return false;
+ }
+
+ foreach ($data as $key => $value) {
+ $this->assign($key, $value);
+ }
+ }
+
// Render a specific page (using a template).
// e.g. pb.renderPage('picwall')
public function renderPage($page)
}
}
-// ------------------------------------------------------------------------------------------
-// Output the last N links in RSS 2.0 format.
-function showRSS()
-{
- header('Content-Type: application/rss+xml; charset=utf-8');
-
- // $usepermalink : If true, use permalink instead of final link.
- // User just has to add 'permalink' in URL parameters. e.g. http://mysite.com/shaarli/?do=rss&permalinks
- // Also enabled through a config option
- $usepermalinks = isset($_GET['permalinks']) || !$GLOBALS['config']['ENABLE_RSS_PERMALINKS'];
-
- // Cache system
- $query = $_SERVER["QUERY_STRING"];
- $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(
- $GLOBALS['config']['DATASTORE'],
- 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:
- $searchtags = !empty($_GET['searchtags']) ? escape($_GET['searchtags']) : '';
- $searchterm = !empty($_GET['searchterm']) ? escape($_GET['searchterm']) : '';
- if (! empty($searchtags) && ! empty($searchterm)) {
- $linksToDisplay = $LINKSDB->filter(
- LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT,
- array($searchtags, $searchterm)
- );
- }
- elseif ($searchtags) {
- $linksToDisplay = $LINKSDB->filter(LinkFilter::$FILTER_TAG, $searchtags);
- }
- elseif ($searchterm) {
- $linksToDisplay = $LINKSDB->filter(LinkFilter::$FILTER_TEXT, $searchterm);
- }
- else {
- $linksToDisplay = $LINKSDB;
- }
-
- $nblinksToDisplay = 50; // Number of links to display.
- // 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));
- 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";
- if (!empty($GLOBALS['config']['PUBSUBHUB_URL']))
- {
- echo '<!-- PubSubHubbub Discovery -->';
- echo '<link rel="hub" href="'.escape($GLOBALS['config']['PUBSUBHUB_URL']).'" xmlns="http://www.w3.org/2005/Atom" />';
- echo '<link rel="self" href="'.$pageaddr.'?do=rss" xmlns="http://www.w3.org/2005/Atom" />';
- echo '<!-- End Of PubSubHubbub Discovery -->';
- }
- $i=0;
- $keys=array(); foreach($linksToDisplay as $key=>$value) { $keys[]=$key; } // No, I can't use array_keys().
- while ($i<$nblinksToDisplay && $i<count($keys))
- {
- $link = $linksToDisplay[$keys[$i]];
- $guid = $pageaddr.'?'.smallHash($link['linkdate']);
- $date = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $link['linkdate']);
- $absurl = $link['url'];
- if (startsWith($absurl,'?')) $absurl=$pageaddr.$absurl; // make permalink URL absolute
- if ($usepermalinks===true)
- echo '<item><title>'.$link['title'].'</title><guid isPermaLink="true">'.$guid.'</guid><link>'.$guid.'</link>';
- else
- echo '<item><title>'.$link['title'].'</title><guid isPermaLink="false">'.$guid.'</guid><link>'.$absurl.'</link>';
- if (!$GLOBALS['config']['HIDE_TIMESTAMPS'] || isLoggedIn()) {
- echo '<pubDate>'.escape($date->format(DateTime::RSS))."</pubDate>\n";
- }
- if ($link['tags']!='') // Adding tags to each RSS entry (as mentioned in RSS specification)
- {
- foreach(explode(' ',$link['tags']) as $tag) { echo '<category domain="'.$pageaddr.'">'.$tag.'</category>'."\n"; }
- }
-
- // Add permalink in description
- $descriptionlink = '(<a href="'.$guid.'">Permalink</a>)';
- // If user wants permalinks first, put the final link in description
- if ($usepermalinks===true) $descriptionlink = '(<a href="'.$absurl.'">Link</a>)';
- if (strlen($link['description'])>0) $descriptionlink = '<br>'.$descriptionlink;
- echo '<description><![CDATA['.
- format_description($link['description'], $GLOBALS['redirector']) .
- $descriptionlink . ']]></description>' . "\n</item>\n";
- $i++;
- }
- echo '</channel></rss><!-- Cached version of '.escape(page_url($_SERVER)).' -->';
-
- $cache->cache(ob_get_contents());
- ob_end_flush();
- exit;
-}
-
-// ------------------------------------------------------------------------------------------
-// Output the last N links in ATOM format.
-function showATOM()
-{
- header('Content-Type: application/atom+xml; charset=utf-8');
-
- // $usepermalink : If true, use permalink instead of final link.
- // User just has to add 'permalink' in URL parameters. e.g. http://mysite.com/shaarli/?do=atom&permalinks
- $usepermalinks = isset($_GET['permalinks']) || !$GLOBALS['config']['ENABLE_RSS_PERMALINKS'];
-
- // Cache system
- $query = $_SERVER["QUERY_STRING"];
- $cache = new CachedPage(
- $GLOBALS['config']['PAGECACHE'],
- page_url($_SERVER),
- 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:
- // Read links from database (and filter private links if used it not logged in).
- $LINKSDB = new LinkDB(
- $GLOBALS['config']['DATASTORE'],
- isLoggedIn(),
- $GLOBALS['config']['HIDE_PUBLIC_LINKS'],
- $GLOBALS['redirector']
- );
-
- // Optionally filter the results:
- $searchtags = !empty($_GET['searchtags']) ? escape($_GET['searchtags']) : '';
- $searchterm = !empty($_GET['searchterm']) ? escape($_GET['searchterm']) : '';
- if (! empty($searchtags) && ! empty($searchterm)) {
- $linksToDisplay = $LINKSDB->filter(
- LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT,
- array($searchtags, $searchterm)
- );
- }
- elseif ($searchtags) {
- $linksToDisplay = $LINKSDB->filter(LinkFilter::$FILTER_TAG, $searchtags);
- }
- elseif ($searchterm) {
- $linksToDisplay = $LINKSDB->filter(LinkFilter::$FILTER_TEXT, $searchterm);
- }
- else {
- $linksToDisplay = $LINKSDB;
- }
-
- $nblinksToDisplay = 50; // Number of links to display.
- // 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));
- $latestDate = '';
- $entries='';
- $i=0;
- $keys=array(); foreach($linksToDisplay as $key=>$value) { $keys[]=$key; } // No, I can't use array_keys().
- while ($i<$nblinksToDisplay && $i<count($keys))
- {
- $link = $linksToDisplay[$keys[$i]];
- $guid = $pageaddr.'?'.smallHash($link['linkdate']);
- $date = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $link['linkdate']);
- $iso8601date = $date->format(DateTime::ISO8601);
- $latestDate = max($latestDate, $iso8601date);
- $absurl = $link['url'];
- if (startsWith($absurl,'?')) $absurl=$pageaddr.$absurl; // make permalink URL absolute
- $entries.='<entry><title>'.$link['title'].'</title>';
- if ($usepermalinks===true)
- $entries.='<link href="'.$guid.'" /><id>'.$guid.'</id>';
- else
- $entries.='<link href="'.$absurl.'" /><id>'.$guid.'</id>';
-
- if (!$GLOBALS['config']['HIDE_TIMESTAMPS'] || isLoggedIn()) {
- $entries.='<updated>'.escape($iso8601date).'</updated>';
- }
-
- // Add permalink in description
- $descriptionlink = '(<a href="'.$guid.'">Permalink</a>)';
- // If user wants permalinks first, put the final link in description
- if ($usepermalinks===true) $descriptionlink = '(<a href="'.$absurl.'">Link</a>)';
- if (strlen($link['description'])>0) $descriptionlink = '<br>'.$descriptionlink;
-
- $entries .= '<content type="html"><![CDATA['.
- format_description($link['description'], $GLOBALS['redirector']) .
- $descriptionlink . "]]></content>\n";
- if ($link['tags']!='') // Adding tags to each ATOM entry (as mentioned in ATOM specification)
- {
- foreach(explode(' ',$link['tags']) as $tag)
- { $entries.='<category scheme="'.$pageaddr.'" term="'.$tag.'" />'."\n"; }
- }
- $entries.="</entry>\n";
- $i++;
- }
- $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(server_url($_SERVER).$_SERVER["REQUEST_URI"]).'" />';
- if (!empty($GLOBALS['config']['PUBSUBHUB_URL']))
- {
- $feed.='<!-- PubSubHubbub Discovery -->';
- $feed.='<link rel="hub" href="'.escape($GLOBALS['config']['PUBSUBHUB_URL']).'" />';
- $feed.='<!-- End Of 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(page_url($_SERVER)).' -->';
- echo $feed;
-
- $cache->cache(ob_get_contents());
- ob_end_flush();
- exit;
-}
-
// ------------------------------------------------------------------------------------------
// Daily RSS feed: 1 RSS entry per day giving all the links on that day.
// Gives the last 7 days (which have links).
showDaily($PAGE);
}
+ // ATOM and RSS feed.
+ if ($targetPage == Router::$PAGE_FEED_ATOM || $targetPage == Router::$PAGE_FEED_RSS) {
+ $feedType = $targetPage == Router::$PAGE_FEED_RSS ? FeedBuilder::$FEED_RSS : FeedBuilder::$FEED_ATOM;
+ header('Content-Type: application/'. $feedType .'+xml; charset=utf-8');
+
+ // Cache system
+ $query = $_SERVER['QUERY_STRING'];
+ $cache = new CachedPage(
+ $GLOBALS['config']['PAGECACHE'],
+ page_url($_SERVER),
+ startsWith($query,'do='. $targetPage) && !isLoggedIn()
+ );
+ $cached = $cache->cachedVersion();
+ if (!empty($cached)) {
+ echo $cached;
+ exit;
+ }
+
+ // Generate data.
+ $feedGenerator = new FeedBuilder($LINKSDB, $feedType, $_SERVER, $_GET, isLoggedIn());
+ $feedGenerator->setLocale(strtolower(setlocale(LC_COLLATE, 0)));
+ $feedGenerator->setHideDates($GLOBALS['config']['HIDE_TIMESTAMPS'] && !isLoggedIn());
+ $feedGenerator->setUsePermalinks(isset($_GET['permalinks']) || !$GLOBALS['config']['ENABLE_RSS_PERMALINKS']);
+ if (!empty($GLOBALS['config']['PUBSUBHUB_URL'])) {
+ $feedGenerator->setPubsubhubUrl($GLOBALS['config']['PUBSUBHUB_URL']);
+ }
+ $data = $feedGenerator->buildData();
+
+ // Process plugin hook.
+ $pluginManager = PluginManager::getInstance();
+ $pluginManager->executeHooks('render_feed', $data, array(
+ 'loggedin' => isLoggedIn(),
+ 'target' => $targetPage,
+ ));
+
+ // Render the template.
+ $PAGE->assignAll($data);
+ $PAGE->renderPage('feed.'. $feedType);
+ $cache->cache(ob_get_contents());
+ ob_end_flush();
+ exit;
+ }
+
// Display openseach plugin (XML)
if ($targetPage == Router::$PAGE_OPENSEARCH) {
header('Content-Type: application/xml; charset=utf-8');
}
if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=genthumbnail')) { genThumbnail(); exit; } // Thumbnail generation/cache does not need the link database.
-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($_SESSION['LINKS_PER_PAGE'])) $_SESSION['LINKS_PER_PAGE']=$GLOBALS['config']['LINKS_PER_PAGE'];
renderPage();