Completed
Pull Request — develop (#209)
by Felipe
26:08 queued 36s
created

PrivilegesController   C

Complexity

Total Complexity 62

Size/Duplication

Total Lines 417
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
dl 0
loc 417
rs 5.9493
c 0
b 0
f 0
wmc 62
lcom 1
cbo 1

5 Methods

Rating   Name   Duplication   Size   Complexity  
B render() 0 26 4
D doDefault() 0 109 19
D printGrantLinks() 0 116 15
D formAlter() 0 93 17
C doAlter() 0 44 7

How to fix   Complexity   

Complex Class

Complex classes like PrivilegesController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use PrivilegesController, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * PHPPgAdmin v6.0.0-beta.48
5
 */
6
7
namespace PHPPgAdmin\Controller;
8
9
/**
10
 * PrivilegesController controller class.
11
 */
12
class PrivilegesController extends BaseController
2 ignored issues
show
Coding Style introduced by
The property $table_place is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
Coding Style introduced by
The property $controller_title is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
13
{
14
    public $table_place      = 'privileges-privileges';
15
    public $controller_title = 'strprivileges';
16
17
    /**
18
     * Default method to render the controller according to the action parameter.
19
     */
20
    public function render()
21
    {
22
        $this->printHeader();
23
        $this->printBody();
24
25
        switch ($this->action) {
26
            case 'save':
27
                if (isset($_REQUEST['cancel'])) {
28
                    $this->doDefault();
29
                } else {
30
                    $this->doAlter($_REQUEST['mode']);
31
                }
32
33
                break;
34
            case 'alter':
35
                $this->formAlter($_REQUEST['mode']);
36
37
                break;
38
            default:
39
                $this->doDefault();
40
41
                break;
42
        }
43
44
        $this->printFooter();
45
    }
46
47
    /**
48
     * Show permissions on a database, namespace, relation, language or function.
49
     *
50
     * @param mixed $msg
51
     */
52
    public function doDefault($msg = '')
53
    {
54
        $data    = $this->misc->getDatabaseAccessor();
55
        $subject = $_REQUEST['subject'];
56
57
        $this->printTrail($subject);
58
59
        // @@@FIXME: This switch is just a temporary solution,
60
        // need a better way, maybe every type of object should
61
        // have a tab bar???
62
63
        if (in_array($subject, [
64
            'server',
65
            'database',
66
            'schema',
67
            'table',
68
            'column',
69
            'view',
70
        ], true)) {
71
            $this->printTabs($subject, 'privileges');
72
        } else {
73
            $this->printTitle($this->lang['strprivileges'], 'pg.privilege');
74
        }
75
76
        $this->printMsg($msg);
77
        if (!isset($data->privlist[$subject])) {
78
            $this->container->utils->halt('No privileges defined for subject '.$subject);
79
80
            return;
81
        }
82
83
        // Determine whether object should be ref'd by name or oid.
84
        if (isset($_REQUEST[$subject.'_oid'])) {
85
            $object = $_REQUEST[$subject.'_oid'];
86
        } else {
87
            $object = $_REQUEST[$subject];
88
        }
89
90
        // Get the privileges on the object, given its type
91
        if ('column' == $subject) {
92
            $privileges = $data->getPrivileges($object, 'column', $_REQUEST['table']);
93
        } else {
94
            $privileges = $data->getPrivileges($object, $subject);
95
        }
96
97
        if (sizeof($privileges) > 0) {
98
            echo '<table>'.PHP_EOL;
99
            if ($data->hasRoles()) {
100
                echo "<tr><th class=\"data\">{$this->lang['strrole']}</th>";
101
            } else {
102
                echo "<tr><th class=\"data\">{$this->lang['strtype']}</th><th class=\"data\">{$this->lang['struser']}/{$this->lang['strgroup']}</th>";
103
            }
104
105
            foreach ($data->privlist[$subject] as $v2) {
106
                // Skip over ALL PRIVILEGES
107
                if ('ALL PRIVILEGES' == $v2) {
108
                    continue;
109
                }
110
111
                echo "<th class=\"data\">{$v2}</th>".PHP_EOL;
112
            }
113
            if ($data->hasGrantOption()) {
114
                echo "<th class=\"data\">{$this->lang['strgrantor']}</th>";
115
            }
116
            echo '</tr>'.PHP_EOL;
117
118
            // Loop over privileges, outputting them
119
            $i = 0;
120
            foreach ($privileges as $v) {
121
                $id = (0 == ($i % 2) ? '1' : '2');
122
                echo "<tr class=\"data{$id}\">".PHP_EOL;
123
                if (!$data->hasRoles()) {
124
                    echo '<td>', $this->misc->printVal($v[0]), '</td>'.PHP_EOL;
125
                }
126
127
                echo '<td>', $this->misc->printVal($v[1]), '</td>'.PHP_EOL;
128
                foreach ($data->privlist[$subject] as $v2) {
129
                    // Skip over ALL PRIVILEGES
130
                    if ('ALL PRIVILEGES' == $v2) {
131
                        continue;
132
                    }
133
134
                    echo '<td>';
135
                    if (in_array($v2, $v[2], true)) {
136
                        echo $this->lang['stryes'];
137
                    } else {
138
                        echo $this->lang['strno'];
139
                    }
140
141
                    // If we have grant option for this, end mark
142
                    if ($data->hasGrantOption() && in_array($v2, $v[4], true)) {
143
                        echo $this->lang['strasterisk'];
144
                    }
145
146
                    echo '</td>'.PHP_EOL;
147
                }
148
                if ($data->hasGrantOption()) {
149
                    echo '<td>', $this->misc->printVal($v[3]), '</td>'.PHP_EOL;
150
                }
151
                echo '</tr>'.PHP_EOL;
152
                ++$i;
153
            }
154
155
            echo '</table>';
156
        } else {
157
            echo "<p>{$this->lang['strnoprivileges']}</p>".PHP_EOL;
158
        }
159
        $this->printGrantLinks();
160
    }
161
162
    public function printGrantLinks()
163
    {
164
        $data     = $this->misc->getDatabaseAccessor();
165
        $subject  = $_REQUEST['subject'];
166
        $alllabel = '';
167
        $alltxt   = '';
168
        // Links for granting to a user or group
169
        switch ($subject) {
170
            case 'table':
171
            case 'view':
172
            case 'sequence':
173
            case 'function':
174
            case 'tablespace':
175
                $alllabel = "showall{$subject}s";
176
                $allurl   = "{$subject}s";
177
                $alltxt   = $this->lang["strshowall{$subject}s"];
178
179
                break;
180
            case 'schema':
181
                $alllabel = 'showallschemas';
182
                $allurl   = 'schemas';
183
                $alltxt   = $this->lang['strshowallschemas'];
184
185
                break;
186
            case 'database':
187
                $alllabel = 'showalldatabases';
188
                $allurl   = 'alldb';
189
                $alltxt   = $this->lang['strshowalldatabases'];
190
191
                break;
192
        }
193
194
        $object = $_REQUEST[$subject];
195
196
        if ('function' == $subject) {
197
            $objectoid = $_REQUEST[$subject.'_oid'];
198
            $urlvars   = [
199
                'action'         => 'alter',
200
                'server'         => $_REQUEST['server'],
201
                'database'       => $_REQUEST['database'],
202
                'schema'         => $_REQUEST['schema'],
203
                $subject         => $object,
204
                "{$subject}_oid" => $objectoid,
205
                'subject'        => $subject,
206
            ];
207
        } elseif ('column' == $subject) {
208
            $urlvars = [
209
                'action'   => 'alter',
210
                'server'   => $_REQUEST['server'],
211
                'database' => $_REQUEST['database'],
212
                'schema'   => $_REQUEST['schema'],
213
                $subject   => $object,
214
                'subject'  => $subject,
215
            ];
216
217
            if (isset($_REQUEST['table'])) {
218
                $urlvars['table'] = $_REQUEST['table'];
219
            } elseif (isset($_REQUEST['view'])) {
220
                $urlvars['view'] = $_REQUEST['view'];
221
            } else {
222
                $urlvars['matview'] = $_REQUEST['matview'];
223
            }
224
        } else {
225
            $urlvars = [
226
                'action'   => 'alter',
227
                'server'   => $_REQUEST['server'],
228
                'database' => $_REQUEST['database'],
229
                $subject   => $object,
230
                'subject'  => $subject,
231
            ];
232
            if (isset($_REQUEST['schema'])) {
233
                $urlvars['schema'] = $_REQUEST['schema'];
234
            }
235
        }
236
237
        $navlinks = [
238
            'grant'  => [
239
                'attr'    => [
240
                    'href' => [
241
                        'url'     => 'privileges',
242
                        'urlvars' => array_merge($urlvars, ['mode' => 'grant']),
243
                    ],
244
                ],
245
                'content' => $this->lang['strgrant'],
246
            ],
247
            'revoke' => [
248
                'attr'    => [
249
                    'href' => [
250
                        'url'     => 'privileges',
251
                        'urlvars' => array_merge($urlvars, ['mode' => 'revoke']),
252
                    ],
253
                ],
254
                'content' => $this->lang['strrevoke'],
255
            ],
256
        ];
257
258
        if (isset($allurl)) {
259
            $navlinks[$alllabel] = [
260
                'attr'    => [
261
                    'href' => [
262
                        'url'     => $allurl,
263
                        'urlvars' => [
264
                            'server'   => $_REQUEST['server'],
265
                            'database' => $_REQUEST['database'],
266
                        ],
267
                    ],
268
                ],
269
                'content' => $alltxt,
270
            ];
271
            if (isset($_REQUEST['schema'])) {
272
                $navlinks[$alllabel]['attr']['href']['urlvars']['schema'] = $_REQUEST['schema'];
273
            }
274
        }
275
276
        $this->printNavLinks($navlinks, $this->table_place, get_defined_vars());
277
    }
278
279
    /**
280
     * Prints the form to grants permision on an object to a user.
281
     *
282
     * @param string $mode either grant or revoke
283
     * @param string $msg  The message
284
     */
285
    public function formAlter($mode, $msg = '')
286
    {
287
        $data = $this->misc->getDatabaseAccessor();
288
289
        $this->coalesceArr($_REQUEST, 'username', []);
290
291
        $this->coalesceArr($_REQUEST, 'groupname', []);
292
293
        $this->coalesceArr($_REQUEST, 'privilege', []);
294
295
        // Get users from the database
296
        $users = $data->getUsers();
297
        // Get groups from the database
298
        $groups = $data->getGroups();
299
300
        $this->printTrail($_REQUEST['subject']);
301
302
        $this->printTitle($this->lang['str'.$mode], 'pg.privilege.'.$mode);
303
304
        $this->printMsg($msg);
305
306
        echo '<form action="'.\SUBFOLDER.'/src/views/privileges" method="post">'.PHP_EOL;
307
        echo '<table>'.PHP_EOL;
308
        echo "<tr><th class=\"data left\">{$this->lang['strusers']}</th>".PHP_EOL;
309
        echo '<td class="data1"><select name="username[]" multiple="multiple" size="', min(6, $users->recordCount()), '">'.PHP_EOL;
310
        while (!$users->EOF) {
311
            $uname = htmlspecialchars($users->fields['usename']);
312
            echo "<option value=\"{$uname}\"",
313
            in_array($users->fields['usename'], $_REQUEST['username'], true) ? ' selected="selected"' : '', ">{$uname}</option>".PHP_EOL;
314
            $users->moveNext();
315
        }
316
        echo '</select></td></tr>'.PHP_EOL;
317
        echo "<tr><th class=\"data left\">{$this->lang['strgroups']}</th>".PHP_EOL;
318
        echo '<td class="data1">'.PHP_EOL;
319
        echo '<input type="checkbox" id="public" name="public"', (isset($_REQUEST['public']) ? ' checked="checked"' : ''), ' /><label for="public">PUBLIC</label>'.PHP_EOL;
320
        // Only show groups if there are groups!
321
        if ($groups->recordCount() > 0) {
322
            echo '<br /><select name="groupname[]" multiple="multiple" size="', min(6, $groups->recordCount()), '">'.PHP_EOL;
323
            while (!$groups->EOF) {
324
                $gname = htmlspecialchars($groups->fields['groname']);
325
                echo "<option value=\"{$gname}\"",
326
                in_array($groups->fields['groname'], $_REQUEST['groupname'], true) ? ' selected="selected"' : '', ">{$gname}</option>".PHP_EOL;
327
                $groups->moveNext();
328
            }
329
            echo '</select>'.PHP_EOL;
330
        }
331
        echo '</td></tr>'.PHP_EOL;
332
        echo "<tr><th class=\"data left required\">{$this->lang['strprivileges']}</th>".PHP_EOL;
333
        echo '<td class="data1">'.PHP_EOL;
334
        foreach ($data->privlist[$_REQUEST['subject']] as $v) {
335
            $v = htmlspecialchars($v);
336
            echo "<input type=\"checkbox\" id=\"privilege[${v}]\" name=\"privilege[${v}]\"",
337
            isset($_REQUEST['privilege'][$v]) ? ' checked="checked"' : '', " /><label for=\"privilege[${v}]\">{$v}</label><br />".PHP_EOL;
338
        }
339
        echo '</td></tr>'.PHP_EOL;
340
        // Grant option
341
        if ($data->hasGrantOption()) {
342
            echo "<tr><th class=\"data left\">{$this->lang['stroptions']}</th>".PHP_EOL;
343
            echo '<td class="data1">'.PHP_EOL;
344
            if ('grant' == $mode) {
345
                echo '<input type="checkbox" id="grantoption" name="grantoption"',
346
                isset($_REQUEST['grantoption']) ? ' checked="checked"' : '', ' /><label for="grantoption">GRANT OPTION</label>'.PHP_EOL;
347
            } elseif ('revoke' == $mode) {
348
                echo '<input type="checkbox" id="grantoption" name="grantoption"',
349
                isset($_REQUEST['grantoption']) ? ' checked="checked"' : '', ' /><label for="grantoption">GRANT OPTION FOR</label><br />'.PHP_EOL;
350
                echo '<input type="checkbox" id="cascade" name="cascade"',
351
                isset($_REQUEST['cascade']) ? ' checked="checked"' : '', ' /><label for="cascade">CASCADE</label><br />'.PHP_EOL;
352
            }
353
            echo '</td></tr>'.PHP_EOL;
354
        }
355
        echo '</table>'.PHP_EOL;
356
357
        echo '<p><input type="hidden" name="action" value="save" />'.PHP_EOL;
358
        echo '<input type="hidden" name="mode" value="', htmlspecialchars($mode), '" />'.PHP_EOL;
359
        echo '<input type="hidden" name="subject" value="', htmlspecialchars($_REQUEST['subject']), '" />'.PHP_EOL;
360
        if (isset($_REQUEST[$_REQUEST['subject'].'_oid'])) {
361
            echo '<input type="hidden" name="', htmlspecialchars($_REQUEST['subject'].'_oid'),
362
            '" value="', htmlspecialchars($_REQUEST[$_REQUEST['subject'].'_oid']), '" />'.PHP_EOL;
363
        }
364
365
        echo '<input type="hidden" name="', htmlspecialchars($_REQUEST['subject']),
366
        '" value="', htmlspecialchars($_REQUEST[$_REQUEST['subject']]), '" />'.PHP_EOL;
367
        if ('column' == $_REQUEST['subject']) {
368
            echo '<input type="hidden" name="table" value="',
369
            htmlspecialchars($_REQUEST['table']), '" />'.PHP_EOL;
370
        }
371
372
        echo $this->misc->form;
373
        echo sprintf('<input type="submit" name="%s" value="%s" />%s', $mode, $this->lang['str'.$mode], PHP_EOL);
374
375
        echo "<input type=\"submit\" name=\"cancel\" value=\"{$this->lang['strcancel']}\" /></p>";
376
        echo '</form>'.PHP_EOL;
377
    }
378
379
    /**
380
     * Grant permissions on an object to a user.
381
     *
382
     * @param string $mode 'grant' or 'revoke'
383
     */
384
    public function doAlter($mode)
385
    {
386
        $data = $this->misc->getDatabaseAccessor();
387
388
        $this->coalesceArr($_REQUEST, 'username', []);
389
390
        $this->coalesceArr($_REQUEST, 'groupname', []);
391
392
        $this->coalesceArr($_REQUEST, 'privilege', []);
393
394
        // Determine whether object should be ref'd by name or oid.
395
        if (isset($_REQUEST[$_REQUEST['subject'].'_oid'])) {
396
            $object = $_REQUEST[$_REQUEST['subject'].'_oid'];
397
        } else {
398
            $object = $_REQUEST[$_REQUEST['subject']];
399
        }
400
401
        if (isset($_REQUEST['table'])) {
402
            $table = $_REQUEST['table'];
403
        } else {
404
            $table = null;
405
        }
406
407
        $status = $data->setPrivileges(
408
            ('grant' == $mode) ? 'GRANT' : 'REVOKE',
409
            $_REQUEST['subject'],
410
            $object,
411
            isset($_REQUEST['public']),
412
            $_REQUEST['username'],
413
            $_REQUEST['groupname'],
414
            array_keys($_REQUEST['privilege']),
415
            isset($_REQUEST['grantoption']),
416
            isset($_REQUEST['cascade']),
417
            $table
418
        );
419
420
        if (0 == $status) {
421
            $this->doDefault($this->lang['strgranted']);
422
        } elseif ($status == -3 || $status == -4) {
423
            $this->formAlter($_REQUEST['mode'], $this->lang['strgrantbad']);
424
        } else {
425
            $this->formAlter($_REQUEST['mode'], $this->lang['strgrantfailed']);
426
        }
427
    }
428
}
429