Completed
Push — master ( 8849ee...a1b70f )
by Andreas
24:35
created

midcom_services_toolbars::_render_toolbar()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 9
ccs 5
cts 5
cp 1
crap 2
rs 10
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
            $component = $context->get_key(MIDCOM_CONTEXT_COMPONENT);
178 338
            $topic = $context->get_key(MIDCOM_CONTEXT_CONTENTTOPIC);
179
180 338
            $this->_toolbars[$context->id][MIDCOM_TOOLBAR_HELP] = new midcom_helper_toolbar_help($component);
181 338
            $this->_toolbars[$context->id][MIDCOM_TOOLBAR_HOST] = new midcom_helper_toolbar_host;
182 338
            $this->_toolbars[$context->id][MIDCOM_TOOLBAR_NODE] = 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

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

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