3 /* ACL selector json backend */
6 use Friendica\Content\Widget;
7 use Friendica\Core\ACL;
8 use Friendica\Core\Addon;
9 use Friendica\Database\DBA;
10 use Friendica\Model\Contact;
11 use Friendica\Model\Item;
12 use Friendica\Util\Proxy as ProxyUtils;
14 require_once 'include/dba.php';
16 function acl_content(App $a)
22 $start = defaults($_REQUEST, 'start' , 0);
23 $count = defaults($_REQUEST, 'count' , 100);
24 $search = defaults($_REQUEST, 'search' , '');
25 $type = defaults($_REQUEST, 'type' , '');
26 $conv_id = defaults($_REQUEST, 'conversation', null);
28 // For use with jquery.textcomplete for private mail completion
29 if (!empty($_REQUEST['query'])) {
33 $search = $_REQUEST['query'];
36 logger("Searching for ".$search." - type ".$type." conversation ".$conv_id, LOGGER_DEBUG);
39 $sql_extra = "AND `name` LIKE '%%" . DBA::escape($search) . "%%'";
40 $sql_extra2 = "AND (`attag` LIKE '%%" . DBA::escape($search) . "%%' OR `name` LIKE '%%" . DBA::escape($search) . "%%' OR `nick` LIKE '%%" . DBA::escape($search) . "%%')";
42 /// @TODO Avoid these needless else blocks by putting variable-initialization atop of if()
43 $sql_extra = $sql_extra2 = '';
46 // count groups and contacts
48 if ($type == '' || $type == 'g') {
49 $r = q("SELECT COUNT(*) AS g FROM `group` WHERE `deleted` = 0 AND `uid` = %d $sql_extra",
52 $group_count = (int) $r[0]['g'];
55 $sql_extra2 .= ' ' . Widget::unavailableNetworks();
58 if ($type == '' || $type == 'c') {
59 // autocomplete for editor mentions
60 $r = q("SELECT COUNT(*) AS c FROM `contact`
61 WHERE `uid` = %d AND NOT `self`
62 AND NOT `blocked` AND NOT `pending` AND NOT `archive`
63 AND `success_update` >= `failure_update`
64 AND `notify` != '' $sql_extra2",
67 $contact_count = (int) $r[0]['c'];
68 } elseif ($type == 'f') {
69 // autocomplete for editor mentions of forums
70 $r = q("SELECT COUNT(*) AS c FROM `contact`
71 WHERE `uid` = %d AND NOT `self`
72 AND NOT `blocked` AND NOT `pending` AND NOT `archive`
73 AND (`forum` OR `prv`)
74 AND `success_update` >= `failure_update`
75 AND `notify` != '' $sql_extra2",
78 $contact_count = (int) $r[0]['c'];
79 } elseif ($type == 'm') {
80 // autocomplete for Private Messages
81 $r = q("SELECT COUNT(*) AS c FROM `contact`
82 WHERE `uid` = %d AND NOT `self`
83 AND NOT `blocked` AND NOT `pending` AND NOT `archive`
84 AND `success_update` >= `failure_update`
85 AND `network` IN ('%s', '%s') $sql_extra2",
87 DBA::escape(NETWORK_DFRN),
88 DBA::escape(NETWORK_DIASPORA)
90 $contact_count = (int) $r[0]['c'];
91 } elseif ($type == 'a') {
92 // autocomplete for Contacts
93 $r = q("SELECT COUNT(*) AS c FROM `contact`
94 WHERE `uid` = %d AND NOT `self`
95 AND NOT `pending` $sql_extra2",
98 $contact_count = (int) $r[0]['c'];
101 $tot = $group_count + $contact_count;
106 if ($type == '' || $type == 'g') {
107 /// @todo We should cache this query.
108 // This can be done when we can delete cache entries via wildcard
109 $r = q("SELECT `group`.`id`, `group`.`name`, GROUP_CONCAT(DISTINCT `group_member`.`contact-id` SEPARATOR ',') AS uids
111 INNER JOIN `group_member` ON `group_member`.`gid`=`group`.`id`
112 WHERE NOT `group`.`deleted` AND `group`.`uid` = %d
114 GROUP BY `group`.`name`, `group`.`id`
115 ORDER BY `group`.`name`
117 intval(local_user()),
125 'photo' => 'images/twopeople.png',
126 'name' => htmlentities($g['name']),
127 'id' => intval($g['id']),
128 'uids' => array_map('intval', explode(',', $g['uids'])),
133 if ((count($groups) > 0) && ($search == '')) {
134 $groups[] = ['separator' => true];
140 $r = q("SELECT `id`, `name`, `nick`, `micro`, `network`, `url`, `attag`, `addr`, `forum`, `prv`, (`prv` OR `forum`) AS `frm` FROM `contact`
141 WHERE `uid` = %d AND NOT `self` AND NOT `blocked` AND NOT `pending` AND NOT `archive` AND `notify` != ''
142 AND `success_update` >= `failure_update` AND NOT (`network` IN ('%s', '%s'))
144 ORDER BY `name` ASC ",
145 intval(local_user()),
146 DBA::escape(NETWORK_OSTATUS),
147 DBA::escape(NETWORK_STATUSNET)
149 } elseif ($type == 'c') {
150 $r = q("SELECT `id`, `name`, `nick`, `micro`, `network`, `url`, `attag`, `addr`, `forum`, `prv` FROM `contact`
151 WHERE `uid` = %d AND NOT `self` AND NOT `blocked` AND NOT `pending` AND NOT `archive` AND `notify` != ''
152 AND `success_update` >= `failure_update` AND NOT (`network` IN ('%s'))
154 ORDER BY `name` ASC ",
155 intval(local_user()),
156 DBA::escape(NETWORK_STATUSNET)
158 } elseif ($type == 'f') {
159 $r = q("SELECT `id`, `name`, `nick`, `micro`, `network`, `url`, `attag`, `addr`, `forum`, `prv` FROM `contact`
160 WHERE `uid` = %d AND NOT `self` AND NOT `blocked` AND NOT `pending` AND NOT `archive` AND `notify` != ''
161 AND `success_update` >= `failure_update` AND NOT (`network` IN ('%s'))
162 AND (`forum` OR `prv`)
164 ORDER BY `name` ASC ",
165 intval(local_user()),
166 DBA::escape(NETWORK_STATUSNET)
168 } elseif ($type == 'm') {
169 $r = q("SELECT `id`, `name`, `nick`, `micro`, `network`, `url`, `attag`, `addr` FROM `contact`
170 WHERE `uid` = %d AND NOT `self` AND NOT `blocked` AND NOT `pending` AND NOT `archive`
171 AND `success_update` >= `failure_update` AND `network` IN ('%s', '%s')
173 ORDER BY `name` ASC ",
174 intval(local_user()),
175 DBA::escape(NETWORK_DFRN),
176 DBA::escape(NETWORK_DIASPORA)
178 } elseif ($type == 'a') {
179 $r = q("SELECT `id`, `name`, `nick`, `micro`, `network`, `url`, `attag`, `addr`, `forum`, `prv` FROM `contact`
180 WHERE `uid` = %d AND `pending` = 0 AND `success_update` >= `failure_update`
182 ORDER BY `name` ASC ",
185 } elseif ($type == 'x') {
186 // autocomplete for global contact search (e.g. navbar search)
187 $search = notags(trim($_REQUEST['search']));
188 $mode = $_REQUEST['smode'];
190 $r = ACL::contactAutocomplete($search, $mode);
195 'photo' => ProxyUtils::proxifyUrl($g['photo'], false, ProxyUtils::SIZE_MICRO),
196 'name' => $g['name'],
197 'nick' => defaults($g, 'addr', $g['url']),
198 'network' => $g['network'],
200 'forum' => !empty($g['community']) ? 1 : 0,
206 'items' => $contacts,
208 echo json_encode($o);
212 if (DBA::isResult($r)) {
217 'photo' => ProxyUtils::proxifyUrl($g['micro'], false, ProxyUtils::SIZE_MICRO),
218 'name' => htmlentities($g['name']),
219 'id' => intval($g['id']),
220 'network' => $g['network'],
222 'nick' => htmlentities(defaults($g, 'attag', $g['nick'])),
223 'addr' => htmlentities(defaults($g, 'addr', $g['url'])),
224 'forum' => !empty($g['forum']) || !empty($g['prv']) ? 1 : 0,
226 if ($entry['forum']) {
229 $contacts[] = $entry;
232 if (count($forums) > 0) {
234 $forums[] = ['separator' => true];
236 $contacts = array_merge($forums, $contacts);
240 $items = array_merge($groups, $contacts);
243 // In multi threaded posts the conv_id is not the parent of the whole thread
244 $parent_item = Item::selectFirst(['parent'], ['id' => $conv_id]);
245 if (DBA::isResult($parent_item)) {
246 $conv_id = $parent_item['parent'];
250 * if $conv_id is set, get unknown contacts in thread
251 * but first get known contacts url to filter them out
253 $known_contacts = array_map(function ($i) {
257 $unknown_contacts = [];
259 $condition = ["`parent` = ?", $conv_id];
260 $params = ['order' => ['author-name' => true]];
261 $authors = Item::selectForUser(local_user(), ['author-link'], $condition, $params);
263 while ($author = Item::fetch($authors)) {
264 $item_authors[$author['author-link']] = $author['author-link'];
266 DBA::close($authors);
268 foreach ($item_authors as $author) {
269 if (in_array($author, $known_contacts)) {
273 $contact = Contact::getDetailsByURL($author);
275 if (count($contact) > 0) {
276 $unknown_contacts[] = [
278 'photo' => ProxyUtils::proxifyUrl($contact['micro'], false, ProxyUtils::SIZE_MICRO),
279 'name' => htmlentities($contact['name']),
280 'id' => intval($contact['cid']),
281 'network' => $contact['network'],
282 'link' => $contact['url'],
283 'nick' => htmlentities(defaults($contact, 'nick', $contact['addr'])),
284 'addr' => htmlentities(defaults($contact, 'addr', $contact['url'])),
285 'forum' => $contact['forum']
290 $items = array_merge($items, $unknown_contacts);
291 $tot += count($unknown_contacts);
299 'contacts' => $contacts,
305 Addon::callHooks('acl_lookup_end', $results);
308 'tot' => $results['tot'],
309 'start' => $results['start'],
310 'count' => $results['count'],
311 'items' => $results['items'],
314 echo json_encode($o);