Passed
Pull Request — master (#982)
by Paolo
05:56
created

LayoutHelper::title()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 9
nc 3
nop 0
dl 0
loc 14
rs 9.9666
c 0
b 0
f 0
1
<?php
2
/**
3
 * BEdita, API-first content management framework
4
 * Copyright 2018 ChannelWeb Srl, Chialab Srl
5
 *
6
 * This file is part of BEdita: you can redistribute it and/or modify
7
 * it under the terms of the GNU Lesser General Public License as published
8
 * by the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * See LICENSE.LGPL or <http://gnu.org/licenses/lgpl-3.0.html> for more details.
12
 */
13
namespace App\View\Helper;
14
15
use App\Utility\Translate;
16
use Cake\Core\Configure;
17
use Cake\Utility\Hash;
18
use Cake\View\Helper;
19
20
/**
21
 * Helper for site layout
22
 *
23
 * @property \Cake\View\Helper\HtmlHelper $Html
24
 * @property \App\View\Helper\LinkHelper $Link
25
 * @property \App\View\Helper\PermsHelper $Perms
26
 * @property \App\View\Helper\SystemHelper $System
27
 */
28
class LayoutHelper extends Helper
29
{
30
    /**
31
     * List of helpers used by this helper
32
     *
33
     * @var array
34
     */
35
    public $helpers = ['Html', 'Link', 'Perms', 'System'];
36
37
    /**
38
     * Is Dashboard
39
     *
40
     * @return bool True if visible for view
41
     */
42
    public function isDashboard(): bool
43
    {
44
        return in_array($this->_View->getName(), ['Dashboard']);
45
    }
46
47
    /**
48
     * Is Login
49
     *
50
     * @return bool True if visible for view
51
     */
52
    public function isLogin(): bool
53
    {
54
        return in_array($this->_View->getName(), ['Login']);
55
    }
56
57
    /**
58
     * Properties for various publication status
59
     *
60
     * @param array $object The object
61
     * @return string pubstatus
62
     */
63
    public function publishStatus(array $object = []): string
64
    {
65
        if (empty($object)) {
66
            return '';
67
        }
68
69
        $end = (string)Hash::get($object, 'attributes.publish_end');
70
        $start = (string)Hash::get($object, 'attributes.publish_start');
71
72
        if (!empty($end) && strtotime($end) <= time()) {
73
            return 'expired';
74
        }
75
        if (!empty($start) && strtotime($start) > time()) {
76
            return 'future';
77
        }
78
        if (!empty((string)Hash::get($object, 'meta.locked'))) {
79
            return 'locked';
80
        }
81
        if ((string)Hash::get($object, 'attributes.status') === 'draft') {
82
            return 'draft';
83
        }
84
85
        return '';
86
    }
87
88
    /**
89
     * Messages visibility
90
     *
91
     * @return bool True if visible for view
92
     */
93
    public function messages(): bool
94
    {
95
        return $this->_View->getName() != 'Login';
96
    }
97
98
    /**
99
     * Return title with object title and current module name
100
     *
101
     * @return string title with object title and current module name separated by '|'
102
     */
103
    public function title(): string
104
    {
105
        $currentModule = (array)$this->getView()->get('currentModule');
106
        $object = (array)$this->getView()->get('object');
107
        $title = '';
108
        if (!empty($currentModule) && !empty($currentModule['name'])) {
109
            $currentModuleName = $currentModule['name'];
110
            if (Hash::check($object, 'attributes.title')) {
111
                $title = $object['attributes']['title'] . ' | ';
112
            }
113
            $title = $title . $currentModuleName;
114
        }
115
116
        return $title;
117
    }
118
119
    /**
120
     * Module main link
121
     *
122
     * @return string The link
123
     */
124
    public function moduleLink(): string
125
    {
126
        $currentModule = (array)$this->getView()->get('currentModule');
127
        if (!empty($currentModule) && !empty($currentModule['name'])) {
128
            $name = $currentModule['name'];
129
            $label = Hash::get($currentModule, 'label', $name);
130
131
            return $this->Html->link(
132
                $this->tr($label),
133
                ['_name' => 'modules:list', 'object_type' => $name],
134
                ['class' => sprintf('has-background-module-%s', $name)]
135
            );
136
        }
137
138
        // if no `currentModule` has been set a `moduleLink` must be set in controller otherwise current link is displayed
139
        return $this->Html->link(
140
            $this->tr($this->getView()->getName()),
141
            (array)$this->getView()->get('moduleLink'),
142
            ['class' => $this->commandLinkClass()]
143
        );
144
    }
145
146
    /**
147
     * Return style class for command link
148
     *
149
     * @return string
150
     */
151
    protected function commandLinkClass(): string
152
    {
153
        $moduleClasses = [
154
            'UserProfile' => 'has-background-black icon-user',
155
            'Import' => 'has-background-black icon-download-alt',
156
            'ObjectTypes' => 'has-background-black',
157
            'Relations' => 'has-background-black',
158
            'PropertyTypes' => 'has-background-black',
159
            'Categories' => 'has-background-black',
160
            'Appearance' => 'has-background-black',
161
            'Applications' => 'has-background-black',
162
            'AsyncJobs' => 'has-background-black',
163
            'Config' => 'has-background-black',
164
            'Endpoints' => 'has-background-black',
165
            'Roles' => 'has-background-black',
166
            'RolesModules' => 'has-background-black',
167
            'EndpointPermissions' => 'has-background-black',
168
            'Tags' => 'has-background-module-tags',
169
        ];
170
171
        return (string)Hash::get($moduleClasses, $this->_View->getName(), 'commands-menu__module');
172
    }
173
174
    /**
175
     * Return custom element via `Properties` configuration for
176
     * a relation or property group in current module.
177
     *
178
     * @param string $item Relation or group name
179
     * @param string $type Item type: `relation` or `group`
180
     * @return string
181
     */
182
    public function customElement(string $item, string $type = 'relation'): string
183
    {
184
        $currentModule = (array)$this->getView()->get('currentModule');
185
        $name = (string)Hash::get($currentModule, 'name');
186
        if ($type === 'relation') {
187
            $path = sprintf('Properties.%s.relations._element.%s', $name, $item);
188
        } else {
189
            $path = sprintf('Properties.%s.view.%s._element', $name, $item);
190
        }
191
192
        return (string)Configure::read($path);
193
    }
194
195
    /**
196
     * Get translated val by input string, using plugins (if any) translations.
197
     *
198
     * @param string $input The input string
199
     * @return string|null
200
     */
201
    public function tr(string $input): ?string
202
    {
203
        return Translate::get($input);
204
    }
205
206
    /**
207
     * Return configuration items to create JSON BEDITA object
208
     *
209
     * @return array
210
     */
211
    public function metaConfig(): array
212
    {
213
        return [
214
            'base' => $this->Link->baseUrl(),
215
            'currentModule' => $this->getView()->get('currentModule', ['name' => 'home']),
216
            'template' => $this->getView()->getTemplate(),
217
            'modules' => array_keys($this->getView()->get('modules', [])),
218
            'plugins' => \App\Plugin::loadedAppPlugins(),
219
            'uploadable' => $this->getView()->get('uploadable', []),
220
            'locale' => \Cake\I18n\I18n::getLocale(),
221
            'csrfToken' => $this->getCsrfToken(),
222
            'maxFileSize' => $this->System->getMaxFileSize(),
223
            'canReadUsers' => $this->Perms->canRead('users'),
224
            'uploadConfig' => $this->System->uploadConfig(),
225
        ];
226
    }
227
228
    /**
229
     * Get csrf token, searching in: request params, data, attributes and cookies
230
     *
231
     * @return string|null
232
     */
233
    public function getCsrfToken(): ?string
234
    {
235
        if (!empty($this->getView()->getRequest()->getParam('_csrfToken'))) {
236
            return $this->getView()->getRequest()->getParam('_csrfToken');
237
        }
238
        if (!empty($this->getView()->getRequest()->getData('_csrfToken'))) {
239
            return $this->getView()->getRequest()->getData('_csrfToken');
240
        }
241
        if (!empty($this->getView()->getRequest()->getAttribute('csrfToken'))) {
242
            return $this->getView()->getRequest()->getAttribute('csrfToken');
243
        }
244
        if (!empty($this->getView()->getRequest()->getCookie('csrfToken'))) {
245
            return $this->getView()->getRequest()->getCookie('csrfToken');
246
        }
247
248
        return null;
249
    }
250
251
    /**
252
     * Trash link by type.
253
     *
254
     * @param string|null $type The object type, if any.
255
     * @return string
256
     */
257
    public function trashLink(?string $type): string
258
    {
259
        if (empty($type) || $type === 'trash') {
260
            return '';
261
        }
262
263
        $modules = (array)$this->_View->get('modules');
264
        if (!Hash::check($modules, sprintf('%s.hints.object_type', $type))) {
265
            return '';
266
        }
267
268
        $classes = sprintf('button icon icon-only-icon has-text-module-%s', $type);
269
        $title = $this->tr($type) . __(' in Trashcan');
270
        $filter = ['type' => [$type]];
271
272
        return $this->Html->link(
273
            sprintf('<span class="is-sr-only">%s</span><Icon icon="carbon:trash-can"></Icon>', __('Trash')),
274
            ['_name' => 'trash:list', '?' => compact('filter')],
275
            ['class' => $classes, 'title' => $title, 'escape' => false]
276
        );
277
    }
278
}
279