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