1<?php 2 3 4namespace ComboStrap; 5 6 7use ComboStrap\Meta\Api\Metadata; 8use ComboStrap\Meta\Api\MetadataStore; 9use ComboStrap\Meta\Api\MetadataText; 10use ComboStrap\Meta\Store\MetadataDokuWikiStore; 11use syntax_plugin_combo_frontmatter; 12 13class PageDescription extends MetadataText 14{ 15 16 /** 17 * The description sub key in the dokuwiki meta 18 * that has the description text 19 */ 20 const ABSTRACT_KEY = "abstract"; 21 public const PROPERTY_NAME = "description"; 22 const DESCRIPTION_ORIGIN = "origin"; 23 const PLUGIN_DESCRIPTION_META = "plugin_description"; 24 25 26 /** 27 * @var string - the origin of the description 28 */ 29 private $descriptionOrigin; 30 31 32 public const DESCRIPTION_PROPERTY = "description"; 33 /** 34 * To indicate from where the description comes 35 * This is when it's the original dokuwiki description 36 */ 37 public const DESCRIPTION_DOKUWIKI_ORIGIN = "dokuwiki"; 38 /** 39 * The origin of the description was set to frontmatter 40 * due to historic reason to say to it comes from combo 41 * (You may set it via the metadata manager and get this origin) 42 */ 43 public const DESCRIPTION_COMBO_ORIGIN = syntax_plugin_combo_frontmatter::CANONICAL; 44 private ?string $defaultValue = null; 45 46 public static function createForPage($page): PageDescription 47 { 48 return (new PageDescription()) 49 ->setResource($page); 50 } 51 52 public static function getTab(): string 53 { 54 return MetaManagerForm::TAB_PAGE_VALUE; 55 } 56 57 public static function getDescription(): string 58 { 59 return "The description is a paragraph that describe your page. It's advertised to external application and used in templating."; 60 } 61 62 public static function getLabel(): string 63 { 64 return "Description"; 65 } 66 67 static public function getName(): string 68 { 69 return self::DESCRIPTION_PROPERTY; 70 } 71 72 public static function getPersistenceType(): string 73 { 74 return MetadataDokuWikiStore::PERSISTENT_DOKUWIKI_KEY; 75 } 76 77 public static function getDataType(): string 78 { 79 return DataType::PARAGRAPH_TYPE_VALUE; 80 } 81 82 83 public static function isMutable(): bool 84 { 85 return true; 86 } 87 88 89 /** 90 * @return string 91 */ 92 public function getValueOrDefault(): string 93 { 94 95 try { 96 $value = $this->getValue(); 97 if (empty($value)) { 98 return $this->getDefaultValue(); 99 } 100 return $value; 101 } catch (ExceptionNotFound $e) { 102 return $this->getDefaultValue(); 103 } 104 105 106 } 107 108 109 /** 110 * @return string - the dokuwiki calculated description 111 * or the resource name if none (case when there is no text at all for instance with only a icon) 112 */ 113 public function getDefaultValue(): string 114 { 115 116 $this->buildCheck(); 117 if ($this->defaultValue === "" || $this->defaultValue === null) { 118 return PageTitle::createForMarkup($this->getResource()) 119 ->getValueOrDefault(); 120 } 121 return $this->defaultValue; 122 123 } 124 125 126 public function setFromStoreValueWithoutException($value): Metadata 127 { 128 129 $metaDataStore = $this->getReadStore(); 130 if (!$metaDataStore->isDokuWikiStore()) { 131 parent::setFromStoreValueWithoutException($value); 132 return $this; 133 } 134 135 if (is_array($value)) { 136 $description = $value[self::ABSTRACT_KEY]; 137 if ($description !== null) { 138 $descriptionOrigin = $value[self::DESCRIPTION_ORIGIN] ?? null; 139 if ($descriptionOrigin !== null) { 140 $this->descriptionOrigin = $descriptionOrigin; 141 parent::setFromStoreValueWithoutException($description); 142 return $this; 143 } 144 } 145 } 146 /** 147 * Plugin Plugin Description Integration 148 */ 149 $value = $metaDataStore->getFromName(self::PLUGIN_DESCRIPTION_META); 150 if ($value !== null) { 151 $keywords = $value["keywords"]; 152 if ($keywords !== null) { 153 parent::setFromStoreValueWithoutException($keywords); 154 $this->descriptionOrigin = self::PLUGIN_DESCRIPTION_META; 155 return $this; 156 } 157 } 158 159 /** 160 * No description set, null 161 */ 162 parent::setFromStoreValueWithoutException(null); 163 164 /** 165 * Default value is derived from the meta store 166 * We need to set it at build time because the store may change 167 * after the build 168 */ 169 $this->defaultValue = $this->getGeneratedValueFromDokuWikiStore($metaDataStore); 170 171 return $this; 172 } 173 174 175 public function setValue($value): Metadata 176 { 177 178 if ($value === "" || $value === null) { 179 180 if ($this->getReadStore() instanceof MetadataDokuWikiStore) { 181 // we need to know the origin of the actual description 182 if ($this->descriptionOrigin === null) { 183 /** 184 * we don't do {@link Metadata::buildCheck() build check} otherwise we get a loop 185 * because it will use back this method {@link Metadata::setValue()} 186 */ 187 $this->buildFromReadStore(); 188 } 189 if ($this->descriptionOrigin === PageDescription::DESCRIPTION_COMBO_ORIGIN) { 190 throw new ExceptionCompile("The description cannot be empty", PageDescription::DESCRIPTION_PROPERTY); 191 } else { 192 // The original description is from Dokuwiki, we don't send an error 193 // otherwise all page without a first description would get an error 194 // (What fucked up is fucked up) 195 return $this; 196 } 197 } 198 199 } 200 201 parent::setValue($value); 202 return $this; 203 } 204 205 /** 206 * @return ?string|array 207 */ 208 public function toStoreValue() 209 { 210 $metaDataStore = $this->getWriteStore(); 211 if (!($metaDataStore instanceof MetadataDokuWikiStore)) { 212 // A string 213 return parent::toStoreValue(); 214 } 215 /** 216 * For dokuwiki, this is an array 217 */ 218 try { 219 return array( 220 self::ABSTRACT_KEY => $this->getValue(), 221 self::DESCRIPTION_ORIGIN => PageDescription::DESCRIPTION_COMBO_ORIGIN 222 ); 223 } catch (ExceptionNotFound $e) { 224 return null; 225 } 226 } 227 228 229 public function getDescriptionOrigin(): string 230 { 231 return $this->descriptionOrigin; 232 } 233 234 private function getGeneratedValueFromDokuWikiStore(MetadataStore $metaDataStore): ?string 235 { 236 237 /** 238 * The generated is in the current metadata 239 */ 240 $descriptionArray = $metaDataStore->getFromName(self::PROPERTY_NAME); 241 if (empty($descriptionArray)) { 242 return null; 243 } 244 if (!array_key_exists(self::ABSTRACT_KEY, $descriptionArray)) { 245 return null; 246 } 247 $value = $descriptionArray[self::ABSTRACT_KEY]; 248 249 250 /** 251 * Dokuwiki description 252 * With some trick 253 * TODO: Generate our own description ? 254 */ 255 // suppress the carriage return 256 $description = str_replace("\n", " ", $value); 257 // suppress the h1 258 $resourceCombo = $this->getResource(); 259 if ($resourceCombo instanceof MarkupPath) { 260 $description = str_replace($resourceCombo->getH1OrDefault(), "", $description); 261 } 262 // Suppress the star, the tab, About 263 $description = preg_replace('/(\*|\t|About)/im', "", $description); 264 // Suppress all double space and trim 265 return trim(preg_replace('/ /m', " ", $description)); 266 } 267 268 269 public static function isOnForm(): bool 270 { 271 return true; 272 } 273} 274