Ejemplo n.º 1
0
 /**
  * Do all that's necessary to convert a single parameter into XML.
  * Can call itself recursively for infinitely deep data structures.
  * 
  * @param ProgramParameter $paramElement
  * @return string
  */
 protected function buildParamXml(ProgramParameter $paramElement)
 {
     $paramXml = '';
     $specialOuterDsName = '';
     // build start ds tag
     $props = $paramElement->getParamProperties();
     // optional by
     $by = $props['by'];
     $byStr = $by ? " by='{$by}'" : '';
     $name = $props['var'];
     // optional "array" attribute
     $isArray = $props['array'];
     $isArrayStr = $isArray ? " array='on'" : '';
     // optional dim (goes best with multi but could exist on its own, too)
     $dim = $props['dim'];
     $dimStr = $dim ? " dim='{$dim}'" : '';
     // if dim>0 and array integrity is specified
     $isMulti = $dim && $this->getOption('arrayIntegrity');
     /* if a multiple occurrence DS or scalar field.
      * later we will wrap an additional DS around it
      * The inner DS or scalar field will be a template with a 'dim' attribute to be expanded on output from XMLSERVICE.
      */
     /* if we add an outer DS that's "multi," don't bother to give the inner (original) ds a name.
      * The inner ds will be repeated many times and its name will be replaced on output by numeric indexes.
      *  So no need to include an inner ds name.
      */
     if ($isMulti) {
         $specialOuterDsName = $name;
         $innerName = '';
     } else {
         // not multi. Use normal inner name.
         $innerName = $name;
         // starts with space, directly following "<data"
     }
     // optional dou (do until)
     $dou = $props['dou'];
     $douStr = $dou ? " dou='{$dou}'" : '';
     // optional len that checks length of the structure/field to which it's appended
     $labelLen = $props['len'];
     $labelLenStr = $labelLen ? " len='{$labelLen}'" : '';
     // it's a data structure
     if ($props['type'] == 'ds') {
         // start ds tag with name and optional dim and by
         $innerNameStr = $innerName ? " var='{$innerName}'" : '';
         $paramXml .= "<ds{$innerNameStr}{$dimStr}{$douStr}{$isArrayStr}{$labelLenStr}>\n";
         // get the subfields
         $dsSubFields = $paramElement->getParamValue();
         if (is_array($dsSubFields) && count($dsSubFields)) {
             // recursively build XML from each data structure subfield
             foreach ($dsSubFields as $subField) {
                 $paramXml .= $this->buildParamXml($subField);
             }
         }
         // complete the ds tag
         $paramXml .= "</ds>\n";
     } else {
         // not a data structure. a regular single field
         $type = $props['type'];
         // optional varying
         // varying only inserted if set on/2/4 (default is off, so we can let XMLSERVICE supply the default behavior if off). The less XML we create and send, the more efficient we will be.
         $varyingStr = '';
         if (isset($props['varying'])) {
             // a valid non-off value, so add the varying attribute.
             if (in_array($props['varying'], $this->_varyingTypes)) {
                 $varyingStr = " varying='{$props['varying']}'";
             }
         }
         // optional enddo
         $enddo = $props['enddo'];
         $enddoStr = $enddo ? " enddo='{$enddo}'" : '';
         // optional setLen to set length value to a numeric field (see 'len' for where the length comes from)
         $labelSetLen = $props['setlen'];
         $labelSetLenStr = $labelSetLen ? " setlen='{$labelSetLen}'" : '';
         $data = $props['data'];
         if (is_object($data)) {
             // uh-oh. Something wrong
             echo "data is not a string. type is: {$type}. data is: " . var_export($data, true) . "<BR>";
         }
         // get hex/ccsid information to include in the data tag
         $this->processParamProps($props);
         $ccsidHexStr = "{$props['ccsidStr']}{$props['hexStr']}";
         $processedData = $props['processedData'];
         // Google Code issue 11
         // Use short type tag when it's empty
         if ($processedData === '') {
             $dataEndTag = " />";
         } else {
             $dataEndTag = ">{$processedData}</data>";
         }
         // use the old, inefficient "repeat item with sequential numbering of field name" technique if backwards compatibility is desired
         $useOldDimWay = $dim && !$isMulti;
         if ($useOldDimWay) {
             //  Backward compatibility technique
             // a flattened group of data fields with sequentially increasing names
             foreach (range(1, $dim) as $sequence) {
                 // only difference is the $sequence inserted after $innerNameStr
                 // and no $dimStr. Because we're physically repeating the line
                 // And always need the name specified with sequence.
                 $paramXml .= "<data var='{$innerName}{$sequence}' type='{$type}'{$ccsidHexStr}{$enddoStr}{$byStr}{$varyingStr}{$labelSetLenStr}{$dataEndTag}";
             }
         } else {
             // Not dim or perhaps dim and multi
             // Use new, efficient, good way. Only one line needed with $dimStr, which XMLSERVICE will expand for us.
             $innerNameStr = $innerName ? " var='{$innerName}'" : '';
             // only need name if exists. If not then it's probably a "multi" and doesn't need an inner name.
             $paramXml .= "<data{$innerNameStr} type='{$type}'{$ccsidHexStr}{$dimStr}{$enddoStr}{$byStr}{$varyingStr}{$labelSetLenStr}{$dataEndTag}";
         }
     }
     // if a multi-occurrence DS or scalar field, wrap in an identially named "array" DS shell.
     // The "array" indicator will help us parse the results on the way out.
     if ($isMulti) {
         $paramXml = "\n\n<ds var='{$specialOuterDsName}' comment='Multi-occur container' array='on'>\n{$paramXml}\n</ds>";
     } elseif ($dim) {
         // if not multi but regular old-style dim, an ordinary <ds> tag will do to contain all the <data> elements.
         $paramXml = "\n\n<ds comment='old-style repeated data array container'>\n{$paramXml}\n</ds>";
     }
     return $paramXml;
 }