view inputParser.inc @ 61:13d899b748b7

Throw exception rather than exiting plain.
author Tom Fredrik "BFG" Klaussen <bfg@blenning.no>
date Thu, 11 Oct 2012 17:19:13 +0200
parents 0e157721bbad
children b7efe2ecbc11
line wrap: on
line source

<?php
/**
 * @file
 * Functionality for translating an XML document into a webpage
 */
function getParam($param)
{
  $param_type=$param->getAttribute("type");
  $param_value;
  if (!$param_type)
    $param_type="scalar";

  if($param_type == "scalar") {
    $param_subst=$param->getAttribute("subst");
    $param_value=$param->getAttribute("value");
    if ($param_subst) {
      /*
      $param_value=preg_replace("/name/", $name, $param_subst);
      $param_value=preg_replace('/lang/', $lang, $param_value);
      */
    }
  }
  elseif($param_type == "array") {
	  $params=$param->getElementsByTagName("param");
	  $param_value=array();
	  foreach ($param->childNodes as $param) {
	    if ($param->nodeType == XML_ELEMENT_NODE)
	    {
	      array_push($param_value, getParam($param));
	    }
	  }
  }
  return $param_value;
}

function getFiles($doc, $options) {
  $lang = $options->getLang();
  $conf = $options->getName();

  $toRemove = array();

  $topLevelTags = $doc->getElementsByTagName("toplevel");
  foreach ($topLevelTags as $topLevel) {
    $topLevel->parentNode->removeChild($topLevel);
  }

  $valueDict = array();
  $fragments = array();
  $setters = $doc->getElementsByTagName("set");
  foreach ($setters as $setTag) {
    $key = $setTag->getAttribute("id");
    $type = $setTag->getAttribute("type");
    if ($type == "fragment") {
      $fragments[$key] = $setTag;
    }
    else {
      $value = $setTag->getAttribute("value");
      if ($key && $value) {
	$valueDict[$key] = $value;
      }
    }
    //We need to iterate in the opposite direction when removing,
    //so best shifting.
    array_unshift($toRemove, $setTag);
  }

  $params = $doc->getElementsByTagName("param");
  foreach ($params as $param) {
    if ($param->getAttribute("type")=="input_config") {
      $id = $param->getAttribute("id");
      if (array_key_exists($id, $valueDict)) {
	$value = $valueDict[$id];
	$tmp = new DOMDocument();

	$tmp->loadXml("<xml>${value}</xml>");
	$parent = $param->parentNode;
	$parent->insertBefore(new DOMText($tmp->textContent), $param);
	//We need to iterate in the opposite direction when removing,
	//so best shifting.
	array_unshift($toRemove, $param);
      }
      elseif (array_key_exists($id, $fragments)) {
	$fragment = $fragments[$id];

	$cloneFragment = $fragment->cloneNode(true);
	$insNode = $param;
	for ($i = $cloneFragment->childNodes->length - 1; $i >= 0; $i--) {
	  $child = $cloneFragment->childNodes->item($i);
	  $child = $child->parentNode->removeChild($child);
	  $insNode = $insNode->parentNode->insertBefore($child, $insNode);
	}

	//We need to iterate in the opposite direction when removing,
	//so best shifting.
	array_unshift($toRemove, $param);
      }
    }
  }

  foreach($toRemove as $param) {
    $parent = $param->parentNode;
    $parent->removeChild($param);
  }

  $body = getElementByTagName($doc,"body");
  $files = $body->getElementsByTagName("file");

  $toRemove = array();

  foreach ($files as $file) {
    $script=$file->getAttribute("script");
    if ($script) {
      $cacheable = false;
      $src="";
      $cwd = getcwd();

      $matches=array();
      preg_match('/(.*\/)/', $script, $matches);
      $dirname=$matches[0];
      preg_match('/([^\/]*)$/', $script, $matches);
      $filename=$matches[0];
      chdir("${lang}/${dirname}");
      $pipe=popen("php ${filename}","r");
      $file_content = stream_get_contents($pipe);
      chdir("${cwd}");
    }
    else {
      $src = $file->getAttribute("src");
      $fname = $options->getBasePath() . "/${lang}/${src}";
      $file_content = $options->getCache()->loadFile($fname);
    }
    if(floatval($file_content)<0) {
      errorPage("Resource not found '${lang}/${src}'");
    }

    $filters = $file->getElementsByTagName("filter");
    foreach($filters as $filter) {
      $func = $filter->getAttribute("function");
      $params = $filter->getElementsByTagName("param");
      $callString = "\$file_content = ${func}(\$file_content, \$options";
      $param_values = array();
      $i = 0;
      foreach ($filter->childNodes as $param) {
	if ($param->nodeType == XML_ELEMENT_NODE)
	  {
	    $param_value[$i] = getParam($param);
	    $callString .= ",\$param_value[$i]";
	    $i++;
	  }
      }
      $callString .= ");";
      eval($callString);
    }
    $ndoc = new DOMDocument();

    $ndoc->loadXml("<xml>${file_content}</xml>");

    $parent = $file->parentNode;
    foreach ($ndoc->firstChild->childNodes as $child) {
      $clonedChild = $doc->importNode($child, true);
      $parent->insertBefore($clonedChild, $file);
    }
    //We need to iterate in the opposite direction when removing,
    //so best shifting.
    array_unshift($toRemove, $file);
  }
  foreach($toRemove as $param) {
    $parent = $param->parentNode;
    $parent->removeChild($param);
  }

  return $doc;
}

function getInput($master, $param, $options)
{
  $lang = $options->getLang();
  $name = $param->getAttribute("id");
  $conf = $options->getName();
  if (!$conf)
    $conf = $param->getAttribute("default");

  $confFile = $options->getBasePath() . "/${lang}/${conf}.xml";
  $options->getCache()->cache_time($confFile);
  $doc = new DOMDocument();
  $doc->load($confFile);

  $toplevel = $doc->getElementsByTagName("toplevel");

  if(! $toplevel->length) {
    errorPage("Resource '${conf}' is not available", 500);
  }

  $includes = $doc->getElementsByTagName("include");
  $recurse = 0;

  while($includes->length > 0) {
    if(++$recurse > MAX_RECURSE) {
      errorPage('Recursion limit exceeded', 500);
    }
    foreach ($includes as $include) {
	$src = $include->getAttribute("src");
	$subdoc = new DOMDocument();
	$subfile = $options->getBasePath() . "/${lang}/${src}";
	$subdoc->load("$subfile");
	$options->getCache()->cache_time($subfile);
	$parent = $include->parentNode;
	$xml = getElementByTagName($subdoc,"xml");
	foreach($xml->childNodes as $child) {
	  $text = $subdoc->saveXml($child);
	  $clonedChild = $doc->importNode($child,true);
	  $parent->insertBefore($clonedChild,$include);
	}
	$parent->removeChild($include);
    }
    $includes = $doc->getElementsByTagName("include");
  }

  return $doc;
}
?>