15f891b7eSNickeau<?php 25f891b7eSNickeau 35f891b7eSNickeauuse ComboStrap\LogUtility; 45f891b7eSNickeauuse ComboStrap\PluginUtility; 5*8aa9d0e6Sgerardnicouse ComboStrap\Site; 65f891b7eSNickeauuse ComboStrap\SnippetManager; 7*8aa9d0e6Sgerardnicouse dokuwiki\Cache\CacheRenderer; 85f891b7eSNickeau 95f891b7eSNickeauif (!defined('DOKU_INC')) die(); 105f891b7eSNickeau 115f891b7eSNickeau/** 125f891b7eSNickeau * 135f891b7eSNickeau * 145f891b7eSNickeau * Add the snippet needed by the components 155f891b7eSNickeau * 165f891b7eSNickeau */ 175f891b7eSNickeauclass action_plugin_combo_snippets extends DokuWiki_Action_Plugin 185f891b7eSNickeau{ 195f891b7eSNickeau 20*8aa9d0e6Sgerardnico const COMBO_CACHE_PREFIX = "combo:cache:"; 215f891b7eSNickeau 225f891b7eSNickeau /** 235f891b7eSNickeau * @var bool - to trace if the header output was called 245f891b7eSNickeau */ 255f891b7eSNickeau private $headerOutputWasCalled = false; 265f891b7eSNickeau 275f891b7eSNickeau function __construct() 285f891b7eSNickeau { 295f891b7eSNickeau // enable direct access to language strings 305f891b7eSNickeau // ie $this->lang 315f891b7eSNickeau $this->setupLocale(); 325f891b7eSNickeau } 335f891b7eSNickeau 345f891b7eSNickeau public function register(Doku_Event_Handler $controller) 355f891b7eSNickeau { 36*8aa9d0e6Sgerardnico 375f891b7eSNickeau $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'componentSnippetHead', array()); 385f891b7eSNickeau $controller->register_hook('TPL_CONTENT_DISPLAY', 'BEFORE', $this, 'componentSnippetContent', array()); 39*8aa9d0e6Sgerardnico 40*8aa9d0e6Sgerardnico 41*8aa9d0e6Sgerardnico $controller->register_hook('PARSER_CACHE_USE', 'AFTER', $this, 'barParsed', array()); 42*8aa9d0e6Sgerardnico 435f891b7eSNickeau } 445f891b7eSNickeau 455f891b7eSNickeau /** 465f891b7eSNickeau * Dokuwiki has already a canonical methodology 475f891b7eSNickeau * https://www.dokuwiki.org/canonical 485f891b7eSNickeau * 495f891b7eSNickeau * @param $event 505f891b7eSNickeau */ 515f891b7eSNickeau function componentSnippetHead($event) 525f891b7eSNickeau { 535f891b7eSNickeau 545f891b7eSNickeau 555f891b7eSNickeau global $ID; 565f891b7eSNickeau if (empty($ID)) { 575f891b7eSNickeau return; 585f891b7eSNickeau } 595f891b7eSNickeau 605f891b7eSNickeau /** 615f891b7eSNickeau * Advertise that the header output was called 625f891b7eSNickeau * If the user is using another template 635f891b7eSNickeau * than strap that does not put the component snippet 645f891b7eSNickeau * in the head 655f891b7eSNickeau * Used in 665f891b7eSNickeau */ 675f891b7eSNickeau $this->headerOutputWasCalled = true; 685f891b7eSNickeau 695f891b7eSNickeau $snippetManager = PluginUtility::getSnippetManager(); 705f891b7eSNickeau 715f891b7eSNickeau /** 72*8aa9d0e6Sgerardnico * For each processed bar in the page 73*8aa9d0e6Sgerardnico * * retrieve the snippets from the cache or store the process one 74*8aa9d0e6Sgerardnico * * add the cache information in meta 755f891b7eSNickeau */ 76*8aa9d0e6Sgerardnico $bars = $snippetManager->getBarsOfPage(); 77*8aa9d0e6Sgerardnico foreach ($bars as $bar => $servedFromCache) { 78*8aa9d0e6Sgerardnico 79*8aa9d0e6Sgerardnico // Add cache meta for info 80*8aa9d0e6Sgerardnico $event->data["meta"][] = array("name" => self::COMBO_CACHE_PREFIX . $bar, "content" => var_export($servedFromCache, true)); 81*8aa9d0e6Sgerardnico 82*8aa9d0e6Sgerardnico // Get or store the data 83*8aa9d0e6Sgerardnico $cache = new \dokuwiki\Cache\Cache($bar, "snippet"); 84*8aa9d0e6Sgerardnico 85*8aa9d0e6Sgerardnico // if the bar was served from the cache 86*8aa9d0e6Sgerardnico if ($servedFromCache) { 87*8aa9d0e6Sgerardnico // Retrieve snippets from previous run 88*8aa9d0e6Sgerardnico 895f891b7eSNickeau $data = $cache->retrieveCache(); 90*8aa9d0e6Sgerardnico 915f891b7eSNickeau if (!empty($data)) { 92*8aa9d0e6Sgerardnico $snippets = unserialize($data); 93*8aa9d0e6Sgerardnico $snippetManager->addSnippetsFromCacheForBar($bar, $snippets); 94*8aa9d0e6Sgerardnico 95*8aa9d0e6Sgerardnico if (Site::debugIsOn()) { 96*8aa9d0e6Sgerardnico LogUtility::log2file("Snippet cache file {$cache->cache} used", LogUtility::LVL_MSG_DEBUG); 97*8aa9d0e6Sgerardnico $event->data['script'][] = array( 98*8aa9d0e6Sgerardnico "type" => "application/json", 99*8aa9d0e6Sgerardnico "_data" => json_encode($snippets), 100*8aa9d0e6Sgerardnico "class" => "combo-snippet-cache-" . str_replace(":", "-", $bar)); 1015f891b7eSNickeau } 102d2ffcff9Sgerardnico 103*8aa9d0e6Sgerardnico } 104*8aa9d0e6Sgerardnico } else { 105*8aa9d0e6Sgerardnico $snippets = $snippetManager->getSnippetsForBar($bar); 106*8aa9d0e6Sgerardnico if(!empty($snippets)) { 107*8aa9d0e6Sgerardnico $cache->storeCache(serialize($snippets)); 108*8aa9d0e6Sgerardnico } 109*8aa9d0e6Sgerardnico } 1105f891b7eSNickeau 111*8aa9d0e6Sgerardnico } 1125f891b7eSNickeau 1135f891b7eSNickeau /** 1145f891b7eSNickeau * tags 1155f891b7eSNickeau */ 1165f891b7eSNickeau foreach ($snippetManager->getTags() as $component => $tags) { 1175f891b7eSNickeau foreach ($tags as $tagType => $tagRows) { 1185f891b7eSNickeau foreach ($tagRows as $tagRow) { 1195f891b7eSNickeau $tagRow["class"] = SnippetManager::getClassFromTag($component);; 1205f891b7eSNickeau $event->data[$tagType][] = $tagRow; 1215f891b7eSNickeau } 1225f891b7eSNickeau } 1235f891b7eSNickeau } 1245f891b7eSNickeau 1255f891b7eSNickeau /** 1265f891b7eSNickeau * Css 1275f891b7eSNickeau */ 1285f891b7eSNickeau foreach ($snippetManager->getCss() as $component => $snippet) { 1295f891b7eSNickeau $event->data['style'][] = array( 1305f891b7eSNickeau "class" => SnippetManager::getClassFromTag($component), 1315f891b7eSNickeau "_data" => $snippet 1325f891b7eSNickeau ); 1335f891b7eSNickeau } 1345f891b7eSNickeau 1355f891b7eSNickeau /** 1365f891b7eSNickeau * Javascript 1375f891b7eSNickeau */ 1385f891b7eSNickeau foreach ($snippetManager->getJavascript() as $component => $snippet) { 1395f891b7eSNickeau $event->data['script'][] = array( 1405f891b7eSNickeau "class" => SnippetManager::getClassFromTag($component), 1415f891b7eSNickeau "type" => "text/javascript", 1425f891b7eSNickeau "_data" => $snippet 1435f891b7eSNickeau ); 1445f891b7eSNickeau } 1455f891b7eSNickeau 1465f891b7eSNickeau 1475f891b7eSNickeau $snippetManager->close(); 1485f891b7eSNickeau 1495f891b7eSNickeau } 1505f891b7eSNickeau 1515f891b7eSNickeau /** 1525f891b7eSNickeau * Used if the template does not run the content 1535f891b7eSNickeau * before the calling of the header as strap does. 1545f891b7eSNickeau * 1555f891b7eSNickeau * In this case, the {@link \ComboStrap\SnippetManager::close()} has 1565f891b7eSNickeau * not run, and the snippets are still in memory. 1575f891b7eSNickeau * 1585f891b7eSNickeau * We store them in the HTML and they 1595f891b7eSNickeau * follows then the HTML cache of DokuWiki 1605f891b7eSNickeau * @param $event 1615f891b7eSNickeau */ 1625f891b7eSNickeau function componentSnippetContent($event) 1635f891b7eSNickeau { 1645f891b7eSNickeau 1655f891b7eSNickeau 1665f891b7eSNickeau /** 1675f891b7eSNickeau * Run only if the header output was already called 1685f891b7eSNickeau */ 1695f891b7eSNickeau if ($this->headerOutputWasCalled) { 1705f891b7eSNickeau 1715f891b7eSNickeau $snippetManager = PluginUtility::getSnippetManager(); 1725f891b7eSNickeau 1735f891b7eSNickeau /** 1745f891b7eSNickeau * tags 1755f891b7eSNickeau */ 1765f891b7eSNickeau foreach ($snippetManager->getTags() as $component => $tags) { 1775f891b7eSNickeau foreach ($tags as $tagType => $tagRows) { 1785f891b7eSNickeau foreach ($tagRows as $tagRow) { 1795f891b7eSNickeau $class = SnippetManager::getClassFromTag($component); 1805f891b7eSNickeau $event->data .= "<$tagType class=\"$class\""; 1815f891b7eSNickeau foreach ($tagRow as $attributeName => $attributeValue) { 1825f891b7eSNickeau if ($attributeName != "_data") { 1835f891b7eSNickeau $event->data .= " $attributeName=\"$attributeValue\""; 1845f891b7eSNickeau } else { 1855f891b7eSNickeau $content = $attributeValue; 1865f891b7eSNickeau } 1875f891b7eSNickeau } 1885f891b7eSNickeau $event->data .= ">"; 1895f891b7eSNickeau if (!empty($content)) { 1905f891b7eSNickeau $event->data .= $content; 1915f891b7eSNickeau } 1925f891b7eSNickeau $event->data .= "</$tagType>"; 1935f891b7eSNickeau } 1945f891b7eSNickeau } 1955f891b7eSNickeau } 1965f891b7eSNickeau 1975f891b7eSNickeau /** 1985f891b7eSNickeau * Css 1995f891b7eSNickeau */ 2005f891b7eSNickeau foreach ($snippetManager->getCss() as $component => $snippet) { 2015f891b7eSNickeau 2025f891b7eSNickeau $class = SnippetManager::getClassFromTag($component); 2035f891b7eSNickeau $event->data .= "<style class=\"$class\">$snippet</style>" . DOKU_LF; 2045f891b7eSNickeau 2055f891b7eSNickeau } 2065f891b7eSNickeau 2075f891b7eSNickeau /** 2085f891b7eSNickeau * Javascript 2095f891b7eSNickeau */ 2105f891b7eSNickeau foreach ($snippetManager->getJavascript() as $component => $snippet) { 2115f891b7eSNickeau $class = SnippetManager::getClassFromTag($component); 2125f891b7eSNickeau $event->data .= "<script class=\"$class\" type=\"text/javascript\">$snippet</script>" . DOKU_LF; 2135f891b7eSNickeau } 2145f891b7eSNickeau 2155f891b7eSNickeau $snippetManager->close(); 2165f891b7eSNickeau 2175f891b7eSNickeau /** 2185f891b7eSNickeau * Set the value back 2195f891b7eSNickeau */ 2205f891b7eSNickeau $this->headerOutputWasCalled = false; 2215f891b7eSNickeau 2225f891b7eSNickeau } 2235f891b7eSNickeau 2245f891b7eSNickeau } 2255f891b7eSNickeau 226*8aa9d0e6Sgerardnico 2275f891b7eSNickeau /** 228*8aa9d0e6Sgerardnico * 229*8aa9d0e6Sgerardnico * @param $event 2305f891b7eSNickeau */ 231*8aa9d0e6Sgerardnico function barParsed($event) 2325f891b7eSNickeau { 233*8aa9d0e6Sgerardnico $data = $event->data; 234*8aa9d0e6Sgerardnico if ($data->mode == "xhtml") { 2355f891b7eSNickeau 236*8aa9d0e6Sgerardnico /* @var CacheRenderer $data */ 237*8aa9d0e6Sgerardnico $page = $data->page; 238*8aa9d0e6Sgerardnico $cached = $event->result; 239*8aa9d0e6Sgerardnico PluginUtility::getSnippetManager()->addBar($page, $cached); 2405f891b7eSNickeau 2415f891b7eSNickeau } 2425f891b7eSNickeau 243*8aa9d0e6Sgerardnico 244*8aa9d0e6Sgerardnico } 2455f891b7eSNickeau 2465f891b7eSNickeau 2475f891b7eSNickeau} 248