home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / tmp / PEAR-1.7.1 / PEAR / PackageFile / Parser / v1.php next >
Encoding:
PHP Script  |  2008-02-15  |  16.6 KB  |  465 lines

  1. <?php
  2. /**
  3.  * package.xml parsing class, package.xml version 1.0
  4.  *
  5.  * PHP versions 4 and 5
  6.  *
  7.  * LICENSE: This source file is subject to version 3.0 of the PHP license
  8.  * that is available through the world-wide-web at the following URI:
  9.  * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
  10.  * the PHP License and are unable to obtain it through the web, please
  11.  * send a note to license@php.net so we can mail you a copy immediately.
  12.  *
  13.  * @category   pear
  14.  * @package    PEAR
  15.  * @author     Greg Beaver <cellog@php.net>
  16.  * @copyright  1997-2008 The PHP Group
  17.  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  18.  * @version    CVS: $Id: v1.php,v 1.27 2008/01/03 20:55:16 cellog Exp $
  19.  * @link       http://pear.php.net/package/PEAR
  20.  * @since      File available since Release 1.4.0a1
  21.  */
  22. /**
  23.  * package.xml abstraction class
  24.  */
  25. require_once 'PEAR/PackageFile/v1.php';
  26. /**
  27.  * Parser for package.xml version 1.0
  28.  * @category   pear
  29.  * @package    PEAR
  30.  * @author     Greg Beaver <cellog@php.net>
  31.  * @copyright  1997-2008 The PHP Group
  32.  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  33.  * @version    Release: @PEAR-VER@
  34.  * @link       http://pear.php.net/package/PEAR
  35.  * @since      Class available since Release 1.4.0a1
  36.  */
  37. class PEAR_PackageFile_Parser_v1
  38. {
  39.     var $_registry;
  40.     var $_config;
  41.     var $_logger;
  42.     /**
  43.      * BC hack to allow PEAR_Common::infoFromString() to sort of
  44.      * work with the version 2.0 format - there's no filelist though
  45.      * @param PEAR_PackageFile_v2
  46.      */
  47.     function fromV2($packagefile)
  48.     {
  49.         $info = $packagefile->getArray(true);
  50.         $ret = new PEAR_PackageFile_v1;
  51.         $ret->fromArray($info['old']);
  52.     }
  53.  
  54.     function setConfig(&$c)
  55.     {
  56.         $this->_config = &$c;
  57.         $this->_registry = &$c->getRegistry();
  58.     }
  59.  
  60.     function setLogger(&$l)
  61.     {
  62.         $this->_logger = &$l;
  63.     }
  64.  
  65.     /**
  66.      * @param string contents of package.xml file, version 1.0
  67.      * @return bool success of parsing
  68.      */
  69.     function &parse($data, $file, $archive = false)
  70.     {
  71.         if (!extension_loaded('xml')) {
  72.             return PEAR::raiseError('Cannot create xml parser for parsing package.xml, no xml extension');
  73.         }
  74.         $xp = xml_parser_create();
  75.         if (!$xp) {
  76.             $a = &PEAR::raiseError('Cannot create xml parser for parsing package.xml');
  77.             return $a;
  78.         }
  79.         xml_set_object($xp, $this);
  80.         xml_set_element_handler($xp, '_element_start_1_0', '_element_end_1_0');
  81.         xml_set_character_data_handler($xp, '_pkginfo_cdata_1_0');
  82.         xml_parser_set_option($xp, XML_OPTION_CASE_FOLDING, false);
  83.  
  84.         $this->element_stack = array();
  85.         $this->_packageInfo = array('provides' => array());
  86.         $this->current_element = false;
  87.         unset($this->dir_install);
  88.         $this->_packageInfo['filelist'] = array();
  89.         $this->filelist =& $this->_packageInfo['filelist'];
  90.         $this->dir_names = array();
  91.         $this->in_changelog = false;
  92.         $this->d_i = 0;
  93.         $this->cdata = '';
  94.         $this->_isValid = true;
  95.  
  96.         if (!xml_parse($xp, $data, 1)) {
  97.             $code = xml_get_error_code($xp);
  98.             $line = xml_get_current_line_number($xp);
  99.             xml_parser_free($xp);
  100.             $a = &PEAR::raiseError(sprintf("XML error: %s at line %d",
  101.                            $str = xml_error_string($code), $line), 2);
  102.             return $a;
  103.         }
  104.  
  105.         xml_parser_free($xp);
  106.  
  107.         $pf = new PEAR_PackageFile_v1;
  108.         $pf->setConfig($this->_config);
  109.         if (isset($this->_logger)) {
  110.             $pf->setLogger($this->_logger);
  111.         }
  112.         $pf->setPackagefile($file, $archive);
  113.         $pf->fromArray($this->_packageInfo);
  114.         return $pf;
  115.     }
  116.     // {{{ _unIndent()
  117.  
  118.     /**
  119.      * Unindent given string
  120.      *
  121.      * @param string $str The string that has to be unindented.
  122.      * @return string
  123.      * @access private
  124.      */
  125.     function _unIndent($str)
  126.     {
  127.         // remove leading newlines
  128.         $str = preg_replace('/^[\r\n]+/', '', $str);
  129.         // find whitespace at the beginning of the first line
  130.         $indent_len = strspn($str, " \t");
  131.         $indent = substr($str, 0, $indent_len);
  132.         $data = '';
  133.         // remove the same amount of whitespace from following lines
  134.         foreach (explode("\n", $str) as $line) {
  135.             if (substr($line, 0, $indent_len) == $indent) {
  136.                 $data .= substr($line, $indent_len) . "\n";
  137.             } elseif (trim(substr($line, 0, $indent_len))) {
  138.                 $data .= ltrim($line);
  139.             }
  140.         }
  141.         return $data;
  142.     }
  143.  
  144.     // Support for package DTD v1.0:
  145.     // {{{ _element_start_1_0()
  146.  
  147.     /**
  148.      * XML parser callback for ending elements.  Used for version 1.0
  149.      * packages.
  150.      *
  151.      * @param resource  $xp    XML parser resource
  152.      * @param string    $name  name of ending element
  153.      *
  154.      * @return void
  155.      *
  156.      * @access private
  157.      */
  158.     function _element_start_1_0($xp, $name, $attribs)
  159.     {
  160.         array_push($this->element_stack, $name);
  161.         $this->current_element = $name;
  162.         $spos = sizeof($this->element_stack) - 2;
  163.         $this->prev_element = ($spos >= 0) ? $this->element_stack[$spos] : '';
  164.         $this->current_attributes = $attribs;
  165.         $this->cdata = '';
  166.         switch ($name) {
  167.             case 'dir':
  168.                 if ($this->in_changelog) {
  169.                     break;
  170.                 }
  171.                 if (array_key_exists('name', $attribs) && $attribs['name'] != '/') {
  172.                     $attribs['name'] = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'),
  173.                         $attribs['name']);
  174.                     if (strrpos($attribs['name'], '/') === strlen($attribs['name']) - 1) {
  175.                         $attribs['name'] = substr($attribs['name'], 0,
  176.                             strlen($attribs['name']) - 1);
  177.                     }
  178.                     if (strpos($attribs['name'], '/') === 0) {
  179.                         $attribs['name'] = substr($attribs['name'], 1);
  180.                     }
  181.                     $this->dir_names[] = $attribs['name'];
  182.                 }
  183.                 if (isset($attribs['baseinstalldir'])) {
  184.                     $this->dir_install = $attribs['baseinstalldir'];
  185.                 }
  186.                 if (isset($attribs['role'])) {
  187.                     $this->dir_role = $attribs['role'];
  188.                 }
  189.                 break;
  190.             case 'file':
  191.                 if ($this->in_changelog) {
  192.                     break;
  193.                 }
  194.                 if (isset($attribs['name'])) {
  195.                     $path = '';
  196.                     if (count($this->dir_names)) {
  197.                         foreach ($this->dir_names as $dir) {
  198.                             $path .= $dir . '/';
  199.                         }
  200.                     }
  201.                     $path .= preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'),
  202.                         $attribs['name']);
  203.                     unset($attribs['name']);
  204.                     $this->current_path = $path;
  205.                     $this->filelist[$path] = $attribs;
  206.                     // Set the baseinstalldir only if the file don't have this attrib
  207.                     if (!isset($this->filelist[$path]['baseinstalldir']) &&
  208.                         isset($this->dir_install))
  209.                     {
  210.                         $this->filelist[$path]['baseinstalldir'] = $this->dir_install;
  211.                     }
  212.                     // Set the Role
  213.                     if (!isset($this->filelist[$path]['role']) && isset($this->dir_role)) {
  214.                         $this->filelist[$path]['role'] = $this->dir_role;
  215.                     }
  216.                 }
  217.                 break;
  218.             case 'replace':
  219.                 if (!$this->in_changelog) {
  220.                     $this->filelist[$this->current_path]['replacements'][] = $attribs;
  221.                 }
  222.                 break;
  223.             case 'maintainers':
  224.                 $this->_packageInfo['maintainers'] = array();
  225.                 $this->m_i = 0; // maintainers array index
  226.                 break;
  227.             case 'maintainer':
  228.                 // compatibility check
  229.                 if (!isset($this->_packageInfo['maintainers'])) {
  230.                     $this->_packageInfo['maintainers'] = array();
  231.                     $this->m_i = 0;
  232.                 }
  233.                 $this->_packageInfo['maintainers'][$this->m_i] = array();
  234.                 $this->current_maintainer =& $this->_packageInfo['maintainers'][$this->m_i];
  235.                 break;
  236.             case 'changelog':
  237.                 $this->_packageInfo['changelog'] = array();
  238.                 $this->c_i = 0; // changelog array index
  239.                 $this->in_changelog = true;
  240.                 break;
  241.             case 'release':
  242.                 if ($this->in_changelog) {
  243.                     $this->_packageInfo['changelog'][$this->c_i] = array();
  244.                     $this->current_release = &$this->_packageInfo['changelog'][$this->c_i];
  245.                 } else {
  246.                     $this->current_release = &$this->_packageInfo;
  247.                 }
  248.                 break;
  249.             case 'deps':
  250.                 if (!$this->in_changelog) {
  251.                     $this->_packageInfo['release_deps'] = array();
  252.                 }
  253.                 break;
  254.             case 'dep':
  255.                 // dependencies array index
  256.                 if (!$this->in_changelog) {
  257.                     $this->d_i++;
  258.                     isset($attribs['type']) ? ($attribs['type'] = strtolower($attribs['type'])) : false;
  259.                     $this->_packageInfo['release_deps'][$this->d_i] = $attribs;
  260.                 }
  261.                 break;
  262.             case 'configureoptions':
  263.                 if (!$this->in_changelog) {
  264.                     $this->_packageInfo['configure_options'] = array();
  265.                 }
  266.                 break;
  267.             case 'configureoption':
  268.                 if (!$this->in_changelog) {
  269.                     $this->_packageInfo['configure_options'][] = $attribs;
  270.                 }
  271.                 break;
  272.             case 'provides':
  273.                 if (empty($attribs['type']) || empty($attribs['name'])) {
  274.                     break;
  275.                 }
  276.                 $attribs['explicit'] = true;
  277.                 $this->_packageInfo['provides']["$attribs[type];$attribs[name]"] = $attribs;
  278.                 break;
  279.             case 'package' :
  280.                 if (isset($attribs['version'])) {
  281.                     $this->_packageInfo['xsdversion'] = trim($attribs['version']);
  282.                 } else {
  283.                     $this->_packageInfo['xsdversion'] = '1.0';
  284.                 }
  285.                 if (isset($attribs['packagerversion'])) {
  286.                     $this->_packageInfo['packagerversion'] = $attribs['packagerversion'];
  287.                 }
  288.                 break;
  289.         }
  290.     }
  291.  
  292.     // }}}
  293.     // {{{ _element_end_1_0()
  294.  
  295.     /**
  296.      * XML parser callback for ending elements.  Used for version 1.0
  297.      * packages.
  298.      *
  299.      * @param resource  $xp    XML parser resource
  300.      * @param string    $name  name of ending element
  301.      *
  302.      * @return void
  303.      *
  304.      * @access private
  305.      */
  306.     function _element_end_1_0($xp, $name)
  307.     {
  308.         $data = trim($this->cdata);
  309.         switch ($name) {
  310.             case 'name':
  311.                 switch ($this->prev_element) {
  312.                     case 'package':
  313.                         $this->_packageInfo['package'] = $data;
  314.                         break;
  315.                     case 'maintainer':
  316.                         $this->current_maintainer['name'] = $data;
  317.                         break;
  318.                 }
  319.                 break;
  320.             case 'extends' :
  321.                 $this->_packageInfo['extends'] = $data;
  322.                 break;
  323.             case 'summary':
  324.                 $this->_packageInfo['summary'] = $data;
  325.                 break;
  326.             case 'description':
  327.                 $data = $this->_unIndent($this->cdata);
  328.                 $this->_packageInfo['description'] = $data;
  329.                 break;
  330.             case 'user':
  331.                 $this->current_maintainer['handle'] = $data;
  332.                 break;
  333.             case 'email':
  334.                 $this->current_maintainer['email'] = $data;
  335.                 break;
  336.             case 'role':
  337.                 $this->current_maintainer['role'] = $data;
  338.                 break;
  339.             case 'version':
  340.                 //$data = ereg_replace ('[^a-zA-Z0-9._\-]', '_', $data);
  341.                 if ($this->in_changelog) {
  342.                     $this->current_release['version'] = $data;
  343.                 } else {
  344.                     $this->_packageInfo['version'] = $data;
  345.                 }
  346.                 break;
  347.             case 'date':
  348.                 if ($this->in_changelog) {
  349.                     $this->current_release['release_date'] = $data;
  350.                 } else {
  351.                     $this->_packageInfo['release_date'] = $data;
  352.                 }
  353.                 break;
  354.             case 'notes':
  355.                 // try to "de-indent" release notes in case someone
  356.                 // has been over-indenting their xml ;-)
  357.                 $data = $this->_unIndent($this->cdata);
  358.                 if ($this->in_changelog) {
  359.                     $this->current_release['release_notes'] = $data;
  360.                 } else {
  361.                     $this->_packageInfo['release_notes'] = $data;
  362.                 }
  363.                 break;
  364.             case 'warnings':
  365.                 if ($this->in_changelog) {
  366.                     $this->current_release['release_warnings'] = $data;
  367.                 } else {
  368.                     $this->_packageInfo['release_warnings'] = $data;
  369.                 }
  370.                 break;
  371.             case 'state':
  372.                 if ($this->in_changelog) {
  373.                     $this->current_release['release_state'] = $data;
  374.                 } else {
  375.                     $this->_packageInfo['release_state'] = $data;
  376.                 }
  377.                 break;
  378.             case 'license':
  379.                 if ($this->in_changelog) {
  380.                     $this->current_release['release_license'] = $data;
  381.                 } else {
  382.                     $this->_packageInfo['release_license'] = $data;
  383.                 }
  384.                 break;
  385.             case 'dep':
  386.                 if ($data && !$this->in_changelog) {
  387.                     $this->_packageInfo['release_deps'][$this->d_i]['name'] = $data;
  388.                 }
  389.                 break;
  390.             case 'dir':
  391.                 if ($this->in_changelog) {
  392.                     break;
  393.                 }
  394.                 array_pop($this->dir_names);
  395.                 break;
  396.             case 'file':
  397.                 if ($this->in_changelog) {
  398.                     break;
  399.                 }
  400.                 if ($data) {
  401.                     $path = '';
  402.                     if (count($this->dir_names)) {
  403.                         foreach ($this->dir_names as $dir) {
  404.                             $path .= $dir . '/';
  405.                         }
  406.                     }
  407.                     $path .= $data;
  408.                     $this->filelist[$path] = $this->current_attributes;
  409.                     // Set the baseinstalldir only if the file don't have this attrib
  410.                     if (!isset($this->filelist[$path]['baseinstalldir']) &&
  411.                         isset($this->dir_install))
  412.                     {
  413.                         $this->filelist[$path]['baseinstalldir'] = $this->dir_install;
  414.                     }
  415.                     // Set the Role
  416.                     if (!isset($this->filelist[$path]['role']) && isset($this->dir_role)) {
  417.                         $this->filelist[$path]['role'] = $this->dir_role;
  418.                     }
  419.                 }
  420.                 break;
  421.             case 'maintainer':
  422.                 if (empty($this->_packageInfo['maintainers'][$this->m_i]['role'])) {
  423.                     $this->_packageInfo['maintainers'][$this->m_i]['role'] = 'lead';
  424.                 }
  425.                 $this->m_i++;
  426.                 break;
  427.             case 'release':
  428.                 if ($this->in_changelog) {
  429.                     $this->c_i++;
  430.                 }
  431.                 break;
  432.             case 'changelog':
  433.                 $this->in_changelog = false;
  434.                 break;
  435.         }
  436.         array_pop($this->element_stack);
  437.         $spos = sizeof($this->element_stack) - 1;
  438.         $this->current_element = ($spos > 0) ? $this->element_stack[$spos] : '';
  439.         $this->cdata = '';
  440.     }
  441.  
  442.     // }}}
  443.     // {{{ _pkginfo_cdata_1_0()
  444.  
  445.     /**
  446.      * XML parser callback for character data.  Used for version 1.0
  447.      * packages.
  448.      *
  449.      * @param resource  $xp    XML parser resource
  450.      * @param string    $name  character data
  451.      *
  452.      * @return void
  453.      *
  454.      * @access private
  455.      */
  456.     function _pkginfo_cdata_1_0($xp, $data)
  457.     {
  458.         if (isset($this->cdata)) {
  459.             $this->cdata .= $data;
  460.         }
  461.     }
  462.  
  463.     // }}}
  464. }
  465. ?>