Lexer->addSpecialPattern(self::PATTERN, $mode, PluginUtility::getModeFromTag($this->getPluginComponent())); } } /** * * The handle function goal is to parse the matched syntax through the pattern function * and to return the result for use in the renderer * This result is always cached until the page is modified. * @param string $match * @param int $state * @param int $pos * @param Doku_Handler $handler * @return array|bool * @see DokuWiki_Syntax_Plugin::handle() * */ function handle($match, $state, $pos, Doku_Handler $handler) { if ($state == DOKU_LEXER_SPECIAL) { $result = []; $page = Page::createPageFromGlobalDokuwikiId(); try { $frontMatterStore = MetadataFrontmatterStore::createFromFrontmatterString($page, $match); $result[self::STATUS] = self::PARSING_STATE_SUCCESSFUL; } catch (ExceptionCombo $e) { // Decode problem $result[self::STATUS] = self::PARSING_STATE_ERROR; $result[PluginUtility::PAYLOAD] = $match; return $result; } /** * Empty string * Rare case, we delete all mutable meta if present */ $frontmatterData = $frontMatterStore->getData(); if ($frontmatterData === null) { global $ID; $meta = p_read_metadata($ID); foreach (Metadata::MUTABLE_METADATA as $metaKey) { if (isset($meta['persistent'][$metaKey])) { unset($meta['persistent'][$metaKey]); } } p_save_metadata($ID, $meta); return array(self::STATUS => self::PARSING_STATE_EMPTY); } /** * Sync */ $targetStore = MetadataDokuWikiStore::getOrCreateFromResource($page); $transfer = MetadataStoreTransfer::createForPage($page) ->fromStore($frontMatterStore) ->toStore($targetStore) ->process($frontmatterData); $messages = $transfer->getMessages(); $dataForRenderer = $transfer->getNormalizedDataArray(); /** * Database update */ try { $databasePage = $page->getDatabasePage(); $databasePage->replicateMetaAttributes(); } catch (Exception $e) { $message = Message::createErrorMessage($e->getMessage()); if ($e instanceof ExceptionCombo) { $message->setCanonical($e->getCanonical()); } $messages[] = $message; } foreach ($messages as $message) { $message->sendLogMsg(); } /** * Return them for metadata rendering */ $result[PluginUtility::ATTRIBUTES] = $dataForRenderer; } /** * End position is the length of the match + 1 for the newline */ $newLine = 1; $endPosition = $pos + strlen($match) + $newLine; $result[PluginUtility::POSITION] = [$pos, $endPosition]; return $result; } /** * Render the output * @param string $format * @param Doku_Renderer $renderer * @param array $data - what the function handle() return'ed * @return boolean - rendered correctly? (however, returned value is not used at the moment) * @see DokuWiki_Syntax_Plugin::render() * * */ function render($format, Doku_Renderer $renderer, $data): bool { switch ($format) { case 'xhtml': global $ID; /** @var Doku_Renderer_xhtml $renderer */ $state = $data[self::STATUS]; if ($state == self::PARSING_STATE_ERROR) { $json = MetadataFrontmatterStore::stripFrontmatterTag($data[PluginUtility::PAYLOAD]); LogUtility::msg("Front Matter: The json object for the page ($ID) is not valid. " . \ComboStrap\Json::getValidationLink($json), LogUtility::LVL_MSG_ERROR); } /** * Section */ list($startPosition, $endPosition) = $data[PluginUtility::POSITION]; if (PluginUtility::getConfValue(self::CONF_ENABLE_SECTION_EDITING, 1)) { $position = $startPosition; $name = self::CANONICAL; PluginUtility::startSection($renderer, $position, $name); $renderer->finishSectionEdit($endPosition); } break; case renderer_plugin_combo_analytics::RENDERER_FORMAT: if ($data[self::STATUS] != self::PARSING_STATE_SUCCESSFUL) { return false; } /** @var renderer_plugin_combo_analytics $renderer */ $frontMatterJsonArray = $data[PluginUtility::ATTRIBUTES]; foreach ($frontMatterJsonArray as $key => $value) { $renderer->setAnalyticsMetaForReporting($key, $value); if ($key === PageImages::PROPERTY_NAME) { $this->updateImageStatistics($value, $renderer); } } break; case "metadata": global $ID; /** @var Doku_Renderer_metadata $renderer */ if ($data[self::STATUS] === self::PARSING_STATE_ERROR) { if (PluginUtility::isDevOrTest()) { // fail if test throw new ExceptionComboRuntime("Front Matter: The json object for the page ($ID) is not valid.", LogUtility::LVL_MSG_ERROR); } return false; } /** * Register media in index */ $page = Page::createPageFromId($ID); $frontMatterJsonArray = $data[PluginUtility::ATTRIBUTES]; if (isset($frontMatterJsonArray[PageImages::getPersistentName()])) { $value = $frontMatterJsonArray[PageImages::getPersistentName()]; /** * @var PageImages $pageImages */ $pageImages = PageImages::createForPage($page) ->buildFromStoreValue($value); $pageImagesObject = $pageImages->getValueAsPageImages(); foreach ($pageImagesObject as $imageValue) { $imagePath = $imageValue->getImage()->getPath()->toAbsolutePath()->toString(); $attributes = [PagePath::PROPERTY_NAME => $imagePath]; if (media_isexternal($imagePath)) { $attributes[MediaLink::MEDIA_DOKUWIKI_TYPE] = MediaLink::EXTERNAL_MEDIA_CALL_NAME; } else { $attributes[MediaLink::MEDIA_DOKUWIKI_TYPE] = MediaLink::INTERNAL_MEDIA_CALL_NAME; } syntax_plugin_combo_media::registerImageMeta($attributes, $renderer); } } break; } return true; } private function updateImageStatistics($value, $renderer) { if (is_array($value) && sizeof($value) > 0) { $firstKey = array_keys($value)[0]; if (is_numeric($firstKey)) { foreach ($value as $subImage) { $this->updateImageStatistics($subImage, $renderer); } return; } } /** * Code below is fucked up */ $path = $value; if (is_array($value) && isset($value[PageImagePath::getPersistentName()])) { $path = $value[PageImagePath::getPersistentName()]; } $media = MediaLink::createFromRenderMatch($path); $attributes = $media->toCallStackArray(); syntax_plugin_combo_media::updateStatistics($attributes, $renderer); } }