1*5f891b7eSNickeau<?php 2*5f891b7eSNickeau 3*5f891b7eSNickeauuse ComboStrap\LogUtility; 4*5f891b7eSNickeauuse ComboStrap\MetadataUtility; 5*5f891b7eSNickeauuse ComboStrap\PluginUtility; 6*5f891b7eSNickeauuse ComboStrap\Page; 7*5f891b7eSNickeauuse ComboStrap\SnippetManager; 8*5f891b7eSNickeauuse ComboStrap\TplUtility; 9*5f891b7eSNickeauuse dokuwiki\Cache\CacheRenderer; 10*5f891b7eSNickeau 11*5f891b7eSNickeauif (!defined('DOKU_INC')) die(); 12*5f891b7eSNickeau 13*5f891b7eSNickeau/** 14*5f891b7eSNickeau * 15*5f891b7eSNickeau * 16*5f891b7eSNickeau * Add the snippet needed by the components 17*5f891b7eSNickeau * 18*5f891b7eSNickeau */ 19*5f891b7eSNickeauclass action_plugin_combo_snippets extends DokuWiki_Action_Plugin 20*5f891b7eSNickeau{ 21*5f891b7eSNickeau 22*5f891b7eSNickeau 23*5f891b7eSNickeau /** 24*5f891b7eSNickeau * @var bool - to trace if the header output was called 25*5f891b7eSNickeau */ 26*5f891b7eSNickeau private $headerOutputWasCalled = false; 27*5f891b7eSNickeau 28*5f891b7eSNickeau function __construct() 29*5f891b7eSNickeau { 30*5f891b7eSNickeau // enable direct access to language strings 31*5f891b7eSNickeau // ie $this->lang 32*5f891b7eSNickeau $this->setupLocale(); 33*5f891b7eSNickeau } 34*5f891b7eSNickeau 35*5f891b7eSNickeau public function register(Doku_Event_Handler $controller) 36*5f891b7eSNickeau { 37*5f891b7eSNickeau $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'componentSnippetHead', array()); 38*5f891b7eSNickeau $controller->register_hook('TPL_CONTENT_DISPLAY', 'BEFORE', $this, 'componentSnippetContent', array()); 39*5f891b7eSNickeau } 40*5f891b7eSNickeau 41*5f891b7eSNickeau /** 42*5f891b7eSNickeau * Dokuwiki has already a canonical methodology 43*5f891b7eSNickeau * https://www.dokuwiki.org/canonical 44*5f891b7eSNickeau * 45*5f891b7eSNickeau * @param $event 46*5f891b7eSNickeau */ 47*5f891b7eSNickeau function componentSnippetHead($event) 48*5f891b7eSNickeau { 49*5f891b7eSNickeau 50*5f891b7eSNickeau 51*5f891b7eSNickeau global $ID; 52*5f891b7eSNickeau if (empty($ID)) { 53*5f891b7eSNickeau return; 54*5f891b7eSNickeau } 55*5f891b7eSNickeau 56*5f891b7eSNickeau /** 57*5f891b7eSNickeau * Advertise that the header output was called 58*5f891b7eSNickeau * If the user is using another template 59*5f891b7eSNickeau * than strap that does not put the component snippet 60*5f891b7eSNickeau * in the head 61*5f891b7eSNickeau * Used in 62*5f891b7eSNickeau */ 63*5f891b7eSNickeau $this->headerOutputWasCalled = true; 64*5f891b7eSNickeau 65*5f891b7eSNickeau $snippetManager = PluginUtility::getSnippetManager(); 66*5f891b7eSNickeau 67*5f891b7eSNickeau /** 68*5f891b7eSNickeau * Because the cache is at the bar level, 69*5f891b7eSNickeau * a rendering for a page may run without the others 70*5f891b7eSNickeau * Therefore we saved the data in between 71*5f891b7eSNickeau * (The storage is done at the page level) 72*5f891b7eSNickeau * Adapted from {@link p_cached_output()} 73*5f891b7eSNickeau */ 74*5f891b7eSNickeau $storedArray = array(); 75*5f891b7eSNickeau $file = wikiFN($ID); 76*5f891b7eSNickeau $cache = new CacheRenderer($ID, $file, "snippet"); 77*5f891b7eSNickeau if ($cache->useCache()) { // useCache means isCacheUsable 78*5f891b7eSNickeau $data = $cache->retrieveCache(); 79*5f891b7eSNickeau global $conf; 80*5f891b7eSNickeau if ($conf['allowdebug']) { 81*5f891b7eSNickeau LogUtility::log2file("Snippet cache file {$cache->cache} used"); 82*5f891b7eSNickeau } 83*5f891b7eSNickeau if (!empty($data)) { 84*5f891b7eSNickeau $storedArray = unserialize($data); 85*5f891b7eSNickeau } 86*5f891b7eSNickeau $snippetManager->mergeWithPreviousRun($storedArray); 87*5f891b7eSNickeau } 88*5f891b7eSNickeau $cache->storeCache(serialize($snippetManager->getData())); 89*5f891b7eSNickeau 90*5f891b7eSNickeau 91*5f891b7eSNickeau /** 92*5f891b7eSNickeau * tags 93*5f891b7eSNickeau */ 94*5f891b7eSNickeau foreach ($snippetManager->getTags() as $component => $tags) { 95*5f891b7eSNickeau foreach ($tags as $tagType => $tagRows) { 96*5f891b7eSNickeau foreach ($tagRows as $tagRow) { 97*5f891b7eSNickeau $tagRow["class"] = SnippetManager::getClassFromTag($component);; 98*5f891b7eSNickeau $event->data[$tagType][] = $tagRow; 99*5f891b7eSNickeau } 100*5f891b7eSNickeau } 101*5f891b7eSNickeau } 102*5f891b7eSNickeau 103*5f891b7eSNickeau /** 104*5f891b7eSNickeau * Css 105*5f891b7eSNickeau */ 106*5f891b7eSNickeau foreach ($snippetManager->getCss() as $component => $snippet) { 107*5f891b7eSNickeau $event->data['style'][] = array( 108*5f891b7eSNickeau "class" => SnippetManager::getClassFromTag($component), 109*5f891b7eSNickeau "_data" => $snippet 110*5f891b7eSNickeau ); 111*5f891b7eSNickeau } 112*5f891b7eSNickeau 113*5f891b7eSNickeau /** 114*5f891b7eSNickeau * Javascript 115*5f891b7eSNickeau */ 116*5f891b7eSNickeau foreach ($snippetManager->getJavascript() as $component => $snippet) { 117*5f891b7eSNickeau $event->data['script'][] = array( 118*5f891b7eSNickeau "class" => SnippetManager::getClassFromTag($component), 119*5f891b7eSNickeau "type" => "text/javascript", 120*5f891b7eSNickeau "_data" => $snippet 121*5f891b7eSNickeau ); 122*5f891b7eSNickeau } 123*5f891b7eSNickeau 124*5f891b7eSNickeau 125*5f891b7eSNickeau $snippetManager->close(); 126*5f891b7eSNickeau 127*5f891b7eSNickeau } 128*5f891b7eSNickeau 129*5f891b7eSNickeau /** 130*5f891b7eSNickeau * Used if the template does not run the content 131*5f891b7eSNickeau * before the calling of the header as strap does. 132*5f891b7eSNickeau * 133*5f891b7eSNickeau * In this case, the {@link \ComboStrap\SnippetManager::close()} has 134*5f891b7eSNickeau * not run, and the snippets are still in memory. 135*5f891b7eSNickeau * 136*5f891b7eSNickeau * We store them in the HTML and they 137*5f891b7eSNickeau * follows then the HTML cache of DokuWiki 138*5f891b7eSNickeau * @param $event 139*5f891b7eSNickeau */ 140*5f891b7eSNickeau function componentSnippetContent($event) 141*5f891b7eSNickeau { 142*5f891b7eSNickeau 143*5f891b7eSNickeau 144*5f891b7eSNickeau /** 145*5f891b7eSNickeau * Run only if the header output was already called 146*5f891b7eSNickeau */ 147*5f891b7eSNickeau if ($this->headerOutputWasCalled) { 148*5f891b7eSNickeau 149*5f891b7eSNickeau $snippetManager = PluginUtility::getSnippetManager(); 150*5f891b7eSNickeau 151*5f891b7eSNickeau /** 152*5f891b7eSNickeau * tags 153*5f891b7eSNickeau */ 154*5f891b7eSNickeau foreach ($snippetManager->getTags() as $component => $tags) { 155*5f891b7eSNickeau foreach ($tags as $tagType => $tagRows) { 156*5f891b7eSNickeau foreach ($tagRows as $tagRow) { 157*5f891b7eSNickeau $class = SnippetManager::getClassFromTag($component); 158*5f891b7eSNickeau $event->data .= "<$tagType class=\"$class\""; 159*5f891b7eSNickeau foreach ($tagRow as $attributeName => $attributeValue) { 160*5f891b7eSNickeau if ($attributeName != "_data") { 161*5f891b7eSNickeau $event->data .= " $attributeName=\"$attributeValue\""; 162*5f891b7eSNickeau } else { 163*5f891b7eSNickeau $content = $attributeValue; 164*5f891b7eSNickeau } 165*5f891b7eSNickeau } 166*5f891b7eSNickeau $event->data .= ">"; 167*5f891b7eSNickeau if (!empty($content)) { 168*5f891b7eSNickeau $event->data .= $content; 169*5f891b7eSNickeau } 170*5f891b7eSNickeau $event->data .= "</$tagType>"; 171*5f891b7eSNickeau } 172*5f891b7eSNickeau } 173*5f891b7eSNickeau } 174*5f891b7eSNickeau 175*5f891b7eSNickeau /** 176*5f891b7eSNickeau * Css 177*5f891b7eSNickeau */ 178*5f891b7eSNickeau foreach ($snippetManager->getCss() as $component => $snippet) { 179*5f891b7eSNickeau 180*5f891b7eSNickeau $class = SnippetManager::getClassFromTag($component); 181*5f891b7eSNickeau $event->data .= "<style class=\"$class\">$snippet</style>" . DOKU_LF; 182*5f891b7eSNickeau 183*5f891b7eSNickeau } 184*5f891b7eSNickeau 185*5f891b7eSNickeau /** 186*5f891b7eSNickeau * Javascript 187*5f891b7eSNickeau */ 188*5f891b7eSNickeau foreach ($snippetManager->getJavascript() as $component => $snippet) { 189*5f891b7eSNickeau $class = SnippetManager::getClassFromTag($component); 190*5f891b7eSNickeau $event->data .= "<script class=\"$class\" type=\"text/javascript\">$snippet</script>" . DOKU_LF; 191*5f891b7eSNickeau } 192*5f891b7eSNickeau 193*5f891b7eSNickeau $snippetManager->close(); 194*5f891b7eSNickeau 195*5f891b7eSNickeau /** 196*5f891b7eSNickeau * Set the value back 197*5f891b7eSNickeau */ 198*5f891b7eSNickeau $this->headerOutputWasCalled = false; 199*5f891b7eSNickeau 200*5f891b7eSNickeau } 201*5f891b7eSNickeau 202*5f891b7eSNickeau } 203*5f891b7eSNickeau 204*5f891b7eSNickeau /** 205*5f891b7eSNickeau * Adapted from {@link p_cached_output()} 206*5f891b7eSNickeau */ 207*5f891b7eSNickeau function getCachedSnippet() 208*5f891b7eSNickeau { 209*5f891b7eSNickeau 210*5f891b7eSNickeau global $ID; 211*5f891b7eSNickeau $file = wikiFN($ID); 212*5f891b7eSNickeau $format = "combo_head"; 213*5f891b7eSNickeau global $conf; 214*5f891b7eSNickeau 215*5f891b7eSNickeau 216*5f891b7eSNickeau } 217*5f891b7eSNickeau 218*5f891b7eSNickeau// function storeSnippetArray() 219*5f891b7eSNickeau// { 220*5f891b7eSNickeau// global $conf; 221*5f891b7eSNickeau// 222*5f891b7eSNickeau// $cache = new CacheRenderer($ID, $file, $format); 223*5f891b7eSNickeau// if (!empty($headHtml)) { 224*5f891b7eSNickeau// if ($cache->storeCache($headHtml)) { // storeCache() attempts to save cachefile 225*5f891b7eSNickeau// if ($conf['allowdebug']) { 226*5f891b7eSNickeau// 227*5f891b7eSNickeau// LogUtility::log2file("No cache file used, but created {$cache->cache} "); 228*5f891b7eSNickeau// } 229*5f891b7eSNickeau// } else { 230*5f891b7eSNickeau// $cache->removeCache(); //try to delete cachefile 231*5f891b7eSNickeau// if ($conf['allowdebug']) { 232*5f891b7eSNickeau// LogUtility::log2file("no cachefile used, caching forbidden"); 233*5f891b7eSNickeau// } 234*5f891b7eSNickeau// } 235*5f891b7eSNickeau// } 236*5f891b7eSNickeau// } 237*5f891b7eSNickeau 238*5f891b7eSNickeau 239*5f891b7eSNickeau} 240