<?php

require_once('Transformer.php');

// XXX: this transformer is not double dapp safe!

class CSV extends Transformer {

  private 
$itemFields;

  public function 
transform() {
    if (empty(
$this->extraArgs['fields']))
      throw new 
MissingArgumentsException(array('fields'));
    
    
// xmlDoc is responsible for reading the Dapp output
    
$xmlDoc = new DOMDocument();
    
$xmlDoc->loadXML($this->xmlContents);
    
$xmlRoot $xmlDoc->documentElement;    
    
    
$this->xpath = new DOMXPath($xmlDoc);

    
// if there was an error process it and display it as the output
    
$messages $this->xpath->query("/results/message");
    if (
$messages->length 0) {
      
header('Content-type: text/plain');    
      echo 
$messages->item(0)->nodeValue."\n";
      exit;
    }

    
// determine the encoding
    
$encoding 'UTF-8';
    
$dapperTag $xmlRoot->getElementsByTagName('dapper')->item(0);
    if (
$dapperTag) {
      
$encodingTag $dapperTag->getElementsByTagName('encoding')->item(0);
      if (
$encodingTag)
        
$encoding $encodingTag->nodeValue;
    }
    
header('Content-type: text/plain; charset='.$encoding);
    
    
// get the content    
    
$groupsOrFields $xmlRoot->childNodes;
    for (
$i=0$i<$groupsOrFields->length$i++) {
      
$childNode $groupsOrFields->item($i);

      if (
$childNode->nodeType != XML_ELEMENT_NODE)
        continue;

      if (
$childNode->getAttribute('type') == 'group') {
        
$this->itemFields = array();

        
$fields $childNode->childNodes;
        
// this loop sets up $this->itemFields
        
for ($j=0$j<$fields->length$j++) {
          
$this->getFieldValue($fields->item($j));
        }
      }
      
// we make a fairly feeble attempt to handle ungrouped fields, at the top
      // level only (doesn't work for double dapps)
      
elseif ($childNode->getAttribute('type') == 'field') {
        
$this->itemFields = array();
        
$this->getFieldValue($childNode);
      }

      if (
sizeof($this->itemFields)) {
        
$lineItems = array();
        foreach (
$this->itemFields as $fieldName => $fieldValues) {
          
$lineItems[] = join(",",$fieldValues);
        }
        echo 
join(','$lineItems)."\n";
      }
    }

  }
  
  private function 
getFieldValue($fieldNode) {
    if (
$fieldNode->nodeType != XML_ELEMENT_NODE)
      return;

    if (
$fieldNode->getAttribute('type') == 'field') {
      
// if the user specified that this field is to be included in the
      // output, then do that
      
$fieldName $fieldNode->tagName;
      foreach (
$this->extraArgs['fields'] as $desiredFieldName) {
        
$value null;
        
        if (
$fieldName == $desiredFieldName)
          
$value $fieldNode->nodeValue;
        
        if (
preg_match('/(.*)@(.*)/',$desiredFieldName,$matches)) {
          
$dappFieldName $matches[1];
          if (
$dappFieldName == $fieldName && $fieldNode->getAttribute($matches[2]))
            
$value $fieldNode->getAttribute($matches[2]);
        }
        
        if (!
is_null($value))
          
$this->itemFields[$fieldName][] = preg_replace('/,\s*/',' ',$value);
      }
    }
  }
  
  public static function 
getDetails() {
    
$details = array();
    
    
$details['args']['fields']        = array('type'     => DAPP_FIELD_OR_ATTRIBUTE_MULTI,
                                              
'required' => true,
                                              
'display'  => 'Fields to Include');

    
$details['description']   = 'Transforms the output of a Dapp into a comma separated'.
                                
'list of values (CSV)';
    
    return 
$details;
  }

}

?>