aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorArthurHoaro <arthur@hoa.ro>2018-06-04 18:34:50 +0200
committerGitHub <noreply@github.com>2018-06-04 18:34:50 +0200
commit17e45b2e9c33c736751e059276fadb480f98e621 (patch)
tree5160e3f04c570ca63ff2645d63f31934f70efeb7
parentd9cd27322a97e6ed3a8b11a380ef0080e3baf79c (diff)
parentf8c5660df82432c7f3bb0686e393db5a2b46eeb5 (diff)
downloadShaarli-17e45b2e9c33c736751e059276fadb480f98e621.tar.gz
Shaarli-17e45b2e9c33c736751e059276fadb480f98e621.tar.zst
Shaarli-17e45b2e9c33c736751e059276fadb480f98e621.zip
Merge pull request #1143 from ArthurHoaro/sort-equal-tags
Fix order of tags with the same number of occurrences
-rw-r--r--application/LinkDB.php29
-rw-r--r--tests/LinkDBTest.php100
2 files changed, 121 insertions, 8 deletions
diff --git a/application/LinkDB.php b/application/LinkDB.php
index c1661d52..cd0f2967 100644
--- a/application/LinkDB.php
+++ b/application/LinkDB.php
@@ -436,15 +436,17 @@ You use the community supported version of the original Shaarli project, by Seba
436 436
437 /** 437 /**
438 * Returns the list tags appearing in the links with the given tags 438 * Returns the list tags appearing in the links with the given tags
439 * @param $filteringTags: tags selecting the links to consider 439 *
440 * @param $visibility: process only all/private/public links 440 * @param array $filteringTags tags selecting the links to consider
441 * @return: a tag=>linksCount array 441 * @param string $visibility process only all/private/public links
442 *
443 * @return array tag => linksCount
442 */ 444 */
443 public function linksCountPerTag($filteringTags = [], $visibility = 'all') 445 public function linksCountPerTag($filteringTags = [], $visibility = 'all')
444 { 446 {
445 $links = empty($filteringTags) ? $this->links : $this->filterSearch(['searchtags' => $filteringTags], false, $visibility); 447 $links = $this->filterSearch(['searchtags' => $filteringTags], false, $visibility);
446 $tags = array(); 448 $tags = [];
447 $caseMapping = array(); 449 $caseMapping = [];
448 foreach ($links as $link) { 450 foreach ($links as $link) {
449 foreach (preg_split('/\s+/', $link['tags'], 0, PREG_SPLIT_NO_EMPTY) as $tag) { 451 foreach (preg_split('/\s+/', $link['tags'], 0, PREG_SPLIT_NO_EMPTY) as $tag) {
450 if (empty($tag)) { 452 if (empty($tag)) {
@@ -458,8 +460,19 @@ You use the community supported version of the original Shaarli project, by Seba
458 $tags[$caseMapping[strtolower($tag)]]++; 460 $tags[$caseMapping[strtolower($tag)]]++;
459 } 461 }
460 } 462 }
461 // Sort tags by usage (most used tag first) 463
462 arsort($tags); 464 /*
465 * Formerly used arsort(), which doesn't define the sort behaviour for equal values.
466 * Also, this function doesn't produce the same result between PHP 5.6 and 7.
467 *
468 * So we now use array_multisort() to sort tags by DESC occurrences,
469 * then ASC alphabetically for equal values.
470 *
471 * @see https://github.com/shaarli/Shaarli/issues/1142
472 */
473 $keys = array_keys($tags);
474 $tmpTags = array_combine($keys, $keys);
475 array_multisort($tags, SORT_DESC, $tmpTags, SORT_ASC, $tags);
463 return $tags; 476 return $tags;
464 } 477 }
465 478
diff --git a/tests/LinkDBTest.php b/tests/LinkDBTest.php
index 5b2f3667..3b980878 100644
--- a/tests/LinkDBTest.php
+++ b/tests/LinkDBTest.php
@@ -542,4 +542,104 @@ class LinkDBTest extends PHPUnit_Framework_TestCase
542 $this->assertEquals(3, count($res)); 542 $this->assertEquals(3, count($res));
543 $this->assertNotContains('cartoon', $linkDB[4]['tags']); 543 $this->assertNotContains('cartoon', $linkDB[4]['tags']);
544 } 544 }
545
546 /**
547 * Test linksCountPerTag all tags without filter.
548 * Equal occurrences should be sorted alphabetically.
549 */
550 public function testCountLinkPerTagAllNoFilter()
551 {
552 $expected = [
553 'web' => 4,
554 'cartoon' => 3,
555 'dev' => 2,
556 'gnu' => 2,
557 'hashtag' => 2,
558 'sTuff' => 2,
559 '-exclude' => 1,
560 '.hidden' => 1,
561 'Mercurial' => 1,
562 'css' => 1,
563 'free' => 1,
564 'html' => 1,
565 'media' => 1,
566 'samba' => 1,
567 'software' => 1,
568 'stallman' => 1,
569 'tag1' => 1,
570 'tag2' => 1,
571 'tag3' => 1,
572 'tag4' => 1,
573 'ut' => 1,
574 'w3c' => 1,
575 ];
576 $tags = self::$privateLinkDB->linksCountPerTag();
577
578 $this->assertEquals($expected, $tags, var_export($tags, true));
579 }
580
581 /**
582 * Test linksCountPerTag all tags with filter.
583 * Equal occurrences should be sorted alphabetically.
584 */
585 public function testCountLinkPerTagAllWithFilter()
586 {
587 $expected = [
588 'gnu' => 2,
589 'hashtag' => 2,
590 '-exclude' => 1,
591 '.hidden' => 1,
592 'free' => 1,
593 'media' => 1,
594 'software' => 1,
595 'stallman' => 1,
596 'stuff' => 1,
597 'web' => 1,
598 ];
599 $tags = self::$privateLinkDB->linksCountPerTag(['gnu']);
600
601 $this->assertEquals($expected, $tags, var_export($tags, true));
602 }
603
604 /**
605 * Test linksCountPerTag public tags with filter.
606 * Equal occurrences should be sorted alphabetically.
607 */
608 public function testCountLinkPerTagPublicWithFilter()
609 {
610 $expected = [
611 'gnu' => 2,
612 'hashtag' => 2,
613 '-exclude' => 1,
614 '.hidden' => 1,
615 'free' => 1,
616 'media' => 1,
617 'software' => 1,
618 'stallman' => 1,
619 'stuff' => 1,
620 'web' => 1,
621 ];
622 $tags = self::$privateLinkDB->linksCountPerTag(['gnu'], 'public');
623
624 $this->assertEquals($expected, $tags, var_export($tags, true));
625 }
626
627 /**
628 * Test linksCountPerTag public tags with filter.
629 * Equal occurrences should be sorted alphabetically.
630 */
631 public function testCountLinkPerTagPrivateWithFilter()
632 {
633 $expected = [
634 'cartoon' => 1,
635 'dev' => 1,
636 'tag1' => 1,
637 'tag2' => 1,
638 'tag3' => 1,
639 'tag4' => 1,
640 ];
641 $tags = self::$privateLinkDB->linksCountPerTag(['dev'], 'private');
642
643 $this->assertEquals($expected, $tags, var_export($tags, true));
644 }
545} 645}