Completed
Push — master ( 8bc3d2...9a12dd )
by Andreas
19:28
created

midcom_services_toolbars::get_host_toolbar()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
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
    function get_host_toolbar() : midcom_helper_toolbar_host
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...
83
    {
84
        return $this->_get_toolbar(MIDCOM_TOOLBAR_HOST);
85
    }
86
87
    /**
88
     * Returns the node toolbar of the current context.
89
     * The toolbar will be created if this is the first request.
90
     */
91 338
    public function get_node_toolbar() : midcom_helper_toolbar_node
92
    {
93 338
        return $this->_get_toolbar(MIDCOM_TOOLBAR_NODE);
94
    }
95
96
    /**
97
     * Returns the view toolbar of the current context.
98
     * The toolbar will be created if this is the first request.
99
     */
100 338
    public function get_view_toolbar() : midcom_helper_toolbar_view
101
    {
102 338
        return $this->_get_toolbar(MIDCOM_TOOLBAR_VIEW);
103
    }
104
105
    /**
106
     * Returns the help toolbar of the current context.
107
     * The toolbar will be created if this is the first request.
108
     */
109 1
    public function get_help_toolbar() : midcom_helper_toolbar_help
110
    {
111 1
        return $this->_get_toolbar(MIDCOM_TOOLBAR_HELP);
112
    }
113
114
    /**
115
     * @param string $identifier
116
     */
117 338
    private function _get_toolbar($identifier) : midcom_helper_toolbar
118
    {
119 338
        $context = midcom_core_context::get();
120
121 338
        if (!array_key_exists($context->id, $this->_toolbars)) {
122 338
            $this->_toolbars[$context->id] = [
123
                MIDCOM_TOOLBAR_HELP => null,
124
                MIDCOM_TOOLBAR_HOST => null,
125
                MIDCOM_TOOLBAR_NODE => null,
126
                MIDCOM_TOOLBAR_VIEW => null
127
            ];
128
        }
129 338
        if (!isset($this->_toolbars[$context->id][$identifier])) {
130 338
            switch ($identifier) {
131
                case MIDCOM_TOOLBAR_HELP:
132 1
                    $component = $context->get_key(MIDCOM_CONTEXT_COMPONENT);
133 1
                    $toolbar = new midcom_helper_toolbar_help($component);
134 1
                    break;
135
                case MIDCOM_TOOLBAR_HOST:
136
                    $toolbar = new midcom_helper_toolbar_host;
137
                    break;
138
                case MIDCOM_TOOLBAR_NODE:
139 338
                    $topic = $context->get_key(MIDCOM_CONTEXT_CONTENTTOPIC);
140 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

140
                    $toolbar = new midcom_helper_toolbar_node(/** @scrutinizer ignore-type */ $topic);
Loading history...
141 338
                    break;
142
                case MIDCOM_TOOLBAR_VIEW:
143 338
                    $toolbar = new midcom_helper_toolbar_view;
144 338
                    break;
145
                default:
146 9
                    $toolbar = new midcom_helper_toolbar;
147 9
                    break;
148
            }
149 338
            $this->_toolbars[$context->id][$identifier] = $toolbar;
150
        }
151 338
        return $this->_toolbars[$context->id][$identifier];
152
    }
153
154
    /**
155
     * Add a toolbar
156
     *
157
     * @param string $identifier
158
     * @param midcom_helper_toolbar $toolbar
159
     */
160 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...
161
    {
162 7
        $context_id = midcom_core_context::get()->id;
163 7
        $this->_toolbars[$context_id][$identifier] = $toolbar;
164 7
    }
165
166
    /**
167
     * Binds the a toolbar to a DBA object. This will append a number of globally available
168
     * toolbar options. For example, expect Metadata- and Version Control-related options
169
     * to be added.
170
     *
171
     * This call is available through convenience functions throughout the framework: The
172
     * toolbar main class has a mapping for it (midcom_helper_toolbar::bind_to($object))
173
     * and object toolbars created by this service will automatically be bound to the
174
     * specified object.
175
     *
176
     * Repeated bind calls are intercepted, you can only bind a toolbar to a single object.
177
     *
178
     * @see midcom_helper_toolbar::bind_to()
179
     * @see create_object_toolbar()
180
     * @param midcom_helper_toolbar $toolbar
181
     */
182 52
    public function bind_toolbar_to_object(midcom_helper_toolbar $toolbar, $object)
183
    {
184 52
        if (!midcom_core_context::get()->get_key(MIDCOM_CONTEXT_ANCHORPREFIX)) {
185
            debug_add("Toolbar for object {$object->guid} was called before topic prefix was available, skipping global items.", MIDCOM_LOG_WARN);
186
            return;
187
        }
188 52
        if (array_key_exists('midcom_services_toolbars_bound_to_object', $toolbar->customdata)) {
189
            // We already processed this toolbar, skipping further adds.
190 1
            return;
191
        }
192 52
        $toolbar->customdata['midcom_services_toolbars_bound_to_object'] = true;
193
194 52
        $reflector = new midcom_helper_reflector($object);
195 52
        $toolbar->set_label($reflector->get_class_label());
196
197 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

197
        $toolbar->/** @scrutinizer ignore-call */ 
198
                  bind_object($object);
Loading history...
198 52
    }
199
200
    /**
201
     * Renders the specified toolbar for the current context.
202
     *
203
     * If the toolbar is undefined, an empty string is returned.
204
     *
205
     * @param int $toolbar_identifier The toolbar identifier constant (one of
206
     *     MIDCOM_TOOLBAR_NODE or MIDCOM_TOOLBAR_VIEW etc.)
207
     * @see midcom_helper_toolbar::render()
208
     */
209 19
    function _render_toolbar($toolbar_identifier) : string
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...
210
    {
211 19
        $this->add_head_elements();
212 19
        return $this->_get_toolbar($toolbar_identifier)->render();
213
    }
214
215
    /**
216
     * Renders the node toolbar for the current context. If the toolbar is undefined,
217
     * an empty string is returned. If you want to show the toolbar directly, look for
218
     * the show_xxx_toolbar methods.
219
     *
220
     * @see midcom_helper_toolbar::render()
221
     */
222
    public function render_node_toolbar() : string
223
    {
224
        return $this->_render_toolbar(MIDCOM_TOOLBAR_NODE);
225
    }
226
227
    /**
228
     * Renders the view toolbar for the current context. If the toolbar is undefined,
229
     * an empty string is returned. If you want to show the toolbar directly, look for
230
     * the show_xxx_toolbar methods.
231
     *
232
     * @see midcom_helper_toolbar::render()
233
     */
234 19
    public function render_view_toolbar() : string
235
    {
236 19
        return $this->_render_toolbar(MIDCOM_TOOLBAR_VIEW);
237
    }
238
239
    /**
240
     * Renders the host toolbar for the current context. If the toolbar is undefined,
241
     * an empty string is returned. If you want to show the toolbar directly, look for
242
     * the show_xxx_toolbar methods.
243
     *
244
     * @see midcom_helper_toolbar::render()
245
     */
246
    public function render_host_toolbar() : string
247
    {
248
        return $this->_render_toolbar(MIDCOM_TOOLBAR_HOST);
249
    }
250
251
    /**
252
     * Renders the help 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
     * @see midcom_helper_toolbar::render()
257
     */
258
    public function render_help_toolbar() : string
259
    {
260
        return $this->_render_toolbar(MIDCOM_TOOLBAR_HELP);
261
    }
262
263
    /**
264
     * Displays the node toolbar for the current context. If the toolbar is undefined,
265
     * an empty string is returned.
266
     *
267
     * @see midcom_helper_toolbar::render()
268
     */
269
    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...
270
    {
271
        if (!$this->_centralized_mode) {
272
            echo $this->render_node_toolbar();
273
        }
274
    }
275
276
    /**
277
     * Displays the host toolbar for the current context. If the toolbar is undefined,
278
     * an empty string is returned.
279
     *
280
     * @see midcom_helper_toolbar::render()
281
     */
282
    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...
283
    {
284
        if (!$this->_centralized_mode) {
285
            echo $this->render_host_toolbar();
286
        }
287
    }
288
289
    /**
290
     * Displays the view toolbar for the current context. If the toolbar is undefined,
291
     * an empty string is returned.
292
     *
293
     * @see midcom_helper_toolbar::render()
294
     */
295 10
    public function show_view_toolbar()
296
    {
297 10
        if (!$this->_centralized_mode) {
298 10
            echo $this->render_view_toolbar();
299
        }
300 10
    }
301
302
    /**
303
     * Displays the help toolbar for the current context. If the toolbar is undefined,
304
     * an empty string is returned.
305
     *
306
     * @see midcom_helper_toolbar::render()
307
     */
308
    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...
309
    {
310
        if (!$this->_centralized_mode) {
311
            echo $this->render_help_toolbar();
312
        }
313
    }
314
315 19
    private function add_head_elements(bool $centralized = false) : bool
316
    {
317 19
        if (   !midcom::get()->auth->user
318 13
            || !midcom::get()->config->get('toolbars_enable_centralized')
319 19
            || !midcom::get()->auth->can_user_do('midcom:centralized_toolbar', null, __CLASS__)) {
320 19
            return false;
321
        }
322
        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

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