1<?php 2/** 3 * Prolog plug-in : Rule-based System for Groupware. 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author Paweł Kupka <pawel.kupka@gmail.com> 7 */ 8 9// must be run within Dokuwiki 10$webroot = reset(split('lib',dirname(__FILE__))); 11if(!defined('DOKU_INC')) define('DOKU_INC', $webroot); 12if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins'); 13if(!defined('DOKU_PAGES')) define('DOKU_PAGES',DOKU_INC.'data/pages'); 14if(!defined('DOKU_TMP')) define('DOKU_TMP',DOKU_INC.'data/tmp'); 15require_once (DOKU_INC.'inc/pageutils.php'); 16require_once (DOKU_INC.'inc/utf8.php'); 17 18class PrologTag { 19 20 var $entryTagPattern = '/<prolog.*>/'; 21 var $exitTagPattern = '/<\/prolog>/'; 22 23 var $attributeEntryPattern = '\('; 24 var $attributeExitPattern = '\)'; 25 var $attributeValuePattern = '[^\)]*'; 26 var $attributeName; 27 var $attributePattern; 28 29 /** 30 * Constructor 31 */ 32 function PrologTag() 33 { 34 } 35 36 /** 37 * Gets all prolog entry tags from the text file 38 * @param string $file file path 39 * @return array $matchedTags found prolog entry tags 40 */ 41 function getEntryTags($file = null) 42 { 43 $fileContent = file_get_contents($file); 44 $foundTags = preg_match_all($this->entryTagPattern, $fileContent, $matchedTags); 45 return $matchedTags[0]; 46 } 47 48 /** 49 * Sets attribute pattern 50 * @param string $attributeName attribute name 51 */ 52 function setAttributePattern($attributeName) 53 { 54 $this->attributeName = $attributeName; 55 $this->attributePattern = '/'; 56 $this->attributePattern .= '([a-zA-Z0-9]+)'; 57 $this->attributePattern .= $this->attributeEntryPattern; 58 $this->attributePattern .= '('.$this->attributeValuePattern.')'; 59 $this->attributePattern .= $this->attributeExitPattern; 60 $this->attributePattern .= '/'; 61 } 62 63 /** 64 * Gets the attribute value from the prolog entry tag 65 * @param string $prologTag prolog entry tag 66 * @return string $matched matched attribute value 67 */ 68 function getAttributeValue($prologTag = null) 69 { 70 $found = preg_match_all($this->attributePattern, $prologTag, $matched); 71 $attrValue = ''; 72 foreach($matched[1] as $i => $attrName) { 73 if($attrName == $this->attributeName) { 74 $attrValue = $matched[2][$i]; 75 break; 76 77 } 78 } 79 return $attrValue; 80 } 81 82 /** 83 * Executes prolog code in the Prolog interpreter 84 * @param string $prologCode the prolog source code 85 * @param string $maxExecutionTime the limit for maximum interpretation time (in seconds) 86 * @return array $executed array with output and errors from the interpreter 87 */ 88 function execute($prologCode = null, $maxExecutionTime = 5) 89 { 90 $executed = array('',''); 91 92 if(!isset($prologCode)) 93 return $executed; 94 95 $maxExecutionTime = intval($maxExecutionTime); 96 if($maxExecutionTime < 1 || $maxExecutionTime > 5) //1sec - 30sec 97 $maxExecutionTime = 5; 98 99 $tmpname = tempnam(DOKU_TMP, 'pl_'); 100 $stdin = $tmpname.'.pl'; 101 unlink($tmpname); 102 103 $handleStdin = fopen($stdin, 'w'); 104 fwrite($handleStdin, $prologCode); 105 fclose($handleStdin); 106 107 108 $descriptorspec = array( 109 0 => array('pipe', 'r'), // stdin 110 1 => array('pipe', 'w'), // stdout 111 2 => array('pipe', 'w') // stderr 112 ); 113 114 $process = proc_open('pl', $descriptorspec, $pipes); 115 116 if(is_resource($process)) { 117 fwrite($pipes[0], '[\''.substr($stdin, 0, -3).'\'].'); 118 fclose($pipes[0]); 119 120 $step = 10000; //0.01 second 121 $maxExecutionTime = $maxExecutionTime * 1000000; 122 $status = proc_get_status($process); 123 while($status['running'] && $maxExecutionTime != 0) { 124 125 $maxExecutionTime -= $step; 126 usleep($step); 127 $status = proc_get_status($process); 128 } 129 130 if($status['running'] == true) { 131 fclose($pipes[1]); //stdout 132 fclose($pipes[2]); //stderr 133 proc_terminate($process); 134 $executed[1] .= 'Process reached the maximum execution time and has been terminated! '; 135 proc_close($process); 136 137 } 138 else { 139 $executed[0] = stream_get_contents($pipes[1]); 140 $executed[1] = stream_get_contents($pipes[2]); 141 fclose($pipes[1]); //stdout 142 fclose($pipes[2]); //stderr 143 proc_close($process); 144 } 145 fclose($pipes[1]); //stdout 146 fclose($pipes[2]); //stderr 147 proc_close($process); 148 149 } 150 unlink($stdin); 151 152 return $executed; 153 } 154} 155?>