root/trunk/midcom/midgard.admin.acl/acl_editor.php

Revision 17350, 20.1 kB (checked in by flack, 3 days ago)

switch to PHP5-style constructors, part 3

  • Property svn:keywords set to Author Date Id Revision
Line 
1 <?php
2 /**
3  * @package midgard.admin.acl
4  * @author The Midgard Project, http://www.midgard-project.org
5  * @version $Id$
6  * @copyright The Midgard Project, http://www.midgard-project.org
7  * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License
8  */
9
10 /**
11  * Basic handler class
12  * @package midgard.admin.acl
13  */
14 class midgard_admin_acl_editor_plugin extends midcom_baseclasses_components_handler
15 {
16     /**
17      * The object we're managing
18      *
19      * @var object
20      * @access private
21      */
22     var $_object = null;
23
24     /**
25      * The Datamanager of the member to display
26      *
27      * @var midcom_helper_datamanager2_datamanager
28      * @access private
29      */
30     var $_datamanager = null;
31
32     /**
33      * The Controller of the member used for editing
34      *
35      * @var midcom_helper_datamanager2_controller_simple
36      * @access private
37      */
38     var $_controller = null;
39
40     /**
41      * The schema database in use, available only while a datamanager is loaded.
42      *
43      * @var Array
44      * @access private
45      */
46     var $_schemadb = null;
47
48     /**
49      * Privileges we're managing here
50      *
51      * @var Array
52      * @access private
53      */
54     var $_privileges = array();
55
56     var $_header = '';
57     var $_row_labels = array();
58     var $_rendered_row_labels = array();
59
60     function midgard_admin_acl_editor_plugin()
61     {
62         parent::__construct();
63
64         $this->_privileges[] = 'midgard:read';
65         $this->_privileges[] = 'midgard:create';
66         $this->_privileges[] = 'midgard:update';
67         $this->_privileges[] = 'midgard:delete';
68         $this->_privileges[] = 'midgard:owner';
69
70         // TEMPORARY CODE: This links the old midcom approval helpers into the site
71         // if we are configured to do so. This will be replaced once we revampt the
72         // Metadata system of MidCOM to use 1.8
73         if ($GLOBALS['midcom_config']['metadata_approval'])
74         {
75             $this->_privileges[] = 'midcom:approve';
76         }
77
78         $_MIDCOM->enable_jquery();
79         $script = "function submit_privileges(form){jQuery('#submit_action',form).attr({name: 'midcom_helper_datamanager2_save', value: 'Save'});form.submit();};";
80         $_MIDCOM->add_jscript($script);
81     }
82
83     function get_plugin_handlers()
84     {
85         return Array
86         (
87             'edit' => Array
88             (
89                 'handler' => Array('midgard_admin_acl_editor_plugin', 'edit'),
90                 'fixed_args' => 'edit',
91                 'variable_args' => 1,
92             ),
93         );
94     }
95
96     /**
97      * Load component-defined additional privileges
98      */
99     function _load_component_privileges()
100     {
101         $component_loader = $_MIDCOM->get_component_loader();
102         $current_manifest = $component_loader->manifests[$_MIDCOM->get_context_data(MIDCOM_CONTEXT_COMPONENT)];
103         foreach ($current_manifest->privileges as $privilege => $default_value)
104         {
105             $this->_privileges[] = $privilege;
106         }
107         /*
108         echo "DEBUG: manifest <pre>\n";
109         print_r($current_manifest);
110         echo "</pre>\n";
111         */
112         if (   isset($current_manifest->customdata['midgard.admin.acl'])
113             && isset($current_manifest->customdata['midgard.admin.acl']['extra_privileges']))
114         {
115             foreach ($current_manifest->customdata['midgard.admin.acl']['extra_privileges'] as $privilege)
116             {
117                 if (!strpos($privilege, ':'))
118                 {
119                     // Only component specified
120                     // TODO: load components manifest and add privileges from there
121                     continue;
122                 }
123                 $this->_privileges[] = $privilege;
124             }
125         }
126
127         // In addition, give component configuration privileges if we're in topic
128         if (is_a($this->_object, 'midcom_baseclasses_database_topic'))
129         {
130             $this->_privileges[] = 'midcom.admin.folder:topic_management';
131             $this->_privileges[] = 'midcom.admin.folder:template_management';
132             $this->_privileges[] = 'midcom:component_config';
133         }
134     }
135
136     function _resolve_object_title($object)
137     {
138         $vars = get_object_vars($object);
139
140         if (array_key_exists('title', $vars))
141         {
142             return $object->title;
143         }
144         elseif (array_key_exists('name', $vars))
145         {
146             return $object->name;
147         }
148         else
149         {
150             return "#{$object->id}";
151         }
152     }
153
154     /**
155      * Loads and prepares the schema database.
156      *
157      * Special treatment is done for the name field, which is set readonly for non-creates
158      * if the simple_name_handling config option is set. (using an auto-generated urlname based
159      * on the title, if it is missing.)
160      *
161      * The operations are done on all available schemas within the DB.
162      */
163     function _load_schemadb()
164     {
165         $this->_schemadb = midcom_helper_datamanager2_schema::load_database('file:/midgard/admin/acl/config/schemadb_default.inc');
166
167         // Populate additional assignee selector
168         $additional_assignees = Array(
169             '' => '',
170         );
171
172         // Populate the magic assignees
173         $additional_assignees['EVERYONE'] = $_MIDCOM->i18n->get_string('EVERYONE', 'midgard.admin.acl');
174         $additional_assignees['USERS'] = $_MIDCOM->i18n->get_string('USERS', 'midgard.admin.acl');
175         $additional_assignees['ANONYMOUS'] = $_MIDCOM->i18n->get_string('ANONYMOUS', 'midgard.admin.acl');
176
177         // List groups as potential assignees
178         $qb = midcom_db_group::new_query_builder();
179         if ($_MIDGARD['sitegroup'] != 0)
180         {
181             // Normally only display groups in current SG
182             $qb->add_constraint('sitegroup', '=', $_MIDGARD['sitegroup']);
183         }
184         $groups = $qb->execute();
185         foreach ($groups as $group)
186         {
187             $label = $group->official;
188             if (empty($group->official))
189             {
190                 $label = $group->name;
191                 if (empty($group->name))
192                 {
193                     $label = sprintf($_MIDCOM->i18n->get_string('group %s', 'midgard.admin.acl'), "#{$group->id}");
194                 }
195             }
196
197             $additional_assignees["group:{$group->guid}"] = $label;
198         }
199
200         $assignees = Array();
201
202         // Populate all resources having existing privileges
203         $existing_privileges = $this->_object->get_privileges();
204
205         foreach ($existing_privileges as $privilege)
206         {
207
208             $assignee = $_MIDCOM->auth->get_assignee($privilege->assignee);
209             if (!$assignee)
210             {
211                 // This is a magic assignee
212                 $label = $_MIDCOM->i18n->get_string($privilege->assignee, 'midgard.admin.acl');
213             }
214             else
215             {
216                 $label = $assignee->name;
217             }
218             $assignees[$privilege->assignee] = $label;
219
220             $key = str_replace(':', '_', $privilege->assignee);
221             if (! isset($this->_row_labels[$key]))
222             {
223                 $this->_row_labels[$key] = $label;
224             }
225
226             // This one is already an assignee, remove from "Add assignee" options
227             if (array_key_exists($privilege->assignee, $additional_assignees))
228             {
229                 unset($additional_assignees[$privilege->assignee]);
230             }
231         }
232
233         // Add the "Add assignees" choices to schema
234         $this->_schemadb['privileges']->fields['add_assignee']['type_config']['options'] = $additional_assignees;
235
236         $header = "<table width=\"100%\" border=\"0\" id=\"midgard_admin_acl\">\n";
237         $header_start = "<tr>\n";
238         $header_end = "</tr>\n";
239         $header_items = array();
240
241         $header .= $header_start;
242
243         foreach ($assignees as $assignee => $label)
244         {
245
246             foreach ($this->_privileges as $privilege)
247             {
248
249                 $privilege_components = explode(':', $privilege);
250                 if (   $privilege_components[0] == 'midcom'
251                     || $privilege_components[0] == 'midgard')
252                 {
253                     // This is one of the core privileges, we handle it
254                     $privilege_label = $privilege;
255                 }
256                 else
257                 {
258                     // This is a component-specific privilege, call component to localize it
259                     $privilege_label = $_MIDCOM->i18n->get_string("privilege {$privilege_components[1]}", $privilege_components[0]);
260                 }
261
262                 if (! isset($header_items[$privilege_label]))
263                 {
264                     $header_items[$privilege_label] = "<th scope=\"col\">{$_MIDCOM->i18n->get_string($privilege_label, 'midgard.admin.acl')}</th>\n";
265                 }
266
267                 $this->_schemadb['privileges']->append_field(str_replace(':', '_', $assignee) . '_' . str_replace(':', '_', str_replace('.', '_', $privilege)), Array
268                     (
269                         'title' => $privilege_label,
270                         'helptext'    => sprintf($_MIDCOM->i18n->get_string('sets privilege %s', 'midgard.admin.acl'), $privilege),
271                         'storage' => null,
272                         'type' => 'privilege',
273                         'type_config' => Array
274                         (
275                             'privilege_name' => $privilege,
276                             'assignee'       => $assignee,
277                         ),
278                         'widget' => 'privilegeselection',
279                     )
280                 );
281             }
282         }
283         $header .= "<th align=\"left\" scope=\"col\">&nbsp;</th>\n";
284         foreach ($header_items as $key => $item)
285         {
286             $header .= $item;
287         }
288         $header .= $header_end;
289         $this->_header = $header;
290     }
291
292     /**
293      * Internal helper, loads the controller for the current article. Any error triggers a 500.
294      *
295      * @access private
296      */
297     function _load_controller()
298     {
299         $_MIDCOM->load_library('midcom.helper.datamanager2');
300         $this->_load_schemadb();
301         $this->_controller =& midcom_helper_datamanager2_controller::create('simple');
302         $this->_controller->schemadb =& $this->_schemadb;
303         $this->_controller->set_storage($this->_object, 'privileges');
304         if (! $this->_controller->initialize())
305         {
306             $_MIDCOM->generate_error(MIDCOM_ERRCRIT, "Failed to initialize a DM2 controller instance for article {$this->_article->id}.");
307             // This will exit.
308         }
309     }
310
311     /**
312      * @param mixed $handler_id The ID of the handler.
313      * @param Array $args The argument list.
314      * @param Array &$data The local request data.
315      * @return boolean Indicating success.
316      */
317     function _handler_edit($handler_id, $args, &$data)
318     {
319         $this->_object = $_MIDCOM->dbfactory->get_object_by_guid($args[0]);
320         if (!$this->_object)
321         {
322             return false;
323         }
324         $this->_object->require_do('midgard:privileges');
325
326         if (! is_a($this->_object, 'midcom_baseclasses_database_topic'))
327         {
328             $_MIDCOM->bind_view_to_object($this->_object);
329         }
330
331         // Load possible additional component privileges
332         $this->_load_component_privileges();
333
334         // Load the datamanager controller
335         $this->_load_controller();
336
337         switch ($this->_controller->process_form())
338         {
339             case 'save':
340                 // Handle populating additional assignees
341                 if ($this->_object->parameter('midgard.admin.acl', 'add_assignee'))
342                 {
343                     // We do this by adding a READ privilege so they show up on get_privileges()
344                     // TODO: Would be nicer to register a priv that doesn't really count
345                     $this->_object->set_privilege('midgard:read', $this->_object->parameter('midgard.admin.acl', 'add_assignee'), MIDCOM_PRIVILEGE_ALLOW);
346
347                     // Then clear the parameter and relocate
348                     $this->_object->parameter('midgard.admin.acl', 'add_assignee', '');
349                     $_MIDCOM->relocate($_MIDGARD['uri']);
350                     // This will exit.
351                 }
352             case 'cancel':
353                 $_MIDCOM->relocate($_MIDCOM->permalinks->create_permalink($this->_object->guid));
354                 // This will exit.
355         }
356
357         $tmp = Array();
358         if (is_a($this->_object, 'midcom_baseclasses_database_topic'))
359         {
360             $tmp[] = Array
361             (
362                 MIDCOM_NAV_URL => "__ais/acl/edit/{$this->_object->guid}.html",
363                 MIDCOM_NAV_NAME => $_MIDCOM->i18n->get_string('topic privileges', 'midgard.admin.acl'),
364             );
365             $this->_node_toolbar->hide_item("__ais/acl/edit/{$this->_object->guid}.html");
366         }
367         else
368         {
369             $tmp[] = Array
370             (
371                 MIDCOM_NAV_URL => $_MIDCOM->permalinks->create_permalink($this->_object->guid),
372                 MIDCOM_NAV_NAME => $this->_resolve_object_title($this->_object),
373             );
374             $tmp[] = Array
375             (
376                 MIDCOM_NAV_URL => "__ais/acl/edit/{$this->_object->guid}.html",
377                 MIDCOM_NAV_NAME => $_MIDCOM->i18n->get_string('privileges', 'midgard.admin.acl'),
378             );
379             $this->_view_toolbar->hide_item("__ais/acl/edit/{$this->_object->guid}.html");
380         }
381         $_MIDCOM->set_custom_context_data('midcom.helper.nav.breadcrumb', $tmp);
382
383         // Add the toolbar items, if necessary
384         $this->_view_toolbar->add_help_item('edit', 'midgard.admin.acl');
385
386         // Figure out label for the object's class
387         switch (get_class($this->_object))
388         {
389             case 'midcom_baseclasses_database_topic':
390                 $type = $_MIDCOM->i18n->get_string('folder', 'midgard.admin.acl');
391                 break;
392             default:
393                 $type_parts = explode('_', get_class($this->_object));
394                 $type = $type_parts[count($type_parts)-1];
395         }
396         $data['title'] = sprintf($_MIDCOM->i18n->get_string('permissions for %s %s', 'midgard.admin.acl'), $type, $this->_resolve_object_title($this->_object));
397         $_MIDCOM->set_pagetitle($data['title']);
398
399         return true;
400     }
401
402     /**
403      *
404      * @param mixed $handler_id The ID of the handler.
405      * @param mixed &$data The local request data.
406      */
407     function _show_edit($handler_id, &$data)
408     {
409         echo "<h1>{$data['title']}</h1>\n";
410
411         // var_dump($this->_controller->formmanager->form, 1);
412
413         $form_start = "<form ";
414         foreach ($this->_controller->formmanager->form->_attributes as $key => $value)
415         {
416             $form_start .= "{$key}=\"{$value}\" ";
417         }
418         $form_start .= "/>\n";
419         echo $form_start;
420
421         $table_start = "<table width=\"100%\" border=\"0\" id=\"midgard_admin_acl\">\n";
422         echo $table_start;
423
424         $priv_item_cnt = count($this->_privileges);
425
426         foreach ($this->_controller->formmanager->form->_elements as $i => $row)
427         {
428             if (is_a($row, 'HTML_QuickForm_hidden'))
429             {
430                 $html = "<input type=\"hidden\" ";
431                 foreach ($row->_attributes as $key => $value)
432                 {
433                     $html .= "{$key}=\"{$value}\" ";
434                 }
435                 $html .= "/>\n";
436                 echo $html;
437             }
438
439             if (is_a($row, 'HTML_QuickForm_select'))
440             {
441                 $html = "<tr></td>\n";
442                 $html .= "<label for=\"{$row->_attributes['id']}\">\n<span class=\"field_text\">{$row->_label}</span>\n";
443                 $html .= $this->_render_select($row);
444                 $html .= "</label>\n";
445                 $html .= "</td></tr>\n";
446
447                 echo $html;
448
449                 $this->_render_header();
450             }
451
452             if (is_a($row, 'HTML_QuickForm_group'))
453             {
454                 $html = '';
455
456                 if ($row->_name == 'form_toolbar')
457                 {
458                     $html .= "<tr><td class=\"privilege_row\">\n";
459                     foreach ($row->_elements as $k => $element)
460                     {
461                         if (is_a($element, 'HTML_QuickForm_submit'))
462                         {
463                             $html .= $this->_render_button($element);
464                         }
465                         $html .= $row->_separator;
466                     }
467                     $html .= "</td></tr>\n";
468
469                     echo $html;
470                     continue;
471                 }
472
473                 $label = $this->_render_row_label($row->_name);
474                 $html .= $label;
475
476                 foreach ($row->_elements as $k => $element)
477                 {
478                     if (is_a($element, 'HTML_QuickForm_select'))
479                     {
480                         $html .= $this->_render_select($element);
481                     }
482                     if (is_a($element, 'HTML_QuickForm_static'))
483                     {
484                         if (strpos($element->_attributes['name'], 'holder_start') !== false)
485                         {
486                             $html .= '<td align="center">';
487                         }
488
489                         $html .= $this->_render_static($element);
490                         if (strpos($element->_attributes['name'], 'initscripts') !== false)
491                         {
492                             $html .= '</td>';
493                         }
494                     }
495
496                 }
497
498                 if ($i == $priv_item_cnt+1)
499                 {
500                     $html .= "</tr>\n";
501                 }
502
503                 echo $html;
504             }
505         }
506
507         $table_end = '</table>';
508         echo $table_end;
509
510         echo "<input type=\"hidden\" name=\"\" value=\"\" id=\"submit_action\"/>\n";
511
512         echo "</form>\n";
513     }
514
515     function _render_select