From: Stig Bakken Date: Thu, 28 Mar 2002 14:07:33 +0000 (+0000) Subject: * added phpdoc X-Git-Tag: php-4.3.0dev-ZendEngine2-Preview1~996 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=78c020a3bb4b8c252a6457525b44506b946bba97;p=php * added phpdoc * now ready to support multiple versions of the package format * don't parse dependencies in changelog * fix libfile parsing * default maintainer roles to 'lead' * added infoFromString() method * added xmlFromInfo() method to regenerate package.xml files --- diff --git a/pear/PEAR/Common.php b/pear/PEAR/Common.php index f1a89476c4..7a594e414b 100644 --- a/pear/PEAR/Common.php +++ b/pear/PEAR/Common.php @@ -23,12 +23,16 @@ require_once 'PEAR.php'; require_once 'Archive/Tar.php'; require_once 'System.php'; -/** +/* * TODO: * - check in inforFromDescFile that the minimal data needed is present * (pack name, version, files, others?) * - inherance of dir attribs to files may fail under certain circumstances */ + +/** + * Class providing common functionality for PEAR adminsitration classes. + */ class PEAR_Common extends PEAR { // {{{ properties @@ -58,12 +62,17 @@ class PEAR_Common extends PEAR * Permitted release states * @var array */ - var $releases_states = array('alpha','beta','stable','snapshot'); + var $releases_states = array('alpha','beta','stable','snapshot','devel'); // }}} // {{{ constructor + /** + * PEAR_Common constructor + * + * @access public + */ function PEAR_Common() { $GLOBALS['_PEAR_Common_tempfiles'] = array(); @@ -74,6 +83,11 @@ class PEAR_Common extends PEAR // }}} // {{{ destructor + /** + * PEAR_Common destructor + * + * @access private + */ function _PEAR_Common() { // doesn't work due to bug #14744 @@ -93,6 +107,17 @@ class PEAR_Common extends PEAR // }}} // {{{ addTempFile() + /** + * Register a temporary file or directory. When the destructor is + * executed, all registered temporary files and directories are + * removed. + * + * @param string name of file or directory + * + * @return void + * + * @access public + */ function addTempFile($file) { $this->_tempfiles[] = $file; @@ -101,6 +126,16 @@ class PEAR_Common extends PEAR // }}} // {{{ mkDirHier() + /** + * Wrapper to System::mkDir(), creates a directory as well as + * any necessary parent directories. + * + * @param string directory name + * + * @return bool TRUE on success, or a PEAR error + * + * @access public + */ function mkDirHier($dir) { $this->log(2, "+ create dir $dir"); @@ -110,6 +145,17 @@ class PEAR_Common extends PEAR // }}} // {{{ log() + /** + * Logging method. + * + * @param int log level (0 is quiet, higher is noisier) + * + * @param string message to write to the log + * + * @return void + * + * @access public + */ function log($level, $msg) { if ($this->debug >= $level) { @@ -120,6 +166,13 @@ class PEAR_Common extends PEAR // }}} // {{{ mkTempDir() + /** + * Create and register a temporary directory. + * + * @return string name of created directory + * + * @access public + */ function mkTempDir() { if (!$tmpdir = System::mktemp('-d pear')) { @@ -132,7 +185,77 @@ class PEAR_Common extends PEAR // }}} // {{{ _element_start() + /** + * XML parser callback for starting elements. Used while package + * format version is not yet known. + * + * @param resource XML parser resource + * @param string name of starting element + * @param array element attributes, name => value + * + * @return void + * + * @access private + */ function _element_start($xp, $name, $attribs) + { + array_push($this->element_stack, $name); + $this->current_element = $name; + $spos = sizeof($this->element_stack) - 2; + $this->prev_element = ($spos >= 0) ? $this->element_stack[$spos] : ''; + $this->current_attributes = $attribs; + switch ($name) { + case 'package': { + if (isset($attribs['version'])) { + $vs = preg_replace('/[^0-9a-z]/', '_', $attribs['version']); + } else { + $vs = '1_0'; + } + $elem_start = '_element_start_'. $vs; + $elem_end = '_element_end_'. $vs; + $cdata = '_pkginfo_cdata_'. $vs; + xml_set_element_handler($xp, $elem_start, $elem_end); + xml_set_character_data_handler($xp, $cdata); + break; + } + } + } + + // }}} + // {{{ _element_end() + + /** + * XML parser callback for ending elements. Used while package + * format version is not yet known. + * + * @param resource XML parser resource + * @param string name of ending element + * + * @return void + * + * @access private + */ + function _element_end($xp, $name) + { + } + + // }}} + + // Support for package DTD v1.0: + // {{{ _element_start_1_0() + + /** + * XML parser callback for ending elements. Used for version 1.0 + * packages. + * + * @param resource XML parser resource + * @param string name of ending element + * + * @return void + * + * @access private + */ + function _element_start_1_0($xp, $name, $attribs) { array_push($this->element_stack, $name); $this->current_element = $name; @@ -154,7 +277,7 @@ class PEAR_Common extends PEAR break; case 'libfile': $this->lib_atts = $attribs; - $this->lib_atts['role'] = 'extension'; + $this->lib_atts['role'] = 'extsrc'; break; case 'maintainers': $this->pkginfo['maintainers'] = array(); @@ -181,20 +304,35 @@ class PEAR_Common extends PEAR } break; case 'deps': - $this->pkginfo['release_deps'] = array(); + if (!$this->in_changelog) { + $this->pkginfo['release_deps'] = array(); + } break; case 'dep': // dependencies array index - $this->d_i = (isset($this->d_i)) ? $this->d_i + 1 : 0; - $this->pkginfo['release_deps'][$this->d_i] = $attribs; + if (!$this->in_changelog) { + $this->d_i = (isset($this->d_i)) ? $this->d_i + 1 : 0; + $this->pkginfo['release_deps'][$this->d_i] = $attribs; + } break; } } // }}} - // {{{ _element_end() + // {{{ _element_end_1_0() - function _element_end($xp, $name) + /** + * XML parser callback for ending elements. Used for version 1.0 + * packages. + * + * @param resource XML parser resource + * @param string name of ending element + * + * @return void + * + * @access private + */ + function _element_end_1_0($xp, $name) { $data = trim($this->cdata); switch ($name) { @@ -294,7 +432,6 @@ class PEAR_Common extends PEAR } break; case 'libfile': - $this->lib_name = $data; $path = ''; if (!empty($this->dir_names)) { foreach ($this->dir_names as $dir) { @@ -310,12 +447,19 @@ class PEAR_Common extends PEAR $this->filelist[$path]['baseinstalldir'] = $this->dir_install; } if (isset($this->lib_sources)) { - $this->filelist[$path]['sources'] = $this->lib_sources; + $this->filelist[$path]['sources'] = implode(' ', $this->lib_sources); } unset($this->lib_atts); unset($this->lib_sources); + unset($this->lib_name); + break; + case 'libname': + $this->lib_name = $data; break; case 'maintainer': + if (empty($this->pkginfo['maintainers'][$this->m_i]['role'])) { + $this->pkginfo['maintainers'][$this->m_i]['role'] = 'lead'; + } $this->m_i++; break; case 'release': @@ -336,22 +480,109 @@ class PEAR_Common extends PEAR } // }}} - // {{{ _pkginfo_cdata() + // {{{ _pkginfo_cdata_1_0() - function _pkginfo_cdata($xp, $data) + /** + * XML parser callback for character data. Used for version 1.0 + * packages. + * + * @param resource XML parser resource + * @param string character data + * + * @return void + * + * @access private + */ + function _pkginfo_cdata_1_0($xp, $data) { $this->cdata .= $data; } + // }}} + + // {{{ infoFromTgzFile() + + /** + * Returns information about a package file. Expects the name of + * a gzipped tar file as input. + * + * @param string name of .tgz file + * + * @return array array with package information + * + * @access public + * + */ + function infoFromTgzFile($file) + { + if (!@is_file($file)) { + return $this->raiseError('tgz :: could not open file'); + } + $tar = new Archive_Tar($file, true); + $content = $tar->listContent(); + if (!is_array($content)) { + return $this->raiseError('tgz :: could not get contents of package'); + } + $xml = null; + foreach ($content as $file) { + $name = $file['filename']; + if ($name == 'package.xml') { + $xml = $name; + } elseif (ereg('^.*/package.xml$', $name, $match)) { + $xml = $match[0]; + } + } + $tmpdir = System::mkTemp('-d pear'); + $this->addTempFile($tmpdir); + if (!$xml || !$tar->extractList($xml, $tmpdir)) { + return $this->raiseError('tgz :: could not extract the package.xml file'); + } + return $this->infoFromDescriptionFile("$tmpdir/$xml"); + } + // }}} // {{{ infoFromDescriptionFile() + /** + * Returns information about a package file. Expects the name of + * a package xml file as input. + * + * @param string name of package xml file + * + * @return array array with package information + * + * @access public + * + */ function infoFromDescriptionFile($descfile) { if (!@is_file($descfile) || !is_readable($descfile) || (!$fp = @fopen($descfile, 'r'))) { return $this->raiseError("Unable to open $descfile"); } + + // read the whole thing so we only get one cdata callback + // for each block of cdata + $data = fread($fp, filesize($descfile)); + return $this->infoFromString($data); + } + + // }}} + // {{{ infoFromString() + + /** + * Returns information about a package file. Expects the contents + * of a package xml file as input. + * + * @param string name of package xml file + * + * @return array array with package information + * + * @access public + * + */ + function infoFromString($data) + { $xp = @xml_parser_create(); if (!$xp) { return $this->raiseError('Unable to create XML parser'); @@ -370,15 +601,13 @@ class PEAR_Common extends PEAR $this->dir_names = array(); $this->in_changelog = false; - // read the whole thing so we only get one cdata callback - // for each block of cdata - $data = fread($fp, filesize($descfile)); if (!xml_parse($xp, $data, 1)) { + $code = xml_get_error_code($xp); $msg = sprintf("XML error: %s at line %d", - xml_error_string(xml_get_error_code($xp)), + xml_error_string($code), xml_get_current_line_number($xp)); xml_parser_free($xp); - return $this->raiseError($msg); + return $this->raiseError($msg, $code); } xml_parser_free($xp); @@ -391,38 +620,131 @@ class PEAR_Common extends PEAR return $this->pkginfo; } // }}} - // {{{ infoFromTgzFile() + // {{{ xmlFromInfo() /** - * Returns info from a tgz pear package - */ - function infoFromTgzFile($file) + * Return an XML document based on the package info (as returned + * by the PEAR_Common::infoFrom* methods). + * + * @param array package info + * + * @return string XML data + * + * @access public + */ + function xmlFromInfo($pkginfo) { - if (!@is_file($file)) { - return $this->raiseError('tgz :: could not open file'); + static $maint_map = array( + "handle" => "user", + "name" => "name", + "email" => "email", + "role" => "role", + ); + $ret = "\n"; + //$ret .= "\n"; + $ret .= " + $pkginfo[package] + ".htmlspecialchars($pkginfo['summary'])." + ".htmlspecialchars($pkginfo['description'])." + +"; + foreach ($pkginfo['maintainers'] as $maint) { + $ret .= " \n"; + foreach ($maint_map as $idx => $elm) { + $ret .= " <$elm>"; + $ret .= htmlspecialchars($maint[$idx]); + $ret .= "\n"; + } + $ret .= " \n"; } - $tar = new Archive_Tar($file, true); - $content = $tar->listContent(); - if (!is_array($content)) { - return $this->raiseError('tgz :: could not get contents of package'); + $ret .= " \n"; + $ret .= $this->_makeReleaseXml($pkginfo); + if (@sizeof($pkginfo['changelog']) > 0) { + $ret .= " \n"; + foreach ($pkginfo['changelog'] as $oldrelease) { + var_dump($oldrelease); + $ret .= $this->_makeReleaseXml($oldrelease, true); + } + $ret .= " \n"; } - $xml = null; - foreach ($content as $file) { - $name = $file['filename']; - if ($name == 'package.xml') { - $xml = $name; - } elseif (ereg('^.*/package.xml$', $name, $match)) { - $xml = $match[0]; + $ret .= "\n"; + return $ret; + } + + // }}} + // {{{ _makeReleaseXml() + + /** + * Generate part of an XML description with release information. + * + * @param array array with release information + * @param bool whether the result will be in a changelog element + * + * @return string XML data + * + * @access private + */ + function _makeReleaseXml($pkginfo, $changelog = false) + { + $indent = $changelog ? " " : ""; + $ret = "$indent \n"; + if (!empty($pkginfo['version'])) { + $ret .= "$indent $pkginfo[version]\n"; + } + if (!empty($pkginfo['release_date'])) { + $ret .= "$indent $pkginfo[release_date]\n"; + } + if (!empty($pkginfo['release_license'])) { + $ret .= "$indent $pkginfo[release_license]\n"; + } + if (!empty($pkginfo['release_state'])) { + $ret .= "$indent $pkginfo[release_state]\n"; + } + if (!empty($pkginfo['release_notes'])) { + $ret .= "$indent $pkginfo[release_notes]\n"; + } + if (sizeof($pkginfo['release_deps']) > 0) { + $ret .= "$indent \n"; + foreach ($pkginfo['release_deps'] as $dep) { + $ret .= "$indent addTempFile($tmpdir); - if (!$xml || !$tar->extractList($xml, $tmpdir)) { - return $this->raiseError('tgz :: could not extract the package.xml file'); + $ret .= "$indent \n"; +/* + ob_start(); + var_dump($pkginfo['filelist']); + $tmp = ob_get_contents(); + ob_end_clean(); + $ret .= $tmp; +*/ + foreach ($pkginfo['filelist'] as $file => $fa) { + if ($fa['role'] == 'extsrc') { + $ret .= "$indent \n"; + $ret .= "$indent $file\n"; + $ret .= "$indent $fa[sources]\n"; + $ret .= "$indent \n"; + } else { + $ret .= "$indent infoFromDescriptionFile("$tmpdir/$xml"); + $ret .= "$indent \n"; + $ret .= "$indent \n"; + return $ret; + } // }}} - } } ?> \ No newline at end of file