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