3 * @copyright Copyright (C) 2020, Friendica
5 * @license GNU AGPL version 3 or any later version
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as
9 * published by the Free Software Foundation, either version 3 of the
10 * License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 namespace Friendica\Content;
24 use Friendica\Database\DBA;
25 use Friendica\Model\Contact;
26 use Friendica\Model\FileTag;
27 use Friendica\Model\Tag;
30 * A content helper class for displaying items
35 * Return array with details for categories and folders for an item
38 * @return [array, array]
41 * [ // categories array
43 * 'name': 'category name',
44 * 'removeurl': 'url to remove this category',
45 * 'first': 'is the first in this array? true/false',
46 * 'last': 'is the last in this array? true/false',
52 * 'name': 'folder name',
53 * 'removeurl': 'url to remove this folder',
54 * 'first': 'is the first in this array? true/false',
55 * 'last': 'is the last in this array? true/false',
61 public function determineCategoriesTerms(array $item)
67 foreach (FileTag::fileToArray($item['file'] ?? '', 'category') as $savedFolderName) {
68 if (!empty($item['author-link'])) {
69 $url = $item['author-link'] . "?category=" . rawurlencode($savedFolderName);
74 'name' => $savedFolderName,
76 'removeurl' => ((local_user() == $item['uid']) ? 'filerm/' . $item['id'] . '?cat=' . rawurlencode($savedFolderName) : ""),
83 if (count($categories)) {
84 $categories[count($categories) - 1]['last'] = true;
87 if (local_user() == $item['uid']) {
88 foreach (FileTag::fileToArray($item['file'] ?? '') as $savedFolderName) {
90 'name' => $savedFolderName,
92 'removeurl' => ((local_user() == $item['uid']) ? 'filerm/' . $item['id'] . '?term=' . rawurlencode($savedFolderName) : ""),
100 if (count($folders)) {
101 $folders[count($folders) - 1]['last'] = true;
104 return [$categories, $folders];
108 * This function removes the tag $tag from the text $body and replaces it with
109 * the appropriate link.
111 * @param string $body the text to replace the tag in
112 * @param string $inform a comma-seperated string containing everybody to inform
113 * @param integer $profile_uid the user id to replace the tag for (0 = anyone)
114 * @param string $tag the tag to replace
115 * @param string $network The network of the post
117 * @return array|bool ['replaced' => $replaced, 'contact' => $contact];
118 * @throws \Friendica\Network\HTTPException\InternalServerErrorException
119 * @throws \ImagickException
121 public static function replaceTag(&$body, &$inform, $profile_uid, $tag, $network = '')
125 //is it a person tag?
126 if (Tag::isType($tag, Tag::MENTION, Tag::IMPLICIT_MENTION, Tag::EXCLUSIVE_MENTION)) {
127 $tag_type = substr($tag, 0, 1);
128 //is it already replaced?
129 if (strpos($tag, '[url=')) {
130 // Checking for the alias that is used for OStatus
131 $pattern = '/[@!]\[url\=(.*?)\](.*?)\[\/url\]/ism';
132 if (preg_match($pattern, $tag, $matches)) {
133 $data = Contact::getDetailsByURL($matches[1]);
135 if ($data['alias'] != '') {
136 $newtag = '@[url=' . $data['alias'] . ']' . $data['nick'] . '[/url]';
143 //get the person's name
144 $name = substr($tag, 1);
146 // Sometimes the tag detection doesn't seem to work right
147 // This is some workaround
148 $nameparts = explode(' ', $name);
149 $name = $nameparts[0];
151 // Try to detect the contact in various ways
152 if (strpos($name, 'http://')) {
153 // At first we have to ensure that the contact exists
154 Contact::getIdForURL($name);
156 // Now we should have something
157 $contact = Contact::getDetailsByURL($name, $profile_uid);
158 } elseif (strpos($name, '@')) {
159 // This function automatically probes when no entry was found
160 $contact = Contact::getDetailsByAddr($name, $profile_uid);
163 $fields = ['id', 'url', 'nick', 'name', 'alias', 'network', 'forum', 'prv'];
165 if (strrpos($name, '+')) {
166 // Is it in format @nick+number?
167 $tagcid = intval(substr($name, strrpos($name, '+') + 1));
168 $contact = DBA::selectFirst('contact', $fields, ['id' => $tagcid, 'uid' => $profile_uid]);
171 // select someone by nick in the current network
172 if (!DBA::isResult($contact) && ($network != '')) {
173 $condition = ["`nick` = ? AND `network` = ? AND `uid` = ?",
174 $name, $network, $profile_uid];
175 $contact = DBA::selectFirst('contact', $fields, $condition);
178 // select someone by attag in the current network
179 if (!DBA::isResult($contact) && ($network != '')) {
180 $condition = ["`attag` = ? AND `network` = ? AND `uid` = ?",
181 $name, $network, $profile_uid];
182 $contact = DBA::selectFirst('contact', $fields, $condition);
185 //select someone by name in the current network
186 if (!DBA::isResult($contact) && ($network != '')) {
187 $condition = ['name' => $name, 'network' => $network, 'uid' => $profile_uid];
188 $contact = DBA::selectFirst('contact', $fields, $condition);
191 // select someone by nick in any network
192 if (!DBA::isResult($contact)) {
193 $condition = ["`nick` = ? AND `uid` = ?", $name, $profile_uid];
194 $contact = DBA::selectFirst('contact', $fields, $condition);
197 // select someone by attag in any network
198 if (!DBA::isResult($contact)) {
199 $condition = ["`attag` = ? AND `uid` = ?", $name, $profile_uid];
200 $contact = DBA::selectFirst('contact', $fields, $condition);
203 // select someone by name in any network
204 if (!DBA::isResult($contact)) {
205 $condition = ['name' => $name, 'uid' => $profile_uid];
206 $contact = DBA::selectFirst('contact', $fields, $condition);
210 // Check if $contact has been successfully loaded
211 if (DBA::isResult($contact)) {
212 if (strlen($inform) && (isset($contact['notify']) || isset($contact['id']))) {
216 if (isset($contact['id'])) {
217 $inform .= 'cid:' . $contact['id'];
218 } elseif (isset($contact['notify'])) {
219 $inform .= $contact['notify'];
222 $profile = $contact['url'];
223 $newname = ($contact['name'] ?? '') ?: $contact['nick'];
226 //if there is an url for this persons profile
227 if (isset($profile) && ($newname != '')) {
229 // create profile link
230 $profile = str_replace(',', '%2c', $profile);
231 $newtag = $tag_type.'[url=' . $profile . ']' . $newname . '[/url]';
232 $body = str_replace($tag_type . $name, $newtag, $body);
236 return ['replaced' => $replaced, 'contact' => $contact];