// Hide public links
private $_hidePublicLinks;
+ // link redirector set in user settings.
+ private $_redirector;
+
/**
* Creates a new LinkDB
*
* Checks if the datastore exists; else, attempts to create a dummy one.
*
- * @param $isLoggedIn is the user logged in?
+ * @param string $datastore datastore file path.
+ * @param boolean $isLoggedIn is the user logged in?
+ * @param boolean $hidePublicLinks if true all links are private.
+ * @param string $redirector link redirector set in user settings.
*/
- function __construct($datastore, $isLoggedIn, $hidePublicLinks)
+ function __construct($datastore, $isLoggedIn, $hidePublicLinks, $redirector = '')
{
$this->_datastore = $datastore;
$this->_loggedIn = $isLoggedIn;
$this->_hidePublicLinks = $hidePublicLinks;
+ $this->_redirector = $redirector;
$this->_checkDB();
$this->_readDB();
}
// Escape links data
foreach($this->_links as &$link) {
- sanitizeLink($link);
+ sanitizeLink($link);
+ // Do not use the redirector for internal links (Shaarli note URL starting with a '?').
+ if (!empty($this->_redirector) && !startsWith($link['url'], '?')) {
+ $link['real_url'] = $this->_redirector . urlencode($link['url']);
+ }
+ else {
+ $link['real_url'] = $link['url'];
+ }
}
}
return true;
}
+
+/**
+ * In a string, converts URLs to clickable links.
+ *
+ * @param string $text input string.
+ * @param string $redirector if a redirector is set, use it to gerenate links.
+ *
+ * @return string returns $text with all links converted to HTML links.
+ *
+ * @see Function inspired from http://www.php.net/manual/en/function.preg-replace.php#85722
+ */
+function text2clickable($text, $redirector)
+{
+ $regex = '!(((?:https?|ftp|file)://|apt:|magnet:)\S+[[:alnum:]]/?)!si';
+
+ if (empty($redirector)) {
+ return preg_replace($regex, '<a href="$1">$1</a>', $text);
+ }
+ // Redirector is set, urlencode the final URL.
+ return preg_replace_callback(
+ $regex,
+ function ($matches) use ($redirector) {
+ return '<a href="' . $redirector . urlencode($matches[1]) .'">'. $matches[1] .'</a>';
+ },
+ $text
+ );
+}
+
+/**
+ * This function inserts where relevant so that multiple spaces are properly displayed in HTML
+ * even in the absence of <pre> (This is used in description to keep text formatting).
+ *
+ * @param string $text input text.
+ *
+ * @return string formatted text.
+ */
+function space2nbsp($text)
+{
+ return preg_replace('/(^| ) /m', '$1 ', $text);
+}
+
+/**
+ * Format Shaarli's description
+ * TODO: Move me to ApplicationUtils when it's ready.
+ *
+ * @param string $description shaare's description.
+ * @param string $redirector if a redirector is set, use it to gerenate links.
+ *
+ * @return string formatted description.
+ */
+function format_description($description, $redirector) {
+ return nl2br(space2nbsp(text2clickable($description, $redirector)));
+}
file_put_contents($GLOBAL['config']['LOG_FILE'], $t, FILE_APPEND);
}
-// In a string, converts URLs to clickable links.
-// Function inspired from http://www.php.net/manual/en/function.preg-replace.php#85722
-function text2clickable($url)
-{
- $redir = empty($GLOBALS['redirector']) ? '' : $GLOBALS['redirector'];
- return preg_replace('!(((?:https?|ftp|file)://|apt:|magnet:)\S+[[:alnum:]]/?)!si','<a href="'.$redir.'$1" rel="nofollow">$1</a>',$url);
-}
-
-// This function inserts where relevant so that multiple spaces are properly displayed in HTML
-// even in the absence of <pre> (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.)
$LINKSDB = new LinkDB(
$GLOBALS['config']['DATASTORE'],
isLoggedIn(),
- $GLOBALS['config']['HIDE_PUBLIC_LINKS']
+ $GLOBALS['config']['HIDE_PUBLIC_LINKS'],
+ $GLOBALS['redirector']
);
// Read links from database (and filter private links if user it not logged in).
// 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['.nl2br(keepMultipleSpaces(text2clickable($link['description']))).$descriptionlink.']]></description>'."\n</item>\n";
+ 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)).' -->';
$LINKSDB = new LinkDB(
$GLOBALS['config']['DATASTORE'],
isLoggedIn(),
- $GLOBALS['config']['HIDE_PUBLIC_LINKS']
+ $GLOBALS['config']['HIDE_PUBLIC_LINKS'],
+ $GLOBALS['redirector']
);
// Optionally filter the results:
if ($usepermalinks===true) $descriptionlink = '(<a href="'.$absurl.'">Link</a>)';
if (strlen($link['description'])>0) $descriptionlink = '<br>'.$descriptionlink;
- $entries.='<content type="html"><![CDATA['.nl2br(keepMultipleSpaces(text2clickable($link['description']))).$descriptionlink."]]></content>\n";
+ $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)
$LINKSDB = new LinkDB(
$GLOBALS['config']['DATASTORE'],
isLoggedIn(),
- $GLOBALS['config']['HIDE_PUBLIC_LINKS']
+ $GLOBALS['config']['HIDE_PUBLIC_LINKS'],
+ $GLOBALS['redirector']
);
/* Some Shaarlies may have very few links, so we need to look
// 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'], '?')) {
$LINKSDB = new LinkDB(
$GLOBALS['config']['DATASTORE'],
isLoggedIn(),
- $GLOBALS['config']['HIDE_PUBLIC_LINKS']
+ $GLOBALS['config']['HIDE_PUBLIC_LINKS'],
+ $GLOBALS['redirector']
);
$day=Date('Ymd',strtotime('-1 day')); // Yesterday, in format YYYYMMDD.
$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']);
}
$LINKSDB = new LinkDB(
$GLOBALS['config']['DATASTORE'],
isLoggedIn(),
- $GLOBALS['config']['HIDE_PUBLIC_LINKS']
+ $GLOBALS['config']['HIDE_PUBLIC_LINKS'],
+ $GLOBALS['redirector']
);
$PAGE = new pageBuilder;
$LINKSDB = new LinkDB(
$GLOBALS['config']['DATASTORE'],
isLoggedIn(),
- $GLOBALS['config']['HIDE_PUBLIC_LINKS']
+ $GLOBALS['config']['HIDE_PUBLIC_LINKS'],
+ $GLOBALS['redirector']
);
$filename=$_FILES['filetoupload']['name'];
$filesize=$_FILES['filetoupload']['size'];
while ($i<$end && $i<count($keys))
{
$link = $linksToDisplay[$keys[$i]];
- $link['description']=nl2br(keepMultipleSpaces(text2clickable($link['description'])));
- $title=$link['title'];
+ $link['description'] = format_description($link['description'], $GLOBALS['redirector']);
$classLi = $i%2!=0 ? '' : 'publicLinkHightLight';
$link['class'] = ($link['private']==0 ? $classLi : 'private');
$link['timestamp']=linkdate2timestamp($link['linkdate']);
$qrcode_html = file_get_contents(PluginManager::$PLUGINS_PATH . '/qrcode/qrcode.html');
foreach ($data['links'] as &$value) {
- $qrcode = sprintf($qrcode_html, $value['url'], $value['url'], PluginManager::$PLUGINS_PATH);
+ $qrcode = sprintf($qrcode_html, $value['real_url'], $value['real_url'], PluginManager::$PLUGINS_PATH);
$value['link_plugin'][] = $qrcode;
}
sizeof(self::$publicLinkDB->filterFullText('free software'))
);
}
+
+ /**
+ * Test real_url without redirector.
+ */
+ public function testLinkRealUrlWithoutRedirector()
+ {
+ $db = new LinkDB(self::$testDatastore, false, false);
+ foreach($db as $link) {
+ $this->assertEquals($link['url'], $link['real_url']);
+ }
+ }
+
+ /**
+ * Test real_url with redirector.
+ */
+ public function testLinkRealUrlWithRedirector()
+ {
+ $redirector = 'http://redirector.to?';
+ $db = new LinkDB(self::$testDatastore, false, false, $redirector);
+ foreach($db as $link) {
+ $this->assertStringStartsWith($redirector, $link['real_url']);
+ }
+ }
}
is_session_id_valid('c0ZqcWF3VFE2NmJBdm1HMVQ0ZHJ3UmZPbTFsNGhkNHI=')
);
}
+
+ /**
+ * Test text2clickable without a redirector being set.
+ */
+ public function testText2clickableWithoutRedirector()
+ {
+ $text = 'stuff http://hello.there/is=someone#here otherstuff';
+ $expectedText = 'stuff <a href="http://hello.there/is=someone#here">http://hello.there/is=someone#here</a> otherstuff';
+ $processedText = text2clickable($text, '');
+ $this->assertEquals($expectedText, $processedText);
+ }
+
+ /**
+ * Test text2clickable a redirector set.
+ */
+ public function testText2clickableWithRedirector()
+ {
+ $text = 'stuff http://hello.there/is=someone#here otherstuff';
+ $redirector = 'http://redirector.to';
+ $expectedText = 'stuff <a href="'.
+ $redirector .
+ urlencode('http://hello.there/is=someone#here') .
+ '">http://hello.there/is=someone#here</a> otherstuff';
+ $processedText = text2clickable($text, $redirector);
+ $this->assertEquals($expectedText, $processedText);
+ }
+
+ /**
+ * Test testSpace2nbsp.
+ */
+ public function testSpace2nbsp()
+ {
+ $text = ' Are you thrilled by flags ?'. PHP_EOL .' Really?';
+ $expectedText = ' Are you thrilled by flags ?'. PHP_EOL .' Really?';
+ $processedText = space2nbsp($text);
+ $this->assertEquals($expectedText, $processedText);
+ }
}
'title' => $str,
'links' => array(
array(
- 'url' => $str,
+ 'real_url' => $str,
)
)
);
$link = $data['links'][0];
// data shouldn't be altered
$this->assertEquals($str, $data['title']);
- $this->assertEquals($str, $link['url']);
+ $this->assertEquals($str, $link['real_url']);
// plugin data
$this->assertEquals(1, count($link['link_plugin']));
</div>
{/if}
<div class="dailyEntryTitle">
- <a href="{$link.url}">{$link.title}</a>
+ <a href="{$link.real_url}">{$link.title}</a>
</div>
{if="$link.thumbnail"}
<div class="dailyEntryThumbnail">{$link.thumbnail}</div>
</form>
</div>
{/if}
- <span class="linktitle"><a href="{$redirector}{$value.url}">{$value.title}</a></span>
+ <span class="linktitle">
+ <a href="{$value.real_url}">{$value.title}</a>
+ </span>
<br>
{if="$value.description"}<div class="linkdescription">{$value.description}</div>{/if}
{if="!$GLOBALS['config']['HIDE_TIMESTAMPS'] || isLoggedIn()"}
<span>{$value}</span> -
{/loop}
- <a href="{$value.url}"><span class="linkurl" title="Short link">{$value.url}</span></a><br>
+ <a href="{$value.real_url}"><span class="linkurl" title="Short link">{$value.url}</span></a><br>
{if="$value.tags"}
<div class="linktaglist">
{loop="value.taglist"}<span class="linktag" title="Add tag"><a href="?addtag={$value|urlencode}">{$value}</a></span> {/loop}
<div id="picwall_container">
{loop="linksToDisplay"}
<div class="picwall_pictureframe">
- {$value.thumbnail}<a href="{$value.url}"><span class="info">{$value.title}</span></a>
+ {$value.thumbnail}<a href="{$value.real_url}"><span class="info">{$value.title}</span></a>
{loop="$value.picwall_plugin"}
{$value}
{/loop}