annotate sites/all/libraries/ARC2/arc/sparqlscript/ARC2_SPARQLScriptProcessor.php @ 11:b0ee71395280

deleted .DS_Store files
author danieleb <danielebarchiesi@me.com>
date Mon, 28 Oct 2013 16:12:13 +0000
parents ce11bbd8f642
children
rev   line source
danielebarchiesi@4 1 <?php
danielebarchiesi@4 2 /**
danielebarchiesi@4 3 * ARC2 SPARQLScript Processor
danielebarchiesi@4 4 *
danielebarchiesi@4 5 * @author Benjamin Nowack <bnowack@semsol.com>
danielebarchiesi@4 6 * @license http://arc.semsol.org/license
danielebarchiesi@4 7 * @package ARC2
danielebarchiesi@4 8 * @version 2010-11-16
danielebarchiesi@4 9 */
danielebarchiesi@4 10
danielebarchiesi@4 11 ARC2::inc('Class');
danielebarchiesi@4 12
danielebarchiesi@4 13 class ARC2_SPARQLScriptProcessor extends ARC2_Class {
danielebarchiesi@4 14
danielebarchiesi@4 15 function __construct($a, &$caller) {
danielebarchiesi@4 16 parent::__construct($a, $caller);
danielebarchiesi@4 17 }
danielebarchiesi@4 18
danielebarchiesi@4 19 function __init() {
danielebarchiesi@4 20 parent::__init();
danielebarchiesi@4 21 $this->max_operations = $this->v('sparqlscript_max_operations', 0, $this->a);
danielebarchiesi@4 22 $this->max_queries = $this->v('sparqlscript_max_queries', 0, $this->a);
danielebarchiesi@4 23 $this->return = 0;
danielebarchiesi@4 24 $this->script_hash = '';
danielebarchiesi@4 25 $this->env = array(
danielebarchiesi@4 26 'endpoint' => '',
danielebarchiesi@4 27 'vars' => array(),
danielebarchiesi@4 28 'output' => '',
danielebarchiesi@4 29 'operation_count' => 0,
danielebarchiesi@4 30 'query_count' => 0,
danielebarchiesi@4 31 'query_log' => array()
danielebarchiesi@4 32 );
danielebarchiesi@4 33 }
danielebarchiesi@4 34
danielebarchiesi@4 35 function reset() {
danielebarchiesi@4 36 $this->__init();
danielebarchiesi@4 37 }
danielebarchiesi@4 38
danielebarchiesi@4 39 /* */
danielebarchiesi@4 40
danielebarchiesi@4 41 function processScript($s) {
danielebarchiesi@4 42 $this->script_hash = abs(crc32($s));
danielebarchiesi@4 43 $parser = $this->getParser();
danielebarchiesi@4 44 $parser->parse($s);
danielebarchiesi@4 45 $blocks = $parser->getScriptBlocks();
danielebarchiesi@4 46 if ($parser->getErrors()) return 0;
danielebarchiesi@4 47 foreach ($blocks as $block) {
danielebarchiesi@4 48 $this->processBlock($block);
danielebarchiesi@4 49 if ($this->return) return 0;
danielebarchiesi@4 50 if ($this->getErrors()) return 0;
danielebarchiesi@4 51 }
danielebarchiesi@4 52 }
danielebarchiesi@4 53
danielebarchiesi@4 54 function getResult() {
danielebarchiesi@4 55 if ($this->return) {
danielebarchiesi@4 56 return $this->getVarValue('__return_value__');
danielebarchiesi@4 57 }
danielebarchiesi@4 58 else {
danielebarchiesi@4 59 return $this->env['output'];
danielebarchiesi@4 60 }
danielebarchiesi@4 61 }
danielebarchiesi@4 62
danielebarchiesi@4 63 /* */
danielebarchiesi@4 64
danielebarchiesi@4 65 function getParser() {
danielebarchiesi@4 66 ARC2::inc('SPARQLScriptParser');
danielebarchiesi@4 67 return new ARC2_SPARQLScriptParser($this->a, $this);
danielebarchiesi@4 68 }
danielebarchiesi@4 69
danielebarchiesi@4 70 /* */
danielebarchiesi@4 71
danielebarchiesi@4 72 function setVar($name, $val, $type = 'literal', $meta = '') {
danielebarchiesi@4 73 /* types: literal, var, rows, bool, doc, http_response, undefined, ? */
danielebarchiesi@4 74 $this->env['vars'][$name] = array(
danielebarchiesi@4 75 'value_type' => $type,
danielebarchiesi@4 76 'value' => $val,
danielebarchiesi@4 77 'meta' => $meta ? $meta : array()
danielebarchiesi@4 78 );
danielebarchiesi@4 79 }
danielebarchiesi@4 80
danielebarchiesi@4 81 function getVar($name) {
danielebarchiesi@4 82 return isset($this->env['vars'][$name]) ? $this->env['vars'][$name] : '';
danielebarchiesi@4 83 }
danielebarchiesi@4 84
danielebarchiesi@4 85 function getVarValue($name) {
danielebarchiesi@4 86 return ($v = $this->getVar($name)) ? (isset($v['value']) ? $v['value'] : $v ) : '';
danielebarchiesi@4 87 }
danielebarchiesi@4 88
danielebarchiesi@4 89 /* */
danielebarchiesi@4 90
danielebarchiesi@4 91 function replacePlaceholders($val, $context = '', $return_string = 1, $loop = 0) {
danielebarchiesi@4 92 do {
danielebarchiesi@4 93 $old_val = $val;
danielebarchiesi@4 94 if (preg_match_all('/(\{(?:[^{}]+|(?R))*\})/', $val, $m)) {
danielebarchiesi@4 95 foreach ($m[1] as $match) {
danielebarchiesi@4 96 if (strpos($val, '$' . $match) === false) {/* just some container brackets, recurse */
danielebarchiesi@4 97 $val = str_replace($match, '{' . $this->replacePlaceholders(substr($match, 1, -1), $context, $return_string, $loop + 1) . '}', $val);
danielebarchiesi@4 98 }
danielebarchiesi@4 99 else {
danielebarchiesi@4 100 $ph = substr($match, 1, -1);
danielebarchiesi@4 101 $sub_val = $this->getPlaceholderValue($ph);
danielebarchiesi@4 102 if (is_array($sub_val)) {
danielebarchiesi@4 103 $sub_val = $this->getArraySerialization($sub_val, $context);
danielebarchiesi@4 104 }
danielebarchiesi@4 105 $val = str_replace('${' . $ph . '}', $sub_val, $val);
danielebarchiesi@4 106 }
danielebarchiesi@4 107 }
danielebarchiesi@4 108 }
danielebarchiesi@4 109 } while (($old_val != $val) && ($loop < 10));
danielebarchiesi@4 110 return $val;
danielebarchiesi@4 111 }
danielebarchiesi@4 112
danielebarchiesi@4 113 function getPlaceholderValue($ph) {
danielebarchiesi@4 114 /* simple vars */
danielebarchiesi@4 115 if (isset($this->env['vars'][$ph])) {
danielebarchiesi@4 116 return $this->v('value', $this->env['vars'][$ph], $this->env['vars'][$ph]);
danielebarchiesi@4 117 }
danielebarchiesi@4 118 /* GET/POST */
danielebarchiesi@4 119 if (preg_match('/^(GET|POST)\.([^\.]+)(.*)$/', $ph, $m)) {
danielebarchiesi@4 120 $vals = strtoupper($m[1]) == 'GET' ? $_GET : $POST;
danielebarchiesi@4 121 $r = isset($vals[$m[2]]) ? $vals[$m[2]] : '';
danielebarchiesi@4 122 return $m[3] ? $this->getPropertyValue(array('value' => $r, 'value_type' => '?'), ltrim($m[3], '.')) : $r;
danielebarchiesi@4 123 }
danielebarchiesi@4 124 /* NOW */
danielebarchiesi@4 125 if (preg_match('/^NOW(.*)$/', $ph, $m)) {
danielebarchiesi@4 126 $rest = $m[1];
danielebarchiesi@4 127 /* may have sub-phs */
danielebarchiesi@4 128 $rest = $this->replacePlaceholders($rest);
danielebarchiesi@4 129 $r_struct = array(
danielebarchiesi@4 130 'y' => date('Y'),
danielebarchiesi@4 131 'mo' => date('m'),
danielebarchiesi@4 132 'd' => date('d'),
danielebarchiesi@4 133 'h' => date('H'),
danielebarchiesi@4 134 'mi' => date('i'),
danielebarchiesi@4 135 's' => date('s')
danielebarchiesi@4 136 );
danielebarchiesi@4 137 if (preg_match('/(\+|\-)\s*([0-9]+)(y|mo|d|h|mi|s)[a-z]*(.*)/is', trim($rest), $m2)) {
danielebarchiesi@4 138 eval('$r_struct[$m2[3]] ' . $m2[1] . '= (int)' . $m2[2] . ';');
danielebarchiesi@4 139 $rest = $m2[4];
danielebarchiesi@4 140 }
danielebarchiesi@4 141 $uts = mktime($r_struct['h'], $r_struct['mi'], $r_struct['s'], $r_struct['mo'], $r_struct['d'], $r_struct['y']);
danielebarchiesi@4 142 $uts -= date('Z', $uts); /* timezone offset */
danielebarchiesi@4 143 $r = date('Y-m-d\TH:i:s\Z', $uts);
danielebarchiesi@4 144 if (preg_match('/^\.(.+)$/', $rest, $m)) {
danielebarchiesi@4 145 return $this->getPropertyValue(array('value' => $r), $m[1]);
danielebarchiesi@4 146 }
danielebarchiesi@4 147 return $r;
danielebarchiesi@4 148 }
danielebarchiesi@4 149 /* property */
danielebarchiesi@4 150 if (preg_match('/^([^\.]+)\.(.+)$/', $ph, $m)) {
danielebarchiesi@4 151 list($var, $path) = array($m[1], $m[2]);
danielebarchiesi@4 152 if (isset($this->env['vars'][$var])) {
danielebarchiesi@4 153 return $this->getPropertyValue($this->env['vars'][$var], $path);
danielebarchiesi@4 154 }
danielebarchiesi@4 155 }
danielebarchiesi@4 156 return '';
danielebarchiesi@4 157 }
danielebarchiesi@4 158
danielebarchiesi@4 159 function getPropertyValue($obj, $path) {
danielebarchiesi@4 160 $val = isset($obj['value']) ? $obj['value'] : $obj;
danielebarchiesi@4 161 $path = $this->replacePlaceholders($path, 'property_value', 0);
danielebarchiesi@4 162 /* reserved */
danielebarchiesi@4 163 if ($path == 'size') {
danielebarchiesi@4 164 if ($obj['value_type'] == 'rows') return count($val);
danielebarchiesi@4 165 if ($obj['value_type'] == 'literal') return strlen($val);
danielebarchiesi@4 166 }
danielebarchiesi@4 167 if (preg_match('/^replace\([\'\"](\/.*\/[a-z]*)[\'\"],\s*[\'\"](.*)[\'\"]\)$/is', $path, $m)) {
danielebarchiesi@4 168 return @preg_replace($m[1], str_replace('$', '\\', $m[2]), $val);
danielebarchiesi@4 169 }
danielebarchiesi@4 170 if (preg_match('/^match\([\'\"](\/.*\/[a-z]*)[\'\"]\)$/is', $path, $m)) {
danielebarchiesi@4 171 return @preg_match($m[1], $val, $m) ? $m : '';
danielebarchiesi@4 172 }
danielebarchiesi@4 173 if (preg_match('/^urlencode\([\'\"]?(get|post|.*)[\'\"]?\)$/is', $path, $m)) {
danielebarchiesi@4 174 return (strtolower($m[1]) == 'post') ? rawurlencode($val) : urlencode($val);
danielebarchiesi@4 175 }
danielebarchiesi@4 176 if (preg_match('/^toDataURI\([^\)]*\)$/is', $path, $m)) {
danielebarchiesi@4 177 return 'data:text/plain;charset=utf-8,' . rawurlencode($val);
danielebarchiesi@4 178 }
danielebarchiesi@4 179 if (preg_match('/^fromDataURI\([^\)]*\)$/is', $path, $m)) {
danielebarchiesi@4 180 return rawurldecode(str_replace('data:text/plain;charset=utf-8,', '', $val));
danielebarchiesi@4 181 }
danielebarchiesi@4 182 if (preg_match('/^toPrettyDate\([^\)]*\)$/is', $path, $m)) {
danielebarchiesi@4 183 $uts = strtotime(preg_replace('/(T|\+00\:00)/', ' ', $val));
danielebarchiesi@4 184 return date('D j M H:i', $uts);
danielebarchiesi@4 185 }
danielebarchiesi@4 186 if (preg_match('/^render\(([^\)]*)\)$/is', $path, $m)) {
danielebarchiesi@4 187 $src_format = trim($m[1], '"\'');
danielebarchiesi@4 188 return $this->render($val, $src_format);
danielebarchiesi@4 189 }
danielebarchiesi@4 190 /* struct */
danielebarchiesi@4 191 if (is_array($val)) {
danielebarchiesi@4 192 if (isset($val[$path])) return $val[$path];
danielebarchiesi@4 193 $exp_path = $this->expandPName($path);
danielebarchiesi@4 194 if (isset($val[$exp_path])) return $val[$exp_path];
danielebarchiesi@4 195 if (preg_match('/^([^\.]+)\.(.+)$/', $path, $m)) {
danielebarchiesi@4 196 list($var, $path) = array($m[1], $m[2]);
danielebarchiesi@4 197 if (isset($val[$var])) {
danielebarchiesi@4 198 return $this->getPropertyValue(array('value' => $val[$var]), $path);
danielebarchiesi@4 199 }
danielebarchiesi@4 200 /* qname */
danielebarchiesi@4 201 $exp_var = $this->expandPName($var);
danielebarchiesi@4 202 if (isset($val[$exp_var])) {
danielebarchiesi@4 203 return $this->getPropertyValue(array('value' => $val[$exp_var]), $path);
danielebarchiesi@4 204 }
danielebarchiesi@4 205 return '';
danielebarchiesi@4 206 }
danielebarchiesi@4 207 }
danielebarchiesi@4 208 /* meta */
danielebarchiesi@4 209 if (preg_match('/^\_/', $path) && isset($obj['meta']) && isset($obj['meta'][substr($path, 1)])) {
danielebarchiesi@4 210 return $obj['meta'][substr($path, 1)];
danielebarchiesi@4 211 }
danielebarchiesi@4 212 return '';
danielebarchiesi@4 213 }
danielebarchiesi@4 214
danielebarchiesi@4 215 function render($val, $src_format = '') {
danielebarchiesi@4 216 if ($src_format) {
danielebarchiesi@4 217 $mthd = 'render' . $this->camelCase($src_format);
danielebarchiesi@4 218 if (method_exists($this, $mthd)) {
danielebarchiesi@4 219 return $this->$mthd($val);
danielebarchiesi@4 220 }
danielebarchiesi@4 221 else {
danielebarchiesi@4 222 return 'No rendering method found for "' . $src_format. '"';
danielebarchiesi@4 223 }
danielebarchiesi@4 224 }
danielebarchiesi@4 225 /* try RDF */
danielebarchiesi@4 226 return $this->getArraySerialization($val);
danielebarchiesi@4 227 }
danielebarchiesi@4 228
danielebarchiesi@4 229 function renderObjects($os) {
danielebarchiesi@4 230 $r = '';
danielebarchiesi@4 231 foreach ($os as $o) {
danielebarchiesi@4 232 $r .= $r ? ', ' : '';
danielebarchiesi@4 233 $r .= $o['value'];
danielebarchiesi@4 234 }
danielebarchiesi@4 235 return $r;
danielebarchiesi@4 236 }
danielebarchiesi@4 237
danielebarchiesi@4 238 /* */
danielebarchiesi@4 239
danielebarchiesi@4 240 function getArraySerialization($v, $context) {
danielebarchiesi@4 241 $v_type = ARC2::getStructType($v);/* string|array|triples|index */
danielebarchiesi@4 242 $pf = ARC2::getPreferredFormat();
danielebarchiesi@4 243 /* string */
danielebarchiesi@4 244 if ($v_type == 'string') return $v;
danielebarchiesi@4 245 /* simple array (e.g. from SELECT) */
danielebarchiesi@4 246 if ($v_type == 'array') {
danielebarchiesi@4 247 return join(', ', $v);
danielebarchiesi@4 248 $m = method_exists($this, 'toLegacy' . $pf) ? 'toLegacy' . $pf : 'toLegacyXML';
danielebarchiesi@4 249 }
danielebarchiesi@4 250 /* rdf */
danielebarchiesi@4 251 if (($v_type == 'triples') || ($v_type == 'index')) {
danielebarchiesi@4 252 $m = method_exists($this, 'to' . $pf) ? 'to' . $pf : ($context == 'query' ? 'toNTriples' : 'toRDFXML');
danielebarchiesi@4 253 }
danielebarchiesi@4 254 /* else */
danielebarchiesi@4 255 return $this->$m($v);
danielebarchiesi@4 256 }
danielebarchiesi@4 257
danielebarchiesi@4 258 /* */
danielebarchiesi@4 259
danielebarchiesi@4 260 function processBlock($block) {
danielebarchiesi@4 261 if ($this->max_operations && ($this->env['operation_count'] >= $this->max_operations)) return $this->addError('Number of ' . $this->max_operations . ' allowed operations exceeded.');
danielebarchiesi@4 262 if ($this->return) return 0;
danielebarchiesi@4 263 $this->env['operation_count']++;
danielebarchiesi@4 264 $type = $block['type'];
danielebarchiesi@4 265 $m = 'process' . $this->camelCase($type) . 'Block';
danielebarchiesi@4 266 if (method_exists($this, $m)) {
danielebarchiesi@4 267 return $this->$m($block);
danielebarchiesi@4 268 }
danielebarchiesi@4 269 return $this->addError('Unsupported block type "' . $type . '"');
danielebarchiesi@4 270 }
danielebarchiesi@4 271
danielebarchiesi@4 272 /* */
danielebarchiesi@4 273
danielebarchiesi@4 274 function processEndpointDeclBlock($block) {
danielebarchiesi@4 275 $this->env['endpoint'] = $block['endpoint'];
danielebarchiesi@4 276 return $this->env;
danielebarchiesi@4 277 }
danielebarchiesi@4 278
danielebarchiesi@4 279 /* */
danielebarchiesi@4 280
danielebarchiesi@4 281 function processQueryBlock($block) {
danielebarchiesi@4 282 if ($this->max_queries && ($this->env['query_count'] >= $this->max_queries)) return $this->addError('Number of ' . $this->max_queries . ' allowed queries exceeded.');
danielebarchiesi@4 283 $this->env['query_count']++;
danielebarchiesi@4 284 $ep_uri = $this->replacePlaceholders($this->env['endpoint'], 'endpoint');
danielebarchiesi@4 285 /* q */
danielebarchiesi@4 286 $prologue = 'BASE <' . $block['base']. '>';
danielebarchiesi@4 287 $q = $this->replacePlaceholders($block['query'], 'query');
danielebarchiesi@4 288 /* prefixes */
danielebarchiesi@4 289 $ns = isset($this->a['ns']) ? array_merge($this->a['ns'], $block['prefixes']) : $block['prefixes'];
danielebarchiesi@4 290 $q = $prologue . "\n" . $this->completeQuery($q, $ns);
danielebarchiesi@4 291 $this->env['query_log'][] = '(' . $ep_uri . ') ' . $q;
danielebarchiesi@4 292 if ($store = $this->getStore($ep_uri)) {
danielebarchiesi@4 293 $sub_r = $this->v('is_remote', '', $store) ? $store->query($q, '', $ep_uri) : $store->query($q);
danielebarchiesi@4 294 /* ignore socket errors */
danielebarchiesi@4 295 if (($errs = $this->getErrors()) && preg_match('/socket/', $errs[0])) {
danielebarchiesi@4 296 $this->warnings[] = $errs[0];
danielebarchiesi@4 297 $this->errors = array();
danielebarchiesi@4 298 $sub_r = array();
danielebarchiesi@4 299 }
danielebarchiesi@4 300 return $sub_r;
danielebarchiesi@4 301 }
danielebarchiesi@4 302 else {
danielebarchiesi@4 303 return $this->addError("no store (" . $ep_uri . ")");
danielebarchiesi@4 304 }
danielebarchiesi@4 305 }
danielebarchiesi@4 306
danielebarchiesi@4 307 function getStore($ep_uri) {
danielebarchiesi@4 308 /* local store */
danielebarchiesi@4 309 if ((!$ep_uri || $ep_uri == ARC2::getScriptURI()) && ($this->v('sparqlscript_default_endpoint', '', $this->a) == 'local')) {
danielebarchiesi@4 310 if (!isset($this->local_store)) $this->local_store = ARC2::getStore($this->a);/* @@todo error checking */
danielebarchiesi@4 311 return $this->local_store;
danielebarchiesi@4 312 }
danielebarchiesi@4 313 elseif ($ep_uri) {
danielebarchiesi@4 314 ARC2::inc('RemoteStore');
danielebarchiesi@4 315 $conf = array_merge($this->a, array('remote_store_endpoint' => $ep_uri, 'reader_timeout' => 10));
danielebarchiesi@4 316 return new ARC2_RemoteStore($conf, $this);
danielebarchiesi@4 317 }
danielebarchiesi@4 318 return 0;
danielebarchiesi@4 319 }
danielebarchiesi@4 320
danielebarchiesi@4 321 /* */
danielebarchiesi@4 322
danielebarchiesi@4 323 function processAssignmentBlock($block) {
danielebarchiesi@4 324 $sub_type = $block['sub_type'];
danielebarchiesi@4 325 $m = 'process' . $this->camelCase($sub_type) . 'AssignmentBlock';
danielebarchiesi@4 326 if (!method_exists($this, $m)) return $this->addError('Unknown method "' . $m . '"');
danielebarchiesi@4 327 return $this->$m($block);
danielebarchiesi@4 328 }
danielebarchiesi@4 329
danielebarchiesi@4 330 function processQueryAssignmentBlock($block) {
danielebarchiesi@4 331 $qr = $this->processQueryBlock($block['query']);
danielebarchiesi@4 332 if ($this->getErrors() || !isset($qr['query_type'])) return 0;
danielebarchiesi@4 333 $qt = $qr['query_type'];
danielebarchiesi@4 334 $vts = array('ask' => 'bool', 'select' => 'rows', 'desribe' => 'doc', 'construct' => 'doc');
danielebarchiesi@4 335 $r = array(
danielebarchiesi@4 336 'value_type' => isset($vts[$qt]) ? $vts[$qt] : $qt . ' result',
danielebarchiesi@4 337 'value' => ($qt == 'select') ? $this->v('rows', array(), $qr['result']) : $qr['result'],
danielebarchiesi@4 338 );
danielebarchiesi@4 339 $this->env['vars'][$block['var']['value']] = $r;
danielebarchiesi@4 340 }
danielebarchiesi@4 341
danielebarchiesi@4 342 function processStringAssignmentBlock($block) {
danielebarchiesi@4 343 $r = array('value_type' => 'literal', 'value' => $this->replacePlaceholders($block['string']['value']));
danielebarchiesi@4 344 $this->env['vars'][$block['var']['value']] = $r;
danielebarchiesi@4 345 }
danielebarchiesi@4 346
danielebarchiesi@4 347 function processVarAssignmentBlock($block) {
danielebarchiesi@4 348 if (isset($this->env['vars'][$block['var2']['value']])) {
danielebarchiesi@4 349 $this->env['vars'][$block['var']['value']] = $this->env['vars'][$block['var2']['value']];
danielebarchiesi@4 350 }
danielebarchiesi@4 351 else {
danielebarchiesi@4 352 $this->env['vars'][$block['var']['value']] = array('value_type' => 'undefined', 'value' => '');
danielebarchiesi@4 353 }
danielebarchiesi@4 354 }
danielebarchiesi@4 355
danielebarchiesi@4 356 function processPlaceholderAssignmentBlock($block) {
danielebarchiesi@4 357 $ph_val = $this->getPlaceholderValue($block['placeholder']['value']);
danielebarchiesi@4 358 $this->env['vars'][$block['var']['value']] = array('value_type' => 'undefined', 'value' => $ph_val);
danielebarchiesi@4 359 }
danielebarchiesi@4 360
danielebarchiesi@4 361 function processVarMergeAssignmentBlock($block) {
danielebarchiesi@4 362 $val1 = isset($this->env['vars'][$block['var2']['value']]) ? $this->env['vars'][$block['var2']['value']] : array('value_type' => 'undefined', 'value' => '');
danielebarchiesi@4 363 $val2 = isset($this->env['vars'][$block['var3']['value']]) ? $this->env['vars'][$block['var3']['value']] : array('value_type' => 'undefined', 'value' => '');
danielebarchiesi@4 364 if (is_array($val1) && is_array($val2)) {
danielebarchiesi@4 365 $this->env['vars'][$block['var']['value']] = array('value_type' => $val2['value_type'], 'value' => array_merge($val1['value'], $val2['value']));
danielebarchiesi@4 366 }
danielebarchiesi@4 367 elseif (is_numeric($val1) && is_numeric($val2)) {
danielebarchiesi@4 368 $this->env['vars'][$block['var']['value']] = $val1 + $val2;
danielebarchiesi@4 369 }
danielebarchiesi@4 370 }
danielebarchiesi@4 371
danielebarchiesi@4 372 function processFunctionCallAssignmentBlock($block) {
danielebarchiesi@4 373 $sub_r = $this->processFunctionCallBlock($block['function_call']);
danielebarchiesi@4 374 if ($this->getErrors()) return 0;
danielebarchiesi@4 375 $this->env['vars'][$block['var']['value']] = $sub_r;
danielebarchiesi@4 376 }
danielebarchiesi@4 377
danielebarchiesi@4 378 /* */
danielebarchiesi@4 379
danielebarchiesi@4 380 function processReturnBlock($block) {
danielebarchiesi@4 381 $sub_type = $block['sub_type'];
danielebarchiesi@4 382 $m = 'process' . $this->camelCase($sub_type) . 'AssignmentBlock';
danielebarchiesi@4 383 if (!method_exists($this, $m)) return $this->addError('Unknown method "' . $m . '"');
danielebarchiesi@4 384 $sub_r = $this->$m($block);
danielebarchiesi@4 385 $this->return = 1;
danielebarchiesi@4 386 return $sub_r;
danielebarchiesi@4 387 }
danielebarchiesi@4 388
danielebarchiesi@4 389 /* */
danielebarchiesi@4 390
danielebarchiesi@4 391 function processIfblockBlock($block) {
danielebarchiesi@4 392 if ($this->testCondition($block['condition'])) {
danielebarchiesi@4 393 $blocks = $block['blocks'];
danielebarchiesi@4 394 }
danielebarchiesi@4 395 else {
danielebarchiesi@4 396 $blocks = $block['else_blocks'];
danielebarchiesi@4 397 }
danielebarchiesi@4 398 foreach ($blocks as $block) {
danielebarchiesi@4 399 $sub_r = $this->processBlock($block);
danielebarchiesi@4 400 if ($this->getErrors()) return 0;
danielebarchiesi@4 401 }
danielebarchiesi@4 402 }
danielebarchiesi@4 403
danielebarchiesi@4 404 function testCondition($cond) {
danielebarchiesi@4 405 $m = 'test' . $this->camelCase($cond['type']) . 'Condition';
danielebarchiesi@4 406 if (!method_exists($this, $m)) return $this->addError('Unknown method "' . $m . '"');
danielebarchiesi@4 407 return $this->$m($cond);
danielebarchiesi@4 408 }
danielebarchiesi@4 409
danielebarchiesi@4 410 function testVarCondition($cond) {
danielebarchiesi@4 411 $r = 0;
danielebarchiesi@4 412 $vn = $cond['value'];
danielebarchiesi@4 413 if (isset($this->env['vars'][$vn])) $r = $this->env['vars'][$vn]['value'];
danielebarchiesi@4 414 $op = $this->v('operator', '', $cond);
danielebarchiesi@4 415 if ($op == '!') $r = !$r;
danielebarchiesi@4 416 return $r ? true : false;
danielebarchiesi@4 417 }
danielebarchiesi@4 418
danielebarchiesi@4 419 function testPlaceholderCondition($cond) {
danielebarchiesi@4 420 $val = $this->getPlaceholderValue($cond['value']);
danielebarchiesi@4 421 $r = $val ? true : false;
danielebarchiesi@4 422 $op = $this->v('operator', '', $cond);
danielebarchiesi@4 423 if ($op == '!') $r = !$r;
danielebarchiesi@4 424 return $r;
danielebarchiesi@4 425 }
danielebarchiesi@4 426
danielebarchiesi@4 427 function testExpressionCondition($cond) {
danielebarchiesi@4 428 $m = 'test' . $this->camelCase($cond['sub_type']) . 'ExpressionCondition';
danielebarchiesi@4 429 if (!method_exists($this, $m)) return $this->addError('Unknown method "' . $m . '"');
danielebarchiesi@4 430 return $this->$m($cond);
danielebarchiesi@4 431 }
danielebarchiesi@4 432
danielebarchiesi@4 433 function testRelationalExpressionCondition($cond) {
danielebarchiesi@4 434 $op = $cond['operator'];
danielebarchiesi@4 435 if ($op == '=') $op = '==';
danielebarchiesi@4 436 $val1 = $this->getPatternValue($cond['patterns'][0]);
danielebarchiesi@4 437 $val2 = $this->getPatternValue($cond['patterns'][1]);
danielebarchiesi@4 438 eval('$result = ($val1 ' . $op . ' $val2) ? 1 : 0;');
danielebarchiesi@4 439 return $result;
danielebarchiesi@4 440 }
danielebarchiesi@4 441
danielebarchiesi@4 442 function testAndExpressionCondition($cond) {
danielebarchiesi@4 443 foreach ($cond['patterns'] as $pattern) {
danielebarchiesi@4 444 if (!$this->testCondition($pattern)) return false;
danielebarchiesi@4 445 }
danielebarchiesi@4 446 return true;
danielebarchiesi@4 447 }
danielebarchiesi@4 448
danielebarchiesi@4 449 function getPatternValue($pattern) {
danielebarchiesi@4 450 $m = 'get' . $this->camelCase($pattern['type']) . 'PatternValue';
danielebarchiesi@4 451 if (!method_exists($this, $m)) return '';
danielebarchiesi@4 452 return $this->$m($pattern);
danielebarchiesi@4 453 }
danielebarchiesi@4 454
danielebarchiesi@4 455 function getLiteralPatternValue($pattern) {
danielebarchiesi@4 456 return $pattern['value'];
danielebarchiesi@4 457 }
danielebarchiesi@4 458
danielebarchiesi@4 459 function getPlaceholderPatternValue($pattern) {
danielebarchiesi@4 460 return $this->getPlaceholderValue($pattern['value']);
danielebarchiesi@4 461 }
danielebarchiesi@4 462
danielebarchiesi@4 463 /* */
danielebarchiesi@4 464
danielebarchiesi@4 465 function processForblockBlock($block) {
danielebarchiesi@4 466 $set = $this->v($block['set'], array('value' => array()), $this->env['vars']);
danielebarchiesi@4 467 $entries = isset($set['value']) ? $set['value'] : $set;
danielebarchiesi@4 468 $iterator = $block['iterator'];
danielebarchiesi@4 469 $blocks = $block['blocks'];
danielebarchiesi@4 470 if (!is_array($entries)) return 0;
danielebarchiesi@4 471 $rc = count($entries);
danielebarchiesi@4 472 foreach ($entries as $i => $entry) {
danielebarchiesi@4 473 $val_type = $this->v('value_type', 'set', $set) . ' entry';
danielebarchiesi@4 474 $this->env['vars'][$iterator] = array(
danielebarchiesi@4 475 'value' => $entry,
danielebarchiesi@4 476 'value_type' => $val_type,
danielebarchiesi@4 477 'meta' => array(
danielebarchiesi@4 478 'pos' => $i,
danielebarchiesi@4 479 'odd_even' => ($i % 2) ? 'even' : 'odd'
danielebarchiesi@4 480 )
danielebarchiesi@4 481 );
danielebarchiesi@4 482 foreach ($blocks as $block) {
danielebarchiesi@4 483 $this->processBlock($block);
danielebarchiesi@4 484 if ($this->getErrors()) return 0;
danielebarchiesi@4 485 }
danielebarchiesi@4 486 }
danielebarchiesi@4 487 }
danielebarchiesi@4 488
danielebarchiesi@4 489 /* */
danielebarchiesi@4 490
danielebarchiesi@4 491 function processLiteralBlock($block) {
danielebarchiesi@4 492 $this->env['output'] .= $this->replacePlaceholders($block['value'], 'output');
danielebarchiesi@4 493 }
danielebarchiesi@4 494
danielebarchiesi@4 495 /* */
danielebarchiesi@4 496
danielebarchiesi@4 497 function processFunctionCallBlock($block) {
danielebarchiesi@4 498 $uri = $this->replacePlaceholders($block['uri'], 'function_call');
danielebarchiesi@4 499 /* built-ins */
danielebarchiesi@4 500 if (strpos($uri, $this->a['ns']['sps']) === 0) {
danielebarchiesi@4 501 return $this->processBuiltinFunctionCallBlock($block);
danielebarchiesi@4 502 }
danielebarchiesi@4 503 /* remote functions */
danielebarchiesi@4 504 }
danielebarchiesi@4 505
danielebarchiesi@4 506 function processBuiltinFunctionCallBlock($block) {
danielebarchiesi@4 507 $fnc_uri = $this->replacePlaceholders($block['uri'], 'function_call');
danielebarchiesi@4 508 $fnc_name = substr($fnc_uri, strlen($this->a['ns']['sps']));
danielebarchiesi@4 509 if (preg_match('/^(get|post)$/i', $fnc_name, $m)) {
danielebarchiesi@4 510 return $this->processHTTPCall($block, strtoupper($m[1]));
danielebarchiesi@4 511 }
danielebarchiesi@4 512 if ($fnc_name == 'eval') {
danielebarchiesi@4 513 return $this->processEvalCall($block);
danielebarchiesi@4 514 }
danielebarchiesi@4 515 }
danielebarchiesi@4 516
danielebarchiesi@4 517 function processEvalCall($block) {
danielebarchiesi@4 518 if (!$block['args']) return 0;
danielebarchiesi@4 519 $arg = $block['args'][0];
danielebarchiesi@4 520 $script = '';
danielebarchiesi@4 521 if ($arg['type'] == 'placeholder') $script = $this->getPlaceholderValue($arg['value']);
danielebarchiesi@4 522 if ($arg['type'] == 'literal') $script = $arg['value'];
danielebarchiesi@4 523 if ($arg['type'] == 'var') $script = $this->getVarValue($arg['value']);
danielebarchiesi@4 524 //echo "\n" . $script . $arg['type'];
danielebarchiesi@4 525 $this->processScript($script);
danielebarchiesi@4 526 }
danielebarchiesi@4 527
danielebarchiesi@4 528 function processHTTPCall($block, $mthd = 'GET') {
danielebarchiesi@4 529 ARC2::inc('Reader');
danielebarchiesi@4 530 $reader = new ARC2_Reader($this->a, $this);
danielebarchiesi@4 531 $url = $this->replacePlaceholders($block['args'][0]['value'], 'function_call');
danielebarchiesi@4 532 if ($mthd != 'GET') {
danielebarchiesi@4 533 $reader->setHTTPMethod($mthd);
danielebarchiesi@4 534 $reader->setCustomHeaders("Content-Type: application/x-www-form-urlencoded");
danielebarchiesi@4 535 }
danielebarchiesi@4 536 $to = $this->v('remote_call_timeout', 0, $this->a);
danielebarchiesi@4 537 $reader->activate($url, '', 0, $to);
danielebarchiesi@4 538 $format = $reader->getFormat();
danielebarchiesi@4 539 $resp = '';
danielebarchiesi@4 540 while ($d = $reader->readStream()) {
danielebarchiesi@4 541 $resp .= $d;
danielebarchiesi@4 542 }
danielebarchiesi@4 543 $reader->closeStream();
danielebarchiesi@4 544 unset($this->reader);
danielebarchiesi@4 545 return array('value_type' => 'http_response', 'value' => $resp);
danielebarchiesi@4 546 }
danielebarchiesi@4 547
danielebarchiesi@4 548 /* */
danielebarchiesi@4 549
danielebarchiesi@4 550 function extractVars($pattern, $input = '') {
danielebarchiesi@4 551 $vars = array();
danielebarchiesi@4 552 /* replace PHs, track ()s */
danielebarchiesi@4 553 $regex = $pattern;
danielebarchiesi@4 554 $vars = array();
danielebarchiesi@4 555 if (preg_match_all('/([\?\$]\{([^\}]+)\}|\([^\)]+\))/', $regex, $m)) {
danielebarchiesi@4 556 $matches = $m[1];
danielebarchiesi@4 557 $pre_vars = $m[2];
danielebarchiesi@4 558 foreach ($matches as $i => $match) {
danielebarchiesi@4 559 $vars[] = $pre_vars[$i];
danielebarchiesi@4 560 if ($pre_vars[$i]) {/* placeholder */
danielebarchiesi@4 561 $regex = str_replace($match, '(.+)', $regex);
danielebarchiesi@4 562 }
danielebarchiesi@4 563 else {/* parentheses, but may contain placeholders */
danielebarchiesi@4 564 $sub_regex = $match;
danielebarchiesi@4 565 while (preg_match('/([\?\$]\{([^\}]+)\})/', $sub_regex, $m)) {
danielebarchiesi@4 566 $sub_regex = str_replace($m[1], '(.+)', $sub_regex);
danielebarchiesi@4 567 $vars[] = $m[2];
danielebarchiesi@4 568 }
danielebarchiesi@4 569 $regex = str_replace($match, $sub_regex, $regex);
danielebarchiesi@4 570 }
danielebarchiesi@4 571 }
danielebarchiesi@4 572 /* eval regex */
danielebarchiesi@4 573 if (@preg_match('/' . $regex . '/is', $input, $m)) {
danielebarchiesi@4 574 $vals = $m;
danielebarchiesi@4 575 }
danielebarchiesi@4 576 else {
danielebarchiesi@4 577 return 0;
danielebarchiesi@4 578 }
danielebarchiesi@4 579 for ($i = 0; $i < count($vars); $i++) {
danielebarchiesi@4 580 if ($vars[$i]) {
danielebarchiesi@4 581 $this->setVar($vars[$i], isset($vals[$i + 1]) ? $vals[$i + 1] : '');
danielebarchiesi@4 582 }
danielebarchiesi@4 583 }
danielebarchiesi@4 584 return 1;
danielebarchiesi@4 585 }
danielebarchiesi@4 586 /* no placeholders */
danielebarchiesi@4 587 return ($pattern == $input) ? 1 : 0;
danielebarchiesi@4 588 }
danielebarchiesi@4 589
danielebarchiesi@4 590 /* */
danielebarchiesi@4 591
danielebarchiesi@4 592 }