Completed
Push — master ( a30dbc...5978b6 )
by Andreas
17:30
created

midcom_services_toolbars::show_toolbar()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 27
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
cc 6
eloc 23
nc 6
nop 2
dl 0
loc 27
ccs 0
cts 22
cp 0
crap 42
rs 8.9297
c 0
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
     * midcom.services.toolbars has two modes, it can either display one centralized toolbar
64
     * for authenticated users, or the node and view toolbars separately for others. This
65
     * property controls whether centralized mode is enabled.
66
     *
67
     * @var boolean
68
     */
69
    private $_enable_centralized = false;
70
71
    /**
72
     * Whether we're in centralized mode, i.e. centralized toolbar has been shown
73
     *
74
     * @var boolean
75
     */
76
    private $_centralized_mode = false;
77
78
    /**
79
     * Simple constructor
80
     */
81 1
    public function __construct()
82
    {
83 1
        static $initialized = false;
84 1
        if ($initialized) {
85
            // This is auth service looping because it instantiates classes for magic privileges!
86
            return;
87
        }
88
89 1
        $initialized = true;
90 1
        if (   !midcom::get()->auth->user
91
            || !midcom::get()->config->get('toolbars_enable_centralized')
92 1
            || !midcom::get()->auth->can_user_do('midcom:centralized_toolbar', null, __CLASS__)) {
93 1
            return;
94
        }
95
96
        if (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

96
        if (midcom::get()->auth->can_user_do('midcom:ajax', null, /** @scrutinizer ignore-type */ $this)) {
Loading history...
97
            midcom::get()->head->enable_jquery_ui(['mouse', 'draggable']);
98
99
            midcom::get()->head->add_jsfile(MIDCOM_STATIC_URL . '/midcom.services.toolbars/jquery.midcom_services_toolbars.js');
100
101
            midcom::get()->head->add_stylesheet(MIDCOM_STATIC_URL . '/midcom.services.toolbars/fancy.css', 'screen');
102
103
            $script = "jQuery('body div.midcom_services_toolbars_fancy').midcom_services_toolbar();";
104
            midcom::get()->head->add_jquery_state_script($script);
105
        } else {
106
            $path = midcom::get()->config->get('toolbars_simple_css_path', MIDCOM_STATIC_URL . "/midcom.services.toolbars/simple.css");
107
            midcom::get()->head->add_stylesheet($path, 'screen');
108
        }
109
        midcom::get()->head->add_stylesheet(MIDCOM_STATIC_URL . '/stock-icons/font-awesome-4.7.0/css/font-awesome.min.css');
110
111
        // We've included CSS and JS, path is clear for centralized mode
112
        $this->_enable_centralized = true;
113
    }
114
115
    public function get_class_magic_default_privileges()
116
    {
117
        return [
118
            'EVERYONE' => [],
119
            'ANONYMOUS' => [],
120
            'USERS' => []
121
        ];
122
    }
123
124
    /**
125
     * Returns the host toolbar of the current context.
126
     * The toolbar will be created if this is the first request.
127
     *
128
     * @return midcom_helper_toolbar_host
129
     */
130
    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...
131
    {
132
        return $this->_get_toolbar(MIDCOM_TOOLBAR_HOST);
133
    }
134
135
    /**
136
     * Returns the node toolbar of the current context.
137
     * The toolbar will be created if this is the first request.
138
     *
139
     * @return midcom_helper_toolbar_node
140
     */
141 338
    public function get_node_toolbar()
142
    {
143 338
        return $this->_get_toolbar(MIDCOM_TOOLBAR_NODE);
144
    }
145
146
    /**
147
     * Returns the view toolbar of the current context.
148
     * The toolbar will be created if this is the first request.
149
     *
150
     * @return midcom_helper_toolbar_view
151
     */
152 338
    public function get_view_toolbar()
153
    {
154 338
        return $this->_get_toolbar(MIDCOM_TOOLBAR_VIEW);
155
    }
156
157
    /**
158
     * Returns the help toolbar of the current context.
159
     * The toolbar will be created if this is the first request.
160
     *
161
     * @return midcom_helper_toolbar_help
162
     */
163 1
    public function get_help_toolbar()
164
    {
165 1
        return $this->_get_toolbar(MIDCOM_TOOLBAR_HELP);
166
    }
167
168
    /**
169
     * @param string $identifier
170
     * @return midcom_helper_toolbar
171
     */
172 338
    private function _get_toolbar($identifier)
173
    {
174 338
        $context = midcom_core_context::get();
175
176 338
        if (!array_key_exists($context->id, $this->_toolbars)) {
177 338
            $this->_toolbars[$context->id] = [
178
                MIDCOM_TOOLBAR_HELP => null,
179
                MIDCOM_TOOLBAR_HOST => null,
180
                MIDCOM_TOOLBAR_NODE => null,
181
                MIDCOM_TOOLBAR_VIEW => null
182
            ];
183
        }
184 338
        if (!isset($this->_toolbars[$context->id][$identifier])) {
185
            switch ($identifier) {
186 338
                case MIDCOM_TOOLBAR_HELP:
187 9
                    $component = $context->get_key(MIDCOM_CONTEXT_COMPONENT);
188 9
                    $toolbar = new midcom_helper_toolbar_help($component);
189 9
                    break;
190 338
                case MIDCOM_TOOLBAR_HOST:
191 9
                    $toolbar = new midcom_helper_toolbar_host;
192 9
                    break;
193 338
                case MIDCOM_TOOLBAR_NODE:
194 338
                    $topic = $context->get_key(MIDCOM_CONTEXT_CONTENTTOPIC);
195 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

195
                    $toolbar = new midcom_helper_toolbar_node(/** @scrutinizer ignore-type */ $topic);
Loading history...
196 338
                    break;
197 338
                case MIDCOM_TOOLBAR_VIEW:
198 338
                    $toolbar = new midcom_helper_toolbar_view;
199 338
                    break;
200
                default:
201 9
                    $toolbar = new midcom_helper_toolbar;
202 9
                    break;
203
            }
204 338
            $this->_toolbars[$context->id][$identifier] = $toolbar;
205
        }
206 338
        return $this->_toolbars[$context->id][$identifier];
207
    }
208
209
    /**
210
     * Add a toolbar
211
     *
212
     * @param string $identifier
213
     * @param midcom_helper_toolbar $toolbar
214
     */
215 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...
216
    {
217 7
        $context_id = midcom_core_context::get()->id;
218 7
        $this->_toolbars[$context_id][$identifier] = $toolbar;
219 7
    }
220
221
    /**
222
     * Binds the a toolbar to a DBA object. This will append a number of globally available
223
     * toolbar options. For example, expect Metadata- and Version Control-related options
224
     * to be added.
225
     *
226
     * This call is available through convenience functions throughout the framework: The
227
     * toolbar main class has a mapping for it (midcom_helper_toolbar::bind_to($object))
228
     * and object toolbars created by this service will automatically be bound to the
229
     * specified object.
230
     *
231
     * Repeated bind calls are intercepted, you can only bind a toolbar to a single object.
232
     *
233
     * @see midcom_helper_toolbar::bind_to()
234
     * @see create_object_toolbar()
235
     * @param midcom_helper_toolbar $toolbar
236
     */
237 52
    public function bind_toolbar_to_object(midcom_helper_toolbar $toolbar, $object)
238
    {
239 52
        if (!midcom_core_context::get()->get_key(MIDCOM_CONTEXT_ANCHORPREFIX)) {
240
            debug_add("Toolbar for object {$object->guid} was called before topic prefix was available, skipping global items.", MIDCOM_LOG_WARN);
241
            return;
242
        }
243 52
        if (array_key_exists('midcom_services_toolbars_bound_to_object', $toolbar->customdata)) {
244
            // We already processed this toolbar, skipping further adds.
245 1
            return;
246
        }
247 52
        $toolbar->customdata['midcom_services_toolbars_bound_to_object'] = true;
248
249 52
        $reflector = new midcom_helper_reflector($object);
250 52
        $toolbar->set_label($reflector->get_class_label());
251
252 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

252
        $toolbar->/** @scrutinizer ignore-call */ 
253
                  bind_object($object);
Loading history...
253 52
    }
254
255
    /**
256
     * Renders the specified toolbar for the current context.
257
     *
258
     * If the toolbar is undefined, an empty string is returned.
259
     *
260
     * @param int $toolbar_identifier The toolbar identifier constant (one of
261
     *     MIDCOM_TOOLBAR_NODE or MIDCOM_TOOLBAR_VIEW etc.)
262
     * @return string The rendered toolbar
263
     * @see midcom_helper_toolbar::render()
264
     */
265 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...
266
    {
267 19
        return $this->_get_toolbar($toolbar_identifier)->render();
268
    }
269
270
    /**
271
     * Renders the node toolbar for the current context. If the toolbar is undefined,
272
     * an empty string is returned. If you want to show the toolbar directly, look for
273
     * the show_xxx_toolbar methods.
274
     *
275
     * @return string The rendered toolbar
276
     * @see midcom_helper_toolbar::render()
277
     */
278 9
    public function render_node_toolbar()
279
    {
280 9
        return $this->_render_toolbar(MIDCOM_TOOLBAR_NODE);
281
    }
282
283
    /**
284
     * Renders the view toolbar for the current context. If the toolbar is undefined,
285
     * an empty string is returned. If you want to show the toolbar directly, look for
286
     * the show_xxx_toolbar methods.
287
     *
288
     * @return string The rendered toolbar
289
     * @see midcom_helper_toolbar::render()
290
     */
291 19
    public function render_view_toolbar()
292
    {
293 19
        return $this->_render_toolbar(MIDCOM_TOOLBAR_VIEW);
294
    }
295
296
    /**
297
     * Renders the host toolbar for the current context. If the toolbar is undefined,
298
     * an empty string is returned. If you want to show the toolbar directly, look for
299
     * the show_xxx_toolbar methods.
300
     *
301
     * @return string The rendered toolbar
302
     * @see midcom_helper_toolbar::render()
303
     */
304 9
    public function render_host_toolbar()
305
    {
306 9
        return $this->_render_toolbar(MIDCOM_TOOLBAR_HOST);
307
    }
308
309
    /**
310
     * Renders the help toolbar for the current context. If the toolbar is undefined,
311
     * an empty string is returned. If you want to show the toolbar directly, look for
312
     * the show_xxx_toolbar methods.
313
     *
314
     * @return string The rendered toolbar
315
     * @see midcom_helper_toolbar::render()
316
     */
317 9
    public function render_help_toolbar()
318
    {
319 9
        return $this->_render_toolbar(MIDCOM_TOOLBAR_HELP);
320
    }
321
322
    /**
323
     * Displays the node toolbar for the current context. If the toolbar is undefined,
324
     * an empty string is returned.
325
     *
326
     * @see midcom_helper_toolbar::render()
327
     */
328
    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...
329
    {
330
        if (!$this->_centralized_mode) {
331
            echo $this->render_node_toolbar();
332
        }
333
    }
334
335
    /**
336
     * Displays the host toolbar for the current context. If the toolbar is undefined,
337
     * an empty string is returned.
338
     *
339
     * @see midcom_helper_toolbar::render()
340
     */
341
    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...
342
    {
343
        if (!$this->_centralized_mode) {
344
            echo $this->render_host_toolbar();
345
        }
346
    }
347
348
    /**
349
     * Displays the view toolbar for the current context. If the toolbar is undefined,
350
     * an empty string is returned.
351
     *
352
     * @see midcom_helper_toolbar::render()
353
     */
354 10
    public function show_view_toolbar()
355
    {
356 10
        if (!$this->_centralized_mode) {
357 10
            echo $this->render_view_toolbar();
358
        }
359 10
    }
360
361
    /**
362
     * Displays the help toolbar for the current context. If the toolbar is undefined,
363
     * an empty string is returned.
364
     *
365
     * @see midcom_helper_toolbar::render()
366
     */
367
    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...
368
    {
369
        if (!$this->_centralized_mode) {
370
            echo $this->render_help_toolbar();
371
        }
372
    }
373
374
    /**
375
     * Displays the combined MidCOM toolbar system for the current context.
376
     *
377
     * @see midcom_helper_toolbar::render()
378
     */
379
    public function show()
380
    {
381
        if (!$this->_enable_centralized) {
382
            return;
383
        }
384
385
        $context_id = midcom_core_context::get()->id;
386
        $this->_centralized_mode = true;
387
388
        $enable_drag = false;
389
        $toolbar_style = "";
390
        $toolbar_class = "midcom_services_toolbars_simple";
391
392
        if (midcom::get()->auth->can_user_do('midcom:ajax', null, midcom_services_toolbars::class)) {
393
            $enable_drag = true;
394
            $toolbar_class = "midcom_services_toolbars_fancy";
395
            $toolbar_style = "display: none;";
396
        }
397
398
        echo "<div class=\"{$toolbar_class}\" style=\"{$toolbar_style}\">\n";
399
        echo "    <div class=\"minimizer\">\n";
400
        echo "    </div>\n";
401
        echo "    <div class=\"items\">\n";
402
403
        foreach (array_reverse($this->_toolbars[$context_id], true) as $identifier => $toolbar) {
404
            if ($toolbar === null) {
405
                $toolbar = $this->_get_toolbar($identifier);
406
            }
407
            $this->show_toolbar($identifier, $toolbar);
408
        }
409
        echo "</div>\n";
410
411
        if ($enable_drag) {
412
            echo "     <div class=\"dragbar\"></div>\n";
413
        }
414
        echo "</div>\n";
415
    }
416
417
    private function show_toolbar($identifier, midcom_helper_toolbar $toolbar)
418
    {
419
        if (empty($toolbar->items)) {
420
            return;
421
        }
422
        switch ($identifier) {
423
            case MIDCOM_TOOLBAR_VIEW:
424
                $id = $class = 'page';
425
                break;
426
            case MIDCOM_TOOLBAR_NODE:
427
                $id = $class = 'folder';
428
                break;
429
            case MIDCOM_TOOLBAR_HOST:
430
                $id = $class = 'host';
431
                break;
432
            case MIDCOM_TOOLBAR_HELP:
433
                $id = $class = 'help';
434
                break;
435
            default:
436
                $id = 'custom-' . $identifier;
437
                $class = 'custom';
438
                break;
439
        }
440
        echo "        <div id=\"midcom_services_toolbars_topic-{$id}\" class=\"item\">\n";
441
        echo "            <span class=\"midcom_services_toolbars_topic_title {$class}\">" . $toolbar->get_label() . "</span>\n";
442
        echo $toolbar->render();
443
        echo "        </div>\n";
444
    }
445
}
446