15f891b7eSNickeau<?php 25f891b7eSNickeau 3*21913ab3SNickeauuse ComboStrap\RasterImageLink; 4*21913ab3SNickeauuse ComboStrap\InternalMediaLink; 55f891b7eSNickeauuse ComboStrap\LogUtility; 65f891b7eSNickeauuse ComboStrap\MetadataUtility; 75f891b7eSNickeauuse ComboStrap\PluginUtility; 85f891b7eSNickeauuse ComboStrap\Page; 95f891b7eSNickeauuse ComboStrap\Site; 105f891b7eSNickeauuse ComboStrap\StringUtility; 115f891b7eSNickeau 125f891b7eSNickeauif (!defined('DOKU_INC')) die(); 135f891b7eSNickeau 145f891b7eSNickeaurequire_once(__DIR__ . '/../class/Site.php'); 15*21913ab3SNickeaurequire_once(__DIR__ . '/../class/RasterImageLink.php'); 165f891b7eSNickeau 175f891b7eSNickeau/** 185f891b7eSNickeau * 195f891b7eSNickeau * For the canonical meta, see {@link action_plugin_combo_metacanonical} 205f891b7eSNickeau * 215f891b7eSNickeau * Inspiration, reference: 225f891b7eSNickeau * https://developers.facebook.com/docs/sharing/webmasters 235f891b7eSNickeau * https://github.com/twbs/bootstrap/blob/v4-dev/site/layouts/partials/social.html 245f891b7eSNickeau * https://github.com/mprins/dokuwiki-plugin-socialcards/blob/master/action.php 255f891b7eSNickeau */ 265f891b7eSNickeauclass action_plugin_combo_metafacebook extends DokuWiki_Action_Plugin 275f891b7eSNickeau{ 285f891b7eSNickeau 295f891b7eSNickeau const FACEBOOK_APP_ID = "486120022012342"; 305f891b7eSNickeau 315f891b7eSNickeau /** 325f891b7eSNickeau * The image 335f891b7eSNickeau */ 345f891b7eSNickeau const CONF_DEFAULT_FACEBOOK_IMAGE = "defaultFacebookImage"; 355f891b7eSNickeau 365f891b7eSNickeau 375f891b7eSNickeau const CANONICAL = "facebook"; 385f891b7eSNickeau 395f891b7eSNickeau 405f891b7eSNickeau function __construct() 415f891b7eSNickeau { 425f891b7eSNickeau // enable direct access to language strings 435f891b7eSNickeau // ie $this->lang 445f891b7eSNickeau $this->setupLocale(); 455f891b7eSNickeau } 465f891b7eSNickeau 475f891b7eSNickeau public function register(Doku_Event_Handler $controller) 485f891b7eSNickeau { 495f891b7eSNickeau $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'metaFacebookProcessing', array()); 505f891b7eSNickeau } 515f891b7eSNickeau 525f891b7eSNickeau /** 535f891b7eSNickeau * 545f891b7eSNickeau * @param $event 555f891b7eSNickeau */ 565f891b7eSNickeau function metaFacebookProcessing($event) 575f891b7eSNickeau { 585f891b7eSNickeau 595f891b7eSNickeau global $ID; 605f891b7eSNickeau if (empty($ID)) { 615f891b7eSNickeau // $ID is null for media 625f891b7eSNickeau return; 635f891b7eSNickeau } 645f891b7eSNickeau 655f891b7eSNickeau 665f891b7eSNickeau $page = new Page($ID); 67dd39a644Sgerardnico if (!$page->existInFs()) { 68dd39a644Sgerardnico return; 69dd39a644Sgerardnico } 70*21913ab3SNickeau 715f891b7eSNickeau /** 725f891b7eSNickeau * No social for bars 735f891b7eSNickeau */ 745f891b7eSNickeau if ($page->isBar()) { 755f891b7eSNickeau return; 765f891b7eSNickeau } 775f891b7eSNickeau 785f891b7eSNickeau 795f891b7eSNickeau /** 805f891b7eSNickeau * "og:url" is already created in the {@link action_plugin_combo_metacanonical} 815f891b7eSNickeau * "og:description" is already created in the {@link action_plugin_combo_metadescription} 825f891b7eSNickeau */ 835f891b7eSNickeau $facebookMeta = array( 845f891b7eSNickeau "og:title" => StringUtility::truncateString($page->getTitleNotEmpty(), 70), 8552206542Sgerardnico "og:description" => $page->getDescriptionOrElseDokuWiki(), 865f891b7eSNickeau ); 875f891b7eSNickeau 885f891b7eSNickeau $title = Site::getTitle(); 895f891b7eSNickeau if (!empty($title)) { 905f891b7eSNickeau $facebookMeta["og:site_name"] = $title; 915f891b7eSNickeau } 925f891b7eSNickeau 935f891b7eSNickeau /** 945f891b7eSNickeau * Type of page 955f891b7eSNickeau */ 965f891b7eSNickeau $ogType = $page->getType(); 975f891b7eSNickeau if (!empty($ogType)) { 985f891b7eSNickeau $facebookMeta["og:type"] = $ogType; 995f891b7eSNickeau } else { 1005f891b7eSNickeau // The default facebook value 1015f891b7eSNickeau $facebookMeta["og:type"] = Page::WEBSITE_TYPE; 1025f891b7eSNickeau } 1035f891b7eSNickeau 1045f891b7eSNickeau if ($ogType == Page::ARTICLE_TYPE) { 1055f891b7eSNickeau // https://ogp.me/#type_article 1065f891b7eSNickeau $facebookMeta["article:published_time"] = date("c", $page->getPublishedElseCreationTimeStamp()); 1075f891b7eSNickeau $facebookMeta["article:modified_time"] = date("c", $page->getModifiedTimestamp()); 1085f891b7eSNickeau } 1095f891b7eSNickeau 1105f891b7eSNickeau /** 111*21913ab3SNickeau * @var InternalMediaLink[] 1125f891b7eSNickeau */ 1135f891b7eSNickeau $facebookImages = $page->getImageSet(); 1145f891b7eSNickeau if (empty($facebookImages)) { 1155f891b7eSNickeau $defaultFacebookImage = cleanID(PluginUtility::getConfValue(self::CONF_DEFAULT_FACEBOOK_IMAGE)); 1165f891b7eSNickeau if (!empty($defaultFacebookImage)) { 117*21913ab3SNickeau $image = InternalMediaLink::createMediaLinkFromPathId($defaultFacebookImage); 1185f891b7eSNickeau if ($image->exists()) { 1195f891b7eSNickeau $facebookImages[] = $image; 1205f891b7eSNickeau } else { 1215f891b7eSNickeau if ($defaultFacebookImage != "logo-facebook.png") { 1225f891b7eSNickeau LogUtility::msg("The default facebook image ($defaultFacebookImage) does not exist", LogUtility::LVL_MSG_ERROR, self::CANONICAL); 1235f891b7eSNickeau } 1245f891b7eSNickeau } 1255f891b7eSNickeau 1265f891b7eSNickeau 1275f891b7eSNickeau } 1285f891b7eSNickeau } 1295f891b7eSNickeau if (!empty($facebookImages)) { 130*21913ab3SNickeau 131*21913ab3SNickeau /** 132*21913ab3SNickeau * One of image/jpeg, image/gif or image/png 133*21913ab3SNickeau * As stated here: https://developers.facebook.com/docs/sharing/webmasters#images 134*21913ab3SNickeau **/ 135*21913ab3SNickeau $facebookMime = ["image/jpeg","image/gif","image/png"]; 1365f891b7eSNickeau foreach ($facebookImages as $facebookImage) { 1375f891b7eSNickeau 138*21913ab3SNickeau if(!in_array($facebookImage->getMime(),$facebookMime)){ 139*21913ab3SNickeau continue; 140*21913ab3SNickeau } 141*21913ab3SNickeau 142*21913ab3SNickeau /** @var RasterImageLink $facebookImage */ 143*21913ab3SNickeau if (!($facebookImage instanceof RasterImageLink)) { 144*21913ab3SNickeau LogUtility::msg("Internal: The image ($facebookImage) is not a raster image and this should not be the case for facebook", LogUtility::LVL_MSG_ERROR, "support"); 145*21913ab3SNickeau continue; 146*21913ab3SNickeau } 147*21913ab3SNickeau 1485f891b7eSNickeau if (!$facebookImage->exists()) { 1495f891b7eSNickeau LogUtility::msg("The image ($facebookImage) does not exist and was not added", LogUtility::LVL_MSG_ERROR, self::CANONICAL); 1505f891b7eSNickeau } else { 1515f891b7eSNickeau 1525f891b7eSNickeau $toSmall = false; 1535f891b7eSNickeau if ($facebookImage->isAnalyzable()) { 1545f891b7eSNickeau 1555f891b7eSNickeau // There is a minimum size constraint of 200px by 200px 156*21913ab3SNickeau if ($facebookImage->getMediaWidth() < 200) { 1575f891b7eSNickeau $toSmall = true; 1585f891b7eSNickeau } else { 159*21913ab3SNickeau $facebookMeta["og:image:width"] = $facebookImage->getMediaWidth(); 160*21913ab3SNickeau if ($facebookImage->getMediaHeight() < 200) { 1615f891b7eSNickeau $toSmall = true; 1625f891b7eSNickeau } else { 163*21913ab3SNickeau $facebookMeta["og:image:height"] = $facebookImage->getMediaHeight(); 1645f891b7eSNickeau } 1655f891b7eSNickeau } 1665f891b7eSNickeau } 1675f891b7eSNickeau 1685f891b7eSNickeau if ($toSmall) { 169*21913ab3SNickeau $message = "The facebook image ($facebookImage) is too small (" . $facebookImage->getMediaWidth() . " x " . $facebookImage->getMediaHeight() . "). The minimum size constraint is 200px by 200px"; 1705f891b7eSNickeau if ($facebookImage->getId() != $page->getFirstImage()->getId()) { 1715f891b7eSNickeau LogUtility::msg($message, LogUtility::LVL_MSG_ERROR, self::CANONICAL); 1725f891b7eSNickeau } else { 1735f891b7eSNickeau LogUtility::log2BrowserConsole($message); 1745f891b7eSNickeau } 1755f891b7eSNickeau } 1765f891b7eSNickeau 1775f891b7eSNickeau 1785f891b7eSNickeau /** 1795f891b7eSNickeau * We may don't known the dimensions 1805f891b7eSNickeau */ 1815f891b7eSNickeau if (!$toSmall) { 1825f891b7eSNickeau $mime = $facebookImage->getMime(); 1835f891b7eSNickeau if (!empty($mime)) { 1845f891b7eSNickeau $facebookMeta["og:image:type"] = $mime[1]; 1855f891b7eSNickeau } 186*21913ab3SNickeau $facebookMeta["og:image"] = $facebookImage->getAbsoluteUrl(); 1875f891b7eSNickeau // One image only 1885f891b7eSNickeau break; 1895f891b7eSNickeau } 1905f891b7eSNickeau } 1915f891b7eSNickeau 1925f891b7eSNickeau } 1935f891b7eSNickeau } 1945f891b7eSNickeau 1955f891b7eSNickeau 1965f891b7eSNickeau $facebookMeta["fb:app_id"] = self::FACEBOOK_APP_ID; 1975f891b7eSNickeau 1985f891b7eSNickeau $lang = $page->getLang(); 1995f891b7eSNickeau if (!empty($lang)) { 2005f891b7eSNickeau 2015f891b7eSNickeau $country = $page->getCountry(); 2025f891b7eSNickeau if (empty($country)) { 2035f891b7eSNickeau $country = $lang; 2045f891b7eSNickeau } 2055f891b7eSNickeau $facebookMeta["og:locale"] = $lang . "_" . strtoupper($country); 2065f891b7eSNickeau 2075f891b7eSNickeau } else { 2085f891b7eSNickeau 2095f891b7eSNickeau // The Facebook default 2105f891b7eSNickeau $facebookMeta["og:locale"] = "en_US"; 2115f891b7eSNickeau 2125f891b7eSNickeau } 2135f891b7eSNickeau 2145f891b7eSNickeau /** 2155f891b7eSNickeau * Add the properties 2165f891b7eSNickeau */ 2175f891b7eSNickeau foreach ($facebookMeta as $property => $content) { 2185f891b7eSNickeau $event->data['meta'][] = array("property" => $property, "content" => $content); 2195f891b7eSNickeau } 2205f891b7eSNickeau 2215f891b7eSNickeau 2225f891b7eSNickeau } 2235f891b7eSNickeau 2245f891b7eSNickeau} 225