Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
85.71% covered (warning)
85.71%
66 / 77
88.89% covered (warning)
88.89%
8 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
legend
85.71% covered (warning)
85.71%
66 / 77
88.89% covered (warning)
88.89%
8 / 9
29.13
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 get_group_value
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
2
 get_group_count
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
 add_group
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
2
 delete_group
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
3
 move_up
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 move_down
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 move
100.00% covered (success)
100.00%
23 / 23
100.00% covered (success)
100.00%
1 / 1
9
 group_type_language
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
56
1<?php
2/**
3*
4* This file is part of the phpBB Forum Software package.
5*
6* @copyright (c) phpBB Limited <https://www.phpbb.com>
7* @license GNU General Public License, version 2 (GPL-2.0)
8*
9* For full copyright and license information, please see
10* the docs/CREDITS.txt file.
11*
12*/
13
14namespace phpbb\groupposition;
15
16/**
17* Legend group position class
18*
19* group_legend is an ascending list 1, 2, ..., n for groups which are displayed. 1 is the first group, n the last.
20* If the value is 0 (self::GROUP_DISABLED) the group is not displayed.
21*/
22class legend implements \phpbb\groupposition\groupposition_interface
23{
24    /**
25    * Group is not displayed
26    */
27    const GROUP_DISABLED = 0;
28
29    /**
30    * Database object
31    * @var \phpbb\db\driver\driver_interface
32    */
33    protected $db;
34
35
36    /**
37    * Constructor
38    *
39    * @param \phpbb\db\driver\driver_interface    $db        Database object
40    */
41    public function __construct(\phpbb\db\driver\driver_interface $db)
42    {
43        $this->db = $db;
44    }
45
46    /**
47    * Returns the group_legend for a given group, if the group exists.
48    *
49    * @param    int        $group_id    group_id of the group to be selected
50    *
51    * @return    int            position of the group
52    * @throws exception
53    */
54    public function get_group_value($group_id)
55    {
56        $sql = 'SELECT group_legend
57            FROM ' . GROUPS_TABLE . '
58            WHERE group_id = ' . (int) $group_id;
59        $result = $this->db->sql_query($sql);
60        $current_value = $this->db->sql_fetchfield('group_legend');
61        $this->db->sql_freeresult($result);
62
63        if ($current_value === false)
64        {
65            // Group not found.
66            throw new exception('NO_GROUP');
67        }
68
69        return (int) $current_value;
70    }
71
72    /**
73    * Get number of groups, displayed on the legend
74    *
75    * @return    int        value of the last item displayed
76    */
77    public function get_group_count()
78    {
79        $sql = 'SELECT group_legend
80            FROM ' . GROUPS_TABLE . '
81            ORDER BY group_legend DESC';
82        $result = $this->db->sql_query_limit($sql, 1);
83        $group_count = (int) $this->db->sql_fetchfield('group_legend');
84        $this->db->sql_freeresult($result);
85
86        return $group_count;
87    }
88
89    /**
90    * {@inheritDoc}
91    */
92    public function add_group($group_id)
93    {
94        $current_value = $this->get_group_value($group_id);
95
96        if ($current_value == self::GROUP_DISABLED)
97        {
98            // Group is currently not displayed, add it at the end.
99            $next_value = 1 + $this->get_group_count();
100
101            $sql = 'UPDATE ' . GROUPS_TABLE . '
102                SET group_legend = ' . $next_value . '
103                WHERE group_legend = ' . self::GROUP_DISABLED . '
104                    AND group_id = ' . (int) $group_id;
105            $this->db->sql_query($sql);
106            return true;
107        }
108
109        return false;
110    }
111
112    /**
113     * Deletes a group by setting the field to self::GROUP_DISABLED and closing the gap in the list.
114     *
115     * @param int $group_id group_id of the group to be deleted
116     * @param bool $skip_group Skip setting the value for this group, to save the query, when you need to update it anyway.
117     * @return    bool        True if the group was deleted successfully
118     * @throws exception
119     */
120    public function delete_group($group_id, $skip_group = false)
121    {
122        $current_value = $this->get_group_value($group_id);
123
124        if ($current_value != self::GROUP_DISABLED)
125        {
126            $this->db->sql_transaction('begin');
127
128            $sql = 'UPDATE ' . GROUPS_TABLE . '
129                SET group_legend = group_legend - 1
130                WHERE group_legend > ' . $current_value;
131            $this->db->sql_query($sql);
132
133            if (!$skip_group)
134            {
135                $sql = 'UPDATE ' . GROUPS_TABLE . '
136                    SET group_legend = ' . self::GROUP_DISABLED . '
137                    WHERE group_id = ' . (int) $group_id;
138                $this->db->sql_query($sql);
139            }
140
141            $this->db->sql_transaction('commit');
142
143            return true;
144        }
145
146        return false;
147    }
148
149    /**
150    * {@inheritDoc}
151    */
152    public function move_up($group_id)
153    {
154        return $this->move($group_id, 1);
155    }
156
157    /**
158    * {@inheritDoc}
159    */
160    public function move_down($group_id)
161    {
162        return $this->move($group_id, -1);
163    }
164
165    /**
166    * {@inheritDoc}
167    */
168    public function move($group_id, $delta)
169    {
170        $delta = (int) $delta;
171        if (!$delta)
172        {
173            return false;
174        }
175
176        $move_up = ($delta > 0) ? true : false;
177        $current_value = $this->get_group_value($group_id);
178
179        if ($current_value != self::GROUP_DISABLED)
180        {
181            $this->db->sql_transaction('begin');
182
183            // First we move all groups between our current value and the target value up/down 1,
184            // so we have a gap for our group to move.
185            $sql = 'UPDATE ' . GROUPS_TABLE . '
186                SET group_legend = group_legend' . (($move_up) ? ' + 1' : ' - 1') . '
187                WHERE group_legend > ' . self::GROUP_DISABLED . '
188                    AND group_legend' . (($move_up) ? ' >= ' : ' <= ') . ($current_value - $delta) . '
189                    AND group_legend' . (($move_up) ? ' < ' : ' > ') . $current_value;
190            $this->db->sql_query($sql);
191
192            // Because there might be fewer groups above/below the group than we wanted to move,
193            // we use the number of changed groups, to update the group.
194            $delta = (int) $this->db->sql_affectedrows();
195
196            if ($delta)
197            {
198                // And now finally, when we moved some other groups and built a gap,
199                // we can move the desired group to it.
200                $sql = 'UPDATE ' . GROUPS_TABLE . '
201                    SET group_legend = group_legend ' . (($move_up) ? ' - ' : ' + ') . $delta . '
202                    WHERE group_id = ' . (int) $group_id;
203                $this->db->sql_query($sql);
204
205                $this->db->sql_transaction('commit');
206
207                return true;
208            }
209
210            $this->db->sql_transaction('commit');
211        }
212
213        return false;
214    }
215
216    /**
217     * Get group type language var
218     *
219     * @param int $group_type group_type from the groups-table
220     *
221     * @return    string        name of the language variable for the given group-type.
222     * @throws exception        If invalid group type is supplied
223     */
224    public static function group_type_language($group_type)
225    {
226        switch ($group_type)
227        {
228            case GROUP_OPEN:
229                return 'GROUP_REQUEST';
230            case GROUP_CLOSED:
231                return 'GROUP_CLOSED';
232            case GROUP_HIDDEN:
233                return 'GROUP_HIDDEN';
234            case GROUP_SPECIAL:
235                return 'GROUP_SPECIAL';
236            case GROUP_FREE:
237                return 'GROUP_OPEN';
238            default:
239                throw new exception('NO_GROUP');
240        }
241    }
242}