diff --git a/composer.json b/composer.json
index 9ed9017d85..83b51a1747 100644
--- a/composer.json
+++ b/composer.json
@@ -83,7 +83,6 @@
"include/dba.php",
"include/enotify.php",
"include/items.php",
- "include/text.php",
"boot.php"
]
},
diff --git a/doc/Addons.md b/doc/Addons.md
index 0382cee49c..69b591a820 100644
--- a/doc/Addons.md
+++ b/doc/Addons.md
@@ -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);
diff --git a/doc/de/Addons.md b/doc/de/Addons.md
index 3cbbb4b0be..755db95d01 100644
--- a/doc/de/Addons.md
+++ b/doc/de/Addons.md
@@ -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);
diff --git a/include/conversation.php b/include/conversation.php
index b6faa4d2c8..8bcd1b338f 100644
--- a/include/conversation.php
+++ b/include/conversation.php
@@ -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
index 2050e57026..0000000000
--- a/include/text.php
+++ /dev/null
@@ -1,275 +0,0 @@
-<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;
-}
diff --git a/mod/editpost.php b/mod/editpost.php
index e14baffa28..690cb2ac0d 100644
--- a/mod/editpost.php
+++ b/mod/editpost.php
@@ -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;
+}
diff --git a/mod/events.php b/mod/events.php
index 649a25ab1b..11bb25f51b 100644
--- a/mod/events.php
+++ b/mod/events.php
@@ -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) {
diff --git a/mod/item.php b/mod/item.php
index 7c8ebee4ab..a5875d258b 100644
--- a/mod/item.php
+++ b/mod/item.php
@@ -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);
diff --git a/mod/lockview.php b/mod/lockview.php
index eede1b6a0d..9f9dcfea42 100644
--- a/mod/lockview.php
+++ b/mod/lockview.php
@@ -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:') . '
';
$l = [];
diff --git a/mod/network.php b/mod/network.php
index 0438be7059..64f5cf505f 100644
--- a/mod/network.php
+++ b/mod/network.php
@@ -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 {
diff --git a/mod/photos.php b/mod/photos.php
index 1789c0710e..d89cd04b0b 100644
--- a/mod/photos.php
+++ b/mod/photos.php
@@ -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;
}
diff --git a/mod/settings.php b/mod/settings.php
index b5011881cb..8c3ce66842 100644
--- a/mod/settings.php
+++ b/mod/settings.php
@@ -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);
diff --git a/src/BaseObject.php b/src/BaseObject.php
index 996824f4a1..2048188451 100644
--- a/src/BaseObject.php
+++ b/src/BaseObject.php
@@ -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
index 0000000000..ed6ec9c877
--- /dev/null
+++ b/src/Content/Item.php
@@ -0,0 +1,79 @@
+ $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
index 0000000000..b73ddce0b3
--- /dev/null
+++ b/src/Content/Text/BBCode/Video.php
@@ -0,0 +1,32 @@
+ $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'])) {
diff --git a/src/Model/Item.php b/src/Model/Item.php
index ff0f46676f..2c544a263b 100644
--- a/src/Model/Item.php
+++ b/src/Model/Item.php
@@ -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.
diff --git a/src/Model/Profile.php b/src/Model/Profile.php
index b69860edff..de32903891 100644
--- a/src/Model/Profile.php
+++ b/src/Model/Profile.php
@@ -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];
}
diff --git a/src/Module/Item/Compose.php b/src/Module/Item/Compose.php
index 11b886a2ed..c44e4c61ab 100644
--- a/src/Module/Item/Compose.php
+++ b/src/Module/Item/Compose.php
@@ -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]]);
diff --git a/src/Module/Profile.php b/src/Module/Profile.php
index ed37540753..f38c77f2cd 100644
--- a/src/Module/Profile.php
+++ b/src/Module/Profile.php
@@ -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 {
diff --git a/src/Object/Post.php b/src/Object/Post.php
index 04775bbd0e..7dd5308017 100644
--- a/src/Object/Post.php
+++ b/src/Object/Post.php
@@ -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
index 0000000000..64253b0652
--- /dev/null
+++ b/src/Protocol/Activity.php
@@ -0,0 +1,23 @@
+ $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
index 0000000000..1fb7787610
--- /dev/null
+++ b/src/Util/ACLFormatter.php
@@ -0,0 +1,67 @@
+<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;
+ }
+}
diff --git a/src/Util/DateTimeFormat.php b/src/Util/DateTimeFormat.php
index 0b47a16f15..e29420e9ea 100644
--- a/src/Util/DateTimeFormat.php
+++ b/src/Util/DateTimeFormat.php
@@ -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;
+ }
}
diff --git a/src/Worker/Notifier.php b/src/Worker/Notifier.php
index 4bf97aca5f..ebc70ffb50 100644
--- a/src/Worker/Notifier.php
+++ b/src/Worker/Notifier.php
@@ -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/src/Content/ItemTest.php b/tests/src/Content/ItemTest.php
new file mode 100644
index 0000000000..5cdfa978bd
--- /dev/null
+++ b/tests/src/Content/ItemTest.php
@@ -0,0 +1,13 @@
+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
index 0000000000..4a176871a1
--- /dev/null
+++ b/tests/src/Content/Text/BBCode/VideoTest.php
@@ -0,0 +1,43 @@
+ [
+ '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));
+ }
+}
diff --git a/tests/src/Core/InstallerTest.php b/tests/src/Core/InstallerTest.php
index a898dd2957..735a52cd09 100644
--- a/tests/src/Core/InstallerTest.php
+++ b/tests/src/Core/InstallerTest.php
@@ -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
index 0000000000..b6fcbf3954
--- /dev/null
+++ b/tests/src/Protocol/ActivityTest.php
@@ -0,0 +1,57 @@
+ [
+ '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/include/TextTest.php b/tests/src/Util/ACLFormaterTest.php
similarity index 53%
rename from tests/include/TextTest.php
rename to tests/src/Util/ACLFormaterTest.php
index 5676da8f62..76a566baaa 100644
--- a/tests/include/TextTest.php
+++ b/tests/src/Util/ACLFormaterTest.php
@@ -1,63 +1,25 @@
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()
{
+ $aclFormatter = new ACLFormatter();
+
$text='<1><2><3><' . Group::FOLLOWERS . '><' . Group::MUTUALS . '>';
- $this->assertEquals(array('1', '2', '3', Group::FOLLOWERS, Group::MUTUALS), expand_acl($text));
+ $this->assertEquals(array('1', '2', '3', Group::FOLLOWERS, Group::MUTUALS), $aclFormatter->expand($text));
}
/**
@@ -65,8 +27,10 @@ class TextTest extends TestCase
*/
public function testExpandAclBigNumber()
{
+ $aclFormatter = new ACLFormatter();
+
$text='<1><' . PHP_INT_MAX . '><15>';
- $this->assertEquals(array('1', (string)PHP_INT_MAX, '15'), expand_acl($text));
+ $this->assertEquals(array('1', (string)PHP_INT_MAX, '15'), $aclFormatter->expand($text));
}
/**
@@ -76,8 +40,10 @@ class TextTest extends TestCase
*/
public function testExpandAclString()
{
+ $aclFormatter = new ACLFormatter();
+
$text="<1><279012>";
- $this->assertEquals(array('1', '279012'), expand_acl($text));
+ $this->assertEquals(array('1', '279012'), $aclFormatter->expand($text));
}
/**
@@ -87,8 +53,10 @@ class TextTest extends TestCase
*/
public function testExpandAclSpace()
{
+ $aclFormatter = new ACLFormatter();
+
$text="<1><279 012><32>";
- $this->assertEquals(array('1', '32'), expand_acl($text));
+ $this->assertEquals(array('1', '32'), $aclFormatter->expand($text));
}
/**
@@ -96,8 +64,10 @@ class TextTest extends TestCase
*/
public function testExpandAclEmpty()
{
+ $aclFormatter = new ACLFormatter();
+
$text="";
- $this->assertEquals(array(), expand_acl($text));
+ $this->assertEquals(array(), $aclFormatter->expand($text));
}
/**
@@ -107,8 +77,10 @@ class TextTest extends TestCase
*/
public function testExpandAclNoBrackets()
{
+ $aclFormatter = new ACLFormatter();
+
$text="According to documentation, that's invalid. "; //should be invalid
- $this->assertEquals(array(), expand_acl($text));
+ $this->assertEquals(array(), $aclFormatter->expand($text));
}
/**
@@ -118,8 +90,10 @@ class TextTest extends TestCase
*/
public function testExpandAclJustOneBracket1()
{
+ $aclFormatter = new ACLFormatter();
+
$text="assertEquals(array(), expand_acl($text));
+ $this->assertEquals(array(), $aclFormatter->expand($text));
}
/**
@@ -129,8 +103,10 @@ class TextTest extends TestCase
*/
public function testExpandAclJustOneBracket2()
{
+ $aclFormatter = new ACLFormatter();
+
$text="Another invalid> string"; //should be invalid
- $this->assertEquals(array(), expand_acl($text));
+ $this->assertEquals(array(), $aclFormatter->expand($text));
}
/**
@@ -140,8 +116,10 @@ class TextTest extends TestCase
*/
public function testExpandAclCloseOnly()
{
+ $aclFormatter = new ACLFormatter();
+
$text="Another> invalid> string>"; //should be invalid
- $this->assertEquals(array(), expand_acl($text));
+ $this->assertEquals(array(), $aclFormatter->expand($text));
}
/**
@@ -151,8 +129,10 @@ class TextTest extends TestCase
*/
public function testExpandAclOpenOnly()
{
+ $aclFormatter = new ACLFormatter();
+
$text="assertEquals(array(), expand_acl($text));
+ $this->assertEquals(array(), $aclFormatter->expand($text));
}
/**
@@ -162,8 +142,10 @@ class TextTest extends TestCase
*/
public function testExpandAclNoMatching1()
{
+ $aclFormatter = new ACLFormatter();
+
$text=" invalid "; //should be invalid
- $this->assertEquals(array(), expand_acl($text));
+ $this->assertEquals(array(), $aclFormatter->expand($text));
}
/**
@@ -174,18 +156,45 @@ class TextTest extends TestCase
*/
public function testExpandAclEmptyMatch()
{
+ $aclFormatter = new ACLFormatter();
+
$text="<1><><3>";
- $this->assertEquals(array('1', '3'), expand_acl($text));
+ $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>',
+ ],
+ ];
}
/**
- * test hex2bin and reverse
+ * @dataProvider dataAclToString
*/
- public function testHex2Bin()
+ public function testAclToString($input, string $assert)
{
- $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)));
+ $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
index 0000000000..bdc902eab2
--- /dev/null
+++ b/tests/src/Util/DateTimeFormatTest.php
@@ -0,0 +1,61 @@
+ [
+ '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));
+ }
+}