Completed
Push — master ( 10885e...e41e62 )
by Andreas
13:56
created

midcom_services_toolbars::get_node_toolbar()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 1
b 0
f 0
1
<?php
2
/**
3
 * @package midcom.services
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
/**
10
 * On-site toolbar service.
11
 *
12
 * This service manages the toolbars used for the on-site administration system.
13
 * For each context, it provides the following set of toolbars:
14
 *
15
 * 1. The <i>Node</i> toolbar is applicable to the current
16
 *    node, which is usually a topic. MidCOM places the topic management operations
17
 *    into this toolbar, where applicable.
18
 *
19
 * 2. The <i>View</i> toolbar is applicable to the specific view ("url"). Usually
20
 *    this maps to a single displayed object (see also the bind_to_object() member
21
 *    function). MidCOM places the object-specific management operations (like
22
 *    Metadata controls) into this toolbar, if it is bound to an object. Otherwise,
23
 *    this toolbar is not touched by MidCOM.
24
 *
25
 * It is important to understand that the default toolbars made available through this
26
 * service are completely specific to a given request context. If you have a dynamic_load
27
 * running on a given site, it will have its own set of toolbars for each instance.
28
 *
29
 * In addition, components may retrieve a third kind of toolbars, which are not under
30
 * the general control of MidCOM, the <i>Object</i> toolbars. They apply to a single
31
 * database object (like a bound <i>View</i> toolbar). The usage of this kind of
32
 * toolbars is completely component-specific.
33
 *
34
 * <b>Implementation notes</b>
35
 *
36
 * It has yet to prove if the toolbar system is needed for a dynamic_load environments.
37
 * The main reason for this is that dl'ed stuff is often quite tight in space and thus cannot
38
 * display any toolbars in a sane way. Usually, the administrative tasks will be bound to the
39
 * main request.
40
 *
41
 * This could be different for portal applications, which display several components on the
42
 * welcome page, each with its own management options.
43
 *
44
 * <b>Configuration</b>
45
 * See midcom_config for configuration options.
46
 *
47
 * @package midcom.services
48
 */
49
class midcom_services_toolbars
50
{
51
    /**
52
     * The toolbars currently available.
53
     *
54
     * This array is indexed by context id; each value consists of a flat array
55
     * of two toolbars, the first object being the Node toolbar, the second
56
     * View toolbar. The toolbars are created on-demand.
57
     *
58
     * @var array
59
     */
60
    private $_toolbars = [];
61
62
    /**
63
     * Whether we're in centralized mode, i.e. centralized toolbar has been shown
64
     *
65
     * @var boolean
66
     */
67
    private $_centralized_mode = false;
68
69
    public function get_class_magic_default_privileges()
70
    {
71
        return [
72
            'EVERYONE' => [],
73
            'ANONYMOUS' => [],
74
            'USERS' => []
75
        ];
76
    }
77
78
    /**
79
     * Returns the host toolbar of the current context.
80
     * The toolbar will be created if this is the first request.
81
     *
82
     * @return midcom_helper_toolbar_host
83
     */
84
    function get_host_toolbar()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
85
    {
86
        return $this->_get_toolbar(MIDCOM_TOOLBAR_HOST);
87
    }
88
89
    /**
90
     * Returns the node toolbar of the current context.
91
     * The toolbar will be created if this is the first request.
92
     *
93
     * @return midcom_helper_toolbar_node
94
     */
95 338
    public function get_node_toolbar()
96
    {
97 338
        return $this->_get_toolbar(MIDCOM_TOOLBAR_NODE);
98
    }
99
100
    /**
101
     * Returns the view toolbar of the current context.
102
     * The toolbar will be created if this is the first request.
103
     *
104
     * @return midcom_helper_toolbar_view
105
     */
106 338
    public function get_view_toolbar()
107
    {
108 338
        return $this->_get_toolbar(MIDCOM_TOOLBAR_VIEW);
109
    }
110
111
    /**
112
     * Returns the help toolbar of the current context.
113
     * The toolbar will be created if this is the first request.
114
     *
115
     * @return midcom_helper_toolbar_help
116
     */
117 1
    public function get_help_toolbar()
118
    {
119 1
        return $this->_get_toolbar(MIDCOM_TOOLBAR_HELP);
120
    }
121
122
    /**
123
     * @param string $identifier
124
     * @return midcom_helper_toolbar
125
     */
126 338
    private function _get_toolbar($identifier)
127
    {
128 338
        $context = midcom_core_context::get();
129
130 338
        if (!array_key_exists($context->id, $this->_toolbars)) {
131 338
            $this->_toolbars[$context->id] = [
132
                MIDCOM_TOOLBAR_HELP => null,
133
                MIDCOM_TOOLBAR_HOST => null,
134
                MIDCOM_TOOLBAR_NODE => null,
135
                MIDCOM_TOOLBAR_VIEW => null
136
            ];
137
        }
138 338
        if (!isset($this->_toolbars[$context->id][$identifier])) {
139
            switch ($identifier) {
140 338
                case MIDCOM_TOOLBAR_HELP:
141 1
                    $component = $context->get_key(MIDCOM_CONTEXT_COMPONENT);
142 1
                    $toolbar = new midcom_helper_toolbar_help($component);
143 1
                    break;
144 338
                case MIDCOM_TOOLBAR_HOST:
145
                    $toolbar = new midcom_helper_toolbar_host;
146
                    break;
147 338
                case MIDCOM_TOOLBAR_NODE:
148 338
                    $topic = $context->get_key(MIDCOM_CONTEXT_CONTENTTOPIC);
149 338
                    $toolbar = new midcom_helper_toolbar_node($topic);
0 ignored issues
show
Bug introduced by
It seems like $topic can also be of type false; however, parameter $topic of midcom_helper_toolbar_node::__construct() does only seem to accept midcom_db_topic, maybe add an additional type check? ( Ignorable by Annotation )

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

149
                    $toolbar = new midcom_helper_toolbar_node(/** @scrutinizer ignore-type */ $topic);
Loading history...
150 338
                    break;
151 338
                case MIDCOM_TOOLBAR_VIEW:
152 338
                    $toolbar = new midcom_helper_toolbar_view;
153 338
                    break;
154
                default:
155 9
                    $toolbar = new midcom_helper_toolbar;
156 9
                    break;
157
            }
158 338
            $this->_toolbars[$context->id][$identifier] = $toolbar;
159
        }
160 338
        return $this->_toolbars[$context->id][$identifier];
161
    }
162
163
    /**
164
     * Add a toolbar
165
     *
166
     * @param string $identifier
167
     * @param midcom_helper_toolbar $toolbar
168
     */
169 7
    function add_toolbar($identifier, midcom_helper_toolbar $toolbar)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
170
    {
171 7
        $context_id = midcom_core_context::get()->id;
172 7
        $this->_toolbars[$context_id][$identifier] = $toolbar;
173 7
    }
174
175
    /**
176
     * Binds the a toolbar to a DBA object. This will append a number of globally available
177
     * toolbar options. For example, expect Metadata- and Version Control-related options
178
     * to be added.
179
     *
180
     * This call is available through convenience functions throughout the framework: The
181
     * toolbar main class has a mapping for it (midcom_helper_toolbar::bind_to($object))
182
     * and object toolbars created by this service will automatically be bound to the
183
     * specified object.
184
     *
185
     * Repeated bind calls are intercepted, you can only bind a toolbar to a single object.
186
     *
187
     * @see midcom_helper_toolbar::bind_to()
188
     * @see create_object_toolbar()
189
     * @param midcom_helper_toolbar $toolbar
190
     */
191 52
    public function bind_toolbar_to_object(midcom_helper_toolbar $toolbar, $object)
192
    {
193 52
        if (!midcom_core_context::get()->get_key(MIDCOM_CONTEXT_ANCHORPREFIX)) {
194
            debug_add("Toolbar for object {$object->guid} was called before topic prefix was available, skipping global items.", MIDCOM_LOG_WARN);
195
            return;
196
        }
197 52
        if (array_key_exists('midcom_services_toolbars_bound_to_object', $toolbar->customdata)) {
198
            // We already processed this toolbar, skipping further adds.
199 1
            return;
200
        }
201 52
        $toolbar->customdata['midcom_services_toolbars_bound_to_object'] = true;
202
203 52
        $reflector = new midcom_helper_reflector($object);
204 52
        $toolbar->set_label($reflector->get_class_label());
205
206 52
        $toolbar->bind_object($object);
0 ignored issues
show
Bug introduced by
The method bind_object() does not exist on midcom_helper_toolbar. It seems like you code against a sub-type of midcom_helper_toolbar such as midcom_helper_toolbar_view. ( Ignorable by Annotation )

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

206
        $toolbar->/** @scrutinizer ignore-call */ 
207
                  bind_object($object);
Loading history...
207 52
    }
208
209
    /**
210
     * Renders the specified toolbar for the current context.
211
     *
212
     * If the toolbar is undefined, an empty string is returned.
213
     *
214
     * @param int $toolbar_identifier The toolbar identifier constant (one of
215
     *     MIDCOM_TOOLBAR_NODE or MIDCOM_TOOLBAR_VIEW etc.)
216
     * @return string The rendered toolbar
217
     * @see midcom_helper_toolbar::render()
218
     */
219 19
    function _render_toolbar($toolbar_identifier)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
220
    {
221 19
        $this->add_head_elements();
222 19
        return $this->_get_toolbar($toolbar_identifier)->render();
223
    }
224
225
    /**
226
     * Renders the node toolbar for the current context. If the toolbar is undefined,
227
     * an empty string is returned. If you want to show the toolbar directly, look for
228
     * the show_xxx_toolbar methods.
229
     *
230
     * @return string The rendered toolbar
231
     * @see midcom_helper_toolbar::render()
232
     */
233
    public function render_node_toolbar()
234
    {
235
        return $this->_render_toolbar(MIDCOM_TOOLBAR_NODE);
236
    }
237
238
    /**
239
     * Renders the view toolbar for the current context. If the toolbar is undefined,
240
     * an empty string is returned. If you want to show the toolbar directly, look for
241
     * the show_xxx_toolbar methods.
242
     *
243
     * @return string The rendered toolbar
244
     * @see midcom_helper_toolbar::render()
245
     */
246 19
    public function render_view_toolbar()
247
    {
248 19
        return $this->_render_toolbar(MIDCOM_TOOLBAR_VIEW);
249
    }
250
251
    /**
252
     * Renders the host toolbar for the current context. If the toolbar is undefined,
253
     * an empty string is returned. If you want to show the toolbar directly, look for
254
     * the show_xxx_toolbar methods.
255
     *
256
     * @return string The rendered toolbar
257
     * @see midcom_helper_toolbar::render()
258
     */
259
    public function render_host_toolbar()
260
    {
261
        return $this->_render_toolbar(MIDCOM_TOOLBAR_HOST);
262
    }
263
264
    /**
265
     * Renders the help toolbar for the current context. If the toolbar is undefined,
266
     * an empty string is returned. If you want to show the toolbar directly, look for
267
     * the show_xxx_toolbar methods.
268
     *
269
     * @return string The rendered toolbar
270
     * @see midcom_helper_toolbar::render()
271
     */
272
    public function render_help_toolbar()
273
    {
274
        return $this->_render_toolbar(MIDCOM_TOOLBAR_HELP);
275
    }
276
277
    /**
278
     * Displays the node toolbar for the current context. If the toolbar is undefined,
279
     * an empty string is returned.
280
     *
281
     * @see midcom_helper_toolbar::render()
282
     */
283
    function show_node_toolbar()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
284
    {
285
        if (!$this->_centralized_mode) {
286
            echo $this->render_node_toolbar();
287
        }
288
    }
289
290
    /**
291
     * Displays the host toolbar for the current context. If the toolbar is undefined,
292
     * an empty string is returned.
293
     *
294
     * @see midcom_helper_toolbar::render()
295
     */
296
    function show_host_toolbar()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
297
    {
298
        if (!$this->_centralized_mode) {
299
            echo $this->render_host_toolbar();
300
        }
301
    }
302
303
    /**
304
     * Displays the view toolbar for the current context. If the toolbar is undefined,
305
     * an empty string is returned.
306
     *
307
     * @see midcom_helper_toolbar::render()
308
     */
309 10
    public function show_view_toolbar()
310
    {
311 10
        if (!$this->_centralized_mode) {
312 10
            echo $this->render_view_toolbar();
313
        }
314 10
    }
315
316
    /**
317
     * Displays the help toolbar for the current context. If the toolbar is undefined,
318
     * an empty string is returned.
319
     *
320
     * @see midcom_helper_toolbar::render()
321
     */
322
    function show_help_toolbar()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
323
    {
324
        if (!$this->_centralized_mode) {
325
            echo $this->render_help_toolbar();
326
        }
327
    }
328
329 19
    private function add_head_elements($centralized = false)
330
    {
331 19
        if (   !midcom::get()->auth->user
332 14
            || !midcom::get()->config->get('toolbars_enable_centralized')
333 19
            || !midcom::get()->auth->can_user_do('midcom:centralized_toolbar', null, __CLASS__)) {
334 19
            return false;
335
        }
336
        if ($centralized && midcom::get()->auth->can_user_do('midcom:ajax', null, $this)) {
0 ignored issues
show
Bug introduced by
$this of type midcom_services_toolbars is incompatible with the type string expected by parameter $class of midcom_services_auth::can_user_do(). ( Ignorable by Annotation )

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

336
        if ($centralized && midcom::get()->auth->can_user_do('midcom:ajax', null, /** @scrutinizer ignore-type */ $this)) {
Loading history...
337
            $this->_centralized_mode = true;
338
            static $run = false;
339
            if (!$run) {
340
                midcom::get()->head->enable_jquery_ui(['mouse', 'draggable']);
341
                midcom::get()->head->add_jsfile(MIDCOM_STATIC_URL . '/midcom.services.toolbars/jquery.midcom_services_toolbars.js');
342
                $script = "jQuery('body div.midcom_services_toolbars_fancy').midcom_services_toolbar();";
343
                midcom::get()->head->add_jquery_state_script($script);
344
                midcom::get()->head->add_stylesheet(MIDCOM_STATIC_URL . '/midcom.services.toolbars/fancy.css', 'screen');
345
                $run = true;
346
            }
347
        } else {
348
            $path = midcom::get()->config->get('toolbars_simple_css_path', MIDCOM_STATIC_URL . "/midcom.services.toolbars/simple.css");
349
            midcom::get()->head->add_stylesheet($path, 'screen');
350
        }
351
        midcom::get()->head->add_stylesheet(MIDCOM_STATIC_URL . '/stock-icons/font-awesome-4.7.0/css/font-awesome.min.css');
352
        return true;
353
    }
354
355
    /**
356
     * Displays the combined MidCOM toolbar system for the current context.
357
     *
358
     * @see midcom_helper_toolbar::render()
359
     */
360 9
    public function show()
361
    {
362 9
        if (!$this->add_head_elements(true)) {
363 9
            return;
364
        }
365
        $context_id = midcom_core_context::get()->id;
366
367
        $enable_drag = false;
368
        $toolbar_style = "";
369
        $toolbar_class = "midcom_services_toolbars_simple";
370
371
        if (midcom::get()->auth->can_user_do('midcom:ajax', null, midcom_services_toolbars::class)) {
372
            $enable_drag = true;
373
            $toolbar_class = "midcom_services_toolbars_fancy";
374
            $toolbar_style = "display: none;";
375
        }
376
377
        echo "<div class=\"{$toolbar_class}\" style=\"{$toolbar_style}\">\n";
378
        echo "    <div class=\"minimizer\">\n";
379
        echo "    </div>\n";
380
        echo "    <div class=\"items\">\n";
381
382
        foreach (array_reverse($this->_toolbars[$context_id], true) as $identifier => $toolbar) {
383
            if ($toolbar === null) {
384
                $toolbar = $this->_get_toolbar($identifier);
385
            }
386
            if (!$toolbar->is_rendered()) {
387
                $this->show_toolbar($identifier, $toolbar);
388
            }
389
        }
390
        echo "</div>\n";
391
392
        if ($enable_drag) {
393
            echo "     <div class=\"dragbar\"></div>\n";
394
        }
395
        echo "</div>\n";
396
    }
397
398
    private function show_toolbar($identifier, midcom_helper_toolbar $toolbar)
399
    {
400
        if (empty($toolbar->items)) {
401
            return;
402
        }
403
        switch ($identifier) {
404
            case MIDCOM_TOOLBAR_VIEW:
405
                $id = $class = 'page';
406
                break;
407
            case MIDCOM_TOOLBAR_NODE:
408
                $id = $class = 'folder';
409
                break;
410
            case MIDCOM_TOOLBAR_HOST:
411
                $id = $class = 'host';
412
                break;
413
            case MIDCOM_TOOLBAR_HELP:
414
                $id = $class = 'help';
415
                break;
416
            default:
417
                $id = 'custom-' . $identifier;
418
                $class = 'custom';
419
                break;
420
        }
421
        echo "        <div id=\"midcom_services_toolbars_topic-{$id}\" class=\"item\">\n";
422
        echo "            <span class=\"midcom_services_toolbars_topic_title {$class}\">" . $toolbar->get_label() . "</span>\n";
423
        echo $toolbar->render();
424
        echo "        </div>\n";
425
    }
426
}
427