Completed
Pull Request — master (#7)
by Dante
02:32 queued 48s
created

HtmlHelper::metaAll()   B

Complexity

Conditions 8
Paths 72

Size

Total Lines 44
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 23
nc 72
nop 1
dl 0
loc 44
rs 8.4444
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
14
namespace BEdita\WebTools\View\Helper;
15
16
use Cake\Core\Configure;
17
use Cake\Utility\Inflector;
18
use Cake\View\Helper\HtmlHelper as CakeHtmlHelper;
19
20
/**
21
 * Html helper.
22
 * It extends {@see \Cake\View\Helper\HtmlHelper} Cake Html Helper
23
 */
24
class HtmlHelper extends CakeHtmlHelper
25
{
26
    /**
27
     * Title for template pages
28
     * If `_title` view var is set, return it
29
     * Otherwise return controller name (and action name if set)
30
     *
31
     * @return string
32
     */
33
    public function title() : string
34
    {
35
        if (isset($this->getView()->viewVars['_title'])) {
36
            return $this->getView()->viewVars['_title'];
37
        }
38
        $title = Inflector::humanize($this->getView()->request->getParam('controller', ''));
39
        $suffix = Inflector::humanize($this->getView()->request->getParam('action', ''));
40
        if (empty($title)) {
41
            $title = $suffix;
42
        } elseif (!empty($suffix)) {
43
            $title .= sprintf(' - %s', $suffix);
44
        }
45
46
        return $title;
47
    }
48
49
    /**
50
     * Html meta: description, content, author, css, generator
51
     *
52
     * @param array $data Data for meta: 'description', 'author', 'docType', 'project', 'theme-color'
53
     * @return string
54
     * @see HtmlHelper
55
     */
56
    public function metaAll(array $data) : string
57
    {
58
        $html = '';
59
60
        // description
61
        if (!empty($data['description'])) {
62
            $html .= $this->metaDescription($data['description']);
63
        }
64
65
        // author
66
        if (!empty($data['author'])) {
67
            $html .= $this->metaAuthor($data['author']);
68
        }
69
70
        // viewport, msapplication-TileColor, theme-color
71
        foreach (['viewport', 'msapplication-TileColor', 'theme-color'] as $attribute) {
72
            if (!empty($data[$attribute])) {
73
                $html .= $this->meta([
74
                    'name' => $attribute,
75
                    'content' => $data[$attribute],
76
                ]);
77
            }
78
        }
79
80
        // css
81
        $docType = '';
82
        if (!empty($data['docType'])) {
83
            $docType = $data['docType'];
84
        } else {
85
            $docType = Configure::read('docType');
86
            if (empty($docType)) {
87
                $docType = 'xhtml-strict';
88
            }
89
        }
90
        $html .= $this->metaCss($docType);
91
92
        // generator
93
        $project = [];
94
        if (!empty($data['project'])) {
95
            $project = $data['project'];
96
        }
97
        $html .= $this->metaGenerator($project);
98
99
        return $html;
100
    }
101
102
    /**
103
     * Return html meta description tag for passed description argument
104
     *
105
     * @param string|null $description The description
106
     * @return string
107
     */
108
    public function metaDescription($description) : string
109
    {
110
        if (empty($description)) {
111
            return '';
112
        }
113
114
        return $this->meta('description', h(strip_tags($description)));
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->meta('desc...ip_tags($description))) could return the type null which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
115
    }
116
117
    /**
118
     * Return html meta author tag for passed creator argument
119
     *
120
     * @param string|null $creator The content creator
121
     * @return string
122
     */
123
    public function metaAuthor(?string $creator) : string
124
    {
125
        if (empty($creator)) {
126
            return '';
127
        }
128
129
        return $this->meta([
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->meta(array...ntent' => h($creator))) could return the type null which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
130
            'name' => 'author',
131
            'content' => h($creator),
132
        ]);
133
    }
134
135
    /**
136
     * Return html meta css tag for passed doc type
137
     *
138
     * @param string $docType The doc type
139
     * @return string
140
     */
141
    public function metaCss(string $docType) : string
142
    {
143
        if ($docType === 'html5') {
144
            return '';
145
        }
146
147
        return $this->meta([
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->meta(array...ontent' => 'text/css')) could return the type null which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
148
            'http-equiv' => 'Content-Style-Type',
149
            'content' => 'text/css',
150
        ]);
151
    }
152
153
    /**
154
     * Return html meta for generator by project name and version passed
155
     *
156
     * @param array $project The project data ('name', 'version')
157
     * @return string
158
     */
159
    public function metaGenerator(array $project) : string
160
    {
161
        if (empty($project) || empty($project['name'])) {
162
            return '';
163
        }
164
        $version = '';
165
        if (!empty($project['version'])) {
166
            $version = $project['version'];
167
        }
168
169
        return $this->meta([
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->meta(array...t['name'], $version)))) could return the type null which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
170
            'name' => 'generator',
171
            'content' => trim(sprintf('%s %s', $project['name'], $version)),
172
        ]);
173
    }
174
175
    /**
176
     * Return html meta for opengraph / facebook
177
     * OG fields:
178
     *
179
     *  - og:title
180
     *  - og:type
181
     *  - og:url
182
     *  - og:image
183
     *
184
     * OG optional fields:
185
     *
186
     *  - og:audio
187
     *  - og:description
188
     *  - og:determiner
189
     *  - og:locale
190
     *  - og:locale:alternate
191
     *  - og:site_name
192
     *  - og:video
193
     *
194
     * OG structured fields:
195
     *
196
     *  - og:image:url // identical to og:image
197
     *  - og:image:secure_url
198
     *  - og:image:type
199
     *  - og:image:width
200
     *  - og:image:height
201
     *  - og:image:alt
202
     *  - og:video:url // identical to og:video
203
     *  - og:video:secure_url
204
     *  - og:video:type
205
     *  - og:video:width
206
     *  - og:video:height
207
     *  - og:audio
208
     *  - og:secure_url
209
     *  - og:type
210
     *
211
     * For details @see http://ogp.me
212
     *
213
     * @param array $data The data ('title', 'type', 'image', 'url')
214
     * @return string
215
     */
216
    public function metaOpenGraph(array $data) : string
217
    {
218
        $html = '';
219
        foreach ($data as $attribute => $val) {
220
            $html .= $this->meta([
221
                'property' => sprintf('og:%s', $attribute),
222
                'content' => $val,
223
            ]);
224
        }
225
226
        return $html;
227
    }
228
229
    /**
230
     * Return html meta for twitter
231
     * twitter fields:
232
     *
233
     *  - twitter:card
234
     *  - twitter:site
235
     *  - twitter:site:id
236
     *  - twitter:creator
237
     *  - twitter:creator:id
238
     *  - twitter:description
239
     *  - twitter:title
240
     *  - twitter:image
241
     *  - twitter:image:alt
242
     *  - twitter:player
243
     *  - twitter:player:width
244
     *  - twitter:player:height
245
     *  - twitter:player:stream
246
     *  - twitter:app:name:iphone
247
     *  - twitter:app:id:iphone
248
     *  - twitter:app:url:iphone
249
     *  - twitter:app:name:ipad
250
     *  - twitter:app:id:ipad
251
     *  - twitter:app:url:ipad
252
     *  - twitter:app:name:googleplay
253
     *  - twitter:app:id:googleplay
254
     *  - twitter:app:url:googleplay
255
     *
256
     * For details @see https://developer.twitter.com/en/docs/tweets/optimize-with-cards/overview/markup.html
257
     *
258
     * @param array $data The data ('card', 'site', 'creator', 'title', 'description', 'image')
259
     * @return string
260
     */
261
    public function metaTwitter(array $data) : string
262
    {
263
        $html = '';
264
        foreach ($data as $attribute => $val) {
265
            $html .= $this->meta([
266
                'property' => sprintf('twitter:%s', $attribute),
267
                'content' => $val,
268
            ]);
269
        }
270
271
        return $html;
272
    }
273
}
274