Completed
Push — master ( a15f92...5650a5 )
by Andreas
18:52
created

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