]> git.mxchange.org Git - friendica.git/blob - include/acl_selectors.php
Merge pull request #611 from fermionic/20130209-cant-select-individual-contacts
[friendica.git] / include / acl_selectors.php
1 <?php
2
3 require_once("include/contact_selectors.php");
4
5 /**
6  * 
7  */
8
9 /**
10  * @package acl_selectors 
11  */
12 function group_select($selname,$selclass,$preselected = false,$size = 4) {
13
14         $a = get_app();
15
16         $o = '';
17
18         $o .= "<select name=\"{$selname}[]\" id=\"$selclass\" class=\"$selclass\" multiple=\"multiple\" size=\"$size\" >\r\n";
19
20         $r = q("SELECT * FROM `group` WHERE `deleted` = 0 AND `uid` = %d ORDER BY `name` ASC",
21                 intval(local_user())
22         );
23
24
25         $arr = array('group' => $r, 'entry' => $o);
26
27         // e.g. 'network_pre_group_deny', 'profile_pre_group_allow'
28
29         call_hooks($a->module . '_pre_' . $selname, $arr);
30
31         if(count($r)) {
32                 foreach($r as $rr) {
33                         if((is_array($preselected)) && in_array($rr['id'], $preselected))
34                                 $selected = " selected=\"selected\" ";
35                         else
36                                 $selected = '';
37                         $trimmed = mb_substr($rr['name'],0,12);
38
39                         $o .= "<option value=\"{$rr['id']}\" $selected title=\"{$rr['name']}\" >$trimmed</option>\r\n";
40                 }
41         
42         }
43         $o .= "</select>\r\n";
44
45         call_hooks($a->module . '_post_' . $selname, $o);
46
47
48         return $o;
49 }
50
51
52 function contact_selector($selname, $selclass, $preselected = false, $options) {
53
54         $a = get_app();
55
56         $mutual = false;
57         $networks = null;
58         $single = false;
59         $exclude = false;
60         $size = 4;
61
62         if(is_array($options)) {
63                 if(x($options,'size'))
64                         $size = $options['size'];
65
66                 if(x($options,'mutual_friends'))
67                         $mutual = true;
68                 if(x($options,'single'))
69                         $single = true;
70                 if(x($options,'multiple'))
71                         $single = false;
72                 if(x($options,'exclude'))
73                         $exclude = $options['exclude'];
74
75                 if(x($options,'networks')) {
76                         switch($options['networks']) {
77                                 case 'DFRN_ONLY':
78                                         $networks = array('dfrn');
79                                         break;
80                                 case 'PRIVATE':
81                                         if(is_array($a->user) && $a->user['prvnets'])
82                                                 $networks = array('dfrn','mail','dspr');
83                                         else
84                                                 $networks = array('dfrn','face','mail', 'dspr');
85                                         break;
86                                 case 'TWO_WAY':
87                                         if(is_array($a->user) && $a->user['prvnets'])
88                                                 $networks = array('dfrn','mail','dspr');
89                                         else
90                                                 $networks = array('dfrn','face','mail','dspr','stat');
91                                         break;                                  
92                                 default:
93                                         break;
94                         }
95                 }
96         }
97                 
98         $x = array('options' => $options, 'size' => $size, 'single' => $single, 'mutual' => $mutual, 'exclude' => $exclude, 'networks' => $networks);
99
100         call_hooks('contact_select_options', $x);
101
102         $o = '';
103
104         $sql_extra = '';
105
106         if($x['mutual']) {
107                 $sql_extra .= sprintf(" AND `rel` = %d ", intval(CONTACT_IS_FRIEND));
108         }
109
110         if(intval($x['exclude']))
111                 $sql_extra .= sprintf(" AND `id` != %d ", intval($x['exclude']));
112
113         if(is_array($x['networks']) && count($x['networks'])) {
114                 for($y = 0; $y < count($x['networks']) ; $y ++)
115                         $x['networks'][$y] = "'" . dbesc($x['networks'][$y]) . "'";
116                 $str_nets = implode(',',$x['networks']);
117                 $sql_extra .= " AND `network` IN ( $str_nets ) ";
118         }
119         
120         $tabindex = (x($options, 'tabindex') ? "tabindex=\"" . $options["tabindex"] . "\"" : "");
121
122         if($x['single'])
123                 $o .= "<select name=\"$selname\" id=\"$selclass\" class=\"$selclass\" size=\"" . $x['size'] . "\" $tabindex >\r\n";
124         else 
125                 $o .= "<select name=\"{$selname}[]\" id=\"$selclass\" class=\"$selclass\" multiple=\"multiple\" size=\"" . $x['size'] . "$\" $tabindex >\r\n";
126
127         $r = q("SELECT `id`, `name`, `url`, `network` FROM `contact` 
128                 WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 AND `pending` = 0 AND `archive` = 0 AND `notify` != ''
129                 $sql_extra
130                 ORDER BY `name` ASC ",
131                 intval(local_user())
132         );
133
134
135         $arr = array('contact' => $r, 'entry' => $o);
136
137         // e.g. 'network_pre_contact_deny', 'profile_pre_contact_allow'
138
139         call_hooks($a->module . '_pre_' . $selname, $arr);
140
141         if(count($r)) {
142                 foreach($r as $rr) {
143                         if((is_array($preselected)) && in_array($rr['id'], $preselected))
144                                 $selected = " selected=\"selected\" ";
145                         else
146                                 $selected = '';
147
148                         $trimmed = mb_substr($rr['name'],0,20);
149
150                         $o .= "<option value=\"{$rr['id']}\" $selected title=\"{$rr['name']}|{$rr['url']}\" >$trimmed</option>\r\n";
151                 }
152         
153         }
154
155         $o .= "</select>\r\n";
156
157         call_hooks($a->module . '_post_' . $selname, $o);
158
159         return $o;
160 }
161
162
163
164 function contact_select($selname, $selclass, $preselected = false, $size = 4, $privmail = false, $celeb = false, $privatenet = false, $tabindex = null) {
165
166         $a = get_app();
167
168         $o = '';
169
170         // When used for private messages, we limit correspondence to mutual DFRN/Friendica friends and the selector
171         // to one recipient. By default our selector allows multiple selects amongst all contacts.
172
173         $sql_extra = '';
174
175         if($privmail || $celeb) {
176                 $sql_extra .= sprintf(" AND `rel` = %d ", intval(CONTACT_IS_FRIEND));
177         }
178
179         if($privmail) {
180                 $sql_extra .= " AND `network` IN ( 'dfrn', 'dspr' ) ";
181         }
182         elseif($privatenet) {   
183                 $sql_extra .= " AND `network` IN ( 'dfrn', 'mail', 'face', 'dspr' ) ";
184         }
185
186         $tabindex = ($tabindex > 0 ? "tabindex=\"$tabindex\"" : "");
187
188         if($privmail)
189                 $o .= "<select name=\"$selname\" id=\"$selclass\" class=\"$selclass\" size=\"$size\" $tabindex >\r\n";
190         else 
191                 $o .= "<select name=\"{$selname}[]\" id=\"$selclass\" class=\"$selclass\" multiple=\"multiple\" size=\"$size\" $tabindex >\r\n";
192
193         $r = q("SELECT `id`, `name`, `url`, `network` FROM `contact` 
194                 WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 AND `pending` = 0 AND `archive` = 0 AND `notify` != ''
195                 $sql_extra
196                 ORDER BY `name` ASC ",
197                 intval(local_user())
198         );
199
200
201         $arr = array('contact' => $r, 'entry' => $o);
202
203         // e.g. 'network_pre_contact_deny', 'profile_pre_contact_allow'
204
205         call_hooks($a->module . '_pre_' . $selname, $arr);
206
207         if(count($r)) {
208                 foreach($r as $rr) {
209                         if((is_array($preselected)) && in_array($rr['id'], $preselected))
210                                 $selected = " selected=\"selected\" ";
211                         else
212                                 $selected = '';
213
214                         $trimmed = mb_substr($rr['name'],0,20);
215
216                         $o .= "<option value=\"{$rr['id']}\" $selected title=\"{$rr['name']}|{$rr['url']}\" >$trimmed</option>\r\n";
217                 }
218         
219         }
220
221         $o .= "</select>\r\n";
222
223         call_hooks($a->module . '_post_' . $selname, $o);
224
225         return $o;
226 }
227
228
229 function fixacl(&$item) {
230         $item = intval(str_replace(array('<','>'),array('',''),$item));
231 }
232
233 function prune_deadguys($arr) {
234
235         if(! $arr)
236                 return $arr;
237         $str = dbesc(implode(',',$arr));
238         $r = q("select id from contact where id in ( " . $str . ") and blocked = 0 and pending = 0 and archive = 0 ");
239         if($r) {
240                 $ret = array();
241                 foreach($r as $rr) 
242                         $ret[] = intval($rr['id']);
243                 return $ret;
244         }
245         return array();
246 }
247
248
249 function get_acl_permissions($user = null) {
250         $allow_cid = $allow_gid = $deny_cid = $deny_gid = false;
251
252         if(is_array($user)) {
253                 $allow_cid = ((strlen($user['allow_cid'])) 
254                         ? explode('><', $user['allow_cid']) : array() );
255                 $allow_gid = ((strlen($user['allow_gid']))
256                         ? explode('><', $user['allow_gid']) : array() );
257                 $deny_cid  = ((strlen($user['deny_cid']))
258                         ? explode('><', $user['deny_cid']) : array() );
259                 $deny_gid  = ((strlen($user['deny_gid']))
260                         ? explode('><', $user['deny_gid']) : array() );
261                 array_walk($allow_cid,'fixacl');
262                 array_walk($allow_gid,'fixacl');
263                 array_walk($deny_cid,'fixacl');
264                 array_walk($deny_gid,'fixacl');
265         }
266
267         $allow_cid = prune_deadguys($allow_cid);
268
269         return array(
270                 'allow_cid' => $allow_cid,
271                 'allow_gid' => $allow_gid,
272                 'deny_cid' => $deny_cid,
273                 'deny_gid' => $deny_gid,
274         );
275 }
276
277
278 function populate_acl($user = null,$celeb = false) {
279
280         $perms = get_acl_permissions($user);
281
282         // We shouldn't need to prune deadguys from the block list. Either way they can't get the message.
283         // Also no point enumerating groups and checking them, that will take place on delivery.
284
285 //      $deny_cid = prune_deadguys($deny_cid);
286
287
288         /*$o = '';
289         $o .= '<div id="acl-wrapper">';
290         $o .= '<div id="acl-permit-outer-wrapper">';
291         $o .= '<div id="acl-permit-text">' . t('Visible To:') . '</div><div id="jot-public">' . t('everybody') . '</div>';
292         $o .= '<div id="acl-permit-text-end"></div>';
293         $o .= '<div id="acl-permit-wrapper">';
294         $o .= '<div id="group_allow_wrapper">';
295         $o .= '<label id="acl-allow-group-label" for="group_allow" >' . t('Groups') . '</label>';
296         $o .= group_select('group_allow','group_allow',$allow_gid);
297         $o .= '</div>';
298         $o .= '<div id="contact_allow_wrapper">';
299         $o .= '<label id="acl-allow-contact-label" for="contact_allow" >' . t('Contacts') . '</label>';
300         $o .= contact_select('contact_allow','contact_allow',$allow_cid,4,false,$celeb,true);
301         $o .= '</div>';
302         $o .= '</div>' . "\r\n";
303         $o .= '<div id="acl-allow-end"></div>' . "\r\n";
304         $o .= '</div>';
305         $o .= '<div id="acl-deny-outer-wrapper">';
306         $o .= '<div id="acl-deny-text">' . t('Except For:') . '</div>';
307         $o .= '<div id="acl-deny-text-end"></div>';
308         $o .= '<div id="acl-deny-wrapper">';
309         $o .= '<div id="group_deny_wrapper" >';
310         $o .= '<label id="acl-deny-group-label" for="group_deny" >' . t('Groups') . '</label>';
311         $o .= group_select('group_deny','group_deny', $deny_gid);
312         $o .= '</div>';
313         $o .= '<div id="contact_deny_wrapper" >';
314         $o .= '<label id="acl-deny-contact-label" for="contact_deny" >' . t('Contacts') . '</label>';
315         $o .= contact_select('contact_deny','contact_deny', $deny_cid,4,false, $celeb,true);
316         $o .= '</div>';
317         $o .= '</div>' . "\r\n";
318         $o .= '<div id="acl-deny-end"></div>' . "\r\n";
319         $o .= '</div>';
320         $o .= '</div>' . "\r\n";
321         $o .= '<div id="acl-wrapper-end"></div>' . "\r\n";*/
322         
323         $tpl = get_markup_template("acl_selector.tpl");
324         $o = replace_macros($tpl, array(
325                 '$showall'=> t("Visible to everybody"),
326                 '$show'          => t("show"),
327                 '$hide'          => t("don't show"),
328                 '$allowcid' => json_encode($perms['allow_cid']),
329                 '$allowgid' => json_encode($perms['allow_gid']),
330                 '$denycid' => json_encode($perms['deny_cid']),
331                 '$denygid' => json_encode($perms['deny_gid']),
332         ));
333         
334         
335         return $o;
336
337 }
338
339 function construct_acl_data(&$a, $user) {
340
341         // Get group and contact information for html ACL selector
342         $acl_data = acl_lookup($a, 'html');
343
344         $user_defaults = get_acl_permissions($user);
345
346         if($acl_data['groups']) {
347                 foreach($acl_data['groups'] as $key=>$group) {
348                         // Add a "selected" flag to groups that are posted to by default
349                         if($user_defaults['allow_gid'] &&
350                            in_array($group['id'], $user_defaults['allow_gid']) && !in_array($group['id'], $user_defaults['deny_gid']) )
351                                 $acl_data['groups'][$key]['selected'] = 1;
352                         else
353                                 $acl_data['groups'][$key]['selected'] = 0;
354                 }
355         }
356         if($acl_data['contacts']) {
357                 foreach($acl_data['contacts'] as $key=>$contact) {
358                         // Add a "selected" flag to groups that are posted to by default
359                         if($user_defaults['allow_cid'] &&
360                            in_array($contact['id'], $user_defaults['allow_cid']) && !in_array($contact['id'], $user_defaults['deny_cid']) )
361                                 $acl_data['contacts'][$key]['selected'] = 1;
362                         else
363                                 $acl_data['contacts'][$key]['selected'] = 0;
364                 }
365         }
366
367         return $acl_data;
368
369 }
370
371 function acl_lookup(&$a, $out_type = 'json') {
372
373         if(!local_user())
374                 return "";
375
376
377         $start = (x($_REQUEST,'start')?$_REQUEST['start']:0);
378         $count = (x($_REQUEST,'count')?$_REQUEST['count']:100);
379         $search = (x($_REQUEST,'search')?$_REQUEST['search']:"");
380         $type = (x($_REQUEST,'type')?$_REQUEST['type']:"");
381         
382
383         // For use with jquery.autocomplete for private mail completion
384
385         if(x($_REQUEST,'query') && strlen($_REQUEST['query'])) {
386                 if(! $type)
387                         $type = 'm';
388                 $search = $_REQUEST['query'];
389         }
390
391
392         if ($search!=""){
393                 $sql_extra = "AND `name` LIKE '%%".dbesc($search)."%%'";
394                 $sql_extra2 = "AND (`attag` LIKE '%%".dbesc($search)."%%' OR `name` LIKE '%%".dbesc($search)."%%' OR `nick` LIKE '%%".dbesc($search)."%%')";
395         } else {
396                 $sql_extra = $sql_extra2 = "";
397         }
398         
399         // count groups and contacts
400         if ($type=='' || $type=='g'){
401                 $r = q("SELECT COUNT(`id`) AS g FROM `group` WHERE `deleted` = 0 AND `uid` = %d $sql_extra",
402                         intval(local_user())
403                 );
404                 $group_count = (int)$r[0]['g'];
405         } else {
406                 $group_count = 0;
407         }
408         
409         if ($type=='' || $type=='c'){
410                 $r = q("SELECT COUNT(`id`) AS c FROM `contact` 
411                                 WHERE `uid` = %d AND `self` = 0 
412                                 AND `blocked` = 0 AND `pending` = 0 AND `archive` = 0
413                                 AND `notify` != '' $sql_extra2" ,
414                         intval(local_user())
415                 );
416                 $contact_count = (int)$r[0]['c'];
417         } 
418         elseif ($type == 'm') {
419
420                 // autocomplete for Private Messages
421
422                 $r = q("SELECT COUNT(`id`) AS c FROM `contact` 
423                                 WHERE `uid` = %d AND `self` = 0 
424                                 AND `blocked` = 0 AND `pending` = 0 AND `archive` = 0 
425                                 AND `network` IN ('%s','%s','%s') $sql_extra2" ,
426                         intval(local_user()),
427                         dbesc(NETWORK_DFRN),
428                         dbesc(NETWORK_ZOT),
429                         dbesc(NETWORK_DIASPORA)
430                 );
431                 $contact_count = (int)$r[0]['c'];
432
433         }
434         elseif ($type == 'a') {
435
436                 // autocomplete for Contacts
437
438                 $r = q("SELECT COUNT(`id`) AS c FROM `contact` 
439                                 WHERE `uid` = %d AND `self` = 0 
440                                 AND `pending` = 0 $sql_extra2" ,
441                         intval(local_user())
442                 );
443                 $contact_count = (int)$r[0]['c'];
444
445         } else {
446                 $contact_count = 0;
447         }
448         
449         $tot = $group_count+$contact_count;
450         
451         $groups = array();
452         $contacts = array();
453         
454         if ($type=='' || $type=='g'){
455                 
456                 $r = q("SELECT `group`.`id`, `group`.`name`, GROUP_CONCAT(DISTINCT `group_member`.`contact-id` SEPARATOR ',') as uids
457                                 FROM `group`,`group_member` 
458                                 WHERE `group`.`deleted` = 0 AND `group`.`uid` = %d 
459                                         AND `group_member`.`gid`=`group`.`id`
460                                         $sql_extra
461                                 GROUP BY `group`.`id`
462                                 ORDER BY `group`.`name` 
463                                 LIMIT %d,%d",
464                         intval(local_user()),
465                         intval($start),
466                         intval($count)
467                 );
468
469                 foreach($r as $g){
470 //              logger('acl: group: ' . $g['name'] . ' members: ' . $g['uids']);                
471                         $groups[] = array(
472                                 "type"  => "g",
473                                 "photo" => "images/twopeople.png",
474                                 "name"  => $g['name'],
475                                 "id"    => intval($g['id']),
476                                 "uids"  => array_map("intval", explode(",",$g['uids'])),
477                                 "link"  => ''
478                         );
479                 }
480         }
481         
482         if ($type=='' || $type=='c'){
483         
484                 $r = q("SELECT `id`, `name`, `nick`, `micro`, `network`, `url`, `attag` FROM `contact` 
485                         WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 AND `pending` = 0 AND `archive` = 0 AND `notify` != ''
486                         $sql_extra2
487                         ORDER BY `name` ASC ",
488                         intval(local_user())
489                 );
490         }
491         elseif($type == 'm') {
492                 $r = q("SELECT `id`, `name`, `nick`, `micro`, `network`, `url`, `attag` FROM `contact` 
493                         WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 AND `pending` = 0 AND `archive` = 0
494                         AND `network` IN ('%s','%s','%s')
495                         $sql_extra2
496                         ORDER BY `name` ASC ",
497                         intval(local_user()),
498                         dbesc(NETWORK_DFRN),
499                         dbesc(NETWORK_ZOT),
500                         dbesc(NETWORK_DIASPORA)
501                 );
502         }
503         elseif($type == 'a') {
504                 $r = q("SELECT `id`, `name`, `nick`, `micro`, `network`, `url`, `attag` FROM `contact` 
505                         WHERE `uid` = %d AND `pending` = 0
506                         $sql_extra2
507                         ORDER BY `name` ASC ",
508                         intval(local_user())
509                 );
510         }
511         else
512                 $r = array();
513
514
515         if($type == 'm' || $type == 'a') {
516                 $x = array();
517                 $x['query'] = $search;
518                 $x['photos'] = array();
519                 $x['links'] = array();
520                 $x['suggestions'] = array();
521                 $x['data'] = array();
522                 if(count($r)) {
523                         foreach($r as $g) {
524                                 $x['photos'][] = $g['micro'];
525                                 $x['links'][] = $g['url'];
526                                 $x['suggestions'][] = $g['name'];
527                                 $x['data'][] = intval($g['id']);
528                         }
529                 }
530                 echo json_encode($x);
531                 killme();
532         }
533
534         if(count($r)) {
535                 foreach($r as $g){
536                         $contacts[] = array(
537                                 "type"  => "c",
538                                 "photo" => $g['micro'],
539                                 "name"  => $g['name'],
540                                 "id"    => intval($g['id']),
541                                 "network" => $g['network'],
542                                 "link" => $g['url'],
543                                 "nick" => ($g['attag']) ? $g['attag'] : $g['nick'],
544                         );
545                 }                       
546         }
547                 
548         $items = array_merge($groups, $contacts);
549
550
551         if($out_type === 'html') {
552                 $o = array(
553                         'tot'           => $tot,
554                         'start' => $start,
555                         'count' => $count,
556                         'groups'        => $groups,
557                         'contacts'      => $contacts,
558                 );
559                 return $o;
560         }
561         
562         $o = array(
563                 'tot'   => $tot,
564                 'start' => $start,
565                 'count' => $count,
566                 'items' => $items,
567         );
568         
569         echo json_encode($o);
570
571         killme();
572 }
573