functions.php
上传用户:gzy2002
上传日期:2010-02-11
资源大小:1785k
文件大小:23k
源码类别:

电子政务应用

开发平台:

Java

  1. <?php
  2. error_reporting(E_ALL & ~E_NOTICE);
  3. @set_time_limit(0);
  4. // ############################################################################
  5. // A version of array_contains() that uses binary sort to find the element
  6. // Only use on sorted arrays!!!
  7. function array_contains_binary($needle, &$haystack) {
  8. if (!is_array($haystack)) {
  9. return false;
  10. }
  11. $low = 0;
  12. $high = count($haystack);
  13. $needle = strtolower($needle);
  14. while ($low <= $high) {
  15. $mid = floor(($low + $high) / 2);
  16. if (strcasecmp($needle, $haystack[$mid]) == 0 ) {
  17. return true;
  18. break;
  19. } elseif (strcasecmp($needle, $haystack[$mid]) < 0 ) {
  20. $high = $mid - 1;
  21. } else {
  22. $low = $mid + 1;
  23. }
  24. }
  25. return false;
  26. }
  27. // ############################################################################
  28. // A version of in_array() that allows case-insensitive matching (by default!)
  29. function array_contains($needle, $haystack, $strict = false, $matchcase = false) {
  30. if (!is_array($haystack)) {
  31. return false;
  32. }
  33. if (!$matchcase and is_string($needle)) {
  34. $needle = strtolower($needle);
  35. }
  36. foreach ($haystack as $element) {
  37. if (!$matchcase and is_string($needle)) {
  38. $element = strtolower($element);
  39. }
  40. if (($strict and $needle === $element) or (!$strict and $needle == $element)) {
  41. return true;
  42. }
  43. }
  44. return false;
  45. }
  46. // ############################################################################
  47. // Returns $true if $eval is true, $false if it is false
  48. function iif($eval, $true, $false = '') {
  49. return (($eval == true) ? ($true) : ($false));
  50. }
  51. // ############################################################################ 
  52. // 
  53. function readfromfile($filename, $binary = true, $getdata = true) { 
  54. $mode = 'r'.iif($binary, 'b'); 
  55. $data = ''; 
  56. if (is_readable($filename) 
  57. and is_resource($fp = @fopen($filename, $mode)) and (!$getdata or filesize($filename) == 0 or $data = @fread($fp, @filesize($filename))) and @fclose($fp)) { 
  58. return $data; 
  59. } else { 
  60. return false; 
  61. }
  62. // ############################################################################ 
  63. // Calculates microtime difference from $start 
  64. function microdiff($start) { 
  65. return realmicrotime() - realmicrotime($start); 
  66.  
  67. // ############################################################################ 
  68. // Returns a real timestamp from a microtime 
  69. function realmicrotime($time = null) { 
  70. if ($time === null) { 
  71. $time = microtime(); 
  72. $timebits = explode(' ', $time); 
  73. return $timebits[0] + $timebits[1]; 
  74. }
  75. // ############################################################################
  76. // Calculates the LCS between the two strings and return the number of similar chars
  77. function spell_similar($A, $B) {
  78. $L = array();
  79. $m = strlen($A);
  80. $n = strlen($B);
  81. for ($i = $m; $i >= 0; $i--) {
  82. for ($j = $n; $j >= 0; $j--) {
  83. if ($i >= $m or $j >= $n) {
  84. $L[$i][$j] = 0;
  85. } elseif ($A[$i] == $B[$j]) {
  86. $L[$i][$j] = 1 + $L[$i+1][$j+1];
  87. } else {
  88. $L[$i][$j] = max($L[$i+1][$j], $L[$i][$j+1]);
  89. }
  90. }
  91. }
  92. return $L[0][0] / max($m, $n);
  93. }
  94. // ############################################################################
  95. // Processes input for fields
  96. function spell_process($text, $method, $useHtml, $sendAfter) {
  97. global $_meta_markers;
  98. $starttime = microdiff(STARTTIME);
  99. $intMaxSuggestions = 6;
  100. $showback = 6;
  101. $showforward = 6;
  102. $userDictionaryAvailable = false;
  103. $userWords = $realWords = $misspelledArray = $deadKeys = $tagKeys = $wordKeys = $sxValues = array();
  104. $jsOutput = '';
  105. //echo '<!-- ';
  106. if (!empty($text)) {
  107. // Operate on the HTML text so it's split correctly
  108. $strDictArray = preg_split("#r?n#", readfromfile('./dict-large.txt'));
  109. echo "Words: ".(microdiff(STARTTIME) - $starttime)."<br />";
  110. $strDictArray = array_flip($strDictArray);
  111. echo "Flip: ".(microdiff(STARTTIME) - $starttime)."<br />";
  112. $originalString = preg_replace("#r?n#", "n", $text);
  113. $words = preg_split('#([^a-z'])#i', $originalString, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
  114. echo "Split: ".(microdiff(STARTTIME) - $starttime)."<br />";
  115. $tagOpen = false;
  116. $realKey = $demoKey = 0;
  117. if ($useHtml) {
  118. while (list($key, $value) = each($words)) {
  119. if ($value == '<') {
  120. $tagOpen = true;
  121. } elseif ($value == '>' or $tagOpen) {
  122. $demoKey--;
  123. $words[$demoKey] .= array_extract($words, $key);
  124. $deadKeys[] = $key;
  125. if ($value == '>') {
  126. $tagKeys[] = $realKey;
  127. $realKey++;
  128. $demoKey = $key;
  129. $tagOpen = false;
  130. }
  131. } else {
  132. $realWords[$realKey] = $value;
  133. $realKey++;
  134. }
  135. $demoKey++;
  136. }
  137. } else {
  138. $realWords = $words;
  139. }
  140. $words = array_values($words);;
  141. $wordCount = count($words);
  142. //print_R($realWords);
  143. echo "HTML: ".(microdiff(STARTTIME) - $starttime)."<br />";
  144. // Tracks original index of word in $words array
  145. $oi = 0;
  146. // Get user's dictionary
  147. /*
  148. $getUserWords = $DB_site->query("
  149. SELECT word
  150. FROM hive_word
  151. WHERE userid = $hiveuser[userid]
  152. ");
  153. while ($userWord = $DB_site->fetch_array($getUserWords)) {
  154. $userWords[] = $userWord['word'];
  155. }
  156. echo "User: ".(microdiff(STARTTIME) - $starttime)."<br />";
  157. */
  158. // Loop over each word in string
  159. $checks = 0;
  160. foreach ($realWords as $strWordKey => $strWordIn) {
  161. //if (in_array($strWordKey, $tagKeys)) {
  162. // This is an HTML tag or a word that was already checked this word
  163. // Increment original index and move along
  164. //continue;
  165. //}
  166. $oi = $strWordKey;
  167. // Remove invalid characters from the word
  168. $strWordOut = $strWordIn;
  169. $strWordOut = preg_replace('#[^a-z']#i', '', $strWordOut);
  170. if (substr_count($strWordOut, "'") > 1) {
  171. $strWordOut = str_replace("'", '', $strWordOut);
  172. }
  173. // Remove 's at the end of the word
  174. if (substr($strWordOut, -2) == "'s") {
  175. $strWordOut = substr($strWordOut, 0, strlen($strWordOut) - 2);
  176. }
  177. $strWordOut = trim($strWordOut, "' tnrx0B");
  178. // Nothing left...
  179. if (empty($strWordOut)) {
  180. continue;
  181. }
  182. // Store the word's key
  183. $wordKeys[] = $oi;
  184. // Word need not have capitals
  185. $checkWord = strtolower($strWordOut);
  186. // Search main dictionary
  187. $spellOk = isset($strDictArray["$checkWord"]);
  188. // Check user's dictionary
  189. // I decided to not do this here, but instead check later if
  190. // if the any of the suggestions match the actual word which
  191. // means it's a word that the user added. The cost of running
  192. // this binary search for every word is just not worth it.
  193. if (false and !$spellOk and !empty($userWords)) {
  194. // Binary sort to find word in user's array
  195. // (Only if the array isn't short)
  196. if (false and count($userWords) < 20) {
  197. $spellOk = in_array($checkWord, $userWords);
  198. } else {
  199. $low = 0;
  200. $high = count($userWords);
  201. while ($low <= $high) {
  202. $mid = floor(($low + $high) / 2);
  203. if (strcasecmp($checkWord, $userWords[$mid]) == 0 ) {
  204. $spellOk = true;
  205. break;
  206. } elseif (strcasecmp($checkWord, $userWords[$mid]) < 0 ) {
  207. $high = $mid - 1;
  208. } else {
  209. $low = $mid + 1;
  210. }
  211. }
  212. }
  213. }
  214. // If word is spelled wrong, store in array
  215. if (!$spellOk) {
  216. // Calculate soundex/metaphone using PHP and create the misspelled array entry
  217. $sndx = $method($strWordOut);
  218. if (!array_contains($sndx, $sxValues)) {
  219. $sxValues[] = $sndx;
  220. }
  221. $misspelledArray[] = array(
  222. 'word' => $strWordIn,
  223. 'sndx' => $sndx,
  224. 'possugs' => array(),
  225. 'realsugs' => array(),
  226. 'oi' => $oi,
  227. );
  228. }
  229. }
  230. $lastOi = $oi;
  231. echo "Spell: ".(microdiff(STARTTIME) - $starttime)."<br />";
  232. $wordKeysFlipped = array_flip($wordKeys);
  233. echo "Flip: ".(microdiff(STARTTIME) - $starttime)."<br />";
  234. // Total count of misspelled words in the array
  235. $misspelledWordCount = count($misspelledArray);
  236. if ($misspelledWordCount > 0) {
  237. // Execute query
  238. $strSuggArray = preg_split("#r?n#", readfromfile('./dict-metaphone-sort.txt'));
  239. echo "Suggest: ".(microdiff(STARTTIME) - $starttime)."<br />";
  240. // JavaScript variables that will store all information
  241. $jsOutput .= "var msWc = $misspelledWordCount;n";
  242. $jsOutput .= "var msMissWordAr = new Array($misspelledWordCount);n";
  243. $jsOutput .= "var msOrigWordAr = new Array($wordCount);n";
  244. $jsOutput .= "var lastOrigWord;n";
  245. // Loop over array to get suggestions
  246. $doneSugsFor = array();
  247. for ($x = 0; $x < $misspelledWordCount; $x++) {
  248. $subAr3 = &$misspelledArray[$x];
  249. $intWordLen = strlen($subAr3['word']);
  250. $subArPoss3 = &$subAr3['possugs'];
  251. // Create context string
  252. $oi = $subAr3['oi'];
  253. $oiStart = $wordKeys[(($wordKeysFlipped[$oi] - $showback) >= 0) ? ($wordKeysFlipped[$oi] - $showback) : 0];
  254. $oiEnd = $wordKeys[(($wordKeysFlipped[$oi] + $showforward + 1) <= count($wordKeys) - 1) ? ($wordKeysFlipped[$oi] + $showforward + 1) : count($wordKeys) - 1];
  255. $context = '';
  256. if ($oi > $showback) {
  257. $context .= '...';
  258. }
  259. for (; $oiStart != $oiEnd + 1; $oiStart++) {
  260. if ($oiStart == $oi) {
  261. $context .= '<font color="red"><b>'.$words[$oi].'</b></font>';
  262. } else {
  263. $context .= $words[$oiStart];
  264. }
  265. }
  266. if ($oi < ($wordCount - 1 - $showforward)) {
  267. $context .= '...';
  268. }
  269. // Loop over similarities (possible suggestions), score and get top (real) suggestions
  270. // Check if we already did suggestions for this word and if so, load that
  271. $dblSimilarityArray = array();
  272. if (false and isset($doneSugsFor["$subAr3[word]"])) {
  273. $dblSimilarityArray = $misspelledArray[$doneSugsFor["$subAr3[word]"]]['possugs'];
  274. } else {
  275. // Binary sort to find word in dict array
  276. $low = $_meta_markers[substr($subAr3['sndx'], 0, 3)][0] - 1;
  277. $high = $_meta_markers[substr($subAr3['sndx'], 0, 3)][1] + 3;
  278. $foundSndx = false;
  279. //echo "Low: $low; High: $high;<br />";
  280. while ($low <= $high) {
  281. $mid = floor(($low + $high) / 2);
  282. $checks++;
  283. //$check = strcasecmp($subAr3['sndx'].'|', substr($strSuggArray[$mid], 0, strlen($subAr3['sndx']) + 1));
  284. $check = strcasecmp($subAr3['sndx'], preg_replace('#^([^|]+)|.*$#', '$1', $strSuggArray[$mid]));
  285. if ($check == 0) {
  286. $foundSndx = true;
  287. break;
  288. } elseif ($check < 0) {
  289. $high = $mid - 1;
  290. } else {
  291. $low = $mid + 1;
  292. }
  293. }
  294. if ($foundSndx) {
  295. $subArPoss3 = explode('|', substr($strSuggArray[$mid], strlen($subAr3['sndx']) + 1));
  296. } else {
  297. $subArPoss3 = array();
  298. }
  299. $subCount = count($subArPoss3);
  300. if ($subCount <= 1) {
  301. $dblSimilarityArray = $subArPoss3;
  302. } else {
  303. for ($y = 0; $y < $subCount; $y++) {
  304. $strSimilarWord = $subArPoss3[$y];
  305. $intSimilarWordLen = strlen($strSimilarWord);
  306. $maxBonus = 3;
  307. $maxScore = ($intWordLen * 2) + $maxBonus;
  308. $LCS = spell_similar($subAr3['word'], $strSimilarWord);
  309. $score = ($maxBonus - abs($intWordLen - $intSimilarWordLen) + $LCS * $maxBonus) / ($maxScore);
  310. $dblSimilarity = round($score, 10);
  311. while (array_key_exists("$dblSimilarity", $dblSimilarityArray)) {
  312. $dblSimilarity += .0000000001;
  313. }
  314. $dblSimilarityArray["$dblSimilarity"] = $strSimilarWord;
  315. }
  316. $subArPoss3 = $dblSimilarityArray;
  317. // Sort array by key value (score)
  318. krsort($dblSimilarityArray);
  319. reset($dblSimilarityArray);
  320. }
  321. }
  322. // Perpare JavaScript variables
  323. $jsOutput .= "msMissWordAr[$x] = new Array(4);n";
  324. $jsOutput .= "msMissWordAr[$x][0] = '".str_replace("n", '', addslashes($subAr3['word']))."';n";
  325. $jsOutput .= "msMissWordAr[$x][1] = $oi;n";
  326. $jsOutput .= "msMissWordAr[$x][2] = '".str_replace(array('n', "n"), '<br />n', trim(addslashes($context)))."';n";
  327. // Build suggestions array
  328. $sugCount = iif($intMaxSuggestions < count($dblSimilarityArray), $intMaxSuggestions, count($dblSimilarityArray));
  329. echo 'Suggs: '.$sugCount.'<br />';
  330. $jsOutput .= "msMissWordAr[$x][3] = new Array($sugCount);n";
  331. for ($l = 0; $l < $sugCount; $l++) {
  332. $jsOutput .= "msMissWordAr[$x][3][$l] = '".str_replace("n", '', addslashes(current($dblSimilarityArray)))."';n";
  333. next($dblSimilarityArray);
  334. }
  335. // Cache this word
  336. if (!isset($doneSugsFor["$subAr3[word]"])) {
  337. $doneSugsFor["$subAr3[word]"] = $oi;
  338. }
  339. }
  340. // Build array of *ALL* words in text
  341. for ($x = 0; $x < count($words); $x++) {
  342. $jsOutput .= "msOrigWordAr[$x] = '".str_replace("n", 'n', addslashes($words[$x]))."';n";
  343. }
  344. // Javascript: reload content frame with new frameset
  345. $jsOutput .= "parent.content.location = 'compose.spell.php?cmd=suggestions&sendafter=$sendAfter';n";
  346. }
  347. }
  348. // Javascript: if no words are misspelled, reload content frame with message page
  349. if (empty($jsOutput)) {
  350. $jsOutput .= "parent.content.location = 'compose.spell.php?cmd=noerrors';n";
  351. }
  352. //echo ' -->';
  353. echo "End: ".(microdiff(STARTTIME) - $starttime)."<br />";
  354. echo "Binary checks: $checks";
  355. return $jsOutput;
  356. }
  357. function alert($text) {
  358. echo "<SCRIPT language="javascript">
  359. alert('$text');
  360. </SCRIPT>";
  361. }
  362. #######################################################
  363. # TEMPORARY TEMPLATE CODE #
  364. function gettemplate($template_name) {
  365. $template = @implode('', @file("./$template_name.html"));
  366. $template = parse_conditionals($template);
  367. return str_replace("'", ''', $template);
  368. }
  369. function makeeval($varname, $templatename = '', $add = false, $dieonecho = true, $comments = true) {
  370. $template = gettemplate($templatename, $comments);
  371. if ($varname == 'echo') {
  372. $template = preg_replace('#<%PHP%>(.+)<%ENDPHP%>#ise', "'";nob_start();n'.stripslashes(stripslashes('\1')).'n$__output = ob_get_contents();nob_end_clean();necho $__output."'", $template);
  373. // echo $template;
  374. return 'echo '.$template.'; ';
  375. } else {
  376. $template = preg_replace('#<%PHP%>(.+)<%ENDPHP%>#ise', "'";nob_start();n'.stripslashes('\1').'n$$varname .= ob_get_contents();nob_end_clean();n$$varname .= "'", $template);
  377. return '$'.$varname.' = '.$template.';';
  378. }
  379. }
  380. ##########################################################
  381. #
  382. # function format_text_item: return formatted string 
  383. # without leading spaces and with slashes
  384. # for example: $in = " test''test  "
  385. # function return: "test''test"
  386. #
  387. function format_text_item($in)
  388. {
  389. // $in = trim($in);
  390. if ((substr($in, 0, 2) == "rn")) {
  391. $in = substr($in, 2);
  392. }
  393. $in = addslashes($in);
  394. return ""$in"";
  395. }
  396. ##########################################################
  397. #
  398. # recursive function tree_to_tertiary_operator: return 
  399. # tertiary operator string, which was built from tree
  400. #
  401. function tree_to_tertiary_operator(& $node)
  402. {
  403. $out = '';
  404. $dataref = $node['data'];
  405. $node_items = array();
  406. for ($i = 0; $i < count($node['data']); $i++)
  407. {
  408. $data_item = & $node['data'][$i];
  409. if (is_array($data_item))
  410. {
  411.   $if_block = '(('.$data_item['if']['conditional'].') ? (';
  412. $if_data = tree_to_tertiary_operator($data_item['if']);
  413. $if_block .= $if_data.') : ';
  414. if (!is_array($data_item['elseif']) && !is_array($data_item['else']))
  415. {
  416. $if_block .= "''";
  417. }
  418. elseif (!is_array($data_item['elseif']) && is_array($data_item['else']))
  419. {
  420. $else_block = tree_to_tertiary_operator($data_item['else']);
  421. $if_block .= "($else_block)";
  422. }
  423. else
  424. {
  425. $elif_block = elsif_array_to_tertiary_operator($data_item['elseif'],
  426. $data_item['else']);
  427. $if_block .= "($elif_block)";
  428. }
  429. array_push ($node_items, $if_block.')');
  430. }
  431. else
  432. {
  433. array_push ($node_items, format_text_item($data_item));
  434. }
  435. }
  436. $out .= join('.', $node_items);
  437. // changed
  438. if (empty($out)) {
  439. $out = '""';
  440. }
  441. return $out;
  442. }
  443. #################################################################
  444. #
  445. # function elsif_array_to_tertiary_operator: return
  446. # tertiary operator string, which was built from tree for 
  447. # elseif operator
  448. #
  449. #
  450. function elsif_array_to_tertiary_operator (& $elsif_array, & $else_hash)
  451. {
  452. $out = '(';
  453. $elsif_hash = array_shift($elsif_array);
  454. $out .= "(".$elsif_hash['conditional'].") ? (";
  455. $out .= tree_to_tertiary_operator($elsif_hash);
  456. $out .= ") : ";
  457. if (count($elsif_array) > 0)
  458. {
  459. $out .= elsif_array_to_tertiary_operator($elsif_array, $else_hash);
  460. }
  461. elseif (is_array($else_hash))
  462. {
  463. $out .= "(";
  464. $out .= tree_to_tertiary_operator($else_hash);
  465. $out .= ")";
  466. }
  467. else
  468. {
  469. $out .= """";
  470. }
  471. $out .= ")";
  472. return $out;
  473. }
  474. ##############################################################
  475. #
  476. # recursive function lex_queue_to_tree: return
  477. # tree. This function check also syntax for all lexemes
  478. #
  479. #
  480. function lex_queue_to_tree(& $root_node,& $lex_queue, $level_deep)
  481. {
  482. $ignore_level_up = 0;
  483. do
  484. {
  485. $next_item = array_shift($lex_queue);
  486. if ($next_item['type'] == 'text')
  487. {
  488. array_push ($root_node['data'], $next_item['value']);
  489. }
  490. elseif ($next_item['type'] == 'if')
  491. {
  492. $conditional = array_shift($lex_queue);
  493. if(!($conditional['type'] == 'conditional' && $conditional['value'] != ""))
  494. {
  495. die ("If requires conditional statement");
  496. }
  497. $new_check_node['if']['parent'] = & $new_check_node;
  498. array_push ($root_node['data'], array(
  499. 'if' => array(
  500. 'conditional' => $conditional['value'],
  501.   'data' => array()
  502. )
  503. ));
  504. $ignore_level_up = 
  505. lex_queue_to_tree($root_node['data'][count($root_node['data']) - 1]['if'],
  506.  $lex_queue, $level_deep + 1);
  507. }
  508. elseif ($next_item['type'] == 'elseif')
  509. {
  510. if ($ignore_level_up > 0) 
  511. $ignore_level_up = 0;
  512. else
  513. {
  514. array_unshift($lex_queue, $next_item);
  515. return 1;
  516. }
  517. $conditional = array_shift($lex_queue);
  518. if(!($conditional['type'] == 'conditional' && $conditional['value']!=""))
  519. {
  520. die ("ElseIf requires conditional statement");
  521. }
  522. if(!(is_array($root_node['data'][count($root_node['data']) - 1])))
  523. {
  524. die ("ElseIf requires preceeding If");
  525. }
  526. if (!is_array($root_node['data'][count($root_node['data']) - 1]['elseif']))
  527. {
  528. $root_node['data'][count($root_node['data']) - 1]['elseif'] = array();
  529. }
  530. array_push($root_node['data'][count($root_node['data']) - 1]['elseif'], array(
  531. 'conditional' => $conditional['value'],
  532. 'data' => array()
  533. ));
  534. $ignore_level_up = 
  535. lex_queue_to_tree($root_node['data'][count($root_node['data']) - 1]['elseif']
  536. [count($root_node['data'][count($root_node['data']) - 1]['elseif']) - 1],
  537.  $lex_queue, $level_deep + 1);
  538. }
  539. elseif ($next_item['type'] == 'else')
  540. {
  541. if ($ignore_level_up > 0) 
  542. $ignore_level_up = 0;
  543. else
  544. {
  545. array_unshift($lex_queue, $next_item);
  546. return 1;
  547. }
  548. if(!(is_array($root_node['data'][count($root_node['data']) - 1])))
  549. {
  550. die ("Else requires preceeding If");
  551. }
  552. if (defined($root_node['data'][count($root_node['data']) - 1]['else']))
  553. {
  554. die ("Else already defined for If");
  555. }
  556. $root_node['data'][count($root_node['data']) - 1]['else'] 
  557. = array( 'data' => array() );
  558. lex_queue_to_tree($root_node['data'][count($root_node['data']) - 1]['else'],
  559.  $lex_queue, $level_deep + 1);
  560. }
  561. elseif ($next_item['type'] == 'endif')
  562. {
  563. if(!$level_deep)
  564. {
  565. die ("EndIf requires preceeding If");
  566. }
  567. return 0;
  568. }
  569. elseif ($next_item['type'] == 'conditional')
  570. {
  571. die ("Unexpected conditional statement, probably bug in parsern");
  572. }
  573. } while (count($lex_queue) > 0);
  574. if ($level_deep)
  575. {
  576. die("No enough EndIf'sn");
  577. }
  578. return 0;
  579. }
  580. #######################################################################
  581. #
  582. # function text_to_lexemes_queue: return hash, which contain 
  583. # queue with lexemes from template
  584. #
  585. #
  586. function text_to_lexemes_queue($text)
  587. {
  588. #list ($parse_conditional, $consume_chars) = (0, 0);
  589. $parse_conditional = 0;
  590. $consume_chars = 0;
  591. $out = array();
  592. do
  593. {
  594. $parse_conditional = 0;
  595. if (preg_match("/^(<%elseifs+)/s", $text, $matches))
  596. {
  597. $consume_chars = strlen($matches[1]);
  598. array_push($out, array( 'type' => 'elseif' ));
  599. $parse_conditional = 1;
  600. }
  601. elseif (preg_match("/^(<%else%>)/s",$text,$matches))
  602. {
  603. $consume_chars = strlen($matches[1]);
  604. array_push($out, array( 'type' => 'else' ));
  605. }
  606. elseif (preg_match("/^(<%endif%>)/s",$text, $matches))
  607. {
  608. $consume_chars = strlen($matches[1]);
  609. array_push($out, array( 'type' => 'endif' ));
  610. }
  611. elseif (preg_match("/^(<%ifs+)/s", $text,$matches))
  612. {
  613. $consume_chars = strlen($matches[1]);
  614. array_push($out, array( 'type' => 'if' ));
  615. $parse_conditional = 1;
  616. }
  617. elseif (preg_match("/^(.)/s", $text, $matches))
  618. {
  619. $consume_chars = 1;
  620. $textchar = $matches[1];
  621.             if ($out[count($out)-1]['type'] == 'text')
  622.             {
  623.                 $out[count($out)-1]['value'] .= $textchar;
  624.             }
  625. else
  626. {
  627. array_push($out, array('type' => 'text', 'value' => $textchar ));
  628. }
  629. }
  630. $text = substr($text, $consume_chars);
  631. if ($parse_conditional)
  632. {
  633. array_push ($out, array('type' => 'conditional', 'value' => read_conditional($text)));
  634. }
  635. } while (strlen ($text));
  636. return $out;
  637. }
  638. ################################################################################
  639. #
  640. # function read_conditional: become reference to conditional in
  641. # if or elseif statements.
  642. #
  643. #
  644. function read_conditional(& $textref)
  645. {
  646. $out='';
  647. $consume_chars=0;
  648. $exit=0;
  649. $parse_quoted=0;
  650. $quote_char=0;
  651. do
  652. {
  653. $parse_quoted = 0;
  654. if ((preg_match("/^(')/", $textref,$matches)) || (preg_match("/^(")/",$textref,$matches)))
  655. {
  656. $quote_char = $matches[1];
  657. $out .= $quote_char;
  658. $consume_chars = 1;
  659. $parse_quoted = 1;
  660. }
  661. elseif (preg_match("/^(%>)/",$textref))
  662. {
  663. $consume_chars = 2;
  664. $exit = 1;
  665. }
  666. elseif (preg_match("/^(.)/s", $textref, $matches))
  667. {
  668. $out .= $matches[1];
  669. $consume_chars = 1;
  670. }
  671. elseif (!strlen($textref))
  672. {
  673. die ("Unexpected end of text while reading PHP conditional statement");
  674. }
  675. $textref = substr($textref, $consume_chars);
  676. if ($parse_quoted)
  677. {
  678. $out .= read_quoted($textref, $quote_char);
  679. }
  680. } while (! $exit);
  681. # (PHP syntax) check out with eval
  682. return $out;
  683. }
  684. ####################################################################
  685. #
  686. # function read_quoted: function for testing quoted text
  687. #
  688. #
  689. function read_quoted (& $textref, $quote_char)
  690. {
  691. $regexp_quote = AddSlashes($quote_char);
  692. $out = '';
  693. $consume_chars = 0;
  694. $exit_quote = 0;
  695. do
  696. {
  697. if ((preg_match("/^\$regexp_quote/",$textref)) || (preg_match("/^\\/", $textref)))
  698. {
  699. $consume_chars = 2;
  700. }
  701. elseif (preg_match("/^$regexp_quote/", $textref))
  702. {
  703. $consume_chars = 1;
  704. $exit_quote = 1;
  705. }
  706. elseif (preg_match("/^(.)/s", $textref))
  707. {
  708. $consume_chars = 1;
  709. }
  710. elseif (!strlen($textref))
  711. {
  712. die ("Unexpected end of text while reading quoted string");
  713. }
  714. $out .= substr($textref, 0, $consume_chars);
  715. $textref = substr($textref, $consume_chars);
  716. } while (! $exit_quote);
  717. return $out;
  718. }
  719. function parse_conditionals($template) {
  720. $template = preg_replace("#s?<%!--.*--!%>s?#", '', $template);
  721. if ($GLOBALS['session_url']) {
  722. $template = preg_replace('#.php(?)?#ies', ''.php{$GLOBALS[session_url]}'.(('1' != '') ? ('{$GLOBALS[session_ampersand]}') : (''))', $template);
  723. }
  724. $lex_queue = text_to_lexemes_queue($template);
  725. $root = array('data' => array());
  726. if (lex_queue_to_tree($root, $lex_queue, 0)) {
  727. die ("Else already defined or ElseIf without Ifn");
  728. }
  729. $output = tree_to_tertiary_operator($root);
  730. $output = get_loops($output);
  731. return $output;
  732. }
  733. function get_loops ($template) {
  734. $template = preg_replace('#<%loop ($[a-zA-Z_x7f-xff][a-zA-Z0-9_x7f-xff]*) ?%>(.*)<%endloop%>#iUse', "loop_code('\1', '\2')",$template);
  735. return $template;
  736. }
  737. function loop_code($loop_name, $loop_code) {
  738. $loop_name = stripslashes($loop_name);
  739. $loop_code = stripslashes($loop_code);
  740. $loop_name2 = substr($loop_name, 1);
  741. $loop_code = str_replace("'", "loop-temp-section", $loop_code);
  742. return " " . doloop('$loop_name2', $loop_name, '$loop_code', $GLOBALS) . "";
  743. }