15f891b7eSNickeau<?php 25f891b7eSNickeau 3*04fd306cSNickeauuse ComboStrap\BlockquoteTag; 4*04fd306cSNickeauuse ComboStrap\ExceptionBadArgument; 5*04fd306cSNickeauuse ComboStrap\ExceptionBadSyntax; 6*04fd306cSNickeauuse ComboStrap\ExceptionNotExists; 7*04fd306cSNickeauuse ComboStrap\ExecutionContext; 8*04fd306cSNickeauuse ComboStrap\FetcherRaster; 9*04fd306cSNickeauuse ComboStrap\Meta\Field\TwitterImage; 10*04fd306cSNickeauuse ComboStrap\Site; 11*04fd306cSNickeauuse ComboStrap\SiteConfig; 12*04fd306cSNickeauuse ComboStrap\WikiPath; 13*04fd306cSNickeauuse ComboStrap\ExceptionCompile; 14*04fd306cSNickeauuse ComboStrap\ExceptionNotFound; 15*04fd306cSNickeauuse ComboStrap\IFetcherLocalImage; 16*04fd306cSNickeauuse ComboStrap\FileSystems; 175f891b7eSNickeauuse ComboStrap\LogUtility; 18*04fd306cSNickeauuse ComboStrap\MarkupPath; 19c3437056SNickeauuse ComboStrap\PageImageUsage; 20f788f694Sgerardnicouse ComboStrap\PluginUtility; 21*04fd306cSNickeauuse ComboStrap\ResourceName; 225f891b7eSNickeauuse ComboStrap\StringUtility; 235f891b7eSNickeau 245f891b7eSNickeau 2537748cd8SNickeaurequire_once(__DIR__ . '/../ComboStrap/Site.php'); 265f891b7eSNickeau 275f891b7eSNickeau/** 285f891b7eSNickeau * 295f891b7eSNickeau * For the canonical meta, see {@link action_plugin_combo_metacanonical} 305f891b7eSNickeau * https://github.com/twbs/bootstrap/blob/v4-dev/site/layouts/partials/social.html 315f891b7eSNickeau * 325f891b7eSNickeau * TODO: https://developer.twitter.com/en/docs/twitter-for-websites/embedded-tweets/overview 335f891b7eSNickeau */ 345f891b7eSNickeauclass action_plugin_combo_metatwitter extends DokuWiki_Action_Plugin 355f891b7eSNickeau{ 365f891b7eSNickeau 375f891b7eSNickeau 385f891b7eSNickeau /** 395f891b7eSNickeau * The handle name 405f891b7eSNickeau */ 415f891b7eSNickeau const CONF_TWITTER_SITE_HANDLE = "twitterSiteHandle"; 425f891b7eSNickeau /** 435f891b7eSNickeau * The handle id 445f891b7eSNickeau */ 455f891b7eSNickeau const CONF_TWITTER_SITE_ID = "twitterSiteId"; 465f891b7eSNickeau 475f891b7eSNickeau /** 485f891b7eSNickeau * Don't track 495f891b7eSNickeau */ 5032b85071SNickeau const CONF_TWITTER_DONT_NOT_TRACK = self::META_DNT; 5132b85071SNickeau const CONF_DONT_NOT_TRACK = self::META_DNT; 525f891b7eSNickeau const CONF_ON = "on"; 535f891b7eSNickeau const CONF_OFF = "off"; 545f891b7eSNickeau 555f891b7eSNickeau /** 565f891b7eSNickeau * The creation ie (combostrap) 575f891b7eSNickeau */ 585f891b7eSNickeau const COMBO_STRAP_TWITTER_HANDLE = "@combostrapweb"; 595f891b7eSNickeau const COMBO_STRAP_TWITTER_ID = "1283330969332842497"; 605f891b7eSNickeau const CANONICAL = "twitter"; 615f891b7eSNickeau 6232b85071SNickeau const META_CARD = "twitter:card"; 6332b85071SNickeau const DEFAULT_IMAGE = ":apple-touch-icon.png"; 6432b85071SNickeau const META_DESCRIPTION = "twitter:description"; 6532b85071SNickeau const META_IMAGE = "twitter:image"; 6632b85071SNickeau const META_TITLE = "twitter:title"; 6732b85071SNickeau const META_CREATOR = "twitter:creator"; 6832b85071SNickeau const META_CREATOR_ID = "twitter:creator:id"; 6932b85071SNickeau const META_SITE = "twitter:site"; 7032b85071SNickeau const META_SITE_ID = "twitter:site:id"; 7132b85071SNickeau const META_IMAGE_ALT = "twitter:image:alt"; 7232b85071SNickeau const META_DNT = "twitter:dnt"; 7332b85071SNickeau const META_WIDGET_CSP = "twitter:widgets:csp"; 7432b85071SNickeau const META_WIDGETS_THEME = "twitter:widgets:theme"; 7532b85071SNickeau const META_WIDGETS_BORDER_COLOR = "twitter:widgets:border-color"; 765f891b7eSNickeau 775f891b7eSNickeau 785f891b7eSNickeau function __construct() 795f891b7eSNickeau { 805f891b7eSNickeau // enable direct access to language strings 815f891b7eSNickeau // ie $this->lang 825f891b7eSNickeau $this->setupLocale(); 835f891b7eSNickeau } 845f891b7eSNickeau 855f891b7eSNickeau public function register(Doku_Event_Handler $controller) 865f891b7eSNickeau { 875f891b7eSNickeau $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'metaTwitterProcessing', array()); 885f891b7eSNickeau } 895f891b7eSNickeau 905f891b7eSNickeau /** 915f891b7eSNickeau * 925f891b7eSNickeau * @param $event 935f891b7eSNickeau */ 945f891b7eSNickeau function metaTwitterProcessing($event) 955f891b7eSNickeau { 965f891b7eSNickeau 97*04fd306cSNickeau $executionContext = ExecutionContext::getActualOrCreateFromEnv(); 98*04fd306cSNickeau 99*04fd306cSNickeau try { 100*04fd306cSNickeau $templateForWebPage = $executionContext->getExecutingPageTemplate(); 101*04fd306cSNickeau if(!$templateForWebPage->isSocial()){ 102*04fd306cSNickeau return; 103*04fd306cSNickeau } 104*04fd306cSNickeau $page = MarkupPath::createPageFromPathObject($templateForWebPage->getRequestedContextPath()); 105*04fd306cSNickeau } catch (ExceptionNotFound $e) { 1065f891b7eSNickeau return; 1075f891b7eSNickeau } 1085f891b7eSNickeau 1095f891b7eSNickeau 110*04fd306cSNickeau if (!FileSystems::exists($page)) { 111dd39a644Sgerardnico return; 112dd39a644Sgerardnico } 11321913ab3SNickeau 1145f891b7eSNickeau /** 1155f891b7eSNickeau * No social for bars 1165f891b7eSNickeau */ 117*04fd306cSNickeau if ($page->isSlot()) { 1185f891b7eSNickeau return; 1195f891b7eSNickeau } 1205f891b7eSNickeau 1215f891b7eSNickeau 1225f891b7eSNickeau // https://datacadamia.com/marketing/twitter#html_meta 1235f891b7eSNickeau // https://developer.twitter.com/en/docs/twitter-for-websites/cards/overview/markup 1245f891b7eSNickeau // https://cards-dev.twitter.com/validator 1255f891b7eSNickeau 126f788f694Sgerardnico 1275f891b7eSNickeau $twitterMeta = array( 12832b85071SNickeau self::META_CARD => "summary", 129c3437056SNickeau self::META_TITLE => StringUtility::truncateString($page->getTitleOrDefault(), 70), 13032b85071SNickeau self::META_CREATOR => self::COMBO_STRAP_TWITTER_HANDLE, 13132b85071SNickeau self::META_CREATOR_ID => self::COMBO_STRAP_TWITTER_ID 1325f891b7eSNickeau ); 133f788f694Sgerardnico $description = $page->getDescriptionOrElseDokuWiki(); 134f788f694Sgerardnico if (!empty($description)) { 135f788f694Sgerardnico // happens in test with document without content 136f788f694Sgerardnico $twitterMeta[self::META_DESCRIPTION] = StringUtility::truncateString($description, 200); 137f788f694Sgerardnico } 1385f891b7eSNickeau 1395f891b7eSNickeau 1405f891b7eSNickeau /** 1415f891b7eSNickeau * Twitter site 1425f891b7eSNickeau */ 143*04fd306cSNickeau $siteTwitterHandle = $this->getConf(self::CONF_TWITTER_SITE_HANDLE); 144*04fd306cSNickeau $siteTwitterId = $this->getConf(self::CONF_TWITTER_SITE_ID); 1455f891b7eSNickeau if (!empty($siteTwitterHandle)) { 14632b85071SNickeau $twitterMeta[self::META_SITE] = $siteTwitterHandle; 1475f891b7eSNickeau 1485f891b7eSNickeau // Identify the Twitter profile of the page that populates the via property 1495f891b7eSNickeau // https://developer.twitter.com/en/docs/twitter-for-websites/webpage-properties 1505f891b7eSNickeau $name = str_replace("@", "", $siteTwitterHandle); 1515f891b7eSNickeau $event->data['link'][] = array("rel" => "me", "href" => "https://twitter.com/$name"); 1525f891b7eSNickeau } 1535f891b7eSNickeau if (!empty($siteTwitterId)) { 15432b85071SNickeau $twitterMeta[self::META_SITE_ID] = $siteTwitterId; 1555f891b7eSNickeau } 1565f891b7eSNickeau 1575f891b7eSNickeau /** 1585f891b7eSNickeau * Card image 1595f891b7eSNickeau */ 160*04fd306cSNickeau try { 161*04fd306cSNickeau $twitterImagePath = TwitterImage::createFromResource($page)->getValueOrDefault(); 162*04fd306cSNickeau } catch (ExceptionNotFound $e) { 163*04fd306cSNickeau // no twitter image 164*04fd306cSNickeau return; 1655f891b7eSNickeau } 1665f891b7eSNickeau 167*04fd306cSNickeau if (!FileSystems::exists($twitterImagePath)) { 168*04fd306cSNickeau LogUtility::error("The twitter image ($twitterImagePath) does not exists.", self::CANONICAL); 169*04fd306cSNickeau return; 1705f891b7eSNickeau } 171*04fd306cSNickeau 172*04fd306cSNickeau try { 173*04fd306cSNickeau $twitterMeta[self::META_IMAGE] = FetcherRaster::createImageFetchFromPath($twitterImagePath)->getFetchUrl()->toAbsoluteUrlString(); 174*04fd306cSNickeau } catch (ExceptionBadArgument|ExceptionBadSyntax|ExceptionNotExists $e) { 175*04fd306cSNickeau LogUtility::error("Error with the twitter image url. " . $e->getMessage(), self::CANONICAL, $e); 176*04fd306cSNickeau return; 177*04fd306cSNickeau } 178*04fd306cSNickeau 179*04fd306cSNickeau $title = ResourceName::getFromPath($twitterImagePath); 18021913ab3SNickeau if (!empty($title)) { 18121913ab3SNickeau $twitterMeta[self::META_IMAGE_ALT] = $title; 1825f891b7eSNickeau } 1835f891b7eSNickeau 1845f891b7eSNickeau /** 1855f891b7eSNickeau * https://developer.twitter.com/en/docs/twitter-for-websites/webpage-properties 1865f891b7eSNickeau */ 18732b85071SNickeau // don't track 188*04fd306cSNickeau $twitterMeta[self::META_DNT] = $this->getConf(self::CONF_TWITTER_DONT_NOT_TRACK, self::CONF_ON); 1895f891b7eSNickeau // turn off csp warning 19032b85071SNickeau $twitterMeta[self::META_WIDGET_CSP] = "on"; 1915f891b7eSNickeau 1925f891b7eSNickeau /** 1935f891b7eSNickeau * Embedded Tweet Theme 1945f891b7eSNickeau */ 195*04fd306cSNickeau $twitterMeta[self::META_WIDGETS_THEME] = $this->getConf(BlockquoteTag::CONF_TWEET_WIDGETS_THEME, BlockquoteTag::CONF_TWEET_WIDGETS_THEME_DEFAULT); 196*04fd306cSNickeau $twitterMeta[self::META_WIDGETS_BORDER_COLOR] = $this->getConf(BlockquoteTag::CONF_TWEET_WIDGETS_BORDER, BlockquoteTag::CONF_TWEET_WIDGETS_BORDER_DEFAULT); 1975f891b7eSNickeau 1985f891b7eSNickeau /** 1995f891b7eSNickeau * Add the properties 2005f891b7eSNickeau */ 2015f891b7eSNickeau foreach ($twitterMeta as $key => $content) { 2025f891b7eSNickeau $event->data['meta'][] = array("name" => $key, "content" => $content); 2035f891b7eSNickeau } 2045f891b7eSNickeau 2055f891b7eSNickeau 2065f891b7eSNickeau } 2075f891b7eSNickeau 2085f891b7eSNickeau} 209