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