-
-/**
- * This function removes the tag $tag from the text $body and replaces it with
- * the appropriate link.
- *
- * @param App $a
- * @param string $body the text to replace the tag in
- * @param string $inform a comma-seperated string containing everybody to inform
- * @param string $str_tags string to add the tag to
- * @param integer $profile_uid
- * @param string $tag the tag to replace
- * @param string $network The network of the post
- *
- * @return array|bool ['replaced' => $replaced, 'contact' => $contact];
- * @throws ImagickException
- * @throws HTTPException\InternalServerErrorException
- */
-function handle_tag(&$body, &$inform, &$str_tags, $profile_uid, $tag, $network = "")
-{
- $replaced = false;
- $r = null;
-
- //is it a person tag?
- if (Term::isType($tag, Term::MENTION, Term::IMPLICIT_MENTION, Term::EXCLUSIVE_MENTION)) {
- $tag_type = substr($tag, 0, 1);
- //is it already replaced?
- if (strpos($tag, '[url=')) {
- //append tag to str_tags
- if (!stristr($str_tags, $tag)) {
- if (strlen($str_tags)) {
- $str_tags .= ',';
- }
- $str_tags .= $tag;
- }
-
- // Checking for the alias that is used for OStatus
- $pattern = "/[@!]\[url\=(.*?)\](.*?)\[\/url\]/ism";
- if (preg_match($pattern, $tag, $matches)) {
- $data = Contact::getDetailsByURL($matches[1]);
-
- if ($data["alias"] != "") {
- $newtag = '@[url=' . $data["alias"] . ']' . $data["nick"] . '[/url]';
-
- if (!stripos($str_tags, '[url=' . $data["alias"] . ']')) {
- if (strlen($str_tags)) {
- $str_tags .= ',';
- }
-
- $str_tags .= $newtag;
- }
- }
- }
-
- return $replaced;
- }
-
- //get the person's name
- $name = substr($tag, 1);
-
- // Sometimes the tag detection doesn't seem to work right
- // This is some workaround
- $nameparts = explode(" ", $name);
- $name = $nameparts[0];
-
- // Try to detect the contact in various ways
- if (strpos($name, 'http://')) {
- // At first we have to ensure that the contact exists
- Contact::getIdForURL($name);
-
- // Now we should have something
- $contact = Contact::getDetailsByURL($name);
- } elseif (strpos($name, '@')) {
- // This function automatically probes when no entry was found
- $contact = Contact::getDetailsByAddr($name);
- } else {
- $contact = false;
- $fields = ['id', 'url', 'nick', 'name', 'alias', 'network', 'forum', 'prv'];
-
- if (strrpos($name, '+')) {
- // Is it in format @nick+number?
- $tagcid = intval(substr($name, strrpos($name, '+') + 1));
- $contact = DBA::selectFirst('contact', $fields, ['id' => $tagcid, 'uid' => $profile_uid]);
- }
-
- // select someone by nick or attag in the current network
- if (!DBA::isResult($contact) && ($network != "")) {
- $condition = ["(`nick` = ? OR `attag` = ?) AND `network` = ? AND `uid` = ?",
- $name, $name, $network, $profile_uid];
- $contact = DBA::selectFirst('contact', $fields, $condition);
- }
-
- //select someone by name in the current network
- if (!DBA::isResult($contact) && ($network != "")) {
- $condition = ['name' => $name, 'network' => $network, 'uid' => $profile_uid];
- $contact = DBA::selectFirst('contact', $fields, $condition);
- }
-
- // select someone by nick or attag in any network
- if (!DBA::isResult($contact)) {
- $condition = ["(`nick` = ? OR `attag` = ?) AND `uid` = ?", $name, $name, $profile_uid];
- $contact = DBA::selectFirst('contact', $fields, $condition);
- }
-
- // select someone by name in any network
- if (!DBA::isResult($contact)) {
- $condition = ['name' => $name, 'uid' => $profile_uid];
- $contact = DBA::selectFirst('contact', $fields, $condition);
- }
- }
-
- // Check if $contact has been successfully loaded
- if (DBA::isResult($contact)) {
- if (strlen($inform) && (isset($contact["notify"]) || isset($contact["id"]))) {
- $inform .= ',';
- }
-
- if (isset($contact["id"])) {
- $inform .= 'cid:' . $contact["id"];
- } elseif (isset($contact["notify"])) {
- $inform .= $contact["notify"];
- }
-
- $profile = $contact["url"];
- $alias = $contact["alias"];
- $newname = ($contact["name"] ?? '') ?: $contact["nick"];
- }
-
- //if there is an url for this persons profile
- if (isset($profile) && ($newname != "")) {
- $replaced = true;
- // create profile link
- $profile = str_replace(',', '%2c', $profile);
- $newtag = $tag_type.'[url=' . $profile . ']' . $newname . '[/url]';
- $body = str_replace($tag_type . $name, $newtag, $body);
- // append tag to str_tags
- if (!stristr($str_tags, $newtag)) {
- if (strlen($str_tags)) {
- $str_tags .= ',';
- }
- $str_tags .= $newtag;
- }
-
- /*
- * Status.Net seems to require the numeric ID URL in a mention if the person isn't
- * subscribed to you. But the nickname URL is OK if they are. Grrr. We'll tag both.
- */
- if (!empty($alias)) {
- $newtag = '@[url=' . $alias . ']' . $newname . '[/url]';
- if (!stripos($str_tags, '[url=' . $alias . ']')) {
- if (strlen($str_tags)) {
- $str_tags .= ',';
- }
- $str_tags .= $newtag;
- }
- }
- }
- }
-
- return ['replaced' => $replaced, 'contact' => $contact];
-}
-
-function item_add_implicit_mentions(array $tags, array $thread_parent_contact, $thread_parent_id)
-{
- if (DI::config()->get('system', 'disable_implicit_mentions')) {
- // Add a tag if the parent contact is from ActivityPub or OStatus (This will notify them)
- if (in_array($thread_parent_contact['network'], [Protocol::OSTATUS, Protocol::ACTIVITYPUB])) {
- $contact = Term::TAG_CHARACTER[Term::MENTION] . '[url=' . $thread_parent_contact['url'] . ']' . $thread_parent_contact['nick'] . '[/url]';
- if (!stripos(implode($tags), '[url=' . $thread_parent_contact['url'] . ']')) {
- $tags[] = $contact;
- }
- }
- } else {
- $implicit_mentions = [
- $thread_parent_contact['url'] => $thread_parent_contact['nick']
- ];
-
- $parent_terms = Term::tagArrayFromItemId($thread_parent_id, [Term::MENTION, Term::IMPLICIT_MENTION]);
-
- foreach ($parent_terms as $parent_term) {
- $implicit_mentions[$parent_term['url']] = $parent_term['term'];
- }
-
- foreach ($implicit_mentions as $url => $label) {
- if ($url != \Friendica\Model\Profile::getMyURL() && !stripos(implode($tags), '[url=' . $url . ']')) {
- $tags[] = Term::TAG_CHARACTER[Term::IMPLICIT_MENTION] . '[url=' . $url . ']' . $label . '[/url]';
- }
- }
- }
-
- return $tags;
-}