Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 172
0.00% covered (danger)
0.00%
0 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
GroupController
0.00% covered (danger)
0.00%
0 / 172
0.00% covered (danger)
0.00%
0 / 7
2162
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 pageGroups
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
6
 formGroupCreate
0.00% covered (danger)
0.00%
0 / 43
0.00% covered (danger)
0.00%
0 / 1
42
 formGroupEdit
0.00% covered (danger)
0.00%
0 / 41
0.00% covered (danger)
0.00%
0 / 1
56
 createGroup
0.00% covered (danger)
0.00%
0 / 34
0.00% covered (danger)
0.00%
0 / 1
210
 updateGroup
0.00% covered (danger)
0.00%
0 / 26
0.00% covered (danger)
0.00%
0 / 1
156
 deleteGroup
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2
3namespace BuyerKiosk\Core\Controllers;
4
5/*******
6
7/groups/*
8
9*******/
10
11// Handles group-related activities
12class GroupController extends BaseController {
13
14    public function __construct($app){
15        $this->_app = $app;
16    }
17    
18    public function pageGroups(){
19        // Access-controlled page
20        if (!$this->_app->user->checkAccess('uri_groups')){
21            $this->_app->notFound();
22        }
23        
24        $groups = GroupLoader::fetchAll();
25        
26        $this->_app->render('groups.html', [
27            'page' => [
28                'author' =>         $this->_app->site->author,
29                'title' =>          "Groups",
30                'description' =>    "Group management, authorization rules, add/remove groups, etc.",
31                'alerts' =>         $this->_app->alerts->getAndClearMessages()
32            ],
33            "groups" => $groups
34        ]);          
35    }    
36
37   // Display the form for creating a new group
38    public function formGroupCreate(){
39        // Access-controlled resource
40        if (!$this->_app->user->checkAccess('create_group')){
41            $this->_app->notFound();
42        }
43        
44        $get = $this->_app->request->get();
45        
46        if (isset($get['render']))
47            $render = $get['render'];
48        else
49            $render = "modal";
50        
51        // Get a list of all themes
52        $theme_list = $this->_app->site->getThemes();
53        
54        // Set default values
55        $data['is_default'] = "0";
56        // Set default title for new users
57        $data['new_user_title'] = "New User";
58        // Set default theme
59        $data['theme'] = "default";
60        // Set default icon
61        $data['icon'] = "fa fa-user";
62        // Set default landing page
63        $data['landing_page'] = "dashboard";
64        
65        // Create a dummy Group to prepopulate fields
66        $group = new Group($data);                
67        
68        if ($render == "modal")
69            $template = "components/group-info-modal.html";
70        else
71            $template = "components/group-info-panel.html";
72        
73        // Determine authorized fields
74        $fields = ['name', 'new_user_title', 'landing_page', 'theme', 'is_default', 'icon'];
75        $show_fields = [];
76        $disabled_fields = [];
77        foreach ($fields as $field){
78            if ($this->_app->user->checkAccess("update_group_setting", ["property" => $field]))
79                $show_fields[] = $field;
80            else
81                $disabled_fields[] = $field;
82        }
83        
84        // Load validator rules
85        $schema = new \Fortress\RequestSchema($this->_app->config('schema.path') . "/forms/group-create.json");
86        $validators = new \Fortress\FormValidationAdapter($this->_app->translator, $schema);
87        
88        $this->_app->render($template, [
89            "box_id" => $get['box_id'],
90            "box_title" => "New Group",
91            "submit_button" => "Create group",
92            "form_action" => $this->_app->site->uri['public'] . "/groups",
93            "group" => $group,
94            "themes" => $theme_list,
95            "fields" => [
96                "disabled" => $disabled_fields,
97                "hidden" => []
98            ],
99            "buttons" => [
100                "hidden" => [
101                    "edit", "delete"
102                ]
103            ],
104            "validators" => $validators->formValidationRulesJson()
105        ]);   
106    }            
107    
108   // Display the form for editing an existing group
109    public function formGroupEdit($group_id){
110        // Access-controlled resource
111        if (!$this->_app->user->checkAccess('uri_groups')){
112            $this->_app->notFound();
113        }
114        
115        $get = $this->_app->request->get();
116        
117        if (isset($get['render']))
118            $render = $get['render'];
119        else
120            $render = "modal";
121        
122        // Get the group to edit
123        $group = GroupLoader::fetch($group_id);
124        
125        // Get a list of all themes
126        $theme_list = $this->_app->site->getThemes();
127        
128        if ($render == "modal")
129            $template = "components/group-info-modal.html";
130        else
131            $template = "components/group-info-panel.html";
132        
133        // Determine authorized fields
134        $fields = ['name', 'new_user_title', 'landing_page', 'theme', 'is_default'];
135        $show_fields = [];
136        $disabled_fields = [];
137        $hidden_fields = [];
138        foreach ($fields as $field){
139            if ($this->_app->user->checkAccess("update_group_setting", ["property" => $field]))
140                $show_fields[] = $field;
141            else if ($this->_app->user->checkAccess("view_group_setting", ["property" => $field]))
142                $disabled_fields[] = $field;
143            else
144                $hidden_fields[] = $field;
145        }
146        
147        // Load validator rules
148        $schema = new \Fortress\RequestSchema($this->_app->config('schema.path') . "/forms/group-update.json");
149        $validators = new \Fortress\ClientSideValidator($schema, $this->_app->translator);          
150        
151        $this->_app->render($template, [
152            "box_id" => $get['box_id'],
153            "box_title" => "Edit Group",
154            "submit_button" => "Update group",
155            "form_action" => $this->_app->site->uri['public'] . "/groups/g/$group_id",
156            "group" => $group,
157            "themes" => $theme_list,
158            "fields" => [
159                "disabled" => $disabled_fields,
160                "hidden" => $hidden_fields
161            ],
162            "buttons" => [
163                "hidden" => [
164                    "edit", "delete"
165                ]
166            ],
167            "validators" => $validators->formValidationRulesJson()
168        ]);   
169    }
170    
171    // Create new group
172    public function createGroup(){
173        $post = $this->_app->request->post();
174        
175        // DEBUG: view posted data
176        //error_log(print_r($post, true));
177        
178        // Load the request schema
179        $requestSchema = new \Fortress\RequestSchema($this->_app->config('schema.path') . "/forms/group-create.json");
180        
181        // Get the alert message stream
182        $ms = $this->_app->alerts; 
183        
184        // Access-controlled resource
185        if (!$this->_app->user->checkAccess('create_group')){
186            $ms->addMessageTranslated("danger", "ACCESS_DENIED");
187            $this->_app->halt(403);
188        }
189
190        // Set up Fortress to process the request
191        $rf = new \Fortress\HTTPRequestFortress($ms, $requestSchema, $post);        
192  
193        // Sanitize data
194        $rf->sanitize();
195                
196        // Validate, and halt on validation errors.
197        $error = !$rf->validate(true);
198        
199        // Get the filtered data
200        $data = $rf->data();        
201        
202        // Remove csrf_token from object data
203        $rf->removeFields(['csrf_token']);
204        
205        // Perform desired data transformations on required fields. 
206        $data['name'] = trim($data['name']);
207        $data['new_user_title'] = trim($data['new_user_title']);
208        $data['landing_page'] = strtolower(trim($data['landing_page']));
209        $data['theme'] = strtolower(trim($data['theme']));
210        $data['can_delete'] = 1;
211        
212        // Check if group name already exists
213        if (GroupLoader::exists($data['name'], 'name')){
214            $ms->addMessageTranslated("danger", "GROUP_NAME_IN_USE", $post);
215            $error = true;
216        }
217        
218        // Halt on any validation errors
219        if ($error) {
220            $this->_app->halt(400);
221        }
222    
223        // Set default values if not specified or not authorized
224        if (!isset($data['theme']) || !$this->_app->user->checkAccess("update_group_setting", ["property" => "theme"]))
225            $data['theme'] = "default";
226    
227        if (!isset($data['new_user_title']) || !$this->_app->user->checkAccess("update_group_setting", ["property" => "new_user_title"])) {
228            // Set default title for new users
229            $data['new_user_title'] = "New User";
230        }
231        
232        if (!isset($data['landing_page']) || !$this->_app->user->checkAccess("update_group_setting", ["property" => "landing_page"])) {
233            $data['landing_page'] = "dashboard";
234        }
235        
236        if (!isset($data['icon']) || !$this->_app->user->checkAccess("update_group_setting", ["property" => "icon"])) {
237            $data['icon'] = "fa fa-user";
238        }
239
240        if (!isset($data['is_default']) || !$this->_app->user->checkAccess("update_group_setting", ["property" => "is_default"])) {
241            $data['is_default'] = "0";
242        }
243        
244        // Create the group
245        $group = new Group($data);
246        
247        // Store new group to database
248        $group->store();        
249        
250        // Success message
251        $ms->addMessageTranslated("success", "GROUP_CREATION_SUCCESSFUL", $data);
252    }
253        
254    
255    // Update group details
256    public function updateGroup($group_id){
257        $post = $this->_app->request->post();
258        
259        // DEBUG: view posted data
260        //error_log(print_r($post, true));
261        
262        // Load the request schema
263        $requestSchema = new \Fortress\RequestSchema($this->_app->config('schema.path') . "/forms/group-update.json");
264        
265        // Get the alert message stream
266        $ms = $this->_app->alerts; 
267        
268        // Get the target group
269        $group = GroupLoader::fetch($group_id);
270        
271        // If desired, put route-level authorization check here
272        
273        // Remove csrf_token
274        unset($post['csrf_token']);
275                                
276        // Check authorization for submitted fields, if the value has been changed
277        foreach ($post as $name => $value) {
278            if (isset($group->$name) && $post[$name] != $group->$name){
279                // Check authorization
280                if (!$this->_app->user->checkAccess('update_group_setting', ['group' => $group, 'property' => $name])){
281                    $ms->addMessageTranslated("danger", "ACCESS_DENIED");
282                    $this->_app->halt(403);
283                }
284            } else if (!isset($group->$name)) {
285                $ms->addMessageTranslated("danger", "NO_DATA");
286                $this->_app->halt(400);
287            }
288        }
289        
290        // Check that name is not already in use
291        if (isset($post['name']) && $post['name'] != $group->name && GroupLoader::exists($post['name'], 'name')){
292            $ms->addMessageTranslated("danger", "GROUP_NAME_IN_USE", $post);
293            $this->_app->halt(400);
294        }
295        
296        // TODO: validate landing page route, theme, icon?
297        
298        // Set up Fortress to process the request
299        $rf = new \Fortress\HTTPRequestFortress($ms, $requestSchema, $post);                    
300    
301        // Sanitize
302        $rf->sanitize();
303    
304        // Validate, and halt on validation errors.
305        if (!$rf->validate()) {
306            $this->_app->halt(400);
307        }   
308               
309        // Get the filtered data
310        $data = $rf->data();
311        
312        // Update the group and generate success messages
313        foreach ($data as $name => $value){
314            if ($value != $group->$name){
315                $group->$name = $value;
316                // Add any custom success messages here
317            }
318        }
319        
320        $ms->addMessageTranslated("success", "GROUP_UPDATE", ["name" => $group->name]);
321        $group->store();        
322        
323    }
324    
325    // Delete a group, removing all users and any group-specific authorization rules
326    public function deleteGroup($group_id){
327        $post = $this->_app->request->post();
328    
329        // Get the target group
330        $group = GroupLoader::fetch($group_id);
331    
332        // Get the alert message stream
333        $ms = $this->_app->alerts;
334        
335        // Check authorization
336        if (!$this->_app->user->checkAccess('delete_group', ['group' => $group])){
337            $ms->addMessageTranslated("danger", "ACCESS_DENIED");
338            $this->_app->halt(403);
339        }
340                
341        // Check that we are allowed to delete this group
342        if ($group->can_delete == "0"){
343            $ms->addMessageTranslated("danger", "CANNOT_DELETE_GROUP", ["name" => $group->name]);
344            $this->_app->halt(403);
345        }
346
347        // Do not allow deletion if this group is currently set as the default primary group
348        if ($group->is_default == GROUP_DEFAULT_PRIMARY){
349            $ms->addMessageTranslated("danger", "GROUP_CANNOT_DELETE_DEFAULT_PRIMARY", ["name" => $group->name]);
350            $this->_app->halt(403);
351        }
352        
353        $ms->addMessageTranslated("success", "GROUP_DELETION_SUCCESSFUL", ["name" => $group->name]);
354        $group->delete();       // TODO: implement Group function
355        unset($group);
356    }
357        
358}
359