xref: /plugin/combo/action/metafacebook.php (revision 522065429f1f017315dfb89e81fe72fea6ca1c90)
1<?php
2
3use ComboStrap\Image;
4use ComboStrap\LogUtility;
5use ComboStrap\MetadataUtility;
6use ComboStrap\PluginUtility;
7use ComboStrap\Page;
8use ComboStrap\Site;
9use ComboStrap\StringUtility;
10
11if (!defined('DOKU_INC')) die();
12
13require_once(__DIR__ . '/../class/Site.php');
14require_once(__DIR__ . '/../class/Image.php');
15
16/**
17 *
18 * For the canonical meta, see {@link action_plugin_combo_metacanonical}
19 *
20 * Inspiration, reference:
21 * https://developers.facebook.com/docs/sharing/webmasters
22 * https://github.com/twbs/bootstrap/blob/v4-dev/site/layouts/partials/social.html
23 * https://github.com/mprins/dokuwiki-plugin-socialcards/blob/master/action.php
24 */
25class action_plugin_combo_metafacebook extends DokuWiki_Action_Plugin
26{
27
28    const FACEBOOK_APP_ID = "486120022012342";
29
30    /**
31     * The image
32     */
33    const CONF_DEFAULT_FACEBOOK_IMAGE = "defaultFacebookImage";
34
35
36    const CANONICAL = "facebook";
37
38
39    function __construct()
40    {
41        // enable direct access to language strings
42        // ie $this->lang
43        $this->setupLocale();
44    }
45
46    public function register(Doku_Event_Handler $controller)
47    {
48        $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'metaFacebookProcessing', array());
49    }
50
51    /**
52     *
53     * @param $event
54     */
55    function metaFacebookProcessing($event)
56    {
57
58        global $ID;
59        if (empty($ID)) {
60            // $ID is null for media
61            return;
62        }
63
64
65        $page = new Page($ID);
66
67        /**
68         * No social for bars
69         */
70        if ($page->isBar()) {
71            return;
72        }
73
74
75        /**
76         * "og:url" is already created in the {@link action_plugin_combo_metacanonical}
77         * "og:description" is already created in the {@link action_plugin_combo_metadescription}
78         */
79        $facebookMeta = array(
80            "og:title" => StringUtility::truncateString($page->getTitleNotEmpty(), 70),
81            "og:description" => $page->getDescriptionOrElseDokuWiki(),
82        );
83
84        $title = Site::getTitle();
85        if (!empty($title)) {
86            $facebookMeta["og:site_name"] = $title;
87        }
88
89        /**
90         * Type of page
91         */
92        $ogType = $page->getType();
93        if (!empty($ogType)) {
94            $facebookMeta["og:type"] = $ogType;
95        } else {
96            // The default facebook value
97            $facebookMeta["og:type"] = Page::WEBSITE_TYPE;
98        }
99
100        if ($ogType == Page::ARTICLE_TYPE) {
101            // https://ogp.me/#type_article
102            $facebookMeta["article:published_time"] = date("c", $page->getPublishedElseCreationTimeStamp());
103            $facebookMeta["article:modified_time"] = date("c", $page->getModifiedTimestamp());
104        }
105
106        /**
107         * @var Image[]
108         */
109        $facebookImages = $page->getImageSet();
110        if (empty($facebookImages)) {
111            $defaultFacebookImage = cleanID(PluginUtility::getConfValue(self::CONF_DEFAULT_FACEBOOK_IMAGE));
112            if (!empty($defaultFacebookImage)) {
113                $image = new Image($defaultFacebookImage);
114                if ($image->exists()) {
115                    $facebookImages[] = $image;
116                } else {
117                    if ($defaultFacebookImage != "logo-facebook.png") {
118                        LogUtility::msg("The default facebook image ($defaultFacebookImage) does not exist", LogUtility::LVL_MSG_ERROR, self::CANONICAL);
119                    }
120                }
121
122
123            }
124        }
125        if (!empty($facebookImages)) {
126            foreach ($facebookImages as $facebookImage) {
127
128                if (!$facebookImage->exists()) {
129                    LogUtility::msg("The image ($facebookImage) does not exist and was not added", LogUtility::LVL_MSG_ERROR, self::CANONICAL);
130                } else {
131
132                    $toSmall = false;
133                    if ($facebookImage->isAnalyzable()) {
134
135                        // There is a minimum size constraint of 200px by 200px
136                        if ($facebookImage->getWidth() < 200) {
137                            $toSmall = true;
138                        } else {
139                            $facebookMeta["og:image:width"] = $facebookImage->getWidth();
140                            if ($facebookImage->getHeight() < 200) {
141                                $toSmall = true;
142                            } else {
143                                $facebookMeta["og:image:height"] = $facebookImage->getHeight();
144                            }
145                        }
146                    }
147
148                    if ($toSmall) {
149                        $message = "The facebook image ($facebookImage) is too small (" . $facebookImage->getWidth() . " x " . $facebookImage->getHeight() . "). The minimum size constraint is 200px by 200px";
150                        if ($facebookImage->getId() != $page->getFirstImage()->getId()) {
151                            LogUtility::msg($message, LogUtility::LVL_MSG_ERROR, self::CANONICAL);
152                        } else {
153                            LogUtility::log2BrowserConsole($message);
154                        }
155                    }
156
157
158                    /**
159                     * We may don't known the dimensions
160                     */
161                    if (!$toSmall) {
162                        $mime = $facebookImage->getMime();
163                        if (!empty($mime)) {
164                            $facebookMeta["og:image:type"] = $mime[1];
165                        }
166                        $facebookMeta["og:image"] = $facebookImage->getUrl();
167                        // One image only
168                        break;
169                    }
170                }
171
172            }
173        }
174
175
176        $facebookMeta["fb:app_id"] = self::FACEBOOK_APP_ID;
177
178        $lang = $page->getLang();
179        if (!empty($lang)) {
180
181            $country = $page->getCountry();
182            if (empty($country)) {
183                $country = $lang;
184            }
185            $facebookMeta["og:locale"] = $lang . "_" . strtoupper($country);
186
187        } else {
188
189            // The Facebook default
190            $facebookMeta["og:locale"] = "en_US";
191
192        }
193
194        /**
195         * Add the properties
196         */
197        foreach ($facebookMeta as $property => $content) {
198            $event->data['meta'][] = array("property" => $property, "content" => $content);
199        }
200
201
202    }
203
204}
205