<?php
require_once('Transformer.php');

class 
GoogleMaps extends Transformer {

  private 
$detailsFields = array();

  public function 
transform() {
    
// make sure there is an address field
    
if (empty($this->extraArgs['addressField'])) {
      throw new 
MissingArgumentsException(array('addressField'));
    }
    
    
// create a DOM object and an xpath object
    
$xmlDoc  = new DOMDocument();
    
$xmlDoc->loadXML($this->xmlContents);
    
$xmlRoot $xmlDoc->documentElement;    
    
$xpath   = new DOMXPath($xmlDoc);
        
    
// get the values of the fields
    
$groupsOrFields $xmlRoot->childNodes;
    
$groupNodes     = array();
    
$fieldNodes     = array();
    for (
$i=0$i<$groupsOrFields->length$i++) {
      
$childNode $groupsOrFields->item($i);

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

      if (
$childNode->getAttribute('type') == 'group')
        
$groupNodes[] = $childNode;
      elseif (
$childNode->getAttribute('type') == 'field')
        
$fieldNodes[] = $childNode;
    }
  
    
// set up the key
    
$key 'YourGoogleMapsKey';

    
// start HTML
    
header('Content-type: text/html; charset=UTF-8');
    
    
?>
    <html>
      <head>
        <title>
          Google Maps: 
          <?php echo $xpath->query("//elements/dapper/dappTitle")->item(0)->nodeValue;?>
        </title>
        <script src="/prototype.js" type="text/javascript"></script>
        <script src="http://maps.google.com/maps?file=api&v=2&key=<?php echo $key;?>" type="text/javascript"></script>
      </head>
      <body onload="addAddresses();">
        <?php
        
if (!empty($this->extraArgs['pageTitle']))
          echo 
'<h1>'.$this->extraArgs['pageTitle'].'</h1>';
        
?>
        <center>
          <div id="mapc"></div>
        </center>
        <script type="text/javascript">
        
        var first = true;
        var geocoder = new GClientGeocoder();
    
        map = new GMap2(document.getElementById("mapc"));
        map.addControl(new GLargeMapControl());    
        map.addControl(new GMapTypeControl());        
        map.setCenter(new GLatLng(36.315125,-32.695312), 2);
    
        function addAddress(address, details) {
          geocoder.getLatLng(
            address,
            function(point) {
              if (point) {
                addPointToMap(point, details);
              }
            }
          );      
        }
        
        function addPointToMap(point, details) {
          var marker = new GMarker(point);
          map.addOverlay(marker);
    
          if (typeof details != 'undefined') {
            GEvent.addListener(marker, "click", function() {
                marker.openInfoWindowHtml(details);
            });
          }
          
          if (first) {
            first = false;
            map.setCenter(point, 11);
          }  
        }    


    
    function addAddresses() {

    <?php

    $addressField  
$this->extraArgs['addressField'];
    
$detailsFields = !empty($this->extraArgs['detailsField']) ? $this->extraArgs['detailsField'] : array();
    if (!
is_array($detailsFields))
      
$detailsFields = array($detailsFields);
    
$this->detailsFields $detailsFields;

    foreach (
$groupNodes as $groupNode) {
      
$fields $groupNode->childNodes;
            
      
$groupFields = array();
      
      for (
$j=0$j<$fields->length$j++) {
        
$fNode $fields->item($j);
        if (
$fNode->nodeType != XML_ELEMENT_NODE)
          continue;
          
        if (
$fNode->tagName == $addressField || in_array($fNode->tagName,$this->detailsFields)) {
          
$groupFields[$fNode->tagName] = $fNode;

        }
      }
      
$addressNode  null;
      
$detailsNodes null;
      
      if (!empty(
$groupFields[$addressField]))
        
$addressNode $groupFields[$addressField];
      
      foreach (
$this->detailsFields as $detailsField) {
        if (!empty(
$groupFields[$detailsField])) {
            
$detailsNodes[] = $groupFields[$detailsField];
        }
      }

      if (isset(
$addressNode)) {
        
$this->addMarker($addressNode,$detailsNodes);
      }
    }
    
    if (
sizeof($fieldNodes)) {
      foreach (
$fieldNodes as $fieldNode) {
        
$this->addMarker($fieldNode);
      }
    }    
    
    
?>
    }
    </script>
    </body>
    </html>
    <?php    
  
}
    
  private function 
addMarker($addressNode$detailsNodes=null) {
    if (
$addressNode->nodeType != XML_ELEMENT_NODE)
      return;

    if (
$addressNode->getAttribute('type') == 'field') {
        
      
$display $addressNode->nodeValue;

      
// if this is the address field, then get it's long/lat and make pin
      
if ($addressNode->tagName == $this->extraArgs['addressField']) {
        
$address preg_replace("/'/","\\'",$display);
        
$address preg_replace("/\n/s"," ",$address);
        
$address preg_replace("//",",",$address);
        
$this->markerIndex++;

        if (
sizeof($this->detailsFields) && isset($detailsNodes) && sizeof($detailsNodes)) {
            
            
$detailsArray = array();
            foreach (
$detailsNodes as $detailsNode) {
              if (
in_array($detailsNode->tagName,$this->detailsFields)) {
                
$details preg_replace("/'/","\\'",$detailsNode->nodeValue);
                
$details preg_replace("/\n/","\\n",$details);
                
$detailsArray[] = $details;
              }
            }
            
$detailsDisplay join("<br/>"$detailsArray);
            echo 
"addAddress('".$address."','".$detailsDisplay."');\n";
  
        }
        else
          echo 
"addAddress('".$address."');\n";
      
      }

    }
  }
  
  public static function 
getDetails() {
    
$details = array();
    
    
$details['args']['addressField'] = array('type'     => DAPP_FIELD,
                                             
'required' => true,
                                             
'display'  => 'Address Field');
    
    
$details['args']['detailsField'] = array('type'     => DAPP_FIELD_MULTI,
                                             
'required' => false,
                                             
'display'  => 'Details Fields');

    
$details['args']['pageTitle']    = array('type'     => USER_FREEFORM,
                                             
'required' => false,
                                             
'display'  => 'Page Title'
                                             
);

    
$details['description']   = 'Transforms the output of a Dapp into a Google Map.';
    
    return 
$details;
  }

}

?>