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