1<?php 2 3 4namespace ComboStrap; 5 6 7class Canonical extends MetadataWikiPath 8{ 9 10 public const PROPERTY_NAME = "canonical"; 11 public const CANONICAL = "canonical"; 12 13 /** 14 * The auto-canonical feature does not create any canonical value on the file system 15 * but creates a canonical in the database (where the {@link \action_plugin_combo_router} 16 * takes its information and it enables to route via a calculated canonical 17 * (ie the {@link Canonical::getDefaultValue()} 18 */ 19 public const CONF_CANONICAL_LAST_NAMES_COUNT = 'MinimalNamesCountForAutomaticCanonical'; 20 21 public static function createForPage(Page $page): Canonical 22 { 23 return (new Canonical()) 24 ->setResource($page); 25 26 } 27 28 public function getTab(): string 29 { 30 return MetaManagerForm::TAB_REDIRECTION_VALUE; 31 } 32 33 public function getDescription(): string 34 { 35 return "The canonical path is a short unique path for the page (used in named permalink)"; 36 } 37 38 public function getLabel(): string 39 { 40 return "Canonical Path"; 41 } 42 43 public static function getName(): string 44 { 45 return self::PROPERTY_NAME; 46 } 47 48 public function getPersistenceType(): string 49 { 50 return MetadataDokuWikiStore::PERSISTENT_METADATA; 51 } 52 53 public function getMutable(): bool 54 { 55 return true; 56 } 57 58 public function getDefaultValue(): ?string 59 { 60 /** 61 * The last part of the id as canonical 62 */ 63 // How many last parts are taken into account in the canonical processing (2 by default) 64 $canonicalLastNamesCount = PluginUtility::getConfValue(self::CONF_CANONICAL_LAST_NAMES_COUNT, 0); 65 if ($canonicalLastNamesCount > 0) { 66 /** 67 * Takes the last names part 68 */ 69 $namesOriginal = $this->getResource()->getPath()->getNames(); 70 /** 71 * Delete the identical names at the end 72 * To resolve this problem 73 * The page (viz:viz) and the page (data:viz:viz) have the same canonical. 74 * The page (viz:viz) will get the canonical viz 75 * The page (data:viz) will get the canonical data:viz 76 */ 77 $i = sizeof($namesOriginal) - 1; 78 $names = $namesOriginal; 79 while ($namesOriginal[$i] == $namesOriginal[$i - 1]) { 80 unset($names[$i]); 81 $i--; 82 if ($i <= 0) { 83 break; 84 } 85 } 86 /** 87 * Minimal length check 88 */ 89 $namesLength = sizeof($names); 90 if ($namesLength > $canonicalLastNamesCount) { 91 $names = array_slice($names, $namesLength - $canonicalLastNamesCount); 92 } 93 /** 94 * If this is a `start` page, delete the name 95 * ie javascript:start will become javascript 96 * (Not a home page) 97 */ 98 if ($this->getResource()->isStartPage()) { 99 $names = array_slice($names, 0, $namesLength - 1); 100 } 101 $calculatedCanonical = implode(":", $names); 102 DokuPath::addRootSeparatorIfNotPresent($calculatedCanonical); 103 return $calculatedCanonical; 104 } 105 return null; 106 } 107 108 public function getCanonical(): string 109 { 110 return self::CANONICAL; 111 } 112 113 114} 115