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