1<?php 2 3use ComboStrap\MetadataUtility; 4use ComboStrap\PluginUtility; 5use ComboStrap\Page; 6 7if (!defined('DOKU_INC')) die(); 8 9/** 10 * 11 * 12 * * The name of the file should be the last name of the class 13 * * There should be only one name 14 */ 15class action_plugin_combo_metacanonical extends DokuWiki_Action_Plugin 16{ 17 18 /** 19 * The conf 20 */ 21 const CANONICAL_LAST_NAMES_COUNT_CONF = 'MinimalNamesCountForAutomaticCanonical'; 22 23 24 function __construct() 25 { 26 // enable direct access to language strings 27 // ie $this->lang 28 $this->setupLocale(); 29 } 30 31 public function register(Doku_Event_Handler $controller) 32 { 33 $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'metaCanonicalProcessing', array()); 34 } 35 36 /** 37 * Dokuwiki has already a canonical methodology 38 * https://www.dokuwiki.org/canonical 39 * 40 * @param $event 41 */ 42 function metaCanonicalProcessing($event) 43 { 44 global $ID; 45 global $conf; 46 47 /** 48 * Split the id by : 49 */ 50 $names = preg_split("/:/", $ID); 51 $namesLength = sizeOf($names); 52 53 /** 54 * No canonical for bars 55 */ 56 $bars = array($conf['sidebar']); 57 $strapTemplateName = 'strap'; 58 if ($conf['template'] === $strapTemplateName) { 59 $bars[] = $conf['tpl'][$strapTemplateName]['headerbar']; 60 $bars[] = $conf['tpl'][$strapTemplateName]['footerbar']; 61 $bars[] = $conf['tpl'][$strapTemplateName]['sidekickbar']; 62 } 63 if (in_array($names[$namesLength - 1], $bars)) { 64 return; 65 } 66 67 /** 68 * Where do we pick the canonical URL 69 */ 70 71 72 /** 73 * Canonical from meta 74 * 75 * FYI: The creation of the link was extracted from 76 * {@link wl()} that call {@link idfilter()} that performs just a replacement 77 * Calling the wl function will not work because 78 * {@link wl()} use the constant DOKU_URL that is set before any test via getBaseURL(true) 79 */ 80 81 $canonical = MetadataUtility::getMeta(Page::CANONICAL_PROPERTY); 82 83 /** 84 * The last part of the id as canonical 85 */ 86 // How many last parts are taken into account in the canonical processing (2 by default) 87 $canonicalLastNamesCount = $this->getConf(self::CANONICAL_LAST_NAMES_COUNT_CONF, 0); 88 if ($canonical == null && $canonicalLastNamesCount > 0) { 89 /** 90 * Takes the last names part 91 */ 92 if ($namesLength > $canonicalLastNamesCount) { 93 $names = array_slice($names, $namesLength - $canonicalLastNamesCount); 94 } 95 /** 96 * If this is a start page, delete the name 97 * ie javascript:start will become javascript 98 */ 99 if ($names[$namesLength - 1] == $conf['start']) { 100 $names = array_slice($names, 0, $namesLength - 1); 101 } 102 $canonical = implode(":", $names); 103 p_set_metadata($ID, array(Page::CANONICAL_PROPERTY => $canonical)); 104 } 105 106 $canonicalUrl = Page::getUrl($canonical); 107 108 /** 109 * Replace the meta entry 110 * 111 * First search the key of the meta array 112 */ 113 $canonicalKey = ""; 114 $canonicalRelArray = array("rel" => "canonical", "href" => $canonicalUrl); 115 foreach ($event->data['link'] as $key => $link) { 116 if ($link["rel"] == "canonical") { 117 $canonicalKey = $key; 118 } 119 } 120 if ($canonicalKey != "") { 121 // Update 122 $event->data['link'][$canonicalKey] = $canonicalRelArray; 123 } else { 124 // Add 125 $event->data['link'][] = $canonicalRelArray; 126 } 127 128 /** 129 * Add the Og canonical meta 130 * https://developers.facebook.com/docs/sharing/webmasters/getting-started/versioned-link/ 131 */ 132 $canonicalOgKeyKey = ""; 133 $canonicalPropertyKey = "og:url"; 134 $canonicalOgArray = array("property" => $canonicalPropertyKey, "content" => $canonicalUrl); 135 foreach ($event->data['meta'] as $key => $meta) { 136 if ($meta["property"] == $canonicalPropertyKey) { 137 $canonicalOgKeyKey = $key; 138 } 139 } 140 if ($canonicalOgKeyKey != "") { 141 // Update 142 $event->data['meta'][$canonicalOgKeyKey] = $canonicalOgArray; 143 } else { 144 // Add 145 $event->data['meta'][] = $canonicalOgArray; 146 } 147 148 } 149 150} 151