Passed
Pull Request — master (#29)
by Mark
01:39
created

handleTplMetaheaderOutput()   F

Complexity

Conditions 13
Paths 385

Size

Total Lines 168

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 168
rs 2.7766
c 0
b 0
f 0
cc 13
nc 385
nop 2

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/*
3
 * Copyright (c) 2013-2016 Mark C. Prins <[email protected]>
4
 *
5
 * Permission to use, copy, modify, and distribute this software for any
6
 * purpose with or without fee is hereby granted, provided that the above
7
 * copyright notice and this permission notice appear in all copies.
8
 *
9
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
 */
17
18
/**
19
 * DokuWiki Plugin socialcards (Action Component).
20
 *
21
 * @license BSD license
22
 * @author  Mark C. Prins <[email protected]>
23
 */
24
25
class action_plugin_socialcards extends DokuWiki_Action_Plugin {
26
27
    /**
28
     * Register our callback for the TPL_METAHEADER_OUTPUT event.
29
     *
30
     * @param $controller Doku_Event_Handler
31
     * @see DokuWiki_Action_Plugin::register()
32
     */
33
    public function register(Doku_Event_Handler $controller) {
34
        $controller->register_hook(
35
            'TPL_METAHEADER_OUTPUT',
36
            'BEFORE',
37
            $this,
38
            'handleTplMetaheaderOutput'
39
        );
40
    }
41
42
    /**
43
     * Retrieve metadata and add to the head of the page using appropriate meta
44
     * tags unless the page does not exist.
45
     *
46
     * @param Doku_Event $event the DokuWiki event. $event->data is a two-dimensional
47
     *                          array of all meta headers. The keys are meta, link and script.
48
     * @param mixed      $param the parameters passed to register_hook when this
49
     *                          handler was registered (not used)
50
     *
51
     * @global array     $INFO
52
     * @global string    $ID    page id
53
     * @global array     $conf  global wiki configuration
54
     * @see http://www.dokuwiki.org/devel:event:tpl_metaheader_output
55
     */
56
    public function handleTplMetaheaderOutput(Doku_Event $event, $param) {
57
        global $ID, $conf, $INFO;
58
59
        if(!page_exists($ID)) {
60
            return;
61
        }
62
63
        // twitter card, see https://dev.twitter.com/cards/markup
64
        // creat a summary card, see https://dev.twitter.com/cards/types/summary
65
        $event->data['meta'][] = array(
66
            'name'    => 'twitter:card',
67
            'content' => "summary",
68
        );
69
70
        $event->data['meta'][] = array(
71
            'name'    => 'twitter:site',
72
            'content' => $this->getConf('twitterName'),
73
        );
74
75
        $event->data['meta'][] = array(
76
            'name'    => 'twitter:title',
77
            'content' => p_get_metadata($ID, 'title', true),
78
        );
79
80
        $desc = p_get_metadata($ID, 'description', true);
81
        if(!empty($desc)) {
82
            $desc                  = str_replace("\n", " ", $desc['abstract']);
83
            $event->data['meta'][] = array(
84
                'name'    => 'twitter:description',
85
                'content' => $desc,
86
            );
87
        }
88
89
        if($this->getConf('twitterUserName') != '') {
90
            $event->data['meta'][] = array(
91
                'name'    => 'twitter:creator',
92
                'content' => $this->getConf('twitterUserName'),
93
            );
94
        }
95
96
        $event->data['meta'][] = array(
97
            'name'    => 'twitter:image',
98
            'content' => $this->getImage(),
99
        );
100
        $event->data['meta'][] = array(
101
            'name'    => 'twitter:image:alt',
102
            'content' => $this->getImageAlt(),
103
        );
104
105
        // opengraph, see http://ogp.me/
106
        //
107
        // to make this work properly the template should be modified adding the
108
        // namespaces for a (x)html 4 template make html tag:
109
        //
110
        // <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="nl" lang="nl"
111
        //       xmlns:og="http://ogp.me/ns#" xmlns:fb="http://ogp.me/ns/fb#"
112
        //       xmlns:article="http://ogp.me/ns/article#" xmlns:place="http://ogp.me/ns/place#">
113
        //
114
        // and for a (x)html 5 template make head tag:
115
        //
116
        // <head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# article: http://ogp.me/ns/article# place: http://ogp.me/ns/place#">
117
118
        // og namespace http://ogp.me/ns#
119
        $event->data['meta'][] = array(
120
            'property' => 'og:locale',
121
            'content'  => $this->getConf('languageTerritory'),
122
        );
123
        $event->data['meta'][] = array(
124
            'property' => 'og:site_name',
125
            'content'  => $conf['title'],
126
        );
127
        $event->data['meta'][] = array(
128
            'property' => 'og:url',
129
            'content'  => wl($ID, '', true),
130
        );
131
        $event->data['meta'][] = array(
132
            'property' => 'og:title',
133
            'content'  => p_get_metadata($ID, 'title', true),
134
        );
135
        if(!empty($desc)) {
136
            $event->data['meta'][] = array(
137
                'property' => 'og:description',
138
                'content'  => $desc,
139
            );
140
        }
141
        $event->data['meta'][] = array(
142
            'property' => 'og:type',
143
            'content'  => "article",
144
        );
145
        $ogImage               = $this->getImage();
146
        $secure                = substr($ogImage, 0, 5) === 'https' ? ':secure_url' : '';
147
        $event->data['meta'][] = array(
148
            'property' => 'og:image' . $secure,
149
            'content'  => $ogImage,
150
        );
151
152
        // article namespace http://ogp.me/ns/article#
153
        $_dates                = p_get_metadata($ID, 'date', true);
154
        $event->data['meta'][] = array(
155
            'property' => 'article:published_time',
156
            'content'  => dformat($_dates['created']),
157
        );
158
        $event->data['meta'][] = array(
159
            'property' => 'article:modified_time',
160
            'content'  => dformat($_dates['modified']),
161
        );
162
        $event->data['meta'][] = array(
163
            'property' => 'article:author',
164
            'content'  => $INFO['editor'],
165
        );
166
        // $event->data['meta'][] = array('property' => 'article:author','content' => p_get_metadata($ID,'creator',true),);
167
        // $event->data['meta'][] = array('property' => 'article:author','content' => p_get_metadata($ID,'user',true),);
168
        $_subject = p_get_metadata($ID, 'subject', true);
169
        if(!empty($_subject)) {
170
            if(!is_array($_subject)) {
171
                $_subject = array($_subject);
172
            }
173
            foreach($_subject as $tag) {
174
                $event->data['meta'][] = array(
175
                    'property' => 'article:tag',
176
                    'content'  => $tag,
177
                );
178
            }
179
        }
180
181
        // place namespace http://ogp.me/ns/place#
182
        $geotags = p_get_metadata($ID, 'geo', true);
183
        $lat     = $geotags['lat'];
184
        $lon     = $geotags['lon'];
185
        if(!(empty($lat) && empty($lon))) {
186
            $event->data['meta'][] = array(
187
                'property' => 'place:location:latitude',
188
                'content'  => $lat,
189
            );
190
            $event->data['meta'][] = array(
191
                'property' => 'place:location:longitude',
192
                'content'  => $lon,
193
            );
194
        }
195
        // see https://developers.facebook.com/docs/opengraph/property-types/#geopoint
196
        $alt = $geotags['alt'];
197
        if(!empty($alt)) {
198
            // facebook expects feet...
199
            $alt                   = $alt * 3.2808;
200
            $event->data['meta'][] = array(
201
                'property' => 'place:location:altitude',
202
                'content'  => $alt,
203
            );
204
        }
205
206
        /* these are not valid for the GeoPoint type..
207
        $region=$geotags['region'];
208
        $country=$geotags['country'];
209
        $placename=$geotags['placename'];
210
        if (!empty($region))    {$event->data['meta'][] = array('property' => 'place:location:region',      'content' => $region,);}
211
        if (!empty($placename)) {$event->data['meta'][] = array('property' => 'place:location:locality',    'content' => $placename,);}
212
        if (!empty($country))   {$event->data['meta'][] = array('property' => 'place:location:country-name','content' => $country,);}
213
        */
214
215
        // optional facebook app ID
216
        $appId = $this->getConf('fbAppId');
217
        if(!empty($appId)) {
218
            $event->data['meta'][] = array(
219
                'property' => 'fb:app_id',
220
                'content'  => $appId,
221
            );
222
        }
223
    }
224
225
    /**
226
     * Gets the canonical image path for this page.
227
     *
228
     * @return string the url to the image to use for this page
229
     * @global string $ID page id
230
     */
231
    private function getImage() {
232
        global $ID;
233
        $rel = p_get_metadata($ID, 'relation', true);
234
        $img = $rel['firstimage'];
235
236
        if(empty($img)) {
237
            $img = $this->getConf('fallbackImage');
238
            if(substr($img, 0, 4) === "http") {
239
                // don't use ml() as this results in a HTTP redirect after
240
                //   hitting the wiki making the card image fail.
241
                return $img;
242
            }
243
        }
244
245
        return ml($img, array(), true, '&amp;', true);
246
    }
247
248
    /**
249
     * Gets the alt text for this page image.
250
     *
251
     * @return string alt text
252
     * @global string $ID page id
253
     */
254
    private function getImageAlt() {
255
        global $ID;
256
        $rel   = p_get_metadata($ID, 'relation', true);
257
        $imgID = $rel['firstimage'];
258
        $alt   = "";
259
260
        if(!empty($imgID)) {
261
            require_once(DOKU_INC . 'inc/JpegMeta.php');
262
            $jpegmeta = new JpegMeta(mediaFN($imgID));
263
            $tags     = array(
264
                'IPTC.Caption',
265
                'EXIF.UserComment',
266
                'EXIF.TIFFImageDescription',
267
                'EXIF.TIFFUserComment',
268
                'IPTC.Headline',
269
                'Xmp.dc:title'
270
            );
271
            $alt      = media_getTag($tags, $jpegmeta, "");
272
        }
273
        return htmlspecialchars($alt);
274
    }
275
}
276