1<?php 2 3 4use ComboStrap\ExceptionComboNotFound; 5use ComboStrap\Page; 6use ComboStrap\Site; 7 8/** 9 * Add all canonical HTML metadata 10 * 11 * In 1.14. we keep the name of the class with canonical to be able to update 12 * Above 1.15, in a release branch, you can just modify it 13 */ 14class action_plugin_combo_metacanonical 15{ 16 17 18 const APPLE_MOBILE_WEB_APP_TITLE_META = "apple-mobile-web-app-title"; 19 const APPLICATION_NAME_META = "application-name"; 20 21 public function register(Doku_Event_Handler $controller) 22 { 23 /** 24 * https://www.dokuwiki.org/devel:event:tpl_metaheader_output 25 */ 26 $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'htmlHeadMetadataProcessing', array()); 27 28 29 } 30 31 32 function htmlHeadMetadataProcessing($event) 33 { 34 35 global $ID; 36 if (empty($ID)) { 37 // $_SERVER['SCRIPT_NAME']== "/lib/exe/mediamanager.php" 38 // $ID is null 39 return; 40 } 41 42 $page = Page::createPageFromId($ID); 43 /** 44 * No metadata for slot page 45 */ 46 if ($page->isSecondarySlot()) { 47 return; 48 } 49 50 /** 51 * Add the canonical metadata value 52 */ 53 $this->canonicalHeadMetadata($event, $page); 54 /** 55 * Add the app name value 56 */ 57 $this->appNameMetadata($event, $page); 58 59 } 60 61 /** 62 * Dokuwiki has already a canonical methodology 63 * https://www.dokuwiki.org/canonical 64 * 65 */ 66 private function canonicalHeadMetadata($event, Page $page) 67 { 68 69 /** 70 * Where do we pick the canonical URL 71 * Canonical from meta 72 * 73 * FYI: The creation of the link was extracted from 74 * {@link wl()} that call {@link idfilter()} that performs just a replacement 75 * Calling the wl function will not work because 76 * {@link wl()} use the constant DOKU_URL that is set before any test via getBaseURL(true) 77 */ 78 $canonicalUrl = $page->getAbsoluteCanonicalUrl(); 79 80 /** 81 * Replace the meta entry 82 * 83 * First search the key of the meta array 84 */ 85 $canonicalKey = ""; 86 $canonicalRelArray = array("rel" => "canonical", "href" => $canonicalUrl); 87 foreach ($event->data['link'] as $key => $link) { 88 if ($link["rel"] == "canonical") { 89 $canonicalKey = $key; 90 } 91 } 92 if ($canonicalKey != "") { 93 // Update 94 $event->data['link'][$canonicalKey] = $canonicalRelArray; 95 } else { 96 // Add 97 $event->data['link'][] = $canonicalRelArray; 98 } 99 100 /** 101 * Add the Og canonical meta 102 * https://developers.facebook.com/docs/sharing/webmasters/getting-started/versioned-link/ 103 */ 104 $canonicalOgKeyKey = ""; 105 $canonicalPropertyKey = "og:url"; 106 $canonicalOgArray = array("property" => $canonicalPropertyKey, "content" => $canonicalUrl); 107 // Search if the canonical property is already present 108 foreach ($event->data['meta'] as $key => $meta) { 109 if (array_key_exists("property", $meta)) { 110 /** 111 * We may have several properties 112 */ 113 if ($meta["property"] == $canonicalPropertyKey) { 114 $canonicalOgKeyKey = $key; 115 } 116 } 117 } 118 if ($canonicalOgKeyKey != "") { 119 // Update 120 $event->data['meta'][$canonicalOgKeyKey] = $canonicalOgArray; 121 } else { 122 // Add 123 $event->data['meta'][] = $canonicalOgArray; 124 } 125 } 126 127 /** 128 * Add the following meta 129 * <meta name="apple-mobile-web-app-title" content="appName"> 130 * <meta name="application-name" content="appName"> 131 * 132 * @param $event 133 * @param Page $page 134 * @return void 135 */ 136 private function appNameMetadata($event, Page $page) 137 { 138 $applicationName = Site::getName(); 139 140 141 $applicationMetaNameValues = [ 142 self::APPLE_MOBILE_WEB_APP_TITLE_META, 143 self::APPLICATION_NAME_META 144 ]; 145 $metaNameKeyProperty = "name"; 146 foreach ($applicationMetaNameValues as $applicationNameValue){ 147 148 $appMobileWebAppTitle = array($metaNameKeyProperty => $applicationNameValue, "content" => $applicationName);; 149 try { 150 $metaKey = $this->getMetaArrayIndex($metaNameKeyProperty, $applicationNameValue, $event->data['meta']); 151 // Update 152 $event->data['meta'][$metaKey] = $appMobileWebAppTitle; 153 } catch (ExceptionComboNotFound $e) { 154 // Add 155 $event->data['meta'][] = $appMobileWebAppTitle; 156 } 157 } 158 159 160 } 161 162 /** 163 * @throws ExceptionComboNotFound 164 */ 165 private function getMetaArrayIndex(string $keyToSearch, string $keyValueToSearch, $metas) 166 { 167 // Search if the canonical property is already present 168 foreach ($metas as $metaKey => $metaValue) { 169 if (array_key_exists($keyToSearch, $metaValue)) { 170 /** 171 * We may have several properties 172 */ 173 if ($metaValue[$keyToSearch] == $keyValueToSearch) { 174 return $metaKey; 175 } 176 } 177 } 178 throw new ExceptionComboNotFound("The meta key {$keyToSearch} with the value {$keyValueToSearch} was not found"); 179 } 180 181 182} 183