From: VirtualTam Date: Mon, 7 Dec 2015 20:48:57 +0000 (+0100) Subject: Merge pull request #393 from ArthurHoaro/tools-js-indent X-Git-Tag: v0.6.2~7 X-Git-Url: https://git.immae.eu/?a=commitdiff_plain;h=b16e3dc5903e23ac653d0de4e3bffc3d1e529a89;hp=0504659db7de8a0e490e26a85ccfe704e5693494;p=github%2Fshaarli%2FShaarli.git Merge pull request #393 from ArthurHoaro/tools-js-indent Minimal indent of tools.html --- diff --git a/.gitignore b/.gitignore index b98c38b9..75cd3a6b 100644 --- a/.gitignore +++ b/.gitignore @@ -19,9 +19,8 @@ composer.lock # Ignore development and test resources coverage doxygen -tests/datastore.php -tests/dummycache/ +sandbox phpmd.html # Ignore user plugin configuration -plugins/*/config.php \ No newline at end of file +plugins/*/config.php diff --git a/Makefile b/Makefile index c560d8d1..a86f9aa8 100644 --- a/Makefile +++ b/Makefile @@ -110,6 +110,7 @@ test: @echo "-------" @echo "PHPUNIT" @echo "-------" + @mkdir -p sandbox @$(BIN)/phpunit tests ## @@ -119,6 +120,7 @@ test: ### remove all unversioned files clean: @git clean -df + @rm -rf sandbox ### generate Doxygen documentation doxygen: clean diff --git a/application/ApplicationUtils.php b/application/ApplicationUtils.php index b0e94e24..274331e1 100644 --- a/application/ApplicationUtils.php +++ b/application/ApplicationUtils.php @@ -4,6 +4,110 @@ */ class ApplicationUtils { + private static $GIT_URL = 'https://raw.githubusercontent.com/shaarli/Shaarli'; + private static $GIT_BRANCHES = array('master', 'stable'); + private static $VERSION_FILE = 'shaarli_version.php'; + private static $VERSION_START_TAG = ''; + + /** + * Gets the latest version code from the Git repository + * + * The code is read from the raw content of the version file on the Git server. + * + * @return mixed the version code from the repository if available, else 'false' + */ + public static function getLatestGitVersionCode($url, $timeout=2) + { + list($headers, $data) = get_http_url($url, $timeout); + + if (strpos($headers[0], '200 OK') === false) { + error_log('Failed to retrieve ' . $url); + return false; + } + + return str_replace( + array(self::$VERSION_START_TAG, self::$VERSION_END_TAG, PHP_EOL), + array('', '', ''), + $data + ); + } + + /** + * Checks if a new Shaarli version has been published on the Git repository + * + * Updates checks are run periodically, according to the following criteria: + * - the update checks are enabled (install, global config); + * - the user is logged in (or this is an open instance); + * - the last check is older than a given interval; + * - the check is non-blocking if the HTTPS connection to Git fails; + * - in case of failure, the update file's modification date is updated, + * to avoid intempestive connection attempts. + * + * @param string $currentVersion the current version code + * @param string $updateFile the file where to store the latest version code + * @param int $checkInterval the minimum interval between update checks (in seconds + * @param bool $enableCheck whether to check for new versions + * @param bool $isLoggedIn whether the user is logged in + * + * @throws Exception an invalid branch has been set for update checks + * + * @return mixed the new version code if available and greater, else 'false' + */ + public static function checkUpdate($currentVersion, + $updateFile, + $checkInterval, + $enableCheck, + $isLoggedIn, + $branch='stable') + { + if (! $isLoggedIn) { + // Do not check versions for visitors + return false; + } + + if (empty($enableCheck)) { + // Do not check if the user doesn't want to + return false; + } + + if (is_file($updateFile) && (filemtime($updateFile) > time() - $checkInterval)) { + // Shaarli has checked for updates recently - skip HTTP query + $latestKnownVersion = file_get_contents($updateFile); + + if (version_compare($latestKnownVersion, $currentVersion) == 1) { + return $latestKnownVersion; + } + return false; + } + + if (! in_array($branch, self::$GIT_BRANCHES)) { + throw new Exception( + 'Invalid branch selected for updates: "' . $branch . '"' + ); + } + + // Late Static Binding allows overriding within tests + // See http://php.net/manual/en/language.oop5.late-static-bindings.php + $latestVersion = static::getLatestGitVersionCode( + self::$GIT_URL . '/' . $branch . '/' . self::$VERSION_FILE + ); + + if (! $latestVersion) { + // Only update the file's modification date + file_put_contents($updateFile, $currentVersion); + return false; + } + + // Update the file's content and modification date + file_put_contents($updateFile, $latestVersion); + + if (version_compare($latestVersion, $currentVersion) == 1) { + return $latestVersion; + } + + return false; + } /** * Checks the PHP version to ensure Shaarli can run diff --git a/application/LinkDB.php b/application/LinkDB.php index 15fadbc3..f771ac8b 100644 --- a/application/LinkDB.php +++ b/application/LinkDB.php @@ -57,18 +57,25 @@ class LinkDB implements Iterator, Countable, ArrayAccess // 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(); } @@ -259,7 +266,14 @@ You use the community supported version of the original Shaarli project, by Seba // 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']; + } } } diff --git a/application/Utils.php b/application/Utils.php index b8579b48..f84f70e4 100644 --- a/application/Utils.php +++ b/application/Utils.php @@ -148,3 +148,56 @@ function is_session_id_valid($sessionId) 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, '$1', $text); + } + // Redirector is set, urlencode the final URL. + return preg_replace_callback( + $regex, + function ($matches) use ($redirector) { + return ''. $matches[1] .''; + }, + $text + ); +} + +/** + * This function inserts   where relevant so that multiple spaces are properly displayed in HTML + * even in the absence of
  (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)));
+}
diff --git a/index.php b/index.php
old mode 100644
new mode 100755
index b4d9395f..0dd5829b
--- a/index.php
+++ b/index.php
@@ -1,6 +1,6 @@
  /shaarli/
 define('WEB_PATH', substr($_SERVER["REQUEST_URI"], 0, 1+strrpos($_SERVER["REQUEST_URI"], '/', 0)));
@@ -305,56 +306,15 @@ function setup_login_state() {
 }
 $userIsLoggedIn = setup_login_state();
 
-// Checks if an update is available for Shaarli.
-// (at most once a day, and only for registered user.)
-// Output: '' = no new version.
-//         other= the available version.
-function checkUpdate()
-{
-    if (!isLoggedIn()) return ''; // Do not check versions for visitors.
-    if (empty($GLOBALS['config']['ENABLE_UPDATECHECK'])) return ''; // Do not check if the user doesn't want to.
-
-    // Get latest version number at most once a day.
-    if (!is_file($GLOBALS['config']['UPDATECHECK_FILENAME']) || (filemtime($GLOBALS['config']['UPDATECHECK_FILENAME'])', '', str_replace('$1',$url);
+    file_put_contents($GLOBALS['config']['LOG_FILE'], $t, FILE_APPEND);
 }
 
-// This function inserts   where relevant so that multiple spaces are properly displayed in HTML
-// even in the absence of 
  (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.)
@@ -672,7 +632,25 @@ class pageBuilder
     private function initialize()
     {
         $this->tpl = new RainTPL;
-        $this->tpl->assign('newversion', escape(checkUpdate()));
+
+        try {
+            $version = ApplicationUtils::checkUpdate(
+                shaarli_version,
+                $GLOBALS['config']['UPDATECHECK_FILENAME'],
+                $GLOBALS['config']['UPDATECHECK_INTERVAL'],
+                $GLOBALS['config']['ENABLE_UPDATECHECK'],
+                isLoggedIn(),
+                $GLOBALS['config']['UPDATECHECK_BRANCH']
+            );
+            $this->tpl->assign('newVersion', escape($version));
+            $this->tpl->assign('versionError', '');
+
+        } catch (Exception $exc) {
+            logm($exc->getMessage());
+            $this->tpl->assign('newVersion', '');
+            $this->tpl->assign('versionError', escape($exc->getMessage()));
+        }
+
         $this->tpl->assign('feedurl', escape(index_url($_SERVER)));
         $searchcrits = ''; // Search criteria
         if (!empty($_GET['searchtags'])) {
@@ -746,7 +724,8 @@ function showRSS()
     $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).
 
@@ -797,7 +776,9 @@ function showRSS()
         // If user wants permalinks first, put the final link in description
         if ($usepermalinks===true) $descriptionlink = '(Link)';
         if (strlen($link['description'])>0) $descriptionlink = '
'.$descriptionlink; - echo ''."\n\n"; + echo '' . "\n\n"; $i++; } echo ''; @@ -835,7 +816,8 @@ function showATOM() $LINKSDB = new LinkDB( $GLOBALS['config']['DATASTORE'], isLoggedIn(), - $GLOBALS['config']['HIDE_PUBLIC_LINKS'] + $GLOBALS['config']['HIDE_PUBLIC_LINKS'], + $GLOBALS['redirector'] ); // Optionally filter the results: @@ -876,7 +858,9 @@ function showATOM() if ($usepermalinks===true) $descriptionlink = '(Link)'; if (strlen($link['description'])>0) $descriptionlink = '
'.$descriptionlink; - $entries.='\n"; + $entries .= '\n"; if ($link['tags']!='') // Adding tags to each ATOM entry (as mentioned in ATOM specification) { foreach(explode(' ',$link['tags']) as $tag) @@ -929,7 +913,8 @@ function showDailyRSS() { $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 @@ -983,7 +968,7 @@ function showDailyRSS() { // 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'], '?')) { @@ -1016,7 +1001,8 @@ function showDaily() $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. @@ -1047,7 +1033,7 @@ function showDaily() $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']); } @@ -1107,7 +1093,8 @@ function renderPage() $LINKSDB = new LinkDB( $GLOBALS['config']['DATASTORE'], isLoggedIn(), - $GLOBALS['config']['HIDE_PUBLIC_LINKS'] + $GLOBALS['config']['HIDE_PUBLIC_LINKS'], + $GLOBALS['redirector'] ); $PAGE = new pageBuilder; @@ -1781,7 +1768,8 @@ function importFile() $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']; @@ -1932,8 +1920,7 @@ function buildLinkList($PAGE,$LINKSDB) while ($i<$end && $i $linkDisp, 'tags' => $LINKSDB->allTags(), ); + // FIXME! temporary fix - see #399. + if (!empty($GLOBALS['pagetitle']) && count($linkDisp) == 1) { + $data['pagetitle'] = $GLOBALS['pagetitle']; + } $pluginManager = PluginManager::getInstance(); $pluginManager->executeHooks('render_linklist', $data, array('loggedin' => isLoggedIn())); diff --git a/plugins/playvideos/README.md b/plugins/playvideos/README.md index ec1ead8d..b1698470 100644 --- a/plugins/playvideos/README.md +++ b/plugins/playvideos/README.md @@ -1,21 +1,29 @@ ### ► Play Videos plugin for Shaarli -This plugin adds a `► Play Videos` button to [Shaarli](https://github.com/shaarli/Shaarli)'s toolbar. Click this button to play all videos on the page in an overlay HTML5 player. Nice for continuous stream of music, documentaries, talks... -This uses code from https://zaius.github.io/youtube_playlist/ and is currently only compatible with Youtube videos. +Adds a `► Play Videos` button to [Shaarli](https://github.com/shaarli/Shaarli)'s toolbar. Click this button to play all videos on the page in an overlay HTML5 player. Nice for continuous stream of music, documentaries, talks... + + -![](https://cdn.mediacru.sh/D_izf0zjAtxy.png) +This uses code from https://zaius.github.io/youtube_playlist/ and is currently only compatible with Youtube videos. #### Installation and setup -Place the files in the `tpl/plugins/playvideos/` directory of your Shaarli. -This is a default Shaarli plugin, you just have to enable it. -To enable the plugin, add `playvideos` to the `TOOLBAR_PLUGINS` config option in your `index.php` or `data/options.php`. Example: +This is a default Shaarli plugin, you just have to enable it. See https://github.com/shaarli/Shaarli/wiki/Shaarli-configuration/ - $GLOBALS['config']['TOOLBAR_PLUGINS'] = array('aplugins', 'anotherone', 'playvideos'); #### Troubleshooting + If your server has [Content Security Policy](http://content-security-policy.com/) headers enabled, this may prevent the script from loading fully. You should relax the CSP in your server settings. Example CSP rule for apache2: -`Header set Content-Security-Policy "script-src 'self' 'unsafe-inline' https://www.youtube.com https://s.ytimg.com 'unsafe-eval'"` + +In `/etc/apache2/conf-available/shaarli-csp.conf`: + +```apache + + Header set Content-Security-Policy "script-src 'self' 'unsafe-inline' https://www.youtube.com https://s.ytimg.com 'unsafe-eval'" + +``` + +Then run `a2enconf shaarli-csp; service apache2 reload` ### License ``` @@ -68,4 +76,4 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------- -``` \ No newline at end of file +``` diff --git a/plugins/qrcode/qrcode.php b/plugins/qrcode/qrcode.php index 1080c964..5f6e76a2 100644 --- a/plugins/qrcode/qrcode.php +++ b/plugins/qrcode/qrcode.php @@ -17,7 +17,7 @@ function hook_qrcode_render_linklist($data) $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; } diff --git a/shaarli_version.php b/shaarli_version.php index a5f0a095..11ad87d7 100644 --- a/shaarli_version.php +++ b/shaarli_version.php @@ -1 +1 @@ - + diff --git a/tests/ApplicationUtilsTest.php b/tests/ApplicationUtilsTest.php index 01301e68..6064357d 100644 --- a/tests/ApplicationUtilsTest.php +++ b/tests/ApplicationUtilsTest.php @@ -5,12 +5,240 @@ require_once 'application/ApplicationUtils.php'; +/** + * Fake ApplicationUtils class to avoid HTTP requests + */ +class FakeApplicationUtils extends ApplicationUtils +{ + public static $VERSION_CODE = ''; + + /** + * Toggle HTTP requests, allow overriding the version code + */ + public static function getLatestGitVersionCode($url, $timeout=0) + { + return self::$VERSION_CODE; + } +} + /** * Unitary tests for Shaarli utilities */ class ApplicationUtilsTest extends PHPUnit_Framework_TestCase { + protected static $testUpdateFile = 'sandbox/update.txt'; + protected static $testVersion = '0.5.0'; + protected static $versionPattern = '/^\d+\.\d+\.\d+$/'; + + /** + * Reset test data for each test + */ + public function setUp() + { + FakeApplicationUtils::$VERSION_CODE = ''; + if (file_exists(self::$testUpdateFile)) { + unlink(self::$testUpdateFile); + } + } + + /** + * Retrieve the latest version code available on Git + * + * Expected format: Semantic Versioning - major.minor.patch + */ + public function testGetLatestGitVersionCode() + { + $testTimeout = 10; + + $this->assertEquals( + '0.5.4', + ApplicationUtils::getLatestGitVersionCode( + 'https://raw.githubusercontent.com/shaarli/Shaarli/' + .'v0.5.4/shaarli_version.php', + $testTimeout + ) + ); + $this->assertRegexp( + self::$versionPattern, + ApplicationUtils::getLatestGitVersionCode( + 'https://raw.githubusercontent.com/shaarli/Shaarli/' + .'master/shaarli_version.php', + $testTimeout + ) + ); + } + + /** + * Attempt to retrieve the latest version from an invalid URL + */ + public function testGetLatestGitVersionCodeInvalidUrl() + { + $this->assertFalse( + ApplicationUtils::getLatestGitVersionCode('htttp://null.io', 1) + ); + } + + /** + * Test update checks - the user is logged off + */ + public function testCheckUpdateLoggedOff() + { + $this->assertFalse( + ApplicationUtils::checkUpdate(self::$testVersion, 'null', 0, false, false) + ); + } + + /** + * Test update checks - the user has disabled updates + */ + public function testCheckUpdateUserDisabled() + { + $this->assertFalse( + ApplicationUtils::checkUpdate(self::$testVersion, 'null', 0, false, true) + ); + } + + /** + * A newer version is available + */ + public function testCheckUpdateNewVersionAvailable() + { + $newVersion = '1.8.3'; + FakeApplicationUtils::$VERSION_CODE = $newVersion; + + $version = FakeApplicationUtils::checkUpdate( + self::$testVersion, + self::$testUpdateFile, + 100, + true, + true + ); + + $this->assertEquals($newVersion, $version); + } + + /** + * No available information about versions + */ + public function testCheckUpdateNewVersionUnavailable() + { + $version = FakeApplicationUtils::checkUpdate( + self::$testVersion, + self::$testUpdateFile, + 100, + true, + true + ); + + $this->assertFalse($version); + } + + /** + * Test update checks - invalid Git branch + * @expectedException Exception + * @expectedExceptionMessageRegExp /Invalid branch selected for updates/ + */ + public function testCheckUpdateInvalidGitBranch() + { + ApplicationUtils::checkUpdate('', 'null', 0, true, true, 'unstable'); + } + + /** + * Shaarli is up-to-date + */ + public function testCheckUpdateNewVersionUpToDate() + { + FakeApplicationUtils::$VERSION_CODE = self::$testVersion; + + $version = FakeApplicationUtils::checkUpdate( + self::$testVersion, + self::$testUpdateFile, + 100, + true, + true + ); + + $this->assertFalse($version); + } + + /** + * Time-traveller's Shaarli + */ + public function testCheckUpdateNewVersionMaartiMcFly() + { + FakeApplicationUtils::$VERSION_CODE = '0.4.1'; + + $version = FakeApplicationUtils::checkUpdate( + self::$testVersion, + self::$testUpdateFile, + 100, + true, + true + ); + + $this->assertFalse($version); + } + + /** + * The version has been checked recently and Shaarli is up-to-date + */ + public function testCheckUpdateNewVersionTwiceUpToDate() + { + FakeApplicationUtils::$VERSION_CODE = self::$testVersion; + + // Create the update file + $version = FakeApplicationUtils::checkUpdate( + self::$testVersion, + self::$testUpdateFile, + 100, + true, + true + ); + + $this->assertFalse($version); + + // Reuse the update file + $version = FakeApplicationUtils::checkUpdate( + self::$testVersion, + self::$testUpdateFile, + 100, + true, + true + ); + + $this->assertFalse($version); + } + + /** + * The version has been checked recently and Shaarli is outdated + */ + public function testCheckUpdateNewVersionTwiceOutdated() + { + $newVersion = '1.8.3'; + FakeApplicationUtils::$VERSION_CODE = $newVersion; + + // Create the update file + $version = FakeApplicationUtils::checkUpdate( + self::$testVersion, + self::$testUpdateFile, + 100, + true, + true + ); + $this->assertEquals($newVersion, $version); + + // Reuse the update file + $version = FakeApplicationUtils::checkUpdate( + self::$testVersion, + self::$testUpdateFile, + 100, + true, + true + ); + $this->assertEquals($newVersion, $version); + } + /** * Check supported PHP versions */ diff --git a/tests/CacheTest.php b/tests/CacheTest.php index aa5395b0..26c43225 100644 --- a/tests/CacheTest.php +++ b/tests/CacheTest.php @@ -11,10 +11,10 @@ require_once 'application/Cache.php'; /** * Unitary tests for cached pages */ -class CachedTest extends PHPUnit_Framework_TestCase +class CacheTest extends PHPUnit_Framework_TestCase { // test cache directory - protected static $testCacheDir = 'tests/dummycache'; + protected static $testCacheDir = 'sandbox/dummycache'; // dummy cached file names / content protected static $pages = array('a', 'toto', 'd7b59c'); @@ -30,13 +30,22 @@ class CachedTest extends PHPUnit_Framework_TestCase } else { array_map('unlink', glob(self::$testCacheDir.'/*')); } - + foreach (self::$pages as $page) { file_put_contents(self::$testCacheDir.'/'.$page.'.cache', $page); } file_put_contents(self::$testCacheDir.'/intru.der', 'ShouldNotBeThere'); } + /** + * Remove dummycache folder after each tests. + */ + public function tearDown() + { + array_map('unlink', glob(self::$testCacheDir.'/*')); + rmdir(self::$testCacheDir); + } + /** * Purge cached pages */ @@ -56,7 +65,7 @@ class CachedTest extends PHPUnit_Framework_TestCase public function testPurgeCachedPagesMissingDir() { $this->assertEquals( - 'Cannot purge tests/dummycache_missing: no directory', + 'Cannot purge sandbox/dummycache_missing: no directory', purgeCachedPages(self::$testCacheDir.'_missing') ); } diff --git a/tests/CachedPageTest.php b/tests/CachedPageTest.php index e97af030..51565cd6 100644 --- a/tests/CachedPageTest.php +++ b/tests/CachedPageTest.php @@ -11,7 +11,7 @@ require_once 'application/CachedPage.php'; class CachedPageTest extends PHPUnit_Framework_TestCase { // test cache directory - protected static $testCacheDir = 'tests/pagecache'; + protected static $testCacheDir = 'sandbox/pagecache'; protected static $url = 'http://shaar.li/?do=atom'; protected static $filename; diff --git a/tests/LinkDBTest.php b/tests/LinkDBTest.php index 8929713d..7b22b270 100644 --- a/tests/LinkDBTest.php +++ b/tests/LinkDBTest.php @@ -16,7 +16,7 @@ require_once 'tests/utils/ReferenceLinkDB.php'; class LinkDBTest extends PHPUnit_Framework_TestCase { // datastore to test write operations - protected static $testDatastore = 'tests/datastore.php'; + protected static $testDatastore = 'sandbox/datastore.php'; protected static $refDB = null; protected static $publicLinkDB = null; protected static $privateLinkDB = null; @@ -511,4 +511,27 @@ class LinkDBTest extends PHPUnit_Framework_TestCase 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']); + } + } } diff --git a/tests/UtilsTest.php b/tests/UtilsTest.php index 4847ea94..02eecda2 100644 --- a/tests/UtilsTest.php +++ b/tests/UtilsTest.php @@ -187,4 +187,41 @@ class UtilsTest extends PHPUnit_Framework_TestCase 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 http://hello.there/is=someone#here 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 http://hello.there/is=someone#here 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); + } } diff --git a/tests/plugins/PlugQrcodeTest.php b/tests/plugins/PlugQrcodeTest.php index 86dc7f29..c749fa86 100644 --- a/tests/plugins/PlugQrcodeTest.php +++ b/tests/plugins/PlugQrcodeTest.php @@ -30,7 +30,7 @@ class PlugQrcodeTest extends PHPUnit_Framework_TestCase 'title' => $str, 'links' => array( array( - 'url' => $str, + 'real_url' => $str, ) ) ); @@ -39,7 +39,7 @@ class PlugQrcodeTest extends PHPUnit_Framework_TestCase $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'])); diff --git a/tpl/daily.html b/tpl/daily.html index 93a3ab45..063dc89a 100644 --- a/tpl/daily.html +++ b/tpl/daily.html @@ -66,7 +66,7 @@ {/if} {if="$link.thumbnail"}
{$link.thumbnail}
diff --git a/tpl/linklist.html b/tpl/linklist.html index f6e9e82b..666748a7 100644 --- a/tpl/linklist.html +++ b/tpl/linklist.html @@ -70,7 +70,9 @@ {/if} - {$value.title} + + {$value.title} +
{if="$value.description"}
{$value.description}
{/if} {if="!$GLOBALS['config']['HIDE_TIMESTAMPS'] || isLoggedIn()"} @@ -83,7 +85,7 @@ {$value} - {/loop} - {$value.url}
+ {$value.url}
{if="$value.tags"}
{loop="value.taglist"}{$value} {/loop} diff --git a/tpl/page.footer.html b/tpl/page.footer.html index 6c29850f..b20aae54 100644 --- a/tpl/page.footer.html +++ b/tpl/page.footer.html @@ -4,8 +4,16 @@ {$value} {/loop}
-{if="$newversion"} -
Shaarli {$newversion} is available.
+{if="$newVersion"} +
+ Shaarli {$newVersion} is + available. +
+{/if} +{if="$versionError"} +
+ Error: {$versionError} +
{/if} {if="isLoggedIn()"} diff --git a/tpl/picwall.html b/tpl/picwall.html index 97d5efdf..230c948b 100644 --- a/tpl/picwall.html +++ b/tpl/picwall.html @@ -16,7 +16,7 @@
{loop="linksToDisplay"}
- {$value.thumbnail}{$value.title} + {$value.thumbnail}{$value.title} {loop="$value.picwall_plugin"} {$value} {/loop}