* 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.
- * @param bool $urlEncode Use `urlencode()` on the URL after the redirector or not.
*
* @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 = '', $urlEncode = true)
+function text2clickable($text)
{
$regex = '!(((?:https?|ftp|file)://|apt:|magnet:)\S+[a-z0-9\(\)]/?)!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, $urlEncode) {
- $url = $urlEncode ? urlencode($matches[1]) : $matches[1];
- return '<a href="' . $redirector . $url .'">'. $matches[1] .'</a>';
- },
- $text
- );
+ return preg_replace($regex, '<a href="$1">$1</a>', $text);
}
/**
* Format Shaarli's description
*
* @param string $description shaare's description.
- * @param string $redirector if a redirector is set, use it to gerenate links.
- * @param bool $urlEncode Use `urlencode()` on the URL after the redirector or not.
* @param string $indexUrl URL to Shaarli's index.
* @return string formatted description.
*/
-function format_description($description, $redirector = '', $urlEncode = true, $indexUrl = '')
+function format_description($description, $indexUrl = '')
{
- return nl2br(space2nbsp(hashtag_autolink(text2clickable($description, $redirector, $urlEncode), $indexUrl)));
+ return nl2br(space2nbsp(hashtag_autolink(text2clickable($description), $indexUrl)));
}
/**
{
return smallHash($date->format(LinkDB::LINK_DATE_FORMAT) . $id);
}
+
+ /**
+ * Returns whether or not the link is an internal note.
+ * Its URL starts by `?` because it's actually a permalink.
+ *
+ * @param string $linkUrl
+ *
+ * @return bool true if internal note, false otherwise.
+ */
+ function is_note($linkUrl)
+ {
+ return isset($linkUrl[0]) && $linkUrl[0] === '?';
+ }
protected function buildItem($link, $pageaddr)
{
$link['guid'] = $pageaddr . '?' . $link['shorturl'];
- // Check for both signs of a note: starting with ? and 7 chars long.
- if ($link['url'][0] === '?' && strlen($link['url']) === 7) {
+ // Prepend the root URL for notes
+ if (is_note($link['url'])) {
$link['url'] = $pageaddr . $link['url'];
}
if ($this->usePermalinks === true) {
} else {
$permalink = '<a href="' . $link['guid'] . '" title="' . t('Permalink') . '">' . t('Permalink') . '</a>';
}
- $link['description'] = format_description($link['description'], '', false, $pageaddr);
+ $link['description'] = format_description($link['description'], $pageaddr);
$link['description'] .= PHP_EOL . '<br>— ' . $permalink;
$pubDate = $link['created'];
$LINKSDB = new LinkDB(
$conf->get('resource.datastore'),
$loginManager->isLoggedIn(),
- $conf->get('privacy.hide_public_links'),
- $conf->get('redirector.url'),
- $conf->get('redirector.encode_url')
+ $conf->get('privacy.hide_public_links')
);
/* Some Shaarlies may have very few links, so we need to look
// We pre-format some fields for proper output.
foreach ($links as &$link) {
- $link['formatedDescription'] = format_description(
- $link['description'],
- $conf->get('redirector.url'),
- $conf->get('redirector.encode_url')
- );
+ $link['formatedDescription'] = format_description($link['description']);
$link['timestamp'] = $link['created']->getTimestamp();
- if (startsWith($link['url'], '?')) {
+ if (is_note($link['url'])) {
$link['url'] = index_url($_SERVER) . $link['url']; // make permalink URL absolute
}
}
$taglist = explode(' ', $link['tags']);
uasort($taglist, 'strcasecmp');
$linksToDisplay[$key]['taglist']=$taglist;
- $linksToDisplay[$key]['formatedDescription'] = format_description(
- $link['description'],
- $conf->get('redirector.url'),
- $conf->get('redirector.encode_url')
- );
+ $linksToDisplay[$key]['formatedDescription'] = format_description($link['description']);
$linksToDisplay[$key]['timestamp'] = $link['created']->getTimestamp();
}
$link['title'] = $link['url'];
}
- if ($conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE) {
+ if ($conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE
+ && ! is_note($link['url'])
+ ) {
$thumbnailer = new Thumbnailer($conf);
$link['thumbnail'] = $thumbnailer->get($url);
}
+ $link['sticky'] = isset($link['sticky']) ? $link['sticky'] : false;
+
$pluginManager->executeHooks('save_link', $link);
$LINKSDB[$id] = $link;
$ids = [];
foreach ($LINKSDB as $link) {
// A note or not HTTP(S)
- if ($link['url'][0] === '?' || ! startsWith(strtolower($link['url']), 'http')) {
+ if (is_note($link['url']) || ! startsWith(strtolower($link['url']), 'http')) {
continue;
}
$ids[] = $link['id'];
$linkDisp = array();
while ($i<$end && $i<count($keys)) {
$link = $linksToDisplay[$keys[$i]];
- $link['description'] = format_description(
- $link['description'],
- $conf->get('redirector.url'),
- $conf->get('redirector.encode_url')
- );
+ $link['description'] = format_description($link['description']);
$classLi = ($i % 2) != 0 ? '' : 'publicLinkHightLight';
$link['class'] = $link['private'] == 0 ? $classLi : 'private';
$link['timestamp'] = $link['created']->getTimestamp();
'search_term' => $searchterm,
'search_tags' => $searchtags,
'visibility' => ! empty($_SESSION['visibility']) ? $_SESSION['visibility'] : '',
- 'redirector' => $conf->get('redirector.url'), // Optional redirector URL.
'links' => $linkDisp,
);
$linkDb = new LinkDB(
$conf->get('resource.datastore'),
$loginManager->isLoggedIn(),
- $conf->get('privacy.hide_public_links'),
- $conf->get('redirector.url'),
- $conf->get('redirector.encode_url')
+ $conf->get('privacy.hide_public_links')
);
$container = new \Slim\Container();
}
/**
- * Test text2clickable without a redirector being set.
+ * Test text2clickable.
*/
- public function testText2clickableWithoutRedirector()
+ public function testText2clickable()
{
$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, '');
+ $processedText = text2clickable($text);
$this->assertEquals($expectedText, $processedText);
$text = 'stuff http://hello.there/is=someone#here(please) otherstuff';
$expectedText = 'stuff <a href="http://hello.there/is=someone#here(please)">'
. 'http://hello.there/is=someone#here(please)</a> otherstuff';
- $processedText = text2clickable($text, '');
+ $processedText = text2clickable($text);
$this->assertEquals($expectedText, $processedText);
+ $text = 'stuff http://hello.there/is=someone#here(please)&no otherstuff';
$text = 'stuff http://hello.there/is=someone#here(please)&no otherstuff';
$expectedText = 'stuff <a href="http://hello.there/is=someone#here(please)&no">'
. 'http://hello.there/is=someone#here(please)&no</a> otherstuff';
- $processedText = text2clickable($text, '');
- $this->assertEquals($expectedText, $processedText);
- }
-
- /**
- * Test text2clickable with 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 text2clickable a redirector set and without URL encode.
- */
- public function testText2clickableWithRedirectorDontEncode()
- {
- $text = 'stuff http://hello.there/?is=someone&or=something#here otherstuff';
- $redirector = 'http://redirector.to';
- $expectedText = 'stuff <a href="' .
- $redirector .
- 'http://hello.there/?is=someone&or=something#here' .
- '">http://hello.there/?is=someone&or=something#here</a> otherstuff';
- $processedText = text2clickable($text, $redirector, false);
+ $processedText = text2clickable($text);
$this->assertEquals($expectedText, $processedText);
}
$this->assertNotContains('>#nothashtag', $autolinkedDescription);
}
+ /**
+ * Test is_note with note URLs.
+ */
+ public function testIsNote()
+ {
+ $this->assertTrue(is_note('?'));
+ $this->assertTrue(is_note('?abcDEf'));
+ $this->assertTrue(is_note('?_abcDEf#123'));
+ }
+
+ /**
+ * Test is_note with non note URLs.
+ */
+ public function testIsNotNote()
+ {
+ $this->assertFalse(is_note(''));
+ $this->assertFalse(is_note('nope'));
+ $this->assertFalse(is_note('https://github.com/shaarli/Shaarli/?hi'));
+ }
+
/**
* Util function to build an hashtag link.
*