PEAR
[ class tree: PEAR ] [ index: PEAR ] [ all elements ]

Source for file v2.php

Documentation is available at v2.php

  1. <?php
  2. /**
  3.  * package.xml generation class, package.xml version 2.0
  4.  *
  5.  * PHP versions 4 and 5
  6.  *
  7.  * @category   pear
  8.  * @package    PEAR
  9.  * @author     Greg Beaver <cellog@php.net>
  10.  * @author     Stephan Schmidt (original XML_Serializer code)
  11.  * @copyright  1997-2009 The Authors
  12.  * @license    http://opensource.org/licenses/bsd-license.php New BSD License
  13.  * @version    CVS: $Id: v2.php 313023 2011-07-06 19:17:11Z dufuz $
  14.  * @link       http://pear.php.net/package/PEAR
  15.  * @since      File available since Release 1.4.0a1
  16.  */
  17. /**
  18.  * file/dir manipulation routines
  19.  */
  20. require_once 'System.php';
  21. require_once 'XML/Util.php';
  22.  
  23. /**
  24.  * This class converts a PEAR_PackageFile_v2 object into any output format.
  25.  *
  26.  * Supported output formats include array, XML string (using S. Schmidt's
  27.  * XML_Serializer, slightly customized)
  28.  * @category   pear
  29.  * @package    PEAR
  30.  * @author     Greg Beaver <cellog@php.net>
  31.  * @author     Stephan Schmidt (original XML_Serializer code)
  32.  * @copyright  1997-2009 The Authors
  33.  * @license    http://opensource.org/licenses/bsd-license.php New BSD License
  34.  * @version    Release: 1.9.4
  35.  * @link       http://pear.php.net/package/PEAR
  36.  * @since      Class available since Release 1.4.0a1
  37.  */
  38. {
  39.    /**
  40.     * default options for the serialization
  41.     * @access private
  42.     * @var array $_defaultOptions 
  43.     */
  44.     var $_defaultOptions = array(
  45.         'indent'             => ' ',                    // string used for indentation
  46.         'linebreak'          => "\n",                  // string used for newlines
  47.         'typeHints'          => false,                 // automatically add type hin attributes
  48.         'addDecl'            => true,                 // add an XML declaration
  49.         'defaultTagName'     => 'XML_Serializer_Tag',  // tag used for indexed arrays or invalid names
  50.         'classAsTagName'     => false,                 // use classname for objects in indexed arrays
  51.         'keyAttribute'       => '_originalKey',        // attribute where original key is stored
  52.         'typeAttribute'      => '_type',               // attribute for type (only if typeHints => true)
  53.         'classAttribute'     => '_class',              // attribute for class of objects (only if typeHints => true)
  54.         'scalarAsAttributes' => false,                 // scalar values (strings, ints,..) will be serialized as attribute
  55.         'prependAttributes'  => '',                    // prepend string for attributes
  56.         'indentAttributes'   => false,                 // indent the attributes, if set to '_auto', it will indent attributes so they all start at the same column
  57.         'mode'               => 'simplexml',             // use 'simplexml' to use parent name as tagname if transforming an indexed array
  58.         'addDoctype'         => false,                 // add a doctype declaration
  59.         'doctype'            => null,                  // supply a string or an array with id and uri ({@see XML_Util::getDoctypeDeclaration()}
  60.         'rootName'           => 'package',                  // name of the root tag
  61.         'rootAttributes'     => array(
  62.             'version' => '2.0',
  63.             'xmlns' => 'http://pear.php.net/dtd/package-2.0',
  64.             'xmlns:tasks' => 'http://pear.php.net/dtd/tasks-1.0',
  65.             'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
  66.             'xsi:schemaLocation' => 'http://pear.php.net/dtd/tasks-1.0
  67. http://pear.php.net/dtd/tasks-1.0.xsd
  68. http://pear.php.net/dtd/package-2.0
  69. http://pear.php.net/dtd/package-2.0.xsd',
  70.         ),               // attributes of the root tag
  71.         'attributesArray'    => 'attribs',                  // all values in this key will be treated as attributes
  72.         'contentName'        => '_content',                   // this value will be used directly as content, instead of creating a new tag, may only be used in conjuction with attributesArray
  73.         'beautifyFilelist'   => false,
  74.         'encoding' => 'UTF-8',
  75.     );
  76.  
  77.    /**
  78.     * options for the serialization
  79.     * @access private
  80.     * @var array $options 
  81.     */
  82.     var $options = array();
  83.  
  84.    /**
  85.     * current tag depth
  86.     * @var integer $_tagDepth 
  87.     */
  88.     var $_tagDepth = 0;
  89.  
  90.    /**
  91.     * serilialized representation of the data
  92.     * @var string $_serializedData 
  93.     */
  94.     var $_serializedData = null;
  95.     /**
  96.      * @var PEAR_PackageFile_v2 
  97.      */
  98.     var $_packagefile;
  99.     /**
  100.      * @param PEAR_PackageFile_v2 
  101.      */
  102.     function PEAR_PackageFile_Generator_v2(&$packagefile)
  103.     {
  104.         $this->_packagefile &$packagefile;
  105.         if (isset($this->_packagefile->encoding)) {
  106.             $this->_defaultOptions['encoding'$this->_packagefile->encoding;
  107.         }
  108.     }
  109.  
  110.     /**
  111.      * @return string 
  112.      */
  113.     function getPackagerVersion()
  114.     {
  115.         return '1.9.4';
  116.     }
  117.  
  118.     /**
  119.      * @param PEAR_Packager 
  120.      * @param bool generate a .tgz or a .tar
  121.      * @param string|nulltemporary directory to package in
  122.      */
  123.     function toTgz(&$packager$compress = true$where = null)
  124.     {
  125.         $a = null;
  126.         return $this->toTgz2($packager$a$compress$where);
  127.     }
  128.  
  129.     /**
  130.      * Package up both a package.xml and package2.xml for the same release
  131.      * @param PEAR_Packager 
  132.      * @param PEAR_PackageFile_v1 
  133.      * @param bool generate a .tgz or a .tar
  134.      * @param string|nulltemporary directory to package in
  135.      */
  136.     function toTgz2(&$packager&$pf1$compress = true$where = null)
  137.     {
  138.         require_once 'Archive/Tar.php';
  139.         if (!$this->_packagefile->isEquivalent($pf1)) {
  140.             return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: "' .
  141.                 basename($pf1->getPackageFile()) .
  142.                 '" is not equivalent to "' basename($this->_packagefile->getPackageFile())
  143.                 . '"');
  144.         }
  145.  
  146.         if ($where === null{
  147.             if (!($where System::mktemp(array('-d')))) {
  148.                 return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: mktemp failed');
  149.             }
  150.         elseif (!@System::mkDir(array('-p'$where))) {
  151.             return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: "' $where '" could' .
  152.                 ' not be created');
  153.         }
  154.  
  155.         $file $where . DIRECTORY_SEPARATOR . 'package.xml';
  156.         if (file_exists($file&& !is_file($file)) {
  157.             return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: unable to save package.xml as' .
  158.                 ' "' $file  .'"');
  159.         }
  160.  
  161.         if (!$this->_packagefile->validate(PEAR_VALIDATE_PACKAGING)) {
  162.             return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: invalid package.xml');
  163.         }
  164.  
  165.         $ext $compress '.tgz' '.tar';
  166.         $pkgver $this->_packagefile->getPackage('-' $this->_packagefile->getVersion();
  167.         $dest_package getcwd(. DIRECTORY_SEPARATOR . $pkgver $ext;
  168.         if (file_exists($dest_package&& !is_file($dest_package)) {
  169.             return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: cannot create tgz file "' .
  170.                 $dest_package '"');
  171.         }
  172.  
  173.         $pkgfile $this->_packagefile->getPackageFile();
  174.         if (!$pkgfile{
  175.             return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: package file object must ' .
  176.                 'be created from a real file');
  177.         }
  178.  
  179.         $pkgdir  dirname(realpath($pkgfile));
  180.         $pkgfile basename($pkgfile);
  181.  
  182.         // {{{ Create the package file list
  183.         $filelist = array();
  184.         $i = 0;
  185.         $this->_packagefile->flattenFilelist();
  186.         $contents $this->_packagefile->getContents();
  187.         if (isset($contents['bundledpackage'])) // bundles of packages
  188.             $contents $contents['bundledpackage'];
  189.             if (!isset($contents[0])) {
  190.                 $contents = array($contents);
  191.             }
  192.  
  193.             $packageDir $where;
  194.             foreach ($contents as $i => $package{
  195.                 $fname $package;
  196.                 $file $pkgdir . DIRECTORY_SEPARATOR . $fname;
  197.                 if (!file_exists($file)) {
  198.                     return $packager->raiseError("File does not exist: $fname");
  199.                 }
  200.  
  201.                 $tfile $packageDir . DIRECTORY_SEPARATOR . $fname;
  202.                 System::mkdir(array('-p'dirname($tfile)));
  203.                 copy($file$tfile);
  204.                 $filelist[$i++$tfile;
  205.                 $packager->log(2"Adding package $fname");
  206.             }
  207.         else // normal packages
  208.             $contents $contents['dir']['file'];
  209.             if (!isset($contents[0])) {
  210.                 $contents = array($contents);
  211.             }
  212.  
  213.             $packageDir $where;
  214.             foreach ($contents as $i => $file{
  215.                 $fname $file['attribs']['name'];
  216.                 $atts $file['attribs'];
  217.                 $orig $file;
  218.                 $file $pkgdir . DIRECTORY_SEPARATOR . $fname;
  219.                 if (!file_exists($file)) {
  220.                     return $packager->raiseError("File does not exist: $fname");
  221.                 }
  222.  
  223.                 $origperms fileperms($file);
  224.                 $tfile $packageDir . DIRECTORY_SEPARATOR . $fname;
  225.                 unset($orig['attribs']);
  226.                 if (count($orig)) // file with tasks
  227.                     // run any package-time tasks
  228.                     $contents file_get_contents($file);
  229.                     foreach ($orig as $tag => $raw{
  230.                         $tag str_replace(
  231.                             array($this->_packagefile->getTasksNs(':''-'),
  232.                             array('''_')$tag);
  233.                         $task = "PEAR_Task_$tag";
  234.                         $task &new $task($this->_packagefile->_config,
  235.                             $this->_packagefile->_logger,
  236.                             PEAR_TASK_PACKAGE);
  237.                         $task->init($raw$attsnull);
  238.                         $res $task->startSession($this->_packagefile$contents$tfile);
  239.                         if (!$res{
  240.                             continue; // skip this task
  241.                         }
  242.  
  243.                         if (PEAR::isError($res)) {
  244.                             return $res;
  245.                         }
  246.  
  247.                         $contents $res// save changes
  248.                         System::mkdir(array('-p'dirname($tfile)));
  249.                         $wp fopen($tfile"wb");
  250.                         fwrite($wp$contents);
  251.                         fclose($wp);
  252.                     }
  253.                 }
  254.  
  255.                 if (!file_exists($tfile)) {
  256.                     System::mkdir(array('-p'dirname($tfile)));
  257.                     copy($file$tfile);
  258.                 }
  259.  
  260.                 chmod($tfile$origperms);
  261.                 $filelist[$i++$tfile;
  262.                 $this->_packagefile->setFileAttribute($fname'md5sum'md5_file($tfile)$i - 1);
  263.                 $packager->log(2"Adding file $fname");
  264.             }
  265.         }
  266.             // }}}
  267.  
  268.         $name       $pf1 !== null ? 'package2.xml' 'package.xml';
  269.         $packagexml $this->toPackageFile($wherePEAR_VALIDATE_PACKAGING$name);
  270.         if ($packagexml{
  271.             $tar =new Archive_Tar($dest_package$compress);
  272.             $tar->setErrorHandling(PEAR_ERROR_RETURN)// XXX Don't print errors
  273.             // ----- Creates with the package.xml file
  274.             $ok $tar->createModify(array($packagexml)''$where);
  275.             if (PEAR::isError($ok)) {
  276.                 return $packager->raiseError($ok);
  277.             elseif (!$ok{
  278.                 return $packager->raiseError('PEAR_Packagefile_v2::toTgz(): adding ' $name .
  279.                     ' failed');
  280.             }
  281.  
  282.             // ----- Add the content of the package
  283.             if (!$tar->addModify($filelist$pkgver$where)) {
  284.                 return $packager->raiseError(
  285.                     'PEAR_Packagefile_v2::toTgz(): tarball creation failed');
  286.             }
  287.  
  288.             // add the package.xml version 1.0
  289.             if ($pf1 !== null{
  290.                 $pfgen &$pf1->getDefaultGenerator();
  291.                 $packagexml1 $pfgen->toPackageFile($wherePEAR_VALIDATE_PACKAGING'package.xml'true);
  292.                 if (!$tar->addModify(array($packagexml1)''$where)) {
  293.                     return $packager->raiseError(
  294.                         'PEAR_Packagefile_v2::toTgz(): adding package.xml failed');
  295.                 }
  296.             }
  297.  
  298.             return $dest_package;
  299.         }
  300.     }
  301.  
  302.     function toPackageFile($where = null$state = PEAR_VALIDATE_NORMAL$name 'package.xml')
  303.     {
  304.         if (!$this->_packagefile->validate($state)) {
  305.             return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: invalid package.xml',
  306.                 nullnullnull$this->_packagefile->getValidationWarnings());
  307.         }
  308.  
  309.         if ($where === null{
  310.             if (!($where System::mktemp(array('-d')))) {
  311.                 return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: mktemp failed');
  312.             }
  313.         elseif (!@System::mkDir(array('-p'$where))) {
  314.             return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: "' $where '" could' .
  315.                 ' not be created');
  316.         }
  317.  
  318.         $newpkgfile $where . DIRECTORY_SEPARATOR . $name;
  319.         $np @fopen($newpkgfile'wb');
  320.         if (!$np{
  321.             return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: unable to save ' .
  322.                "$name as $newpkgfile");
  323.         }
  324.         fwrite($np$this->toXml($state));
  325.         fclose($np);
  326.         return $newpkgfile;
  327.     }
  328.  
  329.     function &toV2()
  330.     {
  331.         return $this->_packagefile;
  332.     }
  333.  
  334.     /**
  335.      * Return an XML document based on the package info (as returned
  336.      * by the PEAR_Common::infoFrom* methods).
  337.      *
  338.      * @return string XML data
  339.      */
  340.     function toXml($state = PEAR_VALIDATE_NORMAL$options = array())
  341.     {
  342.         $this->_packagefile->setDate(date('Y-m-d'));
  343.         $this->_packagefile->setTime(date('H:i:s'));
  344.         if (!$this->_packagefile->validate($state)) {
  345.             return false;
  346.         }
  347.  
  348.         if (is_array($options)) {
  349.             $this->options array_merge($this->_defaultOptions$options);
  350.         else {
  351.             $this->options $this->_defaultOptions;
  352.         }
  353.  
  354.         $arr $this->_packagefile->getArray();
  355.         if (isset($arr['filelist'])) {
  356.             unset($arr['filelist']);
  357.         }
  358.  
  359.         if (isset($arr['_lastversion'])) {
  360.             unset($arr['_lastversion']);
  361.         }
  362.  
  363.         // Fix the notes a little bit
  364.         if (isset($arr['notes'])) {
  365.             // This trims out the indenting, needs fixing
  366.             $arr['notes'"\n" trim($arr['notes']"\n";
  367.         }
  368.  
  369.         if (isset($arr['changelog']&& !empty($arr['changelog'])) {
  370.             // Fix for inconsistency how the array is filled depending on the changelog release amount
  371.             if (!isset($arr['changelog']['release'][0])) {
  372.                 $release $arr['changelog']['release'];
  373.                 unset($arr['changelog']['release']);
  374.  
  375.                 $arr['changelog']['release']    = array();
  376.                 $arr['changelog']['release'][0$release;
  377.             }
  378.  
  379.             foreach (array_keys($arr['changelog']['release']as $key{
  380.                 $c =$arr['changelog']['release'][$key];
  381.                 if (isset($c['notes'])) {
  382.                     // This trims out the indenting, needs fixing
  383.                     $c['notes'"\n" trim($c['notes']"\n";
  384.                 }
  385.             }
  386.         }
  387.  
  388.         if ($state PEAR_VALIDATE_PACKAGING && !isset($arr['bundle'])) {
  389.             $use $this->_recursiveXmlFilelist($arr['contents']['dir']['file']);
  390.             unset($arr['contents']['dir']['file']);
  391.             if (isset($use['dir'])) {
  392.                 $arr['contents']['dir']['dir'$use['dir'];
  393.             }
  394.             if (isset($use['file'])) {
  395.                 $arr['contents']['dir']['file'$use['file'];
  396.             }
  397.             $this->options['beautifyFilelist'= true;
  398.         }
  399.  
  400.         $arr['attribs']['packagerversion''1.9.4';
  401.         if ($this->serialize($arr$options)) {
  402.             return $this->_serializedData "\n";
  403.         }
  404.  
  405.         return false;
  406.     }
  407.  
  408.  
  409.     function _recursiveXmlFilelist($list)
  410.     {
  411.         $dirs = array();
  412.         if (isset($list['attribs'])) {
  413.             $file $list['attribs']['name'];
  414.             unset($list['attribs']['name']);
  415.             $attributes $list['attribs'];
  416.             $this->_addDir($dirsexplode('/'dirname($file))$file$attributes);
  417.         else {
  418.             foreach ($list as $a{
  419.                 $file $a['attribs']['name'];
  420.                 $attributes $a['attribs'];
  421.                 unset($a['attribs']);
  422.                 $this->_addDir($dirsexplode('/'dirname($file))$file$attributes$a);
  423.             }
  424.         }
  425.         $this->_formatDir($dirs);
  426.         $this->_deFormat($dirs);
  427.         return $dirs;
  428.     }
  429.  
  430.     function _addDir(&$dirs$dir$file = null$attributes = null$tasks = null)
  431.     {
  432.         if (!$tasks{
  433.             $tasks = array();
  434.         }
  435.         if ($dir == array(|| $dir == array('.')) {
  436.             $dirs['file'][basename($file)$tasks;
  437.             $attributes['name'basename($file);
  438.             $dirs['file'][basename($file)]['attribs'$attributes;
  439.             return;
  440.         }
  441.         $curdir array_shift($dir);
  442.         if (!isset($dirs['dir'][$curdir])) {
  443.             $dirs['dir'][$curdir= array();
  444.         }
  445.         $this->_addDir($dirs['dir'][$curdir]$dir$file$attributes$tasks);
  446.     }
  447.  
  448.     function _formatDir(&$dirs)
  449.     {
  450.         if (!count($dirs)) {
  451.             return array();
  452.         }
  453.         $newdirs = array();
  454.         if (isset($dirs['dir'])) {
  455.             $newdirs['dir'$dirs['dir'];
  456.         }
  457.         if (isset($dirs['file'])) {
  458.             $newdirs['file'$dirs['file'];
  459.         }
  460.         $dirs $newdirs;
  461.         if (isset($dirs['dir'])) {
  462.             uksort($dirs['dir']'strnatcasecmp');
  463.             foreach ($dirs['dir'as $dir => $contents{
  464.                 $this->_formatDir($dirs['dir'][$dir]);
  465.             }
  466.         }
  467.         if (isset($dirs['file'])) {
  468.             uksort($dirs['file']'strnatcasecmp');
  469.         };
  470.     }
  471.  
  472.     function _deFormat(&$dirs)
  473.     {
  474.         if (!count($dirs)) {
  475.             return array();
  476.         }
  477.         $newdirs = array();
  478.         if (isset($dirs['dir'])) {
  479.             foreach ($dirs['dir'as $dir => $contents{
  480.                 $newdir = array();
  481.                 $newdir['attribs']['name'$dir;
  482.                 $this->_deFormat($contents);
  483.                 foreach ($contents as $tag => $val{
  484.                     $newdir[$tag$val;
  485.                 }
  486.                 $newdirs['dir'][$newdir;
  487.             }
  488.             if (count($newdirs['dir']== 1{
  489.                 $newdirs['dir'$newdirs['dir'][0];
  490.             }
  491.         }
  492.         if (isset($dirs['file'])) {
  493.             foreach ($dirs['file'as $name => $file{
  494.                 $newdirs['file'][$file;
  495.             }
  496.             if (count($newdirs['file']== 1{
  497.                 $newdirs['file'$newdirs['file'][0];
  498.             }
  499.         }
  500.         $dirs $newdirs;
  501.     }
  502.  
  503.     /**
  504.     * reset all options to default options
  505.     *
  506.     * @access   public
  507.     * @see      setOption(), XML_Unserializer()
  508.     */
  509.     function resetOptions()
  510.     {
  511.         $this->options $this->_defaultOptions;
  512.     }
  513.  
  514.    /**
  515.     * set an option
  516.     *
  517.     * You can use this method if you do not want to set all options in the constructor
  518.     *
  519.     * @access   public
  520.     * @see      resetOption(), XML_Serializer()
  521.     */
  522.     function setOption($name$value)
  523.     {
  524.         $this->options[$name$value;
  525.     }
  526.  
  527.    /**
  528.     * sets several options at once
  529.     *
  530.     * You can use this method if you do not want to set all options in the constructor
  531.     *
  532.     * @access   public
  533.     * @see      resetOption(), XML_Unserializer(), setOption()
  534.     */
  535.     function setOptions($options)
  536.     {
  537.         $this->options array_merge($this->options$options);
  538.     }
  539.  
  540.    /**
  541.     * serialize data
  542.     *
  543.     * @access   public
  544.     * @param    mixed    $data data to serialize
  545.     * @return   boolean  true on success, pear error on failure
  546.     */
  547.     function serialize($data$options = null)
  548.     {
  549.         // if options have been specified, use them instead
  550.         // of the previously defined ones
  551.         if (is_array($options)) {
  552.             $optionsBak $this->options;
  553.             if (isset($options['overrideOptions']&& $options['overrideOptions'== true{
  554.                 $this->options array_merge($this->_defaultOptions$options);
  555.             else {
  556.                 $this->options array_merge($this->options$options);
  557.             }
  558.         else {
  559.             $optionsBak = null;
  560.         }
  561.  
  562.         //  start depth is zero
  563.         $this->_tagDepth = 0;
  564.         $this->_serializedData '';
  565.         // serialize an array
  566.         if (is_array($data)) {
  567.             $tagName = isset($this->options['rootName']$this->options['rootName''array';
  568.             $this->_serializedData .= $this->_serializeArray($data$tagName$this->options['rootAttributes']);
  569.         }
  570.  
  571.         // add doctype declaration
  572.         if ($this->options['addDoctype'=== true{
  573.             $this->_serializedData = XML_Util::getDoctypeDeclaration($tagName$this->options['doctype'])
  574.                                    . $this->options['linebreak']
  575.                                    . $this->_serializedData;
  576.         }
  577.  
  578.         //  build xml declaration
  579.         if ($this->options['addDecl']{
  580.             $atts = array();
  581.             $encoding = isset($this->options['encoding']$this->options['encoding': null;
  582.             $this->_serializedData = XML_Util::getXMLDeclaration('1.0'$encoding)
  583.                                    . $this->options['linebreak']
  584.                                    . $this->_serializedData;
  585.         }
  586.  
  587.  
  588.         if ($optionsBak !== null{
  589.             $this->options $optionsBak;
  590.         }
  591.  
  592.         return  true;
  593.     }
  594.  
  595.    /**
  596.     * get the result of the serialization
  597.     *
  598.     * @access public
  599.     * @return string serialized XML
  600.     */
  601.     function getSerializedData()
  602.     {
  603.         if ($this->_serializedData === null{
  604.             return  $this->raiseError('No serialized data available. Use XML_Serializer::serialize() first.'XML_SERIALIZER_ERROR_NO_SERIALIZATION);
  605.         }
  606.         return $this->_serializedData;
  607.     }
  608.  
  609.    /**
  610.     * serialize any value
  611.     *
  612.     * This method checks for the type of the value and calls the appropriate method
  613.     *
  614.     * @access private
  615.     * @param  mixed     $value 
  616.     * @param  string    $tagName 
  617.     * @param  array     $attributes 
  618.     * @return string 
  619.     */
  620.     function _serializeValue($value$tagName = null$attributes = array())
  621.     {
  622.         if (is_array($value)) {
  623.             $xml $this->_serializeArray($value$tagName$attributes);
  624.         elseif (is_object($value)) {
  625.             $xml $this->_serializeObject($value$tagName);
  626.         else {
  627.             $tag = array(
  628.                           'qname'      => $tagName,
  629.                           'attributes' => $attributes,
  630.                           'content'    => $value
  631.                         );
  632.             $xml $this->_createXMLTag($tag);
  633.         }
  634.         return $xml;
  635.     }
  636.  
  637.    /**
  638.     * serialize an array
  639.     *
  640.     * @access   private
  641.     * @param    array   $array       array to serialize
  642.     * @param    string  $tagName     name of the root tag
  643.     * @param    array   $attributes  attributes for the root tag
  644.     * @return   string  $string      serialized data
  645.     * @uses     XML_Util::isValidName() to check, whether key has to be substituted
  646.     */
  647.     function _serializeArray(&$array$tagName = null$attributes = array())
  648.     {
  649.         $_content = null;
  650.  
  651.         /**
  652.          * check for special attributes
  653.          */
  654.         if ($this->options['attributesArray'!== null{
  655.             if (isset($array[$this->options['attributesArray']])) {
  656.                 $attributes $array[$this->options['attributesArray']];
  657.                 unset($array[$this->options['attributesArray']]);
  658.             }
  659.             /**
  660.              * check for special content
  661.              */
  662.             if ($this->options['contentName'!== null{
  663.                 if (isset($array[$this->options['contentName']])) {
  664.                     $_content $array[$this->options['contentName']];
  665.                     unset($array[$this->options['contentName']]);
  666.                 }
  667.             }
  668.         }
  669.  
  670.         /*
  671.         * if mode is set to simpleXML, check whether
  672.         * the array is associative or indexed
  673.         */
  674.         if (is_array($array&& $this->options['mode'== 'simplexml'{
  675.             $indexed = true;
  676.             if (!count($array)) {
  677.                 $indexed = false;
  678.             }
  679.             foreach ($array as $key => $val{
  680.                 if (!is_int($key)) {
  681.                     $indexed = false;
  682.                     break;
  683.                 }
  684.             }
  685.  
  686.             if ($indexed && $this->options['mode'== 'simplexml'{
  687.                 $string '';
  688.                 foreach ($array as $key => $val{
  689.                     if ($this->options['beautifyFilelist'&& $tagName == 'dir'{
  690.                         if (!isset($this->_curdir)) {
  691.                             $this->_curdir '';
  692.                         }
  693.                         $savedir $this->_curdir;
  694.                         if (isset($val['attribs'])) {
  695.                             if ($val['attribs']['name'== '/'{
  696.                                 $this->_curdir '/';
  697.                             else {
  698.                                 if ($this->_curdir == '/'{
  699.                                     $this->_curdir '';
  700.                                 }
  701.                                 $this->_curdir .= '/' $val['attribs']['name'];
  702.                             }
  703.                         }
  704.                     }
  705.                     $string .= $this->_serializeValue$val$tagName$attributes);
  706.                     if ($this->options['beautifyFilelist'&& $tagName == 'dir'{
  707.                         $string .= ' <!-- ' $this->_curdir ' -->';
  708.                         if (empty($savedir)) {
  709.                             unset($this->_curdir);
  710.                         else {
  711.                             $this->_curdir $savedir;
  712.                         }
  713.                     }
  714.  
  715.                     $string .= $this->options['linebreak'];
  716.                     // do indentation
  717.                     if ($this->options['indent'!== null && $this->_tagDepth > 0{
  718.                         $string .= str_repeat($this->options['indent']$this->_tagDepth);
  719.                     }
  720.                 }
  721.                 return rtrim($string);
  722.             }
  723.         }
  724.  
  725.         if ($this->options['scalarAsAttributes'=== true{
  726.             foreach ($array as $key => $value{
  727.                 if (is_scalar($value&& (XML_Util::isValidName($key=== true)) {
  728.                     unset($array[$key]);
  729.                     $attributes[$this->options['prependAttributes'].$key$value;
  730.                 }
  731.             }
  732.         }
  733.  
  734.         // check for empty array => create empty tag
  735.         if (empty($array)) {
  736.             $tag = array(
  737.                             'qname'      => $tagName,
  738.                             'content'    => $_content,
  739.                             'attributes' => $attributes
  740.                         );
  741.  
  742.         else {
  743.             $this->_tagDepth++;
  744.             $tmp $this->options['linebreak'];
  745.             foreach ($array as $key => $value{
  746.                 // do indentation
  747.                 if ($this->options['indent'!== null && $this->_tagDepth > 0{
  748.                     $tmp .= str_repeat($this->options['indent']$this->_tagDepth);
  749.                 }
  750.  
  751.                 // copy key
  752.                 $origKey $key;
  753.                 // key cannot be used as tagname => use default tag
  754.                 $valid = XML_Util::isValidName($key);
  755.                 if (PEAR::isError($valid)) {
  756.                     if ($this->options['classAsTagName'&& is_object($value)) {
  757.                         $key get_class($value);
  758.                     else {
  759.                         $key $this->options['defaultTagName'];
  760.                     }
  761.                 }
  762.                 $atts = array();
  763.                 if ($this->options['typeHints'=== true{
  764.                     $atts[$this->options['typeAttribute']] gettype($value);
  765.                     if ($key !== $origKey{
  766.                         $atts[$this->options['keyAttribute']] = (string)$origKey;
  767.                     }
  768.  
  769.                 }
  770.                 if ($this->options['beautifyFilelist'&& $key == 'dir'{
  771.                     if (!isset($this->_curdir)) {
  772.                         $this->_curdir '';
  773.                     }
  774.                     $savedir $this->_curdir;
  775.                     if (isset($value['attribs'])) {
  776.                         if ($value['attribs']['name'== '/'{
  777.                             $this->_curdir '/';
  778.                         else {
  779.                             $this->_curdir .= '/' $value['attribs']['name'];
  780.                         }
  781.                     }
  782.                 }
  783.  
  784.                 if (is_string($value&& $value && ($value{strlen($value- 1== "\n")) {
  785.                     $value .= str_repeat($this->options['indent']$this->_tagDepth);
  786.                 }
  787.                 $tmp .= $this->_createXMLTag(array(
  788.                                                     'qname'      => $key,
  789.                                                     'attributes' => $atts,
  790.                                                     'content'    => $value )
  791.                                             );
  792.                 if ($this->options['beautifyFilelist'&& $key == 'dir'{
  793.                     if (isset($value['attribs'])) {
  794.                         $tmp .= ' <!-- ' $this->_curdir ' -->';
  795.                         if (empty($savedir)) {
  796.                             unset($this->_curdir);
  797.                         else {
  798.                             $this->_curdir $savedir;
  799.                         }
  800.                     }
  801.                 }
  802.                 $tmp .= $this->options['linebreak'];
  803.             }
  804.  
  805.             $this->_tagDepth--;
  806.             if ($this->options['indent']!==null && $this->_tagDepth>0{
  807.                 $tmp .= str_repeat($this->options['indent']$this->_tagDepth);
  808.             }
  809.  
  810.             if (trim($tmp=== ''{
  811.                 $tmp = null;
  812.             }
  813.  
  814.             $tag = array(
  815.                 'qname'      => $tagName,
  816.                 'content'    => $tmp,
  817.                 'attributes' => $attributes
  818.             );
  819.         }
  820.         if ($this->options['typeHints'=== true{
  821.             if (!isset($tag['attributes'][$this->options['typeAttribute']])) {
  822.                 $tag['attributes'][$this->options['typeAttribute']] 'array';
  823.             }
  824.         }
  825.  
  826.         $string $this->_createXMLTag($tagfalse);
  827.         return $string;
  828.     }
  829.  
  830.    /**
  831.     * create a tag from an array
  832.     * this method awaits an array in the following format
  833.     * array(
  834.     *       'qname'        => $tagName,
  835.     *       'attributes'   => array(),
  836.     *       'content'      => $content,      // optional
  837.     *       'namespace'    => $namespace     // optional
  838.     *       'namespaceUri' => $namespaceUri  // optional
  839.     *   )
  840.     *
  841.     * @access   private
  842.     * @param    array   $tag tag definition
  843.     * @param    boolean $replaceEntities whether to replace XML entities in content or not
  844.     * @return   string  $string XML tag
  845.     */
  846.     function _createXMLTag($tag$replaceEntities = true)
  847.     {
  848.         if ($this->options['indentAttributes'!== false{
  849.             $multiline = true;
  850.             $indent    str_repeat($this->options['indent']$this->_tagDepth);
  851.  
  852.             if ($this->options['indentAttributes'== '_auto'{
  853.                 $indent .= str_repeat(' '(strlen($tag['qname'])+2));
  854.  
  855.             else {
  856.                 $indent .= $this->options['indentAttributes'];
  857.             }
  858.         else {
  859.             $indent $multiline = false;
  860.         }
  861.  
  862.         if (is_array($tag['content'])) {
  863.             if (empty($tag['content'])) {
  864.                 $tag['content''';
  865.             }
  866.         elseif(is_scalar($tag['content']&& (string)$tag['content'== ''{
  867.             $tag['content''';
  868.         }
  869.  
  870.         if (is_scalar($tag['content']|| is_null($tag['content'])) {
  871.             if ($this->options['encoding'== 'UTF-8' &&
  872.                   version_compare(phpversion()'5.0.0''lt')
  873.             {
  874.                 $tag['content'utf8_encode($tag['content']);
  875.             }
  876.  
  877.             if ($replaceEntities === true{
  878.                 $replaceEntities = XML_UTIL_ENTITIES_XML;
  879.             }
  880.  
  881.             $tag = XML_Util::createTagFromArray($tag$replaceEntities$multiline$indent$this->options['linebreak']);
  882.         elseif (is_array($tag['content'])) {
  883.             $tag $this->_serializeArray($tag['content']$tag['qname']$tag['attributes']);
  884.         elseif (is_object($tag['content'])) {
  885.             $tag $this->_serializeObject($tag['content']$tag['qname']$tag['attributes']);
  886.         elseif (is_resource($tag['content'])) {
  887.             settype($tag['content']'string');
  888.             $tag = XML_Util::createTagFromArray($tag$replaceEntities);
  889.         }
  890.         return  $tag;
  891.     }
  892. }

Documentation generated on Wed, 06 Jul 2011 23:31:34 +0000 by phpDocumentor 1.4.3. PEAR Logo Copyright © PHP Group 2004.