]> git.immae.eu Git - github/shaarli/Shaarli.git/commitdiff
Merge pull request #947 from thewilli/wildcardsearch
authorArthurHoaro <arthur@hoa.ro>
Fri, 29 Sep 2017 16:38:02 +0000 (18:38 +0200)
committerGitHub <noreply@github.com>
Fri, 29 Sep 2017 16:38:02 +0000 (18:38 +0200)
wildcard tag search support

21 files changed:
.travis.yml
Makefile
application/HttpUtils.php
application/config/ConfigManager.php
doc/md/Release-Shaarli.md
doc/md/Shaarli-configuration.md
doc/md/Unit-tests-Docker.md [new file with mode: 0644]
docker/test/alpine36/Dockerfile [new file with mode: 0644]
docker/test/debian8/Dockerfile [new file with mode: 0644]
docker/test/debian9/Dockerfile [new file with mode: 0644]
docker/test/ubuntu16/Dockerfile [new file with mode: 0644]
index.php
mkdocs.yml
tests/HttpUtils/IsHttpsTest.php [new file with mode: 0644]
tests/languages/de/UtilsDeTest.php
tests/languages/en/UtilsEnTest.php
tests/languages/fr/UtilsFrTest.php
tpl/default/css/shaarli.css
tpl/default/js/shaarli.js
tpl/default/loginform.html
tpl/vintage/loginform.html

index 26535ad34f66fbdb68adb9446ad386ee057b3707..b6b9bddf60d0595dae6069fd33cf8ad166c5cee5 100644 (file)
@@ -1,12 +1,6 @@
 sudo: false
-dist: precise
+dist: trusty
 language: php
-addons:
-  apt:
-    packages:
-      - locales
-      - language-pack-de
-      - language-pack-fr
 cache:
   directories:
     - $HOME/.composer/cache
@@ -18,6 +12,7 @@ php:
 install:
   - composer self-update
   - composer install --prefer-dist
+  - locale -a
 script:
   - make clean
   - make check_permissions
index 6483fca78815b77994bea6539621c2826d0920e4..a3696ec987886657dfd2ecca1345575c4928c38c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -18,6 +18,16 @@ PHP_COMMA_SOURCE = index.php,application,tests,plugins
 
 all: static_analysis_summary check_permissions test
 
+##
+# Docker test adapter
+#
+# Shaarli sources and vendored libraries are copied from a shared volume
+# to a user-owned directory to enable running tests as a non-root user.
+##
+docker_%:
+       rsync -az /shaarli/ ~/shaarli/
+       cd ~/shaarli && make $*
+
 ##
 # Concise status of the project
 # These targets are non-blocking: || exit 0
@@ -159,14 +169,14 @@ composer_dependencies: clean
        find vendor/ -name ".git" -type d -exec rm -rf {} +
 
 ### generate a release tarball and include 3rd-party dependencies
-release_tar: composer_dependencies doc_html
+release_tar: composer_dependencies htmldoc
        git archive --prefix=$(ARCHIVE_PREFIX) -o $(ARCHIVE_VERSION).tar HEAD
        tar rvf $(ARCHIVE_VERSION).tar --transform "s|^vendor|$(ARCHIVE_PREFIX)vendor|" vendor/
        tar rvf $(ARCHIVE_VERSION).tar --transform "s|^doc/html|$(ARCHIVE_PREFIX)doc/html|" doc/html/
        gzip $(ARCHIVE_VERSION).tar
 
 ### generate a release zip and include 3rd-party dependencies
-release_zip: composer_dependencies doc_html
+release_zip: composer_dependencies htmldoc
        git archive --prefix=$(ARCHIVE_PREFIX) -o $(ARCHIVE_VERSION).zip -9 HEAD
        mkdir -p $(ARCHIVE_PREFIX)/{doc,vendor}
        rsync -a doc/html/ $(ARCHIVE_PREFIX)doc/html/
@@ -195,17 +205,11 @@ doxygen: clean
        @rm -rf doxygen
        @( cat Doxyfile ; echo "PROJECT_NUMBER=`git describe`" ) | doxygen -
 
-### Convert local markdown documentation to HTML
-#
-# For all pages:
-#  - convert GitHub-flavoured relative links to standard Markdown
-#  - generate html documentation with mkdocs
-htmlpages:
+### generate HTML documentation from Markdown pages with MkDocs
+htmldoc:
        python3 -m venv venv/
        bash -c 'source venv/bin/activate; \
        pip install mkdocs; \
        mkdocs build'
        find doc/html/ -type f -exec chmod a-x '{}' \;
        rm -r venv
-
-doc_html: authors htmlpages
index 88a1efdb86382646648d9a26a2cbeab022f7ecdf..0083596643f510d4ea131fad9df25de215ff77ac 100644 (file)
@@ -401,3 +401,31 @@ function getIpAddressFromProxy($server, $trustedIps)
 
     return array_pop($ips);
 }
+
+/**
+ * Returns true if Shaarli's currently browsed in HTTPS.
+ * Supports reverse proxies (if the headers are correctly set).
+ *
+ * @param array $server $_SERVER.
+ *
+ * @return bool true if HTTPS, false otherwise.
+ */
+function is_https($server)
+{
+
+    if (isset($server['HTTP_X_FORWARDED_PORT'])) {
+        // Keep forwarded port
+        if (strpos($server['HTTP_X_FORWARDED_PORT'], ',') !== false) {
+            $ports = explode(',', $server['HTTP_X_FORWARDED_PORT']);
+            $port = trim($ports[0]);
+        } else {
+            $port = $server['HTTP_X_FORWARDED_PORT'];
+        }
+
+        if ($port == '443') {
+            return true;
+        }
+    }
+
+    return ! empty($server['HTTPS']);
+}
index 0fc5a5c7f2b319401fe698c77a88b1fcb0786f62..32f6ef6db5418044a12fd92959e19a2d7634a029 100644 (file)
@@ -327,7 +327,10 @@ class ConfigManager
 
         $this->setEmpty('privacy.default_private_links', false);
         $this->setEmpty('privacy.hide_public_links', false);
+        $this->setEmpty('privacy.force_login', false);
         $this->setEmpty('privacy.hide_timestamps', false);
+        // default state of the 'remember me' checkbox of the login form
+        $this->setEmpty('privacy.remember_user_default', true);
 
         $this->setEmpty('thumbnail.enable_thumbnails', true);
         $this->setEmpty('thumbnail.enable_localcache', true);
index 974a743861994dc44126f69329a90537898f89ad..e22eabc9f32af872d7771a3cda37391261fc6464 100644 (file)
@@ -46,6 +46,12 @@ TBA
 
 
 ## Increment the version code, update docs, create and push a signed tag
+### Update the list of Git contributors
+```bash
+$ make authors
+$ git commit -s -m "Update AUTHORS"
+```
+
 ### Create and merge a Pull Request
 This one is pretty straightforward ;-)
 
index 188a3c09161ef5c68676a3d29d8b133464ede493..374864147065318ea2b703253bea39e2daa29458 100644 (file)
@@ -90,7 +90,10 @@ _These settings should not be edited_
 
 - **default_private_links**: Check the private checkbox by default for every new link.  
 - **hide_public_links**: All links are hidden while logged out.  
+- **force_login**: if **hide_public_links** and this are set to `true`, all anonymous users are redirected to the login page.
 - **hide_timestamps**: Timestamps are hidden.
+- **remember_user_default**: Default state of the login page's *remember me* checkbox
+    - `true`: checked by default, `false`: unchecked by default
 
 ### Feed
 
@@ -192,7 +195,9 @@ _These settings should not be edited_
     "privacy": {
         "default_private_links": true,
         "hide_public_links": false,
-        "hide_timestamps": false
+        "force_login": false,
+        "hide_timestamps": false,
+        "remember_user_default": true
     },
     "thumbnail": {
         "enable_thumbnails": true,
diff --git a/doc/md/Unit-tests-Docker.md b/doc/md/Unit-tests-Docker.md
new file mode 100644 (file)
index 0000000..c2de7cc
--- /dev/null
@@ -0,0 +1,56 @@
+## Running tests inside Docker containers
+
+Read first:
+
+- [Docker 101](docker/docker-101.md)
+- [Docker resources](docker/resources.md)
+- [Unit tests](Unit-tests.md)
+
+### Docker test images
+
+Test Dockerfiles are located under `docker/tests/<distribution>/Dockerfile`,
+and can be used to build Docker images to run Shaarli test suites under common
+Linux environments.
+
+Dockerfiles are provided for the following environments:
+
+- `alpine36` - [Alpine 3.6](https://www.alpinelinux.org/downloads/)
+- `debian8` - [Debian 8 Jessie](https://www.debian.org/DebianJessie) (oldstable)
+- `debian9` - [Debian 9 Stretch](https://wiki.debian.org/DebianStretch) (stable)
+- `ubuntu16` - [Ubuntu 16.04 Xenial Xerus](http://releases.ubuntu.com/16.04/) (LTS)
+
+What's behind the curtains:
+
+- each image provides:
+    - a base Linux OS
+    - Shaarli PHP dependencies (OS packages)
+    - test PHP dependencies (OS packages)
+    - Composer
+- the local workspace is mapped to the container's `/shaarli/` directory,
+- the files are rsync'd to so tests are run using a standard Linux user account
+  (running tests as `root` would bypass permission checks and may hide issues)
+- the tests are run inside the container.
+
+### Building test images
+
+```bash
+# build the Debian 9 Docker image
+$ cd /path/to/shaarli
+$ cd docker/test/debian9
+$ docker build -t shaarli-test:debian9 .
+```
+
+### Running tests
+
+```bash
+$ cd /path/to/shaarli
+
+# install/update 3rd-party test dependencies
+$ composer install --prefer-dist
+
+# run tests using the freshly built image
+$ docker run -v $PWD:/shaarli shaarli-test:debian9 docker_test
+
+# run the full test campaign
+$ docker run -v $PWD:/shaarli shaarli-test:debian9 docker_all_tests
+```
diff --git a/docker/test/alpine36/Dockerfile b/docker/test/alpine36/Dockerfile
new file mode 100644 (file)
index 0000000..fa84f6e
--- /dev/null
@@ -0,0 +1,34 @@
+FROM alpine:3.6
+MAINTAINER Shaarli Community
+
+RUN apk --update --no-cache add \
+        ca-certificates \
+        curl \
+        make \
+        php7 \
+        php7-ctype \
+        php7-curl \
+        php7-dom \
+        php7-gd \
+        php7-iconv \
+        php7-intl \
+        php7-json \
+        php7-mbstring \
+        php7-openssl \
+        php7-phar \
+        php7-session \
+        php7-simplexml \
+        php7-tokenizer \
+        php7-xdebug \
+        php7-xml \
+        php7-zlib \
+        rsync
+
+RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
+
+RUN mkdir /shaarli
+WORKDIR /shaarli
+VOLUME /shaarli
+
+ENTRYPOINT ["make"]
+CMD []
diff --git a/docker/test/debian8/Dockerfile b/docker/test/debian8/Dockerfile
new file mode 100644 (file)
index 0000000..eaa34e9
--- /dev/null
@@ -0,0 +1,35 @@
+FROM debian:jessie
+MAINTAINER Shaarli Community
+
+ENV TERM dumb
+ENV DEBIAN_FRONTEND noninteractive
+ENV LANG en_US.UTF-8
+ENV LANGUAGE en_US:en
+
+RUN apt-get update \
+    && apt-get install --no-install-recommends -y \
+       ca-certificates \
+       curl \
+       locales \
+       make \
+       php5 \
+       php5-curl \
+       php5-gd \
+       php5-intl \
+       php5-xdebug \
+       rsync \
+    && apt-get clean
+
+RUN locale-gen en_US.UTF-8 \
+    && locale-gen de_DE.UTF-8 \
+    && locale-gen fr_FR.UTF-8
+
+ADD https://getcomposer.org/composer.phar /usr/local/bin/composer
+RUN chmod 755 /usr/local/bin/composer
+
+RUN mkdir /shaarli
+WORKDIR /shaarli
+VOLUME /shaarli
+
+ENTRYPOINT ["make"]
+CMD []
diff --git a/docker/test/debian9/Dockerfile b/docker/test/debian9/Dockerfile
new file mode 100644 (file)
index 0000000..3ab4b93
--- /dev/null
@@ -0,0 +1,36 @@
+FROM debian:stretch
+MAINTAINER Shaarli Community
+
+ENV TERM dumb
+ENV DEBIAN_FRONTEND noninteractive
+ENV LANG en_US.UTF-8
+ENV LANGUAGE en_US:en
+
+RUN apt-get update \
+    && apt-get install --no-install-recommends -y \
+       ca-certificates \
+       curl \
+       locales \
+       make \
+       php7.0 \
+       php7.0-curl \
+       php7.0-gd \
+       php7.0-intl \
+       php7.0-xml \
+       php-xdebug \
+       rsync \
+    && apt-get clean
+
+RUN locale-gen en_US.UTF-8 \
+    && locale-gen de_DE.UTF-8 \
+    && locale-gen fr_FR.UTF-8
+
+ADD https://getcomposer.org/composer.phar /usr/local/bin/composer
+RUN chmod 755 /usr/local/bin/composer
+
+RUN mkdir /shaarli
+WORKDIR /shaarli
+VOLUME /shaarli
+
+ENTRYPOINT ["make"]
+CMD []
diff --git a/docker/test/ubuntu16/Dockerfile b/docker/test/ubuntu16/Dockerfile
new file mode 100644 (file)
index 0000000..e53ed9e
--- /dev/null
@@ -0,0 +1,36 @@
+FROM ubuntu:16.04
+MAINTAINER Shaarli Community
+
+ENV TERM dumb
+ENV DEBIAN_FRONTEND noninteractive
+ENV LANG en_US.UTF-8
+ENV LANGUAGE en_US:en
+
+RUN apt-get update \
+    && apt-get install --no-install-recommends -y \
+       ca-certificates \
+       curl \
+       language-pack-de \
+       language-pack-en \
+       language-pack-fr \
+       locales \
+       make \
+       php7.0 \
+       php7.0-curl \
+       php7.0-gd \
+       php7.0-intl \
+       php7.0-xml \
+       php-xdebug \
+       rsync \
+    && apt-get clean
+
+ADD https://getcomposer.org/composer.phar /usr/local/bin/composer
+RUN chmod 755 /usr/local/bin/composer
+
+RUN useradd -m dev \
+    && mkdir /shaarli
+USER dev
+WORKDIR /shaarli
+
+ENTRYPOINT ["make"]
+CMD []
index 7df6d819ef4edc12ad95e66e659c21897beb88e3..fb00a9fa3adb8d302f712fcbe7d7fc2a694409f4 100644 (file)
--- a/index.php
+++ b/index.php
@@ -583,20 +583,29 @@ function showDailyRSS($conf) {
  */
 function showDaily($pageBuilder, $LINKSDB, $conf, $pluginManager)
 {
-    $day=date('Ymd',strtotime('-1 day')); // Yesterday, in format YYYYMMDD.
-    if (isset($_GET['day'])) $day=$_GET['day'];
+    $day = date('Ymd', strtotime('-1 day')); // Yesterday, in format YYYYMMDD.
+    if (isset($_GET['day'])) {
+      $day = $_GET['day'];
+    }
 
     $days = $LINKSDB->days();
-    $i = array_search($day,$days);
-    if ($i===false) { $i=count($days)-1; $day=$days[$i]; }
-    $previousday='';
-    $nextday='';
-    if ($i!==false)
-    {
-        if ($i>=1) $previousday=$days[$i-1];
-        if ($i<count($days)-1) $nextday=$days[$i+1];
+    $i = array_search($day, $days);
+    if ($i === false && count($days)) {
+        // no links for day, but at least one day with links
+        $i = count($days) - 1;
+        $day = $days[$i];
     }
+    $previousday = '';
+    $nextday = '';
 
+    if ($i !== false) {
+        if ($i >= 1) {
+             $previousday=$days[$i - 1];
+        }
+        if ($i < count($days) - 1) {
+          $nextday = $days[$i + 1];
+        }
+    }
     try {
         $linksToDisplay = $LINKSDB->filterDay($day);
     } catch (Exception $exc) {
@@ -605,9 +614,7 @@ function showDaily($pageBuilder, $LINKSDB, $conf, $pluginManager)
     }
 
     // We pre-format some fields for proper output.
-    foreach($linksToDisplay as $key=>$link)
-    {
-
+    foreach($linksToDisplay as $key => $link) {
         $taglist = explode(' ',$link['tags']);
         uasort($taglist, 'strcasecmp');
         $linksToDisplay[$key]['taglist']=$taglist;
@@ -621,21 +628,22 @@ function showDaily($pageBuilder, $LINKSDB, $conf, $pluginManager)
        so I manually spread entries with a simple method: I roughly evaluate the
        height of a div according to title and description length.
     */
-    $columns=array(array(),array(),array()); // Entries to display, for each column.
-    $fill=array(0,0,0);  // Rough estimate of columns fill.
-    foreach($linksToDisplay as $key=>$link)
-    {
+    $columns = array(array(), array(), array()); // Entries to display, for each column.
+    $fill = array(0, 0, 0);  // Rough estimate of columns fill.
+    foreach($linksToDisplay as $key => $link) {
         // Roughly estimate length of entry (by counting characters)
         // Title: 30 chars = 1 line. 1 line is 30 pixels height.
         // Description: 836 characters gives roughly 342 pixel height.
         // This is not perfect, but it's usually OK.
-        $length=strlen($link['title'])+(342*strlen($link['description']))/836;
-        if ($link['thumbnail']) $length +=100; // 1 thumbnails roughly takes 100 pixels height.
+        $length = strlen($link['title']) + (342 * strlen($link['description'])) / 836;
+        if ($link['thumbnail']) {
+          $length += 100; // 1 thumbnails roughly takes 100 pixels height.
+        }
         // Then put in column which is the less filled:
-        $smallest=min($fill); // find smallest value in array.
-        $index=array_search($smallest,$fill); // find index of this smallest value.
-        array_push($columns[$index],$link); // Put entry in this column.
-        $fill[$index]+=$length;
+        $smallest = min($fill); // find smallest value in array.
+        $index = array_search($smallest, $fill); // find index of this smallest value.
+        array_push($columns[$index], $link); // Put entry in this column.
+        $fill[$index] += $length;
     }
 
     $dayDate = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $day.'_000000');
@@ -710,6 +718,23 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history)
     $query = (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : '';
     $targetPage = Router::findPage($query, $_GET, isLoggedIn());
 
+    if (
+        // if the user isn't logged in
+        !isLoggedIn() &&
+        // and Shaarli doesn't have public content...
+        $conf->get('privacy.hide_public_links') &&
+        // and is configured to enforce the login
+        $conf->get('privacy.force_login') &&
+        // and the current page isn't already the login page
+        $targetPage !== Router::$PAGE_LOGIN &&
+        // and the user is not requesting a feed (which would lead to a different content-type as expected)
+        $targetPage !== Router::$PAGE_FEED_ATOM &&
+        $targetPage !== Router::$PAGE_FEED_RSS
+    ) {
+        // force current page to be the login page
+        $targetPage = Router::$PAGE_LOGIN;
+    }
+
     // Call plugin hooks for header, footer and includes, specifying which page will be rendered.
     // Then assign generated data to RainTPL.
     $common_hooks = array(
@@ -737,6 +762,8 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history)
             $PAGE->assign('username', escape($_GET['username']));
         }
         $PAGE->assign('returnurl',(isset($_SERVER['HTTP_REFERER']) ? escape($_SERVER['HTTP_REFERER']):''));
+        // add default state of the 'remember me' checkbox
+        $PAGE->assign('remember_user_default', $conf->get('privacy.remember_user_default'));
         $PAGE->renderPage('loginform');
         exit;
     }
@@ -1055,10 +1082,10 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history)
     // -------- Display the Tools menu if requested (import/export/bookmarklet...)
     if ($targetPage == Router::$PAGE_TOOLS)
     {
-        $data = array(
+        $data = [
             'pageabsaddr' => index_url($_SERVER),
-            'sslenabled' => !empty($_SERVER['HTTPS'])
-        );
+            'sslenabled' => is_https($_SERVER),
+        ];
         $pluginManager->executeHooks('render_tools', $data);
 
         foreach ($data as $key => $value) {
@@ -1320,10 +1347,17 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history)
             die('Wrong token.');
         }
 
-        if (strpos($_GET['lf_linkdate'], ' ') !== false) {
-            $ids = array_values(array_filter(preg_split('/\s+/', escape($_GET['lf_linkdate']))));
+        $ids = trim($_GET['lf_linkdate']);
+        if (strpos($ids, ' ') !== false) {
+            // multiple, space-separated ids provided
+            $ids = array_values(array_filter(preg_split('/\s+/', escape($ids))));
         } else {
-            $ids = [$_GET['lf_linkdate']];
+            // only a single id provided
+            $ids = [$ids];
+        }
+        // assert at least one id is given
+        if(!count($ids)){
+            die('no id provided');
         }
         foreach ($ids as $id) {
             $id = (int) escape($id);
index 648d8f67b473ac75fa430108d04c4c9b2c624180..03a7a34e80e3f448e1e8bbffec77cbd76490dc29 100644 (file)
@@ -45,6 +45,7 @@ pages:
     - Static analysis: Static-analysis.md
     - Theming: Theming.md
     - Unit tests: Unit-tests.md
+    - Unit tests inside Docker: Unit-tests-Docker.md
 - About:
     - FAQ: FAQ.md
     - Community & Related software: Community-&-Related-software.md
diff --git a/tests/HttpUtils/IsHttpsTest.php b/tests/HttpUtils/IsHttpsTest.php
new file mode 100644 (file)
index 0000000..097f2bc
--- /dev/null
@@ -0,0 +1,36 @@
+<?php
+
+
+/**
+ * Class IsHttpsTest
+ *
+ * Test class for is_https() function.
+ */
+class IsHttpsTest extends PHPUnit_Framework_TestCase
+{
+
+    /**
+     * Test is_https with HTTPS values.
+     */
+    public function testIsHttpsTrue()
+    {
+        $this->assertTrue(is_https(['HTTPS' => true]));
+        $this->assertTrue(is_https(['HTTPS' => '1']));
+        $this->assertTrue(is_https(['HTTPS' => false, 'HTTP_X_FORWARDED_PORT' => 443]));
+        $this->assertTrue(is_https(['HTTPS' => false, 'HTTP_X_FORWARDED_PORT' => '443']));
+        $this->assertTrue(is_https(['HTTPS' => false, 'HTTP_X_FORWARDED_PORT' => '443,123,456,']));
+    }
+
+    /**
+     * Test is_https with HTTP values.
+     */
+    public function testIsHttpsFalse()
+    {
+        $this->assertFalse(is_https([]));
+        $this->assertFalse(is_https(['HTTPS' => false]));
+        $this->assertFalse(is_https(['HTTPS' => '0']));
+        $this->assertFalse(is_https(['HTTPS' => false, 'HTTP_X_FORWARDED_PORT' => 123]));
+        $this->assertFalse(is_https(['HTTPS' => false, 'HTTP_X_FORWARDED_PORT' => '123']));
+        $this->assertFalse(is_https(['HTTPS' => false, 'HTTP_X_FORWARDED_PORT' => ',123,456,']));
+    }
+}
index 6c9c9adce8cb6b02653bf32b4660f5f69c04edd5..4569c923b3171609d8a755cd32aa4cdf06c755a2 100644 (file)
@@ -81,12 +81,12 @@ class UtilsDeTest extends UtilsTest
     }
 
     /**
-     * Test autoLocale with multiples value, the second one is valid
+     * Test autoLocale with multiples value, the second one is available
      */
-    public function testAutoLocaleMultipleSecondValid()
+    public function testAutoLocaleMultipleSecondAvailable()
     {
         $current = setlocale(LC_ALL, 0);
-        $header = 'pt_BR,fr-fr';
+        $header = 'mag_IN,fr-fr';
         autoLocale($header);
         $this->assertEquals('fr_FR.utf8', setlocale(LC_ALL, 0));
 
@@ -106,12 +106,12 @@ class UtilsDeTest extends UtilsTest
     }
 
     /**
-     * Test autoLocale with an invalid value: defaults to en_US.
+     * Test autoLocale with an unavailable value: defaults to en_US.
      */
-    public function testAutoLocaleInvalid()
+    public function testAutoLocaleUnavailable()
     {
         $current = setlocale(LC_ALL, 0);
-        autoLocale('pt_BR');
+        autoLocale('mag_IN');
         $this->assertEquals('en_US.utf8', setlocale(LC_ALL, 0));
 
         setlocale(LC_ALL, $current);
index d8680b2b429c1ae6ab4b1f0f888e61c5d3faf4a4..a74063ae92de8fdd41c65727f64c8e071b0bfebd 100644 (file)
@@ -81,12 +81,12 @@ class UtilsEnTest extends UtilsTest
     }
 
     /**
-     * Test autoLocale with multiples value, the second one is valid
+     * Test autoLocale with multiples value, the second one is available
      */
-    public function testAutoLocaleMultipleSecondValid()
+    public function testAutoLocaleMultipleSecondAvailable()
     {
         $current = setlocale(LC_ALL, 0);
-        $header = 'pt_BR,fr-fr';
+        $header = 'mag_IN,fr-fr';
         autoLocale($header);
         $this->assertEquals('fr_FR.utf8', setlocale(LC_ALL, 0));
 
@@ -106,12 +106,12 @@ class UtilsEnTest extends UtilsTest
     }
 
     /**
-     * Test autoLocale with an invalid value: defaults to en_US.
+     * Test autoLocale with an unavailable value: defaults to en_US.
      */
-    public function testAutoLocaleInvalid()
+    public function testAutoLocaleUnavailable()
     {
         $current = setlocale(LC_ALL, 0);
-        autoLocale('pt_BR');
+        autoLocale('mag_IN');
         $this->assertEquals('en_US.utf8', setlocale(LC_ALL, 0));
 
         setlocale(LC_ALL, $current);
index 0d50a87829f241591b0868446831c2918dcd4618..3dbb126faef25b2b82b6d7bf4571eff124ec98d1 100644 (file)
@@ -81,12 +81,12 @@ class UtilsFrTest extends UtilsTest
     }
 
     /**
-     * Test autoLocale with multiples value, the second one is valid
+     * Test autoLocale with multiples value, the second one is available
      */
-    public function testAutoLocaleMultipleSecondValid()
+    public function testAutoLocaleMultipleSecondAvailable()
     {
         $current = setlocale(LC_ALL, 0);
-        $header = 'pt_BR,de-de';
+        $header = 'mag_IN,de-de';
         autoLocale($header);
         $this->assertEquals('de_DE.utf8', setlocale(LC_ALL, 0));
 
@@ -106,12 +106,12 @@ class UtilsFrTest extends UtilsTest
     }
 
     /**
-     * Test autoLocale with an invalid value: defaults to en_US.
+     * Test autoLocale with an unavailable value: defaults to en_US.
      */
-    public function testAutoLocaleInvalid()
+    public function testAutoLocaleUnavailable()
     {
         $current = setlocale(LC_ALL, 0);
-        autoLocale('pt_BR');
+        autoLocale('mag_IN');
         $this->assertEquals('en_US.utf8', setlocale(LC_ALL, 0));
 
         setlocale(LC_ALL, $current);
index e1868c59aafaa5da7f37b5b6972ac5986be0d6fb..ba589723b3c999e1361f6cab0cc8ebbaf3e830c1 100644 (file)
@@ -539,7 +539,7 @@ body, .pure-g [class*="pure-u"] {
 }
 
 .linklist-item-title a:visited .linklist-link {
-    color: #555555;
+    color: #2a4c41;
 }
 
 .linklist-item-title a:hover, .linklist-item-title .linklist-link:hover{
index 4f49affa3321226024bae670117d7851ba385141..1c66ebbdd708f033c5ae26e747e3f313137edee7 100644 (file)
@@ -401,14 +401,14 @@ window.onload = function () {
 
             var message = 'Are you sure you want to delete '+ links.length +' links?\n';
             message += 'This action is IRREVERSIBLE!\n\nTitles:\n';
-            var ids = '';
+            var ids = [];
             links.forEach(function(item) {
                 message += '  - '+ item['title'] +'\n';
-                ids += item['id'] +'+';
+                ids.push(item['id']);
             });
 
             if (window.confirm(message)) {
-                window.location = '?delete_link&lf_linkdate='+ ids +'&token='+ token.value;
+                window.location = '?delete_link&lf_linkdate='+ ids.join('+') +'&token='+ token.value;
             }
         });
     }
@@ -607,10 +607,11 @@ function htmlEntities(str)
 function activateFirefoxSocial(node) {
     var loc = location.href;
     var baseURL = loc.substring(0, loc.lastIndexOf("/") + 1);
+    var title = document.title;
 
     // Keeping the data separated (ie. not in the DOM) so that it's maintainable and diffable.
     var data = {
-        name: "{$shaarlititle}",
+        name: title,
         description: "The personal, minimalist, super-fast, database free, bookmarking service by the Shaarli community.",
         author: "Shaarli",
         version: "1.0.0",
index eb6d83781817690374ad593d4457eaf0fdd60401..5777a2186da5d94521d5d7c43726a4ab79da1de1 100644 (file)
@@ -30,7 +30,8 @@
         </div>
         <div class="remember-me">
           <input type="checkbox" name="longlastingsession" id="longlastingsessionform"
-             checked="checked" tabindex="22">
+             {if="$remember_user_default"}checked="checked"{/if}
+             tabindex="22">
           <label for="longlastingsessionform">{'Remember me'|t}</label>
         </div>
         <div>
index 84176385765837973d77be29941db622ccad1f6a..1becd44f7db6c305d9bed899c65c13db6aa16305 100644 (file)
@@ -24,7 +24,9 @@
         </label>
         <input type="submit" value="Login" class="bigbutton" tabindex="4">
         <label for="longlastingsession">
-          <input type="checkbox" name="longlastingsession" id="longlastingsession" tabindex="3">
+          <input type="checkbox" name="longlastingsession"
+                 id="longlastingsession" tabindex="3"
+                 {if="$remember_user_default"}checked="checked"{/if}>
           Stay signed in (Do not check on public computers)</label>
         <input type="hidden" name="token" value="{$token}">
         {if="$returnurl"}<input type="hidden" name="returnurl" value="{$returnurl}">{/if}