]> git.mxchange.org Git - friendica.git/commitdiff
Merge pull request #7765 from nupplaphil/task/move_text
authorHypolite Petovan <hypolite@mrpetovan.com>
Wed, 23 Oct 2019 19:57:01 +0000 (15:57 -0400)
committerGitHub <noreply@github.com>
Wed, 23 Oct 2019 19:57:01 +0000 (15:57 -0400)
Move include/text.php to class structure

33 files changed:
composer.json
doc/Addons.md
doc/de/Addons.md
include/conversation.php
include/text.php [deleted file]
mod/editpost.php
mod/events.php
mod/item.php
mod/lockview.php
mod/network.php
mod/photos.php
mod/settings.php
src/BaseObject.php
src/Content/Item.php [new file with mode: 0644]
src/Content/Text/BBCode/Video.php [new file with mode: 0644]
src/Model/Event.php
src/Model/Item.php
src/Model/Profile.php
src/Module/Item/Compose.php
src/Module/Profile.php
src/Object/Post.php
src/Protocol/Activity.php [new file with mode: 0644]
src/Protocol/DFRN.php
src/Util/ACLFormatter.php [new file with mode: 0644]
src/Util/DateTimeFormat.php
src/Worker/Notifier.php
tests/include/TextTest.php [deleted file]
tests/src/Content/ItemTest.php [new file with mode: 0644]
tests/src/Content/Text/BBCode/VideoTest.php [new file with mode: 0644]
tests/src/Core/InstallerTest.php
tests/src/Protocol/ActivityTest.php [new file with mode: 0644]
tests/src/Util/ACLFormaterTest.php [new file with mode: 0644]
tests/src/Util/DateTimeFormatTest.php [new file with mode: 0644]

index 9ed9017d85a4fa55088c7b2f3b6021782aa15d9e..83b51a17470350bdc2585395ded22eea1c5e41f6 100644 (file)
@@ -83,7 +83,6 @@
                        "include/dba.php",
                        "include/enotify.php",
                        "include/items.php",
-                       "include/text.php",
                        "boot.php"
                ]
        },
index 0382cee49ccf12e892fa54e6d87853b27c5bc92b..69b591a820f724f8a1936f0fafc0d124244e8140 100644 (file)
@@ -503,16 +503,6 @@ Here is a complete list of all hook callbacks with file locations (as of 24-Sep-
     Hook::callAll('item_photo_menu', $args);
     Hook::callAll('jot_tool', $jotplugins);
 
-### include/text.php
-
-    Hook::callAll('contact_block_end', $arr);
-    Hook::callAll('poke_verbs', $arr);
-    Hook::callAll('put_item_in_cache', $hook_data);
-    Hook::callAll('prepare_body_init', $item);
-    Hook::callAll('prepare_body_content_filter', $hook_data);
-    Hook::callAll('prepare_body', $hook_data);
-    Hook::callAll('prepare_body_final', $hook_data);
-
 ### include/items.php
 
     Hook::callAll('page_info_data', $data);
@@ -649,6 +639,11 @@ Here is a complete list of all hook callbacks with file locations (as of 24-Sep-
     Hook::callAll('post_remote_end', $posted_item);
     Hook::callAll('tagged', $arr);
     Hook::callAll('post_local_end', $new_item);
+    Hook::callAll('put_item_in_cache', $hook_data);
+    Hook::callAll('prepare_body_init', $item);
+    Hook::callAll('prepare_body_content_filter', $hook_data);
+    Hook::callAll('prepare_body', $hook_data);
+    Hook::callAll('prepare_body_final', $hook_data);
 
 ### src/Model/Contact.php
 
@@ -673,6 +668,10 @@ Here is a complete list of all hook callbacks with file locations (as of 24-Sep-
     Hook::callAll('register_account', $uid);
     Hook::callAll('remove_user', $user);
 
+### src/Content/ContactBlock.php
+
+    Hook::callAll('contact_block_end', $arr);
+
 ### src/Content/Text/BBCode.php
 
     Hook::callAll('bbcode', $text);
@@ -746,6 +745,10 @@ Here is a complete list of all hook callbacks with file locations (as of 24-Sep-
 
     self::callSingle(self::getApp(), 'hook_fork', $fork_hook, $hookdata);
 
+### src/Core/L10n/L10n.php
+
+    Hook::callAll('poke_verbs', $arr);
+
 ### src/Core/Worker.php
 
     Hook::callAll("proc_run", $arr);
index 3cbbb4b0bea9d1d6e2e36f748a6d0ec13238a4d6..755db95d018ce00634bfcd83e62b1e48b7d314f0 100644 (file)
@@ -226,16 +226,6 @@ Eine komplette Liste aller Hook-Callbacks mit den zugehörigen Dateien (am 01-Ap
     Hook::callAll('item_photo_menu', $args);
     Hook::callAll('jot_tool', $jotplugins);
 
-### include/text.php
-
-    Hook::callAll('contact_block_end', $arr);
-    Hook::callAll('poke_verbs', $arr);
-    Hook::callAll('put_item_in_cache', $hook_data);
-    Hook::callAll('prepare_body_init', $item);
-    Hook::callAll('prepare_body_content_filter', $hook_data);
-    Hook::callAll('prepare_body', $hook_data);
-    Hook::callAll('prepare_body_final', $hook_data);
-
 ### include/items.php
 
     Hook::callAll('page_info_data', $data);
@@ -365,6 +355,11 @@ Eine komplette Liste aller Hook-Callbacks mit den zugehörigen Dateien (am 01-Ap
     Hook::callAll('post_remote_end', $posted_item);
     Hook::callAll('tagged', $arr);
     Hook::callAll('post_local_end', $new_item);
+    Hook::callAll('put_item_in_cache', $hook_data);
+    Hook::callAll('prepare_body_init', $item);
+    Hook::callAll('prepare_body_content_filter', $hook_data);
+    Hook::callAll('prepare_body', $hook_data);
+    Hook::callAll('prepare_body_final', $hook_data);
 
 ### src/Model/Contact.php
 
@@ -387,6 +382,10 @@ Eine komplette Liste aller Hook-Callbacks mit den zugehörigen Dateien (am 01-Ap
 
     Hook::callAll('register_account', $uid);
     Hook::callAll('remove_user', $user);
+    
+### src/Content/ContactBlock.php
+
+    Hook::callAll('contact_block_end', $arr);
 
 ### src/Content/Text/BBCode.php
 
@@ -457,6 +456,18 @@ Eine komplette Liste aller Hook-Callbacks mit den zugehörigen Dateien (am 01-Ap
     Hook::callAll($a->module.'_post_'.$selname, $o);
     Hook::callAll('jot_networks', $jotnets);
 
+### src/Core/Authentication.php
+
+    Hook::callAll('logged_in', $a->user);
+
+### src/Core/Hook.php
+
+    self::callSingle(self::getApp(), 'hook_fork', $fork_hook, $hookdata);
+
+### src/Core/L10n/L10n.php
+
+    Hook::callAll('poke_verbs', $arr);
+
 ### src/Core/Worker.php
 
     Hook::callAll("proc_run", $arr);
index b6faa4d2c88e3e97f5f1b06449f9a7a3b0e0de88..8bcd1b338fd5d121ba72af7d8a332fad027bee11 100644 (file)
@@ -4,8 +4,10 @@
  */
 
 use Friendica\App;
+use Friendica\BaseObject;
 use Friendica\Content\ContactSelector;
 use Friendica\Content\Feature;
+use Friendica\Content\Item as ContentItem;
 use Friendica\Content\Pager;
 use Friendica\Content\Text\BBCode;
 use Friendica\Core\Config;
@@ -24,6 +26,7 @@ use Friendica\Model\Profile;
 use Friendica\Model\Term;
 use Friendica\Object\Post;
 use Friendica\Object\Thread;
+use Friendica\Protocol\Activity;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Proxy as ProxyUtils;
 use Friendica\Util\Temporal;
@@ -138,12 +141,15 @@ function localize_item(&$item)
        During the further steps of the database restructuring I would like to address this issue.
        */
 
+       /** @var Activity $activity */
+       $activity = BaseObject::getClass(Activity::class);
+
        $xmlhead = "<" . "?xml version='1.0' encoding='UTF-8' ?" . ">";
-       if (activity_match($item['verb'], ACTIVITY_LIKE)
-               || activity_match($item['verb'], ACTIVITY_DISLIKE)
-               || activity_match($item['verb'], ACTIVITY_ATTEND)
-               || activity_match($item['verb'], ACTIVITY_ATTENDNO)
-               || activity_match($item['verb'], ACTIVITY_ATTENDMAYBE)) {
+       if ($activity->match($item['verb'], ACTIVITY_LIKE)
+               || $activity->match($item['verb'], ACTIVITY_DISLIKE)
+               || $activity->match($item['verb'], ACTIVITY_ATTEND)
+               || $activity->match($item['verb'], ACTIVITY_ATTENDNO)
+               || $activity->match($item['verb'], ACTIVITY_ATTENDMAYBE)) {
 
                $fields = ['author-link', 'author-name', 'verb', 'object-type', 'resource-id', 'body', 'plink'];
                $obj = Item::selectFirst($fields, ['uri' => $item['parent-uri']]);
@@ -178,22 +184,22 @@ function localize_item(&$item)
                $plink = '[url=' . $obj['plink'] . ']' . $post_type . '[/url]';
 
                $bodyverb = '';
-               if (activity_match($item['verb'], ACTIVITY_LIKE)) {
+               if ($activity->match($item['verb'], ACTIVITY_LIKE)) {
                        $bodyverb = L10n::t('%1$s likes %2$s\'s %3$s');
-               } elseif (activity_match($item['verb'], ACTIVITY_DISLIKE)) {
+               } elseif ($activity->match($item['verb'], ACTIVITY_DISLIKE)) {
                        $bodyverb = L10n::t('%1$s doesn\'t like %2$s\'s %3$s');
-               } elseif (activity_match($item['verb'], ACTIVITY_ATTEND)) {
+               } elseif ($activity->match($item['verb'], ACTIVITY_ATTEND)) {
                        $bodyverb = L10n::t('%1$s attends %2$s\'s %3$s');
-               } elseif (activity_match($item['verb'], ACTIVITY_ATTENDNO)) {
+               } elseif ($activity->match($item['verb'], ACTIVITY_ATTENDNO)) {
                        $bodyverb = L10n::t('%1$s doesn\'t attend %2$s\'s %3$s');
-               } elseif (activity_match($item['verb'], ACTIVITY_ATTENDMAYBE)) {
+               } elseif ($activity->match($item['verb'], ACTIVITY_ATTENDMAYBE)) {
                        $bodyverb = L10n::t('%1$s attends maybe %2$s\'s %3$s');
                }
 
                $item['body'] = sprintf($bodyverb, $author, $objauthor, $plink);
        }
 
-       if (activity_match($item['verb'], ACTIVITY_FRIEND)) {
+       if ($activity->match($item['verb'], ACTIVITY_FRIEND)) {
 
                if ($item['object-type']=="" || $item['object-type']!== ACTIVITY_OBJ_PERSON) return;
 
@@ -275,7 +281,7 @@ function localize_item(&$item)
 
        }
 
-       if (activity_match($item['verb'], ACTIVITY_TAG)) {
+       if ($activity->match($item['verb'], ACTIVITY_TAG)) {
                $fields = ['author-id', 'author-link', 'author-name', 'author-network',
                        'verb', 'object-type', 'resource-id', 'body', 'plink'];
                $obj = Item::selectFirst($fields, ['uri' => $item['parent-uri']]);
@@ -320,7 +326,7 @@ function localize_item(&$item)
                $item['body'] = L10n::t('%1$s tagged %2$s\'s %3$s with %4$s', $author, $objauthor, $plink, $tag);
        }
 
-       if (activity_match($item['verb'], ACTIVITY_FAVORITE)) {
+       if ($activity->match($item['verb'], ACTIVITY_FAVORITE)) {
                if ($item['object-type'] == "") {
                        return;
                }
@@ -393,19 +399,22 @@ function count_descendants($item) {
 
 function visible_activity($item) {
 
+       /** @var Activity $activity */
+       $activity = BaseObject::getClass(Activity::class);
+
        /*
         * likes (etc.) can apply to other things besides posts. Check if they are post children,
         * in which case we handle them specially
         */
        $hidden_activities = [ACTIVITY_LIKE, ACTIVITY_DISLIKE, ACTIVITY_ATTEND, ACTIVITY_ATTENDNO, ACTIVITY_ATTENDMAYBE, ACTIVITY_FOLLOW, ACTIVITY2_ANNOUNCE];
        foreach ($hidden_activities as $act) {
-               if (activity_match($item['verb'], $act)) {
+               if ($activity->match($item['verb'], $act)) {
                        return false;
                }
        }
 
        // @TODO below if() block can be rewritten to a single line: $isVisible = allConditionsHere;
-       if (activity_match($item['verb'], ACTIVITY_FOLLOW) && $item['object-type'] === ACTIVITY_OBJ_NOTE && empty($item['self']) && $item['uid'] == local_user()) {
+       if ($activity->match($item['verb'], ACTIVITY_FOLLOW) && $item['object-type'] === ACTIVITY_OBJ_NOTE && empty($item['self']) && $item['uid'] == local_user()) {
                return false;
        }
 
@@ -663,7 +672,10 @@ function conversation(App $a, array $items, Pager $pager, $mode, $update, $previ
 
                                $body = Item::prepareBody($item, true, $preview);
 
-                               list($categories, $folders) = get_cats_and_terms($item);
+                               /** @var ContentItem $contItem */
+                               $contItem = BaseObject::getClass(ContentItem::class);
+
+                               list($categories, $folders) = $contItem->determineCategoriesTerms($item);
 
                                if (!empty($item['content-warning']) && PConfig::get(local_user(), 'system', 'disable_cw', false)) {
                                        $title = ucfirst($item['content-warning']);
@@ -1017,7 +1029,10 @@ function builtin_activity_puller($item, &$conv_responses) {
                                return;
                }
 
-               if (activity_match($item['verb'], $verb) && ($item['id'] != $item['parent'])) {
+               /** @var Activity $activity */
+               $activity = BaseObject::getClass(Activity::class);
+
+               if ($activity->match($item['verb'], $verb) && ($item['id'] != $item['parent'])) {
                        $author = ['uid' => 0, 'id' => $item['author-id'],
                                'network' => $item['author-network'], 'url' => $item['author-link']];
                        $url = Contact::magicLinkByContact($author);
diff --git a/include/text.php b/include/text.php
deleted file mode 100644 (file)
index 2050e57..0000000
+++ /dev/null
@@ -1,275 +0,0 @@
-<?php
-/**
- * @file include/text.php
- */
-
-use Friendica\App;
-use Friendica\Content\Text\BBCode;
-use Friendica\Core\Protocol;
-use Friendica\Model\Contact;
-use Friendica\Model\FileTag;
-use Friendica\Model\Group;
-use Friendica\Util\Strings;
-
-/**
- * Turn user/group ACLs stored as angle bracketed text into arrays
- *
- * @param string $s
- * @return array
- */
-function expand_acl($s) {
-       // turn string array of angle-bracketed elements into numeric array
-       // e.g. "<1><2><3>" => array(1,2,3);
-       preg_match_all('/<(' . Group::FOLLOWERS . '|'. Group::MUTUALS . '|[0-9]+)>/', $s, $matches, PREG_PATTERN_ORDER);
-
-       return $matches[1];
-}
-
-
-/**
- * Wrap ACL elements in angle brackets for storage
- * @param string $item
- */
-function sanitise_acl(&$item) {
-       if (intval($item)) {
-               $item = '<' . intval(Strings::escapeTags(trim($item))) . '>';
-       } elseif (in_array($item, [Group::FOLLOWERS, Group::MUTUALS])) {
-               $item = '<' . $item . '>';
-       } else {
-               unset($item);
-       }
-}
-
-
-/**
- * Convert an ACL array to a storable string
- *
- * Normally ACL permissions will be an array.
- * We'll also allow a comma-separated string.
- *
- * @param string|array $p
- * @return string
- */
-function perms2str($p) {
-       $ret = '';
-       if (is_array($p)) {
-               $tmp = $p;
-       } else {
-               $tmp = explode(',', $p);
-       }
-
-       if (is_array($tmp)) {
-               array_walk($tmp, 'sanitise_acl');
-               $ret = implode('', $tmp);
-       }
-       return $ret;
-}
-
-/**
- *  for html,xml parsing - let's say you've got
- *  an attribute foobar="class1 class2 class3"
- *  and you want to find out if it contains 'class3'.
- *  you can't use a normal sub string search because you
- *  might match 'notclass3' and a regex to do the job is
- *  possible but a bit complicated.
- *  pass the attribute string as $attr and the attribute you
- *  are looking for as $s - returns true if found, otherwise false
- *
- * @param string $attr attribute value
- * @param string $s string to search
- * @return boolean True if found, False otherwise
- */
-function attribute_contains($attr, $s) {
-       $a = explode(' ', $attr);
-       return (count($a) && in_array($s,$a));
-}
-
-/**
- * Compare activity uri. Knows about activity namespace.
- *
- * @param string $haystack
- * @param string $needle
- * @return boolean
- */
-function activity_match($haystack,$needle) {
-       return (($haystack === $needle) || ((basename($needle) === $haystack) && strstr($needle, NAMESPACE_ACTIVITY_SCHEMA)));
-}
-
-/**
- * quick and dirty quoted_printable encoding
- *
- * @param string $s
- * @return string
- */
-function qp($s) {
-       return str_replace("%", "=", rawurlencode($s));
-}
-
-/**
- * @brief Find any non-embedded images in private items and add redir links to them
- *
- * @param App $a
- * @param array &$item The field array of an item row
- */
-function redir_private_images($a, &$item)
-{
-       $matches = [];
-       $cnt = preg_match_all('|\[img\](http[^\[]*?/photo/[a-fA-F0-9]+?(-[0-9]\.[\w]+?)?)\[\/img\]|', $item['body'], $matches, PREG_SET_ORDER);
-       if ($cnt) {
-               foreach ($matches as $mtch) {
-                       if (strpos($mtch[1], '/redir') !== false) {
-                               continue;
-                       }
-
-                       if ((local_user() == $item['uid']) && ($item['private'] == 1) && ($item['contact-id'] != $a->contact['id']) && ($item['network'] == Protocol::DFRN)) {
-                               $img_url = 'redir/' . $item['contact-id'] . '?url=' . urlencode($mtch[1]);
-                               $item['body'] = str_replace($mtch[0], '[img]' . $img_url . '[/img]', $item['body']);
-                       }
-               }
-       }
-}
-
-/**
- * @brief Given a text string, convert from bbcode to html and add smilie icons.
- *
- * @param string $text String with bbcode.
- * @return string Formatted HTML
- * @throws \Friendica\Network\HTTPException\InternalServerErrorException
- */
-function prepare_text($text)
-{
-       $s = BBCode::convert($text);
-       return trim($s);
-}
-
-/**
- * return array with details for categories and folders for an item
- *
- * @param array $item
- * @return array
- *
-  * [
- *      [ // categories array
- *          {
- *               'name': 'category name',
- *               'removeurl': 'url to remove this category',
- *               'first': 'is the first in this array? true/false',
- *               'last': 'is the last in this array? true/false',
- *           } ,
- *           ....
- *       ],
- *       [ //folders array
- *                     {
- *               'name': 'folder name',
- *               'removeurl': 'url to remove this folder',
- *               'first': 'is the first in this array? true/false',
- *               'last': 'is the last in this array? true/false',
- *           } ,
- *           ....
- *       ]
- *  ]
- */
-function get_cats_and_terms($item)
-{
-       $categories = [];
-       $folders = [];
-       $first = true;
-
-       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)) {
-               $categories[count($categories) - 1]['last'] = true;
-       }
-
-       if (local_user() == $item['uid']) {
-               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;
-               }
-       }
-
-       if (count($folders)) {
-               $folders[count($folders) - 1]['last'] = true;
-       }
-
-       return [$categories, $folders];
-}
-
-/**
- * return number of bytes in size (K, M, G)
- * @param string $size_str
- * @return int
- */
-function return_bytes($size_str) {
-       switch (substr ($size_str, -1)) {
-               case 'M': case 'm': return (int)$size_str * 1048576;
-               case 'K': case 'k': return (int)$size_str * 1024;
-               case 'G': case 'g': return (int)$size_str * 1073741824;
-               default: return $size_str;
-       }
-}
-
-function bb_translate_video($s) {
-
-       $matches = null;
-       $r = preg_match_all("/\[video\](.*?)\[\/video\]/ism",$s,$matches,PREG_SET_ORDER);
-       if ($r) {
-               foreach ($matches as $mtch) {
-                       if ((stristr($mtch[1], 'youtube')) || (stristr($mtch[1], 'youtu.be'))) {
-                               $s = str_replace($mtch[0], '[youtube]' . $mtch[1] . '[/youtube]', $s);
-                       } elseif (stristr($mtch[1], 'vimeo')) {
-                               $s = str_replace($mtch[0], '[vimeo]' . $mtch[1] . '[/vimeo]', $s);
-                       }
-               }
-       }
-       return $s;
-}
-
-function undo_post_tagging($s) {
-       $matches = null;
-       $cnt = preg_match_all('/([!#@])\[url=(.*?)\](.*?)\[\/url\]/ism', $s, $matches, PREG_SET_ORDER);
-       if ($cnt) {
-               foreach ($matches as $mtch) {
-                       if (in_array($mtch[1], ['!', '@'])) {
-                               $contact = Contact::getDetailsByURL($mtch[2]);
-                               $mtch[3] = empty($contact['addr']) ? $mtch[2] : $contact['addr'];
-                       }
-                       $s = str_replace($mtch[0], $mtch[1] . $mtch[3],$s);
-               }
-       }
-       return $s;
-}
-
-/// @TODO Rewrite this
-function is_a_date_arg($s) {
-       $i = intval($s);
-
-       if ($i > 1900) {
-               $y = date('Y');
-
-               if ($i <= $y + 1 && strpos($s, '-') == 4) {
-                       $m = intval(substr($s, 5));
-
-                       if ($m > 0 && $m <= 12) {
-                               return true;
-                       }
-               }
-       }
-
-       return false;
-}
index e14baffa28aca2cad4f483c097cc38487a9194c1..690cb2ac0d0947d40da1e0a5b9c6994b8f0653d8 100644 (file)
@@ -8,9 +8,10 @@ use Friendica\Content\Feature;
 use Friendica\Core\Hook;
 use Friendica\Core\L10n;
 use Friendica\Core\Renderer;
+use Friendica\Database\DBA;
+use Friendica\Model\Contact;
 use Friendica\Model\FileTag;
 use Friendica\Model\Item;
-use Friendica\Database\DBA;
 use Friendica\Util\Crypto;
 
 function editpost_content(App $a)
@@ -118,3 +119,18 @@ function editpost_content(App $a)
 
        return $o;
 }
+
+function undo_post_tagging($s) {
+       $matches = null;
+       $cnt = preg_match_all('/([!#@])\[url=(.*?)\](.*?)\[\/url\]/ism', $s, $matches, PREG_SET_ORDER);
+       if ($cnt) {
+               foreach ($matches as $mtch) {
+                       if (in_array($mtch[1], ['!', '@'])) {
+                               $contact = Contact::getDetailsByURL($mtch[2]);
+                               $mtch[3] = empty($contact['addr']) ? $mtch[2] : $contact['addr'];
+                       }
+                       $s = str_replace($mtch[0], $mtch[1] . $mtch[3],$s);
+               }
+       }
+       return $s;
+}
index 649a25ab1b35505e29c5ee5b121f836c400446a0..11bb25f51b9f8f8ec10e686e7f7a4ce9c2ee132e 100644 (file)
@@ -5,6 +5,7 @@
  */
 
 use Friendica\App;
+use Friendica\BaseObject;
 use Friendica\Content\Nav;
 use Friendica\Content\Widget\CalendarExport;
 use Friendica\Core\ACL;
@@ -18,6 +19,7 @@ use Friendica\Model\Event;
 use Friendica\Model\Item;
 use Friendica\Model\Profile;
 use Friendica\Module\Login;
+use Friendica\Util\ACLFormatter;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Strings;
 use Friendica\Util\Temporal;
@@ -146,10 +148,14 @@ function events_post(App $a)
 
 
        if ($share) {
-               $str_group_allow   = perms2str($_POST['group_allow']   ?? '');
-               $str_contact_allow = perms2str($_POST['contact_allow'] ?? '');
-               $str_group_deny    = perms2str($_POST['group_deny']    ?? '');
-               $str_contact_deny  = perms2str($_POST['contact_deny']  ?? '');
+
+               /** @var ACLFormatter $aclFormatter */
+               $aclFormatter = BaseObject::getClass(ACLFormatter::class);
+
+               $str_group_allow   = $aclFormatter->toString($_POST['group_allow'] ?? '');
+               $str_contact_allow = $aclFormatter->toString($_POST['contact_allow'] ?? '');
+               $str_group_deny    = $aclFormatter->toString($_POST['group_deny'] ?? '');
+               $str_contact_deny  = $aclFormatter->toString($_POST['contact_deny'] ?? '');
 
                // Undo the pseudo-contact of self, since there are real contacts now
                if (strpos($str_contact_allow, '<' . $self . '>') !== false) {
index 7c8ebee4abfdf5e3ae5c8271b394bd8bf4d0147e..a5875d258b2641f74da1c46f1b2b2902c9d98883 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 use Friendica\App;
+use Friendica\BaseObject;
 use Friendica\Content\Pager;
 use Friendica\Content\Text\BBCode;
 use Friendica\Content\Text\HTML;
@@ -24,8 +25,8 @@ use Friendica\Core\Hook;
 use Friendica\Core\L10n;
 use Friendica\Core\Logger;
 use Friendica\Core\Protocol;
-use Friendica\Core\System;
 use Friendica\Core\Session;
+use Friendica\Core\System;
 use Friendica\Core\Worker;
 use Friendica\Database\DBA;
 use Friendica\Model\Attach;
@@ -37,6 +38,7 @@ use Friendica\Model\Photo;
 use Friendica\Model\Term;
 use Friendica\Protocol\Diaspora;
 use Friendica\Protocol\Email;
+use Friendica\Util\ACLFormatter;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Emailer;
 use Friendica\Util\Security;
@@ -269,10 +271,14 @@ function item_post(App $a) {
                        $str_contact_deny  = $user['deny_cid'];
                } else {
                        // use the posted permissions
-                       $str_group_allow   = perms2str($_REQUEST['group_allow'] ?? '');
-                       $str_contact_allow = perms2str($_REQUEST['contact_allow'] ?? '');
-                       $str_group_deny    = perms2str($_REQUEST['group_deny'] ?? '');
-                       $str_contact_deny  = perms2str($_REQUEST['contact_deny'] ?? '');
+
+                       /** @var ACLFormatter $aclFormatter */
+                       $aclFormatter = BaseObject::getClass(ACLFormatter::class);
+
+                       $str_group_allow   = $aclFormatter->toString($_REQUEST['group_allow'] ?? '');
+                       $str_contact_allow = $aclFormatter->toString($_REQUEST['contact_allow'] ?? '');
+                       $str_group_deny    = $aclFormatter->toString($_REQUEST['group_deny'] ?? '');
+                       $str_contact_deny  = $aclFormatter->toString($_REQUEST['contact_deny'] ?? '');
                }
 
                $title             = Strings::escapeTags(trim($_REQUEST['title']    ?? ''));
@@ -499,8 +505,9 @@ function item_post(App $a) {
                $objecttype = ACTIVITY_OBJ_BOOKMARK;
        }
 
-       $body = bb_translate_video($body);
-
+       /** @var BBCode\Video $bbCodeVideo */
+       $bbCodeVideo = BaseObject::getClass(BBCode\Video::class);
+       $body =  $bbCodeVideo->transform($body);
 
        // Fold multi-line [code] sequences
        $body = preg_replace('/\[\/code\]\s*\[code\]/ism', "\n", $body);
index eede1b6a0dac4eca34d039a470b3d22f7e5dcdfa..9f9dcfea421beee54a110ccb730cf17eb6ab50ab 100644 (file)
@@ -3,11 +3,13 @@
  * @file mod/lockview.php
  */
 use Friendica\App;
+use Friendica\BaseObject;
 use Friendica\Core\Hook;
 use Friendica\Core\L10n;
 use Friendica\Database\DBA;
 use Friendica\Model\Group;
 use Friendica\Model\Item;
+use Friendica\Util\ACLFormatter;
 
 function lockview_content(App $a)
 {
@@ -59,10 +61,13 @@ function lockview_content(App $a)
                exit();
        }
 
-       $allowed_users  = expand_acl($item['allow_cid']);
-       $allowed_groups = expand_acl($item['allow_gid']);
-       $deny_users     = expand_acl($item['deny_cid']);
-       $deny_groups    = expand_acl($item['deny_gid']);
+       /** @var ACLFormatter $aclFormatter */
+       $aclFormatter = BaseObject::getClass(ACLFormatter::class);
+
+       $allowed_users = $aclFormatter->expand($item['allow_cid']);
+       $allowed_groups = $aclFormatter->expand($item['allow_gid']);
+       $deny_users = $aclFormatter->expand($item['deny_cid']);
+       $deny_groups = $aclFormatter->expand($item['deny_gid']);
 
        $o = L10n::t('Visible to:') . '<br />';
        $l = [];
index 0438be7059d7680ba8dbd926ef922473ed4bd9b5..64f5cf505f64f3530f790713c54c79cd25e5f312 100644 (file)
@@ -5,6 +5,7 @@
  */
 
 use Friendica\App;
+use Friendica\BaseObject;
 use Friendica\Content\Feature;
 use Friendica\Content\ForumManager;
 use Friendica\Content\Nav;
@@ -51,9 +52,12 @@ function network_init(App $a)
                $group_id = 0;
        }
 
+       /** @var DateTimeFormat $dtFormat */
+       $dtFormat = BaseObject::getClass(DateTimeFormat::class);
+
        if ($a->argc > 1) {
                for ($x = 1; $x < $a->argc; $x ++) {
-                       if (is_a_date_arg($a->argv[$x])) {
+                       if ($dtFormat->isYearMonth($a->argv[$x])) {
                                $is_a_date_query = true;
                                break;
                        }
@@ -461,9 +465,12 @@ function networkThreadedView(App $a, $update, $parent)
 
        $default_permissions = [];
 
+       /** @var DateTimeFormat $dtFormat */
+       $dtFormat = BaseObject::getClass(DateTimeFormat::class);
+
        if ($a->argc > 1) {
                for ($x = 1; $x < $a->argc; $x ++) {
-                       if (is_a_date_arg($a->argv[$x])) {
+                       if ($dtFormat->isYearMonth($a->argv[$x])) {
                                if ($datequery) {
                                        $datequery2 = Strings::escapeHtml($a->argv[$x]);
                                } else {
index 1789c0710e1ea6d74fcf34b3f22dba1dc597576d..d89cd04b0be334874559bf9f4cdb983edbd8a2fc 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 use Friendica\App;
+use Friendica\BaseObject;
 use Friendica\Content\Feature;
 use Friendica\Content\Nav;
 use Friendica\Content\Pager;
@@ -14,18 +15,17 @@ use Friendica\Core\Hook;
 use Friendica\Core\L10n;
 use Friendica\Core\Logger;
 use Friendica\Core\Renderer;
-use Friendica\Core\System;
 use Friendica\Core\Session;
+use Friendica\Core\System;
 use Friendica\Database\DBA;
 use Friendica\Model\Contact;
-use Friendica\Model\Group;
 use Friendica\Model\Item;
 use Friendica\Model\Photo;
 use Friendica\Model\Profile;
 use Friendica\Model\User;
 use Friendica\Network\Probe;
 use Friendica\Object\Image;
-use Friendica\Protocol\DFRN;
+use Friendica\Util\ACLFormatter;
 use Friendica\Util\Crypto;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Map;
@@ -296,10 +296,13 @@ function photos_post(App $a)
                $albname     = !empty($_POST['albname'])   ? Strings::escapeTags(trim($_POST['albname']))   : '';
                $origaname   = !empty($_POST['origaname']) ? Strings::escapeTags(trim($_POST['origaname'])) : '';
 
-               $str_group_allow   = !empty($_POST['group_allow'])   ? perms2str($_POST['group_allow'])   : '';
-               $str_contact_allow = !empty($_POST['contact_allow']) ? perms2str($_POST['contact_allow']) : '';
-               $str_group_deny    = !empty($_POST['group_deny'])    ? perms2str($_POST['group_deny'])    : '';
-               $str_contact_deny  = !empty($_POST['contact_deny'])  ? perms2str($_POST['contact_deny'])  : '';
+               /** @var ACLFormatter $aclFormatter */
+               $aclFormatter = BaseObject::getClass(ACLFormatter::class);
+
+               $str_group_allow   = !empty($_POST['group_allow'])   ? $aclFormatter->toString($_POST['group_allow'])   : '';
+               $str_contact_allow = !empty($_POST['contact_allow']) ? $aclFormatter->toString($_POST['contact_allow']) : '';
+               $str_group_deny    = !empty($_POST['group_deny'])    ? $aclFormatter->toString($_POST['group_deny'])    : '';
+               $str_contact_deny  = !empty($_POST['contact_deny'])  ? $aclFormatter->toString($_POST['contact_deny'])  : '';
 
                $resource_id = $a->argv[3];
 
@@ -635,10 +638,13 @@ function photos_post(App $a)
        $group_deny    = $_REQUEST['group_deny']    ?? [];
        $contact_deny  = $_REQUEST['contact_deny']  ?? [];
 
-       $str_group_allow   = perms2str(is_array($group_allow)   ? $group_allow   : explode(',', $group_allow));
-       $str_contact_allow = perms2str(is_array($contact_allow) ? $contact_allow : explode(',', $contact_allow));
-       $str_group_deny    = perms2str(is_array($group_deny)    ? $group_deny    : explode(',', $group_deny));
-       $str_contact_deny  = perms2str(is_array($contact_deny)  ? $contact_deny  : explode(',', $contact_deny));
+       /** @var ACLFormatter $aclFormatter */
+       $aclFormatter = BaseObject::getClass(ACLFormatter::class);
+
+       $str_group_allow   = $aclFormatter->toString(is_array($group_allow)   ? $group_allow   : explode(',', $group_allow));
+       $str_contact_allow = $aclFormatter->toString(is_array($contact_allow) ? $contact_allow : explode(',', $contact_allow));
+       $str_group_deny    = $aclFormatter->toString(is_array($group_deny)    ? $group_deny    : explode(',', $group_deny));
+       $str_contact_deny  = $aclFormatter->toString(is_array($contact_deny)  ? $contact_deny  : explode(',', $contact_deny));
 
        $ret = ['src' => '', 'filename' => '', 'filesize' => 0, 'type' => ''];
 
@@ -1438,7 +1444,12 @@ function photos_content(App $a)
                                        $template = $tpl;
                                        $sparkle = '';
 
-                                       if ((activity_match($item['verb'], ACTIVITY_LIKE) || activity_match($item['verb'], ACTIVITY_DISLIKE)) && ($item['id'] != $item['parent'])) {
+                                       /** @var \Friendica\Protocol\Activity $activity */
+                                       $activity = BaseObject::getClass(\Friendica\Protocol\Activity::class);
+
+                                       if (($activity->match($item['verb'], ACTIVITY_LIKE) ||
+                                            $activity->match($item['verb'], ACTIVITY_DISLIKE)) &&
+                                           ($item['id'] != $item['parent'])) {
                                                continue;
                                        }
 
index b5011881cb9b5871308dba82c7d5f4211c955589..8c3ce668426ed6615ee14a81a6ac8817af71b5ae 100644 (file)
@@ -5,6 +5,7 @@
 
 use Friendica\App;
 use Friendica\BaseModule;
+use Friendica\BaseObject;
 use Friendica\Content\Feature;
 use Friendica\Content\Nav;
 use Friendica\Core\ACL;
@@ -25,6 +26,7 @@ use Friendica\Model\Group;
 use Friendica\Model\User;
 use Friendica\Module\Login;
 use Friendica\Protocol\Email;
+use Friendica\Util\ACLFormatter;
 use Friendica\Util\Network;
 use Friendica\Util\Strings;
 use Friendica\Util\Temporal;
@@ -533,10 +535,13 @@ function settings_post(App $a)
                date_default_timezone_set($timezone);
        }
 
-       $str_group_allow   = !empty($_POST['group_allow'])   ? perms2str($_POST['group_allow'])   : '';
-       $str_contact_allow = !empty($_POST['contact_allow']) ? perms2str($_POST['contact_allow']) : '';
-       $str_group_deny    = !empty($_POST['group_deny'])    ? perms2str($_POST['group_deny'])    : '';
-       $str_contact_deny  = !empty($_POST['contact_deny'])  ? perms2str($_POST['contact_deny'])  : '';
+       /** @var ACLFormatter $aclFormatter */
+       $aclFormatter = BaseObject::getClass(ACLFormatter::class);
+
+       $str_group_allow   = !empty($_POST['group_allow'])   ? $aclFormatter->toString($_POST['group_allow'])   : '';
+       $str_contact_allow = !empty($_POST['contact_allow']) ? $aclFormatter->toString($_POST['contact_allow']) : '';
+       $str_group_deny    = !empty($_POST['group_deny'])    ? $aclFormatter->toString($_POST['group_deny'])    : '';
+       $str_contact_deny  = !empty($_POST['contact_deny'])  ? $aclFormatter->toString($_POST['contact_deny'])  : '';
 
        $openidserver = $a->user['openidserver'];
        //$openid = Strings::normaliseOpenID($openid);
index 996824f4a132b631dddfbad6a6296f6a5f5905fd..20481884517e565123d8b17f7038a6033250525a 100644 (file)
@@ -54,7 +54,7 @@ class BaseObject
         *
         * @throws InternalServerErrorException
         */
-       protected static function getClass(string $name)
+       public static function getClass(string $name)
        {
                if (empty(self::$dice)) {
                        throw new InternalServerErrorException('DICE isn\'t initialized.');
diff --git a/src/Content/Item.php b/src/Content/Item.php
new file mode 100644 (file)
index 0000000..ed6ec9c
--- /dev/null
@@ -0,0 +1,79 @@
+<?php
+
+namespace Friendica\Content;
+
+use Friendica\Model\FileTag;
+
+/**
+ * A content helper class for displaying items
+ */
+final class Item
+{
+       /**
+        * Return array with details for categories and folders for an item
+        *
+        * @param array $item
+        * @return [array, array]
+        *
+        * [
+        *      [ // categories array
+        *          {
+        *               'name': 'category name',
+        *               'removeurl': 'url to remove this category',
+        *               'first': 'is the first in this array? true/false',
+        *               'last': 'is the last in this array? true/false',
+        *           } ,
+        *           ....
+        *       ],
+        *       [ //folders array
+        *                      {
+        *               'name': 'folder name',
+        *               'removeurl': 'url to remove this folder',
+        *               'first': 'is the first in this array? true/false',
+        *               'last': 'is the last in this array? true/false',
+        *           } ,
+        *           ....
+        *       ]
+        *  ]
+        */
+       public function determineCategoriesTerms(array $item)
+       {
+               $categories = [];
+               $folders = [];
+               $first = true;
+
+               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)) {
+                       $categories[count($categories) - 1]['last'] = true;
+               }
+
+               if (local_user() == $item['uid']) {
+                       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;
+                       }
+               }
+
+               if (count($folders)) {
+                       $folders[count($folders) - 1]['last'] = true;
+               }
+
+               return [$categories, $folders];
+       }
+}
diff --git a/src/Content/Text/BBCode/Video.php b/src/Content/Text/BBCode/Video.php
new file mode 100644 (file)
index 0000000..b73ddce
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+
+namespace Friendica\Content\Text\BBCode;
+
+/**
+ * Video specific BBCode util class
+ */
+final class Video
+{
+       /**
+        * Transforms video BBCode tagged links to youtube/vimeo tagged links
+        *
+        * @param string $bbCodeString The input BBCode styled string
+        *
+        * @return string The transformed text
+        */
+       public function transform(string $bbCodeString)
+       {
+               $matches = null;
+               $found = preg_match_all("/\[video\](.*?)\[\/video\]/ism",$bbCodeString,$matches,PREG_SET_ORDER);
+               if ($found) {
+                       foreach ($matches as $match) {
+                               if ((stristr($match[1], 'youtube')) || (stristr($match[1], 'youtu.be'))) {
+                                       $bbCodeString = str_replace($match[0], '[youtube]' . $match[1] . '[/youtube]', $bbCodeString);
+                               } elseif (stristr($match[1], 'vimeo')) {
+                                       $bbCodeString = str_replace($match[0], '[vimeo]' . $match[1] . '[/vimeo]', $bbCodeString);
+                               }
+                       }
+               }
+               return $bbCodeString;
+       }
+}
index 91521808447ad472b8d3935474673685ff65d56c..cbd245a2339713494d740d7d5085b3374e144458 100644 (file)
@@ -911,7 +911,7 @@ class Event extends BaseObject
                $tpl = Renderer::getMarkupTemplate('event_stream_item.tpl');
                $return = Renderer::replaceMacros($tpl, [
                        '$id'             => $item['event-id'],
-                       '$title'          => prepare_text($item['event-summary']),
+                       '$title'          => BBCode::convert($item['event-summary']),
                        '$dtstart_label'  => L10n::t('Starts:'),
                        '$dtstart_title'  => $dtstart_title,
                        '$dtstart_dt'     => $dtstart_dt,
@@ -929,7 +929,7 @@ class Event extends BaseObject
                        '$author_name'    => $item['author-name'],
                        '$author_link'    => $profile_link,
                        '$author_avatar'  => $item['author-avatar'],
-                       '$description'    => prepare_text($item['event-desc']),
+                       '$description'    => BBCode::convert($item['event-desc']),
                        '$location_label' => L10n::t('Location:'),
                        '$show_map_label' => L10n::t('Show map'),
                        '$hide_map_label' => L10n::t('Hide map'),
@@ -979,7 +979,7 @@ class Event extends BaseObject
                        }
                }
 
-               $location['name'] = prepare_text($location['name']);
+               $location['name'] = BBCode::convert($location['name']);
 
                // Construct the map HTML.
                if (isset($location['address'])) {
index ff0f46676f0e6d560991a0551505c9fb0a9db599..2c544a263b5ee4a4b04626d2c3a193d231addc43 100644 (file)
@@ -17,13 +17,15 @@ use Friendica\Core\Logger;
 use Friendica\Core\PConfig;
 use Friendica\Core\Protocol;
 use Friendica\Core\Renderer;
-use Friendica\Core\System;
 use Friendica\Core\Session;
+use Friendica\Core\System;
 use Friendica\Core\Worker;
 use Friendica\Database\DBA;
+use Friendica\Protocol\Activity;
 use Friendica\Protocol\ActivityPub;
 use Friendica\Protocol\Diaspora;
 use Friendica\Protocol\OStatus;
+use Friendica\Util\ACLFormatter;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Map;
 use Friendica\Util\Network;
@@ -1357,13 +1359,16 @@ class Item extends BaseObject
                        $item['parent-uri'] = $item['thr-parent'];
                }
 
+               /** @var Activity $activity */
+               $activity = self::getClass(Activity::class);
+
                if (isset($item['gravity'])) {
                        $item['gravity'] = intval($item['gravity']);
                } elseif ($item['parent-uri'] === $item['uri']) {
                        $item['gravity'] = GRAVITY_PARENT;
-               } elseif (activity_match($item['verb'], ACTIVITY_POST)) {
+               } elseif ($activity->match($item['verb'], ACTIVITY_POST)) {
                        $item['gravity'] = GRAVITY_COMMENT;
-               } elseif (activity_match($item['verb'], ACTIVITY_FOLLOW)) {
+               } elseif ($activity->match($item['verb'], ACTIVITY_FOLLOW)) {
                        $item['gravity'] = GRAVITY_ACTIVITY;
                } else {
                        $item['gravity'] = GRAVITY_UNKNOWN;   // Should not happen
@@ -2892,10 +2897,13 @@ class Item extends BaseObject
         */
        public static function enumeratePermissions(array $obj, bool $check_dead = false)
        {
-               $allow_people = expand_acl($obj['allow_cid']);
-               $allow_groups = Group::expand($obj['uid'], expand_acl($obj['allow_gid']), $check_dead);
-               $deny_people  = expand_acl($obj['deny_cid']);
-               $deny_groups  = Group::expand($obj['uid'], expand_acl($obj['deny_gid']), $check_dead);
+               /** @var ACLFormatter $aclFormater */
+               $aclFormater = self::getClass(ACLFormatter::class);
+
+               $allow_people = $aclFormater->expand($obj['allow_cid']);
+               $allow_groups = Group::expand($obj['uid'], $aclFormater->expand($obj['allow_gid']), $check_dead);
+               $deny_people  = $aclFormater->expand($obj['deny_cid']);
+               $deny_groups  = Group::expand($obj['uid'], $aclFormater->expand($obj['deny_gid']), $check_dead);
                $recipients   = array_unique(array_merge($allow_people, $allow_groups));
                $deny         = array_unique(array_merge($deny_people, $deny_groups));
                $recipients   = array_diff($recipients, $deny);
@@ -3342,10 +3350,9 @@ class Item extends BaseObject
                        || $rendered_hash != hash("md5", $item["body"])
                        || Config::get("system", "ignore_cache")
                ) {
-                       $a = self::getApp();
-                       redir_private_images($a, $item);
+                       self::addRedirToImageTags($item);
 
-                       $item["rendered-html"] = prepare_text($item["body"]);
+                       $item["rendered-html"] = BBCode::convert($item["body"]);
                        $item["rendered-hash"] = hash("md5", $item["body"]);
 
                        $hook_data = ['item' => $item, 'rendered-html' => $item['rendered-html'], 'rendered-hash' => $item['rendered-hash']];
@@ -3378,6 +3385,31 @@ class Item extends BaseObject
                $item["body"] = $body;
        }
 
+       /**
+        * @brief Find any non-embedded images in private items and add redir links to them
+        *
+        * @param array &$item The field array of an item row
+        */
+       private static function addRedirToImageTags(array &$item)
+       {
+               $app = self::getApp();
+
+               $matches = [];
+               $cnt = preg_match_all('|\[img\](http[^\[]*?/photo/[a-fA-F0-9]+?(-[0-9]\.[\w]+?)?)\[\/img\]|', $item['body'], $matches, PREG_SET_ORDER);
+               if ($cnt) {
+                       foreach ($matches as $mtch) {
+                               if (strpos($mtch[1], '/redir') !== false) {
+                                       continue;
+                               }
+
+                               if ((local_user() == $item['uid']) && ($item['private'] == 1) && ($item['contact-id'] != $app->contact['id']) && ($item['network'] == Protocol::DFRN)) {
+                                       $img_url = 'redir/' . $item['contact-id'] . '?url=' . urlencode($mtch[1]);
+                                       $item['body'] = str_replace($mtch[0], '[img]' . $img_url . '[/img]', $item['body']);
+                               }
+                       }
+               }
+       }
+
        /**
         * @brief Given an item array, convert the body element from bbcode to html and add smilie icons.
         * If attach is true, also add icons for item attachments.
index b69860edfff73038d4f6438f4ab2e865be765c2c..de329038911dfb342b2bd168b837d318d667750e 100644 (file)
@@ -823,51 +823,51 @@ class Profile
                                $profile['religion'] = [L10n::t('Religion:'), $a->profile['religion']];
                        }
 
-                       if ($txt = prepare_text($a->profile['about'])) {
+                       if ($txt = BBCode::convert($a->profile['about'])) {
                                $profile['about'] = [L10n::t('About:'), $txt];
                        }
 
-                       if ($txt = prepare_text($a->profile['interest'])) {
+                       if ($txt = BBCode::convert($a->profile['interest'])) {
                                $profile['interest'] = [L10n::t('Hobbies/Interests:'), $txt];
                        }
 
-                       if ($txt = prepare_text($a->profile['likes'])) {
+                       if ($txt = BBCode::convert($a->profile['likes'])) {
                                $profile['likes'] = [L10n::t('Likes:'), $txt];
                        }
 
-                       if ($txt = prepare_text($a->profile['dislikes'])) {
+                       if ($txt = BBCode::convert($a->profile['dislikes'])) {
                                $profile['dislikes'] = [L10n::t('Dislikes:'), $txt];
                        }
 
-                       if ($txt = prepare_text($a->profile['contact'])) {
+                       if ($txt = BBCode::convert($a->profile['contact'])) {
                                $profile['contact'] = [L10n::t('Contact information and Social Networks:'), $txt];
                        }
 
-                       if ($txt = prepare_text($a->profile['music'])) {
+                       if ($txt = BBCode::convert($a->profile['music'])) {
                                $profile['music'] = [L10n::t('Musical interests:'), $txt];
                        }
 
-                       if ($txt = prepare_text($a->profile['book'])) {
+                       if ($txt = BBCode::convert($a->profile['book'])) {
                                $profile['book'] = [L10n::t('Books, literature:'), $txt];
                        }
 
-                       if ($txt = prepare_text($a->profile['tv'])) {
+                       if ($txt = BBCode::convert($a->profile['tv'])) {
                                $profile['tv'] = [L10n::t('Television:'), $txt];
                        }
 
-                       if ($txt = prepare_text($a->profile['film'])) {
+                       if ($txt = BBCode::convert($a->profile['film'])) {
                                $profile['film'] = [L10n::t('Film/dance/culture/entertainment:'), $txt];
                        }
 
-                       if ($txt = prepare_text($a->profile['romance'])) {
+                       if ($txt = BBCode::convert($a->profile['romance'])) {
                                $profile['romance'] = [L10n::t('Love/Romance:'), $txt];
                        }
 
-                       if ($txt = prepare_text($a->profile['work'])) {
+                       if ($txt = BBCode::convert($a->profile['work'])) {
                                $profile['work'] = [L10n::t('Work/employment:'), $txt];
                        }
 
-                       if ($txt = prepare_text($a->profile['education'])) {
+                       if ($txt = BBCode::convert($a->profile['education'])) {
                                $profile['education'] = [L10n::t('School/education:'), $txt];
                        }
 
index 11b886a2edea9151f97d9812710aa7ee33e72dfa..c44e4c61ab8f66eef3afc77276f43569fa2a9d19 100644 (file)
@@ -16,6 +16,7 @@ use Friendica\Model\Item;
 use Friendica\Model\User;
 use Friendica\Module\Login;
 use Friendica\Network\HTTPException\NotImplementedException;
+use Friendica\Util\ACLFormatter;
 use Friendica\Util\Crypto;
 
 class Compose extends BaseModule
@@ -58,6 +59,9 @@ class Compose extends BaseModule
 
                $user = User::getById(local_user(), ['allow_cid', 'allow_gid', 'deny_cid', 'deny_gid', 'hidewall', 'default-location']);
 
+               /** @var ACLFormatter $aclFormatter */
+               $aclFormatter = self::getClass(ACLFormatter::class);
+
                switch ($posttype) {
                        case Item::PT_PERSONAL_NOTE:
                                $compose_title = L10n::t('Compose new personal note');
@@ -70,8 +74,8 @@ class Compose extends BaseModule
                                $compose_title = L10n::t('Compose new post');
                                $type = 'post';
                                $doesFederate = true;
-                               $contact_allow = implode(',', expand_acl($user['allow_cid']));
-                               $group_allow = implode(',', expand_acl($user['allow_gid'])) ?: Group::FOLLOWERS;
+                               $contact_allow = implode(',', $aclFormatter->expand($user['allow_cid']));
+                               $group_allow = implode(',', $aclFormatter->expand($user['allow_gid'])) ?: Group::FOLLOWERS;
                                break;
                }
 
@@ -82,8 +86,8 @@ class Compose extends BaseModule
                $wall          = $_REQUEST['wall']          ?? $type == 'post';
                $contact_allow = $_REQUEST['contact_allow'] ?? $contact_allow;
                $group_allow   = $_REQUEST['group_allow']   ?? $group_allow;
-               $contact_deny  = $_REQUEST['contact_deny']  ?? implode(',', expand_acl($user['deny_cid']));
-               $group_deny    = $_REQUEST['group_deny']    ?? implode(',', expand_acl($user['deny_gid']));
+               $contact_deny  = $_REQUEST['contact_deny']  ?? implode(',', $aclFormatter->expand($user['deny_cid']));
+               $group_deny    = $_REQUEST['group_deny']    ?? implode(',', $aclFormatter->expand($user['deny_gid']));
                $visibility    = ($contact_allow . $user['allow_gid'] . $user['deny_cid'] . $user['deny_gid']) ? 'custom' : 'public';
 
                $acl_contacts = Contact::selectToArray(['id', 'name', 'addr', 'micro'], ['uid' => local_user(), 'pending' => false, 'rel' => [Contact::FOLLOWER, Contact::FRIEND]]);
index ed37540753582fea049838a2139b5f285f0c88ad..f38c77f2cdcb5d8ba79d8484af15f8325da4e7e9 100644 (file)
@@ -131,9 +131,12 @@ class Profile extends BaseModule
 
                $category = $datequery = $datequery2 = '';
 
+               /** @var DateTimeFormat $dtFormat */
+               $dtFormat = self::getClass(DateTimeFormat::class);
+
                if ($a->argc > 2) {
                        for ($x = 2; $x < $a->argc; $x ++) {
-                               if (is_a_date_arg($a->argv[$x])) {
+                               if ($dtFormat->isYearMonth($a->argv[$x])) {
                                        if ($datequery) {
                                                $datequery2 = Strings::escapeHtml($a->argv[$x]);
                                        } else {
index 04775bbd0e2f964c3a3a3b6202e7c4d85e85b467..7dd5308017749b58cd819bf8efb4cb9c20165eaf 100644 (file)
@@ -7,6 +7,7 @@ namespace Friendica\Object;
 use Friendica\BaseObject;
 use Friendica\Content\ContactSelector;
 use Friendica\Content\Feature;
+use Friendica\Content\Item as ContentItem;
 use Friendica\Core\Addon;
 use Friendica\Core\Config;
 use Friendica\Core\Hook;
@@ -21,6 +22,7 @@ use Friendica\Model\Contact;
 use Friendica\Model\Item;
 use Friendica\Model\Term;
 use Friendica\Model\User;
+use Friendica\Protocol\Activity;
 use Friendica\Util\Crypto;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Proxy as ProxyUtils;
@@ -323,7 +325,10 @@ class Post extends BaseObject
 
                $body = Item::prepareBody($item, true);
 
-               list($categories, $folders) = get_cats_and_terms($item);
+               /** @var ContentItem $contItem */
+               $contItem = self::getClass(ContentItem::class);
+
+               list($categories, $folders) = $contItem->determineCategoriesTerms($item);
 
                $body_e       = $body;
                $text_e       = strip_tags($body);
@@ -517,12 +522,17 @@ class Post extends BaseObject
                        Logger::log('[WARN] Post::addChild : Item already exists (' . $item->getId() . ').', Logger::DEBUG);
                        return false;
                }
+
+               /** @var Activity $activity */
+               $activity = self::getClass(Activity::class);
+
                /*
                 * Only add what will be displayed
                 */
                if ($item->getDataValue('network') === Protocol::MAIL && local_user() != $item->getDataValue('uid')) {
                        return false;
-               } elseif (activity_match($item->getDataValue('verb'), ACTIVITY_LIKE) || activity_match($item->getDataValue('verb'), ACTIVITY_DISLIKE)) {
+               } elseif ($activity->match($item->getDataValue('verb'), ACTIVITY_LIKE) ||
+                         $activity->match($item->getDataValue('verb'), ACTIVITY_DISLIKE)) {
                        return false;
                }
 
diff --git a/src/Protocol/Activity.php b/src/Protocol/Activity.php
new file mode 100644 (file)
index 0000000..64253b0
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+
+namespace Friendica\Protocol;
+
+/**
+ * Base class for the Activity namespace
+ */
+final class Activity
+{
+       /**
+        * Compare activity uri. Knows about activity namespace.
+        *
+        * @param string $haystack
+        * @param string $needle
+        *
+        * @return boolean
+        */
+       public function match(string $haystack, string $needle) {
+               return (($haystack === $needle) ||
+                       ((basename($needle) === $haystack) &&
+                        strstr($needle, NAMESPACE_ACTIVITY_SCHEMA)));
+       }
+}
index d557af0692fb761db121bb815a59f93bf024aa8b..e1901011e166a74a4e5e99eba8058065170c1e6d 100644 (file)
@@ -12,6 +12,7 @@ use DOMDocument;
 use DOMXPath;
 use Friendica\App;
 use Friendica\App\BaseURL;
+use Friendica\BaseObject;
 use Friendica\Content\OEmbed;
 use Friendica\Content\Text\BBCode;
 use Friendica\Content\Text\HTML;
@@ -2180,24 +2181,27 @@ class DFRN
                        // The functions below are partly used by ostatus.php as well - where we have this variable
                        $contact = Contact::selectFirst([], ['id' => $importer['id']]);
 
+                       /** @var Activity $activity */
+                       $activity = BaseObject::getClass(Activity::class);
+
                        // Big question: Do we need these functions? They were part of the "consume_feed" function.
                        // This function once was responsible for DFRN and OStatus.
-                       if (activity_match($item["verb"], ACTIVITY_FOLLOW)) {
+                       if ($activity->match($item["verb"], ACTIVITY_FOLLOW)) {
                                Logger::log("New follower");
                                Contact::addRelationship($importer, $contact, $item);
                                return false;
                        }
-                       if (activity_match($item["verb"], ACTIVITY_UNFOLLOW)) {
+                       if ($activity->match($item["verb"], ACTIVITY_UNFOLLOW)) {
                                Logger::log("Lost follower");
                                Contact::removeFollower($importer, $contact, $item);
                                return false;
                        }
-                       if (activity_match($item["verb"], ACTIVITY_REQ_FRIEND)) {
+                       if ($activity->match($item["verb"], ACTIVITY_REQ_FRIEND)) {
                                Logger::log("New friend request");
                                Contact::addRelationship($importer, $contact, $item, true);
                                return false;
                        }
-                       if (activity_match($item["verb"], ACTIVITY_UNFRIEND)) {
+                       if ($activity->match($item["verb"], ACTIVITY_UNFRIEND)) {
                                Logger::log("Lost sharer");
                                Contact::removeSharer($importer, $contact, $item);
                                return false;
diff --git a/src/Util/ACLFormatter.php b/src/Util/ACLFormatter.php
new file mode 100644 (file)
index 0000000..1fb7787
--- /dev/null
@@ -0,0 +1,67 @@
+<?php
+
+namespace Friendica\Util;
+
+use Friendica\Model\Group;
+
+/**
+ * Util class for ACL formatting
+ */
+final class ACLFormatter
+{
+       /**
+        * Turn user/group ACLs stored as angle bracketed text into arrays
+        *
+        * @param string $ids A angle-bracketed list of IDs
+        *
+        * @return array The array based on the IDs
+        */
+       public function expand(string $ids)
+       {
+               // turn string array of angle-bracketed elements into numeric array
+               // e.g. "<1><2><3>" => array(1,2,3);
+               preg_match_all('/<(' . Group::FOLLOWERS . '|'. Group::MUTUALS . '|[0-9]+)>/', $ids, $matches, PREG_PATTERN_ORDER);
+
+               return $matches[1];
+       }
+
+       /**
+        * Wrap ACL elements in angle brackets for storage
+        *
+        * @param string $item The item to sanitise
+        */
+       private function sanitize(string &$item) {
+               if (intval($item)) {
+                       $item = '<' . intval(Strings::escapeTags(trim($item))) . '>';
+               } elseif (in_array($item, [Group::FOLLOWERS, Group::MUTUALS])) {
+                       $item = '<' . $item . '>';
+               } else {
+                       $item = '';
+               }
+       }
+
+       /**
+        * Convert an ACL array to a storable string
+        *
+        * Normally ACL permissions will be an array.
+        * We'll also allow a comma-separated string.
+        *
+        * @param string|array $permissions
+        *
+        * @return string
+        */
+       function toString($permissions) {
+               $return = '';
+               if (is_array($permissions)) {
+                       $item = $permissions;
+               } else {
+                       $item = explode(',', $permissions);
+               }
+
+               if (is_array($item)) {
+                       array_walk($item, [$this, 'sanitize']);
+                       $return = implode('', $item);
+               }
+               return $return;
+       }
+}
index 0b47a16f1549b5fa86c4417bc1bd6949c6684c5c..e29420e9ea41c272dcbbb63868bc0ffac6972b0a 100644 (file)
@@ -148,4 +148,37 @@ class DateTimeFormat
 
                return $d->format($format);
        }
+
+       /**
+        * Checks, if the given string is a date with the pattern YYYY-MM
+        *
+        * @param string $dateString The given date
+        *
+        * @return boolean True, if the date is a valid pattern
+        */
+       public function isYearMonth(string $dateString)
+       {
+               // Check format (2019-01, 2019-1, 2019-10)
+               if (!preg_match('/^([12]\d{3}-(1[0-2]|0[1-9]|\d))$/', $dateString)) {
+                       return false;
+               }
+
+               $date = DateTime::createFromFormat('Y-m', $dateString);
+
+               if (!$date) {
+                       return false;
+               }
+
+               try {
+                       $now = new DateTime();
+               } catch (\Throwable $t) {
+                       return false;
+               }
+
+               if ($date > $now) {
+                       return false;
+               }
+
+               return true;
+       }
 }
index 4bf97aca5fa9ef7d3b36585bd74e835e5c7cbf96..ebc70ffb502f3e48f180deda209836b2191d92a7 100644 (file)
@@ -24,6 +24,7 @@ use Friendica\Protocol\ActivityPub;
 use Friendica\Protocol\Diaspora;
 use Friendica\Protocol\OStatus;
 use Friendica\Protocol\Salmon;
+use Friendica\Util\ACLFormatter;
 
 require_once 'include/items.php';
 
@@ -272,10 +273,13 @@ class Notifier
                                        $public_message = false; // private recipients, not public
                                }
 
-                               $allow_people = expand_acl($parent['allow_cid']);
-                               $allow_groups = Group::expand($uid, expand_acl($parent['allow_gid']),true);
-                               $deny_people  = expand_acl($parent['deny_cid']);
-                               $deny_groups  = Group::expand($uid, expand_acl($parent['deny_gid']));
+                               /** @var ACLFormatter $aclFormatter */
+                               $aclFormatter = BaseObject::getClass(ACLFormatter::class);
+
+                               $allow_people = $aclFormatter->expand($parent['allow_cid']);
+                               $allow_groups = Group::expand($uid, $aclFormatter->expand($parent['allow_gid']),true);
+                               $deny_people  = $aclFormatter->expand($parent['deny_cid']);
+                               $deny_groups  = Group::expand($uid, $aclFormatter->expand($parent['deny_gid']));
 
                                // if our parent is a public forum (forum_mode == 1), uplink to the origional author causing
                                // a delivery fork. private groups (forum_mode == 2) do not uplink
diff --git a/tests/include/TextTest.php b/tests/include/TextTest.php
deleted file mode 100644 (file)
index 5676da8..0000000
+++ /dev/null
@@ -1,191 +0,0 @@
-<?php
-/**
- * TextTest class.
- */
-
-namespace Friendica\Test;
-
-use Friendica\Model\Group;
-use PHPUnit\Framework\TestCase;
-
-/**
- * Tests for text functions.
- */
-class TextTest extends TestCase
-{
-       /**
-        * test attribute contains
-        */
-       public function testAttributeContains1()
-       {
-               $testAttr="class1 notclass2 class3";
-               $this->assertTrue(attribute_contains($testAttr, "class3"));
-               $this->assertFalse(attribute_contains($testAttr, "class2"));
-       }
-
-       /**
-        * test attribute contains
-        */
-       public function testAttributeContains2()
-       {
-               $testAttr="class1 not-class2 class3";
-               $this->assertTrue(attribute_contains($testAttr, "class3"));
-               $this->assertFalse(attribute_contains($testAttr, "class2"));
-       }
-
-       /**
-        * test with empty input
-        */
-       public function testAttributeContainsEmpty()
-       {
-               $testAttr="";
-               $this->assertFalse(attribute_contains($testAttr, "class2"));
-       }
-
-       /**
-        * test input with special chars
-        */
-       public function testAttributeContainsSpecialChars()
-       {
-               $testAttr="--... %\$ä() /(=?}";
-               $this->assertFalse(attribute_contains($testAttr, "class2"));
-       }
-
-       /**
-        * test expand_acl, perfect input
-        */
-       public function testExpandAclNormal()
-       {
-               $text='<1><2><3><' . Group::FOLLOWERS . '><' . Group::MUTUALS . '>';
-               $this->assertEquals(array('1', '2', '3', Group::FOLLOWERS, Group::MUTUALS), expand_acl($text));
-       }
-
-       /**
-        * test with a big number
-        */
-       public function testExpandAclBigNumber()
-       {
-               $text='<1><' . PHP_INT_MAX . '><15>';
-               $this->assertEquals(array('1', (string)PHP_INT_MAX, '15'), expand_acl($text));
-       }
-
-       /**
-        * test with a string in it.
-        *
-        * @todo is this valid input? Otherwise: should there be an exception?
-        */
-       public function testExpandAclString()
-       {
-               $text="<1><279012><tt>";
-               $this->assertEquals(array('1', '279012'), expand_acl($text));
-       }
-
-       /**
-        * test with a ' ' in it.
-        *
-        * @todo is this valid input? Otherwise: should there be an exception?
-        */
-       public function testExpandAclSpace()
-       {
-               $text="<1><279 012><32>";
-               $this->assertEquals(array('1', '32'), expand_acl($text));
-       }
-
-       /**
-        * test empty input
-        */
-       public function testExpandAclEmpty()
-       {
-               $text="";
-               $this->assertEquals(array(), expand_acl($text));
-       }
-
-       /**
-        * test invalid input, no < at all
-        *
-        * @todo should there be an exception?
-        */
-       public function testExpandAclNoBrackets()
-       {
-               $text="According to documentation, that's invalid. "; //should be invalid
-               $this->assertEquals(array(), expand_acl($text));
-       }
-
-       /**
-        * test invalid input, just open <
-        *
-        * @todo should there be an exception?
-        */
-       public function testExpandAclJustOneBracket1()
-       {
-               $text="<Another invalid string"; //should be invalid
-               $this->assertEquals(array(), expand_acl($text));
-       }
-
-       /**
-        * test invalid input, just close >
-        *
-        * @todo should there be an exception?
-        */
-       public function testExpandAclJustOneBracket2()
-       {
-               $text="Another invalid> string"; //should be invalid
-               $this->assertEquals(array(), expand_acl($text));
-       }
-
-       /**
-        * test invalid input, just close >
-        *
-        * @todo should there be an exception?
-        */
-       public function testExpandAclCloseOnly()
-       {
-               $text="Another> invalid> string>"; //should be invalid
-               $this->assertEquals(array(), expand_acl($text));
-       }
-
-       /**
-        * test invalid input, just open <
-        *
-        * @todo should there be an exception?
-        */
-       public function testExpandAclOpenOnly()
-       {
-               $text="<Another< invalid string<"; //should be invalid
-               $this->assertEquals(array(), expand_acl($text));
-       }
-
-       /**
-        * test invalid input, open and close do not match
-        *
-        * @todo should there be an exception?
-        */
-       public function testExpandAclNoMatching1()
-       {
-               $text="<Another<> invalid <string>"; //should be invalid
-               $this->assertEquals(array(), expand_acl($text));
-       }
-
-       /**
-        * test invalid input, empty <>
-        *
-        * @todo should there be an exception? Or array(1, 3)
-        * (This should be array(1,3) - mike)
-        */
-       public function testExpandAclEmptyMatch()
-       {
-               $text="<1><><3>";
-               $this->assertEquals(array('1', '3'), expand_acl($text));
-       }
-
-       /**
-        * test hex2bin and reverse
-        */
-       public function testHex2Bin()
-       {
-               $this->assertEquals(-3, hex2bin(bin2hex(-3)));
-               $this->assertEquals(0, hex2bin(bin2hex(0)));
-               $this->assertEquals(12, hex2bin(bin2hex(12)));
-               $this->assertEquals(PHP_INT_MAX, hex2bin(bin2hex(PHP_INT_MAX)));
-       }
-}
diff --git a/tests/src/Content/ItemTest.php b/tests/src/Content/ItemTest.php
new file mode 100644 (file)
index 0000000..5cdfa97
--- /dev/null
@@ -0,0 +1,13 @@
+<?php
+
+namespace Friendica\Test\src\Content;
+
+use Friendica\Test\MockedTest;
+
+class ItemTest extends MockedTest
+{
+       public function testDetermineCategoriesTerms()
+       {
+               $this->markTestIncomplete('Test data needed.');
+       }
+}
diff --git a/tests/src/Content/Text/BBCode/VideoTest.php b/tests/src/Content/Text/BBCode/VideoTest.php
new file mode 100644 (file)
index 0000000..4a17687
--- /dev/null
@@ -0,0 +1,43 @@
+<?php
+
+namespace Friendica\Test\Content\Text\BBCode;
+
+use Friendica\Content\Text\BBCode\Video;
+use Friendica\Test\MockedTest;
+
+class VideoTest extends MockedTest
+{
+       public function dataVideo()
+       {
+               return [
+                       'youtube' => [
+                               'input' => '[video]https://youtube.link/4523[/video]',
+                               'assert' => '[youtube]https://youtube.link/4523[/youtube]',
+                       ],
+                       'youtu.be' => [
+                               'input' => '[video]https://youtu.be.link/4523[/video]',
+                               'assert' => '[youtube]https://youtu.be.link/4523[/youtube]',
+                       ],
+                       'vimeo' => [
+                               'input' => '[video]https://vimeo.link/2343[/video]',
+                               'assert' => '[vimeo]https://vimeo.link/2343[/vimeo]',
+                       ],
+                       'mixed' => [
+                               'input' => '[video]https://vimeo.link/2343[/video] With other [b]string[/b] [video]https://youtu.be/blaa[/video]',
+                               'assert' => '[vimeo]https://vimeo.link/2343[/vimeo] With other [b]string[/b] [youtube]https://youtu.be/blaa[/youtube]',
+                       ]
+               ];
+       }
+
+       /**
+        * Test if the BBCode is successfully transformed for video links
+        *
+        * @dataProvider dataVideo
+        */
+       public function testTransform(string $input, string $assert)
+       {
+               $bbCodeVideo = new Video();
+
+               $this->assertEquals($assert, $bbCodeVideo->transform($input));
+       }
+}
index a898dd2957bb85cc100c9c9281194811716e8251..735a52cd09f3d87db68079d27017d3980b87fc4c 100644 (file)
@@ -339,9 +339,6 @@ class InstallerTest extends MockedTest
                // Mocking that we can use CURL
                $this->setFunctions(['curl_init' => true]);
 
-               // needed because of "normalise_link"
-               require_once __DIR__ . '/../../../include/text.php';
-
                $install = new Installer();
 
                $this->assertTrue($install->checkHtAccess('https://test'));
diff --git a/tests/src/Protocol/ActivityTest.php b/tests/src/Protocol/ActivityTest.php
new file mode 100644 (file)
index 0000000..b6fcbf3
--- /dev/null
@@ -0,0 +1,57 @@
+<?php
+
+namespace Friendica\Test\Protocol;
+
+use Friendica\Protocol\Activity;
+use Friendica\Test\MockedTest;
+
+class ActivityTest extends MockedTest
+{
+       public function dataMatch()
+       {
+               return [
+                       'empty' => [
+                               'haystack' => '',
+                               'needle' => '',
+                               'assert' => true,
+                       ],
+                       'simple' => [
+                               'haystack' => ACTIVITY_OBJ_TAGTERM,
+                               'needle' => ACTIVITY_OBJ_TAGTERM,
+                               'assert' => true,
+                       ],
+                       'withNamespace' => [
+                               'haystack' => 'tagterm',
+                               'needle' => NAMESPACE_ACTIVITY_SCHEMA . ACTIVITY_OBJ_TAGTERM,
+                               'assert' => true,
+                       ],
+                       'invalidSimple' => [
+                               'haystack' => 'tagterm',
+                               'needle' => '',
+                               'assert' => false,
+                       ],
+                       'invalidWithOutNamespace' => [
+                               'haystack' => 'tagterm',
+                               'needle' => ACTIVITY_OBJ_TAGTERM,
+                               'assert' => false,
+                       ],
+                       'withSubPath' => [
+                               'haystack' => 'tagterm',
+                               'needle' =>  NAMESPACE_ACTIVITY_SCHEMA . '/bla/' . ACTIVITY_OBJ_TAGTERM,
+                               'assert' => true,
+                       ],
+               ];
+       }
+
+       /**
+        * Test the different, possible matchings
+        *
+        * @dataProvider dataMatch
+        */
+       public function testMatch(string $haystack, string $needle, bool $assert)
+       {
+               $activity = new Activity();
+
+               $this->assertEquals($assert, $activity->match($haystack, $needle));
+       }
+}
diff --git a/tests/src/Util/ACLFormaterTest.php b/tests/src/Util/ACLFormaterTest.php
new file mode 100644 (file)
index 0000000..76a566b
--- /dev/null
@@ -0,0 +1,200 @@
+<?php
+
+namespace Friendica\Test\src\Util;
+
+use Friendica\Model\Group;
+use Friendica\Util\ACLFormatter;
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @brief ACLFormater utility testing class
+ */
+class ACLFormaterTest extends TestCase
+{
+       /**
+        * test expand_acl, perfect input
+        */
+       public function testExpandAclNormal()
+       {
+               $aclFormatter = new ACLFormatter();
+
+               $text='<1><2><3><' . Group::FOLLOWERS . '><' . Group::MUTUALS . '>';
+               $this->assertEquals(array('1', '2', '3', Group::FOLLOWERS, Group::MUTUALS), $aclFormatter->expand($text));
+       }
+
+       /**
+        * test with a big number
+        */
+       public function testExpandAclBigNumber()
+       {
+               $aclFormatter = new ACLFormatter();
+
+               $text='<1><' . PHP_INT_MAX . '><15>';
+               $this->assertEquals(array('1', (string)PHP_INT_MAX, '15'), $aclFormatter->expand($text));
+       }
+
+       /**
+        * test with a string in it.
+        *
+        * @todo is this valid input? Otherwise: should there be an exception?
+        */
+       public function testExpandAclString()
+       {
+               $aclFormatter = new ACLFormatter();
+
+               $text="<1><279012><tt>";
+               $this->assertEquals(array('1', '279012'), $aclFormatter->expand($text));
+       }
+
+       /**
+        * test with a ' ' in it.
+        *
+        * @todo is this valid input? Otherwise: should there be an exception?
+        */
+       public function testExpandAclSpace()
+       {
+               $aclFormatter = new ACLFormatter();
+
+               $text="<1><279 012><32>";
+               $this->assertEquals(array('1', '32'), $aclFormatter->expand($text));
+       }
+
+       /**
+        * test empty input
+        */
+       public function testExpandAclEmpty()
+       {
+               $aclFormatter = new ACLFormatter();
+
+               $text="";
+               $this->assertEquals(array(), $aclFormatter->expand($text));
+       }
+
+       /**
+        * test invalid input, no < at all
+        *
+        * @todo should there be an exception?
+        */
+       public function testExpandAclNoBrackets()
+       {
+               $aclFormatter = new ACLFormatter();
+
+               $text="According to documentation, that's invalid. "; //should be invalid
+               $this->assertEquals(array(), $aclFormatter->expand($text));
+       }
+
+       /**
+        * test invalid input, just open <
+        *
+        * @todo should there be an exception?
+        */
+       public function testExpandAclJustOneBracket1()
+       {
+               $aclFormatter = new ACLFormatter();
+
+               $text="<Another invalid string"; //should be invalid
+               $this->assertEquals(array(), $aclFormatter->expand($text));
+       }
+
+       /**
+        * test invalid input, just close >
+        *
+        * @todo should there be an exception?
+        */
+       public function testExpandAclJustOneBracket2()
+       {
+               $aclFormatter = new ACLFormatter();
+
+               $text="Another invalid> string"; //should be invalid
+               $this->assertEquals(array(), $aclFormatter->expand($text));
+       }
+
+       /**
+        * test invalid input, just close >
+        *
+        * @todo should there be an exception?
+        */
+       public function testExpandAclCloseOnly()
+       {
+               $aclFormatter = new ACLFormatter();
+
+               $text="Another> invalid> string>"; //should be invalid
+               $this->assertEquals(array(), $aclFormatter->expand($text));
+       }
+
+       /**
+        * test invalid input, just open <
+        *
+        * @todo should there be an exception?
+        */
+       public function testExpandAclOpenOnly()
+       {
+               $aclFormatter = new ACLFormatter();
+
+               $text="<Another< invalid string<"; //should be invalid
+               $this->assertEquals(array(), $aclFormatter->expand($text));
+       }
+
+       /**
+        * test invalid input, open and close do not match
+        *
+        * @todo should there be an exception?
+        */
+       public function testExpandAclNoMatching1()
+       {
+               $aclFormatter = new ACLFormatter();
+
+               $text="<Another<> invalid <string>"; //should be invalid
+               $this->assertEquals(array(), $aclFormatter->expand($text));
+       }
+
+       /**
+        * test invalid input, empty <>
+        *
+        * @todo should there be an exception? Or array(1, 3)
+        * (This should be array(1,3) - mike)
+        */
+       public function testExpandAclEmptyMatch()
+       {
+               $aclFormatter = new ACLFormatter();
+
+               $text="<1><><3>";
+               $this->assertEquals(array('1', '3'), $aclFormatter->expand($text));
+       }
+
+       public function dataAclToString()
+       {
+               return [
+                       'empty'   => [
+                               'input'  => '',
+                               'assert' => '',
+                       ],
+                       'string'  => [
+                               'input'  => '1,2,3,4',
+                               'assert' => '<1><2><3><4>',
+                       ],
+                       'array'   => [
+                               'input'  => [1, 2, 3, 4],
+                               'assert' => '<1><2><3><4>',
+                       ],
+                       'invalid' => [
+                               'input'  => [1, 'a', 3, 4],
+                               'assert' => '<1><3><4>',
+                       ],
+                       'invalidString' => [
+                               'input'  => 'a,bsd23,4',
+                               'assert' => '<4>',
+                       ],
+               ];
+       }
+
+       /**
+        * @dataProvider dataAclToString
+        */
+       public function testAclToString($input, string $assert)
+       {
+               $aclFormatter = new ACLFormatter();
+
+               $this->assertEquals($assert, $aclFormatter->toString($input));
+       }
+}
diff --git a/tests/src/Util/DateTimeFormatTest.php b/tests/src/Util/DateTimeFormatTest.php
new file mode 100644 (file)
index 0000000..bdc902e
--- /dev/null
@@ -0,0 +1,61 @@
+<?php
+
+namespace Friendica\Test\src\Util;
+
+use Friendica\Test\MockedTest;
+use Friendica\Util\DateTimeFormat;
+
+class DateTimeFormatTest extends MockedTest
+{
+       public function dataYearMonth()
+       {
+               return [
+                       'validNormal' => [
+                               'input' => '1990-10',
+                               'assert' => true,
+                       ],
+                       'validOneCharMonth' => [
+                               'input' => '1990-1',
+                               'assert' => true,
+                       ],
+                       'validTwoCharMonth' => [
+                               'input' => '1990-01',
+                               'assert' => true,
+                       ],
+                       'invalidFormat' => [
+                               'input' => '199-11',
+                               'assert' => false,
+                       ],
+                       'invalidFormat2' => [
+                               'input' => '1990-15',
+                               'assert' => false,
+                       ],
+                       'invalidFormat3' => [
+                               'input' => '99-101',
+                               'assert' => false,
+                       ],
+                       'invalidFormat4' => [
+                               'input' => '11-1990',
+                               'assert' => false,
+                       ],
+                       'invalidFuture' => [
+                               'input' => '3030-12',
+                               'assert' => false,
+                       ],
+                       'invalidYear' => [
+                               'input' => '-100-10',
+                               'assert' => false,
+                       ],
+               ];
+       }
+
+       /**
+        * @dataProvider dataYearMonth
+        */
+       public function testIsYearMonth(string $input, bool $assert)
+       {
+               $dtFormat = new DateTimeFormat();
+
+               $this->assertEquals($assert, $dtFormat->isYearMonth($input));
+       }
+}