15f891b7eSNickeau<?php 25f891b7eSNickeau 3*654a02feSgerardnicouse ComboStrap\DokuPath; 45f891b7eSNickeauuse ComboStrap\LogUtility; 55f891b7eSNickeauuse ComboStrap\PluginUtility; 6*654a02feSgerardnicouse ComboStrap\Resources; 78aa9d0e6Sgerardnicouse ComboStrap\Site; 85f891b7eSNickeauuse ComboStrap\SnippetManager; 98aa9d0e6Sgerardnicouse dokuwiki\Cache\CacheRenderer; 105f891b7eSNickeau 115f891b7eSNickeauif (!defined('DOKU_INC')) die(); 125f891b7eSNickeau 135f891b7eSNickeau/** 145f891b7eSNickeau * 155f891b7eSNickeau * 165f891b7eSNickeau * Add the snippet needed by the components 175f891b7eSNickeau * 185f891b7eSNickeau */ 195f891b7eSNickeauclass action_plugin_combo_snippets extends DokuWiki_Action_Plugin 205f891b7eSNickeau{ 215f891b7eSNickeau 228aa9d0e6Sgerardnico const COMBO_CACHE_PREFIX = "combo:cache:"; 235f891b7eSNickeau 245f891b7eSNickeau /** 255f891b7eSNickeau * @var bool - to trace if the header output was called 265f891b7eSNickeau */ 275f891b7eSNickeau private $headerOutputWasCalled = false; 285f891b7eSNickeau 295f891b7eSNickeau function __construct() 305f891b7eSNickeau { 315f891b7eSNickeau // enable direct access to language strings 325f891b7eSNickeau // ie $this->lang 335f891b7eSNickeau $this->setupLocale(); 345f891b7eSNickeau } 355f891b7eSNickeau 365f891b7eSNickeau public function register(Doku_Event_Handler $controller) 375f891b7eSNickeau { 388aa9d0e6Sgerardnico 3921913ab3SNickeau /** 4021913ab3SNickeau * To add the snippets in the header 4121913ab3SNickeau */ 425f891b7eSNickeau $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'componentSnippetHead', array()); 4321913ab3SNickeau 4421913ab3SNickeau /** 4521913ab3SNickeau * To add the snippets in the content 4621913ab3SNickeau * if they have not been added to the header 4721913ab3SNickeau */ 485f891b7eSNickeau $controller->register_hook('TPL_CONTENT_DISPLAY', 'BEFORE', $this, 'componentSnippetContent', array()); 498aa9d0e6Sgerardnico 5021913ab3SNickeau /** 5121913ab3SNickeau * To reset the value 5221913ab3SNickeau */ 5321913ab3SNickeau $controller->register_hook('DOKUWIKI_DONE', 'BEFORE', $this, 'close', array()); 548aa9d0e6Sgerardnico 5521913ab3SNickeau 5621913ab3SNickeau /** 5721913ab3SNickeau * To log the cache used by bar 5821913ab3SNickeau */ 598aa9d0e6Sgerardnico $controller->register_hook('PARSER_CACHE_USE', 'AFTER', $this, 'barParsed', array()); 608aa9d0e6Sgerardnico 615f891b7eSNickeau } 625f891b7eSNickeau 635f891b7eSNickeau /** 6432b85071SNickeau * Reset variable 6532b85071SNickeau * Otherwise in test, when we call it two times, it just fail 6632b85071SNickeau */ 6721913ab3SNickeau function close() 6821913ab3SNickeau { 6932b85071SNickeau 7032b85071SNickeau $this->headerOutputWasCalled = false; 7132b85071SNickeau 7232b85071SNickeau /** 7332b85071SNickeau * Fighting the fact that in 7.2, 7432b85071SNickeau * there is still a cache 7532b85071SNickeau */ 7632b85071SNickeau PluginUtility::initSnippetManager(); 7732b85071SNickeau 7832b85071SNickeau } 7932b85071SNickeau 8032b85071SNickeau /** 815f891b7eSNickeau * Dokuwiki has already a canonical methodology 825f891b7eSNickeau * https://www.dokuwiki.org/canonical 835f891b7eSNickeau * 845f891b7eSNickeau * @param $event 855f891b7eSNickeau */ 865f891b7eSNickeau function componentSnippetHead($event) 875f891b7eSNickeau { 885f891b7eSNickeau 895f891b7eSNickeau 905f891b7eSNickeau global $ID; 915f891b7eSNickeau if (empty($ID)) { 9221913ab3SNickeau global $_SERVER; 9321913ab3SNickeau $requestUri = $_SERVER['REQUEST_URI']; 9421913ab3SNickeau if (!strpos($requestUri, "/lib/exe/ajax.php") !== false) { 9521913ab3SNickeau global $_REQUEST; 9621913ab3SNickeau $call = $_REQUEST['call']; 9721913ab3SNickeau if ($call != action_plugin_combo_webcode::CALL_ID) { 985f891b7eSNickeau return; 995f891b7eSNickeau } 10021913ab3SNickeau } 10121913ab3SNickeau } 1025f891b7eSNickeau 1035f891b7eSNickeau /** 1045f891b7eSNickeau * Advertise that the header output was called 1055f891b7eSNickeau * If the user is using another template 1065f891b7eSNickeau * than strap that does not put the component snippet 1075f891b7eSNickeau * in the head 1085f891b7eSNickeau * Used in 1095f891b7eSNickeau */ 1105f891b7eSNickeau $this->headerOutputWasCalled = true; 1115f891b7eSNickeau 1125f891b7eSNickeau $snippetManager = PluginUtility::getSnippetManager(); 1135f891b7eSNickeau 1145f891b7eSNickeau /** 1158aa9d0e6Sgerardnico * For each processed bar in the page 1168aa9d0e6Sgerardnico * * retrieve the snippets from the cache or store the process one 1178aa9d0e6Sgerardnico * * add the cache information in meta 1185f891b7eSNickeau */ 1198aa9d0e6Sgerardnico $bars = $snippetManager->getBarsOfPage(); 120*654a02feSgerardnico foreach ($bars as $barId => $servedFromCache) { 1218aa9d0e6Sgerardnico 12221913ab3SNickeau // Add cache information into the head meta 123*654a02feSgerardnico $event->data["meta"][] = array("name" => self::COMBO_CACHE_PREFIX . $barId, "content" => var_export($servedFromCache, true)); 1248aa9d0e6Sgerardnico 1258aa9d0e6Sgerardnico // Get or store the data 126*654a02feSgerardnico $cache = new \dokuwiki\Cache\Cache($barId, "snippet"); 127*654a02feSgerardnico $barFileSystemPath = DokuPath::createPagePathFromPath(DokuPath::SEPARATOR . $barId)->getFileSystemPath(); 128*654a02feSgerardnico $dependencies = array( 129*654a02feSgerardnico "files" => [ 130*654a02feSgerardnico $barFileSystemPath, 131*654a02feSgerardnico Resources::getComboHome() . "/plugin.info.txt" 132*654a02feSgerardnico ] 133*654a02feSgerardnico ); 1348aa9d0e6Sgerardnico 1358aa9d0e6Sgerardnico // if the bar was served from the cache 136*654a02feSgerardnico if ($servedFromCache && $cache->useCache($dependencies)) { 1378aa9d0e6Sgerardnico 13821913ab3SNickeau // Retrieve snippets from previous run 1395f891b7eSNickeau $data = $cache->retrieveCache(); 1408aa9d0e6Sgerardnico 1415f891b7eSNickeau if (!empty($data)) { 1428aa9d0e6Sgerardnico $snippets = unserialize($data); 143*654a02feSgerardnico $snippetManager->addSnippetsFromCacheForBar($barId, $snippets); 1448aa9d0e6Sgerardnico 1458aa9d0e6Sgerardnico if (Site::debugIsOn()) { 1468aa9d0e6Sgerardnico LogUtility::log2file("Snippet cache file {$cache->cache} used", LogUtility::LVL_MSG_DEBUG); 1478aa9d0e6Sgerardnico $event->data['script'][] = array( 1488aa9d0e6Sgerardnico "type" => "application/json", 1498aa9d0e6Sgerardnico "_data" => json_encode($snippets), 150*654a02feSgerardnico "class" => "combo-snippet-cache-" . str_replace(":", "-", $barId)); 1515f891b7eSNickeau } 152d2ffcff9Sgerardnico 1538aa9d0e6Sgerardnico } 1548aa9d0e6Sgerardnico } else { 155*654a02feSgerardnico $snippets = $snippetManager->getSnippetsForBar($barId); 1568aa9d0e6Sgerardnico if (!empty($snippets)) { 1578aa9d0e6Sgerardnico $cache->storeCache(serialize($snippets)); 1588aa9d0e6Sgerardnico } 1598aa9d0e6Sgerardnico } 1605f891b7eSNickeau 1618aa9d0e6Sgerardnico } 1625f891b7eSNickeau 1635f891b7eSNickeau /** 16421913ab3SNickeau * Snippets 1655f891b7eSNickeau */ 16621913ab3SNickeau foreach ($snippetManager->getSnippets() as $tagType => $tags) { 16721913ab3SNickeau 16821913ab3SNickeau foreach ($tags as $tag) { 16921913ab3SNickeau $event->data[$tagType][] = $tag; 1705f891b7eSNickeau } 1715f891b7eSNickeau 1725f891b7eSNickeau } 1735f891b7eSNickeau 1745f891b7eSNickeau 1755f891b7eSNickeau $snippetManager->close(); 1765f891b7eSNickeau 1775f891b7eSNickeau } 1785f891b7eSNickeau 1795f891b7eSNickeau /** 1805f891b7eSNickeau * Used if the template does not run the content 1815f891b7eSNickeau * before the calling of the header as strap does. 1825f891b7eSNickeau * 1835f891b7eSNickeau * In this case, the {@link \ComboStrap\SnippetManager::close()} has 1845f891b7eSNickeau * not run, and the snippets are still in memory. 1855f891b7eSNickeau * 1865f891b7eSNickeau * We store them in the HTML and they 1875f891b7eSNickeau * follows then the HTML cache of DokuWiki 1885f891b7eSNickeau * @param $event 1895f891b7eSNickeau */ 1905f891b7eSNickeau function componentSnippetContent($event) 1915f891b7eSNickeau { 1925f891b7eSNickeau 1935f891b7eSNickeau 1945f891b7eSNickeau /** 1955f891b7eSNickeau * Run only if the header output was already called 1965f891b7eSNickeau */ 1975f891b7eSNickeau if ($this->headerOutputWasCalled) { 1985f891b7eSNickeau 1995f891b7eSNickeau $snippetManager = PluginUtility::getSnippetManager(); 2005f891b7eSNickeau 20121913ab3SNickeau foreach ($snippetManager->getSnippets() as $tagType => $tags) { 20221913ab3SNickeau 20321913ab3SNickeau foreach ($tags as $tag) { 20421913ab3SNickeau $event->data .= DOKU_LF . "<$tagType"; 20521913ab3SNickeau $attributes = ""; 20621913ab3SNickeau $content = null; 20721913ab3SNickeau foreach ($tag as $attributeName => $attributeValue) { 2085f891b7eSNickeau if ($attributeName != "_data") { 20921913ab3SNickeau $attributes .= " $attributeName=\"$attributeValue\""; 2105f891b7eSNickeau } else { 2115f891b7eSNickeau $content = $attributeValue; 2125f891b7eSNickeau } 2135f891b7eSNickeau } 21421913ab3SNickeau $event->data .= "$attributes>"; 2155f891b7eSNickeau if (!empty($content)) { 2165f891b7eSNickeau $event->data .= $content; 2175f891b7eSNickeau } 21821913ab3SNickeau $event->data .= "</$tagType>" . DOKU_LF; 2195f891b7eSNickeau } 2205f891b7eSNickeau 2215f891b7eSNickeau } 2225f891b7eSNickeau 2235f891b7eSNickeau $snippetManager->close(); 2245f891b7eSNickeau 2255f891b7eSNickeau /** 2265f891b7eSNickeau * Set the value back 2275f891b7eSNickeau */ 2285f891b7eSNickeau $this->headerOutputWasCalled = false; 2295f891b7eSNickeau 2305f891b7eSNickeau } 2315f891b7eSNickeau 2325f891b7eSNickeau } 2335f891b7eSNickeau 2348aa9d0e6Sgerardnico 2355f891b7eSNickeau /** 2368aa9d0e6Sgerardnico * 2378aa9d0e6Sgerardnico * @param $event 2385f891b7eSNickeau */ 2398aa9d0e6Sgerardnico function barParsed($event) 2405f891b7eSNickeau { 2418aa9d0e6Sgerardnico $data = $event->data; 2428aa9d0e6Sgerardnico if ($data->mode == "xhtml") { 2435f891b7eSNickeau 2448aa9d0e6Sgerardnico /* @var CacheRenderer $data */ 245*654a02feSgerardnico $pageId = $data->page; 2468aa9d0e6Sgerardnico $cached = $event->result; 247*654a02feSgerardnico PluginUtility::getSnippetManager()->addBar($pageId, $cached); 2485f891b7eSNickeau 2495f891b7eSNickeau } 2505f891b7eSNickeau 2518aa9d0e6Sgerardnico 2528aa9d0e6Sgerardnico } 2535f891b7eSNickeau 2545f891b7eSNickeau 2555f891b7eSNickeau} 256