diff options
-rw-r--r-- | application/LinkDB.php | 3 | ||||
-rw-r--r-- | application/Router.php | 6 | ||||
-rw-r--r-- | application/Updater.php | 20 | ||||
-rw-r--r-- | assets/default/scss/shaarli.scss | 12 | ||||
-rw-r--r-- | index.php | 19 | ||||
-rw-r--r-- | tests/FeedBuilderTest.php | 18 | ||||
-rw-r--r-- | tests/LinkDBTest.php | 10 | ||||
-rw-r--r-- | tests/NetscapeBookmarkUtils/BookmarkExportTest.php | 4 | ||||
-rw-r--r-- | tests/Updater/UpdaterTest.php | 61 | ||||
-rw-r--r-- | tests/api/controllers/links/GetLinksTest.php | 21 | ||||
-rw-r--r-- | tests/utils/ReferenceLinkDB.php | 45 | ||||
-rw-r--r-- | tpl/default/linklist.html | 6 |
12 files changed, 199 insertions, 26 deletions
diff --git a/application/LinkDB.php b/application/LinkDB.php index cd0f2967..cdd68cfb 100644 --- a/application/LinkDB.php +++ b/application/LinkDB.php | |||
@@ -537,6 +537,9 @@ You use the community supported version of the original Shaarli project, by Seba | |||
537 | $order = $order === 'ASC' ? -1 : 1; | 537 | $order = $order === 'ASC' ? -1 : 1; |
538 | // Reorder array by dates. | 538 | // Reorder array by dates. |
539 | usort($this->links, function($a, $b) use ($order) { | 539 | usort($this->links, function($a, $b) use ($order) { |
540 | if (isset($a['sticky']) && isset($b['sticky']) && $a['sticky'] !== $b['sticky']) { | ||
541 | return $a['sticky'] ? -1 : 1; | ||
542 | } | ||
540 | return $a['created'] < $b['created'] ? 1 * $order : -1 * $order; | 543 | return $a['created'] < $b['created'] ? 1 * $order : -1 * $order; |
541 | }); | 544 | }); |
542 | 545 | ||
diff --git a/application/Router.php b/application/Router.php index bf86b884..beb3165b 100644 --- a/application/Router.php +++ b/application/Router.php | |||
@@ -37,6 +37,8 @@ class Router | |||
37 | 37 | ||
38 | public static $PAGE_DELETELINK = 'delete_link'; | 38 | public static $PAGE_DELETELINK = 'delete_link'; |
39 | 39 | ||
40 | public static $PAGE_PINLINK = 'pin'; | ||
41 | |||
40 | public static $PAGE_EXPORT = 'export'; | 42 | public static $PAGE_EXPORT = 'export'; |
41 | 43 | ||
42 | public static $PAGE_IMPORT = 'import'; | 44 | public static $PAGE_IMPORT = 'import'; |
@@ -146,6 +148,10 @@ class Router | |||
146 | return self::$PAGE_DELETELINK; | 148 | return self::$PAGE_DELETELINK; |
147 | } | 149 | } |
148 | 150 | ||
151 | if (startsWith($query, 'do='. self::$PAGE_PINLINK)) { | ||
152 | return self::$PAGE_PINLINK; | ||
153 | } | ||
154 | |||
149 | if (startsWith($query, 'do='. self::$PAGE_EXPORT)) { | 155 | if (startsWith($query, 'do='. self::$PAGE_EXPORT)) { |
150 | return self::$PAGE_EXPORT; | 156 | return self::$PAGE_EXPORT; |
151 | } | 157 | } |
diff --git a/application/Updater.php b/application/Updater.php index 480bff82..5dde47cb 100644 --- a/application/Updater.php +++ b/application/Updater.php | |||
@@ -517,6 +517,26 @@ class Updater | |||
517 | 517 | ||
518 | return true; | 518 | return true; |
519 | } | 519 | } |
520 | |||
521 | /** | ||
522 | * Set sticky = false on all links | ||
523 | * | ||
524 | * @return bool true if the update is successful, false otherwise. | ||
525 | */ | ||
526 | public function updateMethodSetSticky() | ||
527 | { | ||
528 | foreach ($this->linkDB as $key => $link) { | ||
529 | if (isset($link['sticky'])) { | ||
530 | return true; | ||
531 | } | ||
532 | $link['sticky'] = false; | ||
533 | $this->linkDB[$key] = $link; | ||
534 | } | ||
535 | |||
536 | $this->linkDB->save($this->conf->get('resource.page_cache')); | ||
537 | |||
538 | return true; | ||
539 | } | ||
520 | } | 540 | } |
521 | 541 | ||
522 | /** | 542 | /** |
diff --git a/assets/default/scss/shaarli.scss b/assets/default/scss/shaarli.scss index b8578ea6..037183dd 100644 --- a/assets/default/scss/shaarli.scss +++ b/assets/default/scss/shaarli.scss | |||
@@ -755,6 +755,14 @@ body, | |||
755 | font-size: 1.3em; | 755 | font-size: 1.3em; |
756 | } | 756 | } |
757 | 757 | ||
758 | .pin-link { | ||
759 | font-size: 1.3em; | ||
760 | } | ||
761 | |||
762 | .pinned-link { | ||
763 | color: #0b5ea6 !important; | ||
764 | } | ||
765 | |||
758 | .linklist-item-description { | 766 | .linklist-item-description { |
759 | position: relative; | 767 | position: relative; |
760 | padding: 0 10px; | 768 | padding: 0 10px; |
@@ -848,6 +856,10 @@ body, | |||
848 | margin: 0 7px; | 856 | margin: 0 7px; |
849 | } | 857 | } |
850 | 858 | ||
859 | .ctrl-delete { | ||
860 | margin: 0 7px 0 0; | ||
861 | } | ||
862 | |||
851 | // 64em -> lg | 863 | // 64em -> lg |
852 | @media screen and (max-width: 64em) { | 864 | @media screen and (max-width: 64em) { |
853 | .linklist-item-infos-url { | 865 | .linklist-item-infos-url { |
@@ -1353,6 +1353,25 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, | |||
1353 | exit; | 1353 | exit; |
1354 | } | 1354 | } |
1355 | 1355 | ||
1356 | if ($targetPage == Router::$PAGE_PINLINK) { | ||
1357 | if (! isset($_GET['id']) || empty($LINKSDB[$_GET['id']])) { | ||
1358 | // FIXME! Use a proper error system. | ||
1359 | $msg = t('Invalid link ID provided'); | ||
1360 | echo '<script>alert("'. $msg .'");document.location=\''. index_url($_SERVER) .'\';</script>'; | ||
1361 | exit; | ||
1362 | } | ||
1363 | if (! $sessionManager->checkToken($_GET['token'])) { | ||
1364 | die('Wrong token.'); | ||
1365 | } | ||
1366 | |||
1367 | $link = $LINKSDB[$_GET['id']]; | ||
1368 | $link['sticky'] = ! $link['sticky']; | ||
1369 | $LINKSDB[(int) $_GET['id']] = $link; | ||
1370 | $LINKSDB->save($conf->get('resource.page_cache')); | ||
1371 | header('Location: '.index_url($_SERVER)); | ||
1372 | exit; | ||
1373 | } | ||
1374 | |||
1356 | if ($targetPage == Router::$PAGE_EXPORT) { | 1375 | if ($targetPage == Router::$PAGE_EXPORT) { |
1357 | // Export links as a Netscape Bookmarks file | 1376 | // Export links as a Netscape Bookmarks file |
1358 | 1377 | ||
diff --git a/tests/FeedBuilderTest.php b/tests/FeedBuilderTest.php index a590306d..4ca58e5a 100644 --- a/tests/FeedBuilderTest.php +++ b/tests/FeedBuilderTest.php | |||
@@ -82,8 +82,8 @@ class FeedBuilderTest extends PHPUnit_Framework_TestCase | |||
82 | $this->assertFalse($data['usepermalinks']); | 82 | $this->assertFalse($data['usepermalinks']); |
83 | $this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links'])); | 83 | $this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links'])); |
84 | 84 | ||
85 | // Test first link (note link) | 85 | // Test first not pinned link (note link) |
86 | $link = reset($data['links']); | 86 | $link = $data['links'][array_keys($data['links'])[2]]; |
87 | $this->assertEquals(41, $link['id']); | 87 | $this->assertEquals(41, $link['id']); |
88 | $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20150310_114651'), $link['created']); | 88 | $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20150310_114651'), $link['created']); |
89 | $this->assertEquals('http://host.tld/?WDWyig', $link['guid']); | 89 | $this->assertEquals('http://host.tld/?WDWyig', $link['guid']); |
@@ -119,7 +119,7 @@ class FeedBuilderTest extends PHPUnit_Framework_TestCase | |||
119 | $data = $feedBuilder->buildData(); | 119 | $data = $feedBuilder->buildData(); |
120 | $this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links'])); | 120 | $this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links'])); |
121 | $this->assertRegExp('/2016-08-03T09:30:33\+\d{2}:\d{2}/', $data['last_update']); | 121 | $this->assertRegExp('/2016-08-03T09:30:33\+\d{2}:\d{2}/', $data['last_update']); |
122 | $link = reset($data['links']); | 122 | $link = $data['links'][array_keys($data['links'])[2]]; |
123 | $this->assertRegExp('/2015-03-10T11:46:51\+\d{2}:\d{2}/', $link['pub_iso_date']); | 123 | $this->assertRegExp('/2015-03-10T11:46:51\+\d{2}:\d{2}/', $link['pub_iso_date']); |
124 | $this->assertRegExp('/2016-08-03T09:30:33\+\d{2}:\d{2}/', $data['links'][8]['up_iso_date']); | 124 | $this->assertRegExp('/2016-08-03T09:30:33\+\d{2}:\d{2}/', $data['links'][8]['up_iso_date']); |
125 | } | 125 | } |
@@ -148,13 +148,13 @@ class FeedBuilderTest extends PHPUnit_Framework_TestCase | |||
148 | public function testBuildDataCount() | 148 | public function testBuildDataCount() |
149 | { | 149 | { |
150 | $criteria = array( | 150 | $criteria = array( |
151 | 'nb' => '1', | 151 | 'nb' => '3', |
152 | ); | 152 | ); |
153 | $feedBuilder = new FeedBuilder(self::$linkDB, FeedBuilder::$FEED_ATOM, self::$serverInfo, $criteria, false); | 153 | $feedBuilder = new FeedBuilder(self::$linkDB, FeedBuilder::$FEED_ATOM, self::$serverInfo, $criteria, false); |
154 | $feedBuilder->setLocale(self::$LOCALE); | 154 | $feedBuilder->setLocale(self::$LOCALE); |
155 | $data = $feedBuilder->buildData(); | 155 | $data = $feedBuilder->buildData(); |
156 | $this->assertEquals(1, count($data['links'])); | 156 | $this->assertEquals(3, count($data['links'])); |
157 | $link = array_shift($data['links']); | 157 | $link = $data['links'][array_keys($data['links'])[2]]; |
158 | $this->assertEquals(41, $link['id']); | 158 | $this->assertEquals(41, $link['id']); |
159 | $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20150310_114651'), $link['created']); | 159 | $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20150310_114651'), $link['created']); |
160 | } | 160 | } |
@@ -171,7 +171,7 @@ class FeedBuilderTest extends PHPUnit_Framework_TestCase | |||
171 | $this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links'])); | 171 | $this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links'])); |
172 | $this->assertTrue($data['usepermalinks']); | 172 | $this->assertTrue($data['usepermalinks']); |
173 | // First link is a permalink | 173 | // First link is a permalink |
174 | $link = array_shift($data['links']); | 174 | $link = $data['links'][array_keys($data['links'])[2]]; |
175 | $this->assertEquals(41, $link['id']); | 175 | $this->assertEquals(41, $link['id']); |
176 | $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20150310_114651'), $link['created']); | 176 | $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20150310_114651'), $link['created']); |
177 | $this->assertEquals('http://host.tld/?WDWyig', $link['guid']); | 177 | $this->assertEquals('http://host.tld/?WDWyig', $link['guid']); |
@@ -179,7 +179,7 @@ class FeedBuilderTest extends PHPUnit_Framework_TestCase | |||
179 | $this->assertContains('Direct link', $link['description']); | 179 | $this->assertContains('Direct link', $link['description']); |
180 | $this->assertContains('http://host.tld/?WDWyig', $link['description']); | 180 | $this->assertContains('http://host.tld/?WDWyig', $link['description']); |
181 | // Second link is a direct link | 181 | // Second link is a direct link |
182 | $link = array_shift($data['links']); | 182 | $link = $data['links'][array_keys($data['links'])[3]]; |
183 | $this->assertEquals(8, $link['id']); | 183 | $this->assertEquals(8, $link['id']); |
184 | $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20150310_114633'), $link['created']); | 184 | $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20150310_114633'), $link['created']); |
185 | $this->assertEquals('http://host.tld/?RttfEw', $link['guid']); | 185 | $this->assertEquals('http://host.tld/?RttfEw', $link['guid']); |
@@ -237,7 +237,7 @@ class FeedBuilderTest extends PHPUnit_Framework_TestCase | |||
237 | ); | 237 | ); |
238 | 238 | ||
239 | // Test first link (note link) | 239 | // Test first link (note link) |
240 | $link = array_shift($data['links']); | 240 | $link = $data['links'][array_keys($data['links'])[2]]; |
241 | $this->assertEquals('http://host.tld:8080/~user/shaarli/?WDWyig', $link['guid']); | 241 | $this->assertEquals('http://host.tld:8080/~user/shaarli/?WDWyig', $link['guid']); |
242 | $this->assertEquals('http://host.tld:8080/~user/shaarli/?WDWyig', $link['url']); | 242 | $this->assertEquals('http://host.tld:8080/~user/shaarli/?WDWyig', $link['url']); |
243 | $this->assertContains('http://host.tld:8080/~user/shaarli/?addtag=hashtag', $link['description']); | 243 | $this->assertContains('http://host.tld:8080/~user/shaarli/?addtag=hashtag', $link['description']); |
diff --git a/tests/LinkDBTest.php b/tests/LinkDBTest.php index 3b980878..fcab76f6 100644 --- a/tests/LinkDBTest.php +++ b/tests/LinkDBTest.php | |||
@@ -239,12 +239,12 @@ class LinkDBTest extends PHPUnit_Framework_TestCase | |||
239 | public function testDays() | 239 | public function testDays() |
240 | { | 240 | { |
241 | $this->assertEquals( | 241 | $this->assertEquals( |
242 | array('20100310', '20121206', '20130614', '20150310'), | 242 | array('20100309', '20100310', '20121206', '20121207', '20130614', '20150310'), |
243 | self::$publicLinkDB->days() | 243 | self::$publicLinkDB->days() |
244 | ); | 244 | ); |
245 | 245 | ||
246 | $this->assertEquals( | 246 | $this->assertEquals( |
247 | array('20100310', '20121206', '20130614', '20141125', '20150310'), | 247 | array('20100309', '20100310', '20121206', '20121207', '20130614', '20141125', '20150310'), |
248 | self::$privateLinkDB->days() | 248 | self::$privateLinkDB->days() |
249 | ); | 249 | ); |
250 | } | 250 | } |
@@ -475,13 +475,15 @@ class LinkDBTest extends PHPUnit_Framework_TestCase | |||
475 | public function testReorderLinksDesc() | 475 | public function testReorderLinksDesc() |
476 | { | 476 | { |
477 | self::$privateLinkDB->reorder('ASC'); | 477 | self::$privateLinkDB->reorder('ASC'); |
478 | $linkIds = array(42, 4, 9, 1, 0, 7, 6, 8, 41); | 478 | $stickyIds = [11, 10]; |
479 | $standardIds = [42, 4, 9, 1, 0, 7, 6, 8, 41]; | ||
480 | $linkIds = array_merge($stickyIds, $standardIds); | ||
479 | $cpt = 0; | 481 | $cpt = 0; |
480 | foreach (self::$privateLinkDB as $key => $value) { | 482 | foreach (self::$privateLinkDB as $key => $value) { |
481 | $this->assertEquals($linkIds[$cpt++], $key); | 483 | $this->assertEquals($linkIds[$cpt++], $key); |
482 | } | 484 | } |
483 | self::$privateLinkDB->reorder('DESC'); | 485 | self::$privateLinkDB->reorder('DESC'); |
484 | $linkIds = array_reverse($linkIds); | 486 | $linkIds = array_merge(array_reverse($stickyIds), array_reverse($standardIds)); |
485 | $cpt = 0; | 487 | $cpt = 0; |
486 | foreach (self::$privateLinkDB as $key => $value) { | 488 | foreach (self::$privateLinkDB as $key => $value) { |
487 | $this->assertEquals($linkIds[$cpt++], $key); | 489 | $this->assertEquals($linkIds[$cpt++], $key); |
diff --git a/tests/NetscapeBookmarkUtils/BookmarkExportTest.php b/tests/NetscapeBookmarkUtils/BookmarkExportTest.php index 6a47bbb9..77fbd5f3 100644 --- a/tests/NetscapeBookmarkUtils/BookmarkExportTest.php +++ b/tests/NetscapeBookmarkUtils/BookmarkExportTest.php | |||
@@ -110,7 +110,7 @@ class BookmarkExportTest extends PHPUnit_Framework_TestCase | |||
110 | $links = NetscapeBookmarkUtils::filterAndFormat(self::$linkDb, 'public', false, ''); | 110 | $links = NetscapeBookmarkUtils::filterAndFormat(self::$linkDb, 'public', false, ''); |
111 | $this->assertEquals( | 111 | $this->assertEquals( |
112 | '?WDWyig', | 112 | '?WDWyig', |
113 | $links[0]['url'] | 113 | $links[2]['url'] |
114 | ); | 114 | ); |
115 | } | 115 | } |
116 | 116 | ||
@@ -128,7 +128,7 @@ class BookmarkExportTest extends PHPUnit_Framework_TestCase | |||
128 | ); | 128 | ); |
129 | $this->assertEquals( | 129 | $this->assertEquals( |
130 | $indexUrl . '?WDWyig', | 130 | $indexUrl . '?WDWyig', |
131 | $links[0]['url'] | 131 | $links[2]['url'] |
132 | ); | 132 | ); |
133 | } | 133 | } |
134 | } | 134 | } |
diff --git a/tests/Updater/UpdaterTest.php b/tests/Updater/UpdaterTest.php index cacee2d2..870f169a 100644 --- a/tests/Updater/UpdaterTest.php +++ b/tests/Updater/UpdaterTest.php | |||
@@ -688,6 +688,7 @@ $GLOBALS[\'privateLinkByDefault\'] = true;'; | |||
688 | } | 688 | } |
689 | 689 | ||
690 | /** | 690 | /** |
691 | <<<<<<< HEAD | ||
691 | * Test updateMethodWebThumbnailer with thumbnails enabled. | 692 | * Test updateMethodWebThumbnailer with thumbnails enabled. |
692 | */ | 693 | */ |
693 | public function testUpdateMethodWebThumbnailerEnabled() | 694 | public function testUpdateMethodWebThumbnailerEnabled() |
@@ -732,4 +733,64 @@ $GLOBALS[\'privateLinkByDefault\'] = true;'; | |||
732 | $this->assertEquals(53, $this->conf->get('thumbnails.height')); | 733 | $this->assertEquals(53, $this->conf->get('thumbnails.height')); |
733 | $this->assertTrue(empty($_SESSION['warnings'])); | 734 | $this->assertTrue(empty($_SESSION['warnings'])); |
734 | } | 735 | } |
736 | |||
737 | /** | ||
738 | * Test updateMethodSetSticky(). | ||
739 | */ | ||
740 | public function testUpdateStickyValid() | ||
741 | { | ||
742 | $blank = [ | ||
743 | 'id' => 1, | ||
744 | 'url' => 'z', | ||
745 | 'title' => '', | ||
746 | 'description' => '', | ||
747 | 'tags' => '', | ||
748 | 'created' => new DateTime(), | ||
749 | ]; | ||
750 | $links = [ | ||
751 | 1 => ['id' => 1] + $blank, | ||
752 | 2 => ['id' => 2] + $blank, | ||
753 | ]; | ||
754 | $refDB = new ReferenceLinkDB(); | ||
755 | $refDB->setLinks($links); | ||
756 | $refDB->write(self::$testDatastore); | ||
757 | $linkDB = new LinkDB(self::$testDatastore, true, false); | ||
758 | |||
759 | $updater = new Updater(array(), $linkDB, $this->conf, true); | ||
760 | $this->assertTrue($updater->updateMethodSetSticky()); | ||
761 | |||
762 | $linkDB = new LinkDB(self::$testDatastore, true, false); | ||
763 | foreach ($linkDB as $link) { | ||
764 | $this->assertFalse($link['sticky']); | ||
765 | } | ||
766 | } | ||
767 | |||
768 | /** | ||
769 | * Test updateMethodSetSticky(). | ||
770 | */ | ||
771 | public function testUpdateStickyNothingToDo() | ||
772 | { | ||
773 | $blank = [ | ||
774 | 'id' => 1, | ||
775 | 'url' => 'z', | ||
776 | 'title' => '', | ||
777 | 'description' => '', | ||
778 | 'tags' => '', | ||
779 | 'created' => new DateTime(), | ||
780 | ]; | ||
781 | $links = [ | ||
782 | 1 => ['id' => 1, 'sticky' => true] + $blank, | ||
783 | 2 => ['id' => 2] + $blank, | ||
784 | ]; | ||
785 | $refDB = new ReferenceLinkDB(); | ||
786 | $refDB->setLinks($links); | ||
787 | $refDB->write(self::$testDatastore); | ||
788 | $linkDB = new LinkDB(self::$testDatastore, true, false); | ||
789 | |||
790 | $updater = new Updater(array(), $linkDB, $this->conf, true); | ||
791 | $this->assertTrue($updater->updateMethodSetSticky()); | ||
792 | |||
793 | $linkDB = new LinkDB(self::$testDatastore, true, false); | ||
794 | $this->assertTrue($linkDB[1]['sticky']); | ||
795 | } | ||
735 | } | 796 | } |
diff --git a/tests/api/controllers/links/GetLinksTest.php b/tests/api/controllers/links/GetLinksTest.php index d22ed3bf..64f02774 100644 --- a/tests/api/controllers/links/GetLinksTest.php +++ b/tests/api/controllers/links/GetLinksTest.php | |||
@@ -95,7 +95,7 @@ class GetLinksTest extends \PHPUnit_Framework_TestCase | |||
95 | $this->assertEquals($this->refDB->countLinks(), count($data)); | 95 | $this->assertEquals($this->refDB->countLinks(), count($data)); |
96 | 96 | ||
97 | // Check order | 97 | // Check order |
98 | $order = [41, 8, 6, 7, 0, 1, 9, 4, 42]; | 98 | $order = [10, 11, 41, 8, 6, 7, 0, 1, 9, 4, 42]; |
99 | $cpt = 0; | 99 | $cpt = 0; |
100 | foreach ($data as $link) { | 100 | foreach ($data as $link) { |
101 | $this->assertEquals(self::NB_FIELDS_LINK, count($link)); | 101 | $this->assertEquals(self::NB_FIELDS_LINK, count($link)); |
@@ -103,7 +103,7 @@ class GetLinksTest extends \PHPUnit_Framework_TestCase | |||
103 | } | 103 | } |
104 | 104 | ||
105 | // Check first element fields | 105 | // Check first element fields |
106 | $first = $data[0]; | 106 | $first = $data[2]; |
107 | $this->assertEquals('http://domain.tld/?WDWyig', $first['url']); | 107 | $this->assertEquals('http://domain.tld/?WDWyig', $first['url']); |
108 | $this->assertEquals('WDWyig', $first['shorturl']); | 108 | $this->assertEquals('WDWyig', $first['shorturl']); |
109 | $this->assertEquals('Link title: @website', $first['title']); | 109 | $this->assertEquals('Link title: @website', $first['title']); |
@@ -120,7 +120,7 @@ class GetLinksTest extends \PHPUnit_Framework_TestCase | |||
120 | $this->assertEmpty($first['updated']); | 120 | $this->assertEmpty($first['updated']); |
121 | 121 | ||
122 | // Multi tags | 122 | // Multi tags |
123 | $link = $data[1]; | 123 | $link = $data[3]; |
124 | $this->assertEquals(7, count($link['tags'])); | 124 | $this->assertEquals(7, count($link['tags'])); |
125 | 125 | ||
126 | // Update date | 126 | // Update date |
@@ -138,7 +138,7 @@ class GetLinksTest extends \PHPUnit_Framework_TestCase | |||
138 | { | 138 | { |
139 | $env = Environment::mock([ | 139 | $env = Environment::mock([ |
140 | 'REQUEST_METHOD' => 'GET', | 140 | 'REQUEST_METHOD' => 'GET', |
141 | 'QUERY_STRING' => 'offset=1&limit=1' | 141 | 'QUERY_STRING' => 'offset=3&limit=1' |
142 | ]); | 142 | ]); |
143 | $request = Request::createFromEnvironment($env); | 143 | $request = Request::createFromEnvironment($env); |
144 | $response = $this->controller->getLinks($request, new Response()); | 144 | $response = $this->controller->getLinks($request, new Response()); |
@@ -164,7 +164,7 @@ class GetLinksTest extends \PHPUnit_Framework_TestCase | |||
164 | $data = json_decode((string) $response->getBody(), true); | 164 | $data = json_decode((string) $response->getBody(), true); |
165 | $this->assertEquals($this->refDB->countLinks(), count($data)); | 165 | $this->assertEquals($this->refDB->countLinks(), count($data)); |
166 | // Check order | 166 | // Check order |
167 | $order = [41, 8, 6, 7, 0, 1, 9, 4, 42]; | 167 | $order = [10, 11, 41, 8, 6, 7, 0, 1, 9, 4, 42]; |
168 | $cpt = 0; | 168 | $cpt = 0; |
169 | foreach ($data as $link) { | 169 | foreach ($data as $link) { |
170 | $this->assertEquals(self::NB_FIELDS_LINK, count($link)); | 170 | $this->assertEquals(self::NB_FIELDS_LINK, count($link)); |
@@ -205,7 +205,8 @@ class GetLinksTest extends \PHPUnit_Framework_TestCase | |||
205 | $this->assertEquals(200, $response->getStatusCode()); | 205 | $this->assertEquals(200, $response->getStatusCode()); |
206 | $data = json_decode((string)$response->getBody(), true); | 206 | $data = json_decode((string)$response->getBody(), true); |
207 | $this->assertEquals($this->refDB->countLinks(), count($data)); | 207 | $this->assertEquals($this->refDB->countLinks(), count($data)); |
208 | $this->assertEquals(41, $data[0]['id']); | 208 | $this->assertEquals(10, $data[0]['id']); |
209 | $this->assertEquals(41, $data[2]['id']); | ||
209 | $this->assertEquals(self::NB_FIELDS_LINK, count($data[0])); | 210 | $this->assertEquals(self::NB_FIELDS_LINK, count($data[0])); |
210 | } | 211 | } |
211 | 212 | ||
@@ -243,7 +244,8 @@ class GetLinksTest extends \PHPUnit_Framework_TestCase | |||
243 | $this->assertEquals(200, $response->getStatusCode()); | 244 | $this->assertEquals(200, $response->getStatusCode()); |
244 | $data = json_decode((string)$response->getBody(), true); | 245 | $data = json_decode((string)$response->getBody(), true); |
245 | $this->assertEquals($this->refDB->countPublicLinks(), count($data)); | 246 | $this->assertEquals($this->refDB->countPublicLinks(), count($data)); |
246 | $this->assertEquals(41, $data[0]['id']); | 247 | $this->assertEquals(10, $data[0]['id']); |
248 | $this->assertEquals(41, $data[2]['id']); | ||
247 | $this->assertEquals(self::NB_FIELDS_LINK, count($data[0])); | 249 | $this->assertEquals(self::NB_FIELDS_LINK, count($data[0])); |
248 | } | 250 | } |
249 | 251 | ||
@@ -413,8 +415,9 @@ class GetLinksTest extends \PHPUnit_Framework_TestCase | |||
413 | $response = $this->controller->getLinks($request, new Response()); | 415 | $response = $this->controller->getLinks($request, new Response()); |
414 | $this->assertEquals(200, $response->getStatusCode()); | 416 | $this->assertEquals(200, $response->getStatusCode()); |
415 | $data = json_decode((string) $response->getBody(), true); | 417 | $data = json_decode((string) $response->getBody(), true); |
416 | $this->assertEquals(9, count($data)); | 418 | $this->assertEquals(\ReferenceLinkDB::$NB_LINKS_TOTAL, count($data)); |
417 | $this->assertEquals(41, $data[0]['id']); | 419 | $this->assertEquals(10, $data[0]['id']); |
420 | $this->assertEquals(41, $data[2]['id']); | ||
418 | 421 | ||
419 | // wildcard: optional ('*' does not need to expand) | 422 | // wildcard: optional ('*' does not need to expand) |
420 | $env = Environment::mock([ | 423 | $env = Environment::mock([ |
diff --git a/tests/utils/ReferenceLinkDB.php b/tests/utils/ReferenceLinkDB.php index e887aa78..7426ad07 100644 --- a/tests/utils/ReferenceLinkDB.php +++ b/tests/utils/ReferenceLinkDB.php | |||
@@ -4,7 +4,7 @@ | |||
4 | */ | 4 | */ |
5 | class ReferenceLinkDB | 5 | class ReferenceLinkDB |
6 | { | 6 | { |
7 | public static $NB_LINKS_TOTAL = 9; | 7 | public static $NB_LINKS_TOTAL = 11; |
8 | 8 | ||
9 | private $_links = array(); | 9 | private $_links = array(); |
10 | private $_publicCount = 0; | 10 | private $_publicCount = 0; |
@@ -16,6 +16,32 @@ class ReferenceLinkDB | |||
16 | public function __construct() | 16 | public function __construct() |
17 | { | 17 | { |
18 | $this->addLink( | 18 | $this->addLink( |
19 | 11, | ||
20 | 'Pined older', | ||
21 | '?PCRizQ', | ||
22 | 'This is an older pinned link', | ||
23 | 0, | ||
24 | DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20100309_101010'), | ||
25 | '', | ||
26 | null, | ||
27 | 'PCRizQ', | ||
28 | true | ||
29 | ); | ||
30 | |||
31 | $this->addLink( | ||
32 | 10, | ||
33 | 'Pined', | ||
34 | '?0gCTjQ', | ||
35 | 'This is a pinned link', | ||
36 | 0, | ||
37 | DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20121207_152312'), | ||
38 | '', | ||
39 | null, | ||
40 | '0gCTjQ', | ||
41 | true | ||
42 | ); | ||
43 | |||
44 | $this->addLink( | ||
19 | 41, | 45 | 41, |
20 | 'Link title: @website', | 46 | 'Link title: @website', |
21 | '?WDWyig', | 47 | '?WDWyig', |
@@ -114,7 +140,17 @@ class ReferenceLinkDB | |||
114 | /** | 140 | /** |
115 | * Adds a new link | 141 | * Adds a new link |
116 | */ | 142 | */ |
117 | protected function addLink($id, $title, $url, $description, $private, $date, $tags, $updated = '', $shorturl = '') | 143 | protected function addLink( |
144 | $id, | ||
145 | $title, | ||
146 | $url, | ||
147 | $description, | ||
148 | $private, | ||
149 | $date, | ||
150 | $tags, | ||
151 | $updated = '', | ||
152 | $shorturl = '', | ||
153 | $pinned = false) | ||
118 | { | 154 | { |
119 | $link = array( | 155 | $link = array( |
120 | 'id' => $id, | 156 | 'id' => $id, |
@@ -126,6 +162,7 @@ class ReferenceLinkDB | |||
126 | 'created' => $date, | 162 | 'created' => $date, |
127 | 'updated' => $updated, | 163 | 'updated' => $updated, |
128 | 'shorturl' => $shorturl ? $shorturl : smallHash($date->format(LinkDB::LINK_DATE_FORMAT) . $id), | 164 | 'shorturl' => $shorturl ? $shorturl : smallHash($date->format(LinkDB::LINK_DATE_FORMAT) . $id), |
165 | 'sticky' => $pinned | ||
129 | ); | 166 | ); |
130 | $this->_links[$id] = $link; | 167 | $this->_links[$id] = $link; |
131 | 168 | ||
@@ -165,6 +202,10 @@ class ReferenceLinkDB | |||
165 | $order = $order === 'ASC' ? -1 : 1; | 202 | $order = $order === 'ASC' ? -1 : 1; |
166 | // Reorder array by dates. | 203 | // Reorder array by dates. |
167 | usort($this->_links, function($a, $b) use ($order) { | 204 | usort($this->_links, function($a, $b) use ($order) { |
205 | if (isset($a['sticky']) && isset($b['sticky']) && $a['sticky'] !== $b['sticky']) { | ||
206 | return $a['sticky'] ? -1 : 1; | ||
207 | } | ||
208 | |||
168 | return $a['created'] < $b['created'] ? 1 * $order : -1 * $order; | 209 | return $a['created'] < $b['created'] ? 1 * $order : -1 * $order; |
169 | }); | 210 | }); |
170 | } | 211 | } |
diff --git a/tpl/default/linklist.html b/tpl/default/linklist.html index 8ea2ce66..aaa9bc74 100644 --- a/tpl/default/linklist.html +++ b/tpl/default/linklist.html | |||
@@ -201,6 +201,12 @@ | |||
201 | <i class="fa fa-trash"></i> | 201 | <i class="fa fa-trash"></i> |
202 | </a> | 202 | </a> |
203 | </span> | 203 | </span> |
204 | <span class="linklist-item-infos-controls-item ctrl-pin"> | ||
205 | <a href="?do=pin&id={$value.id}&token={$token}" | ||
206 | title="{$strDelete}" class="pin-link {if="$value.sticky"}pinned-link{/if} pure-u-0 pure-u-lg-visible"> | ||
207 | <i class="fa fa-thumb-tack"></i> | ||
208 | </a> | ||
209 | </span> | ||
204 | </div> | 210 | </div> |
205 | {/if} | 211 | {/if} |
206 | <a href="?{$value.shorturl}" title="{$strPermalink}"> | 212 | <a href="?{$value.shorturl}" title="{$strPermalink}"> |