Merge pull request #1143 from ArthurHoaro/sort-equal-tags
Fix order of tags with the same number of occurrences
This commit is contained in:
commit
17e45b2e9c
2 changed files with 121 additions and 8 deletions
|
@ -436,15 +436,17 @@ public function filterSearch($filterRequest = array(), $casesensitive = false, $
|
|||
|
||||
/**
|
||||
* Returns the list tags appearing in the links with the given tags
|
||||
* @param $filteringTags: tags selecting the links to consider
|
||||
* @param $visibility: process only all/private/public links
|
||||
* @return: a tag=>linksCount array
|
||||
*
|
||||
* @param array $filteringTags tags selecting the links to consider
|
||||
* @param string $visibility process only all/private/public links
|
||||
*
|
||||
* @return array tag => linksCount
|
||||
*/
|
||||
public function linksCountPerTag($filteringTags = [], $visibility = 'all')
|
||||
{
|
||||
$links = empty($filteringTags) ? $this->links : $this->filterSearch(['searchtags' => $filteringTags], false, $visibility);
|
||||
$tags = array();
|
||||
$caseMapping = array();
|
||||
$links = $this->filterSearch(['searchtags' => $filteringTags], false, $visibility);
|
||||
$tags = [];
|
||||
$caseMapping = [];
|
||||
foreach ($links as $link) {
|
||||
foreach (preg_split('/\s+/', $link['tags'], 0, PREG_SPLIT_NO_EMPTY) as $tag) {
|
||||
if (empty($tag)) {
|
||||
|
@ -458,8 +460,19 @@ public function linksCountPerTag($filteringTags = [], $visibility = 'all')
|
|||
$tags[$caseMapping[strtolower($tag)]]++;
|
||||
}
|
||||
}
|
||||
// Sort tags by usage (most used tag first)
|
||||
arsort($tags);
|
||||
|
||||
/*
|
||||
* Formerly used arsort(), which doesn't define the sort behaviour for equal values.
|
||||
* Also, this function doesn't produce the same result between PHP 5.6 and 7.
|
||||
*
|
||||
* So we now use array_multisort() to sort tags by DESC occurrences,
|
||||
* then ASC alphabetically for equal values.
|
||||
*
|
||||
* @see https://github.com/shaarli/Shaarli/issues/1142
|
||||
*/
|
||||
$keys = array_keys($tags);
|
||||
$tmpTags = array_combine($keys, $keys);
|
||||
array_multisort($tags, SORT_DESC, $tmpTags, SORT_ASC, $tags);
|
||||
return $tags;
|
||||
}
|
||||
|
||||
|
|
|
@ -542,4 +542,104 @@ public function testDeleteTag()
|
|||
$this->assertEquals(3, count($res));
|
||||
$this->assertNotContains('cartoon', $linkDB[4]['tags']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test linksCountPerTag all tags without filter.
|
||||
* Equal occurrences should be sorted alphabetically.
|
||||
*/
|
||||
public function testCountLinkPerTagAllNoFilter()
|
||||
{
|
||||
$expected = [
|
||||
'web' => 4,
|
||||
'cartoon' => 3,
|
||||
'dev' => 2,
|
||||
'gnu' => 2,
|
||||
'hashtag' => 2,
|
||||
'sTuff' => 2,
|
||||
'-exclude' => 1,
|
||||
'.hidden' => 1,
|
||||
'Mercurial' => 1,
|
||||
'css' => 1,
|
||||
'free' => 1,
|
||||
'html' => 1,
|
||||
'media' => 1,
|
||||
'samba' => 1,
|
||||
'software' => 1,
|
||||
'stallman' => 1,
|
||||
'tag1' => 1,
|
||||
'tag2' => 1,
|
||||
'tag3' => 1,
|
||||
'tag4' => 1,
|
||||
'ut' => 1,
|
||||
'w3c' => 1,
|
||||
];
|
||||
$tags = self::$privateLinkDB->linksCountPerTag();
|
||||
|
||||
$this->assertEquals($expected, $tags, var_export($tags, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test linksCountPerTag all tags with filter.
|
||||
* Equal occurrences should be sorted alphabetically.
|
||||
*/
|
||||
public function testCountLinkPerTagAllWithFilter()
|
||||
{
|
||||
$expected = [
|
||||
'gnu' => 2,
|
||||
'hashtag' => 2,
|
||||
'-exclude' => 1,
|
||||
'.hidden' => 1,
|
||||
'free' => 1,
|
||||
'media' => 1,
|
||||
'software' => 1,
|
||||
'stallman' => 1,
|
||||
'stuff' => 1,
|
||||
'web' => 1,
|
||||
];
|
||||
$tags = self::$privateLinkDB->linksCountPerTag(['gnu']);
|
||||
|
||||
$this->assertEquals($expected, $tags, var_export($tags, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test linksCountPerTag public tags with filter.
|
||||
* Equal occurrences should be sorted alphabetically.
|
||||
*/
|
||||
public function testCountLinkPerTagPublicWithFilter()
|
||||
{
|
||||
$expected = [
|
||||
'gnu' => 2,
|
||||
'hashtag' => 2,
|
||||
'-exclude' => 1,
|
||||
'.hidden' => 1,
|
||||
'free' => 1,
|
||||
'media' => 1,
|
||||
'software' => 1,
|
||||
'stallman' => 1,
|
||||
'stuff' => 1,
|
||||
'web' => 1,
|
||||
];
|
||||
$tags = self::$privateLinkDB->linksCountPerTag(['gnu'], 'public');
|
||||
|
||||
$this->assertEquals($expected, $tags, var_export($tags, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test linksCountPerTag public tags with filter.
|
||||
* Equal occurrences should be sorted alphabetically.
|
||||
*/
|
||||
public function testCountLinkPerTagPrivateWithFilter()
|
||||
{
|
||||
$expected = [
|
||||
'cartoon' => 1,
|
||||
'dev' => 1,
|
||||
'tag1' => 1,
|
||||
'tag2' => 1,
|
||||
'tag3' => 1,
|
||||
'tag4' => 1,
|
||||
];
|
||||
$tags = self::$privateLinkDB->linksCountPerTag(['dev'], 'private');
|
||||
|
||||
$this->assertEquals($expected, $tags, var_export($tags, true));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue