PageRenderTime 67ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 1ms

/php-lib/div.php

https://github.com/pragres/cubay
PHP | 7863 lines | 6206 code | 802 blank | 855 comment | 1077 complexity | 196bfc3d1ac8a7d77e5a643527217da6 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /**
  3. * [[]] Div PHP Template Engine
  4. *
  5. * Div (division) is a template engine for PHP 5.x or higher and it is a social project
  6. * without spirit of lucre financed by Pragres (http://pragres.com)
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation.
  11. *
  12. * This program is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  14. * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  15. * for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program as the file LICENSE.txt; if not, please see
  19. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
  20. *
  21. * @author Rafael Rodriguez Ramirez <rafa@pragres.com>
  22. * @version : 4.5
  23. * @link http://divengine.com
  24. */
  25. /**
  26. * Constants
  27. *
  28. * PACKAGES The path of templates's root directory.
  29. * DIV_DEFAULT_TPL_FILE_EXT The default extension for template files
  30. * DIV_DEFAULT_DATA_FILE_EXT The default extension for data files
  31. * DIV_MAX_PARSE_CYCLES The max number of cycles of the parser (to prevent infinite loop and more)
  32. * DIV_MAX_FILENAME_SIZE The max size of file name or dir name in your operating system
  33. */
  34. if (! defined('PACKAGES'))
  35. define('PACKAGES', './');
  36. if (! defined('DIV_DEFAULT_TPL_FILE_EXT'))
  37. define('DIV_DEFAULT_TPL_FILE_EXT', 'tpl');
  38. if (! defined('DIV_DEFAULT_DATA_FILE_EXT'))
  39. define('DIV_DEFAULT_DATA_FILE_EXT', 'json');
  40. if (! defined('DIV_MAX_PARSE_CYCLES'))
  41. define('DIV_MAX_PARSE_CYCLES', 100);
  42. if (! defined('DIV_MAX_FILENAME_SIZE'))
  43. define('DIV_MAX_FILENAME_SIZE', 250);
  44. define('DIV_PHP_ALLOWED_FUNCTIONS', 'isset,empty,is_null,is_numeric,is_bool,is_integer,is_double,' . 'sizeof,is_finite,is_float,is_infinite,is_int,is_long,is_nan,' . 'is_real,is_scalar,is_string,mt_rand,mt_srand,mt_getrandmax,' . 'rand,urlencode,urldecode,uniqid,date,time,intval,htmlspecialchars,' . 'htmlspecialchars_decode,strtr,strpos,str_replace,str_ireplace,' . 'substr,sprintf,abs,acos,acosh,asin,atan2,atanh,base_convert,' . 'bindec,ceil,cos,cosh,decbin,dechex,decoct,deg2rad,exp,expm1,' . 'floor,fmod,getrandmax,hexdec,hypot,lcg_value,log10,log1p,log,' . 'max,min,octdec,pi,pow,rad2deg,rand,round,sin,sinh,sqrt,srand,' . 'tan,tanh,cal_days_in_month,cal_from_jd,cal_info,cal_to_jd,' . 'easter_date,easter_days,frenchtojd,gregoriantojd,jddayofweek,' . 'jdmonthname,jdtofrench,jdtogregorian,jdtojewish,jdtojulian,' . 'jdtounix,jewishtojd,jewishtojd,unixtojd,checkdate,' . 'date_default_timezone_get,strtotime,date_sunset,gmdate,gmmktime,' . 'gmstrftime,idate,microtime,mktime,strftime,strptime,strtotime,' . 'timezone_name_from_abbr,timezone_version_get,bcadd,bccomp,' . 'bcdiv,bcmod,bcmul,bcpow,bcpowmod,bcscale,bcsqrt,bcsub,addcslashes,' . 'addslashes,bin2hex,chop,chr,chunk_split,convert_cyr_string,' . 'convert_uudecode,convert_uuencode,count,count_chars,crc32,crypt,' . 'hebrev,hebrevc,hex2bin,html_entity_decode,htmlentities,' . 'htmlspecialchars_decode,htmlspecialchars,lcfirst,levenshtein,' . 'ltrim,md5,metaphone,money_format,nl_langinfo,nl2br,number_format,' . 'ord,quoted_printable_decode,quoted_printable_encode,quotemeta,' . 'rtrim,sha1,similar_text,soundex,sprintf,str_pad,str_repeat,' . 'str_rot13,str_shuffle,strcasecmp,strchr,strcmp,strcoll,strcspn,' . 'strip_tags,stripcslashes,stripos,stripslashes,stristr,strlen,' . 'strnatcasecmp,strnatcmp,strncasecmp,strncmp,strpbrk,strrchr,' . 'strrev,strripos,strrpos,strspn,strtolower,strtoupper,strtr,' . 'substr_compare,substr_count,substr_replace,trim,ucfirst,ucwords,' . 'wordwrap,floatval,strval,implode,explode');
  45. define('DIV_PHP_VALID_TOKENS_FOR_EXPRESSIONS', 'T_ARRAY,T_ARRAY_CAST,T_BOOLEAN_AND,T_BOOLEAN_OR,T_BOOL_CAST,' . 'T_CHARACTER,T_CONSTANT_ENCAPSED_STRING,T_DNUMBER,T_DOUBLE_CAST,' . 'T_EMPTY,T_INT_CAST,T_ISSET,T_IS_EQUAL,T_IS_GREATER_OR_EQUAL,' . 'T_SR,T_IS_IDENTICAL,T_IS_NOT_EQUAL,T_IS_NOT_IDENTICAL,' . 'T_IS_SMALLER_OR_EQUAL,T_LNUMBER,T_LOGICAL_AND,T_LOGICAL_OR,T_LOGICAL_XOR,' . 'T_SL,T_SL_EQUAL,T_SR_EQUAL,T_STRING_CAST,T_STRING_VARNAME,T_VARIABLE,' . 'T_WHITESPACE,T_CURLY_OPEN,T_INC,T_COMMENT,T_DOUBLE_ARROW,' . 'T_ENCAPSED_AND_WHITESPACE');
  46. define('DIV_PHP_VALID_TOKENS_FOR_MACROS', 'T_AS,T_DO,T_DOUBLE_COLON,T_ECHO,T_ELSE,T_ELSEIF,T_FOR,T_FOREACH,T_IF,' . 'T_MOD_EQUAL,T_MUL_EQUAL,T_OBJECT_OPERATOR,T_NUM_STRING,T_OR_EQUAL,' . 'T_PAAMAYIM_NEKUDOTAYIM,T_PLUS_EQUAL,T_PRINT,' . 'T_START_HEREDOC,T_SWITCH,T_WHILE,' . 'T_ENDIF,T_ENDFOR,T_ENDFOREACH,T_ENDSWITCH,T_ENDWHILE,T_END_HEREDOC,' . 'T_PAAMAYIM_NEKUDOTAYIM');
  47. define('DIV_PHP_ALLOWED_METHODS', 'getRanges,asThis,atLeastOneString,getLastKeyOfArray,getCountOfParagraphs,getCountOfSentences,getCountOfWords,' . 'htmlToText,isArrayOfArray,isArrayOfObjects,isCli,isNumericList,jsonDecode,jsonEncode,isString,mixedBool');
  48. define('DIV_ERROR_WARNING', 'WARNING');
  49. define('DIV_ERROR_FATAL', 'FATAL');
  50. define('DIV_METHOD_NOT_EXISTS', 'DIV_METHOD_NOT_EXISTS');
  51. define('DIV_UNICODE_ERROR', - 1);
  52. define('DIV_MOMENT_BEFORE_PARSE', 'DIV_MOMENT_BEFORE_PARSE');
  53. define('DIV_MOMENT_AFTER_PARSE', 'DIV_MOMENT_AFTER_PARSE');
  54. define('DIV_MOMENT_AFTER_INCLUDE', 'DIV_MOMENT_AFTER_INCLUDE');
  55. define('DIV_MOMENT_AFTER_REPLACE', 'DIV_MOMENT_AFTER_REPLACE');
  56. // ------------------------------------- D E F A U L T D I A L E C T --------------------------------------//
  57. if (! defined('DIV_TAG_REPLACEMENT_PREFIX'))
  58. define('DIV_TAG_REPLACEMENT_PREFIX', '{'); // Variables
  59. if (! defined('DIV_TAG_REPLACEMENT_SUFFIX'))
  60. define('DIV_TAG_REPLACEMENT_SUFFIX', '}');
  61. if (! defined('DIV_TAG_MULTI_MODIFIERS_PREFIX'))
  62. define('DIV_TAG_MULTI_MODIFIERS_PREFIX', '{$');
  63. if (! defined('DIV_TAG_MULTI_MODIFIERS_OPERATOR'))
  64. define('DIV_TAG_MULTI_MODIFIERS_OPERATOR', '|');
  65. if (! defined('DIV_TAG_MULTI_MODIFIERS_SEPARATOR'))
  66. define('DIV_TAG_MULTI_MODIFIERS_SEPARATOR', '|');
  67. if (! defined('DIV_TAG_MULTI_MODIFIERS_SUFFIX'))
  68. define('DIV_TAG_MULTI_MODIFIERS_SUFFIX', '|}');
  69. if (! defined('DIV_TAG_SUBMATCH_SEPARATOR'))
  70. define('DIV_TAG_SUBMATCH_SEPARATOR', ':');
  71. if (! defined('DIV_TAG_MODIFIER_SIMPLE'))
  72. define('DIV_TAG_MODIFIER_SIMPLE', '$'); // Variable's modifiers
  73. if (! defined('DIV_TAG_MODIFIER_CAPITALIZE_FIRST'))
  74. define('DIV_TAG_MODIFIER_CAPITALIZE_FIRST', '^');
  75. if (! defined('DIV_TAG_MODIFIER_CAPITALIZE_WORDS'))
  76. define('DIV_TAG_MODIFIER_CAPITALIZE_WORDS', '^^');
  77. if (! defined('DIV_TAG_MODIFIER_UPPERCASE'))
  78. define('DIV_TAG_MODIFIER_UPPERCASE', '^^^');
  79. if (! defined('DIV_TAG_MODIFIER_LOWERCASE'))
  80. define('DIV_TAG_MODIFIER_LOWERCASE', '_');
  81. if (! defined('DIV_TAG_MODIFIER_LENGTH'))
  82. define('DIV_TAG_MODIFIER_LENGTH', '%');
  83. if (! defined('DIV_TAG_MODIFIER_COUNT_WORDS'))
  84. define('DIV_TAG_MODIFIER_COUNT_WORDS', '%%');
  85. if (! defined('DIV_TAG_MODIFIER_COUNT_SENTENCES'))
  86. define('DIV_TAG_MODIFIER_COUNT_SENTENCES', '%%%');
  87. if (! defined('DIV_TAG_MODIFIER_COUNT_PARAGRAPHS'))
  88. define('DIV_TAG_MODIFIER_COUNT_PARAGRAPHS', '%%%%');
  89. if (! defined('DIV_TAG_MODIFIER_ENCODE_URL'))
  90. define('DIV_TAG_MODIFIER_ENCODE_URL', '&');
  91. if (! defined('DIV_TAG_MODIFIER_ENCODE_RAW_URL'))
  92. define('DIV_TAG_MODIFIER_ENCODE_RAW_URL', '&&');
  93. if (! defined('DIV_TAG_MODIFIER_ENCODE_JSON'))
  94. define('DIV_TAG_MODIFIER_ENCODE_JSON', 'json:');
  95. if (! defined('DIV_TAG_MODIFIER_HTML_ENTITIES'))
  96. define('DIV_TAG_MODIFIER_HTML_ENTITIES', 'html:');
  97. if (! defined('DIV_TAG_MODIFIER_NL2BR'))
  98. define('DIV_TAG_MODIFIER_NL2BR', 'br:');
  99. if (! defined('DIV_TAG_MODIFIER_TRUNCATE'))
  100. define('DIV_TAG_MODIFIER_TRUNCATE', '~');
  101. if (! defined('DIV_TAG_MODIFIER_WORDWRAP'))
  102. define('DIV_TAG_MODIFIER_WORDWRAP', '/');
  103. if (! defined('DIV_TAG_MODIFIER_SUBSTRING_SEPARATOR'))
  104. define('DIV_TAG_MODIFIER_SUBSTRING_SEPARATOR', ',');
  105. if (! defined('DIV_TAG_MODIFIER_SINGLE_QUOTES'))
  106. define('DIV_TAG_MODIFIER_SINGLE_QUOTES', "'");
  107. if (! defined('DIV_TAG_MODIFIER_JS'))
  108. define('DIV_TAG_MODIFIER_JS', "js:");
  109. if (! defined('DIV_TAG_MODIFIER_FORMAT'))
  110. define('DIV_TAG_MODIFIER_FORMAT', '');
  111. if (! defined('DIV_TAG_DATE_FORMAT_PREFIX'))
  112. define('DIV_TAG_DATE_FORMAT_PREFIX', '{/'); // Data format
  113. if (! defined('DIV_TAG_DATE_FORMAT_SUFFIX'))
  114. define('DIV_TAG_DATE_FORMAT_SUFFIX', '/}');
  115. if (! defined('DIV_TAG_DATE_FORMAT_SEPARATOR'))
  116. define('DIV_TAG_DATE_FORMAT_SEPARATOR', ':');
  117. if (! defined('DIV_TAG_NUMBER_FORMAT_PREFIX'))
  118. define('DIV_TAG_NUMBER_FORMAT_PREFIX', '{#');
  119. if (! defined('DIV_TAG_NUMBER_FORMAT_SUFFIX'))
  120. define('DIV_TAG_NUMBER_FORMAT_SUFFIX', '#}');
  121. if (! defined('DIV_TAG_NUMBER_FORMAT_SEPARATOR'))
  122. define('DIV_TAG_NUMBER_FORMAT_SEPARATOR', ':');
  123. if (! defined('DIV_TAG_FORMULA_BEGIN'))
  124. define('DIV_TAG_FORMULA_BEGIN', '(#'); // Formulas
  125. if (! defined('DIV_TAG_FORMULA_END'))
  126. define('DIV_TAG_FORMULA_END', '#)');
  127. if (! defined('DIV_TAG_FORMULA_FORMAT_SEPARATOR'))
  128. define('DIV_TAG_FORMULA_FORMAT_SEPARATOR', ':');
  129. if (! defined('DIV_TAG_SUBPARSER_BEGIN_PREFIX'))
  130. define('DIV_TAG_SUBPARSER_BEGIN_PREFIX', '{'); // Sub-parsers
  131. if (! defined('DIV_TAG_SUBPARSER_BEGIN_SUFFIX'))
  132. define('DIV_TAG_SUBPARSER_BEGIN_SUFFIX', '}');
  133. if (! defined('DIV_TAG_SUBPARSER_END_PREFIX'))
  134. define('DIV_TAG_SUBPARSER_END_PREFIX', '{/');
  135. if (! defined('DIV_TAG_SUBPARSER_END_SUFFIX'))
  136. define('DIV_TAG_SUBPARSER_END_SUFFIX', '}');
  137. if (! defined('DIV_TAG_IGNORE_BEGIN'))
  138. define('DIV_TAG_IGNORE_BEGIN', '{ignore}'); // Ignored parts
  139. if (! defined('DIV_TAG_IGNORE_END'))
  140. define('DIV_TAG_IGNORE_END', '{/ignore}');
  141. if (! defined('DIV_TAG_COMMENT_BEGIN'))
  142. define('DIV_TAG_COMMENT_BEGIN', '<!--{'); // Comments
  143. if (! defined('DIV_TAG_COMMENT_END'))
  144. define('DIV_TAG_COMMENT_END', '}-->');
  145. if (! defined('DIV_TAG_TXT_BEGIN'))
  146. define('DIV_TAG_TXT_BEGIN', '{txt}'); // HTML to Plain text
  147. if (! defined('DIV_TAG_TXT_END'))
  148. define('DIV_TAG_TXT_END', '{/txt}');
  149. if (! defined('DIV_TAG_TXT_WIDTH_SEPARATOR'))
  150. define('DIV_TAG_TXT_WIDTH_SEPARATOR', '=>');
  151. if (! defined('DIV_TAG_STRIP_BEGIN'))
  152. define('DIV_TAG_STRIP_BEGIN', '{strip}'); // Strip
  153. if (! defined('DIV_TAG_STRIP_END'))
  154. define('DIV_TAG_STRIP_END', '{/strip}');
  155. if (! defined('DIV_TAG_LOOP_BEGIN_PREFIX'))
  156. define('DIV_TAG_LOOP_BEGIN_PREFIX', '[$'); // Loops
  157. if (! defined('DIV_TAG_LOOP_BEGIN_SUFFIX'))
  158. define('DIV_TAG_LOOP_BEGIN_SUFFIX', ']');
  159. if (! defined('DIV_TAG_LOOP_END_PREFIX'))
  160. define('DIV_TAG_LOOP_END_PREFIX', '[/$');
  161. if (! defined('DIV_TAG_LOOP_END_SUFFIX'))
  162. define('DIV_TAG_LOOP_END_SUFFIX', ']');
  163. if (! defined('DIV_TAG_EMPTY'))
  164. define('DIV_TAG_EMPTY', '@empty@');
  165. if (! defined('DIV_TAG_BREAK'))
  166. define('DIV_TAG_BREAK', '@break@');
  167. if (! defined('DIV_TAG_LOOP_VAR_SEPARATOR'))
  168. define('DIV_TAG_LOOP_VAR_SEPARATOR', '=>');
  169. if (! defined('DIV_TAG_ITERATION_BEGIN_PREFIX'))
  170. define('DIV_TAG_ITERATION_BEGIN_PREFIX', '[:'); // Iterations
  171. if (! defined('DIV_TAG_ITERATION_BEGIN_SUFFIX'))
  172. define('DIV_TAG_ITERATION_BEGIN_SUFFIX', ':]');
  173. if (! defined('DIV_TAG_ITERATION_END'))
  174. define('DIV_TAG_ITERATION_END', '[/]');
  175. if (! defined('DIV_TAG_ITERATION_PARAM_SEPARATOR'))
  176. define('DIV_TAG_ITERATION_PARAM_SEPARATOR', ',');
  177. if (! defined('DIV_TAG_CONDITIONAL_TRUE_BEGIN_PREFIX'))
  178. define('DIV_TAG_CONDITIONAL_TRUE_BEGIN_PREFIX', '?$'); // Conditional parts
  179. if (! defined('DIV_TAG_CONDITIONAL_TRUE_BEGIN_SUFFIX'))
  180. define('DIV_TAG_CONDITIONAL_TRUE_BEGIN_SUFFIX', '');
  181. if (! defined('DIV_TAG_CONDITIONAL_TRUE_END_PREFIX'))
  182. define('DIV_TAG_CONDITIONAL_TRUE_END_PREFIX', '$');
  183. if (! defined('DIV_TAG_CONDITIONAL_TRUE_END_SUFFIX'))
  184. define('DIV_TAG_CONDITIONAL_TRUE_END_SUFFIX', '?');
  185. if (! defined('DIV_TAG_CONDITIONAL_FALSE_BEGIN_PREFIX'))
  186. define('DIV_TAG_CONDITIONAL_FALSE_BEGIN_PREFIX', '!$');
  187. if (! defined('DIV_TAG_CONDITIONAL_FALSE_BEGIN_SUFFIX'))
  188. define('DIV_TAG_CONDITIONAL_FALSE_BEGIN_SUFFIX', '');
  189. if (! defined('DIV_TAG_CONDITIONAL_FALSE_END_PREFIX'))
  190. define('DIV_TAG_CONDITIONAL_FALSE_END_PREFIX', '$');
  191. if (! defined('DIV_TAG_CONDITIONAL_FALSE_END_SUFFIX'))
  192. define('DIV_TAG_CONDITIONAL_FALSE_END_SUFFIX', '!');
  193. if (! defined('DIV_TAG_ELSE'))
  194. define('DIV_TAG_ELSE', '@else@');
  195. if (! defined('DIV_TAG_CONDITIONS_BEGIN_PREFIX'))
  196. define('DIV_TAG_CONDITIONS_BEGIN_PREFIX', '{?('); // Conditions
  197. if (! defined('DIV_TAG_CONDITIONS_BEGIN_SUFFIX'))
  198. define('DIV_TAG_CONDITIONS_BEGIN_SUFFIX', ')?}');
  199. if (! defined('DIV_TAG_CONDITIONS_END'))
  200. define('DIV_TAG_CONDITIONS_END', '{/?}');
  201. if (! defined('DIV_TAG_TPLVAR_BEGIN'))
  202. define('DIV_TAG_TPLVAR_BEGIN', '{='); // Template vars
  203. if (! defined('DIV_TAG_TPLVAR_END'))
  204. define('DIV_TAG_TPLVAR_END', '=}');
  205. if (! defined('DIV_TAG_TPLVAR_ASSIGN_OPERATOR'))
  206. define('DIV_TAG_TPLVAR_ASSIGN_OPERATOR', ':');
  207. if (! defined('DIV_TAG_TPLVAR_PROTECTOR'))
  208. define('DIV_TAG_TPLVAR_PROTECTOR', '*');
  209. if (! defined('DIV_TAG_DEFAULT_REPLACEMENT_BEGIN'))
  210. define('DIV_TAG_DEFAULT_REPLACEMENT_BEGIN', '{@'); // Default replacement
  211. if (! defined('DIV_TAG_DEFAULT_REPLACEMENT_END'))
  212. define('DIV_TAG_DEFAULT_REPLACEMENT_END', '@}');
  213. if (! defined('DIV_TAG_INCLUDE_BEGIN'))
  214. define('DIV_TAG_INCLUDE_BEGIN', '{% '); // Includes
  215. if (! defined('DIV_TAG_INCLUDE_END'))
  216. define('DIV_TAG_INCLUDE_END', ' %}');
  217. if (! defined('DIV_TAG_PREPROCESSED_BEGIN'))
  218. define('DIV_TAG_PREPROCESSED_BEGIN', '{%% '); // Pre-processed
  219. if (! defined('DIV_TAG_PREPROCESSED_END'))
  220. define('DIV_TAG_PREPROCESSED_END', ' %%}');
  221. if (! defined('DIV_TAG_CAPSULE_BEGIN_PREFIX'))
  222. define('DIV_TAG_CAPSULE_BEGIN_PREFIX', '[['); // Capsules
  223. if (! defined('DIV_TAG_CAPSULE_BEGIN_SUFFIX'))
  224. define('DIV_TAG_CAPSULE_BEGIN_SUFFIX', '');
  225. if (! defined('DIV_TAG_CAPSULE_END_PREFIX'))
  226. define('DIV_TAG_CAPSULE_END_PREFIX', '');
  227. if (! defined('DIV_TAG_CAPSULE_END_SUFFIX'))
  228. define('DIV_TAG_CAPSULE_END_SUFFIX', ']]');
  229. if (! defined('DIV_TAG_MULTI_REPLACEMENT_BEGIN_PREFIX'))
  230. define('DIV_TAG_MULTI_REPLACEMENT_BEGIN_PREFIX', '{:'); // Multi replacements
  231. if (! defined('DIV_TAG_MULTI_REPLACEMENT_BEGIN_SUFFIX'))
  232. define('DIV_TAG_MULTI_REPLACEMENT_BEGIN_SUFFIX', '}');
  233. if (! defined('DIV_TAG_MULTI_REPLACEMENT_END_PREFIX'))
  234. define('DIV_TAG_MULTI_REPLACEMENT_END_PREFIX', '{:/');
  235. if (! defined('DIV_TAG_MULTI_REPLACEMENT_END_SUFFIX'))
  236. define('DIV_TAG_MULTI_REPLACEMENT_END_SUFFIX', '}');
  237. if (! defined('DIV_TAG_FRIENDLY_BEGIN'))
  238. define('DIV_TAG_FRIENDLY_BEGIN', '<!--|'); // Friendly tags
  239. if (! defined('DIV_TAG_FRIENDLY_END'))
  240. define('DIV_TAG_FRIENDLY_END', '|-->');
  241. if (! defined('DIV_TAG_AGGREGATE_FUNCTION_COUNT'))
  242. define('DIV_TAG_AGGREGATE_FUNCTION_COUNT', 'count'); // Aggregate functions
  243. if (! defined('DIV_TAG_AGGREGATE_FUNCTION_MAX'))
  244. define('DIV_TAG_AGGREGATE_FUNCTION_MAX', 'max');
  245. if (! defined('DIV_TAG_AGGREGATE_FUNCTION_MIN'))
  246. define('DIV_TAG_AGGREGATE_FUNCTION_MIN', 'min');
  247. if (! defined('DIV_TAG_AGGREGATE_FUNCTION_SUM'))
  248. define('DIV_TAG_AGGREGATE_FUNCTION_SUM', 'sum');
  249. if (! defined('DIV_TAG_AGGREGATE_FUNCTION_AVG'))
  250. define('DIV_TAG_AGGREGATE_FUNCTION_AVG', 'avg');
  251. if (! defined('DIV_TAG_AGGREGATE_FUNCTION_SEPARATOR'))
  252. define('DIV_TAG_AGGREGATE_FUNCTION_SEPARATOR', ':');
  253. if (! defined('DIV_TAG_AGGREGATE_FUNCTION_PROPERTY_SEPARATOR'))
  254. define('DIV_TAG_AGGREGATE_FUNCTION_PROPERTY_SEPARATOR', '-');
  255. if (! defined('DIV_TAG_LOCATION_BEGIN'))
  256. define('DIV_TAG_LOCATION_BEGIN', '(( '); // Locations
  257. if (! defined('DIV_TAG_LOCATION_END'))
  258. define('DIV_TAG_LOCATION_END', ' ))');
  259. if (! defined('DIV_TAG_LOCATION_CONTENT_BEGIN_PREFIX'))
  260. define('DIV_TAG_LOCATION_CONTENT_BEGIN_PREFIX', '{{');
  261. if (! defined('DIV_TAG_LOCATION_CONTENT_BEGIN_SUFFIX'))
  262. define('DIV_TAG_LOCATION_CONTENT_BEGIN_SUFFIX', '');
  263. if (! defined('DIV_TAG_LOCATION_CONTENT_END_PREFIX'))
  264. define('DIV_TAG_LOCATION_CONTENT_END_PREFIX', '');
  265. if (! defined('DIV_TAG_LOCATION_CONTENT_END_SUFFIX'))
  266. define('DIV_TAG_LOCATION_CONTENT_END_SUFFIX', '}}');
  267. if (! defined('DIV_TAG_MACRO_BEGIN'))
  268. define('DIV_TAG_MACRO_BEGIN', '<?'); // Macros
  269. if (! defined('DIV_TAG_MACRO_END'))
  270. define('DIV_TAG_MACRO_END', '?>');
  271. if (! defined('DIV_TAG_SPECIAL_REPLACE_NEW_LINE'))
  272. define('DIV_TAG_SPECIAL_REPLACE_NEW_LINE', '{\n}'); // Special replacements
  273. if (! defined('DIV_TAG_SPECIAL_REPLACE_CAR_RETURN'))
  274. define('DIV_TAG_SPECIAL_REPLACE_CAR_RETURN', '{\r}');
  275. if (! defined('DIV_TAG_SPECIAL_REPLACE_HORIZONTAL_TAB'))
  276. define('DIV_TAG_SPECIAL_REPLACE_HORIZONTAL_TAB', '{\t}');
  277. if (! defined('DIV_TAG_SPECIAL_REPLACE_VERTICAL_TAB'))
  278. define('DIV_TAG_SPECIAL_REPLACE_VERTICAL_TAB', '{\v}');
  279. if (! defined('DIV_TAG_SPECIAL_REPLACE_NEXT_PAGE'))
  280. define('DIV_TAG_SPECIAL_REPLACE_NEXT_PAGE', '{\f}');
  281. if (! defined('DIV_TAG_SPECIAL_REPLACE_DOLLAR_SYMBOL'))
  282. define('DIV_TAG_SPECIAL_REPLACE_DOLLAR_SYMBOL', '{\$}');
  283. if (! defined('DIV_TAG_TEASER_BREAK'))
  284. define('DIV_TAG_TEASER_BREAK', '<!--break-->');
  285. define('DIV_DEFAULT_DIALECT', '{
  286. \'DIV_TAG_REPLACEMENT_PREFIX\' : \'{\', \'DIV_TAG_REPLACEMENT_SUFFIX\' : \'}\',
  287. \'DIV_TAG_MULTI_MODIFIERS_PREFIX\' : \'{$\', \'DIV_TAG_MULTI_MODIFIERS_SEPARATOR\' : \'|\',
  288. \'DIV_TAG_MULTI_MODIFIERS_OPERATOR\' : \'|\', \'DIV_TAG_MULTI_MODIFIERS_SUFFIX\' : \'|}\',
  289. \'DIV_TAG_SUBMATCH_SEPARATOR\' : \':\', \'DIV_TAG_MODIFIER_SIMPLE\' : \'$\',
  290. \'DIV_TAG_MODIFIER_CAPITALIZE_FIRST\' : \'^\', \'DIV_TAG_MODIFIER_CAPITALIZE_WORDS\' : \'^^\',
  291. \'DIV_TAG_MODIFIER_UPPERCASE\' : \'^^^\', \'DIV_TAG_MODIFIER_LOWERCASE\' : \'_\',
  292. \'DIV_TAG_MODIFIER_LENGTH\' : \'%\', \'DIV_TAG_MODIFIER_COUNT_WORDS\' : \'%%\',
  293. \'DIV_TAG_MODIFIER_COUNT_SENTENCES\' : \'%%%\', \'DIV_TAG_MODIFIER_COUNT_PARAGRAPHS\' : \'%%%%\',
  294. \'DIV_TAG_MODIFIER_ENCODE_URL\' : \'&\', \'DIV_TAG_MODIFIER_ENCODE_RAW_URL\' : \'&&\',
  295. \'DIV_TAG_MODIFIER_ENCODE_JSON\' : \'json:\', \'DIV_TAG_MODIFIER_HTML_ENTITIES\' : \'html:\',
  296. \'DIV_TAG_MODIFIER_NL2BR\' : \'br:\', \'DIV_TAG_MODIFIER_TRUNCATE\' : \'~\',
  297. \'DIV_TAG_MODIFIER_WORDWRAP\' : \'/\', \'DIV_TAG_MODIFIER_SUBSTRING_SEPARATOR\' : \',\',
  298. \'DIV_TAG_MODIFIER_SINGLE_QUOTES\' : "\'", \'DIV_TAG_MODIFIER_JS\' : \'js:\',
  299. \'DIV_TAG_MODIFIER_FORMAT\' : \'\', \'DIV_TAG_DATE_FORMAT_PREFIX\' : \'{/\',
  300. \'DIV_TAG_DATE_FORMAT_SUFFIX\' : \'/}\', \'DIV_TAG_DATE_FORMAT_SEPARATOR\' : \':\',
  301. \'DIV_TAG_NUMBER_FORMAT_PREFIX\' : \'{#\', \'DIV_TAG_NUMBER_FORMAT_SUFFIX\' : \'#}\',
  302. \'DIV_TAG_NUMBER_FORMAT_SEPARATOR\' : \':\', \'DIV_TAG_FORMULA_BEGIN\' : \'(#\',
  303. \'DIV_TAG_FORMULA_END\' : \'#)\', \'DIV_TAG_FORMULA_FORMAT_SEPARATOR\' : \':\',
  304. \'DIV_TAG_SUBPARSER_BEGIN_PREFIX\' : \'{\', \'DIV_TAG_SUBPARSER_BEGIN_SUFFIX\' : \'}\',
  305. \'DIV_TAG_SUBPARSER_END_PREFIX\' : \'{/\', \'DIV_TAG_SUBPARSER_END_SUFFIX\' : \'}\',
  306. \'DIV_TAG_IGNORE_BEGIN\' : \'{ignore}\', \'DIV_TAG_IGNORE_END\' : \'{/ignore}\',
  307. \'DIV_TAG_COMMENT_BEGIN\' : \'<!--{\', \'DIV_TAG_COMMENT_END\' : \'}-->\',
  308. \'DIV_TAG_TXT_BEGIN\' : \'{txt}\', \'DIV_TAG_TXT_END\' : \'{/txt}\',
  309. \'DIV_TAG_TXT_WIDTH_SEPARATOR\' : \'=>\', \'DIV_TAG_STRIP_BEGIN\' : \'{strip}\',
  310. \'DIV_TAG_STRIP_END\' : \'{/strip}\', \'DIV_TAG_LOOP_BEGIN_PREFIX\' : \'[$\',
  311. \'DIV_TAG_LOOP_BEGIN_SUFFIX\' : \']\', \'DIV_TAG_LOOP_END_PREFIX\' : \'[/$\',
  312. \'DIV_TAG_LOOP_END_SUFFIX\' : \']\', \'DIV_TAG_EMPTY\' : \'@empty@\',
  313. \'DIV_TAG_BREAK\' : \'@break@\', \'DIV_TAG_LOOP_VAR_SEPARATOR\' : \'=>\',
  314. \'DIV_TAG_ITERATION_BEGIN_PREFIX\' : \'[:\', \'DIV_TAG_ITERATION_BEGIN_SUFFIX\' : \':]\',
  315. \'DIV_TAG_ITERATION_END\' : \'[/]\', \'DIV_TAG_ITERATION_PARAM_SEPARATOR\' : \',\',
  316. \'DIV_TAG_CONDITIONAL_TRUE_BEGIN_PREFIX\' : \'?$\', \'DIV_TAG_CONDITIONAL_TRUE_BEGIN_SUFFIX\' : \'\',
  317. \'DIV_TAG_CONDITIONAL_TRUE_END_PREFIX\' : \'$\', \'DIV_TAG_CONDITIONAL_TRUE_END_SUFFIX\' : \'?\',
  318. \'DIV_TAG_CONDITIONAL_FALSE_BEGIN_PREFIX\' : \'!$\', \'DIV_TAG_CONDITIONAL_FALSE_BEGIN_SUFFIX\' : \'\',
  319. \'DIV_TAG_CONDITIONAL_FALSE_END_PREFIX\' : \'$\', \'DIV_TAG_CONDITIONAL_FALSE_END_SUFFIX\' : \'!\',
  320. \'DIV_TAG_ELSE\' : \'@else@\', \'DIV_TAG_CONDITIONS_BEGIN_PREFIX\' : \'{?(\',
  321. \'DIV_TAG_CONDITIONS_BEGIN_SUFFIX\' : \')?}\', \'DIV_TAG_CONDITIONS_END\' : \'{/?}\',
  322. \'DIV_TAG_TPLVAR_BEGIN\' : \'{=\', \'DIV_TAG_TPLVAR_END\' : \'=}\',
  323. \'DIV_TAG_TPLVAR_ASSIGN_OPERATOR\' : \':\', \'DIV_TAG_TPLVAR_PROTECTOR\' : \'*\',
  324. \'DIV_TAG_DEFAULT_REPLACEMENT_BEGIN\' : \'{@\', \'DIV_TAG_DEFAULT_REPLACEMENT_END\' : \'@}\',
  325. \'DIV_TAG_INCLUDE_BEGIN\' : \'{% \', \'DIV_TAG_INCLUDE_END\' : \' %}\',
  326. \'DIV_TAG_PREPROCESSED_BEGIN\' : \'{%% \', \'DIV_TAG_PREPROCESSED_END\' : \' %%}\',
  327. \'DIV_TAG_CAPSULE_BEGIN_PREFIX\' : \'[[\', \'DIV_TAG_CAPSULE_BEGIN_SUFFIX\' : \'\',
  328. \'DIV_TAG_CAPSULE_END_PREFIX\' : \'\', \'DIV_TAG_CAPSULE_END_SUFFIX\' : \']]\',
  329. \'DIV_TAG_MULTI_REPLACEMENT_BEGIN_PREFIX\' : \'{:\', \'DIV_TAG_MULTI_REPLACEMENT_BEGIN_SUFFIX\' : \'}\',
  330. \'DIV_TAG_MULTI_REPLACEMENT_END_PREFIX\' : \'{:/\', \'DIV_TAG_MULTI_REPLACEMENT_END_SUFFIX\' : \'}\',
  331. \'DIV_TAG_FRIENDLY_BEGIN\' : \'<!--|\', \'DIV_TAG_FRIENDLY_END\' : \'|-->\',
  332. \'DIV_TAG_AGGREGATE_FUNCTION_COUNT\' : \'count\', \'DIV_TAG_AGGREGATE_FUNCTION_MAX\' : \'max\',
  333. \'DIV_TAG_AGGREGATE_FUNCTION_MIN\' : \'min\', \'DIV_TAG_AGGREGATE_FUNCTION_SUM\' : \'sum\',
  334. \'DIV_TAG_AGGREGATE_FUNCTION_AVG\' : \'avg\', \'DIV_TAG_AGGREGATE_FUNCTION_SEPARATOR\' : \':\',
  335. \'DIV_TAG_AGGREGATE_FUNCTION_PROPERTY_SEPARATOR\' : \'-\', \'DIV_TAG_LOCATION_BEGIN\' : \'(( \',
  336. \'DIV_TAG_LOCATION_END\' : \' ))\', \'DIV_TAG_LOCATION_CONTENT_BEGIN_PREFIX\' : \'{{\',
  337. \'DIV_TAG_LOCATION_CONTENT_BEGIN_SUFFIX\' : \'\', \'DIV_TAG_LOCATION_CONTENT_END_PREFIX\' : \'\',
  338. \'DIV_TAG_LOCATION_CONTENT_END_SUFFIX\' : \'}}\', \'DIV_TAG_MACRO_BEGIN\' : \'<?\',
  339. \'DIV_TAG_MACRO_END\' : \'?>\', \'DIV_TAG_SPECIAL_REPLACE_NEW_LINE\' : \'{\\n}\',
  340. \'DIV_TAG_SPECIAL_REPLACE_CAR_RETURN\' : \'{\\r}\', \'DIV_TAG_SPECIAL_REPLACE_HORIZONTAL_TAB\' : \'{\\t}\',
  341. \'DIV_TAG_SPECIAL_REPLACE_VERTICAL_TAB\' : \'{\\v}\', \'DIV_TAG_SPECIAL_REPLACE_NEXT_PAGE\' : \'{\\f}\',
  342. \'DIV_TAG_SPECIAL_REPLACE_DOLLAR_SYMBOL\' : \'{\\$}\', \'DIV_TAG_TEASER_BREAK\' : \'<!--break-->\'
  343. }');
  344. // --------------------------------------------------------------------------------------------------------------------------------------//
  345. define('DIV_TEMPLATE_FOR_DOCS', '
  346. @_DIALECT = ' . uniqid() . '
  347. <html>
  348. <head>
  349. <title>{$title}</title>
  350. <style type="text/css">
  351. body {background: #656565; font-family: Verdana;}
  352. div.section {background: white; margin-top: 20px; padding: 10px; width: 780px;}
  353. .section h2 {color: white; font-size: 24px;font-weight: bold; margin-left: -30px;padding-bottom: 5px; padding-left: 30px;padding-top: 5px; background: black; border-left: 10px solid gray;}
  354. h1 {color: white;}
  355. table.data td {padding: 5px;border-bottom: 1px solid gray; border-right: 1px solid gray;}
  356. table.data th {padding: 5px;color: white; background: black;}
  357. .code {padding: 0px; margin: 0px; background: #eeeeee; color: black; font-family: "Courier New"; text-align: left; font-size: 13px;}
  358. .code .line {text-align:right; background: gray; color: white; border-right: 2px solid black; padding-right: 5px;}
  359. table.index, table.index a, table.index a:visited {color:white;}
  360. div.header {color: white;}
  361. .template-description{background: #eeeeee; padding: 10px;}
  362. </style>
  363. </head>
  364. <body>
  365. <label><a href="#header" style="position: fixed; bottom: 5px; right: 5px;color: white;">Index</a></label>
  366. <table width="750" align="center"><tr><td valign="top">
  367. <div id = "header" class = "header">
  368. <h1>{$title}</h1>
  369. <p>Generated by Div at {/div.now:Y-m-d H:i:s/}</p>
  370. <h2>Index</h2>
  371. <table class="index data" width="100%">
  372. <tr><th></th><th>Name</th><th>Description</th><th>Version</th></tr>
  373. [$docs]
  374. <tr><td>{$_order}</td>
  375. <td><a href="#{$_key}">?$name {$name} $name?</a></td>
  376. <td>?$description {$description} $description?</td>
  377. <td>?$version {$version} $version?</td></tr>
  378. [/$docs]
  379. </table>
  380. </div>
  381. {= repl1: [["<",""],[">",""]] =}
  382. [$docs]
  383. <div class="section">
  384. <h2 id = "{$_key}">?$icon {$icon} $icon? {$name}</h2>
  385. <table width="100%">
  386. <tr><td align="right">Path:</td><td>{$_key} </td></tr>
  387. ?$type <tr><td align="right" width="150">Type:</td><td><b>{$type}</b></td></tr>$type?
  388. ?$author <tr><td align="right" width="150">Author:</td><td><b>{html:author}</b></td></tr> $author?
  389. ?$version <tr><td align="right" width="150">Version:</td><td><b>{$version}</b></td></tr> $version?
  390. ?$update <tr><td align="right" width="150">Last update:</td><td>{$update} </td></tr>$update?
  391. </table>
  392. <br/>
  393. ?$description <p class="template-description">{$description}</p>$description?
  394. ?$vars
  395. <h3>Template\'s Variables ({$vars})</h3>
  396. <table class="data">
  397. <tr><th></th><th></th><th>Type</th><th>Name</th><th>Description</th></tr>
  398. [$vars]
  399. {?( trim("{\'value}") !== "" )?}
  400. <?
  401. $value = trim(str_replace(array("\t","\n","\r")," ", $value));
  402. while(strpos($value, " ")) $value = str_replace(" "," ", $value);
  403. $pars = explode(" ", $value, 4);
  404. ?>
  405. <tr>
  406. <td>{$_order}</td>
  407. [$pars]
  408. <td>{:repl1}{$value}{:/repl1}</td>
  409. [/$pars]
  410. </tr>
  411. {/?}
  412. [/$vars]
  413. </table>
  414. $vars?
  415. ?$include
  416. <h3>Include:</h3>
  417. [$include]
  418. {$_order}. <a href="#{$value}">{$value}</a><br/>
  419. [/$include]
  420. $include?
  421. ?$example
  422. <h3>Example:</h3>
  423. <table width = "100%" class="code" cellspacing="0" cellpadding="0">
  424. [$example]
  425. <tr>
  426. <td class="line" width="30">{$_order}</td>
  427. <td><pre class="code">{html_wysiwyg:afterReplace}{$value}{/html_wysiwyg:afterReplace}</pre></td>
  428. </tr>
  429. [/$example]
  430. </table>
  431. $example?
  432. </div>
  433. [/$docs]
  434. </td></tr></table>
  435. </body>
  436. </html>');
  437. /**
  438. * The div class is the complete implementation of Div.
  439. *
  440. * See the following example:
  441. *
  442. * echo new div('Hello {$name}', array('name' => 'Peter Pan'));
  443. */
  444. class div {
  445. // Public
  446. public $__src = null;
  447. // template source
  448. public $__src_original = null;
  449. // original template source
  450. public $__items = array();
  451. // template variables
  452. public $__items_orig = array();
  453. // original template variables
  454. public $__memory = array();
  455. // to remember the template variables
  456. public $__path = '';
  457. // path to current template file
  458. public $__ignore = array();
  459. // template variables to ignore
  460. public $__restore = array();
  461. // template's parts to restore after parse
  462. public $__packages = PACKAGES;
  463. // path of current templates's root folder
  464. public $__properties = array();
  465. // properties of the template
  466. // Private
  467. private $__id = null;
  468. // template id
  469. private $__temp = array();
  470. // temporal vars
  471. private $__crc = null;
  472. // template cheksum
  473. // Globals
  474. private static $__custom_modifiers = array();
  475. // custom variable's modifiers
  476. private static $__globals = array();
  477. // global template's variables
  478. private static $__globals_design = array();
  479. // global template's variables defined in the design
  480. private static $__globals_design_protected = array();
  481. // global and protected template variables defined in the design
  482. private static $__defaults = array();
  483. // default value for another value
  484. private static $__defaults_by_var = array();
  485. // default value for another value by variable
  486. private static $__system_data = null;
  487. // system data
  488. private static $__system_data_allowed = array(
  489. 'div.version' => true,
  490. 'div.post' => true,
  491. 'div.get' => true,
  492. 'div.now' => true
  493. );
  494. private static $__discard_file_system = false;
  495. // do not load code from files
  496. private static $__allowed_functions = array();
  497. // list of allowed custom functions
  498. private static $__allowed_methods = null;
  499. // list of allowed class's methods
  500. private static $__sub_parsers = array();
  501. // list of subparsers
  502. private static $__docs = array();
  503. // template's documentation
  504. private static $__docs_on = false;
  505. // on/off documentation
  506. private static $__includes_historial = array();
  507. // includes's historial
  508. // Internals
  509. private static $__version = '4.5';
  510. // current version of Div
  511. private static $__super_class = null;
  512. // name of the super class
  513. private static $__parent_method_names = array();
  514. // name of parent class's methods
  515. private static $__method_names = null;
  516. // name of current methods
  517. private static $__parse_duration = null;
  518. // duration of parser
  519. private static $__parse_level = 0;
  520. // current level of parser
  521. private static $__engine = null;
  522. // auxiliary engine
  523. private static $__modifiers = array( // variable's modifiers
  524. DIV_TAG_MODIFIER_SIMPLE,
  525. DIV_TAG_MODIFIER_CAPITALIZE_FIRST,
  526. DIV_TAG_MODIFIER_CAPITALIZE_WORDS,
  527. DIV_TAG_MODIFIER_UPPERCASE,
  528. DIV_TAG_MODIFIER_LOWERCASE,
  529. DIV_TAG_MODIFIER_LENGTH,
  530. DIV_TAG_MODIFIER_COUNT_WORDS,
  531. DIV_TAG_MODIFIER_COUNT_SENTENCES,
  532. DIV_TAG_MODIFIER_COUNT_PARAGRAPHS,
  533. DIV_TAG_MODIFIER_ENCODE_URL,
  534. DIV_TAG_MODIFIER_ENCODE_RAW_URL,
  535. DIV_TAG_MODIFIER_HTML_ENTITIES,
  536. DIV_TAG_MODIFIER_NL2BR,
  537. DIV_TAG_MODIFIER_ENCODE_JSON,
  538. DIV_TAG_MODIFIER_SINGLE_QUOTES,
  539. DIV_TAG_MODIFIER_JS
  540. );
  541. private static $__dialect_checked = false;
  542. // is current dialect checked?
  543. private static $__allowed_php_functions = null;
  544. // allowed PHP functions
  545. private static $__log_mode = false;
  546. // is log mode?
  547. private static $__log_file = null;
  548. // the log filename
  549. private static $__is_cli = null;
  550. // is PHP cli?
  551. private static $__ignored_parts = array();
  552. // ignored parts
  553. private static $__last_id = 0;
  554. // last template id
  555. private static $__remember = array();
  556. // remember previous work
  557. private static $__dont_remember_it = array();
  558. // do not remember it work
  559. private static $__errors = array();
  560. // errors historial
  561. private static $__include_paths = null;
  562. private static $__packages_by_class = array();
  563. /**
  564. * Constructor
  565. *
  566. * @param string $src
  567. * @param mixed $items
  568. * @param array $ignore
  569. * @return div
  570. */
  571. public function __construct($src = null, $items = null, $ignore = array()){
  572. // Validate the current dialect
  573. if (self::$__dialect_checked == false) {
  574. $r = self::isValidCurrentDialect();
  575. if ($r !== true)
  576. self::error('Current dialect is invalid: ' . $r, DIV_ERROR_FATAL);
  577. self::$__dialect_checked = true;
  578. }
  579. $classname = get_class($this);
  580. self::$__packages_by_class[$classname] = $this->__packages;
  581. if (is_null(self::$__super_class))
  582. self::$__super_class = $this->getSuperParent();
  583. if (is_null(self::$__parent_method_names))
  584. self::$__parent_method_names = get_class_methods(self::$__super_class);
  585. $this->__id = ++ self::$__last_id;
  586. if (self::$__log_mode)
  587. $this->logger('Building instance #' . $this->__id . ' of ' . $classname . '...');
  588. // Calling the beforeBuild hook
  589. $this->beforeBuild($src, $items);
  590. if (is_null($items) && ! is_null($this->__items))
  591. $items = $this->__items;
  592. $this->__items_orig = $items;
  593. $decode = true;
  594. $discardfs = self::$__discard_file_system;
  595. if (is_null($src)) {
  596. if ($classname != self::$__super_class && is_null($this->__src))
  597. $src = $classname;
  598. if (! is_null($this->__src))
  599. $src = $this->__src;
  600. }
  601. if (is_null($items)) {
  602. $items = $src;
  603. $items = str_replace('.' . DIV_DEFAULT_TPL_FILE_EXT, '', $items);
  604. $decode = false;
  605. }
  606. if (! $discardfs) {
  607. if (self::isString($items))
  608. if (strlen($items . '.' . DIV_DEFAULT_DATA_FILE_EXT) < 255) {
  609. $exists = false;
  610. if (self::fileExists($items)) {
  611. $items = self::getFileContents($items);
  612. $exists = true;
  613. } elseif (self::fileExists($items . '.' . DIV_DEFAULT_DATA_FILE_EXT)) {
  614. $items = self::getFileContents($items . '.' . DIV_DEFAULT_DATA_FILE_EXT);
  615. $exists = true;
  616. }
  617. if ($exists === true || $decode === true)
  618. $items = self::jsonDecode($items);
  619. if ($exists === true)
  620. break;
  621. }
  622. }
  623. if (is_object($items)) {
  624. if (method_exists($items, '__toString')) {
  625. $itemstr = "$items";
  626. if (! isset($items->value))
  627. $items->value = $itemstr;
  628. $items->_to_string = $itemstr;
  629. }
  630. $items = get_object_vars($items);
  631. }
  632. if (! $discardfs)
  633. $src = $this->loadTemplate($src);
  634. if (! is_array($items))
  635. $items = array();
  636. $this->__src = $src;
  637. $this->__src_original = $src;
  638. $this->__items = $items;
  639. if (self::isString($ignore))
  640. $ignore = explode(',', $ignore);
  641. if (isset($ignore[0]))
  642. foreach ( $ignore as $key => $val )
  643. $this->__ignore[$val] = true;
  644. // Calling the afterBuild hook
  645. $this->afterBuild();
  646. // Enabling methods
  647. if (is_null(self::$__allowed_methods)) {
  648. $keys = explode(",", DIV_PHP_ALLOWED_METHODS);
  649. ;
  650. self::$__allowed_methods = array_combine($keys, $keys);
  651. if (self::$__super_class != $classname) {
  652. $keys = array_diff(get_class_methods($classname), get_class_methods(self::$__super_class));
  653. if (isset($keys[0]))
  654. self::$__allowed_methods = array_merge(self::$__allowed_methods, array_combine($keys, $keys));
  655. }
  656. }
  657. // Pre-defined subparsers
  658. self::setSubParser('parse', 'subParse_parse');
  659. self::setSubParser('html_wysiwyg', 'subParse_html_wysiwyg');
  660. }
  661. /**
  662. * Return a list of include_path setting + the PACKAGES
  663. *
  664. * @return array
  665. */
  666. final static function getIncludePaths($packages = PACKAGES){
  667. if (is_null(self::$__include_paths)) {
  668. $os = self::getOperatingSystem();
  669. self::$__include_paths = explode(($os == "win32" ? ";" : ":"), ini_get("include_path"));
  670. self::$__include_paths[] = $packages;
  671. }
  672. return self::$__include_paths;
  673. }
  674. /**
  675. * Return the current operating system
  676. *
  677. * @return string (win32/linux/unix)
  678. */
  679. final static function getOperatingSystem(){
  680. if (isset($_SERVER['SERVER_SOFTWARE'])) {
  681. if (isset($_SERVER['WINDIR']) || strpos($_SERVER['SERVER_SOFTWARE'], 'Win32') !== FALSE)
  682. return "win32";
  683. if (! isset($_SERVER['WINDIR']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Linux') !== FALSE)
  684. return "linux";
  685. }
  686. if (file_exists("C:\Windows"))
  687. return "win32";
  688. return "unix";
  689. }
  690. /**
  691. * Return the super parent class name
  692. *
  693. * @param string $classname
  694. * @return string
  695. */
  696. final public function getSuperParent($classname = null){
  697. if (is_null($classname))
  698. $classname = get_class($this);
  699. $parent = get_parent_class($classname);
  700. if ($parent === false)
  701. return $classname;
  702. return $this->getSuperParent($parent);
  703. ;
  704. }
  705. /**
  706. * Return the current template's id
  707. *
  708. * @return integer
  709. */
  710. final public function getId(){
  711. return $this->__id;
  712. }
  713. /**
  714. * Create an auxiliar instance (as singleton)
  715. *
  716. * @param string $classname
  717. */
  718. final static function createAuxiliarEngine(&$from = null){
  719. if (is_null($from))
  720. $classname = self::$__super_class;
  721. else
  722. $classname = get_class($from);
  723. if (! is_null(self::$__engine))
  724. if (get_class(self::$__engine) != $classname)
  725. self::$__engine = null;
  726. if (is_null(self::$__engine)) {
  727. if (self::$__log_mode)
  728. self::log("createAuxiliarEngine: A new $classname instance will be created ...");
  729. $tmp = self::$__discard_file_system;
  730. self::$__discard_file_system = true;
  731. self::$__engine = new $classname("", array());
  732. if (! is_null($from)) {
  733. self::$__engine->__items = $from->__items;
  734. self::$__engine->__items_orig = $from->__items_orig;
  735. }
  736. self::$__discard_file_system = $tmp;
  737. }
  738. }
  739. /**
  740. * Create a clone of auxiliary
  741. *
  742. * @return div
  743. */
  744. final static function getAuxiliaryEngineClone(&$items = null, &$items_orig = null){
  745. $obj = clone self::$__engine;
  746. if (self::$__log_mode)
  747. self::log("getAuxiliaryEngineClone: New auxiliary #" . $obj->getId());
  748. if (! is_null($items))
  749. $obj->__items = $items;
  750. if (! is_null($items_orig))
  751. $obj->__items_orig = $items_orig;
  752. return $obj;
  753. }
  754. /**
  755. * Save parser's operationsd
  756. *
  757. * @param array $params
  758. */
  759. final public function saveOperation($params = array()){
  760. if (! isset(self::$__remember[$this->__crc]))
  761. self::$__remember[$this->__crc] = array();
  762. $id = crc32(serialize($params));
  763. if (! isset(self::$__remember[$this->__crc][$id]))
  764. self::$__remember[$this->__crc][$id] = $params;
  765. }
  766. /**
  767. * Add a custom variable's modifier
  768. *
  769. * @param string $prefix
  770. * @param string $function
  771. */
  772. final static function addCustomModifier($prefix, $function){
  773. self::$__custom_modifiers[$prefix] = array(
  774. $prefix,
  775. $function
  776. );
  777. self::$__modifiers[] = $prefix;
  778. }
  779. /**
  780. * Enable system var for utility
  781. *
  782. * @param string $var
  783. */
  784. final static function enableSystemVar($var){
  785. self::$__system_data_allowed[$var] = true;
  786. }
  787. /**
  788. * Disable system var for performance
  789. *
  790. * @param string $var
  791. */
  792. final static function disableSystemVar($var){
  793. if (isset(self::$__system_data_allowed[$var]))
  794. unset(self::$__system_data_allowed[$var]);
  795. }
  796. /**
  797. * Return the loaded data from the system
  798. *
  799. * @return array
  800. */
  801. final static function getSystemData(){
  802. if (self::$__system_data == null) {
  803. self::$__system_data = array();
  804. if (isset(self::$__system_data_allowed['div.ascii'])) {
  805. $ascii = array();
  806. for($i = 0; $i <= 255; $i ++)
  807. $ascii[$i] = chr($i);
  808. self::$__system_data['div.ascii'] = $ascii;
  809. }
  810. if (isset(self::$__system_data_allowed['div.now']))
  811. self::$__system_data['div.now'] = time();
  812. if (isset(self::$__system_data_allowed['div.post']))
  813. self::$__system_data['div.post'] = $_POST;
  814. if (isset(self::$__system_data_allowed['div.get']))
  815. self::$__system_data['div.get'] = $_GET;
  816. if (isset(self::$__system_data_allowed['div.server']))
  817. self::$__system_data['div.server'] = $_SERVER;
  818. if (isset(self::$__system_data_allowed['div.session']))
  819. self::$__system_data['div.session'] = isset($_SESSION) ? $_SESSION : array();
  820. if (isset(self::$__system_data_allowed['div.version']))
  821. self::$__system_data['div.version'] = self::$__version;
  822. if (isset(self::$__system_data_allowed['div.script_name'])) {
  823. $script_name = explode('/', $_SERVER['SCRIPT_NAME']);
  824. $script_name = $script_name[count($script_name) - 1];
  825. self::$__system_data['div.script_name'] = $script_name;
  826. }
  827. }
  828. return self::$__system_data;
  829. }
  830. /**
  831. * Set allowed function
  832. *
  833. * @param string $funcname
  834. */
  835. final static function setAllowedFunction($funcname){
  836. self::$__allowed_functions[$funcname] = true;
  837. }
  838. /**
  839. * Unset allowed function
  840. *
  841. * @param string $funcname
  842. */
  843. final static function unsetAllowedFunction($funcname){
  844. self::$__allowed_functions[$funcname] = false;
  845. }
  846. /**
  847. * Add or set a global var
  848. *
  849. * @param string $var
  850. * @param mixed $value
  851. */
  852. final static function setGlobal($var, $value){
  853. self::$__globals[$var] = $value;
  854. }
  855. /**
  856. * Remove a global var
  857. *
  858. * @param string $var
  859. */
  860. final static function delGlobal($var){
  861. unset(self::$__globals[$var]);
  862. }
  863. /**
  864. * Add or set a default replacement of value
  865. *
  866. * @param mixed $search
  867. * @param mixed $replace
  868. */
  869. final static function setDefault($search, $replace){
  870. self::$__defaults[serialize($search)] = $replace;
  871. }
  872. /**
  873. * Add or set a default replacement of value for a specific var
  874. *
  875. * @param string $var
  876. * @param mixed $search
  877. * @param mixed $replace
  878. * @param boolean $update
  879. */
  880. final static function setDefaultByVar($var, $search, $replace, $update = true){
  881. $id = serialize($search);
  882. if (! isset(self::$__defaults_by_var[$var]))
  883. self::$__defaults_by_var[$var] = array();
  884. if (! isset(self::$__defaults_by_var[$var][$id]) && $update === true)
  885. self::$__defaults_by_var[$var][$id] = $replace;
  886. }
  887. /**
  888. * Set a sub-parser
  889. *
  890. * @param string $name
  891. * @param string $function
  892. */
  893. final static function setSubParser($name, $function = null){
  894. if (is_array($name)) {
  895. if (is_null($function)) {
  896. foreach ( $name as $key => $value ) {
  897. if (is_numeric($key))
  898. self::$__sub_parsers[$value] = $value;
  899. else
  900. self::$__sub_parsers[$key] = $value;
  901. }
  902. } elseif (is_array($function)) {
  903. foreach ( $name as $key => $value )
  904. self::$__sub_parsers[$value] = $function[$key];
  905. } else {
  906. foreach ( $name as $key => $value )
  907. self::$__sub_parsers[$value] = $function;
  908. }
  909. } else {
  910. if (is_null($function))
  911. $function = $name;
  912. self::$__sub_parsers[$name] = $function;
  913. }
  914. self::repairSubparsers();
  915. }
  916. /**
  917. * Repair the subparsers and their events
  918. */
  919. final static function repairSubparsers(){
  920. $events = array(
  921. 'beforeParse',
  922. 'afterInclude',
  923. 'afterParse',
  924. 'afterReplace'
  925. );
  926. $news = array();
  927. foreach ( self::$__sub_parsers as $parser => $function ) {
  928. $arr = explode(":", $parser);
  929. if (isset($arr[1])) {
  930. $last = array_pop($arr);
  931. if (array_search($last, $events) !== false)
  932. continue;
  933. }
  934. foreach ( $events as $event )
  935. if (! isset(self::$__sub_parsers["$parser:$event"])) {
  936. $news["$parser:$event"] = $function;
  937. }
  938. }
  939. self::$__sub_parsers = array_merge(self::$__sub_parsers, $news);
  940. }
  941. /**
  942. * Load template from filesystem
  943. *
  944. * @param string $path
  945. * @return string
  946. */
  947. final public function loadTemplate($path){
  948. if (self::$__log_mode === true)
  949. $this->logger("Loading the template: $path");
  950. $src = $path;
  951. if (strlen($path) < 255) {
  952. $paths = array(
  953. $path,
  954. $path . '.' . DIV_DEFAULT_TPL_FILE_EXT,
  955. $path,
  956. $path . '.' . DIV_DEFAULT_TPL_FILE_EXT
  957. );
  958. foreach ( $paths as $pathx ) {
  959. if (strlen($pathx) < 255)
  960. if (self::fileExists($pathx)) {
  961. $src = self::getFileContents($pathx);
  962. $this->__path = $pathx;
  963. break;
  964. }
  965. }
  966. }
  967. return $src;
  968. }
  969. /**
  970. * Change the template and the original template
  971. *
  972. * @param string $src
  973. */
  974. final public function changeTemplate($src = null){
  975. $decode = true;
  976. $classname = get_class($this);
  977. $discardfs = self::$__discard_file_system;
  978. if (is_null($src)) {
  979. if ($classname != self::$__super_class && is_null($this->__src))
  980. $src = $classname;
  981. if (! is_null($this->__src))
  982. $src = $this->__src;
  983. }
  984. if (! $discardfs)
  985. $src = $this->loadTemplate($src);
  986. $this->__src = $src;
  987. $this->__src_original = $src;
  988. }
  989. /**
  990. * Return the code of current template
  991. *
  992. * @return string
  993. */
  994. final public function getTemplate(){
  995. return $this->__src;
  996. }
  997. /**
  998. * Return the original code of template
  999. *
  1000. * @return string
  1001. */
  1002. final public function getOriginalTemplate(){
  1003. return $this->__src_original;
  1004. }
  1005. /**
  1006. * Remove a default replacement
  1007. *
  1008. * @param mixed $search
  1009. */
  1010. final static function delDefault($search){
  1011. $id = serialize($search);
  1012. if (isset(self::$__defaults[$id]))
  1013. unset(self::$__defaults[$id]);
  1014. }
  1015. /**
  1016. * Remove a default replacement by var
  1017. *
  1018. * @param string $var
  1019. * @param mixed $search
  1020. */
  1021. final static function delDefaultByVar($var, $search){
  1022. if (isset(self::$__defaults_by_var[$var])) {
  1023. $id = serialize($search);
  1024. if (isset(self::$__defaults_by_var[$var][$id]))
  1025. unset(self::$__defaults_by_var[$var][$id]);
  1026. }
  1027. }
  1028. /**
  1029. * Add or Set item of information
  1030. *
  1031. * @param string $var
  1032. * @param mixed $value
  1033. * @return mixed
  1034. */
  1035. final public function setItem($var, $value = null){
  1036. if (is_array($var)) {
  1037. $r = array();
  1038. foreach ( $var as $idx => $val ) {
  1039. if (self::issetVar($idx, $this->__items))
  1040. $r[$idx] = self::getVarValue($idx, $this->__items);
  1041. else
  1042. $r[$idx] = null;
  1043. self::setVarValue($idx, $val, $this->__items);
  1044. }
  1045. return $r;
  1046. }
  1047. if (self::issetVar($var, $this->__items))
  1048. $item = self::getVarValue($var, $this->__items);
  1049. else
  1050. $item = null;
  1051. self::setVarValue($var, $value, $this->__items);
  1052. return $item;
  1053. }
  1054. /**
  1055. * Delete an item of information
  1056. *
  1057. * @param string $var
  1058. * @return boolean
  1059. */
  1060. final public function delItem($var){
  1061. return self::unsetVar($var, $this->__items);
  1062. }
  1063. /**
  1064. * Return an item
  1065. *
  1066. * @param array $array
  1067. * @param mixed $index
  1068. * @param mixed $default
  1069. * @return mixed
  1070. */
  1071. final public function getItem($var, $default = null){
  1072. if (! self::issetVar($var, $this->__items))
  1073. return $default;
  1074. return self::getVarValue($var, $this->__items);
  1075. }
  1076. /**
  1077. * Return a list of block's ranges
  1078. *
  1079. * @param string $tagini
  1080. * @param string $tagend
  1081. * @param boolean $onlyfirst
  1082. * @param integer $pos
  1083. * @return array
  1084. */
  1085. final public function getRanges($tagini, $tagend, $src = null, $onlyfirst = false, $pos = 0){
  1086. $ranges = array();
  1087. if (is_null($src))
  1088. if (isset($this))
  1089. $src = $this->__src;
  1090. if (! is_null($src))
  1091. if (isset($src[0]) && ! empty($src)) {
  1092. $ltagini = strlen($tagini);
  1093. $ltagend = strlen($tagend);
  1094. do {
  1095. $ini = strpos($src, $tagini, $pos);
  1096. if ($ini !== false) {
  1097. if (isset($src[$ini + $ltagini])) {
  1098. $fin = strpos($src, $tagend, $ini + $ltagini);
  1099. if ($fin !== false) {
  1100. $l = strlen($src);
  1101. $last_pos = - 1;
  1102. while ( true ) {
  1103. $ini = strpos($src, $tagini, $pos);
  1104. if ($ini === false || ($ini !== false && $pos == $last_pos))
  1105. break;
  1106. $end = false;
  1107. $plus = 1;
  1108. $posi = $ini + $ltagini;
  1109. $last_posi = $posi - 1;
  1110. while ( true ) {
  1111. $open = strpos($src, $tagini, $posi);
  1112. $close = strpos($src, $tagend, $posi);
  1113. if ($open === false && $close === false)
  1114. break; // not open and not close
  1115. if ($open === false && $close !== false && $posi === $last_posi)
  1116. break; // close and not open
  1117. if ($open !== false && $close === false && $posi === $last_posi)
  1118. break; // open and not close
  1119. if ($open !== false || $close !== false) { // open or close
  1120. if (($close < $open || $open === false) && $close !== false) { // close if is closed and before open or not open
  1121. $last_posi = $posi;
  1122. $posi = $close + $ltagend;
  1123. $plus --;
  1124. // IMPORTANT! Don't separate elseif
  1125. } elseif (($open < $close || $close === false) && $open !== false) { // open if is opened and before close or not close
  1126. $last_posi = $posi;
  1127. $posi = $open + $ltagini;
  1128. $plus ++;
  1129. }
  1130. }
  1131. if ($plus === 0) { // all opens are closed
  1132. $end = $close;
  1133. break;
  1134. }
  1135. if ($open >= $l)
  1136. break;
  1137. }
  1138. $last_pos = $pos;
  1139. if ($end != false) {
  1140. $ranges[] = array(
  1141. $ini,
  1142. $end
  1143. );
  1144. if ($onlyfirst == true)
  1145. break;
  1146. $pos = $ini + $ltagini;
  1147. continue;
  1148. }
  1149. }
  1150. }
  1151. }
  1152. }
  1153. if (! isset($ranges[0]) && $ini !== false) {
  1154. if (self::$__log_mode)
  1155. if (isset($this)) {
  1156. foreach ( $this->__items as $key => $value )
  1157. if (strpos($tagini, $key) !== false) {
  1158. $this->logger('Unclosed tag ' . $tagini . ' at ' . $ini . ' character', DIV_ERROR_WARNING);
  1159. break;
  1160. }
  1161. }
  1162. $pos = $ini + 1;
  1163. continue;
  1164. }
  1165. break;
  1166. } while ( true );
  1167. }
  1168. return $ranges;
  1169. }
  1170. /**
  1171. * Return a list of ranges of blocks
  1172. *
  1173. * @param string $src
  1174. * @param string $begin_prefix
  1175. * @param string $begin_suffix
  1176. * @param string $end_prefix
  1177. * @param string $end_suffix
  1178. * @param integer $after
  1179. * @param integer $before
  1180. * @return array
  1181. */
  1182. final public function getBlockRanges($src = null, $begin_prefix = '{', $begin_suffix = '}', $end_prefix = '{/', $end_suffix = '}', $after = 0, $before = null, $onlyfirst = false){
  1183. if (is_null($src))
  1184. $src = $this->__src;
  1185. if (! is_null($before))
  1186. $src = substr($src, 0, $before);
  1187. $l = strlen($src);
  1188. $l1 = strlen($begin_prefix);
  1189. $tagsya = array();
  1190. $ranges = array();
  1191. $from = $after;
  1192. do {
  1193. $prefix_pos = strpos($src, $begin_prefix, $from);
  1194. if ($prefix_pos !== false) {
  1195. if (isset($src[$prefix_pos + 1])) {
  1196. if ($begin_suffix != '' && ! is_null($begin_suffix)) {
  1197. $suffix_pos = strpos($src, $begin_suffix, $prefix_pos + 1);
  1198. } else {
  1199. $stopchars = array(
  1200. ' ',
  1201. "\n",
  1202. "\r",
  1203. "\t",
  1204. "<",
  1205. ">"
  1206. );
  1207. $stoppos = array();
  1208. foreach ( $stopchars as $k => $v ) {
  1209. $pp = strpos($src, $v, $prefix_pos);
  1210. if ($pp === false)
  1211. continue;
  1212. $stoppos[] = $pp;
  1213. }
  1214. $suffix_pos = false;
  1215. if (count($stoppos) > 0)
  1216. $suffix_pos = min($stoppos);
  1217. }
  1218. $key = '';
  1219. if ($suffix_pos < $l && $suffix_pos !== false) {
  1220. $key = substr($src, $prefix_pos + $l1, $suffix_pos - $prefix_pos - $l1);
  1221. }
  1222. if ($key !== '' && ! isset($tagsya[$key])) {
  1223. $tag_begin = $begin_prefix . $key . $begin_suffix;
  1224. $tag_end = $end_prefix . $key . $end_suffix;
  1225. $rs = $this->getRanges($tag_begin, $tag_end, $src, $onlyfirst, $from);
  1226. $l2 = strlen($tag_begin);
  1227. foreach ( $rs as $k => $v ) {
  1228. $rs[$k][2] = $key;
  1229. $rs[$k][3] = substr($src, $v[0] + $l2, $v[1] - $v[0] - $l2);
  1230. }
  1231. $ranges = array_merge($ranges, $rs);
  1232. // Only the first...
  1233. if ($onlyfirst)
  1234. if (isset($ranges[0]))
  1235. break;
  1236. $tagsya[$key] = true;
  1237. }
  1238. }
  1239. $from = $prefix_pos + 1;
  1240. }
  1241. } while ( $prefix_pos !== false );
  1242. return $ranges;
  1243. }
  1244. /**
  1245. * Return a default replacement of value
  1246. *
  1247. * @param mixed $value
  1248. * @return mixed
  1249. */
  1250. final static function getDefault($value){
  1251. $id = serialize($value);
  1252. if (isset(self::$__defaults[$id]))
  1253. return self::$__defaults[$id];
  1254. return $value;
  1255. }
  1256. /**
  1257. * Return a default replacement of value by var
  1258. *
  1259. * @param string $var
  1260. * @param mixed $value
  1261. * @return mixed
  1262. */
  1263. final static function getDefaultByVar($var, $value){
  1264. if (isset(self::$__defaults_by_var[$var])) {
  1265. $id = serialize($value);
  1266. if (isset(self::$__defaults_by_var[$var][$id])

Large files files are truncated, but you can click here to view the full file