$order = $order === 'ASC' ? -1 : 1;
// Reorder array by dates.
usort($this->links, function($a, $b) use ($order) {
+ if (isset($a['sticky']) && isset($b['sticky']) && $a['sticky'] !== $b['sticky']) {
+ return $a['sticky'] ? -1 : 1;
+ }
return $a['created'] < $b['created'] ? 1 * $order : -1 * $order;
});
public static $PAGE_DELETELINK = 'delete_link';
+ public static $PAGE_PINLINK = 'pin';
+
public static $PAGE_EXPORT = 'export';
public static $PAGE_IMPORT = 'import';
return self::$PAGE_DELETELINK;
}
+ if (startsWith($query, 'do='. self::$PAGE_PINLINK)) {
+ return self::$PAGE_PINLINK;
+ }
+
if (startsWith($query, 'do='. self::$PAGE_EXPORT)) {
return self::$PAGE_EXPORT;
}
return true;
}
+
+ /**
+ * Set sticky = false on all links
+ *
+ * @return bool true if the update is successful, false otherwise.
+ */
+ public function updateMethodSetSticky()
+ {
+ foreach ($this->linkDB as $key => $link) {
+ if (isset($link['sticky'])) {
+ return true;
+ }
+ $link['sticky'] = false;
+ $this->linkDB[$key] = $link;
+ }
+
+ $this->linkDB->save($this->conf->get('resource.page_cache'));
+
+ return true;
+ }
}
/**
font-size: 1.3em;
}
+.pin-link {
+ font-size: 1.3em;
+}
+
+.pinned-link {
+ color: #0b5ea6 !important;
+}
+
.linklist-item-description {
position: relative;
padding: 0 10px;
margin: 0 7px;
}
+.ctrl-delete {
+ margin: 0 7px 0 0;
+}
+
// 64em -> lg
@media screen and (max-width: 64em) {
.linklist-item-infos-url {
exit;
}
+ if ($targetPage == Router::$PAGE_PINLINK) {
+ if (! isset($_GET['id']) || empty($LINKSDB[$_GET['id']])) {
+ // FIXME! Use a proper error system.
+ $msg = t('Invalid link ID provided');
+ echo '<script>alert("'. $msg .'");document.location=\''. index_url($_SERVER) .'\';</script>';
+ exit;
+ }
+ if (! $sessionManager->checkToken($_GET['token'])) {
+ die('Wrong token.');
+ }
+
+ $link = $LINKSDB[$_GET['id']];
+ $link['sticky'] = ! $link['sticky'];
+ $LINKSDB[(int) $_GET['id']] = $link;
+ $LINKSDB->save($conf->get('resource.page_cache'));
+ header('Location: '.index_url($_SERVER));
+ exit;
+ }
+
if ($targetPage == Router::$PAGE_EXPORT) {
// Export links as a Netscape Bookmarks file
$this->assertFalse($data['usepermalinks']);
$this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links']));
- // Test first link (note link)
- $link = reset($data['links']);
+ // Test first not pinned link (note link)
+ $link = $data['links'][array_keys($data['links'])[2]];
$this->assertEquals(41, $link['id']);
$this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20150310_114651'), $link['created']);
$this->assertEquals('http://host.tld/?WDWyig', $link['guid']);
$data = $feedBuilder->buildData();
$this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links']));
$this->assertRegExp('/2016-08-03T09:30:33\+\d{2}:\d{2}/', $data['last_update']);
- $link = reset($data['links']);
+ $link = $data['links'][array_keys($data['links'])[2]];
$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']);
}
public function testBuildDataCount()
{
$criteria = array(
- 'nb' => '1',
+ 'nb' => '3',
);
$feedBuilder = new FeedBuilder(self::$linkDB, FeedBuilder::$FEED_ATOM, self::$serverInfo, $criteria, false);
$feedBuilder->setLocale(self::$LOCALE);
$data = $feedBuilder->buildData();
- $this->assertEquals(1, count($data['links']));
- $link = array_shift($data['links']);
+ $this->assertEquals(3, count($data['links']));
+ $link = $data['links'][array_keys($data['links'])[2]];
$this->assertEquals(41, $link['id']);
$this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20150310_114651'), $link['created']);
}
$this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links']));
$this->assertTrue($data['usepermalinks']);
// First link is a permalink
- $link = array_shift($data['links']);
+ $link = $data['links'][array_keys($data['links'])[2]];
$this->assertEquals(41, $link['id']);
$this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20150310_114651'), $link['created']);
$this->assertEquals('http://host.tld/?WDWyig', $link['guid']);
$this->assertContains('Direct link', $link['description']);
$this->assertContains('http://host.tld/?WDWyig', $link['description']);
// Second link is a direct link
- $link = array_shift($data['links']);
+ $link = $data['links'][array_keys($data['links'])[3]];
$this->assertEquals(8, $link['id']);
$this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20150310_114633'), $link['created']);
$this->assertEquals('http://host.tld/?RttfEw', $link['guid']);
);
// Test first link (note link)
- $link = array_shift($data['links']);
+ $link = $data['links'][array_keys($data['links'])[2]];
$this->assertEquals('http://host.tld:8080/~user/shaarli/?WDWyig', $link['guid']);
$this->assertEquals('http://host.tld:8080/~user/shaarli/?WDWyig', $link['url']);
$this->assertContains('http://host.tld:8080/~user/shaarli/?addtag=hashtag', $link['description']);
public function testDays()
{
$this->assertEquals(
- array('20100310', '20121206', '20130614', '20150310'),
+ array('20100309', '20100310', '20121206', '20121207', '20130614', '20150310'),
self::$publicLinkDB->days()
);
$this->assertEquals(
- array('20100310', '20121206', '20130614', '20141125', '20150310'),
+ array('20100309', '20100310', '20121206', '20121207', '20130614', '20141125', '20150310'),
self::$privateLinkDB->days()
);
}
public function testReorderLinksDesc()
{
self::$privateLinkDB->reorder('ASC');
- $linkIds = array(42, 4, 9, 1, 0, 7, 6, 8, 41);
+ $stickyIds = [11, 10];
+ $standardIds = [42, 4, 9, 1, 0, 7, 6, 8, 41];
+ $linkIds = array_merge($stickyIds, $standardIds);
$cpt = 0;
foreach (self::$privateLinkDB as $key => $value) {
$this->assertEquals($linkIds[$cpt++], $key);
}
self::$privateLinkDB->reorder('DESC');
- $linkIds = array_reverse($linkIds);
+ $linkIds = array_merge(array_reverse($stickyIds), array_reverse($standardIds));
$cpt = 0;
foreach (self::$privateLinkDB as $key => $value) {
$this->assertEquals($linkIds[$cpt++], $key);
$links = NetscapeBookmarkUtils::filterAndFormat(self::$linkDb, 'public', false, '');
$this->assertEquals(
'?WDWyig',
- $links[0]['url']
+ $links[2]['url']
);
}
);
$this->assertEquals(
$indexUrl . '?WDWyig',
- $links[0]['url']
+ $links[2]['url']
);
}
}
}
/**
+<<<<<<< HEAD
* Test updateMethodWebThumbnailer with thumbnails enabled.
*/
public function testUpdateMethodWebThumbnailerEnabled()
$this->assertEquals(53, $this->conf->get('thumbnails.height'));
$this->assertTrue(empty($_SESSION['warnings']));
}
+
+ /**
+ * Test updateMethodSetSticky().
+ */
+ public function testUpdateStickyValid()
+ {
+ $blank = [
+ 'id' => 1,
+ 'url' => 'z',
+ 'title' => '',
+ 'description' => '',
+ 'tags' => '',
+ 'created' => new DateTime(),
+ ];
+ $links = [
+ 1 => ['id' => 1] + $blank,
+ 2 => ['id' => 2] + $blank,
+ ];
+ $refDB = new ReferenceLinkDB();
+ $refDB->setLinks($links);
+ $refDB->write(self::$testDatastore);
+ $linkDB = new LinkDB(self::$testDatastore, true, false);
+
+ $updater = new Updater(array(), $linkDB, $this->conf, true);
+ $this->assertTrue($updater->updateMethodSetSticky());
+
+ $linkDB = new LinkDB(self::$testDatastore, true, false);
+ foreach ($linkDB as $link) {
+ $this->assertFalse($link['sticky']);
+ }
+ }
+
+ /**
+ * Test updateMethodSetSticky().
+ */
+ public function testUpdateStickyNothingToDo()
+ {
+ $blank = [
+ 'id' => 1,
+ 'url' => 'z',
+ 'title' => '',
+ 'description' => '',
+ 'tags' => '',
+ 'created' => new DateTime(),
+ ];
+ $links = [
+ 1 => ['id' => 1, 'sticky' => true] + $blank,
+ 2 => ['id' => 2] + $blank,
+ ];
+ $refDB = new ReferenceLinkDB();
+ $refDB->setLinks($links);
+ $refDB->write(self::$testDatastore);
+ $linkDB = new LinkDB(self::$testDatastore, true, false);
+
+ $updater = new Updater(array(), $linkDB, $this->conf, true);
+ $this->assertTrue($updater->updateMethodSetSticky());
+
+ $linkDB = new LinkDB(self::$testDatastore, true, false);
+ $this->assertTrue($linkDB[1]['sticky']);
+ }
}
$this->assertEquals($this->refDB->countLinks(), count($data));
// Check order
- $order = [41, 8, 6, 7, 0, 1, 9, 4, 42];
+ $order = [10, 11, 41, 8, 6, 7, 0, 1, 9, 4, 42];
$cpt = 0;
foreach ($data as $link) {
$this->assertEquals(self::NB_FIELDS_LINK, count($link));
}
// Check first element fields
- $first = $data[0];
+ $first = $data[2];
$this->assertEquals('http://domain.tld/?WDWyig', $first['url']);
$this->assertEquals('WDWyig', $first['shorturl']);
$this->assertEquals('Link title: @website', $first['title']);
$this->assertEmpty($first['updated']);
// Multi tags
- $link = $data[1];
+ $link = $data[3];
$this->assertEquals(7, count($link['tags']));
// Update date
{
$env = Environment::mock([
'REQUEST_METHOD' => 'GET',
- 'QUERY_STRING' => 'offset=1&limit=1'
+ 'QUERY_STRING' => 'offset=3&limit=1'
]);
$request = Request::createFromEnvironment($env);
$response = $this->controller->getLinks($request, new Response());
$data = json_decode((string) $response->getBody(), true);
$this->assertEquals($this->refDB->countLinks(), count($data));
// Check order
- $order = [41, 8, 6, 7, 0, 1, 9, 4, 42];
+ $order = [10, 11, 41, 8, 6, 7, 0, 1, 9, 4, 42];
$cpt = 0;
foreach ($data as $link) {
$this->assertEquals(self::NB_FIELDS_LINK, count($link));
$this->assertEquals(200, $response->getStatusCode());
$data = json_decode((string)$response->getBody(), true);
$this->assertEquals($this->refDB->countLinks(), count($data));
- $this->assertEquals(41, $data[0]['id']);
+ $this->assertEquals(10, $data[0]['id']);
+ $this->assertEquals(41, $data[2]['id']);
$this->assertEquals(self::NB_FIELDS_LINK, count($data[0]));
}
$this->assertEquals(200, $response->getStatusCode());
$data = json_decode((string)$response->getBody(), true);
$this->assertEquals($this->refDB->countPublicLinks(), count($data));
- $this->assertEquals(41, $data[0]['id']);
+ $this->assertEquals(10, $data[0]['id']);
+ $this->assertEquals(41, $data[2]['id']);
$this->assertEquals(self::NB_FIELDS_LINK, count($data[0]));
}
$response = $this->controller->getLinks($request, new Response());
$this->assertEquals(200, $response->getStatusCode());
$data = json_decode((string) $response->getBody(), true);
- $this->assertEquals(9, count($data));
- $this->assertEquals(41, $data[0]['id']);
+ $this->assertEquals(\ReferenceLinkDB::$NB_LINKS_TOTAL, count($data));
+ $this->assertEquals(10, $data[0]['id']);
+ $this->assertEquals(41, $data[2]['id']);
// wildcard: optional ('*' does not need to expand)
$env = Environment::mock([
*/
class ReferenceLinkDB
{
- public static $NB_LINKS_TOTAL = 9;
+ public static $NB_LINKS_TOTAL = 11;
private $_links = array();
private $_publicCount = 0;
*/
public function __construct()
{
+ $this->addLink(
+ 11,
+ 'Pined older',
+ '?PCRizQ',
+ 'This is an older pinned link',
+ 0,
+ DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20100309_101010'),
+ '',
+ null,
+ 'PCRizQ',
+ true
+ );
+
+ $this->addLink(
+ 10,
+ 'Pined',
+ '?0gCTjQ',
+ 'This is a pinned link',
+ 0,
+ DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20121207_152312'),
+ '',
+ null,
+ '0gCTjQ',
+ true
+ );
+
$this->addLink(
41,
'Link title: @website',
/**
* Adds a new link
*/
- protected function addLink($id, $title, $url, $description, $private, $date, $tags, $updated = '', $shorturl = '')
+ protected function addLink(
+ $id,
+ $title,
+ $url,
+ $description,
+ $private,
+ $date,
+ $tags,
+ $updated = '',
+ $shorturl = '',
+ $pinned = false)
{
$link = array(
'id' => $id,
'created' => $date,
'updated' => $updated,
'shorturl' => $shorturl ? $shorturl : smallHash($date->format(LinkDB::LINK_DATE_FORMAT) . $id),
+ 'sticky' => $pinned
);
$this->_links[$id] = $link;
$order = $order === 'ASC' ? -1 : 1;
// Reorder array by dates.
usort($this->_links, function($a, $b) use ($order) {
+ if (isset($a['sticky']) && isset($b['sticky']) && $a['sticky'] !== $b['sticky']) {
+ return $a['sticky'] ? -1 : 1;
+ }
+
return $a['created'] < $b['created'] ? 1 * $order : -1 * $order;
});
}
<i class="fa fa-trash"></i>
</a>
</span>
+ <span class="linklist-item-infos-controls-item ctrl-pin">
+ <a href="?do=pin&id={$value.id}&token={$token}"
+ title="{$strDelete}" class="pin-link {if="$value.sticky"}pinned-link{/if} pure-u-0 pure-u-lg-visible">
+ <i class="fa fa-thumb-tack"></i>
+ </a>
+ </span>
</div>
{/if}
<a href="?{$value.shorturl}" title="{$strPermalink}">