PageRenderTime 55ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/core/ktheme.class.php

http://awarenet.googlecode.com/
PHP | 429 lines | 203 code | 81 blank | 145 comment | 38 complexity | 57579b751760e0b4282d5550c681228c MD5 | raw file
Possible License(s): GPL-3.0
  1. <?
  2. //--------------------------------------------------------------------------------------------------
  3. //* object to allow access to the default theme
  4. //--------------------------------------------------------------------------------------------------
  5. class KTheme {
  6. //----------------------------------------------------------------------------------------------
  7. // member variables
  8. //----------------------------------------------------------------------------------------------
  9. var $name; // name of current theme [string]
  10. var $loaded = false; // is set to true if a theme is loaded [bool]
  11. var $style; // array of style variables, colors, etc [array]
  12. var $styleLoaded = false; // is set to true when stylesheet is loaded [bool]
  13. //----------------------------------------------------------------------------------------------
  14. //. constructor
  15. //----------------------------------------------------------------------------------------------
  16. //opt: theme - name of current theme [string]
  17. function KTheme($theme = '') {
  18. global $kapenta;
  19. $this->style = array();
  20. if ('' != $theme) { $this->load($theme); }
  21. else { $this->load($kapenta->defaultTheme); }
  22. }
  23. //----------------------------------------------------------------------------------------------
  24. //. load a theme
  25. //----------------------------------------------------------------------------------------------
  26. function load($theme) {
  27. $this->name = $theme;
  28. $this->readStyle();
  29. $this->loaded = true;
  30. }
  31. //==============================================================================================
  32. // BLOCKS
  33. //==============================================================================================
  34. //----------------------------------------------------------------------------------------------
  35. //. load a block template file
  36. //----------------------------------------------------------------------------------------------
  37. //arg: fileName - relative to installPath [string]
  38. //returns: block template, or null string on failure [string]
  39. function loadBlock($fileName) {
  40. global $kapenta, $user, $session;
  41. if ($kapenta->fileExists($fileName)) {
  42. $raw = $kapenta->fileGetContents($fileName, false, true);
  43. // special admin option TODO: make this a setting
  44. /*
  45. if (('admin' == $user->role) AND (substr($fileName, 0, 8) == 'modules/')) {
  46. if ($request['module'] != 'blocks') {
  47. $parts = explode('/', $fileName);
  48. $raw .= "<small><a href='/blocks/edit/module_" . $parts[1] . '/'
  49. . $parts[2] . "'>[edit block]</a></small>";
  50. }
  51. }
  52. */
  53. return $raw;
  54. } else {
  55. $msg = 'Could not load requested block file:<br/>' . $fileName;
  56. $session->msgAdmin($msg, 'bad');
  57. return '';
  58. }
  59. }
  60. //----------------------------------------------------------------------------------------------
  61. //. substitute an array of values for labels in text
  62. //----------------------------------------------------------------------------------------------
  63. //arg: labels - array of variable names (keys) and values to replace them with [array]
  64. //returns: txt with labels replaced [string]
  65. function replaceLabels($labels, $txt) {
  66. global $kapenta;
  67. $labels['serverPath'] = $kapenta->serverPath;
  68. $labels['websiteName'] = $kapenta->websiteName;
  69. if (false == is_array($labels)) { return $txt; } // no. because no.
  70. foreach ($labels as $label => $val) {
  71. if (false == is_array($val)) { $txt = str_replace('%%' . $label . '%%', $val, $txt); }
  72. }
  73. return $txt;
  74. }
  75. //--------------------------------------------------------------------------------------------------
  76. //. save a block, deprecated
  77. //--------------------------------------------------------------------------------------------------
  78. //arg: fileName - relative to installPath [string]
  79. //arg: raw - file contents [string]
  80. //returns: true on success, false on failure [bool]
  81. function saveBlock($fileName, $raw) {
  82. global $kapenta;
  83. $result = $kapenta->filePutContents($fileName, $raw, false, true);
  84. return $result;
  85. }
  86. //----------------------------------------------------------------------------------------------
  87. //. remove blocks from a string
  88. //----------------------------------------------------------------------------------------------
  89. //arg: txt - text or HTML which may contain blocks [string]
  90. //returns: txt without blocks [string]
  91. //: useful for summaries, text snippets, etc
  92. function stripBlocks($txt) {
  93. $txt = str_replace('<', '{{-less-than-}}', $txt);
  94. $txt = str_replace('>', '{{-greater-than-}}', $txt);
  95. $txt = str_replace('[[:', "<blocktag '", $txt);
  96. $txt = str_replace(':]]', "'>", $txt);
  97. $txt = strip_tags($txt);
  98. $txt = str_replace('{{-less-than-}}', '<', $txt);
  99. $txt = str_replace('{{-greater-than-}}', '>', $txt);
  100. return $txt;
  101. }
  102. //----------------------------------------------------------------------------------------------
  103. //. create a clean, short summary of a section of (x)HTML
  104. //----------------------------------------------------------------------------------------------
  105. //arg: html - source document to be summarized [string]
  106. //opt: length - maximum length, default is 300 [int]
  107. //returns: plaintext [string]
  108. function makeSummary($html, $length = 300) {
  109. global $utils;
  110. $length = (int)$length;
  111. $html = $this->stripBlocks($html); // remove blocks
  112. $html = preg_replace("'<[\/\!]*?[^<>]*?>'si", "", $html); // remove HTML
  113. $srch = array('<', '>', '&nbsp;');
  114. $repl = array('&lt;', '&gt;', ' ');
  115. $html = substr($html, 0, $length) . '...'; // cut down to length
  116. return $html;
  117. }
  118. //----------------------------------------------------------------------------------------------
  119. //. execute a block
  120. //----------------------------------------------------------------------------------------------
  121. //arg: ba - block tag data [array]
  122. //returns: block content, usually html, xml or text [string]
  123. //: this is quite an old function, from before views were separated into their own files
  124. function runBlock($ba) {
  125. global $kapenta, $session;
  126. $apiFile = $this->getBlockApiFile($ba['api'], $ba['method']);
  127. $fnName = $ba['api'] . '_' . $ba['method'];
  128. if ($kapenta->fileExists($apiFile)) {
  129. require_once($kapenta->installPath . $apiFile);
  130. if (function_exists($fnName)) {
  131. return call_user_func($fnName, ($ba['args']));
  132. } else {
  133. $msg = "called function $fnName does not exist in $apiFile";
  134. $kapenta->logErr('blocks', 'runBlock', $msg);
  135. $session->msgAdmin($msg);
  136. }
  137. } else {
  138. $msg = "api file does not exist: " . $apiFile;
  139. $kapenta->logErr('blocks', 'runBlock', $msg);
  140. //$session->msgAdmin("api file does not exist: " . $apiFile);
  141. }
  142. return '';
  143. }
  144. //----------------------------------------------------------------------------------------------
  145. //. a get block API's filename
  146. //----------------------------------------------------------------------------------------------
  147. //arg: module - module name [string]
  148. //arg: fn - view name [string]
  149. //returns: filename relative to installPath [string]
  150. //: this is quite an old function, from before views were separated into their own files
  151. function getBlockApiFile($module, $fn) {
  152. global $kapenta;
  153. $file = 'modules/' . $module . '/views/' . $fn . '.fn.php';
  154. if ('theme' == $module)
  155. { $file = 'themes/' . $kapenta->defaultTheme . '/views/' . $fn . '.fn.php'; }
  156. return $file;
  157. }
  158. //----------------------------------------------------------------------------------------------
  159. //. extract all blocks from a piece of text and return an array
  160. //----------------------------------------------------------------------------------------------
  161. //arg: txt - text or HTML which may contain block tags [string]
  162. //returns: array of blocks [array:string]
  163. function findUniqueBlocks($txt) {
  164. $blocks = array(); //% return value [array:string]
  165. $txt = str_replace("\r", '', $txt); // strip newlines
  166. $txt = str_replace("\n", '', $txt);
  167. $txt = str_replace('[[:', "\n[[:", $txt); // place blocks on their own line
  168. $txt = str_replace(':]]', ":]]\n", $txt);
  169. $lines = explode("\n", $txt); //% [array:string]
  170. foreach($lines as $line) { // for each line which might be a block
  171. $line = trim($line);
  172. if (strlen($line) > 8) {
  173. //--------------------------------------------------------------------------------------
  174. // if this line begins with [[:: and ends with ::]]
  175. //--------------------------------------------------------------------------------------
  176. if ((substr($line, 0, 3) == '[[:') AND (substr(strrev($line), 0, 3) == ']]:'))
  177. { $blocks[] = $line; }
  178. }
  179. }
  180. $blocks = array_unique($blocks); // prevent looking up the same thing twice
  181. return $blocks;
  182. }
  183. //----------------------------------------------------------------------------------------------
  184. //. read block to extract api, method and arguments
  185. //----------------------------------------------------------------------------------------------
  186. //arg: block - a block tag [string]
  187. //returns: block components [array]
  188. //; TODO: overhaul this
  189. function blockToArray($block) {
  190. global $page, $session;
  191. $ba = array();
  192. $original = trim($block);
  193. $block = str_replace("[[:", '', $block);
  194. $block = str_replace(":]]", '', $block);
  195. $parts = explode('::', $block);
  196. if (count($parts) >= 2) {
  197. //--------------------------------------------------------------------------------------
  198. // get the api and method
  199. //--------------------------------------------------------------------------------------
  200. $ba['api'] = array_shift($parts);
  201. $ba['method'] = array_shift($parts);
  202. $ba['args'] = array();
  203. //--------------------------------------------------------------------------------------
  204. // add page arguments
  205. //--------------------------------------------------------------------------------------
  206. if (false == is_array($page->blockArgs)) {
  207. $page->blockArgs = array();
  208. $session->msgAdmin("\$page->blockArgs not an array.", 'bug');
  209. } else {
  210. foreach($page->blockArgs as $argName => $argValue) {
  211. $ba['args'][$argName] = $argValue;
  212. }
  213. }
  214. //--------------------------------------------------------------------------------------
  215. // get any explicit arguments (overrwrites page args)
  216. //--------------------------------------------------------------------------------------
  217. foreach($parts as $part) {
  218. $eqPos = strpos($part, '=');
  219. if (false == $eqPos) {
  220. $ba['args'][$part] = true;
  221. } else {
  222. $argName = substr($part, 0, $eqPos);
  223. $argValue = substr($part, ($eqPos + 1));
  224. $ba['args'][$argName] = $argValue;
  225. }
  226. }
  227. } else { return false; }
  228. $ba['args']['rawblock'] = $original; // spacial magic block argument
  229. //$ba['args']['rawblock64'] = base64_encode($original); // ...
  230. return $ba;
  231. }
  232. //----------------------------------------------------------------------------------------------
  233. //. expand all blocks within a string
  234. //----------------------------------------------------------------------------------------------
  235. //arg: txt - text containing block tags to be expanded [string]
  236. //arg: calledBy - newline delimited list of parents, set to empty string [string]
  237. //returns: txt with blocks recusively expanded [string]
  238. //: calledBy is used to prevent infinite recursion, newline delimited list of parents
  239. function expandBlocks($txt, $calledBy = '') {
  240. //------------------------------------------------------------------------------------------
  241. // filter out any calling blocks - prevent infinite recursion
  242. //------------------------------------------------------------------------------------------
  243. $ban = explode("\n", $calledBy);
  244. foreach($ban as $killThis)
  245. { if (strlen($killThis) > 3) { $txt = str_replace($killThis, '', $txt); } }
  246. //------------------------------------------------------------------------------------------
  247. // replace each block with result from the appropriate blocks API
  248. //------------------------------------------------------------------------------------------
  249. $blocks = $this->findUniqueBlocks($txt);
  250. foreach ($blocks as $block) {
  251. //--------------------------------------------------------------------------------------
  252. // load the appropriate block API and execute the hook
  253. //--------------------------------------------------------------------------------------
  254. $ba = $this->blockToArray($block);
  255. $bHTML = $this->runBlock($ba);
  256. //--------------------------------------------------------------------------------------
  257. // recurse, expand any blocks that were created by the hook
  258. //--------------------------------------------------------------------------------------
  259. $bHTML = $this->expandBlocks($bHTML, $calledBy . $block . "\n");
  260. $txt = str_replace($block, $bHTML, $txt);
  261. }
  262. return $txt;
  263. }
  264. //==============================================================================================
  265. // UTILITY
  266. //==============================================================================================
  267. //----------------------------------------------------------------------------------------------
  268. //. render a 2d array as a table
  269. //----------------------------------------------------------------------------------------------
  270. //arg: ary - 2d array of table rows and columns [array]
  271. //opt: wireframe - use kapenta's default wireframe table style [bool]
  272. //opt: firstrowtitle - if column titles in first row to be highlighted [bool]
  273. //returns: HTML table, false on failure [string][bool]
  274. //: TODO: consider moving this to theme
  275. function arrayToHtmlTable($ary, $wireframe = false, $firstrowtitle = false) {
  276. if (false == $wireframe) {
  277. $html = "<table noborder width='100%'>";
  278. foreach($ary as $row) {
  279. $html .= "\t<tr>\n";
  280. foreach($row as $col) { $html .= "\t\t<td>" . $col . "</td>\n"; }
  281. $html .= "\t</tr>\n";
  282. }
  283. $html .= "</table>";
  284. } else {
  285. $html = "<table class='wireframe' width='100%'>";
  286. foreach($ary as $row) {
  287. $tdClass = 'wireframe';
  288. if (true == $firstrowtitle) { $firstrowtitle = false; $tdClass = 'title'; }
  289. $html .= "\t<tr>\n";
  290. foreach($row as $col) { $html .= "\t\t<td class='". $tdClass ."'>". $col ."</td>\n"; }
  291. $html .= "\t</tr>\n";
  292. }
  293. $html .= "</table>";
  294. }
  295. return $html;
  296. }
  297. //==============================================================================================
  298. // TAGS
  299. //==============================================================================================
  300. //----------------------------------------------------------------------------------------------
  301. //. convert a set of tags from array to HTML representation
  302. //----------------------------------------------------------------------------------------------
  303. //arg: tags - 2d array of name, weight, link [array]
  304. //note: we don't show tags with weight/magnitude less than 1
  305. function makeTagCloud($tags) {
  306. $html = ''; //% return value
  307. $max = 1;
  308. $min = 1;
  309. foreach($tags as $tag) { if ($tag['weight'] > $max) { $max = $tag['weight']; } }
  310. foreach($tags as $tag) {
  311. $size = floor((5 / $max) * $tag['weight']);
  312. $html .= "<a href='" . $tag['link'] . "' style='color: #444444;'>"
  313. . "<font size='" . $size . "'>" . $tag['name'] . "</font></a>\n";
  314. }
  315. return $html;
  316. }
  317. //==============================================================================================
  318. // STYLES
  319. //==============================================================================================
  320. //----------------------------------------------------------------------------------------------
  321. //. load theme style variables into an array (usually attached to page object)
  322. //----------------------------------------------------------------------------------------------
  323. //arg: theme - theme name [string]
  324. //returns: theme stylesheet as associative array, or false on failure [array][bool]
  325. function readStyle() {
  326. $xmlFile = 'themes/' . $this->name . '/style.xml.php';
  327. $xmlDoc = new KXmlDocument($xmlFile, true);
  328. if (false == $xmlDoc->loaded) { return false; }
  329. $ary = $xmlDoc->getChildren2d();
  330. $this->style = $ary;
  331. $this->styleLoaded = true;
  332. return $ary;
  333. }
  334. //----------------------------------------------------------------------------------------------
  335. //. save an array of style variables
  336. //----------------------------------------------------------------------------------------------
  337. //arg: theme - name of theme [string]
  338. //arg: style - theme stylesheet; associative array [array]
  339. //returns: true on success, else false [bool]
  340. //: TODO: use filePutContents
  341. function writeStyle() {
  342. global $kapenta, $utils;
  343. if (false == $kapenta->themeExists($this->name)) { return false; }
  344. $xml = $utils->arrayToXml2d('theme', $style, true); // construct XML
  345. return $kapenta->filePutContents($fileName, $xml, false, true); // save to file
  346. }
  347. }
  348. ?>