]> git.mxchange.org Git - friendica.git/commitdiff
Merge pull request #7199 from MrPetovan/bug/7171-filer-network
authorPhilipp <admin+Github@philipp.info>
Wed, 29 May 2019 05:03:44 +0000 (07:03 +0200)
committerGitHub <noreply@github.com>
Wed, 29 May 2019 05:03:44 +0000 (07:03 +0200)
Allow commas in saved folder names

15 files changed:
boot.php
include/text.php
mod/item.php
mod/network.php
src/App.php
src/Content/ForumManager.php
src/Content/Widget.php
src/Model/FileTag.php
src/Module/Filer/RemoveTag.php
src/Module/Filer/SaveTag.php
tests/src/Model/FileTagTest.php [new file with mode: 0644]
view/templates/saved_searches_aside.tpl
view/theme/frio/templates/saved_searches_aside.tpl
view/theme/quattro/templates/saved_searches_aside.tpl
view/theme/vier/theme.php

index b8705fdf133cadb057f0ec82cab00d688a6971b5..eb04732c5d87bcc56cdda0784f1a061bd9db0289 100644 (file)
--- a/boot.php
+++ b/boot.php
@@ -534,39 +534,6 @@ function is_site_admin()
        return local_user() && $admin_email && in_array(defaults($a->user, 'email', ''), $adminlist);
 }
 
-/**
- * @brief Returns querystring as string from a mapped array.
- *
- * @param array  $params mapped array with query parameters
- * @param string $name   of parameter, default null
- *
- * @return string
- */
-function build_querystring($params, $name = null)
-{
-       $ret = "";
-       foreach ($params as $key => $val) {
-               if (is_array($val)) {
-                       /// @TODO maybe not compare against null, use is_null()
-                       if ($name == null) {
-                               $ret .= build_querystring($val, $key);
-                       } else {
-                               $ret .= build_querystring($val, $name . "[$key]");
-                       }
-               } else {
-                       $val = urlencode($val);
-                       /// @TODO maybe not compare against null, use is_null()
-                       if ($name != null) {
-                               /// @TODO two string concated, can be merged to one
-                               $ret .= $name . "[$key]" . "=$val&";
-                       } else {
-                               $ret .= "$key=$val&";
-                       }
-               }
-       }
-       return $ret;
-}
-
 function explode_querystring($query)
 {
        $arg_st = strpos($query, '?');
index c4249f86c49acc47d245163f3eed9bd3787ff866..eb65334fd94e72469c33ee7a2b31ca36a8e15c7c 100644 (file)
@@ -8,10 +8,8 @@ use Friendica\Content\Smilies;
 use Friendica\Content\Text\BBCode;
 use Friendica\Core\Protocol;
 use Friendica\Model\Contact;
-
 use Friendica\Model\FileTag;
 use Friendica\Util\Strings;
-use Friendica\Util\XML;
 
 /**
  * Turn user/group ACLs stored as angle bracketed text into arrays
@@ -186,21 +184,17 @@ function get_cats_and_terms($item)
 {
        $categories = [];
        $folders = [];
-
-       $matches = [];
        $first = true;
-       $cnt = preg_match_all('/<(.*?)>/', $item['file'], $matches, PREG_SET_ORDER);
-       if ($cnt) {
-               foreach ($matches as $mtch) {
-                       $categories[] = [
-                               'name' => XML::escape(FileTag::decode($mtch[1])),
-                               'url' =>  "#",
-                               'removeurl' => ((local_user() == $item['uid'])?'filerm/' . $item['id'] . '?f=&cat=' . XML::escape(FileTag::decode($mtch[1])):""),
-                               'first' => $first,
-                               'last' => false
-                       ];
-                       $first = false;
-               }
+
+       foreach (FileTag::fileToArray($item['file'], 'category') as $savedFolderName) {
+               $categories[] = [
+                       'name' => $savedFolderName,
+                       'url' => "#",
+                       'removeurl' => ((local_user() == $item['uid']) ? 'filerm/' . $item['id'] . '?f=&cat=' . rawurlencode($savedFolderName) : ""),
+                       'first' => $first,
+                       'last' => false
+               ];
+               $first = false;
        }
 
        if (count($categories)) {
@@ -208,20 +202,15 @@ function get_cats_and_terms($item)
        }
 
        if (local_user() == $item['uid']) {
-               $matches = [];
-               $first = true;
-               $cnt = preg_match_all('/\[(.*?)\]/', $item['file'], $matches, PREG_SET_ORDER);
-               if ($cnt) {
-                       foreach ($matches as $mtch) {
-                               $folders[] = [
-                                       'name' => XML::escape(FileTag::decode($mtch[1])),
-                                       'url' =>  "#",
-                                       'removeurl' => ((local_user() == $item['uid']) ? 'filerm/' . $item['id'] . '?f=&term=' . XML::escape(FileTag::decode($mtch[1])) : ""),
-                                       'first' => $first,
-                                       'last' => false
-                               ];
-                               $first = false;
-                       }
+               foreach (FileTag::fileToArray($item['file']) as $savedFolderName) {
+                       $folders[] = [
+                               'name' => $savedFolderName,
+                               'url' => "#",
+                               'removeurl' => ((local_user() == $item['uid']) ? 'filerm/' . $item['id'] . '?f=&term=' . rawurlencode($savedFolderName) : ""),
+                               'first' => $first,
+                               'last' => false
+                       ];
+                       $first = false;
                }
        }
 
index b126c4825b6ef7a8ca83f517a9edc52f08352e9c..7af5c712f6b3bbf59fdf4705fa5f9516344ade4a 100644 (file)
@@ -327,10 +327,9 @@ function item_post(App $a) {
                }
        }
 
-       if (!empty($categories))
-       {
+       if (!empty($categories)) {
                // get the "fileas" tags for this post
-               $filedas = FileTag::fileToList($categories, 'file');
+               $filedas = FileTag::fileToArray($categories);
        }
 
        // save old and new categories, so we can determine what needs to be deleted from pconfig
@@ -338,10 +337,9 @@ function item_post(App $a) {
        $categories = FileTag::listToFile(trim(defaults($_REQUEST, 'category', '')), 'category');
        $categories_new = $categories;
 
-       if (!empty($filedas))
-       {
+       if (!empty($filedas)) {
                // append the fileas stuff to the new categories list
-               $categories .= FileTag::listToFile($filedas, 'file');
+               $categories .= FileTag::arrayToFile($filedas);
        }
 
        // get contact info for poster
index c8786b2f7b372b47fd5640e468fa77718e5d7e44..7753ba2ca4f1373e3e09a750f48e17c8ced43e0c 100644 (file)
@@ -77,9 +77,7 @@ function network_init(App $a)
 
        // convert query string to array. remove friendica args
        $query_array = [];
-       $query_string = str_replace($a->cmd . '?', '', $a->query_string);
-       parse_str($query_string, $query_array);
-       array_shift($query_array);
+       parse_str(parse_url($a->query_string, PHP_URL_QUERY), $query_array);
 
        // fetch last used network view and redirect if needed
        if (!$is_a_date_query) {
@@ -99,7 +97,7 @@ function network_init(App $a)
 
                if ($remember_tab) {
                        // redirect if current selected tab is '/network' and
-                       // last selected tab is _not_ '/network?f=&order=comment'.
+                       // last selected tab is _not_ '/network?order=comment'.
                        // and this isn't a date query
 
                        $tab_baseurls = [
@@ -111,12 +109,12 @@ function network_init(App $a)
                                '',     //bookmarked
                        ];
                        $tab_args = [
-                               'f=&order=comment', //all
-                               'f=&order=post',    //postord
-                               'f=&conv=1',        //conv
+                               'order=comment', //all
+                               'order=post',    //postord
+                               'conv=1',        //conv
                                '',                 //new
-                               'f=&star=1',        //starred
-                               'f=&bmark=1',       //bookmarked
+                               'star=1',        //starred
+                               'bmark=1',       //bookmarked
                        ];
 
                        $k = array_search('active', $last_sel_tabs);
@@ -140,7 +138,7 @@ function network_init(App $a)
 
                if ($remember_tab) {
                        $net_args = array_merge($query_array, $net_args);
-                       $net_queries = build_querystring($net_args);
+                       $net_queries = http_build_query($net_args);
 
                        $redir_url = ($net_queries ? $net_baseurl . '?' . $net_queries : $net_baseurl);
 
@@ -202,12 +200,12 @@ function saved_searches($search)
  *
  * urls -> returns
  *        '/network'                    => $no_active = 'active'
- *        '/network?f=&order=comment'    => $comment_active = 'active'
- *        '/network?f=&order=post'    => $postord_active = 'active'
- *        '/network?f=&conv=1',        => $conv_active = 'active'
+ *        '/network?order=comment'    => $comment_active = 'active'
+ *        '/network?order=post'    => $postord_active = 'active'
+ *        '/network?conv=1',        => $conv_active = 'active'
  *        '/network/new',                => $new_active = 'active'
- *        '/network?f=&star=1',        => $starred_active = 'active'
- *        '/network?f=&bmark=1',        => $bookmarked_active = 'active'
+ *        '/network?star=1',        => $starred_active = 'active'
+ *        '/network?bmark=1',        => $bookmarked_active = 'active'
  *
  * @param App $a
  * @return array ($no_active, $comment_active, $postord_active, $conv_active, $new_active, $starred_active, $bookmarked_active);
@@ -973,7 +971,7 @@ function network_tabs(App $a)
        $tabs = [
                [
                        'label' => L10n::t('Commented Order'),
-                       'url'   => str_replace('/new', '', $cmd) . '?f=&order=comment' . (!empty($_GET['cid']) ? '&cid=' . $_GET['cid'] : ''),
+                       'url'   => str_replace('/new', '', $cmd) . '?order=comment' . (!empty($_GET['cid']) ? '&cid=' . $_GET['cid'] : ''),
                        'sel'   => $all_active,
                        'title' => L10n::t('Sort by Comment Date'),
                        'id'    => 'commented-order-tab',
@@ -981,7 +979,7 @@ function network_tabs(App $a)
                ],
                [
                        'label' => L10n::t('Posted Order'),
-                       'url'   => str_replace('/new', '', $cmd) . '?f=&order=post' . (!empty($_GET['cid']) ? '&cid=' . $_GET['cid'] : ''),
+                       'url'   => str_replace('/new', '', $cmd) . '?order=post' . (!empty($_GET['cid']) ? '&cid=' . $_GET['cid'] : ''),
                        'sel'   => $postord_active,
                        'title' => L10n::t('Sort by Post Date'),
                        'id'    => 'posted-order-tab',
@@ -991,7 +989,7 @@ function network_tabs(App $a)
 
        $tabs[] = [
                'label' => L10n::t('Personal'),
-               'url'   => str_replace('/new', '', $cmd) . (!empty($_GET['cid']) ? '/?f=&cid=' . $_GET['cid'] : '/?f=') . '&conv=1',
+               'url'   => str_replace('/new', '', $cmd) . (!empty($_GET['cid']) ? '/?cid=' . $_GET['cid'] : '/?f=') . '&conv=1',
                'sel'   => $conv_active,
                'title' => L10n::t('Posts that mention or involve you'),
                'id'    => 'personal-tab',
@@ -1001,7 +999,7 @@ function network_tabs(App $a)
        if (Feature::isEnabled(local_user(), 'new_tab')) {
                $tabs[] = [
                        'label' => L10n::t('New'),
-                       'url'   => 'network/new' . (!empty($_GET['cid']) ? '/?f=&cid=' . $_GET['cid'] : ''),
+                       'url'   => 'network/new' . (!empty($_GET['cid']) ? '/?cid=' . $_GET['cid'] : ''),
                        'sel'   => $new_active,
                        'title' => L10n::t('Activity Stream - by date'),
                        'id'    => 'activitiy-by-date-tab',
@@ -1012,7 +1010,7 @@ function network_tabs(App $a)
        if (Feature::isEnabled(local_user(), 'link_tab')) {
                $tabs[] = [
                        'label' => L10n::t('Shared Links'),
-                       'url'   => str_replace('/new', '', $cmd) . (!empty($_GET['cid']) ? '/?f=&cid=' . $_GET['cid'] : '/?f=') . '&bmark=1',
+                       'url'   => str_replace('/new', '', $cmd) . (!empty($_GET['cid']) ? '/?cid=' . $_GET['cid'] : '/?f=') . '&bmark=1',
                        'sel'   => $bookmarked_active,
                        'title' => L10n::t('Interesting Links'),
                        'id'    => 'shared-links-tab',
@@ -1022,7 +1020,7 @@ function network_tabs(App $a)
 
        $tabs[] = [
                'label' => L10n::t('Starred'),
-               'url'   => str_replace('/new', '', $cmd) . (!empty($_GET['cid']) ? '/?f=&cid=' . $_GET['cid'] : '/?f=') . '&star=1',
+               'url'   => str_replace('/new', '', $cmd) . (!empty($_GET['cid']) ? '/?cid=' . $_GET['cid'] : '/?f=') . '&star=1',
                'sel'   => $starred_active,
                'title' => L10n::t('Favourite Posts'),
                'id'    => 'starred-posts-tab',
index 2e357f8651a6e738aa31ab106429fcfcef6d96c6..e5ec66f5e3815bbe3ce724d039a5c162bf5cce02 100644 (file)
@@ -1104,7 +1104,7 @@ class App
 
                // Compatibility with the Android Diaspora client
                if ($this->module == 'stream') {
-                       $this->internalRedirect('network?f=&order=post');
+                       $this->internalRedirect('network?order=post');
                }
 
                if ($this->module == 'conversations') {
@@ -1112,15 +1112,15 @@ class App
                }
 
                if ($this->module == 'commented') {
-                       $this->internalRedirect('network?f=&order=comment');
+                       $this->internalRedirect('network?order=comment');
                }
 
                if ($this->module == 'liked') {
-                       $this->internalRedirect('network?f=&order=comment');
+                       $this->internalRedirect('network?order=comment');
                }
 
                if ($this->module == 'activity') {
-                       $this->internalRedirect('network/?f=&conv=1');
+                       $this->internalRedirect('network?conv=1');
                }
 
                if (($this->module == 'status_messages') && ($this->cmd == 'status_messages/new')) {
index af2c3725c40700f6a3d068d6f348fb4a3c72de1f..98ea7aa6b97456fad2b8860205dc85d468080a7f 100644 (file)
@@ -111,7 +111,7 @@ class ForumManager
                                $selected = (($cid == $contact['id']) ? ' forum-selected' : '');
 
                                $entry = [
-                                       'url' => 'network?f=&cid=' . $contact['id'],
+                                       'url' => 'network?cid=' . $contact['id'],
                                        'external_url' => Contact::magicLink($contact['url']),
                                        'name' => $contact['name'],
                                        'cid' => $contact['id'],
index 066c17413a3a8db9b56da401f1b5e481a339cb08..dcfc1d0e3d95da631db6899dc781c10eff9f017c 100644 (file)
@@ -256,7 +256,7 @@ class Widget
         * @param string $baseurl  baseurl
         * @param string $selected optional, default empty
         * @return string|void
-        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
+        * @throws \Exception
         */
        public static function fileAs($baseurl, $selected = '')
        {
@@ -269,15 +269,9 @@ class Widget
                        return;
                }
 
-               $matches = [];
-               $terms = array();
-               $cnt = preg_match_all('/\[(.*?)\]/', $saved, $matches, PREG_SET_ORDER);
-               if ($cnt) {
-                       foreach ($matches as $mtch)
-                       {
-                               $unescaped = XML::escape(FileTag::decode($mtch[1]));
-                               $terms[] = ['ref' => $unescaped, 'name' => $unescaped];
-                       }
+               $terms = [];
+               foreach (FileTag::fileToArray($saved) as $savedFolderName) {
+                       $terms[] = ['ref' => $savedFolderName, 'name' => $savedFolderName];
                }
 
                return self::filter(
@@ -312,15 +306,9 @@ class Widget
                        return;
                }
 
-               $matches = [];
                $terms = array();
-               $cnt = preg_match_all('/<(.*?)>/', $saved, $matches, PREG_SET_ORDER);
-
-               if ($cnt) {
-                       foreach ($matches as $mtch) {
-                               $unescaped = XML::escape(FileTag::decode($mtch[1]));
-                               $terms[] = ['ref' => $unescaped, 'name' => $unescaped];
-                       }
+               foreach (FileTag::fileToArray($saved, 'category') as $savedFolderName) {
+                       $terms[] = ['ref' => $savedFolderName, 'name' => $savedFolderName];
                }
 
                return self::filter(
index 2ad864c9c4d1fe4cce6db1fa3fa6919a2b9ff48c..c743cb127827946ebcc03b163044a7e02d9a8f63 100644 (file)
@@ -11,127 +11,149 @@ use Friendica\Database\DBA;
 
 /**
  * @brief This class handles FileTag related functions
+ *
+ * post categories and "save to file" use the same item.file table for storage.
+ * We will differentiate the different uses by wrapping categories in angle brackets
+ * and save to file categories in square brackets.
+ * To do this we need to escape these characters if they appear in our tag.
  */
 class FileTag
 {
-    // post categories and "save to file" use the same item.file table for storage.
-    // We will differentiate the different uses by wrapping categories in angle brackets
-    // and save to file categories in square brackets.
-    // To do this we need to escape these characters if they appear in our tag.
-
-    /**
-     * @brief URL encode &lt, &gt, left and right brackets
-     * 
-     * @param string $s String to be URL encoded.
-     * 
-     * @return string   The URL encoded string.
-     */
-    public static function encode($s)
-    {
-        return str_replace(['<', '>', '[', ']'], ['%3c', '%3e', '%5b', '%5d'], $s);
-    }
-
-    /**
-     * @brief URL decode &lt, &gt, left and right brackets
-     * 
-     * @param string $s The URL encoded string to be decoded
-     * 
-     * @return string   The decoded string.
-     */
-    public static function decode($s)
-    {
-        return str_replace(['%3c', '%3e', '%5b', '%5d'], ['<', '>', '[', ']'], $s);
-    }
-
-    /**
-     * @brief Query files for tag
-     * 
-     * @param string $table The table to be queired.
-     * @param string $s     The search term
-     * @param string $type  Optional file type.
-     * 
-     * @return string       Query string.
-     */
-    public static function fileQuery($table, $s, $type = 'file')
-    {
-        if ($type == 'file') {
-            $str = preg_quote('[' . str_replace('%', '%%', self::encode($s)) . ']');
-        } else {
-            $str = preg_quote('<' . str_replace('%', '%%', self::encode($s)) . '>');
-        }
-
-        return " AND " . (($table) ? DBA::escape($table) . '.' : '') . "file regexp '" . DBA::escape($str) . "' ";
-    }
-
-    /**
-     * @brief Get file tags from list
-     * 
-     * ex. given music,video return <music><video> or [music][video]
-     * @param string $list  A comma delimited list of tags.
-     * @param string $type  Optional file type.
-     * 
-     * @return string       A list of file tags.
-     */
-    public static function listToFile($list, $type = 'file')
-    {
-        $tag_list = '';
-        if (strlen($list)) {
-            $list_array = explode(",", $list);
-            if ($type == 'file') {
-                $lbracket = '[';
-                $rbracket = ']';
-            } else {
-                $lbracket = '<';
-                $rbracket = '>';
-            }
-
-            foreach ($list_array as $item)
-            {
-                if (strlen($item))
-                {
-                    $tag_list .= $lbracket . self::encode(trim($item))  . $rbracket;
-                }
-            }
-        }
-
-        return $tag_list;
-    }
-
-    /**
-     * @brief Get list from file tags
-     * 
-     * ex. given <music><video>[friends], return music,video or friends
-     * @param string $file  File tags
-     * @param string $type  Optional file type.
-     * 
-     * @return string       Comma delimited list of tag names.
-     */
-    public static function fileToList($file, $type = 'file')
-    {
-        $matches = false;
-        $list = '';
-
-        if ($type == 'file') {
-            $cnt = preg_match_all('/\[(.*?)\]/', $file, $matches, PREG_SET_ORDER);
-        } else {
-            $cnt = preg_match_all('/<(.*?)>/', $file, $matches, PREG_SET_ORDER);
-        }
-
-        if ($cnt)
-        {
-            foreach ($matches as $mtch)
-            {
-                if (strlen($list))
-                {
-                    $list .= ',';
-                }
-
-                $list .= self::decode($mtch[1]);
-            }
-        }
-
-        return $list;
-    }
+       /**
+        * @brief URL encode <, >, left and right brackets
+        *
+        * @param string $s String to be URL encoded.
+        *
+        * @return string   The URL encoded string.
+        */
+       public static function encode($s)
+       {
+               return str_replace(['<', '>', '[', ']'], ['%3c', '%3e', '%5b', '%5d'], $s);
+       }
+
+       /**
+        * @brief URL decode <, >, left and right brackets
+        *
+        * @param string $s The URL encoded string to be decoded
+        *
+        * @return string   The decoded string.
+        */
+       public static function decode($s)
+       {
+               return str_replace(['%3c', '%3e', '%5b', '%5d'], ['<', '>', '[', ']'], $s);
+       }
+
+       /**
+        * @brief Query files for tag
+        *
+        * @param string $table The table to be queired.
+        * @param string $s     The search term
+        * @param string $type  Optional file type.
+        *
+        * @return string       Query string.
+        */
+       public static function fileQuery($table, $s, $type = 'file')
+       {
+               if ($type == 'file') {
+                       $str = preg_quote('[' . str_replace('%', '%%', self::encode($s)) . ']');
+               } else {
+                       $str = preg_quote('<' . str_replace('%', '%%', self::encode($s)) . '>');
+               }
+
+               return " AND " . (($table) ? DBA::escape($table) . '.' : '') . "file regexp '" . DBA::escape($str) . "' ";
+       }
+
+       /**
+        * Get file tags from array
+        *
+        * ex. given [music,video] return <music><video> or [music][video]
+        *
+        * @param array  $array A list of tags.
+        * @param string $type  Optional file type.
+        *
+        * @return string       A list of file tags.
+        */
+       public static function arrayToFile(array $array, string $type = 'file')
+       {
+               $tag_list = '';
+               if ($type == 'file') {
+                       $lbracket = '[';
+                       $rbracket = ']';
+               } else {
+                       $lbracket = '<';
+                       $rbracket = '>';
+               }
+
+               foreach ($array as $item) {
+                       if (strlen($item)) {
+                               $tag_list .= $lbracket . self::encode(trim($item)) . $rbracket;
+                       }
+               }
+
+               return $tag_list;
+       }
+
+       /**
+        * Get tag list from file tags
+        *
+        * ex. given <music><video>[friends], return [music,video] or [friends]
+        *
+        * @param string $file File tags
+        * @param string $type Optional file type.
+        *
+        * @return array        List of tag names.
+        */
+       public static function fileToArray(string $file, string $type = 'file')
+       {
+               $matches = [];
+               $return = [];
+
+               if ($type == 'file') {
+                       $cnt = preg_match_all('/\[(.*?)\]/', $file, $matches, PREG_SET_ORDER);
+               } else {
+                       $cnt = preg_match_all('/<(.*?)>/', $file, $matches, PREG_SET_ORDER);
+               }
+
+               if ($cnt) {
+                       foreach ($matches as $match) {
+                               $return[] = self::decode($match[1]);
+                       }
+               }
+
+               return $return;
+       }
+
+       /**
+        * @brief      Get file tags from list
+        *
+        * ex. given music,video return <music><video> or [music][video]
+        * @param string $list A comma delimited list of tags.
+        * @param string $type Optional file type.
+        *
+        * @return string       A list of file tags.
+        * @deprecated since 2019.06 use arrayToFile() instead
+        */
+       public static function listToFile($list, $type = 'file')
+       {
+               $list_array = explode(',', $list);
+
+               return self::arrayToFile($list_array, $type);
+       }
+
+       /**
+        * @brief      Get list from file tags
+        *
+        * ex. given <music><video>[friends], return music,video or friends
+        * @param string $file File tags
+        * @param string $type Optional file type.
+        *
+        * @return string       Comma delimited list of tag names.
+        * @deprecated since 2019.06 use fileToArray() instead
+        */
+       public static function fileToList($file, $type = 'file')
+       {
+               return implode(',', self::fileToArray($file, $type));
+       }
 
        /**
         * @brief Update file tags in PConfig
@@ -142,83 +164,74 @@ class FileTag
         * @param string $type     Optional file type.
         *
         * @return boolean          A value indicating success or failure.
-        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
+        * @throws \Exception
         */
-    public static function updatePconfig($uid, $file_old, $file_new, $type = 'file')
-    {
-        if (!intval($uid)) {
-            return false;
-        } elseif ($file_old == $file_new) {
-            return true;
-        }
-
-        $saved = PConfig::get($uid, 'system', 'filetags');
-
-        if (strlen($saved))
-        {
-            if ($type == 'file') {
-                $lbracket = '[';
-                $rbracket = ']';
-                $termtype = TERM_FILE;
-            } else {
-                $lbracket = '<';
-                $rbracket = '>';
-                $termtype = TERM_CATEGORY;
-            }
-
-            $filetags_updated = $saved;
-
-            // check for new tags to be added as filetags in pconfig
-            $new_tags = [];
-            $check_new_tags = explode(",", self::fileToList($file_new, $type));
-
-            foreach ($check_new_tags as $tag)
-            {
-                if (!stristr($saved,$lbracket . self::encode($tag) . $rbracket)) {
-                    $new_tags[] = $tag;
-                }
-            }
-
-            $filetags_updated .= self::listToFile(implode(",", $new_tags), $type);
-
-            // check for deleted tags to be removed from filetags in pconfig
-            $deleted_tags = [];
-            $check_deleted_tags = explode(",", self::fileToList($file_old, $type));
-
-            foreach ($check_deleted_tags as $tag)
-            {
-                if (!stristr($file_new,$lbracket . self::encode($tag) . $rbracket)) {
-                    $deleted_tags[] = $tag;
-                }
-            }
-
-            foreach ($deleted_tags as $key => $tag)
-            {
-                $r = q("SELECT `oid` FROM `term` WHERE `term` = '%s' AND `otype` = %d AND `type` = %d AND `uid` = %d",
-                    DBA::escape($tag),
-                    intval(TERM_OBJ_POST),
-                    intval($termtype),
-                    intval($uid));
-
-                if (DBA::isResult($r)) {
-                    unset($deleted_tags[$key]);
-                } else {
-                    $filetags_updated = str_replace($lbracket . self::encode($tag) . $rbracket, '', $filetags_updated);
-                }
-            }
-
-            if ($saved != $filetags_updated)
-            {
-                PConfig::set($uid, 'system', 'filetags', $filetags_updated);
-            }
-
-            return true;
-        } elseif (strlen($file_new)) {
-            PConfig::set($uid, 'system', 'filetags', $file_new);
-        }
-
-        return true;
-    }
+       public static function updatePconfig($uid, $file_old, $file_new, $type = 'file')
+       {
+               if (!intval($uid)) {
+                       return false;
+               } elseif ($file_old == $file_new) {
+                       return true;
+               }
+
+               $saved = PConfig::get($uid, 'system', 'filetags');
+
+               if (strlen($saved)) {
+                       if ($type == 'file') {
+                               $lbracket = '[';
+                               $rbracket = ']';
+                               $termtype = TERM_FILE;
+                       } else {
+                               $lbracket = '<';
+                               $rbracket = '>';
+                               $termtype = TERM_CATEGORY;
+                       }
+
+                       $filetags_updated = $saved;
+
+                       // check for new tags to be added as filetags in pconfig
+                       $new_tags = [];
+                       foreach (self::fileToArray($file_new, $type) as $tag) {
+                               if (!stristr($saved, $lbracket . self::encode($tag) . $rbracket)) {
+                                       $new_tags[] = $tag;
+                               }
+                       }
+
+                       $filetags_updated .= self::arrayToFile($new_tags, $type);
+
+                       // check for deleted tags to be removed from filetags in pconfig
+                       $deleted_tags = [];
+                       foreach (self::fileToArray($file_old, $type) as $tag) {
+                               if (!stristr($file_new, $lbracket . self::encode($tag) . $rbracket)) {
+                                       $deleted_tags[] = $tag;
+                               }
+                       }
+
+                       foreach ($deleted_tags as $key => $tag) {
+                               $r = q("SELECT `oid` FROM `term` WHERE `term` = '%s' AND `otype` = %d AND `type` = %d AND `uid` = %d",
+                                       DBA::escape($tag),
+                                       intval(Term::OBJECT_TYPE_POST),
+                                       intval($termtype),
+                                       intval($uid));
+
+                               if (DBA::isResult($r)) {
+                                       unset($deleted_tags[$key]);
+                               } else {
+                                       $filetags_updated = str_replace($lbracket . self::encode($tag) . $rbracket, '', $filetags_updated);
+                               }
+                       }
+
+                       if ($saved != $filetags_updated) {
+                               PConfig::set($uid, 'system', 'filetags', $filetags_updated);
+                       }
+
+                       return true;
+               } elseif (strlen($file_new)) {
+                       PConfig::set($uid, 'system', 'filetags', $file_new);
+               }
+
+               return true;
+       }
 
        /**
         * @brief Add tag to file
@@ -230,34 +243,30 @@ class FileTag
         * @return boolean      A value indicating success or failure.
         * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         */
-    public static function saveFile($uid, $item_id, $file)
-    {
-        if (!intval($uid))
-        {
-            return false;
-        }
-
-        $item = Item::selectFirst(['file'], ['id' => $item_id, 'uid' => $uid]);
-        if (DBA::isResult($item))
-        {
-            if (!stristr($item['file'], '[' . self::encode($file) . ']'))
-            {
-                $fields = ['file' => $item['file'] . '[' . self::encode($file) . ']'];
-                Item::update($fields, ['id' => $item_id]);
-            }
-
-            $saved = PConfig::get($uid, 'system', 'filetags');
-
-            if (!strlen($saved) || !stristr($saved, '[' . self::encode($file) . ']'))
-            {
-                PConfig::set($uid, 'system', 'filetags', $saved . '[' . self::encode($file) . ']');
-            }
-
-            info(L10n::t('Item filed'));
-        }
-
-        return true;
-    }
+       public static function saveFile($uid, $item_id, $file)
+       {
+               if (!intval($uid)) {
+                       return false;
+               }
+
+               $item = Item::selectFirst(['file'], ['id' => $item_id, 'uid' => $uid]);
+               if (DBA::isResult($item)) {
+                       if (!stristr($item['file'], '[' . self::encode($file) . ']')) {
+                               $fields = ['file' => $item['file'] . '[' . self::encode($file) . ']'];
+                               Item::update($fields, ['id' => $item_id]);
+                       }
+
+                       $saved = PConfig::get($uid, 'system', 'filetags');
+
+                       if (!strlen($saved) || !stristr($saved, '[' . self::encode($file) . ']')) {
+                               PConfig::set($uid, 'system', 'filetags', $saved . '[' . self::encode($file) . ']');
+                       }
+
+                       info(L10n::t('Item filed'));
+               }
+
+               return true;
+       }
 
        /**
         * @brief Remove tag from file
@@ -270,45 +279,42 @@ class FileTag
         * @return boolean      A value indicating success or failure.
         * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         */
-    public static function unsaveFile($uid, $item_id, $file, $cat = false)
-    {
-        if (!intval($uid))
-        {
-            return false;
-        }
-
-        if ($cat == true) {
-            $pattern = '<' . self::encode($file) . '>';
-            $termtype = TERM_CATEGORY;
-        } else {
-            $pattern = '[' . self::encode($file) . ']';
-            $termtype = TERM_FILE;
-        }
-
-        $item = Item::selectFirst(['file'], ['id' => $item_id, 'uid' => $uid]);
-
-        if (!DBA::isResult($item))
-        {
-            return false;
-        }
-
-        $fields = ['file' => str_replace($pattern, '', $item['file'])];
-
-        Item::update($fields, ['id' => $item_id]);
-
-        $r = q("SELECT `oid` FROM `term` WHERE `term` = '%s' AND `otype` = %d AND `type` = %d AND `uid` = %d",
-            DBA::escape($file),
-            intval(TERM_OBJ_POST),
-            intval($termtype),
-            intval($uid)
-        );
-
-        if (!DBA::isResult($r))
-        {
-            $saved = PConfig::get($uid, 'system', 'filetags');
-            PConfig::set($uid, 'system', 'filetags', str_replace($pattern, '', $saved));
-        }
-
-        return true;
-    }
+       public static function unsaveFile($uid, $item_id, $file, $cat = false)
+       {
+               if (!intval($uid)) {
+                       return false;
+               }
+
+               if ($cat == true) {
+                       $pattern = '<' . self::encode($file) . '>';
+                       $termtype = Term::CATEGORY;
+               } else {
+                       $pattern = '[' . self::encode($file) . ']';
+                       $termtype = Term::FILE;
+               }
+
+               $item = Item::selectFirst(['file'], ['id' => $item_id, 'uid' => $uid]);
+
+               if (!DBA::isResult($item)) {
+                       return false;
+               }
+
+               $fields = ['file' => str_replace($pattern, '', $item['file'])];
+
+               Item::update($fields, ['id' => $item_id]);
+
+               $r = q("SELECT `oid` FROM `term` WHERE `term` = '%s' AND `otype` = %d AND `type` = %d AND `uid` = %d",
+                       DBA::escape($file),
+                       intval(Term::OBJECT_TYPE_POST),
+                       intval($termtype),
+                       intval($uid)
+               );
+
+               if (!DBA::isResult($r)) {
+                       $saved = PConfig::get($uid, 'system', 'filetags');
+                       PConfig::set($uid, 'system', 'filetags', str_replace($pattern, '', $saved));
+               }
+
+               return true;
+       }
 }
index bddaaf9dc2bfdb9d070dfcdaf6e09a3af5bd4048..7e88b2e72eece491bc57e4ee2c1772f778727216 100644 (file)
@@ -46,6 +46,6 @@ class RemoveTag extends BaseModule
                        info('Item was not deleted');
                }
 
-               $app->internalRedirect('/network?f=&file=' . rawurlencode($term));
+               $app->internalRedirect('network?file=' . rawurlencode($term));
        }
 }
index f5d6115199a2ca007333212cab6da91ed21e0225..aeafdbeb5905a379f8e5482805549930b5e37a3a 100644 (file)
@@ -41,8 +41,7 @@ class SaveTag extends BaseModule
 
                // return filer dialog
                $filetags = PConfig::get(local_user(), 'system', 'filetags');
-               $filetags = Model\FileTag::fileToList($filetags, 'file');
-               $filetags = explode(",", $filetags);
+               $filetags = Model\FileTag::fileToArray($filetags);
 
                $tpl = Renderer::getMarkupTemplate("filer_dialog.tpl");
                echo Renderer::replaceMacros($tpl, [
diff --git a/tests/src/Model/FileTagTest.php b/tests/src/Model/FileTagTest.php
new file mode 100644 (file)
index 0000000..f74bec3
--- /dev/null
@@ -0,0 +1,119 @@
+<?php
+
+namespace Friendica\Test\src\Model;
+
+use Friendica\Model\FileTag;
+use PHPUnit\Framework\TestCase;
+
+class FileTagTest extends TestCase
+{
+    public function dataArrayToFile()
+    {
+        return [
+            'list-category' => [
+                'array' => ['1', '2', '3', 'a', 'b', 'c'],
+                'type' => 'category',
+                'file' => '<1><2><3><a><b><c>',
+            ],
+            'list-file' => [
+                'array' => ['1', '2', '3', 'a', 'b', 'c'],
+                'type' => 'file',
+                'file' => '[1][2][3][a][b][c]',
+            ],
+            'chevron-category' => [
+                'array' => ['Left < Center > Right'],
+                'type' => 'category',
+                'file' => '<Left %3c Center %3e Right>',
+            ],
+            'bracket-file' => [
+                'array' => ['Glass [half-full]'],
+                'type' => 'file',
+                'file' => '[Glass %5bhalf-full%5d]',
+            ],
+            /** @see https://github.com/friendica/friendica/issues/7171 */
+            'bug-7171-category' => [
+                'array' => ['Science, Health, Medicine'],
+                'type' => 'category',
+                'file' => '<Science, Health, Medicine>',
+            ],
+            'bug-7171-file' => [
+                'array' => ['Science, Health, Medicine'],
+                'type' => 'file',
+                'file' => '[Science, Health, Medicine]',
+            ],
+        ];
+    }
+
+    /**
+     * Test convert saved folders arrays to a file/category field
+     * @dataProvider dataArrayToFile
+     *
+     * @param array  $array
+     * @param string $type
+     * @param string $file
+     */
+    public function testArrayToFile(array $array, string $type, string $file)
+    {
+        $this->assertEquals($file, FileTag::arrayToFile($array, $type));
+    }
+
+    public function dataFileToArray()
+    {
+        return [
+            'list-category' => [
+                'file' => '<1><2><3><a><b><c>',
+                'type' => 'category',
+                'array' => ['1', '2', '3', 'a', 'b', 'c'],
+            ],
+            'list-file' => [
+                'file' => '[1][2][3][a][b][c]',
+                'type' => 'file',
+                'array' => ['1', '2', '3', 'a', 'b', 'c'],
+            ],
+            'combinedlist-category' => [
+                'file' => '[1][2][3]<a><b><c>',
+                'type' => 'category',
+                'array' => ['a', 'b', 'c'],
+            ],
+            'combinedlist-file' => [
+                'file' => '[1][2][3]<a><b><c>',
+                'type' => 'file',
+                'array' => ['1', '2', '3'],
+            ],
+            'chevron-category' => [
+                'file' => '<Left %3c Center %3e Right>',
+                'type' => 'category',
+                'array' => ['Left < Center > Right'],
+            ],
+            'bracket-file' => [
+                'file' => '[Glass %5bhalf-full%5d]',
+                'type' => 'file',
+                'array' => ['Glass [half-full]'],
+            ],
+            /** @see https://github.com/friendica/friendica/issues/7171 */
+            'bug-7171-category' => [
+                'file' => '<Science, Health, Medicine>',
+                'type' => 'category',
+                'array' => ['Science, Health, Medicine'],
+            ],
+            'bug-7171-file' => [
+                'file' => '[Science, Health, Medicine]',
+                'type' => 'file',
+                'array' => ['Science, Health, Medicine'],
+            ],
+        ];
+    }
+
+    /**
+     * Test convert different saved folders to a file/category field
+     * @dataProvider dataFileToArray
+     *
+     * @param string $file
+     * @param string $type
+     * @param array  $array
+     */
+    public function testFileToArray(string $file, string $type, array $array)
+    {
+        $this->assertEquals($array, FileTag::fileToArray($file, $type));
+    }
+}
index 5000e4acb1186af5912f14f278f3c49fd2b36e08..caf60cc0bc68fe310c2fc98667edea5675af5a50 100644 (file)
@@ -6,7 +6,7 @@
        <ul role="menu" id="saved-search-ul">
                {{foreach $saved as $search}}
                <li role="menuitem" class="saved-search-li clear">
-                       <a title="{{$search.delete}}" onclick="return confirmDelete();" id="drop-saved-search-term-{{$search.id}}" class="iconspacer savedsearchdrop " href="network/?f=&amp;remove=1&amp;search={{$search.encodedterm}}"></a>
+                       <a title="{{$search.delete}}" onclick="return confirmDelete();" id="drop-saved-search-term-{{$search.id}}" class="iconspacer savedsearchdrop " href="network?remove=1&amp;search={{$search.encodedterm}}"></a>
                        <a id="saved-search-term-{{$search.id}}" class="savedsearchterm" href="search?search={{$search.encodedterm}}">{{$search.term}}</a>
                </li>
                {{/foreach}}
index 77444f48962fd95ad4c156d7b0494f8a5abb18aa..48b07bcdefbfe7510591dcc08b4490771b564c4b 100644 (file)
@@ -6,7 +6,7 @@
        <ul role="menu" id="saved-search-ul">
                {{foreach $saved as $search}}
                <li role="menuitem" class="saved-search-li clear">
-                       <a title="{{$search.delete}}" onclick="return confirmDelete();" id="drop-saved-search-term-{{$search.id}}" class="savedsearchdrop pull-right widget-action faded-icon" href="network/?f=&amp;remove=1&amp;search={{$search.encodedterm}}">
+                       <a title="{{$search.delete}}" onclick="return confirmDelete();" id="drop-saved-search-term-{{$search.id}}" class="savedsearchdrop pull-right widget-action faded-icon" href="network?remove=1&amp;search={{$search.encodedterm}}">
                                <i class="fa fa-trash" aria-hidden="true"></i>
                        </a>
                        <a id="saved-search-term-{{$search.id}}" class="savedsearchterm" href="search?search={{$search.encodedterm}}">{{$search.term}}</a>
index b1a945bc8380d534b9838a6e6b14598086a6be9c..4b2b001483d6bee446507a004777f4e10d9b9bf6 100644 (file)
@@ -5,7 +5,7 @@
                {{foreach $saved as $search}}
                        <li class="tool {{if $search.selected}}selected{{/if}}">
                                        <a href="search?search={{$search.encodedterm}}" class="label" >{{$search.term}}</a>
-                                       <a href="network/?f=&remove=1&search={{$search.encodedterm}}" class="action icon s10 delete" title="{{$search.delete}}" onclick="return confirmDelete();"></a>
+                                       <a href="network?remove=1&search={{$search.encodedterm}}" class="action icon s10 delete" title="{{$search.delete}}" onclick="return confirmDelete();"></a>
                        </li>
                {{/foreach}}
        </ul>
index 41553cf8c4aa765795bf81d5c98dbfd48d8d1175..3e4a837cd0d74e7db2f69d2443e4ae10d912aa38 100644 (file)
@@ -230,7 +230,7 @@ function vier_community_info()
                                $selected = (($cid == $contact['id']) ? ' forum-selected' : '');
 
                                $entry = [
-                                       'url'          => 'network?f=&cid=' . $contact['id'],
+                                       'url'          => 'network?cid=' . $contact['id'],
                                        'external_url' => Contact::magicLink($contact['url']),
                                        'name'         => $contact['name'],
                                        'cid'          => $contact['id'],