1<?php 2 3use ComboStrap\BlockquoteTag; 4use ComboStrap\ExceptionBadArgument; 5use ComboStrap\ExceptionBadSyntax; 6use ComboStrap\ExceptionNotExists; 7use ComboStrap\ExecutionContext; 8use ComboStrap\FetcherRaster; 9use ComboStrap\Meta\Field\TwitterImage; 10use ComboStrap\Site; 11use ComboStrap\SiteConfig; 12use ComboStrap\WikiPath; 13use ComboStrap\ExceptionCompile; 14use ComboStrap\ExceptionNotFound; 15use ComboStrap\IFetcherLocalImage; 16use ComboStrap\FileSystems; 17use ComboStrap\LogUtility; 18use ComboStrap\MarkupPath; 19use ComboStrap\PageImageUsage; 20use ComboStrap\PluginUtility; 21use ComboStrap\ResourceName; 22use ComboStrap\StringUtility; 23 24 25require_once(__DIR__ . '/../ComboStrap/Site.php'); 26 27/** 28 * 29 * For the canonical meta, see {@link action_plugin_combo_metacanonical} 30 * https://github.com/twbs/bootstrap/blob/v4-dev/site/layouts/partials/social.html 31 * 32 * TODO: https://developer.twitter.com/en/docs/twitter-for-websites/embedded-tweets/overview 33 */ 34class action_plugin_combo_metatwitter extends DokuWiki_Action_Plugin 35{ 36 37 38 /** 39 * The handle name 40 */ 41 const CONF_TWITTER_SITE_HANDLE = "twitterSiteHandle"; 42 /** 43 * The handle id 44 */ 45 const CONF_TWITTER_SITE_ID = "twitterSiteId"; 46 47 /** 48 * Don't track 49 */ 50 const CONF_TWITTER_DONT_NOT_TRACK = self::META_DNT; 51 const CONF_DONT_NOT_TRACK = self::META_DNT; 52 const CONF_ON = "on"; 53 const CONF_OFF = "off"; 54 55 /** 56 * The creation ie (combostrap) 57 */ 58 const COMBO_STRAP_TWITTER_HANDLE = "@combostrapweb"; 59 const COMBO_STRAP_TWITTER_ID = "1283330969332842497"; 60 const CANONICAL = "twitter"; 61 62 const META_CARD = "twitter:card"; 63 const DEFAULT_IMAGE = ":apple-touch-icon.png"; 64 const META_DESCRIPTION = "twitter:description"; 65 const META_IMAGE = "twitter:image"; 66 const META_TITLE = "twitter:title"; 67 const META_CREATOR = "twitter:creator"; 68 const META_CREATOR_ID = "twitter:creator:id"; 69 const META_SITE = "twitter:site"; 70 const META_SITE_ID = "twitter:site:id"; 71 const META_IMAGE_ALT = "twitter:image:alt"; 72 const META_DNT = "twitter:dnt"; 73 const META_WIDGET_CSP = "twitter:widgets:csp"; 74 const META_WIDGETS_THEME = "twitter:widgets:theme"; 75 const META_WIDGETS_BORDER_COLOR = "twitter:widgets:border-color"; 76 77 78 function __construct() 79 { 80 // enable direct access to language strings 81 // ie $this->lang 82 $this->setupLocale(); 83 } 84 85 public function register(Doku_Event_Handler $controller) 86 { 87 $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'metaTwitterProcessing', array()); 88 } 89 90 /** 91 * 92 * @param $event 93 */ 94 function metaTwitterProcessing($event) 95 { 96 97 $executionContext = ExecutionContext::getActualOrCreateFromEnv(); 98 99 try { 100 $templateForWebPage = $executionContext->getExecutingPageTemplate(); 101 if(!$templateForWebPage->isSocial()){ 102 return; 103 } 104 $page = MarkupPath::createPageFromPathObject($templateForWebPage->getRequestedContextPath()); 105 } catch (ExceptionNotFound $e) { 106 return; 107 } 108 109 110 if (!FileSystems::exists($page)) { 111 return; 112 } 113 114 /** 115 * No social for bars 116 */ 117 if ($page->isSlot()) { 118 return; 119 } 120 121 122 // https://datacadamia.com/marketing/twitter#html_meta 123 // https://developer.twitter.com/en/docs/twitter-for-websites/cards/overview/markup 124 // https://cards-dev.twitter.com/validator 125 126 127 $twitterMeta = array( 128 self::META_CARD => "summary", 129 self::META_TITLE => StringUtility::truncateString($page->getTitleOrDefault(), 70), 130 self::META_CREATOR => self::COMBO_STRAP_TWITTER_HANDLE, 131 self::META_CREATOR_ID => self::COMBO_STRAP_TWITTER_ID 132 ); 133 $description = $page->getDescriptionOrElseDokuWiki(); 134 if (!empty($description)) { 135 // happens in test with document without content 136 $twitterMeta[self::META_DESCRIPTION] = StringUtility::truncateString($description, 200); 137 } 138 139 140 /** 141 * Twitter site 142 */ 143 $siteTwitterHandle = $this->getConf(self::CONF_TWITTER_SITE_HANDLE); 144 $siteTwitterId = $this->getConf(self::CONF_TWITTER_SITE_ID); 145 if (!empty($siteTwitterHandle)) { 146 $twitterMeta[self::META_SITE] = $siteTwitterHandle; 147 148 // Identify the Twitter profile of the page that populates the via property 149 // https://developer.twitter.com/en/docs/twitter-for-websites/webpage-properties 150 $name = str_replace("@", "", $siteTwitterHandle); 151 $event->data['link'][] = array("rel" => "me", "href" => "https://twitter.com/$name"); 152 } 153 if (!empty($siteTwitterId)) { 154 $twitterMeta[self::META_SITE_ID] = $siteTwitterId; 155 } 156 157 /** 158 * Card image 159 */ 160 try { 161 $twitterImagePath = TwitterImage::createFromResource($page)->getValueOrDefault(); 162 } catch (ExceptionNotFound $e) { 163 // no twitter image 164 return; 165 } 166 167 if (!FileSystems::exists($twitterImagePath)) { 168 LogUtility::error("The twitter image ($twitterImagePath) does not exists.", self::CANONICAL); 169 return; 170 } 171 172 try { 173 $twitterMeta[self::META_IMAGE] = FetcherRaster::createImageFetchFromPath($twitterImagePath)->getFetchUrl()->toAbsoluteUrlString(); 174 } catch (ExceptionBadArgument|ExceptionBadSyntax|ExceptionNotExists $e) { 175 LogUtility::error("Error with the twitter image url. " . $e->getMessage(), self::CANONICAL, $e); 176 return; 177 } 178 179 $title = ResourceName::getFromPath($twitterImagePath); 180 if (!empty($title)) { 181 $twitterMeta[self::META_IMAGE_ALT] = $title; 182 } 183 184 /** 185 * https://developer.twitter.com/en/docs/twitter-for-websites/webpage-properties 186 */ 187 // don't track 188 $twitterMeta[self::META_DNT] = $this->getConf(self::CONF_TWITTER_DONT_NOT_TRACK, self::CONF_ON); 189 // turn off csp warning 190 $twitterMeta[self::META_WIDGET_CSP] = "on"; 191 192 /** 193 * Embedded Tweet Theme 194 */ 195 $twitterMeta[self::META_WIDGETS_THEME] = $this->getConf(BlockquoteTag::CONF_TWEET_WIDGETS_THEME, BlockquoteTag::CONF_TWEET_WIDGETS_THEME_DEFAULT); 196 $twitterMeta[self::META_WIDGETS_BORDER_COLOR] = $this->getConf(BlockquoteTag::CONF_TWEET_WIDGETS_BORDER, BlockquoteTag::CONF_TWEET_WIDGETS_BORDER_DEFAULT); 197 198 /** 199 * Add the properties 200 */ 201 foreach ($twitterMeta as $key => $content) { 202 $event->data['meta'][] = array("name" => $key, "content" => $content); 203 } 204 205 206 } 207 208} 209