Merge pull request #768 from ArthurHoaro/feature/get-public-links
Update LinkFilter to be able to filter only public links
This commit is contained in:
commit
89dcbe5277
5 changed files with 107 additions and 39 deletions
|
@ -443,11 +443,11 @@ public function filterDay($request) {
|
||||||
* - searchtags: list of tags
|
* - searchtags: list of tags
|
||||||
* - searchterm: term search
|
* - searchterm: term search
|
||||||
* @param bool $casesensitive Optional: Perform case sensitive filter
|
* @param bool $casesensitive Optional: Perform case sensitive filter
|
||||||
* @param bool $privateonly Optional: Returns private links only if true.
|
* @param string $visibility return only all/private/public links
|
||||||
*
|
*
|
||||||
* @return array filtered links, all links if no suitable filter was provided.
|
* @return array filtered links, all links if no suitable filter was provided.
|
||||||
*/
|
*/
|
||||||
public function filterSearch($filterRequest = array(), $casesensitive = false, $privateonly = false)
|
public function filterSearch($filterRequest = array(), $casesensitive = false, $visibility = 'all')
|
||||||
{
|
{
|
||||||
// Filter link database according to parameters.
|
// Filter link database according to parameters.
|
||||||
$searchtags = !empty($filterRequest['searchtags']) ? escape($filterRequest['searchtags']) : '';
|
$searchtags = !empty($filterRequest['searchtags']) ? escape($filterRequest['searchtags']) : '';
|
||||||
|
@ -475,7 +475,7 @@ public function filterSearch($filterRequest = array(), $casesensitive = false, $
|
||||||
}
|
}
|
||||||
|
|
||||||
$linkFilter = new LinkFilter($this);
|
$linkFilter = new LinkFilter($this);
|
||||||
return $linkFilter->filter($type, $request, $casesensitive, $privateonly);
|
return $linkFilter->filter($type, $request, $casesensitive, $visibility);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -51,12 +51,16 @@ public function __construct($links)
|
||||||
* @param string $type Type of filter (eg. tags, permalink, etc.).
|
* @param string $type Type of filter (eg. tags, permalink, etc.).
|
||||||
* @param mixed $request Filter content.
|
* @param mixed $request Filter content.
|
||||||
* @param bool $casesensitive Optional: Perform case sensitive filter if true.
|
* @param bool $casesensitive Optional: Perform case sensitive filter if true.
|
||||||
* @param bool $privateonly Optional: Only returns private links if true.
|
* @param string $visibility Optional: return only all/private/public links
|
||||||
*
|
*
|
||||||
* @return array filtered link list.
|
* @return array filtered link list.
|
||||||
*/
|
*/
|
||||||
public function filter($type, $request, $casesensitive = false, $privateonly = false)
|
public function filter($type, $request, $casesensitive = false, $visibility = 'all')
|
||||||
{
|
{
|
||||||
|
if (! in_array($visibility, ['all', 'public', 'private'])) {
|
||||||
|
$visibility = 'all';
|
||||||
|
}
|
||||||
|
|
||||||
switch($type) {
|
switch($type) {
|
||||||
case self::$FILTER_HASH:
|
case self::$FILTER_HASH:
|
||||||
return $this->filterSmallHash($request);
|
return $this->filterSmallHash($request);
|
||||||
|
@ -64,42 +68,44 @@ public function filter($type, $request, $casesensitive = false, $privateonly = f
|
||||||
if (!empty($request)) {
|
if (!empty($request)) {
|
||||||
$filtered = $this->links;
|
$filtered = $this->links;
|
||||||
if (isset($request[0])) {
|
if (isset($request[0])) {
|
||||||
$filtered = $this->filterTags($request[0], $casesensitive, $privateonly);
|
$filtered = $this->filterTags($request[0], $casesensitive, $visibility);
|
||||||
}
|
}
|
||||||
if (isset($request[1])) {
|
if (isset($request[1])) {
|
||||||
$lf = new LinkFilter($filtered);
|
$lf = new LinkFilter($filtered);
|
||||||
$filtered = $lf->filterFulltext($request[1], $privateonly);
|
$filtered = $lf->filterFulltext($request[1], $visibility);
|
||||||
}
|
}
|
||||||
return $filtered;
|
return $filtered;
|
||||||
}
|
}
|
||||||
return $this->noFilter($privateonly);
|
return $this->noFilter($visibility);
|
||||||
case self::$FILTER_TEXT:
|
case self::$FILTER_TEXT:
|
||||||
return $this->filterFulltext($request, $privateonly);
|
return $this->filterFulltext($request, $visibility);
|
||||||
case self::$FILTER_TAG:
|
case self::$FILTER_TAG:
|
||||||
return $this->filterTags($request, $casesensitive, $privateonly);
|
return $this->filterTags($request, $casesensitive, $visibility);
|
||||||
case self::$FILTER_DAY:
|
case self::$FILTER_DAY:
|
||||||
return $this->filterDay($request);
|
return $this->filterDay($request);
|
||||||
default:
|
default:
|
||||||
return $this->noFilter($privateonly);
|
return $this->noFilter($visibility);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unknown filter, but handle private only.
|
* Unknown filter, but handle private only.
|
||||||
*
|
*
|
||||||
* @param bool $privateonly returns private link only if true.
|
* @param string $visibility Optional: return only all/private/public links
|
||||||
*
|
*
|
||||||
* @return array filtered links.
|
* @return array filtered links.
|
||||||
*/
|
*/
|
||||||
private function noFilter($privateonly = false)
|
private function noFilter($visibility = 'all')
|
||||||
{
|
{
|
||||||
if (! $privateonly) {
|
if ($visibility === 'all') {
|
||||||
return $this->links;
|
return $this->links;
|
||||||
}
|
}
|
||||||
|
|
||||||
$out = array();
|
$out = array();
|
||||||
foreach ($this->links as $key => $value) {
|
foreach ($this->links as $key => $value) {
|
||||||
if ($value['private']) {
|
if ($value['private'] && $visibility === 'private') {
|
||||||
|
$out[$key] = $value;
|
||||||
|
} else if (! $value['private'] && $visibility === 'public') {
|
||||||
$out[$key] = $value;
|
$out[$key] = $value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -151,14 +157,14 @@ private function filterSmallHash($smallHash)
|
||||||
* - see https://github.com/shaarli/Shaarli/issues/75 for examples
|
* - see https://github.com/shaarli/Shaarli/issues/75 for examples
|
||||||
*
|
*
|
||||||
* @param string $searchterms search query.
|
* @param string $searchterms search query.
|
||||||
* @param bool $privateonly return only private links if true.
|
* @param string $visibility Optional: return only all/private/public links.
|
||||||
*
|
*
|
||||||
* @return array search results.
|
* @return array search results.
|
||||||
*/
|
*/
|
||||||
private function filterFulltext($searchterms, $privateonly = false)
|
private function filterFulltext($searchterms, $visibility = 'all')
|
||||||
{
|
{
|
||||||
if (empty($searchterms)) {
|
if (empty($searchterms)) {
|
||||||
return $this->links;
|
return $this->noFilter($visibility);
|
||||||
}
|
}
|
||||||
|
|
||||||
$filtered = array();
|
$filtered = array();
|
||||||
|
@ -189,8 +195,12 @@ private function filterFulltext($searchterms, $privateonly = false)
|
||||||
foreach ($this->links as $id => $link) {
|
foreach ($this->links as $id => $link) {
|
||||||
|
|
||||||
// ignore non private links when 'privatonly' is on.
|
// ignore non private links when 'privatonly' is on.
|
||||||
if (! $link['private'] && $privateonly === true) {
|
if ($visibility !== 'all') {
|
||||||
continue;
|
if (! $link['private'] && $visibility === 'private') {
|
||||||
|
continue;
|
||||||
|
} else if ($link['private'] && $visibility === 'public') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Concatenate link fields to search across fields.
|
// Concatenate link fields to search across fields.
|
||||||
|
@ -235,16 +245,16 @@ private function filterFulltext($searchterms, $privateonly = false)
|
||||||
*
|
*
|
||||||
* @param string $tags list of tags separated by commas or blank spaces.
|
* @param string $tags list of tags separated by commas or blank spaces.
|
||||||
* @param bool $casesensitive ignore case if false.
|
* @param bool $casesensitive ignore case if false.
|
||||||
* @param bool $privateonly returns private links only.
|
* @param string $visibility Optional: return only all/private/public links.
|
||||||
*
|
*
|
||||||
* @return array filtered links.
|
* @return array filtered links.
|
||||||
*/
|
*/
|
||||||
public function filterTags($tags, $casesensitive = false, $privateonly = false)
|
public function filterTags($tags, $casesensitive = false, $visibility = 'all')
|
||||||
{
|
{
|
||||||
// Implode if array for clean up.
|
// Implode if array for clean up.
|
||||||
$tags = is_array($tags) ? trim(implode(' ', $tags)) : $tags;
|
$tags = is_array($tags) ? trim(implode(' ', $tags)) : $tags;
|
||||||
if (empty($tags)) {
|
if (empty($tags)) {
|
||||||
return $this->links;
|
return $this->noFilter($visibility);
|
||||||
}
|
}
|
||||||
|
|
||||||
$searchtags = self::tagsStrToArray($tags, $casesensitive);
|
$searchtags = self::tagsStrToArray($tags, $casesensitive);
|
||||||
|
@ -255,8 +265,12 @@ public function filterTags($tags, $casesensitive = false, $privateonly = false)
|
||||||
|
|
||||||
foreach ($this->links as $key => $link) {
|
foreach ($this->links as $key => $link) {
|
||||||
// ignore non private links when 'privatonly' is on.
|
// ignore non private links when 'privatonly' is on.
|
||||||
if (! $link['private'] && $privateonly === true) {
|
if ($visibility !== 'all') {
|
||||||
continue;
|
if (! $link['private'] && $visibility === 'private') {
|
||||||
|
continue;
|
||||||
|
} else if ($link['private'] && $visibility === 'public') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$linktags = self::tagsStrToArray($link['tags'], $casesensitive);
|
$linktags = self::tagsStrToArray($link['tags'], $casesensitive);
|
||||||
|
@ -341,7 +355,7 @@ protected function searchTagAndHashTag($tag, $taglist, $description)
|
||||||
* @param bool $casesensitive will convert everything to lowercase if false.
|
* @param bool $casesensitive will convert everything to lowercase if false.
|
||||||
*
|
*
|
||||||
* @return array filtered tags string.
|
* @return array filtered tags string.
|
||||||
*/
|
*/
|
||||||
public static function tagsStrToArray($tags, $casesensitive)
|
public static function tagsStrToArray($tags, $casesensitive)
|
||||||
{
|
{
|
||||||
// We use UTF-8 conversion to handle various graphemes (i.e. cyrillic, or greek)
|
// We use UTF-8 conversion to handle various graphemes (i.e. cyrillic, or greek)
|
||||||
|
|
|
@ -41,7 +41,8 @@ public function getLinks($request, $response)
|
||||||
'searchterm' => $request->getParam('searchterm', ''),
|
'searchterm' => $request->getParam('searchterm', ''),
|
||||||
],
|
],
|
||||||
false,
|
false,
|
||||||
$private === 'true' || $private === '1'
|
// to updated in another PR depending on the API doc
|
||||||
|
($private === 'true' || $private === '1') ? 'private' : 'all'
|
||||||
);
|
);
|
||||||
|
|
||||||
// Return links from the {offset}th link, starting from 0.
|
// Return links from the {offset}th link, starting from 0.
|
||||||
|
|
|
@ -1614,8 +1614,8 @@ function buildLinkList($PAGE,$LINKSDB, $conf, $pluginManager)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Filter links according search parameters.
|
// Filter links according search parameters.
|
||||||
$privateonly = !empty($_SESSION['privateonly']);
|
$visibility = ! empty($_SESSION['privateonly']) ? 'private' : 'all';
|
||||||
$linksToDisplay = $LINKSDB->filterSearch($_GET, false, $privateonly);
|
$linksToDisplay = $LINKSDB->filterSearch($_GET, false, $visibility);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---- Handle paging.
|
// ---- Handle paging.
|
||||||
|
|
|
@ -12,13 +12,18 @@ class LinkFilterTest extends PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
protected static $linkFilter;
|
protected static $linkFilter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ReferenceLinkDB instance
|
||||||
|
*/
|
||||||
|
protected static $refDB;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instanciate linkFilter with ReferenceLinkDB data.
|
* Instanciate linkFilter with ReferenceLinkDB data.
|
||||||
*/
|
*/
|
||||||
public static function setUpBeforeClass()
|
public static function setUpBeforeClass()
|
||||||
{
|
{
|
||||||
$refDB = new ReferenceLinkDB();
|
self::$refDB = new ReferenceLinkDB();
|
||||||
self::$linkFilter = new LinkFilter($refDB->getLinks());
|
self::$linkFilter = new LinkFilter(self::$refDB->getLinks());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,14 +32,30 @@ public static function setUpBeforeClass()
|
||||||
public function testFilter()
|
public function testFilter()
|
||||||
{
|
{
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
ReferenceLinkDB::$NB_LINKS_TOTAL,
|
self::$refDB->countLinks(),
|
||||||
count(self::$linkFilter->filter('', ''))
|
count(self::$linkFilter->filter('', ''))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
self::$refDB->countLinks(),
|
||||||
|
count(self::$linkFilter->filter('', '', 'all'))
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
self::$refDB->countLinks(),
|
||||||
|
count(self::$linkFilter->filter('', '', 'randomstr'))
|
||||||
|
);
|
||||||
|
|
||||||
// Private only.
|
// Private only.
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
2,
|
self::$refDB->countPrivateLinks(),
|
||||||
count(self::$linkFilter->filter('', '', false, true))
|
count(self::$linkFilter->filter('', '', false, 'private'))
|
||||||
|
);
|
||||||
|
|
||||||
|
// Public only.
|
||||||
|
$this->assertEquals(
|
||||||
|
self::$refDB->countPublicLinks(),
|
||||||
|
count(self::$linkFilter->filter('', '', false, 'public'))
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
|
@ -58,10 +79,26 @@ public function testFilterOneTag()
|
||||||
count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, 'web', false))
|
count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, 'web', false))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
4,
|
||||||
|
count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, 'web', false, 'all'))
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
4,
|
||||||
|
count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, 'web', false, 'default-blabla'))
|
||||||
|
);
|
||||||
|
|
||||||
// Private only.
|
// Private only.
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
1,
|
1,
|
||||||
count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, 'web', false, true))
|
count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, 'web', false, 'private'))
|
||||||
|
);
|
||||||
|
|
||||||
|
// Public only.
|
||||||
|
$this->assertEquals(
|
||||||
|
3,
|
||||||
|
count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, 'web', false, 'public'))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,14 +290,30 @@ public function testFilterFullTextDescription()
|
||||||
public function testFilterFullTextTags()
|
public function testFilterFullTextTags()
|
||||||
{
|
{
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
2,
|
6,
|
||||||
count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'gnu'))
|
count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'web'))
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
6,
|
||||||
|
count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'web', 'all'))
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
6,
|
||||||
|
count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'web', 'bla'))
|
||||||
);
|
);
|
||||||
|
|
||||||
// Private only.
|
// Private only.
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
1,
|
1,
|
||||||
count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'web', false, true))
|
count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'web', false, 'private'))
|
||||||
|
);
|
||||||
|
|
||||||
|
// Public only.
|
||||||
|
$this->assertEquals(
|
||||||
|
5,
|
||||||
|
count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'web', false, 'public'))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -409,7 +462,7 @@ public function testFilterByHashtag()
|
||||||
LinkFilter::$FILTER_TAG,
|
LinkFilter::$FILTER_TAG,
|
||||||
$hashtag,
|
$hashtag,
|
||||||
false,
|
false,
|
||||||
true
|
'private'
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue