]> git.mxchange.org Git - friendica.git/blob - src/Model/Group.php
7d2e8f4898f07f1aea58752f7793af5e660586e5
[friendica.git] / src / Model / Group.php
1 <?php
2
3 /**
4  * @file src/Model/Group.php
5  */
6
7 namespace Friendica\Model;
8
9 use Friendica\BaseObject;
10 use Friendica\Database\DBM;
11 use dba;
12
13 require_once 'boot.php';
14 require_once 'include/text.php';
15
16 /**
17  * @brief functions for interacting with the group database table
18  */
19 class Group extends BaseObject
20 {
21         /**
22          * @brief Create a new contact group
23          *
24          * Note: If we found a deleted group with the same name, we restore it
25          *
26          * @param int $uid
27          * @param string $name
28          * @return boolean
29          */
30         public static function create($uid, $name)
31         {
32                 $return = false;
33                 if (x($uid) && x($name)) {
34                         $gid = self::getIdByName($uid, $name); // check for dupes
35                         if ($gid !== false) {
36                                 // This could be a problem.
37                                 // Let's assume we've just created a group which we once deleted
38                                 // all the old members are gone, but the group remains so we don't break any security
39                                 // access lists. What we're doing here is reviving the dead group, but old content which
40                                 // was restricted to this group may now be seen by the new group members.
41                                 $group = dba::select('group', ['deleted'], ['id' => $gid], ['limit' => 1]);
42                                 if (DBM::is_result($group) && $group['deleted']) {
43                                         dba::update('group', ['deleted' => 0], ['gid' => $gid]);
44                                         notice(t('A deleted group with this name was revived. Existing item permissions <strong>may</strong> apply to this group and any future members. If this is not what you intended, please create another group with a different name.') . EOL);
45                                 }
46                                 return true;
47                         }
48
49                         $return = dba::insert('group', ['uid' => $uid, 'name' => $name]);
50                 }
51                 return $return;
52         }
53
54         /**
55          * @brief Get a list of group ids a contact belongs to
56          *
57          * @todo Get rid of $uid, the contact id already bears the information
58          *
59          * @param int $uid
60          * @param int $cid
61          * @return array
62          */
63         private static function getByContactIdForUserId($uid, $cid)
64         {
65                 $stmt = dba::p('SELECT `id`
66                         FROM `group`
67                         INNER JOIN `group_member`
68                                 ON `group_member`.`gid` = `group`.`id`
69                         WHERE `group`.`uid` = ?
70                         AND `group_member`.`contact-id` = ?',
71                         $uid,
72                         $cid
73                 );
74
75                 $return = [];
76                 if (DBM::is_result($stmt)) {
77                         while($group = dba::fetch($stmt)) {
78                                 $return[] = $group['id'];
79                         }
80                 }
81
82                 return $return;
83         }
84
85         /**
86          * @brief count unread group items
87          *
88          * Count unread items of each groups of the local user
89          *
90          * @return array
91          *      'id' => group id
92          *      'name' => group name
93          *      'count' => counted unseen group items
94          */
95         public static function countUnseen()
96         {
97                 $stmt = dba::p("SELECT `group`.`id`, `group`.`name`,
98                                 (SELECT COUNT(*) FROM `item` FORCE INDEX (`uid_unseen_contactid`)
99                                         WHERE `uid` = ?
100                                         AND `unseen`
101                                         AND `contact-id` IN
102                                                 (SELECT `contact-id`
103                                                 FROM `group_member`
104                                                 WHERE `group_member`.`gid` = `group`.`id`
105                                                 AND `group_member`.`uid` = ?)
106                                         ) AS `count`
107                                 FROM `group`
108                                 WHERE `group`.`uid` = ?;",
109                         local_user(),
110                         local_user(),
111                         local_user()
112                 );
113
114                 return dba::inArray($stmt);
115         }
116
117         /**
118          * @brief Get the group id for a user/name couple
119          *
120          * Returns false if no group has been found.
121          *
122          * @param int $uid
123          * @param string $name
124          * @return int|boolean
125          */
126         public static function getIdByName($uid, $name)
127         {
128                 if (!$uid || !strlen($name)) {
129                         return false;
130                 }
131
132                 $group = dba::select('group', ['id'], ['uid' => $uid, 'name' => $name], ['limit' => 1]);
133                 if (DBM::is_result($group)) {
134                         return $group['id'];
135                 }
136
137                 return false;
138         }
139
140         /**
141          * @brief Mark a group as deleted
142          *
143          * @param type $gid
144          * @return boolean
145          */
146         public static function remove($gid) {
147                 if (! $gid) {
148                         return false;
149                 }
150
151                 // remove group from default posting lists
152                 $user = dba::select('user', ['def_gid', 'allow_gid', 'deny_gid'], ['uid' => $uid], ['limit' => 1]);
153                 if (DBM::is_result($user)) {
154                         $change = false;
155
156                         if ($user['def_gid'] == $gid) {
157                                 $user['def_gid'] = 0;
158                                 $change = true;
159                         }
160                         if (strpos($user['allow_gid'], '<' . $gid . '>') !== false) {
161                                 $user['allow_gid'] = str_replace('<' . $gid . '>', '', $user['allow_gid']);
162                                 $change = true;
163                         }
164                         if (strpos($user['deny_gid'], '<' . $gid . '>') !== false) {
165                                 $user['deny_gid'] = str_replace('<' . $gid . '>', '', $user['deny_gid']);
166                                 $change = true;
167                         }
168
169                         if ($change) {
170                                 dba::update('user', $user, ['uid' => $uid]);
171                         }
172                 }
173
174                 // remove all members
175                 dba::delete('group_member', ['gid' => $gid]);
176
177                 // remove group
178                 $return = dba::update('group', ['deleted' => 1], ['id' => $gid]);
179
180                 return $return;
181         }
182
183         /**
184          * @brief Mark a group as deleted based on its name
185          *
186          * @deprecated Use Group::remove instead
187          *
188          * @param type $uid
189          * @param type $name
190          * @return type
191          */
192         public static function removeByName($uid, $name) {
193                 $return = false;
194                 if (x($uid) && x($name)) {
195                         $gid = self::getIdByName($uid, $name);
196
197                         $return = self::remove($gid);
198                 }
199
200                 return $return;
201         }
202
203         /**
204          * @brief Adds a contact to a group
205          *
206          * @param int $gid
207          * @param int $cid
208          * @return boolean
209          */
210         public static function addMember($gid, $cid)
211         {
212                 if (!$gid || !$cid) {
213                         return false;
214                 }
215
216                 $row_exists = dba::exists('group_member', ['gid' => $gid, 'contact-id' => $cid]);
217                 if ($row_exists) {
218                         // Row already existing, nothing to do
219                         $return = true;
220                 } else {
221                         $return = dba::insert('group_member', ['gid' => $gid, 'contact-id' => $cid]);
222                 }
223
224                 return $return;
225         }
226
227         /**
228          * @brief Removes a contact from a group
229          *
230          * @param int $gid
231          * @param int $cid
232          * @return boolean
233          */
234         public static function removeMember($gid, $cid)
235         {
236                 if (!$gid || !$cid) {
237                         return false;
238                 }
239
240                 $return = dba::delete('group_member', ['gid' => $gid, 'contact-id' => $cid]);
241
242                 return $return;
243         }
244
245         /**
246          * @brief Removes a contact from a group based on its name
247          *
248          * @deprecated Use Group::removeMember instead
249          *
250          * @param int $uid
251          * @param string $name
252          * @param int $cid
253          * @return boolean
254          */
255         public static function removeMemberByName($uid, $name, $cid)
256         {
257                 $gid = self::getIdByName($uid, $name);
258
259                 $return = self::removeMember($gid, $cid);
260
261                 return $return;
262         }
263
264         /**
265          * @brief Returns the combined list of contact ids from a group id list
266          *
267          * @param array $group_ids
268          * @param boolean $check_dead
269          * @param boolean $use_gcontact
270          * @return array
271          */
272         public static function expand($group_ids, $check_dead = false, $use_gcontact = false)
273         {
274                 if (!is_array($group_ids) || !count($group_ids)) {
275                         return [];
276                 }
277
278                 $condition = '`gid` IN (' . substr(str_repeat("?, ", count($group_ids)), 0, -2) . ')';
279                 if ($use_gcontact) {
280                         $sql = 'SELECT `gcontact`.`id` AS `contact-id` FROM `group_member`
281                                         INNER JOIN `contact` ON `contact`.`id` = `group_member`.`contact-id`
282                                         INNER JOIN `gcontact` ON `gcontact`.`nurl` = `contact`.`nurl`
283                                 WHERE ' . $condition;
284                         $param_arr = array_merge([$sql], $group_ids);
285                         $stmt = call_user_func_array('dba::p', $param_arr);
286                 } else {
287                         $condition_array = array_merge([$condition], $group_ids);
288                         $stmt = dba::select('group_member', ['contact-id'], $condition_array);
289                 }
290
291                 $return = [];
292                 while($group_member = dba::fetch($stmt)) {
293                         $return[] = $group_member['contact-id'];
294                 }
295
296                 if ($check_dead && !$use_gcontact) {
297                         require_once 'include/acl_selectors.php';
298                         $return = prune_deadguys($return);
299                 }
300                 return $return;
301         }
302
303         /**
304          * @brief Returns a templated group selection list
305          *
306          * @param int $uid
307          * @param int $gid An optional pre-selected group
308          * @param string $label An optional label of the list
309          * @return string
310          */
311         public static function displayGroupSelection($uid, $gid = 0, $label = '')
312         {
313                 $o = '';
314
315                 $stmt = dba::select('group', [], ['deleted' => 0, 'uid' => $uid], ['order' => ['name' => 'ASC']]);
316
317                 $display_groups = [
318                         [
319                                 'name' => '',
320                                 'id' => '0',
321                                 'selected' => ''
322                         ]
323                 ];
324                 while ($group = dba::fetch($stmt)) {
325                         $display_groups[] = [
326                                 'name' => $group['name'],
327                                 'id' => $group['id'],
328                                 'selected' => $gid == $group['id'] ? 'true' : ''
329                         ];
330                 }
331                 logger('groups: ' . print_r($display_groups, true));
332
333                 if ($label == '') {
334                         $label = t('Default privacy group for new contacts');
335                 }
336
337                 $o = replace_macros(get_markup_template('group_selection.tpl'), array(
338                         '$label' => $label,
339                         '$groups' => $display_groups
340                 ));
341                 return $o;
342         }
343
344         /**
345          * @brief Create group sidebar widget
346          *
347          * @param string $every
348          * @param string $each
349          * @param string $editmode
350          *      'standard' => include link 'Edit groups'
351          *      'extended' => include link 'Create new group'
352          *      'full' => include link 'Create new group' and provide for each group a link to edit this group
353          * @param int $group_id
354          * @param int $cid
355          * @return string
356          */
357         public static function sidebarWidget($every = 'contacts', $each = 'group', $editmode = 'standard', $group_id = 0, $cid = 0)
358         {
359                 $o = '';
360
361                 if (!local_user()) {
362                         return '';
363                 }
364
365                 $display_groups = [
366                         [
367                                 'text' => t('Everybody'),
368                                 'id' => 0,
369                                 'selected' => (($group_id == 0) ? 'group-selected' : ''),
370                                 'href' => $every,
371                         ]
372                 ];
373
374                 $stmt = dba::select('group', [], ['deleted' => 0, 'uid' => local_user()], ['order' => ['name' => 'ASC']]);
375
376                 $member_of = array();
377                 if ($cid) {
378                         $member_of = self::getByContactIdForUserId(local_user(), $cid);
379                 }
380
381                 while ($group = dba::fetch($stmt)) {
382                         $selected = (($group_id == $group['id']) ? ' group-selected' : '');
383
384                         if ($editmode == 'full') {
385                                 $groupedit = [
386                                         'href' => 'group/' . $group['id'],
387                                         'title' => t('edit'),
388                                 ];
389                         } else {
390                                 $groupedit = null;
391                         }
392
393                         $display_groups[] = [
394                                 'id'   => $group['id'],
395                                 'cid'  => $cid,
396                                 'text' => $group['name'],
397                                 'href' => $each . '/' . $group['id'],
398                                 'edit' => $groupedit,
399                                 'selected' => $selected,
400                                 'ismember' => in_array($group['id'], $member_of),
401                         ];
402                 }
403
404                 $tpl = get_markup_template('group_side.tpl');
405                 $o = replace_macros($tpl, [
406                         '$add' => t('add'),
407                         '$title' => t('Groups'),
408                         '$groups' => $display_groups,
409                         'newgroup' => $editmode == 'extended' || $editmode == 'full' ? 1 : '',
410                         'grouppage' => 'group/',
411                         '$edittext' => t('Edit group'),
412                         '$ungrouped' => $every === 'contacts' ? t('Contacts not in any group') : '',
413                         '$createtext' => t('Create a new group'),
414                         '$creategroup' => t('Group Name: '),
415                         '$editgroupstext' => t('Edit groups'),
416                         '$form_security_token' => get_form_security_token('group_edit'),
417                 ]);
418
419
420                 return $o;
421         }
422 }