1007225e5Sgerardnico<?php 2007225e5Sgerardnico 3c3437056SNickeau 43dc080c1Sgerardnicouse ComboStrap\ExceptionComboNotFound; 571f916b9Sgerardnicouse ComboStrap\Page; 63dc080c1Sgerardnicouse ComboStrap\Site; 7007225e5Sgerardnico 8007225e5Sgerardnico/** 93dc080c1Sgerardnico * Add all canonical HTML metadata 103dc080c1Sgerardnico * 113dc080c1Sgerardnico * In 1.14. we keep the name of the class with canonical to be able to update 123dc080c1Sgerardnico * Above 1.15, in a release branch, you can just modify it 13007225e5Sgerardnico */ 14c3437056SNickeauclass action_plugin_combo_metacanonical 15007225e5Sgerardnico{ 16007225e5Sgerardnico 17007225e5Sgerardnico 183dc080c1Sgerardnico const APPLE_MOBILE_WEB_APP_TITLE_META = "apple-mobile-web-app-title"; 193dc080c1Sgerardnico const APPLICATION_NAME_META = "application-name"; 203dc080c1Sgerardnico 21007225e5Sgerardnico public function register(Doku_Event_Handler $controller) 22007225e5Sgerardnico { 2385e82846SNickeau /** 2485e82846SNickeau * https://www.dokuwiki.org/devel:event:tpl_metaheader_output 2585e82846SNickeau */ 263dc080c1Sgerardnico $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'htmlHeadMetadataProcessing', array()); 27c3437056SNickeau 28c3437056SNickeau 29007225e5Sgerardnico } 30007225e5Sgerardnico 313dc080c1Sgerardnico 323dc080c1Sgerardnico function htmlHeadMetadataProcessing($event) 33007225e5Sgerardnico { 34007225e5Sgerardnico 355f891b7eSNickeau global $ID; 365f891b7eSNickeau if (empty($ID)) { 375f891b7eSNickeau // $_SERVER['SCRIPT_NAME']== "/lib/exe/mediamanager.php" 389da76789Sgerardnico // $ID is null 399da76789Sgerardnico return; 409da76789Sgerardnico } 419da76789Sgerardnico 4285e82846SNickeau $page = Page::createPageFromId($ID); 43007225e5Sgerardnico /** 443dc080c1Sgerardnico * No metadata for slot page 45007225e5Sgerardnico */ 464cadd4f8SNickeau if ($page->isSecondarySlot()) { 47007225e5Sgerardnico return; 48007225e5Sgerardnico } 49007225e5Sgerardnico 50007225e5Sgerardnico /** 513dc080c1Sgerardnico * Add the canonical metadata value 52007225e5Sgerardnico */ 533dc080c1Sgerardnico $this->canonicalHeadMetadata($event, $page); 54007225e5Sgerardnico /** 553dc080c1Sgerardnico * Add the app name value 563dc080c1Sgerardnico */ 573dc080c1Sgerardnico $this->appNameMetadata($event, $page); 583dc080c1Sgerardnico 593dc080c1Sgerardnico } 603dc080c1Sgerardnico 613dc080c1Sgerardnico /** 623dc080c1Sgerardnico * Dokuwiki has already a canonical methodology 633dc080c1Sgerardnico * https://www.dokuwiki.org/canonical 643dc080c1Sgerardnico * 653dc080c1Sgerardnico */ 663dc080c1Sgerardnico private function canonicalHeadMetadata($event, Page $page) 673dc080c1Sgerardnico { 683dc080c1Sgerardnico 693dc080c1Sgerardnico /** 703dc080c1Sgerardnico * Where do we pick the canonical URL 71007225e5Sgerardnico * Canonical from meta 72007225e5Sgerardnico * 73007225e5Sgerardnico * FYI: The creation of the link was extracted from 74007225e5Sgerardnico * {@link wl()} that call {@link idfilter()} that performs just a replacement 75007225e5Sgerardnico * Calling the wl function will not work because 76007225e5Sgerardnico * {@link wl()} use the constant DOKU_URL that is set before any test via getBaseURL(true) 77007225e5Sgerardnico */ 78c3437056SNickeau $canonicalUrl = $page->getAbsoluteCanonicalUrl(); 79007225e5Sgerardnico 80007225e5Sgerardnico /** 81007225e5Sgerardnico * Replace the meta entry 82007225e5Sgerardnico * 83007225e5Sgerardnico * First search the key of the meta array 84007225e5Sgerardnico */ 85007225e5Sgerardnico $canonicalKey = ""; 86007225e5Sgerardnico $canonicalRelArray = array("rel" => "canonical", "href" => $canonicalUrl); 87007225e5Sgerardnico foreach ($event->data['link'] as $key => $link) { 88007225e5Sgerardnico if ($link["rel"] == "canonical") { 89007225e5Sgerardnico $canonicalKey = $key; 90007225e5Sgerardnico } 91007225e5Sgerardnico } 92007225e5Sgerardnico if ($canonicalKey != "") { 93007225e5Sgerardnico // Update 94007225e5Sgerardnico $event->data['link'][$canonicalKey] = $canonicalRelArray; 95007225e5Sgerardnico } else { 96007225e5Sgerardnico // Add 97007225e5Sgerardnico $event->data['link'][] = $canonicalRelArray; 98007225e5Sgerardnico } 99007225e5Sgerardnico 100007225e5Sgerardnico /** 101007225e5Sgerardnico * Add the Og canonical meta 102007225e5Sgerardnico * https://developers.facebook.com/docs/sharing/webmasters/getting-started/versioned-link/ 103007225e5Sgerardnico */ 104007225e5Sgerardnico $canonicalOgKeyKey = ""; 105007225e5Sgerardnico $canonicalPropertyKey = "og:url"; 106007225e5Sgerardnico $canonicalOgArray = array("property" => $canonicalPropertyKey, "content" => $canonicalUrl); 107ebdc69ceSgerardnico // Search if the canonical property is already present 108007225e5Sgerardnico foreach ($event->data['meta'] as $key => $meta) { 109ebdc69ceSgerardnico if (array_key_exists("property", $meta)) { 110ebdc69ceSgerardnico /** 111ebdc69ceSgerardnico * We may have several properties 112ebdc69ceSgerardnico */ 113007225e5Sgerardnico if ($meta["property"] == $canonicalPropertyKey) { 114007225e5Sgerardnico $canonicalOgKeyKey = $key; 115007225e5Sgerardnico } 116007225e5Sgerardnico } 117ebdc69ceSgerardnico } 118007225e5Sgerardnico if ($canonicalOgKeyKey != "") { 119007225e5Sgerardnico // Update 120007225e5Sgerardnico $event->data['meta'][$canonicalOgKeyKey] = $canonicalOgArray; 121007225e5Sgerardnico } else { 122007225e5Sgerardnico // Add 123007225e5Sgerardnico $event->data['meta'][] = $canonicalOgArray; 124007225e5Sgerardnico } 1253dc080c1Sgerardnico } 1263dc080c1Sgerardnico 1273dc080c1Sgerardnico /** 1283dc080c1Sgerardnico * Add the following meta 1293dc080c1Sgerardnico * <meta name="apple-mobile-web-app-title" content="appName"> 1303dc080c1Sgerardnico * <meta name="application-name" content="appName"> 1313dc080c1Sgerardnico * 1323dc080c1Sgerardnico * @param $event 1333dc080c1Sgerardnico * @param Page $page 1343dc080c1Sgerardnico * @return void 1353dc080c1Sgerardnico */ 1363dc080c1Sgerardnico private function appNameMetadata($event, Page $page) 1373dc080c1Sgerardnico { 1383dc080c1Sgerardnico $applicationName = Site::getName(); 1393dc080c1Sgerardnico 1403dc080c1Sgerardnico 1413dc080c1Sgerardnico $applicationMetaNameValues = [ 1423dc080c1Sgerardnico self::APPLE_MOBILE_WEB_APP_TITLE_META, 1433dc080c1Sgerardnico self::APPLICATION_NAME_META 1443dc080c1Sgerardnico ]; 1453dc080c1Sgerardnico $metaNameKeyProperty = "name"; 1463dc080c1Sgerardnico foreach ($applicationMetaNameValues as $applicationNameValue){ 1473dc080c1Sgerardnico 1483dc080c1Sgerardnico $appMobileWebAppTitle = array($metaNameKeyProperty => $applicationNameValue, "content" => $applicationName);; 1493dc080c1Sgerardnico try { 1503dc080c1Sgerardnico $metaKey = $this->getMetaArrayIndex($metaNameKeyProperty, $applicationNameValue, $event->data['meta']); 1513dc080c1Sgerardnico // Update 1523dc080c1Sgerardnico $event->data['meta'][$metaKey] = $appMobileWebAppTitle; 1533dc080c1Sgerardnico } catch (ExceptionComboNotFound $e) { 1543dc080c1Sgerardnico // Add 1553dc080c1Sgerardnico $event->data['meta'][] = $appMobileWebAppTitle; 1563dc080c1Sgerardnico } 1573dc080c1Sgerardnico } 1583dc080c1Sgerardnico 159007225e5Sgerardnico 160007225e5Sgerardnico } 161007225e5Sgerardnico 1623dc080c1Sgerardnico /** 1633dc080c1Sgerardnico * @throws ExceptionComboNotFound 1643dc080c1Sgerardnico */ 165*0db54741Sgerardnico private function getMetaArrayIndex(string $keyToSearch, string $keyValueToSearch, $metas) 1663dc080c1Sgerardnico { 1673dc080c1Sgerardnico // Search if the canonical property is already present 168*0db54741Sgerardnico foreach ($metas as $metaKey => $metaValue) { 169*0db54741Sgerardnico if (array_key_exists($keyToSearch, $metaValue)) { 1703dc080c1Sgerardnico /** 1713dc080c1Sgerardnico * We may have several properties 1723dc080c1Sgerardnico */ 173*0db54741Sgerardnico if ($metaValue[$keyToSearch] == $keyValueToSearch) { 174*0db54741Sgerardnico return $metaKey; 1753dc080c1Sgerardnico } 1763dc080c1Sgerardnico } 1773dc080c1Sgerardnico } 178*0db54741Sgerardnico throw new ExceptionComboNotFound("The meta key {$keyToSearch} with the value {$keyValueToSearch} was not found"); 1793dc080c1Sgerardnico } 1803dc080c1Sgerardnico 1813dc080c1Sgerardnico 182007225e5Sgerardnico} 183