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