Passed
Push — master ( 9df40e...8d71ac )
by Andreas
23:46
created

midcom_services_toolbars::show_view_toolbar()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 2
nc 2
nop 0
dl 0
loc 4
ccs 3
cts 3
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
     * 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 341
    public function get_node_toolbar() : midcom_helper_toolbar_node
92
    {
93 341
        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 341
    public function get_view_toolbar() : midcom_helper_toolbar_view
101
    {
102 341
        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 341
    private function _get_toolbar(string $identifier) : midcom_helper_toolbar
115
    {
116 341
        $context = midcom_core_context::get();
117
118 341
        if (!array_key_exists($context->id, $this->_toolbars)) {
119 341
            $this->_toolbars[$context->id] = [
120
                MIDCOM_TOOLBAR_HELP => null,
121
                MIDCOM_TOOLBAR_HOST => null,
122
                MIDCOM_TOOLBAR_NODE => null,
123
                MIDCOM_TOOLBAR_VIEW => null
124
            ];
125
        }
126 341
        if (!isset($this->_toolbars[$context->id][$identifier])) {
127 341
            switch ($identifier) {
128
                case MIDCOM_TOOLBAR_HELP:
129 6
                    $component = $context->get_key(MIDCOM_CONTEXT_COMPONENT);
130 6
                    $toolbar = new midcom_helper_toolbar_help($component);
0 ignored issues
show
Bug introduced by
It seems like $component can also be of type false; however, parameter $component of midcom_helper_toolbar_help::__construct() does only seem to accept string, 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

130
                    $toolbar = new midcom_helper_toolbar_help(/** @scrutinizer ignore-type */ $component);
Loading history...
131 6
                    break;
132
                case MIDCOM_TOOLBAR_HOST:
133 5
                    $toolbar = new midcom_helper_toolbar_host;
134 5
                    break;
135
                case MIDCOM_TOOLBAR_NODE:
136 341
                    $topic = $context->get_key(MIDCOM_CONTEXT_CONTENTTOPIC);
137 341
                    $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

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

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

191
        $reflector = new midcom_helper_reflector(/** @scrutinizer ignore-type */ $object);
Loading history...
192 52
        $toolbar->set_label($reflector->get_class_label());
193
194 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

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

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