]> git.immae.eu Git - github/shaarli/Shaarli.git/commitdiff
Merge pull request #1538 from ArthurHoaro/feature/plugins-bookmark-service
authorArthurHoaro <arthur@hoa.ro>
Sun, 6 Sep 2020 12:13:16 +0000 (14:13 +0200)
committerGitHub <noreply@github.com>
Sun, 6 Sep 2020 12:13:16 +0000 (14:13 +0200)
Inject BookmarkServiceInterface in plugins data

25 files changed:
application/Languages.php
application/bookmark/BookmarkArray.php
application/bookmark/BookmarkFileService.php
application/bookmark/BookmarkServiceInterface.php
application/feed/FeedBuilder.php
application/front/ShaarliMiddleware.php
application/front/controller/visitor/FeedController.php
application/legacy/LegacyController.php
application/legacy/LegacyRouter.php
application/render/PageBuilder.php
assets/default/js/base.js
assets/default/scss/shaarli.scss
inc/languages/jp/LC_MESSAGES/shaarli.po [moved from inc/languages/ja/LC_MESSAGES/shaarli.po with 100% similarity]
package.json
plugins/default_colors/default_colors.php
plugins/qrcode/qrcode.php
tests/feed/FeedBuilderTest.php
tests/front/controller/admin/ConfigureControllerTest.php
tests/front/controller/visitor/FeedControllerTest.php
tests/legacy/LegacyControllerTest.php
tests/legacy/LegacyRouterTest.php [deleted file]
tests/plugins/PluginDefaultColorsTest.php
tpl/default/linklist.html
tpl/default/linklist.paging.html
yarn.lock

index 5cda802e0c1faaf57058e0dca653cc713c90c0c3..d83e0765794af8cfbf0a5f762b5070162181a811 100644 (file)
@@ -179,9 +179,10 @@ class Languages
     {
         return [
             'auto' => t('Automatic'),
+            'de' => t('German'),
             'en' => t('English'),
             'fr' => t('French'),
-            'de' => t('German'),
+            'jp' => t('Japanese'),
         ];
     }
 }
index d87d43b41ae41a3753aff732aa3989636728c4b4..3bd5eb20f64bebe26d6306ba3590190eb90ec55b 100644 (file)
@@ -234,16 +234,17 @@ class BookmarkArray implements \Iterator, \Countable, \ArrayAccess
      *
      * Also update the urls and ids mapping arrays.
      *
-     * @param string $order ASC|DESC
+     * @param string $order        ASC|DESC
+     * @param bool   $ignoreSticky If set to true, sticky bookmarks won't be first
      */
-    public function reorder($order = 'DESC')
+    public function reorder(string $order = 'DESC', bool $ignoreSticky = false): void
     {
         $order = $order === 'ASC' ? -1 : 1;
         // Reorder array by dates.
-        usort($this->bookmarks, function ($a, $b) use ($order) {
+        usort($this->bookmarks, function ($a, $b) use ($order, $ignoreSticky) {
             /** @var $a Bookmark */
             /** @var $b Bookmark */
-            if ($a->isSticky() !== $b->isSticky()) {
+            if (false === $ignoreSticky && $a->isSticky() !== $b->isSticky()) {
                 return $a->isSticky() ? -1 : 1;
             }
             return $a->getCreated() < $b->getCreated() ? 1 * $order : -1 * $order;
index b3a90ed4623beecc7c75d96be635e33decfd6aed..e3a611461a7aae9ecd3f0070a3341aa872aa737d 100644 (file)
@@ -114,8 +114,13 @@ class BookmarkFileService implements BookmarkServiceInterface
     /**
      * @inheritDoc
      */
-    public function search($request = [], $visibility = null, $caseSensitive = false, $untaggedOnly = false)
-    {
+    public function search(
+        $request = [],
+        $visibility = null,
+        $caseSensitive = false,
+        $untaggedOnly = false,
+        bool $ignoreSticky = false
+    ) {
         if ($visibility === null) {
             $visibility = $this->isLoggedIn ? BookmarkFilter::$ALL : BookmarkFilter::$PUBLIC;
         }
@@ -124,6 +129,10 @@ class BookmarkFileService implements BookmarkServiceInterface
         $searchtags = isset($request['searchtags']) ? $request['searchtags'] : '';
         $searchterm = isset($request['searchterm']) ? $request['searchterm'] : '';
 
+        if ($ignoreSticky) {
+            $this->bookmarks->reorder('DESC', true);
+        }
+
         return $this->bookmarkFilter->filter(
             BookmarkFilter::$FILTER_TAG | BookmarkFilter::$FILTER_TEXT,
             [$searchtags, $searchterm],
index ce8bd912bf6b5a8d086646a9f1fd4f8fd297fe62..b9b483eb8ae14ae70582ec5589eb67fd9f066558 100644 (file)
@@ -49,10 +49,17 @@ interface BookmarkServiceInterface
      * @param string $visibility
      * @param bool   $caseSensitive
      * @param bool   $untaggedOnly
+     * @param bool   $ignoreSticky
      *
      * @return Bookmark[]
      */
-    public function search($request = [], $visibility = null, $caseSensitive = false, $untaggedOnly = false);
+    public function search(
+        $request = [],
+        $visibility = null,
+        $caseSensitive = false,
+        $untaggedOnly = false,
+        bool $ignoreSticky = false
+    );
 
     /**
      * Get a single bookmark by its ID.
index 269ad87722cfc5888070ce05dc5c730149a9129b..3653c32f981b360d52d556e4ea48e5ee6c1e4ab3 100644 (file)
@@ -102,7 +102,7 @@ class FeedBuilder
         }
 
         // Optionally filter the results:
-        $linksToDisplay = $this->linkDB->search($userInput);
+        $linksToDisplay = $this->linkDB->search($userInput, null, false, false, true);
 
         $nblinksToDisplay = $this->getNbLinks(count($linksToDisplay), $userInput);
 
index c015c0c6f0284fcfb9802a9938494c60763f721e..d1aa139989e2689ee61df29f47c2cd08bd2d9999 100644 (file)
@@ -94,7 +94,7 @@ class ShaarliMiddleware
             && $this->container->conf->get('privacy.force_login')
             // and the current page isn't already the login page
             // and the user is not requesting a feed (which would lead to a different content-type as expected)
-            && !in_array($next->getName(), ['login', 'atom', 'rss'], true)
+            && !in_array($next->getName(), ['login', 'processLogin', 'atom', 'rss'], true)
         ) {
             throw new UnauthorizedException();
         }
index da2848c2b0151b115d5d3427236a7f039c96265b..8d8b546aad35cc58573e0083b3ed9d283c0b71a7 100644 (file)
@@ -46,10 +46,10 @@ class FeedController extends ShaarliVisitorController
 
         $data = $this->container->feedBuilder->buildData($feedType, $request->getParams());
 
-        $this->executePageHooks('render_feed', $data, $feedType);
+        $this->executePageHooks('render_feed', $data, 'feed.' . $feedType);
         $this->assignAllView($data);
 
-        $content = $this->render('feed.'. $feedType);
+        $content = $this->render('feed.' . $feedType);
 
         $cache->cache($content);
 
index 26465d2cf56fcf78fb91f7ec608ede92a8c97d9e..826604e77204f3726862890d0478ad5b448f7199 100644 (file)
@@ -39,29 +39,44 @@ class LegacyController extends ShaarliVisitorController
     /** Legacy route: ?post= */
     public function post(Request $request, Response $response): Response
     {
-        $parameters = count($request->getQueryParams()) > 0 ? '?' . http_build_query($request->getQueryParams()) : '';
+        $route = '/admin/shaare';
+        $buildParameters = function (?array $parameters, bool $encode) {
+            if ($encode) {
+                $parameters = array_map('urlencode', $parameters);
+            }
+
+            return count($parameters) > 0 ? '?' . http_build_query($parameters) : '';
+        };
+
 
         if (!$this->container->loginManager->isLoggedIn()) {
-            return $this->redirect($response, '/login' . $parameters);
+            $parameters = $buildParameters($request->getQueryParams(), true);
+            return $this->redirect($response, '/login?returnurl='. $this->getBasePath() . $route . $parameters);
         }
 
-        return $this->redirect($response, '/admin/shaare' . $parameters);
+        $parameters = $buildParameters($request->getQueryParams(), false);
+
+        return $this->redirect($response, $route . $parameters);
     }
 
     /** Legacy route: ?addlink= */
     protected function addlink(Request $request, Response $response): Response
     {
+        $route = '/admin/add-shaare';
+
         if (!$this->container->loginManager->isLoggedIn()) {
-            return $this->redirect($response, '/login');
+            return $this->redirect($response, '/login?returnurl=' . $this->getBasePath() . $route);
         }
 
-        return $this->redirect($response, '/admin/add-shaare');
+        return $this->redirect($response, $route);
     }
 
     /** Legacy route: ?do=login */
     protected function login(Request $request, Response $response): Response
     {
-        return $this->redirect($response, '/login');
+        $returnUrl = $request->getQueryParam('returnurl');
+
+        return $this->redirect($response, '/login' . ($returnUrl ? '?returnurl=' . $returnUrl : ''));
     }
 
     /** Legacy route: ?do=logout */
@@ -127,4 +142,21 @@ class LegacyController extends ShaarliVisitorController
 
         return $this->redirect($response, '/feed/' . $feedType . $parameters);
     }
+
+    /** Legacy route: ?do=configure */
+    protected function configure(Request $request, Response $response): Response
+    {
+        $route = '/admin/configure';
+
+        if (!$this->container->loginManager->isLoggedIn()) {
+            return $this->redirect($response, '/login?returnurl=' . $this->getBasePath() . $route);
+        }
+
+        return $this->redirect($response, $route);
+    }
+
+    protected function getBasePath(): string
+    {
+        return $this->container->basePath ?: '';
+    }
 }
index cea99154cd5885ad495156fd8cfcf68c746f89a5..0449c7e11db4e062ee75352958bd646363e7e4dd 100644 (file)
@@ -17,15 +17,15 @@ class LegacyRouter
 
     public static $PAGE_PICWALL = 'picwall';
 
-    public static $PAGE_TAGCLOUD = 'tagcloud';
+    public static $PAGE_TAGCLOUD = 'tag.cloud';
 
-    public static $PAGE_TAGLIST = 'taglist';
+    public static $PAGE_TAGLIST = 'tag.list';
 
     public static $PAGE_DAILY = 'daily';
 
-    public static $PAGE_FEED_ATOM = 'atom';
+    public static $PAGE_FEED_ATOM = 'feed.atom';
 
-    public static $PAGE_FEED_RSS = 'rss';
+    public static $PAGE_FEED_RSS = 'feed.rss';
 
     public static $PAGE_TOOLS = 'tools';
 
@@ -37,7 +37,7 @@ class LegacyRouter
 
     public static $PAGE_ADDLINK = 'addlink';
 
-    public static $PAGE_EDITLINK = 'edit_link';
+    public static $PAGE_EDITLINK = 'editlink';
 
     public static $PAGE_DELETELINK = 'delete_link';
 
@@ -60,128 +60,4 @@ class LegacyRouter
     public static $PAGE_THUMBS_UPDATE = 'thumbs_update';
 
     public static $GET_TOKEN = 'token';
-
-    /**
-     * Reproducing renderPage() if hell, to avoid regression.
-     *
-     * This highlights how bad this needs to be rewrite,
-     * but let's focus on plugins for now.
-     *
-     * @param string $query    $_SERVER['QUERY_STRING'].
-     * @param array  $get      $_SERVER['GET'].
-     * @param bool   $loggedIn true if authenticated user.
-     *
-     * @return string page found.
-     */
-    public static function findPage($query, $get, $loggedIn)
-    {
-        $loggedIn = ($loggedIn === true) ? true : false;
-
-        if (empty($query) && !isset($get['edit_link']) && !isset($get['post'])) {
-            return self::$PAGE_LINKLIST;
-        }
-
-        if (startsWith($query, 'do=' . self::$PAGE_LOGIN) && $loggedIn === false) {
-            return self::$PAGE_LOGIN;
-        }
-
-        if (startsWith($query, 'do=' . self::$PAGE_PICWALL)) {
-            return self::$PAGE_PICWALL;
-        }
-
-        if (startsWith($query, 'do=' . self::$PAGE_TAGCLOUD)) {
-            return self::$PAGE_TAGCLOUD;
-        }
-
-        if (startsWith($query, 'do=' . self::$PAGE_TAGLIST)) {
-            return self::$PAGE_TAGLIST;
-        }
-
-        if (startsWith($query, 'do=' . self::$PAGE_OPENSEARCH)) {
-            return self::$PAGE_OPENSEARCH;
-        }
-
-        if (startsWith($query, 'do=' . self::$PAGE_DAILY)) {
-            return self::$PAGE_DAILY;
-        }
-
-        if (startsWith($query, 'do=' . self::$PAGE_FEED_ATOM)) {
-            return self::$PAGE_FEED_ATOM;
-        }
-
-        if (startsWith($query, 'do=' . self::$PAGE_FEED_RSS)) {
-            return self::$PAGE_FEED_RSS;
-        }
-
-        if (startsWith($query, 'do=' . self::$PAGE_THUMBS_UPDATE)) {
-            return self::$PAGE_THUMBS_UPDATE;
-        }
-
-        if (startsWith($query, 'do=' . self::$AJAX_THUMB_UPDATE)) {
-            return self::$AJAX_THUMB_UPDATE;
-        }
-
-        // At this point, only loggedin pages.
-        if (!$loggedIn) {
-            return self::$PAGE_LINKLIST;
-        }
-
-        if (startsWith($query, 'do=' . self::$PAGE_TOOLS)) {
-            return self::$PAGE_TOOLS;
-        }
-
-        if (startsWith($query, 'do=' . self::$PAGE_CHANGEPASSWORD)) {
-            return self::$PAGE_CHANGEPASSWORD;
-        }
-
-        if (startsWith($query, 'do=' . self::$PAGE_CONFIGURE)) {
-            return self::$PAGE_CONFIGURE;
-        }
-
-        if (startsWith($query, 'do=' . self::$PAGE_CHANGETAG)) {
-            return self::$PAGE_CHANGETAG;
-        }
-
-        if (startsWith($query, 'do=' . self::$PAGE_ADDLINK)) {
-            return self::$PAGE_ADDLINK;
-        }
-
-        if (isset($get['edit_link']) || isset($get['post'])) {
-            return self::$PAGE_EDITLINK;
-        }
-
-        if (isset($get['delete_link'])) {
-            return self::$PAGE_DELETELINK;
-        }
-
-        if (isset($get[self::$PAGE_CHANGE_VISIBILITY])) {
-            return self::$PAGE_CHANGE_VISIBILITY;
-        }
-
-        if (startsWith($query, 'do=' . self::$PAGE_PINLINK)) {
-            return self::$PAGE_PINLINK;
-        }
-
-        if (startsWith($query, 'do=' . self::$PAGE_EXPORT)) {
-            return self::$PAGE_EXPORT;
-        }
-
-        if (startsWith($query, 'do=' . self::$PAGE_IMPORT)) {
-            return self::$PAGE_IMPORT;
-        }
-
-        if (startsWith($query, 'do=' . self::$PAGE_PLUGINSADMIN)) {
-            return self::$PAGE_PLUGINSADMIN;
-        }
-
-        if (startsWith($query, 'do=' . self::$PAGE_SAVE_PLUGINSADMIN)) {
-            return self::$PAGE_SAVE_PLUGINSADMIN;
-        }
-
-        if (startsWith($query, 'do=' . self::$GET_TOKEN)) {
-            return self::$GET_TOKEN;
-        }
-
-        return self::$PAGE_LINKLIST;
-    }
 }
index 7a7166732392a5726227bd33d769f0dd8abbc96e..c52e3b76143530343f5da67ce32e9f74a805d236 100644 (file)
@@ -149,6 +149,8 @@ class PageBuilder
 
         $this->tpl->assign('formatter', $this->conf->get('formatter', 'default'));
 
+        $this->tpl->assign('links_per_page', $this->session['LINKS_PER_PAGE']);
+
         // To be removed with a proper theme configuration.
         $this->tpl->assign('conf', $this->conf);
     }
index 0f29799d148d8f864ff009ef2f7034aa5bbf07c3..2793882349ad9fd1503eef0bf5baf5681f9f2b0f 100644 (file)
@@ -25,16 +25,18 @@ function findParent(element, tagName, attributes) {
 /**
  * Ajax request to refresh the CSRF token.
  */
-function refreshToken(basePath) {
-  console.log('refresh');
+function refreshToken(basePath, callback) {
   const xhr = new XMLHttpRequest();
   xhr.open('GET', `${basePath}/admin/token`);
   xhr.onload = () => {
     const elements = document.querySelectorAll('input[name="token"]');
     [...elements].forEach((element) => {
-      console.log(element);
       element.setAttribute('value', xhr.responseText);
     });
+
+    if (callback) {
+      callback(xhr.response);
+    }
   };
   xhr.send();
 }
@@ -622,4 +624,15 @@ function init(description) {
   [...autocompleteFields].forEach((autocompleteField) => {
     awesomepletes.push(createAwesompleteInstance(autocompleteField));
   });
+
+  const exportForm = document.querySelector('#exportform');
+  if (exportForm != null) {
+    exportForm.addEventListener('submit', (event) => {
+      event.preventDefault();
+
+      refreshToken(basePath, () => {
+        event.target.submit();
+      });
+    });
+  }
 })();
index 759dff29828f9bce824d7f5f9e185a23c6b70458..7ab09d3f2e313657f6682bf211b7d9462c6a88e7 100644 (file)
@@ -616,6 +616,11 @@ body,
     padding: 5px;
     text-decoration: none;
     color: $dark-grey;
+
+    &.selected {
+      background: var(--main-color);
+      color: $white;
+     }
   }
 
   input {
index f3d9b51eb2271002df8c617636dab110b011401d..dc2b287280b41593854aa31705a7a78d436b2f5c 100644 (file)
@@ -21,7 +21,7 @@
     "eslint-plugin-import": "^2.8.0",
     "extract-text-webpack-plugin": "^3.0.2",
     "file-loader": "^1.1.6",
-    "node-sass": "^4.12.0",
+    "node-sass": "^4.13.1",
     "sass-lint": "^1.12.1",
     "sass-loader": "^6.0.6",
     "style-loader": "^0.19.1",
index 1928cc9f49b527e8aadddf64ed9796d9628bacc7..e1fd5cfbdb19daf547519af2d7f41482c88f7b96 100644 (file)
@@ -15,6 +15,8 @@ const DEFAULT_COLORS_PLACEHOLDERS = [
     'DEFAULT_COLORS_DARK_MAIN',
 ];
 
+const DEFAULT_COLORS_CSS_FILE = '/default_colors/default_colors.css';
+
 /**
  * Display an error if the plugin is active a no color is configured.
  *
@@ -24,58 +26,62 @@ const DEFAULT_COLORS_PLACEHOLDERS = [
  */
 function default_colors_init($conf)
 {
-    $params = '';
+    $params = [];
     foreach (DEFAULT_COLORS_PLACEHOLDERS as $placeholder) {
-        $params .= trim($conf->get('plugins.'. $placeholder, ''));
+        $value = trim($conf->get('plugins.'. $placeholder, ''));
+        if (strlen($value) > 0) {
+            $params[$placeholder] = $value;
+        }
     }
 
     if (empty($params)) {
         $error = t('Default colors plugin error: '.
             'This plugin is active and no custom color is configured.');
-        return array($error);
+        return [$error];
+    }
+
+    // Colors are defined but the custom CSS file does not exist -> generate it
+    if (!file_exists(PluginManager::$PLUGINS_PATH . DEFAULT_COLORS_CSS_FILE)) {
+        default_colors_generate_css_file($params);
     }
 }
 
 /**
- * When plugin parameters are saved, we regenerate the custom CSS file with provided settings.
+ * When linklist is displayed, include default_colors CSS file.
  *
- * @param array $data $_POST array
+ * @param array $data - header data.
  *
- * @return array Updated $_POST array
+ * @return mixed - header data with default_colors CSS file added.
  */
-function hook_default_colors_save_plugin_parameters($data)
+function hook_default_colors_render_includes($data)
 {
     $file = PluginManager::$PLUGINS_PATH . '/default_colors/default_colors.css';
-    $template = file_get_contents(PluginManager::$PLUGINS_PATH . '/default_colors/default_colors.css.template');
-    $content = '';
-    foreach (DEFAULT_COLORS_PLACEHOLDERS as $rule) {
-        $content .= ! empty($data[$rule])
-            ? default_colors_format_css_rule($data, $rule) .';'. PHP_EOL
-            : '';
-    }
-
-    if (! empty($content)) {
-        file_put_contents($file, sprintf($template, $content));
+    if (file_exists($file )) {
+        $data['css_files'][] = $file ;
     }
 
     return $data;
 }
 
 /**
- * When linklist is displayed, include default_colors CSS file.
- *
- * @param array $data - header data.
+ * Regenerate the custom CSS file with provided settings.
  *
- * @return mixed - header data with default_colors CSS file added.
+ * @param array $params Plugin configuration (CSS rules)
  */
-function hook_default_colors_render_includes($data)
+function default_colors_generate_css_file($params): void
 {
     $file = PluginManager::$PLUGINS_PATH . '/default_colors/default_colors.css';
-    if (file_exists($file )) {
-        $data['css_files'][] = $file ;
+    $template = file_get_contents(PluginManager::$PLUGINS_PATH . '/default_colors/default_colors.css.template');
+    $content = '';
+    foreach (DEFAULT_COLORS_PLACEHOLDERS as $rule) {
+        $content .= !empty($params[$rule])
+            ? default_colors_format_css_rule($params, $rule) .';'. PHP_EOL
+            : '';
     }
 
-    return $data;
+    if (! empty($content)) {
+        file_put_contents($file, sprintf($template, $content));
+    }
 }
 
 /**
index 3b5dae344dd63c3b688fc2d40ee8ff2af99e8f09..56ae47b30ad29b9ff46e085108b7e06c8638d61b 100644 (file)
@@ -42,7 +42,7 @@ function hook_qrcode_render_linklist($data)
 function hook_qrcode_render_footer($data)
 {
     if ($data['_PAGE_'] == TemplatePage::LINKLIST) {
-        $data['js_files'][] =  PluginManager::$PLUGINS_PATH . '/qrcode/shaarli-qrcode.js';
+        $data['js_files'][] =  ($data['_BASE_PATH_'] ?? '') . '/' . PluginManager::$PLUGINS_PATH . '/qrcode/shaarli-qrcode.js';
     }
 
     return $data;
@@ -58,7 +58,7 @@ function hook_qrcode_render_footer($data)
 function hook_qrcode_render_includes($data)
 {
     if ($data['_PAGE_'] == TemplatePage::LINKLIST) {
-        $data['css_files'][] = PluginManager::$PLUGINS_PATH . '/qrcode/qrcode.css';
+        $data['css_files'][] = ($data['_BASE_PATH_'] ?? '') . '/' . PluginManager::$PLUGINS_PATH . '/qrcode/qrcode.css';
     }
 
     return $data;
index 5c2aaedb30f131f9689c14afd03300b459a7d0e2..fe37d5f23a08068ddb2e8e91f77c872225173deb 100644 (file)
@@ -87,7 +87,7 @@ class FeedBuilderTest extends \PHPUnit\Framework\TestCase
         $this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links']));
 
         // Test first not pinned link (note link)
-        $link = $data['links'][array_keys($data['links'])[2]];
+        $link = $data['links'][array_keys($data['links'])[0]];
         $this->assertEquals(41, $link['id']);
         $this->assertEquals(DateTime::createFromFormat(Bookmark::LINK_DATE_FORMAT, '20150310_114651'), $link['created']);
         $this->assertEquals('http://host.tld/shaare/WDWyig', $link['guid']);
@@ -128,7 +128,7 @@ class FeedBuilderTest extends \PHPUnit\Framework\TestCase
         $data = $feedBuilder->buildData(FeedBuilder::$FEED_ATOM, null);
         $this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links']));
         $this->assertRegExp('/2016-08-03T09:30:33\+\d{2}:\d{2}/', $data['last_update']);
-        $link = $data['links'][array_keys($data['links'])[2]];
+        $link = $data['links'][array_keys($data['links'])[0]];
         $this->assertRegExp('/2015-03-10T11:46:51\+\d{2}:\d{2}/', $link['pub_iso_date']);
         $this->assertRegExp('/2016-08-03T09:30:33\+\d{2}:\d{2}/', $data['links'][8]['up_iso_date']);
     }
@@ -173,7 +173,7 @@ class FeedBuilderTest extends \PHPUnit\Framework\TestCase
         $feedBuilder->setLocale(self::$LOCALE);
         $data = $feedBuilder->buildData(FeedBuilder::$FEED_ATOM, $criteria);
         $this->assertEquals(3, count($data['links']));
-        $link = $data['links'][array_keys($data['links'])[2]];
+        $link = $data['links'][array_keys($data['links'])[0]];
         $this->assertEquals(41, $link['id']);
         $this->assertEquals(DateTime::createFromFormat(Bookmark::LINK_DATE_FORMAT, '20150310_114651'), $link['created']);
     }
@@ -195,7 +195,7 @@ class FeedBuilderTest extends \PHPUnit\Framework\TestCase
         $this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links']));
         $this->assertTrue($data['usepermalinks']);
         // First link is a permalink
-        $link = $data['links'][array_keys($data['links'])[2]];
+        $link = $data['links'][array_keys($data['links'])[0]];
         $this->assertEquals(41, $link['id']);
         $this->assertEquals(DateTime::createFromFormat(Bookmark::LINK_DATE_FORMAT, '20150310_114651'), $link['created']);
         $this->assertEquals('http://host.tld/shaare/WDWyig', $link['guid']);
@@ -203,7 +203,7 @@ class FeedBuilderTest extends \PHPUnit\Framework\TestCase
         $this->assertContains('Direct link', $link['description']);
         $this->assertContains('http://host.tld/shaare/WDWyig', $link['description']);
         // Second link is a direct link
-        $link = $data['links'][array_keys($data['links'])[3]];
+        $link = $data['links'][array_keys($data['links'])[1]];
         $this->assertEquals(8, $link['id']);
         $this->assertEquals(DateTime::createFromFormat(Bookmark::LINK_DATE_FORMAT, '20150310_114633'), $link['created']);
         $this->assertEquals('http://host.tld/shaare/RttfEw', $link['guid']);
@@ -270,7 +270,7 @@ class FeedBuilderTest extends \PHPUnit\Framework\TestCase
         );
 
         // Test first link (note link)
-        $link = $data['links'][array_keys($data['links'])[2]];
+        $link = $data['links'][array_keys($data['links'])[0]];
         $this->assertEquals('http://host.tld:8080/~user/shaarli/shaare/WDWyig', $link['guid']);
         $this->assertEquals('http://host.tld:8080/~user/shaarli/shaare/WDWyig', $link['url']);
         $this->assertContains('http://host.tld:8080/~user/shaarli/./add-tag/hashtag', $link['description']);
index f2f84bacabde367edfcdbe61f8ea2f9fb8ce2447..612f20f12588a62c03060a27a0aa7da00298b8b2 100644 (file)
@@ -62,7 +62,7 @@ class ConfigureControllerTest extends TestCase
         static::assertSame('privacy.hide_public_links', $assignedVariables['hide_public_links']);
         static::assertSame('api.enabled', $assignedVariables['api_enabled']);
         static::assertSame('api.secret', $assignedVariables['api_secret']);
-        static::assertCount(4, $assignedVariables['languages']);
+        static::assertCount(5, $assignedVariables['languages']);
         static::assertArrayHasKey('gd_enabled', $assignedVariables);
         static::assertSame('thumbnails.mode', $assignedVariables['thumbnails_mode']);
     }
index fb417e2a2b152f1a6c52e166c275afda7ab1e190..0a6b577f4dd2f3d19ce1383a641852f2fd6766f1 100644 (file)
@@ -52,7 +52,7 @@ class FeedControllerTest extends TestCase
                 static::assertSame('data', $data['content']);
 
                 static::assertArrayHasKey('loggedin', $param);
-                static::assertSame('rss', $param['target']);
+                static::assertSame('feed.rss', $param['target']);
             })
         ;
 
@@ -91,7 +91,7 @@ class FeedControllerTest extends TestCase
                 static::assertSame('data', $data['content']);
 
                 static::assertArrayHasKey('loggedin', $param);
-                static::assertSame('atom', $param['target']);
+                static::assertSame('feed.atom', $param['target']);
             })
         ;
 
@@ -131,7 +131,7 @@ class FeedControllerTest extends TestCase
                 static::assertSame('data', $data['content']);
 
                 static::assertArrayHasKey('loggedin', $param);
-                static::assertSame('atom', $param['target']);
+                static::assertSame('feed.atom', $param['target']);
             })
         ;
 
index 759a5b2a5d6269c133bed96e53cf1c886e23a80a..4e52f3e186597375b351d575c1067b9a7dbd7573 100644 (file)
@@ -66,11 +66,11 @@ class LegacyControllerTest extends TestCase
     {
         return [
             ['post', [], '/admin/shaare', true],
-            ['post', [], '/login', false],
+            ['post', [], '/login?returnurl=/subfolder/admin/shaare', false],
             ['post', ['title' => 'test'], '/admin/shaare?title=test', true],
-            ['post', ['title' => 'test'], '/login?title=test', false],
+            ['post', ['title' => 'test'], '/login?returnurl=/subfolder/admin/shaare?title=test', false],
             ['addlink', [], '/admin/add-shaare', true],
-            ['addlink', [], '/login', false],
+            ['addlink', [], '/login?returnurl=/subfolder/admin/add-shaare', false],
             ['login', [], '/login', true],
             ['login', [], '/login', false],
             ['logout', [], '/admin/logout', true],
@@ -94,6 +94,8 @@ class LegacyControllerTest extends TestCase
             ['opensearch', [], '/open-search', true],
             ['dailyrss', [], '/daily-rss', false],
             ['dailyrss', [], '/daily-rss', true],
+            ['configure', [], '/login?returnurl=/subfolder/admin/configure', false],
+            ['configure', [], '/admin/configure', true],
         ];
     }
 }
diff --git a/tests/legacy/LegacyRouterTest.php b/tests/legacy/LegacyRouterTest.php
deleted file mode 100644 (file)
index c2019ca..0000000
+++ /dev/null
@@ -1,512 +0,0 @@
-<?php
-
-namespace Shaarli\Legacy;
-
-use PHPUnit\Framework\TestCase;
-
-/**
- * Unit tests for Router
- */
-class LegacyRouterTest extends TestCase
-{
-    /**
-     * Test findPage: login page output.
-     * Valid: page should be return.
-     *
-     * @return void
-     */
-    public function testFindPageLoginValid()
-    {
-        $this->assertEquals(
-            LegacyRouter::$PAGE_LOGIN,
-            LegacyRouter::findPage('do=login', array(), false)
-        );
-
-        $this->assertEquals(
-            LegacyRouter::$PAGE_LOGIN,
-            LegacyRouter::findPage('do=login', array(), 1)
-        );
-
-        $this->assertEquals(
-            LegacyRouter::$PAGE_LOGIN,
-            LegacyRouter::findPage('do=login&stuff', array(), false)
-        );
-    }
-
-    /**
-     * Test findPage: login page output.
-     * Invalid: page shouldn't be return.
-     *
-     * @return void
-     */
-    public function testFindPageLoginInvalid()
-    {
-        $this->assertNotEquals(
-            LegacyRouter::$PAGE_LOGIN,
-            LegacyRouter::findPage('do=login', array(), true)
-        );
-
-        $this->assertNotEquals(
-            LegacyRouter::$PAGE_LOGIN,
-            LegacyRouter::findPage('do=other', array(), false)
-        );
-    }
-
-    /**
-     * Test findPage: picwall page output.
-     * Valid: page should be return.
-     *
-     * @return void
-     */
-    public function testFindPagePicwallValid()
-    {
-        $this->assertEquals(
-            LegacyRouter::$PAGE_PICWALL,
-            LegacyRouter::findPage('do=picwall', array(), false)
-        );
-
-        $this->assertEquals(
-            LegacyRouter::$PAGE_PICWALL,
-            LegacyRouter::findPage('do=picwall', array(), true)
-        );
-    }
-
-    /**
-     * Test findPage: picwall page output.
-     * Invalid: page shouldn't be return.
-     *
-     * @return void
-     */
-    public function testFindPagePicwallInvalid()
-    {
-        $this->assertEquals(
-            LegacyRouter::$PAGE_PICWALL,
-            LegacyRouter::findPage('do=picwall&stuff', array(), false)
-        );
-
-        $this->assertNotEquals(
-            LegacyRouter::$PAGE_PICWALL,
-            LegacyRouter::findPage('do=other', array(), false)
-        );
-    }
-
-    /**
-     * Test findPage: tagcloud page output.
-     * Valid: page should be return.
-     *
-     * @return void
-     */
-    public function testFindPageTagcloudValid()
-    {
-        $this->assertEquals(
-            LegacyRouter::$PAGE_TAGCLOUD,
-            LegacyRouter::findPage('do=tagcloud', array(), false)
-        );
-
-        $this->assertEquals(
-            LegacyRouter::$PAGE_TAGCLOUD,
-            LegacyRouter::findPage('do=tagcloud', array(), true)
-        );
-
-        $this->assertEquals(
-            LegacyRouter::$PAGE_TAGCLOUD,
-            LegacyRouter::findPage('do=tagcloud&stuff', array(), false)
-        );
-    }
-
-    /**
-     * Test findPage: tagcloud page output.
-     * Invalid: page shouldn't be return.
-     *
-     * @return void
-     */
-    public function testFindPageTagcloudInvalid()
-    {
-        $this->assertNotEquals(
-            LegacyRouter::$PAGE_TAGCLOUD,
-            LegacyRouter::findPage('do=other', array(), false)
-        );
-    }
-
-    /**
-     * Test findPage: linklist page output.
-     * Valid: page should be return.
-     *
-     * @return void
-     */
-    public function testFindPageLinklistValid()
-    {
-        $this->assertEquals(
-            LegacyRouter::$PAGE_LINKLIST,
-            LegacyRouter::findPage('', array(), true)
-        );
-
-        $this->assertEquals(
-            LegacyRouter::$PAGE_LINKLIST,
-            LegacyRouter::findPage('whatever', array(), true)
-        );
-
-        $this->assertEquals(
-            LegacyRouter::$PAGE_LINKLIST,
-            LegacyRouter::findPage('whatever', array(), false)
-        );
-
-        $this->assertEquals(
-            LegacyRouter::$PAGE_LINKLIST,
-            LegacyRouter::findPage('do=tools', array(), false)
-        );
-    }
-
-    /**
-     * Test findPage: tools page output.
-     * Valid: page should be return.
-     *
-     * @return void
-     */
-    public function testFindPageToolsValid()
-    {
-        $this->assertEquals(
-            LegacyRouter::$PAGE_TOOLS,
-            LegacyRouter::findPage('do=tools', array(), true)
-        );
-
-        $this->assertEquals(
-            LegacyRouter::$PAGE_TOOLS,
-            LegacyRouter::findPage('do=tools&stuff', array(), true)
-        );
-    }
-
-    /**
-     * Test findPage: tools page output.
-     * Invalid: page shouldn't be return.
-     *
-     * @return void
-     */
-    public function testFindPageToolsInvalid()
-    {
-        $this->assertNotEquals(
-            LegacyRouter::$PAGE_TOOLS,
-            LegacyRouter::findPage('do=tools', array(), 1)
-        );
-
-        $this->assertNotEquals(
-            LegacyRouter::$PAGE_TOOLS,
-            LegacyRouter::findPage('do=tools', array(), false)
-        );
-
-        $this->assertNotEquals(
-            LegacyRouter::$PAGE_TOOLS,
-            LegacyRouter::findPage('do=other', array(), true)
-        );
-    }
-
-    /**
-     * Test findPage: changepasswd page output.
-     * Valid: page should be return.
-     *
-     * @return void
-     */
-    public function testFindPageChangepasswdValid()
-    {
-        $this->assertEquals(
-            LegacyRouter::$PAGE_CHANGEPASSWORD,
-            LegacyRouter::findPage('do=changepasswd', array(), true)
-        );
-        $this->assertEquals(
-            LegacyRouter::$PAGE_CHANGEPASSWORD,
-            LegacyRouter::findPage('do=changepasswd&stuff', array(), true)
-        );
-    }
-
-    /**
-     * Test findPage: changepasswd page output.
-     * Invalid: page shouldn't be return.
-     *
-     * @return void
-     */
-    public function testFindPageChangepasswdInvalid()
-    {
-        $this->assertNotEquals(
-            LegacyRouter::$PAGE_CHANGEPASSWORD,
-            LegacyRouter::findPage('do=changepasswd', array(), 1)
-        );
-
-        $this->assertNotEquals(
-            LegacyRouter::$PAGE_CHANGEPASSWORD,
-            LegacyRouter::findPage('do=changepasswd', array(), false)
-        );
-
-        $this->assertNotEquals(
-            LegacyRouter::$PAGE_CHANGEPASSWORD,
-            LegacyRouter::findPage('do=other', array(), true)
-        );
-    }
-    /**
-     * Test findPage: configure page output.
-     * Valid: page should be return.
-     *
-     * @return void
-     */
-    public function testFindPageConfigureValid()
-    {
-        $this->assertEquals(
-            LegacyRouter::$PAGE_CONFIGURE,
-            LegacyRouter::findPage('do=configure', array(), true)
-        );
-
-        $this->assertEquals(
-            LegacyRouter::$PAGE_CONFIGURE,
-            LegacyRouter::findPage('do=configure&stuff', array(), true)
-        );
-    }
-
-    /**
-     * Test findPage: configure page output.
-     * Invalid: page shouldn't be return.
-     *
-     * @return void
-     */
-    public function testFindPageConfigureInvalid()
-    {
-        $this->assertNotEquals(
-            LegacyRouter::$PAGE_CONFIGURE,
-            LegacyRouter::findPage('do=configure', array(), 1)
-        );
-
-        $this->assertNotEquals(
-            LegacyRouter::$PAGE_CONFIGURE,
-            LegacyRouter::findPage('do=configure', array(), false)
-        );
-
-        $this->assertNotEquals(
-            LegacyRouter::$PAGE_CONFIGURE,
-            LegacyRouter::findPage('do=other', array(), true)
-        );
-    }
-
-    /**
-     * Test findPage: changetag page output.
-     * Valid: page should be return.
-     *
-     * @return void
-     */
-    public function testFindPageChangetagValid()
-    {
-        $this->assertEquals(
-            LegacyRouter::$PAGE_CHANGETAG,
-            LegacyRouter::findPage('do=changetag', array(), true)
-        );
-
-        $this->assertEquals(
-            LegacyRouter::$PAGE_CHANGETAG,
-            LegacyRouter::findPage('do=changetag&stuff', array(), true)
-        );
-    }
-
-    /**
-     * Test findPage: changetag page output.
-     * Invalid: page shouldn't be return.
-     *
-     * @return void
-     */
-    public function testFindPageChangetagInvalid()
-    {
-        $this->assertNotEquals(
-            LegacyRouter::$PAGE_CHANGETAG,
-            LegacyRouter::findPage('do=changetag', array(), 1)
-        );
-
-        $this->assertNotEquals(
-            LegacyRouter::$PAGE_CHANGETAG,
-            LegacyRouter::findPage('do=changetag', array(), false)
-        );
-
-        $this->assertNotEquals(
-            LegacyRouter::$PAGE_CHANGETAG,
-            LegacyRouter::findPage('do=other', array(), true)
-        );
-    }
-
-    /**
-     * Test findPage: addlink page output.
-     * Valid: page should be return.
-     *
-     * @return void
-     */
-    public function testFindPageAddlinkValid()
-    {
-        $this->assertEquals(
-            LegacyRouter::$PAGE_ADDLINK,
-            LegacyRouter::findPage('do=addlink', array(), true)
-        );
-
-        $this->assertEquals(
-            LegacyRouter::$PAGE_ADDLINK,
-            LegacyRouter::findPage('do=addlink&stuff', array(), true)
-        );
-    }
-
-    /**
-     * Test findPage: addlink page output.
-     * Invalid: page shouldn't be return.
-     *
-     * @return void
-     */
-    public function testFindPageAddlinkInvalid()
-    {
-        $this->assertNotEquals(
-            LegacyRouter::$PAGE_ADDLINK,
-            LegacyRouter::findPage('do=addlink', array(), 1)
-        );
-
-        $this->assertNotEquals(
-            LegacyRouter::$PAGE_ADDLINK,
-            LegacyRouter::findPage('do=addlink', array(), false)
-        );
-
-        $this->assertNotEquals(
-            LegacyRouter::$PAGE_ADDLINK,
-            LegacyRouter::findPage('do=other', array(), true)
-        );
-    }
-
-    /**
-     * Test findPage: export page output.
-     * Valid: page should be return.
-     *
-     * @return void
-     */
-    public function testFindPageExportValid()
-    {
-        $this->assertEquals(
-            LegacyRouter::$PAGE_EXPORT,
-            LegacyRouter::findPage('do=export', array(), true)
-        );
-
-        $this->assertEquals(
-            LegacyRouter::$PAGE_EXPORT,
-            LegacyRouter::findPage('do=export&stuff', array(), true)
-        );
-    }
-
-    /**
-     * Test findPage: export page output.
-     * Invalid: page shouldn't be return.
-     *
-     * @return void
-     */
-    public function testFindPageExportInvalid()
-    {
-        $this->assertNotEquals(
-            LegacyRouter::$PAGE_EXPORT,
-            LegacyRouter::findPage('do=export', array(), 1)
-        );
-
-        $this->assertNotEquals(
-            LegacyRouter::$PAGE_EXPORT,
-            LegacyRouter::findPage('do=export', array(), false)
-        );
-
-        $this->assertNotEquals(
-            LegacyRouter::$PAGE_EXPORT,
-            LegacyRouter::findPage('do=other', array(), true)
-        );
-    }
-
-    /**
-     * Test findPage: import page output.
-     * Valid: page should be return.
-     *
-     * @return void
-     */
-    public function testFindPageImportValid()
-    {
-        $this->assertEquals(
-            LegacyRouter::$PAGE_IMPORT,
-            LegacyRouter::findPage('do=import', array(), true)
-        );
-
-        $this->assertEquals(
-            LegacyRouter::$PAGE_IMPORT,
-            LegacyRouter::findPage('do=import&stuff', array(), true)
-        );
-    }
-
-    /**
-     * Test findPage: import page output.
-     * Invalid: page shouldn't be return.
-     *
-     * @return void
-     */
-    public function testFindPageImportInvalid()
-    {
-        $this->assertNotEquals(
-            LegacyRouter::$PAGE_IMPORT,
-            LegacyRouter::findPage('do=import', array(), 1)
-        );
-
-        $this->assertNotEquals(
-            LegacyRouter::$PAGE_IMPORT,
-            LegacyRouter::findPage('do=import', array(), false)
-        );
-
-        $this->assertNotEquals(
-            LegacyRouter::$PAGE_IMPORT,
-            LegacyRouter::findPage('do=other', array(), true)
-        );
-    }
-
-    /**
-     * Test findPage: editlink page output.
-     * Valid: page should be return.
-     *
-     * @return void
-     */
-    public function testFindPageEditlinkValid()
-    {
-        $this->assertEquals(
-            LegacyRouter::$PAGE_EDITLINK,
-            LegacyRouter::findPage('whatever', array('edit_link' => 1), true)
-        );
-
-        $this->assertEquals(
-            LegacyRouter::$PAGE_EDITLINK,
-            LegacyRouter::findPage('', array('edit_link' => 1), true)
-        );
-
-
-        $this->assertEquals(
-            LegacyRouter::$PAGE_EDITLINK,
-            LegacyRouter::findPage('whatever', array('post' => 1), true)
-        );
-
-        $this->assertEquals(
-            LegacyRouter::$PAGE_EDITLINK,
-            LegacyRouter::findPage('whatever', array('post' => 1, 'edit_link' => 1), true)
-        );
-    }
-
-    /**
-     * Test findPage: editlink page output.
-     * Invalid: page shouldn't be return.
-     *
-     * @return void
-     */
-    public function testFindPageEditlinkInvalid()
-    {
-        $this->assertNotEquals(
-            LegacyRouter::$PAGE_EDITLINK,
-            LegacyRouter::findPage('whatever', array('edit_link' => 1), false)
-        );
-
-        $this->assertNotEquals(
-            LegacyRouter::$PAGE_EDITLINK,
-            LegacyRouter::findPage('whatever', array('edit_link' => 1), 1)
-        );
-
-        $this->assertNotEquals(
-            LegacyRouter::$PAGE_EDITLINK,
-            LegacyRouter::findPage('whatever', array(), true)
-        );
-    }
-}
index b9951cca6cb7ce68b4e4cc2024cdce999c6894d0..9835dfa39ac7de4706d0f62b63cf86ed35f9d974 100644 (file)
@@ -2,7 +2,6 @@
 
 namespace Shaarli\Plugin\DefaultColors;
 
-use DateTime;
 use PHPUnit\Framework\TestCase;
 use Shaarli\Bookmark\LinkDB;
 use Shaarli\Config\ConfigManager;
@@ -57,6 +56,8 @@ class PluginDefaultColorsTest extends TestCase
         $conf->set('plugins.DEFAULT_COLORS_BACKGROUND', 'value');
         $errors = default_colors_init($conf);
         $this->assertEmpty($errors);
+
+        $this->assertFileExists($file = 'sandbox/default_colors/default_colors.css');
     }
 
     /**
@@ -72,9 +73,9 @@ class PluginDefaultColorsTest extends TestCase
     /**
      * Test the save plugin parameters hook with all colors specified.
      */
-    public function testSavePluginParametersAll()
+    public function testGenerateCssFile()
     {
-        $post = [
+        $params = [
             'other1' => true,
             'DEFAULT_COLORS_MAIN' => 'blue',
             'DEFAULT_COLORS_BACKGROUND' => 'pink',
@@ -82,7 +83,7 @@ class PluginDefaultColorsTest extends TestCase
             'DEFAULT_COLORS_DARK_MAIN' => 'green',
         ];
 
-        hook_default_colors_save_plugin_parameters($post);
+        default_colors_generate_css_file($params);
         $this->assertFileExists($file = 'sandbox/default_colors/default_colors.css');
         $content = file_get_contents($file);
         $expected = ':root {
@@ -98,16 +99,16 @@ class PluginDefaultColorsTest extends TestCase
     /**
      * Test the save plugin parameters hook with only one color specified.
      */
-    public function testSavePluginParametersSingle()
+    public function testGenerateCssFileSingle()
     {
-        $post = [
+        $params = [
             'other1' => true,
             'DEFAULT_COLORS_BACKGROUND' => 'pink',
             'other2' => ['yep'],
             'DEFAULT_COLORS_DARK_MAIN' => '',
         ];
 
-        hook_default_colors_save_plugin_parameters($post);
+        default_colors_generate_css_file($params);
         $this->assertFileExists($file = 'sandbox/default_colors/default_colors.css');
         $content = file_get_contents($file);
         $expected = ':root {
@@ -121,9 +122,9 @@ class PluginDefaultColorsTest extends TestCase
     /**
      * Test the save plugin parameters hook with no color specified.
      */
-    public function testSavePluginParametersNone()
+    public function testGenerateCssFileNone()
     {
-        hook_default_colors_save_plugin_parameters([]);
+        default_colors_generate_css_file([]);
         $this->assertFileNotExists($file = 'sandbox/default_colors/default_colors.css');
     }
 
index c7617b228b5c13be9a140865a9c8e0dd5c7be784..2475f5fdbe2eacf9db05b170534a4a4e44892ecb 100644 (file)
                     <i class="fa fa-trash" aria-hidden="true"></i>
                   </a>
                   &middot;
-                  <a href="{$base_path}/admin/shaare/{$value.id}" aria-label="{$strEdit}" title="{$strEdit}"><i class="fa fa-pencil-square-o edit-link" aria-hidden="true"></i></a>
+                  <a href="{$base_path}/admin/shaare/{$value.id}" aria-label="{$strEdit}" title="{$strEdit}">
+                    <i class="fa fa-pencil-square-o edit-link" aria-hidden="true"></i>
+                  </a>
+                  &middot;
+                  <a href="{$base_path}/admin/shaare/{$value.id}/pin?token={$token}"
+                     aria-label="{$strToggleSticky}"
+                     title="{$strToggleSticky}"
+                     class="pin-link {if="$value.sticky"}pinned-link{/if}"
+                  >
+                    <i class="fa fa-thumb-tack" aria-hidden="true"></i>
+                  </a>
                 {/if}
               </div>
             </div>
index 20853330749343622c8042a0c8294d2470062cda..aa637868eb94e2a91cb9e8a5af22011cb6bbc77f 100644 (file)
 
     <div class="linksperpage pure-u-1-3">
       <div class="pure-u-0 pure-u-lg-visible">{'Links per page'|t}</div>
-      <a href="{$base_path}/links-per-page?nb=20">20</a>
-      <a href="{$base_path}/links-per-page?nb=50">50</a>
-      <a href="{$base_path}/links-per-page?nb=100">100</a>
+      <a href="{$base_path}/links-per-page?nb=20"
+                       {if="$links_per_page == 20"}class="selected"{/if}>20</a>
+      <a href="{$base_path}/links-per-page?nb=50"
+                       {if="$links_per_page == 50"}class="selected"{/if}>50</a>
+      <a href="{$base_path}/links-per-page?nb=100"
+                       {if="$links_per_page == 100"}class="selected"{/if}>100</a>
       <form method="GET" class="pure-u-0 pure-u-lg-visible" action="{$base_path}/links-per-page">
-        <input type="text" name="nb" placeholder="133">
+        <input type="text" name="nb" placeholder="133"
+                       {if="$links_per_page != 20 && $links_per_page != 50 && $links_per_page != 100"}
+                               value="{$links_per_page}"{/if}>
       </form>
       <a href="#" class="filter-off fold-all pure-u-0 pure-u-lg-visible" aria-label="{'Fold all'|t}" title="{'Fold all'|t}">
         <i class="fa fa-chevron-up" aria-hidden="true"></i>
index df6479505770634460f8b5c5ddc6e12eba09f3af..a7ddcfd3dd176c29e6bd19800e339cfc69a6576d 100644 (file)
--- a/yarn.lock
+++ b/yarn.lock
@@ -3432,10 +3432,10 @@ lodash.uniq@^4.5.0:
   resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
   integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
 
-lodash@^4.0.0, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.3.0, lodash@~4.17.10:
-  version "4.17.19"
-  resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b"
-  integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==
+lodash@^4.0.0, lodash@^4.17.11, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.3.0, lodash@~4.17.10:
+  version "4.17.20"
+  resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52"
+  integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==
 
 longest@^1.0.1:
   version "1.0.1"
@@ -3787,10 +3787,10 @@ node-pre-gyp@^0.12.0:
     semver "^5.3.0"
     tar "^4"
 
-node-sass@^4.12.0:
-  version "4.12.0"
-  resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.12.0.tgz#0914f531932380114a30cc5fa4fa63233a25f017"
-  integrity sha512-A1Iv4oN+Iel6EPv77/HddXErL2a+gZ4uBeZUy+a8O35CFYTXhgA8MgLCWBtwpGZdCvTvQ9d+bQxX/QC36GDPpQ==
+node-sass@^4.13.1:
+  version "4.13.1"
+  resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.13.1.tgz#9db5689696bb2eec2c32b98bfea4c7a2e992d0a3"
+  integrity sha512-TTWFx+ZhyDx1Biiez2nB0L3YrCZ/8oHagaDalbuBSlqXgUPsdkUSzJsVxeDO9LtPB49+Fh3WQl3slABo6AotNw==
   dependencies:
     async-foreach "^0.1.3"
     chalk "^1.1.1"
@@ -3799,7 +3799,7 @@ node-sass@^4.12.0:
     get-stdin "^4.0.1"
     glob "^7.0.3"
     in-publish "^2.0.0"
-    lodash "^4.17.11"
+    lodash "^4.17.15"
     meow "^3.7.0"
     mkdirp "^0.5.1"
     nan "^2.13.2"