]> git.immae.eu Git - github/shaarli/Shaarli.git/commitdiff
Merge pull request #887 from ArthurHoaro/hotfix/dash-tag-rename
authorArthurHoaro <arthur@hoa.ro>
Sat, 5 Aug 2017 07:59:03 +0000 (09:59 +0200)
committerGitHub <noreply@github.com>
Sat, 5 Aug 2017 07:59:03 +0000 (09:59 +0200)
Make sure that the tag exists before altering/removing it

application/LinkDB.php
index.php
tests/LinkDBTest.php

index 9e3efd6b4229a691dbd9028deb73d4428cbeeea1..9308164af685bd8830b6c1a4a68621fddaa9f548 100644 (file)
@@ -464,6 +464,39 @@ You use the community supported version of the original Shaarli project, by Seba
         return $tags;
     }
 
+    /**
+     * Rename or delete a tag across all links.
+     *
+     * @param string $from Tag to rename
+     * @param string $to   New tag. If none is provided, the from tag will be deleted
+     *
+     * @return array|bool List of altered links or false on error
+     */
+    public function renameTag($from, $to)
+    {
+        if (empty($from)) {
+            return false;
+        }
+        $delete = empty($to);
+        // True for case-sensitive tag search.
+        $linksToAlter = $this->filterSearch(['searchtags' => $from], true);
+        foreach($linksToAlter as $key => &$value)
+        {
+            $tags = preg_split('/\s+/', trim($value['tags']));
+            if (($pos = array_search($from, $tags)) !== false) {
+                if ($delete) {
+                    unset($tags[$pos]); // Remove tag.
+                } else {
+                    $tags[$pos] = trim($to);
+                }
+                $value['tags'] = trim(implode(' ', array_unique($tags)));
+                $this[$value['id']] = $value;
+            }
+        }
+
+        return $linksToAlter;
+    }
+
     /**
      * Returns the list of days containing articles (oldest first)
      * Output: An array containing days (in format YYYYMMDD).
index 5c292b04489cf55da21fb2b2071462c960a4ae99..9025df58f03202aaad35c32c58160ebe902e30d9 100644 (file)
--- a/index.php
+++ b/index.php
@@ -686,6 +686,7 @@ function showLinkList($PAGE, $LINKSDB, $conf, $pluginManager) {
  * @param ConfigManager $conf          Configuration Manager instance.
  * @param PluginManager $pluginManager Plugin Manager instance,
  * @param LinkDB        $LINKSDB
+ * @param History       $history       instance
  */
 function renderPage($conf, $pluginManager, $LINKSDB, $history)
 {
@@ -1198,41 +1199,18 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history)
             die('Wrong token.');
         }
 
-        // Delete a tag:
-        if (isset($_POST['deletetag']) && !empty($_POST['fromtag'])) {
-            $needle = trim($_POST['fromtag']);
-            // True for case-sensitive tag search.
-            $linksToAlter = $LINKSDB->filterSearch(array('searchtags' => $needle), true);
-            foreach($linksToAlter as $key=>$value)
-            {
-                $tags = explode(' ',trim($value['tags']));
-                unset($tags[array_search($needle,$tags)]); // Remove tag.
-                $value['tags']=trim(implode(' ',$tags));
-                $LINKSDB[$key]=$value;
-                $history->updateLink($LINKSDB[$key]);
-            }
-            $LINKSDB->save($conf->get('resource.page_cache'));
-            echo '<script>alert("Tag was removed from '.count($linksToAlter).' links.");document.location=\'?do=changetag\';</script>';
-            exit;
-        }
-
-        // Rename a tag:
-        if (isset($_POST['renametag']) && !empty($_POST['fromtag']) && !empty($_POST['totag'])) {
-            $needle = trim($_POST['fromtag']);
-            // True for case-sensitive tag search.
-            $linksToAlter = $LINKSDB->filterSearch(array('searchtags' => $needle), true);
-            foreach($linksToAlter as $key=>$value) {
-                $tags = preg_split('/\s+/', trim($value['tags']));
-                // Replace tags value.
-                $tags[array_search($needle, $tags)] = trim($_POST['totag']);
-                $value['tags'] = implode(' ', array_unique($tags));
-                $LINKSDB[$key] = $value;
-                $history->updateLink($LINKSDB[$key]);
-            }
-            $LINKSDB->save($conf->get('resource.page_cache')); // Save to disk.
-            echo '<script>alert("Tag was renamed in '.count($linksToAlter).' links.");document.location=\'?searchtags='.urlencode(escape($_POST['totag'])).'\';</script>';
-            exit;
+        $alteredLinks = $LINKSDB->renameTag(escape($_POST['fromtag']), escape($_POST['totag']));
+        $LINKSDB->save($conf->get('resource.page_cache'));
+        foreach ($alteredLinks as $link) {
+            $history->updateLink($link);
         }
+        $delete = empty($_POST['totag']);
+        $redirect = $delete ? 'do=changetag' : 'searchtags='. urlencode(escape($_POST['totag']));
+        $alert = $delete
+            ? sprintf(t('The tag was removed from %d links.'), count($alteredLinks))
+            : sprintf(t('The tag was renamed in %d links.'), count($alteredLinks));
+        echo '<script>alert("'. $alert .'");document.location=\'?'. $redirect .'\';</script>';
+        exit;
     }
 
     // -------- User wants to add a link without using the bookmarklet: Show form.
@@ -2259,6 +2237,12 @@ if (!isset($_SESSION['LINKS_PER_PAGE'])) {
     $_SESSION['LINKS_PER_PAGE'] = $conf->get('general.links_per_page', 20);
 }
 
+try {
+    $history = new History($conf->get('resource.history'));
+} catch(Exception $e) {
+    die($e->getMessage());
+}
+
 $linkDb = new LinkDB(
     $conf->get('resource.datastore'),
     isLoggedIn(),
@@ -2267,12 +2251,6 @@ $linkDb = new LinkDB(
     $conf->get('redirector.encode_url')
 );
 
-try {
-    $history = new History($conf->get('resource.history'));
-} catch(Exception $e) {
-    die($e->getMessage());
-}
-
 $container = new \Slim\Container();
 $container['conf'] = $conf;
 $container['plugins'] = $pluginManager;
index 25438277e5babf1b7850c3dd65fd92972c7c37aa..5b2f366766b73d62d27a0a487c8d037531a2bd92 100644 (file)
@@ -487,4 +487,59 @@ class LinkDBTest extends PHPUnit_Framework_TestCase
             $this->assertEquals($linkIds[$cpt++], $key);
         }
     }
+
+    /**
+     * Test rename tag with a valid value present in multiple links
+     */
+    public function testRenameTagMultiple()
+    {
+        self::$refDB->write(self::$testDatastore);
+        $linkDB = new LinkDB(self::$testDatastore, true, false);
+
+        $res = $linkDB->renameTag('cartoon', 'Taz');
+        $this->assertEquals(3, count($res));
+        $this->assertContains(' Taz ', $linkDB[4]['tags']);
+        $this->assertContains(' Taz ', $linkDB[1]['tags']);
+        $this->assertContains(' Taz ', $linkDB[0]['tags']);
+    }
+
+    /**
+     * Test rename tag with a valid value
+     */
+    public function testRenameTagCaseSensitive()
+    {
+        self::$refDB->write(self::$testDatastore);
+        $linkDB = new LinkDB(self::$testDatastore, true, false, '');
+
+        $res = $linkDB->renameTag('sTuff', 'Taz');
+        $this->assertEquals(1, count($res));
+        $this->assertEquals('Taz', $linkDB[41]['tags']);
+    }
+
+    /**
+     * Test rename tag with invalid values
+     */
+    public function testRenameTagInvalid()
+    {
+        $linkDB = new LinkDB(self::$testDatastore, false, false);
+
+        $this->assertFalse($linkDB->renameTag('', 'test'));
+        $this->assertFalse($linkDB->renameTag('', ''));
+        // tag non existent
+        $this->assertEquals([], $linkDB->renameTag('test', ''));
+        $this->assertEquals([], $linkDB->renameTag('test', 'retest'));
+    }
+
+    /**
+     * Test delete tag with a valid value
+     */
+    public function testDeleteTag()
+    {
+        self::$refDB->write(self::$testDatastore);
+        $linkDB = new LinkDB(self::$testDatastore, true, false);
+
+        $res = $linkDB->renameTag('cartoon', null);
+        $this->assertEquals(3, count($res));
+        $this->assertNotContains('cartoon', $linkDB[4]['tags']);
+    }
 }