]> git.mxchange.org Git - friendica.git/blob - src/Model/Term.php
Use the item classes where possible
[friendica.git] / src / Model / Term.php
1 <?php
2 /**
3  * @file src/Model/Term
4  */
5 namespace Friendica\Model;
6
7 use Friendica\Core\System;
8 use Friendica\Database\DBM;
9 use Friendica\Model\Item;
10 use dba;
11
12 require_once 'boot.php';
13 require_once 'include/conversation.php';
14 require_once 'include/dba.php';
15
16 class Term
17 {
18         public static function insertFromTagFieldByItemId($itemid)
19         {
20                 $profile_base = System::baseUrl();
21                 $profile_data = parse_url($profile_base);
22                 $profile_path = defaults($profile_data, 'path', '');
23                 $profile_base_friendica = $profile_data['host'] . $profile_path . '/profile/';
24                 $profile_base_diaspora = $profile_data['host'] . $profile_path . '/u/';
25
26                 $fields = ['guid', 'uid', 'id', 'edited', 'deleted', 'created', 'received', 'title', 'body', 'tag', 'parent'];
27                 $message = dba::selectFirst('item', $fields, ['id' => $itemid]);
28                 if (!DBM::is_result($message)) {
29                         return;
30                 }
31
32                 // Clean up all tags
33                 dba::delete('term', ['otype' => TERM_OBJ_POST, 'oid' => $itemid, 'type' => [TERM_HASHTAG, TERM_MENTION]]);
34
35                 if ($message['deleted']) {
36                         return;
37                 }
38
39                 $taglist = explode(',', $message['tag']);
40
41                 $tags_string = '';
42                 foreach ($taglist as $tag) {
43                         if ((substr(trim($tag), 0, 1) == '#') || (substr(trim($tag), 0, 1) == '@')) {
44                                 $tags_string .= ' ' . trim($tag);
45                         } else {
46                                 $tags_string .= ' #' . trim($tag);
47                         }
48                 }
49
50                 $data = ' ' . $message['title'] . ' ' . $message['body'] . ' ' . $tags_string . ' ';
51
52                 // ignore anything in a code block
53                 $data = preg_replace('/\[code\](.*?)\[\/code\]/sm', '', $data);
54
55                 $tags = [];
56
57                 $pattern = '/\W\#([^\[].*?)[\s\'".,:;\?!\[\]\/]/ism';
58                 if (preg_match_all($pattern, $data, $matches)) {
59                         foreach ($matches[1] as $match) {
60                                 $tags['#' . strtolower($match)] = '';
61                         }
62                 }
63
64                 $pattern = '/\W([\#@])\[url\=(.*?)\](.*?)\[\/url\]/ism';
65                 if (preg_match_all($pattern, $data, $matches, PREG_SET_ORDER)) {
66                         foreach ($matches as $match) {
67                                 $tags[$match[1] . strtolower(trim($match[3], ',.:;[]/\"?!'))] = $match[2];
68                         }
69                 }
70
71                 foreach ($tags as $tag => $link) {
72                         if (substr(trim($tag), 0, 1) == '#') {
73                                 // try to ignore #039 or #1 or anything like that
74                                 if (ctype_digit(substr(trim($tag), 1))) {
75                                         continue;
76                                 }
77
78                                 // try to ignore html hex escapes, e.g. #x2317
79                                 if ((substr(trim($tag), 1, 1) == 'x' || substr(trim($tag), 1, 1) == 'X') && ctype_digit(substr(trim($tag), 2))) {
80                                         continue;
81                                 }
82
83                                 $type = TERM_HASHTAG;
84                                 $term = substr($tag, 1);
85                         } elseif (substr(trim($tag), 0, 1) == '@') {
86                                 $type = TERM_MENTION;
87                                 $term = substr($tag, 1);
88                         } else { // This shouldn't happen
89                                 $type = TERM_HASHTAG;
90                                 $term = $tag;
91                         }
92
93                         if ($message['uid'] == 0) {
94                                 $global = true;
95                                 dba::update('term', ['global' => true], ['otype' => TERM_OBJ_POST, 'guid' => $message['guid']]);
96                         } else {
97                                 $global = dba::exists('term', ['uid' => 0, 'otype' => TERM_OBJ_POST, 'guid' => $message['guid']]);
98                         }
99
100                         dba::insert('term', [
101                                 'uid'      => $message['uid'],
102                                 'oid'      => $itemid,
103                                 'otype'    => TERM_OBJ_POST,
104                                 'type'     => $type,
105                                 'term'     => $term,
106                                 'url'      => $link,
107                                 'guid'     => $message['guid'],
108                                 'created'  => $message['created'],
109                                 'received' => $message['received'],
110                                 'global'   => $global
111                         ]);
112
113                         // Search for mentions
114                         if ((substr($tag, 0, 1) == '@') && (strpos($link, $profile_base_friendica) || strpos($link, $profile_base_diaspora))) {
115                                 $users = q("SELECT `uid` FROM `contact` WHERE self AND (`url` = '%s' OR `nurl` = '%s')", $link, $link);
116                                 foreach ($users AS $user) {
117                                         if ($user['uid'] == $message['uid']) {
118                                                 Item::update(['mention' => true], ['id' => $itemid]);
119                                                 dba::update('thread', ['mention' => true], ['iid' => $message['parent']]);
120                                         }
121                                 }
122                         }
123                 }
124         }
125
126         /**
127          * @param integer $itemid item id
128          * @return void
129          */
130         public static function insertFromFileFieldByItemId($itemid)
131         {
132                 $message = dba::selectFirst('item', ['uid', 'deleted', 'file'], ['id' => $itemid]);
133                 if (!DBM::is_result($message)) {
134                         return;
135                 }
136
137                 // Clean up all tags
138                 dba::delete('term', ['otype' => TERM_OBJ_POST, 'oid' => $itemid, 'type' => [TERM_FILE, TERM_CATEGORY]]);
139
140                 if ($message["deleted"]) {
141                         return;
142                 }
143
144                 if (preg_match_all("/\[(.*?)\]/ism", $message["file"], $files)) {
145                         foreach ($files[1] as $file) {
146                                 dba::insert('term', [
147                                         'uid' => $message["uid"],
148                                         'oid' => $itemid,
149                                         'otype' => TERM_OBJ_POST,
150                                         'type' => TERM_FILE,
151                                         'term' => $file
152                                 ]);
153                         }
154                 }
155
156                 if (preg_match_all("/\<(.*?)\>/ism", $message["file"], $files)) {
157                         foreach ($files[1] as $file) {
158                                 dba::insert('term', [
159                                         'uid' => $message["uid"],
160                                         'oid' => $itemid,
161                                         'otype' => TERM_OBJ_POST,
162                                         'type' => TERM_CATEGORY,
163                                         'term' => $file
164                                 ]);
165                         }
166                 }
167         }
168
169         /**
170          * Sorts an item's tags into mentions, hashtags and other tags. Generate personalized URLs by user and modify the
171          * provided item's body with them.
172          *
173          * @param array $item
174          * @return array
175          */
176         public static function populateTagsFromItem(&$item)
177         {
178                 $return = [
179                         'tags' => [],
180                         'hashtags' => [],
181                         'mentions' => [],
182                 ];
183
184                 $searchpath = System::baseUrl() . "/search?tag=";
185
186                 $taglist = dba::select(
187                         'term',
188                         ['type', 'term', 'url'],
189                         ["`otype` = ? AND `oid` = ? AND `type` IN (?, ?)", TERM_OBJ_POST, $item['id'], TERM_HASHTAG, TERM_MENTION],
190                         ['order' => ['tid']]
191                 );
192
193                 while ($tag = dba::fetch($taglist)) {
194                         if ($tag["url"] == "") {
195                                 $tag["url"] = $searchpath . strtolower($tag["term"]);
196                         }
197
198                         $orig_tag = $tag["url"];
199
200                         $tag["url"] = Contact::magicLinkById($item['author-id'], $tag['url']);
201
202                         if ($tag["type"] == TERM_HASHTAG) {
203                                 if ($orig_tag != $tag["url"]) {
204                                         $item['body'] = str_replace($orig_tag, $tag["url"], $item['body']);
205                                 }
206
207                                 $return['hashtags'][] = "#<a href=\"" . $tag["url"] . "\" target=\"_blank\">" . $tag["term"] . "</a>";
208                                 $prefix = "#";
209                         } elseif ($tag["type"] == TERM_MENTION) {
210                                 $return['mentions'][] = "@<a href=\"" . $tag["url"] . "\" target=\"_blank\">" . $tag["term"] . "</a>";
211                                 $prefix = "@";
212                         }
213
214                         $return['tags'][] = $prefix . "<a href=\"" . $tag["url"] . "\" target=\"_blank\">" . $tag["term"] . "</a>";
215                 }
216                 dba::close($taglist);
217
218                 return $return;
219         }
220 }