]> git.mxchange.org Git - friendica.git/blob - mod/acl.php
The central item fetch does work now and the API now uses these functions
[friendica.git] / mod / acl.php
1 <?php
2
3 /* ACL selector json backend */
4
5 use Friendica\App;
6 use Friendica\Content\Widget;
7 use Friendica\Core\ACL;
8 use Friendica\Core\Addon;
9 use Friendica\Database\DBM;
10 use Friendica\Model\Contact;
11
12 require_once 'include/dba.php';
13 require_once 'mod/proxy.php';
14
15 function acl_content(App $a)
16 {
17         if (!local_user()) {
18                 return '';
19         }
20
21         $start   = defaults($_REQUEST, 'start'       , 0);
22         $count   = defaults($_REQUEST, 'count'       , 100);
23         $search  = defaults($_REQUEST, 'search'      , '');
24         $type    = defaults($_REQUEST, 'type'        , '');
25         $conv_id = defaults($_REQUEST, 'conversation', null);
26
27         // For use with jquery.textcomplete for private mail completion
28         if (!empty($_REQUEST['query'])) {
29                 if (!$type) {
30                         $type = 'm';
31                 }
32                 $search = $_REQUEST['query'];
33         }
34
35         logger("Searching for ".$search." - type ".$type." conversation ".$conv_id, LOGGER_DEBUG);
36
37         if ($search != '') {
38                 $sql_extra = "AND `name` LIKE '%%" . dbesc($search) . "%%'";
39                 $sql_extra2 = "AND (`attag` LIKE '%%" . dbesc($search) . "%%' OR `name` LIKE '%%" . dbesc($search) . "%%' OR `nick` LIKE '%%" . dbesc($search) . "%%')";
40         } else {
41                 /// @TODO Avoid these needless else blocks by putting variable-initialization atop of if()
42                 $sql_extra = $sql_extra2 = '';
43         }
44
45         // count groups and contacts
46         $group_count = 0;
47         if ($type == '' || $type == 'g') {
48                 $r = q("SELECT COUNT(*) AS g FROM `group` WHERE `deleted` = 0 AND `uid` = %d $sql_extra",
49                         intval(local_user())
50                 );
51                 $group_count = (int) $r[0]['g'];
52         }
53
54         $sql_extra2 .= ' ' . Widget::unavailableNetworks();
55
56         $contact_count = 0;
57         if ($type == '' || $type == 'c') {
58                 // autocomplete for editor mentions
59                 $r = q("SELECT COUNT(*) AS c FROM `contact`
60                                 WHERE `uid` = %d AND NOT `self`
61                                 AND NOT `blocked` AND NOT `pending` AND NOT `archive`
62                                 AND `success_update` >= `failure_update`
63                                 AND `notify` != '' $sql_extra2",
64                         intval(local_user())
65                 );
66                 $contact_count = (int) $r[0]['c'];
67         } elseif ($type == 'f') {
68                 // autocomplete for editor mentions of forums
69                 $r = q("SELECT COUNT(*) AS c FROM `contact`
70                                 WHERE `uid` = %d AND NOT `self`
71                                 AND NOT `blocked` AND NOT `pending` AND NOT `archive`
72                                 AND (`forum` OR `prv`)
73                                 AND `success_update` >= `failure_update`
74                                 AND `notify` != '' $sql_extra2",
75                         intval(local_user())
76                 );
77                 $contact_count = (int) $r[0]['c'];
78         } elseif ($type == 'm') {
79                 // autocomplete for Private Messages
80                 $r = q("SELECT COUNT(*) AS c FROM `contact`
81                                 WHERE `uid` = %d AND NOT `self`
82                                 AND NOT `blocked` AND NOT `pending` AND NOT `archive`
83                                 AND `success_update` >= `failure_update`
84                                 AND `network` IN ('%s', '%s') $sql_extra2",
85                         intval(local_user()),
86                         dbesc(NETWORK_DFRN),
87                         dbesc(NETWORK_DIASPORA)
88                 );
89                 $contact_count = (int) $r[0]['c'];
90         } elseif ($type == 'a') {
91                 // autocomplete for Contacts
92                 $r = q("SELECT COUNT(*) AS c FROM `contact`
93                                 WHERE `uid` = %d AND NOT `self`
94                                 AND NOT `pending` $sql_extra2",
95                         intval(local_user())
96                 );
97                 $contact_count = (int) $r[0]['c'];
98         }
99
100         $tot = $group_count + $contact_count;
101
102         $groups = [];
103         $contacts = [];
104
105         if ($type == '' || $type == 'g') {
106                 /// @todo We should cache this query.
107                 // This can be done when we can delete cache entries via wildcard
108                 $r = q("SELECT `group`.`id`, `group`.`name`, GROUP_CONCAT(DISTINCT `group_member`.`contact-id` SEPARATOR ',') AS uids
109                                 FROM `group`
110                                 INNER JOIN `group_member` ON `group_member`.`gid`=`group`.`id`
111                                 WHERE NOT `group`.`deleted` AND `group`.`uid` = %d
112                                         $sql_extra
113                                 GROUP BY `group`.`name`, `group`.`id`
114                                 ORDER BY `group`.`name`
115                                 LIMIT %d,%d",
116                         intval(local_user()),
117                         intval($start),
118                         intval($count)
119                 );
120
121                 foreach ($r as $g) {
122                         $groups[] = [
123                                 'type'  => 'g',
124                                 'photo' => 'images/twopeople.png',
125                                 'name'  => htmlentities($g['name']),
126                                 'id'    => intval($g['id']),
127                                 'uids'  => array_map('intval', explode(',', $g['uids'])),
128                                 'link'  => '',
129                                 'forum' => '0'
130                         ];
131                 }
132                 if ((count($groups) > 0) && ($search == '')) {
133                         $groups[] = ['separator' => true];
134                 }
135         }
136
137         $r = [];
138         if ($type == '') {
139                 $r = q("SELECT `id`, `name`, `nick`, `micro`, `network`, `url`, `attag`, `addr`, `forum`, `prv`, (`prv` OR `forum`) AS `frm` FROM `contact`
140                                 WHERE `uid` = %d AND NOT `self` AND NOT `blocked` AND NOT `pending` AND NOT `archive` AND `notify` != ''
141                                 AND `success_update` >= `failure_update` AND NOT (`network` IN ('%s', '%s'))
142                                 $sql_extra2
143                                 ORDER BY `name` ASC ",
144                         intval(local_user()),
145                         dbesc(NETWORK_OSTATUS),
146                         dbesc(NETWORK_STATUSNET)
147                 );
148         } elseif ($type == 'c') {
149                 $r = q("SELECT `id`, `name`, `nick`, `micro`, `network`, `url`, `attag`, `addr`, `forum`, `prv` FROM `contact`
150                                 WHERE `uid` = %d AND NOT `self` AND NOT `blocked` AND NOT `pending` AND NOT `archive` AND `notify` != ''
151                                 AND `success_update` >= `failure_update` AND NOT (`network` IN ('%s'))
152                                 $sql_extra2
153                                 ORDER BY `name` ASC ",
154                         intval(local_user()),
155                         dbesc(NETWORK_STATUSNET)
156                 );
157         } elseif ($type == 'f') {
158                 $r = q("SELECT `id`, `name`, `nick`, `micro`, `network`, `url`, `attag`, `addr`, `forum`, `prv` FROM `contact`
159                                 WHERE `uid` = %d AND NOT `self` AND NOT `blocked` AND NOT `pending` AND NOT `archive` AND `notify` != ''
160                                 AND `success_update` >= `failure_update` AND NOT (`network` IN ('%s'))
161                                 AND (`forum` OR `prv`)
162                                 $sql_extra2
163                                 ORDER BY `name` ASC ",
164                         intval(local_user()),
165                         dbesc(NETWORK_STATUSNET)
166                 );
167         } elseif ($type == 'm') {
168                 $r = q("SELECT `id`, `name`, `nick`, `micro`, `network`, `url`, `attag`, `addr` FROM `contact`
169                                 WHERE `uid` = %d AND NOT `self` AND NOT `blocked` AND NOT `pending` AND NOT `archive`
170                                 AND `success_update` >= `failure_update` AND `network` IN ('%s', '%s')
171                                 $sql_extra2
172                                 ORDER BY `name` ASC ",
173                         intval(local_user()),
174                         dbesc(NETWORK_DFRN),
175                         dbesc(NETWORK_DIASPORA)
176                 );
177         } elseif ($type == 'a') {
178                 $r = q("SELECT `id`, `name`, `nick`, `micro`, `network`, `url`, `attag`, `addr`, `forum`, `prv` FROM `contact`
179                                 WHERE `uid` = %d AND `pending` = 0 AND `success_update` >= `failure_update`
180                                 $sql_extra2
181                                 ORDER BY `name` ASC ",
182                         intval(local_user())
183                 );
184         } elseif ($type == 'x') {
185                 // autocomplete for global contact search (e.g. navbar search)
186                 $search = notags(trim($_REQUEST['search']));
187                 $mode = $_REQUEST['smode'];
188
189                 $r = ACL::contactAutocomplete($search, $mode);
190
191                 $contacts = [];
192                 foreach ($r as $g) {
193                         $contacts[] = [
194                                 'photo'   => proxy_url($g['photo'], false, PROXY_SIZE_MICRO),
195                                 'name'    => $g['name'],
196                                 'nick'    => defaults($g, 'addr', $g['url']),
197                                 'network' => $g['network'],
198                                 'link'    => $g['url'],
199                                 'forum'   => !empty($g['community']) ? 1 : 0,
200                         ];
201                 }
202                 $o = [
203                         'start' => $start,
204                         'count' => $count,
205                         'items' => $contacts,
206                 ];
207                 echo json_encode($o);
208                 exit;
209         }
210
211         if (DBM::is_result($r)) {
212                 $forums = [];
213                 foreach ($r as $g) {
214                         $entry = [
215                                 'type'    => 'c',
216                                 'photo'   => proxy_url($g['micro'], false, PROXY_SIZE_MICRO),
217                                 'name'    => htmlentities($g['name']),
218                                 'id'      => intval($g['id']),
219                                 'network' => $g['network'],
220                                 'link'    => $g['url'],
221                                 'nick'    => htmlentities(defaults($g, 'attag', $g['nick'])),
222                                 'addr'    => htmlentities(defaults($g, 'addr', $g['url'])),
223                                 'forum'   => !empty($g['forum']) || !empty($g['prv']) ? 1 : 0,
224                         ];
225                         if ($entry['forum']) {
226                                 $forums[] = $entry;
227                         } else {
228                                 $contacts[] = $entry;
229                         }
230                 }
231                 if (count($forums) > 0) {
232                         if ($search == '') {
233                                 $forums[] = ['separator' => true];
234                         }
235                         $contacts = array_merge($forums, $contacts);
236                 }
237         }
238
239         $items = array_merge($groups, $contacts);
240
241         if ($conv_id) {
242                 // In multi threaded posts the conv_id is not the parent of the whole thread
243                 $parent_item = dba::selectFirst('item', ['parent'], ['id' => $conv_id]);
244                 if (DBM::is_result($parent_item)) {
245                         $conv_id = $parent_item['parent'];
246                 }
247
248                 /*
249                  * if $conv_id is set, get unknown contacts in thread
250                  * but first get known contacts url to filter them out
251                  */
252                 $known_contacts = array_map(function ($i) {
253                         return dbesc($i['link']);
254                 }, $contacts);
255
256                 $unknown_contacts = [];
257                 $r = q("SELECT `author-link`
258                                 FROM `item` WHERE `parent` = %d
259                                         AND (`author-name` LIKE '%%%s%%' OR `author-link` LIKE '%%%s%%')
260                                         AND `author-link` NOT IN ('%s')
261                                 GROUP BY `author-link`, `author-avatar`, `author-name`
262                                 ORDER BY `author-name` ASC
263                                 ",
264                         intval($conv_id),
265                         dbesc($search),
266                         dbesc($search),
267                         implode("', '", $known_contacts)
268                 );
269                 if (DBM::is_result($r)) {
270                         foreach ($r as $row) {
271                                 $contact = Contact::getDetailsByURL($row['author-link']);
272
273                                 if (count($contact) > 0) {
274                                         $unknown_contacts[] = [
275                                                 'type'    => 'c',
276                                                 'photo'   => proxy_url($contact['micro'], false, PROXY_SIZE_MICRO),
277                                                 'name'    => htmlentities($contact['name']),
278                                                 'id'      => intval($contact['cid']),
279                                                 'network' => $contact['network'],
280                                                 'link'    => $contact['url'],
281                                                 'nick'    => htmlentities(defaults($contact, 'nick', $contact['addr'])),
282                                                 'addr'    => htmlentities(defaults($contact, 'addr', $contact['url'])),
283                                                 'forum'   => $contact['forum']
284                                         ];
285                                 }
286                         }
287                 }
288
289                 $items = array_merge($items, $unknown_contacts);
290                 $tot += count($unknown_contacts);
291         }
292
293         $results = [
294                 'tot'      => $tot,
295                 'start'    => $start,
296                 'count'    => $count,
297                 'groups'   => $groups,
298                 'contacts' => $contacts,
299                 'items'    => $items,
300                 'type'     => $type,
301                 'search'   => $search,
302         ];
303
304         Addon::callHooks('acl_lookup_end', $results);
305
306         $o = [
307                 'tot'   => $results['tot'],
308                 'start' => $results['start'],
309                 'count' => $results['count'],
310                 'items' => $results['items'],
311         ];
312
313         echo json_encode($o);
314         exit;
315 }