Completed
Push — master ( f16f44...7a2452 )
by Andreas
21:05
created

load_assignees()   B

Complexity

Conditions 8
Paths 50

Size

Total Lines 40
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 11.0764

Importance

Changes 0
Metric Value
cc 8
eloc 24
nc 50
nop 0
dl 0
loc 40
ccs 14
cts 22
cp 0.6364
crap 11.0764
rs 8.4444
c 0
b 0
f 0
1
<?php
2
/**
3
 * @package midgard.admin.asgard
4
 * @author The Midgard Project, http://www.midgard-project.org
5
 * @copyright The Midgard Project, http://www.midgard-project.org
6
 * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License
7
 */
8
9
use midcom\datamanager\schemadb;
10
use midcom\datamanager\datamanager;
11
use midcom\datamanager\controller;
12
use Symfony\Component\HttpFoundation\Request;
13
14
/**
15
 * Permissions interface
16
 *
17
 * @package midgard.admin.asgard
18
 */
19
class midgard_admin_asgard_handler_object_permissions extends midcom_baseclasses_components_handler
20
{
21
    use midgard_admin_asgard_handler;
22
23
    /**
24
     * The object whose permissions we handle
25
     *
26
     * @var midcom_core_dbaobject
27
     */
28
    private $_object;
29
30
    /**
31
     * The Controller of the object used for editing
32
     *
33
     * @var controller
34
     */
35
    private $_controller;
36
37
    /**
38
     * Privileges we're managing here
39
     *
40
     * @var Array
41
     */
42
    private $_privileges = [
43
        // Midgard core level privileges
44
        'midgard:owner', 'midgard:read', 'midgard:update', 'midgard:delete', 'midgard:create',
45
        'midgard:parameters', 'midgard:attachments', 'midgard:privileges'
46
    ];
47
48
    /**
49
     * Table header
50
     *
51
     * @var String
52
     */
53
    private $_header = '';
54
55
    /**
56
     * Available row labels
57
     *
58
     * @var Array
59
     */
60
    private $_row_labels = [];
61
62
    private $additional_assignee;
63
64 1
    public function _on_initialize()
65
    {
66 1
        if (midcom::get()->config->get('metadata_approval')) {
67
            $this->_privileges[] = 'midcom:approve';
68
        }
69
70 1
        midcom::get()->head->add_jsfile(MIDCOM_STATIC_URL . '/midgard.admin.asgard/permissions/permissions.js');
71 1
        $this->add_stylesheet(MIDCOM_STATIC_URL . '/midgard.admin.asgard/permissions/layout.css');
72 1
    }
73
74
    /**
75
     * Simple helper which references all important members to the request data listing
76
     * for usage within the style listing.
77
     */
78 1
    private function _prepare_request_data()
79
    {
80 1
        $this->_request_data['object'] = $this->_object;
81 1
        $this->_request_data['controller'] = $this->_controller;
82 1
    }
83
84
    /**
85
     * Load component-defined additional privileges
86
     */
87 1
    private function _load_component_privileges()
88
    {
89 1
        $component_loader = midcom::get()->componentloader;
90
91
        // Store temporarily the requested object
92 1
        $tmp = $this->_object;
93
94 1
        $i = 0;
95 1
        while (   !empty($tmp->guid)
96 1
               && !is_a($tmp, midcom_db_topic::class)
97 1
               && $i < 100) {
98
            // Get the parent; wishing eventually to get a topic
99
            $tmp = $tmp->get_parent();
100
            $i++;
101
        }
102
103
        // If the temporary object eventually reached a topic, fetch its manifest
104 1
        if (is_a($tmp, midcom_db_topic::class)) {
105 1
            $current_manifest = $component_loader->manifests[$tmp->component];
106
        } else {
107
            $current_manifest = $component_loader->manifests[midcom_core_context::get()->get_key(MIDCOM_CONTEXT_COMPONENT)];
108
        }
109 1
        $this->_privileges = array_merge($this->_privileges, array_keys($current_manifest->privileges));
110
111 1
        if (!empty($current_manifest->customdata['midgard.admin.asgard.acl']['extra_privileges'])) {
112
            foreach ($current_manifest->customdata['midgard.admin.asgard.acl']['extra_privileges'] as $privilege) {
113
                if (!strpos($privilege, ':')) {
114
                    // Only component specified
115
                    // TODO: load components manifest and add privileges from there
116
                    continue;
117
                }
118
                $this->_privileges[] = $privilege;
119
            }
120
        }
121
122
        // In addition, give component configuration privileges if we're in topic
123 1
        if ($this->_object instanceof midcom_db_topic) {
124 1
            $this->_privileges[] = 'midcom.admin.folder:topic_management';
125 1
            $this->_privileges[] = 'midcom.admin.folder:template_management';
126 1
            $this->_privileges[] = 'midcom:component_config';
127 1
            $this->_privileges[] = 'midcom:urlname';
128
        }
129 1
    }
130
131
    /**
132
     * Generates, loads and prepares the schema database.
133
     *
134
     * @return controller
135
     */
136 1
    private function load_controller()
137
    {
138 1
        $schemadb = schemadb::from_path($this->_config->get('schemadb_permissions'));
139
140 1
        $assignees = $this->load_assignees();
141 1
        $this->process_assignees($assignees, $schemadb);
142 1
        $assignee_field =& $schemadb->get('privileges')->get_field('add_assignee');
143
144 1
        if (!$this->additional_assignee) {
145
            // Populate additional assignee selector
146
            $additional_assignees = [
147 1
                '' => '',
148 1
                'EVERYONE' => $this->_l10n->get('EVERYONE'),
149 1
                'USERS' => $this->_l10n->get('USERS'),
150 1
                'ANONYMOUS' => $this->_l10n->get('ANONYMOUS')
151
            ];
152
153
            // List groups as potential assignees
154 1
            $qb = midcom_db_group::new_query_builder();
155 1
            foreach ($qb->execute() as $group) {
156 1
                if (!array_key_exists("group:{$group->guid}", $assignees)) {
157 1
                    $additional_assignees["group:{$group->guid}"] = $group->get_label();
0 ignored issues
show
Bug introduced by
The method get_label() does not exist on midcom_core_dbaobject. It seems like you code against a sub-type of midcom_core_dbaobject such as org_openpsa_calendar_event_dba or org_openpsa_invoices_invoice_dba or net_nemein_tag_tag_dba or org_openpsa_invoices_invoice_item_dba or midcom_db_parameter or org_openpsa_calendar_event_member_dba or org_openpsa_sales_salesproject_offer_dba or midcom_db_topic or net_nemein_tag_link_dba or org_openpsa_invoices_billing_data_dba or org_openpsa_directmarketing_campaign_member_dba or org_openpsa_contacts_group_dba or midcom_db_person or midcom_db_member or org_openpsa_projects_project or org_openpsa_calendar_event_resource_dba or midcom_db_group or org_openpsa_projects_task_dba or org_openpsa_documents_document_dba. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

157
                    /** @scrutinizer ignore-call */ 
158
                    $additional_assignees["group:{$group->guid}"] = $group->get_label();
Loading history...
158
                }
159
            }
160 1
            asort($additional_assignees);
161
162
            // Add the 'Add assignees' choices to schema
163 1
            $assignee_field['type_config']['options'] = $additional_assignees;
164
        } else {
165
            $assignee_field['type'] = 'text';
166
            $assignee_field['widget'] = 'hidden';
167
        }
168 1
        $dm = new datamanager($schemadb);
169
170
        return $dm
171 1
            ->set_storage($this->_object)
172 1
            ->get_controller();
173
    }
174
175 1
    private function process_assignees(array $assignees, schemadb $schemadb)
176
    {
177 1
        $header = '';
178 1
        $header_items = [];
179 1
        $fields = $schemadb->get('privileges')->get('fields');
180
181 1
        foreach ($assignees as $assignee => $label) {
182 1
            $classname = '';
183 1
            if (strpos($assignee, '/')) {
184
                list($assignee, $classname) = explode('/', $assignee, 2);
185
            }
186 1
            foreach ($this->_privileges as $privilege) {
187 1
                $privilege_components = explode(':', $privilege);
188 1
                if (   $privilege_components[0] == 'midcom'
189 1
                    || $privilege_components[0] == 'midgard') {
190
                    // This is one of the core privileges, we handle it
191 1
                    $privilege_label = $privilege;
192
                } else {
193
                    // This is a component-specific privilege, call component to localize it
194 1
                    $privilege_label = $this->_i18n->get_string("privilege {$privilege_components[1]}", $privilege_components[0]);
195
                }
196
197 1
                if (!isset($header_items[$privilege_label])) {
198 1
                    $header_items[$privilege_label] = "        <th scope=\"col\" class=\"{$privilege_components[1]}\"><span>" . $this->_l10n->get($privilege_label) . "</span></th>\n";
199
                }
200
201 1
                $fields[str_replace([':', '.'], '_', $assignee . $classname . '__' . $privilege)] = [
202 1
                    'title' => $privilege_label,
203
                    'storage' => null,
204 1
                    'type' => 'privilege',
205
                    'type_config' => [
206 1
                        'privilege_name' => $privilege,
207 1
                        'assignee' => $assignee,
208 1
                        'classname' => $classname
209
                    ],
210 1
                    'widget' => 'privilegeselection'
211
                ];
212
            }
213
        }
214
215 1
        $schemadb->get('privileges')->set('fields', $fields);
216
217 1
        $header .= "        <th scope=\"col\" class=\"assignee_name\"><span>&nbsp;</span></th>\n";
218 1
        $header .= implode('', $header_items);
219 1
        $header .= "        <th scope=\"col\" class=\"row_actions\"><span>&nbsp;</span></th>\n";
220
221 1
        $this->_header = $header;
222 1
    }
223
224 1
    private function load_assignees()
225
    {
226 1
        $assignees = [];
227
228
        // Populate all resources having existing privileges
229 1
        $existing_privileges = $this->_object->get_privileges();
230 1
        if ($this->additional_assignee) {
231
            $existing_privileges[] = new midcom_core_privilege(['assignee' => $this->additional_assignee]);
232
        }
233 1
        foreach ($existing_privileges as $privilege) {
234 1
            if (!in_array($privilege->privilegename, $this->_privileges)) {
235
                $this->_privileges[] = $privilege->privilegename;
236
            }
237 1
            if ($privilege->is_magic_assignee()) {
238
                // This is a magic assignee
239 1
                $label = $this->_l10n->get($privilege->assignee);
240
            } else {
241
                // Inconsistent privilege base will mess here. Let's give a chance to remove ghosts
242
                $assignee = midcom::get()->auth->get_assignee($privilege->assignee);
243
244
                if (is_object($assignee)) {
245
                    $label = $assignee->name;
246
                } else {
247
                    $label = $this->_l10n->get('ghost assignee for '. $privilege->assignee);
248
                }
249
            }
250
251 1
            if ($privilege->classname) {
252
                $label .= ' / ' . $privilege->classname;
253
                $assignees[$privilege->assignee . '/' . $privilege->classname] = $label;
254
            } else {
255 1
                $assignees[$privilege->assignee] = $label;
256
            }
257
258 1
            $key = str_replace(':', '_', $privilege->assignee) . $privilege->classname;
259 1
            if (!isset($this->_row_labels[$key])) {
260 1
                $this->_row_labels[$key] = $label;
261
            }
262
        }
263 1
        return $assignees;
264
    }
265
266
    /**
267
     * Object editing view
268
     *
269
     * @param Request $request The request object
270
     * @param mixed $handler_id The ID of the handler.
271
     * @param string $guid The object's GUID
272
     * @param array $data The local request data.
273
     */
274 1
    public function _handler_edit(Request $request, $handler_id, $guid, array &$data)
275
    {
276 1
        $this->_object = midcom::get()->dbfactory->get_object_by_guid($guid);
277 1
        $this->_object->require_do('midgard:privileges');
278 1
        midcom::get()->auth->require_user_do('midgard.admin.asgard:manage_objects', null, 'midgard_admin_asgard_plugin');
279
280
        // Load possible additional component privileges
281 1
        $this->_load_component_privileges();
282
283 1
        if ($request->request->count() > 0) {
284
            $formdata = $request->request->all();
285
            $formdata = reset($formdata);
286
            $this->additional_assignee = $formdata['add_assignee'];
287
        }
288
289
        // Load the datamanager controller
290 1
        $this->_controller = $this->load_controller();
291
292 1
        switch ($this->_controller->handle($request)) {
293 1
            case 'save':
294
                return new midcom_response_relocate($this->router->generate('object_permissions', ['guid' => $this->_object->guid]));
295 1
            case 'cancel':
296
                return new midcom_response_relocate($this->router->generate('object_view', ['guid' => $this->_object->guid]));
297
        }
298
299 1
        $this->_prepare_request_data();
300
301 1
        midgard_admin_asgard_plugin::bind_to_object($this->_object, $handler_id, $data);
302 1
        return $this->get_response();
303
    }
304
305
    /**
306
     * Shows the loaded object in editor.
307
     *
308
     * @param mixed $handler_id The ID of the handler.
309
     * @param array $data The local request data.
310
     */
311 1
    public function _show_edit($handler_id, array &$data)
312
    {
313 1
        $data['editor_header_titles'] = $this->_header;
314 1
        $data['row_labels'] = $this->_row_labels;
315
316 1
        $data['renderer'] = $this->_controller->get_datamanager()->get_renderer('form');
317 1
        $data['form'] = $data['renderer']->get_view();
318
319 1
        midcom_show_style('midgard_admin_asgard_object_permissions');
320 1
    }
321
}
322