update PEAR to 1.9.4
This commit is contained in:
parent
347ce2aafa
commit
9c2f105164
|
@ -0,0 +1,338 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* The OS_Guess class
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Stig Bakken <ssb@php.net>
|
||||||
|
* @author Gregory Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: Guess.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since PEAR 0.1
|
||||||
|
*/
|
||||||
|
|
||||||
|
// {{{ uname examples
|
||||||
|
|
||||||
|
// php_uname() without args returns the same as 'uname -a', or a PHP-custom
|
||||||
|
// string for Windows.
|
||||||
|
// PHP versions prior to 4.3 return the uname of the host where PHP was built,
|
||||||
|
// as of 4.3 it returns the uname of the host running the PHP code.
|
||||||
|
//
|
||||||
|
// PC RedHat Linux 7.1:
|
||||||
|
// Linux host.example.com 2.4.2-2 #1 Sun Apr 8 20:41:30 EDT 2001 i686 unknown
|
||||||
|
//
|
||||||
|
// PC Debian Potato:
|
||||||
|
// Linux host 2.4.17 #2 SMP Tue Feb 12 15:10:04 CET 2002 i686 unknown
|
||||||
|
//
|
||||||
|
// PC FreeBSD 3.3:
|
||||||
|
// FreeBSD host.example.com 3.3-STABLE FreeBSD 3.3-STABLE #0: Mon Feb 21 00:42:31 CET 2000 root@example.com:/usr/src/sys/compile/CONFIG i386
|
||||||
|
//
|
||||||
|
// PC FreeBSD 4.3:
|
||||||
|
// FreeBSD host.example.com 4.3-RELEASE FreeBSD 4.3-RELEASE #1: Mon Jun 25 11:19:43 EDT 2001 root@example.com:/usr/src/sys/compile/CONFIG i386
|
||||||
|
//
|
||||||
|
// PC FreeBSD 4.5:
|
||||||
|
// FreeBSD host.example.com 4.5-STABLE FreeBSD 4.5-STABLE #0: Wed Feb 6 23:59:23 CET 2002 root@example.com:/usr/src/sys/compile/CONFIG i386
|
||||||
|
//
|
||||||
|
// PC FreeBSD 4.5 w/uname from GNU shellutils:
|
||||||
|
// FreeBSD host.example.com 4.5-STABLE FreeBSD 4.5-STABLE #0: Wed Feb i386 unknown
|
||||||
|
//
|
||||||
|
// HP 9000/712 HP-UX 10:
|
||||||
|
// HP-UX iq B.10.10 A 9000/712 2008429113 two-user license
|
||||||
|
//
|
||||||
|
// HP 9000/712 HP-UX 10 w/uname from GNU shellutils:
|
||||||
|
// HP-UX host B.10.10 A 9000/712 unknown
|
||||||
|
//
|
||||||
|
// IBM RS6000/550 AIX 4.3:
|
||||||
|
// AIX host 3 4 000003531C00
|
||||||
|
//
|
||||||
|
// AIX 4.3 w/uname from GNU shellutils:
|
||||||
|
// AIX host 3 4 000003531C00 unknown
|
||||||
|
//
|
||||||
|
// SGI Onyx IRIX 6.5 w/uname from GNU shellutils:
|
||||||
|
// IRIX64 host 6.5 01091820 IP19 mips
|
||||||
|
//
|
||||||
|
// SGI Onyx IRIX 6.5:
|
||||||
|
// IRIX64 host 6.5 01091820 IP19
|
||||||
|
//
|
||||||
|
// SparcStation 20 Solaris 8 w/uname from GNU shellutils:
|
||||||
|
// SunOS host.example.com 5.8 Generic_108528-12 sun4m sparc
|
||||||
|
//
|
||||||
|
// SparcStation 20 Solaris 8:
|
||||||
|
// SunOS host.example.com 5.8 Generic_108528-12 sun4m sparc SUNW,SPARCstation-20
|
||||||
|
//
|
||||||
|
// Mac OS X (Darwin)
|
||||||
|
// Darwin home-eden.local 7.5.0 Darwin Kernel Version 7.5.0: Thu Aug 5 19:26:16 PDT 2004; root:xnu/xnu-517.7.21.obj~3/RELEASE_PPC Power Macintosh
|
||||||
|
//
|
||||||
|
// Mac OS X early versions
|
||||||
|
//
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
/* TODO:
|
||||||
|
* - define endianness, to allow matchSignature("bigend") etc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves information about the current operating system
|
||||||
|
*
|
||||||
|
* This class uses php_uname() to grok information about the current OS
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Stig Bakken <ssb@php.net>
|
||||||
|
* @author Gregory Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 0.1
|
||||||
|
*/
|
||||||
|
class OS_Guess
|
||||||
|
{
|
||||||
|
var $sysname;
|
||||||
|
var $nodename;
|
||||||
|
var $cpu;
|
||||||
|
var $release;
|
||||||
|
var $extra;
|
||||||
|
|
||||||
|
function OS_Guess($uname = null)
|
||||||
|
{
|
||||||
|
list($this->sysname,
|
||||||
|
$this->release,
|
||||||
|
$this->cpu,
|
||||||
|
$this->extra,
|
||||||
|
$this->nodename) = $this->parseSignature($uname);
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseSignature($uname = null)
|
||||||
|
{
|
||||||
|
static $sysmap = array(
|
||||||
|
'HP-UX' => 'hpux',
|
||||||
|
'IRIX64' => 'irix',
|
||||||
|
);
|
||||||
|
static $cpumap = array(
|
||||||
|
'i586' => 'i386',
|
||||||
|
'i686' => 'i386',
|
||||||
|
'ppc' => 'powerpc',
|
||||||
|
);
|
||||||
|
if ($uname === null) {
|
||||||
|
$uname = php_uname();
|
||||||
|
}
|
||||||
|
$parts = preg_split('/\s+/', trim($uname));
|
||||||
|
$n = count($parts);
|
||||||
|
|
||||||
|
$release = $machine = $cpu = '';
|
||||||
|
$sysname = $parts[0];
|
||||||
|
$nodename = $parts[1];
|
||||||
|
$cpu = $parts[$n-1];
|
||||||
|
$extra = '';
|
||||||
|
if ($cpu == 'unknown') {
|
||||||
|
$cpu = $parts[$n - 2];
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($sysname) {
|
||||||
|
case 'AIX' :
|
||||||
|
$release = "$parts[3].$parts[2]";
|
||||||
|
break;
|
||||||
|
case 'Windows' :
|
||||||
|
switch ($parts[1]) {
|
||||||
|
case '95/98':
|
||||||
|
$release = '9x';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$release = $parts[1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$cpu = 'i386';
|
||||||
|
break;
|
||||||
|
case 'Linux' :
|
||||||
|
$extra = $this->_detectGlibcVersion();
|
||||||
|
// use only the first two digits from the kernel version
|
||||||
|
$release = preg_replace('/^([0-9]+\.[0-9]+).*/', '\1', $parts[2]);
|
||||||
|
break;
|
||||||
|
case 'Mac' :
|
||||||
|
$sysname = 'darwin';
|
||||||
|
$nodename = $parts[2];
|
||||||
|
$release = $parts[3];
|
||||||
|
if ($cpu == 'Macintosh') {
|
||||||
|
if ($parts[$n - 2] == 'Power') {
|
||||||
|
$cpu = 'powerpc';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'Darwin' :
|
||||||
|
if ($cpu == 'Macintosh') {
|
||||||
|
if ($parts[$n - 2] == 'Power') {
|
||||||
|
$cpu = 'powerpc';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$release = preg_replace('/^([0-9]+\.[0-9]+).*/', '\1', $parts[2]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$release = preg_replace('/-.*/', '', $parts[2]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($sysmap[$sysname])) {
|
||||||
|
$sysname = $sysmap[$sysname];
|
||||||
|
} else {
|
||||||
|
$sysname = strtolower($sysname);
|
||||||
|
}
|
||||||
|
if (isset($cpumap[$cpu])) {
|
||||||
|
$cpu = $cpumap[$cpu];
|
||||||
|
}
|
||||||
|
return array($sysname, $release, $cpu, $extra, $nodename);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _detectGlibcVersion()
|
||||||
|
{
|
||||||
|
static $glibc = false;
|
||||||
|
if ($glibc !== false) {
|
||||||
|
return $glibc; // no need to run this multiple times
|
||||||
|
}
|
||||||
|
$major = $minor = 0;
|
||||||
|
include_once "System.php";
|
||||||
|
// Use glibc's <features.h> header file to
|
||||||
|
// get major and minor version number:
|
||||||
|
if (@file_exists('/usr/include/features.h') &&
|
||||||
|
@is_readable('/usr/include/features.h')) {
|
||||||
|
if (!@file_exists('/usr/bin/cpp') || !@is_executable('/usr/bin/cpp')) {
|
||||||
|
$features_file = fopen('/usr/include/features.h', 'rb');
|
||||||
|
while (!feof($features_file)) {
|
||||||
|
$line = fgets($features_file, 8192);
|
||||||
|
if (!$line || (strpos($line, '#define') === false)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (strpos($line, '__GLIBC__')) {
|
||||||
|
// major version number #define __GLIBC__ version
|
||||||
|
$line = preg_split('/\s+/', $line);
|
||||||
|
$glibc_major = trim($line[2]);
|
||||||
|
if (isset($glibc_minor)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strpos($line, '__GLIBC_MINOR__')) {
|
||||||
|
// got the minor version number
|
||||||
|
// #define __GLIBC_MINOR__ version
|
||||||
|
$line = preg_split('/\s+/', $line);
|
||||||
|
$glibc_minor = trim($line[2]);
|
||||||
|
if (isset($glibc_major)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose($features_file);
|
||||||
|
if (!isset($glibc_major) || !isset($glibc_minor)) {
|
||||||
|
return $glibc = '';
|
||||||
|
}
|
||||||
|
return $glibc = 'glibc' . trim($glibc_major) . "." . trim($glibc_minor) ;
|
||||||
|
} // no cpp
|
||||||
|
|
||||||
|
$tmpfile = System::mktemp("glibctest");
|
||||||
|
$fp = fopen($tmpfile, "w");
|
||||||
|
fwrite($fp, "#include <features.h>\n__GLIBC__ __GLIBC_MINOR__\n");
|
||||||
|
fclose($fp);
|
||||||
|
$cpp = popen("/usr/bin/cpp $tmpfile", "r");
|
||||||
|
while ($line = fgets($cpp, 1024)) {
|
||||||
|
if ($line{0} == '#' || trim($line) == '') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (list($major, $minor) = explode(' ', trim($line))) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pclose($cpp);
|
||||||
|
unlink($tmpfile);
|
||||||
|
} // features.h
|
||||||
|
|
||||||
|
if (!($major && $minor) && @is_link('/lib/libc.so.6')) {
|
||||||
|
// Let's try reading the libc.so.6 symlink
|
||||||
|
if (preg_match('/^libc-(.*)\.so$/', basename(readlink('/lib/libc.so.6')), $matches)) {
|
||||||
|
list($major, $minor) = explode('.', $matches[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!($major && $minor)) {
|
||||||
|
return $glibc = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $glibc = "glibc{$major}.{$minor}";
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSignature()
|
||||||
|
{
|
||||||
|
if (empty($this->extra)) {
|
||||||
|
return "{$this->sysname}-{$this->release}-{$this->cpu}";
|
||||||
|
}
|
||||||
|
return "{$this->sysname}-{$this->release}-{$this->cpu}-{$this->extra}";
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSysname()
|
||||||
|
{
|
||||||
|
return $this->sysname;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNodename()
|
||||||
|
{
|
||||||
|
return $this->nodename;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCpu()
|
||||||
|
{
|
||||||
|
return $this->cpu;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRelease()
|
||||||
|
{
|
||||||
|
return $this->release;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getExtra()
|
||||||
|
{
|
||||||
|
return $this->extra;
|
||||||
|
}
|
||||||
|
|
||||||
|
function matchSignature($match)
|
||||||
|
{
|
||||||
|
$fragments = is_array($match) ? $match : explode('-', $match);
|
||||||
|
$n = count($fragments);
|
||||||
|
$matches = 0;
|
||||||
|
if ($n > 0) {
|
||||||
|
$matches += $this->_matchFragment($fragments[0], $this->sysname);
|
||||||
|
}
|
||||||
|
if ($n > 1) {
|
||||||
|
$matches += $this->_matchFragment($fragments[1], $this->release);
|
||||||
|
}
|
||||||
|
if ($n > 2) {
|
||||||
|
$matches += $this->_matchFragment($fragments[2], $this->cpu);
|
||||||
|
}
|
||||||
|
if ($n > 3) {
|
||||||
|
$matches += $this->_matchFragment($fragments[3], $this->extra);
|
||||||
|
}
|
||||||
|
return ($matches == $n);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _matchFragment($fragment, $value)
|
||||||
|
{
|
||||||
|
if (strcspn($fragment, '*?') < strlen($fragment)) {
|
||||||
|
$reg = '/^' . str_replace(array('*', '?', '/'), array('.*', '.', '\\/'), $fragment) . '\\z/';
|
||||||
|
return preg_match($reg, $value);
|
||||||
|
}
|
||||||
|
return ($fragment == '*' || !strcasecmp($fragment, $value));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Local Variables:
|
||||||
|
* indent-tabs-mode: nil
|
||||||
|
* c-basic-offset: 4
|
||||||
|
* End:
|
||||||
|
*/
|
|
@ -0,0 +1,27 @@
|
||||||
|
Copyright (c) 1997-2009,
|
||||||
|
Stig Bakken <ssb@php.net>,
|
||||||
|
Gregory Beaver <cellog@php.net>,
|
||||||
|
Helgi Þormar Þorbjörnsson <helgi@php.net>,
|
||||||
|
Tomas V.V.Cox <cox@idecnet.com>,
|
||||||
|
Martin Jansen <mj@php.net>.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -1,26 +1,27 @@
|
||||||
<?php
|
<?php
|
||||||
//
|
/**
|
||||||
// +--------------------------------------------------------------------+
|
* PEAR, the PHP Extension and Application Repository
|
||||||
// | PEAR, the PHP Extension and Application Repository |
|
*
|
||||||
// +--------------------------------------------------------------------+
|
* PEAR class and PEAR_Error class
|
||||||
// | Copyright (c) 1997-2004 The PHP Group |
|
*
|
||||||
// +--------------------------------------------------------------------+
|
* PHP versions 4 and 5
|
||||||
// | This source file is subject to version 3.0 of the PHP license, |
|
*
|
||||||
// | that is bundled with this package in the file LICENSE, and is |
|
* @category pear
|
||||||
// | available through the world-wide-web at the following url: |
|
* @package PEAR
|
||||||
// | http://www.php.net/license/3_0.txt. |
|
* @author Sterling Hughes <sterling@php.net>
|
||||||
// | If you did not receive a copy of the PHP license and are unable to |
|
* @author Stig Bakken <ssb@php.net>
|
||||||
// | obtain it through the world-wide-web, please send a note to |
|
* @author Tomas V.V.Cox <cox@idecnet.com>
|
||||||
// | license@php.net so we can mail you a copy immediately. |
|
* @author Greg Beaver <cellog@php.net>
|
||||||
// +--------------------------------------------------------------------+
|
* @copyright 1997-2010 The Authors
|
||||||
// | Authors: Sterling Hughes <sterling@php.net> |
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
// | Stig Bakken <ssb@php.net> |
|
* @version CVS: $Id: PEAR.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
// | Tomas V.V.Cox <cox@idecnet.com> |
|
* @link http://pear.php.net/package/PEAR
|
||||||
// +--------------------------------------------------------------------+
|
* @since File available since Release 0.1
|
||||||
//
|
*/
|
||||||
// $Id: PEAR.php,v 1.82.2.6 2005/01/01 05:24:51 cellog Exp $
|
|
||||||
//
|
|
||||||
|
|
||||||
|
/**#@+
|
||||||
|
* ERROR constants
|
||||||
|
*/
|
||||||
define('PEAR_ERROR_RETURN', 1);
|
define('PEAR_ERROR_RETURN', 1);
|
||||||
define('PEAR_ERROR_PRINT', 2);
|
define('PEAR_ERROR_PRINT', 2);
|
||||||
define('PEAR_ERROR_TRIGGER', 4);
|
define('PEAR_ERROR_TRIGGER', 4);
|
||||||
|
@ -31,6 +32,7 @@ define('PEAR_ERROR_CALLBACK', 16);
|
||||||
* @deprecated
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
define('PEAR_ERROR_EXCEPTION', 32);
|
define('PEAR_ERROR_EXCEPTION', 32);
|
||||||
|
/**#@-*/
|
||||||
define('PEAR_ZE2', (function_exists('version_compare') &&
|
define('PEAR_ZE2', (function_exists('version_compare') &&
|
||||||
version_compare(zend_version(), "2-dev", "ge")));
|
version_compare(zend_version(), "2-dev", "ge")));
|
||||||
|
|
||||||
|
@ -44,15 +46,6 @@ if (substr(PHP_OS, 0, 3) == 'WIN') {
|
||||||
define('PEAR_OS', 'Unix'); // blatant assumption
|
define('PEAR_OS', 'Unix'); // blatant assumption
|
||||||
}
|
}
|
||||||
|
|
||||||
// instant backwards compatibility
|
|
||||||
if (!defined('PATH_SEPARATOR')) {
|
|
||||||
if (OS_WINDOWS) {
|
|
||||||
define('PATH_SEPARATOR', ';');
|
|
||||||
} else {
|
|
||||||
define('PATH_SEPARATOR', ':');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$GLOBALS['_PEAR_default_error_mode'] = PEAR_ERROR_RETURN;
|
$GLOBALS['_PEAR_default_error_mode'] = PEAR_ERROR_RETURN;
|
||||||
$GLOBALS['_PEAR_default_error_options'] = E_USER_NOTICE;
|
$GLOBALS['_PEAR_default_error_options'] = E_USER_NOTICE;
|
||||||
$GLOBALS['_PEAR_destructor_object_list'] = array();
|
$GLOBALS['_PEAR_destructor_object_list'] = array();
|
||||||
|
@ -78,14 +71,21 @@ $GLOBALS['_PEAR_error_handler_stack'] = array();
|
||||||
* IMPORTANT! To use the emulated destructors you need to create the
|
* IMPORTANT! To use the emulated destructors you need to create the
|
||||||
* objects by reference: $obj =& new PEAR_child;
|
* objects by reference: $obj =& new PEAR_child;
|
||||||
*
|
*
|
||||||
* @since PHP 4.0.2
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
* @author Stig Bakken <ssb@php.net>
|
* @author Stig Bakken <ssb@php.net>
|
||||||
* @see http://pear.php.net/manual/
|
* @author Tomas V.V. Cox <cox@idecnet.com>
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2006 The PHP Group
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @see PEAR_Error
|
||||||
|
* @since Class available since PHP 4.0.2
|
||||||
|
* @link http://pear.php.net/manual/en/core.pear.php#core.pear.pear
|
||||||
*/
|
*/
|
||||||
class PEAR
|
class PEAR
|
||||||
{
|
{
|
||||||
// {{{ properties
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether to enable internal debug messages.
|
* Whether to enable internal debug messages.
|
||||||
*
|
*
|
||||||
|
@ -136,10 +136,6 @@ class PEAR
|
||||||
*/
|
*/
|
||||||
var $_expected_errors = array();
|
var $_expected_errors = array();
|
||||||
|
|
||||||
// }}}
|
|
||||||
|
|
||||||
// {{{ constructor
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor. Registers this object in
|
* Constructor. Registers this object in
|
||||||
* $_PEAR_destructor_object_list for destructor emulation if a
|
* $_PEAR_destructor_object_list for destructor emulation if a
|
||||||
|
@ -156,9 +152,11 @@ class PEAR
|
||||||
if ($this->_debug) {
|
if ($this->_debug) {
|
||||||
print "PEAR constructor called, class=$classname\n";
|
print "PEAR constructor called, class=$classname\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($error_class !== null) {
|
if ($error_class !== null) {
|
||||||
$this->_error_class = $error_class;
|
$this->_error_class = $error_class;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ($classname && strcasecmp($classname, "pear")) {
|
while ($classname && strcasecmp($classname, "pear")) {
|
||||||
$destructor = "_$classname";
|
$destructor = "_$classname";
|
||||||
if (method_exists($this, $destructor)) {
|
if (method_exists($this, $destructor)) {
|
||||||
|
@ -175,9 +173,6 @@ class PEAR
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ destructor
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destructor (the emulated type of...). Does nothing right now,
|
* Destructor (the emulated type of...). Does nothing right now,
|
||||||
* but is included for forward compatibility, so subclass
|
* but is included for forward compatibility, so subclass
|
||||||
|
@ -195,9 +190,6 @@ class PEAR
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ getStaticProperty()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If you have a class that's mostly/entirely static, and you need static
|
* If you have a class that's mostly/entirely static, and you need static
|
||||||
* properties, you can use this method to simulate them. Eg. in your method(s)
|
* properties, you can use this method to simulate them. Eg. in your method(s)
|
||||||
|
@ -213,11 +205,16 @@ class PEAR
|
||||||
function &getStaticProperty($class, $var)
|
function &getStaticProperty($class, $var)
|
||||||
{
|
{
|
||||||
static $properties;
|
static $properties;
|
||||||
return $properties[$class][$var];
|
if (!isset($properties[$class])) {
|
||||||
|
$properties[$class] = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
if (!array_key_exists($var, $properties[$class])) {
|
||||||
// {{{ registerShutdownFunc()
|
$properties[$class][$var] = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $properties[$class][$var];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use this function to register a shutdown method for static
|
* Use this function to register a shutdown method for static
|
||||||
|
@ -230,12 +227,15 @@ class PEAR
|
||||||
*/
|
*/
|
||||||
function registerShutdownFunc($func, $args = array())
|
function registerShutdownFunc($func, $args = array())
|
||||||
{
|
{
|
||||||
|
// if we are called statically, there is a potential
|
||||||
|
// that no shutdown func is registered. Bug #6445
|
||||||
|
if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) {
|
||||||
|
register_shutdown_function("_PEAR_call_destructors");
|
||||||
|
$GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true;
|
||||||
|
}
|
||||||
$GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args);
|
$GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args);
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ isError()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tell whether a value is a PEAR error.
|
* Tell whether a value is a PEAR error.
|
||||||
*
|
*
|
||||||
|
@ -247,22 +247,20 @@ class PEAR
|
||||||
* @access public
|
* @access public
|
||||||
* @return bool true if parameter is an error
|
* @return bool true if parameter is an error
|
||||||
*/
|
*/
|
||||||
static function isError($data, $code = null)
|
function isError($data, $code = null)
|
||||||
{
|
{
|
||||||
if ($data instanceof PEAR_Error) {
|
if (!is_a($data, 'PEAR_Error')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (is_null($code)) {
|
if (is_null($code)) {
|
||||||
return true;
|
return true;
|
||||||
} elseif (is_string($code)) {
|
} elseif (is_string($code)) {
|
||||||
return $data->getMessage() == $code;
|
return $data->getMessage() == $code;
|
||||||
} else {
|
|
||||||
return $data->getCode() == $code;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
return $data->getCode() == $code;
|
||||||
// {{{ setErrorHandling()
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets how errors generated by this object should be handled.
|
* Sets how errors generated by this object should be handled.
|
||||||
|
@ -302,10 +300,9 @@ class PEAR
|
||||||
*
|
*
|
||||||
* @since PHP 4.0.5
|
* @since PHP 4.0.5
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function setErrorHandling($mode = null, $options = null)
|
function setErrorHandling($mode = null, $options = null)
|
||||||
{
|
{
|
||||||
if (isset($this) && $this instanceof PEAR) {
|
if (isset($this) && is_a($this, 'PEAR')) {
|
||||||
$setmode = &$this->_default_error_mode;
|
$setmode = &$this->_default_error_mode;
|
||||||
$setoptions = &$this->_default_error_options;
|
$setoptions = &$this->_default_error_options;
|
||||||
} else {
|
} else {
|
||||||
|
@ -340,9 +337,6 @@ class PEAR
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ expectError()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is used to tell which errors you expect to get.
|
* This method is used to tell which errors you expect to get.
|
||||||
* Expected errors are always returned with error mode
|
* Expected errors are always returned with error mode
|
||||||
|
@ -365,12 +359,9 @@ class PEAR
|
||||||
} else {
|
} else {
|
||||||
array_push($this->_expected_errors, array($code));
|
array_push($this->_expected_errors, array($code));
|
||||||
}
|
}
|
||||||
return sizeof($this->_expected_errors);
|
return count($this->_expected_errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ popExpect()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method pops one element off the expected error codes
|
* This method pops one element off the expected error codes
|
||||||
* stack.
|
* stack.
|
||||||
|
@ -382,9 +373,6 @@ class PEAR
|
||||||
return array_pop($this->_expected_errors);
|
return array_pop($this->_expected_errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ _checkDelExpect()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method checks unsets an error code if available
|
* This method checks unsets an error code if available
|
||||||
*
|
*
|
||||||
|
@ -396,8 +384,7 @@ class PEAR
|
||||||
function _checkDelExpect($error_code)
|
function _checkDelExpect($error_code)
|
||||||
{
|
{
|
||||||
$deleted = false;
|
$deleted = false;
|
||||||
|
foreach ($this->_expected_errors as $key => $error_array) {
|
||||||
foreach ($this->_expected_errors AS $key => $error_array) {
|
|
||||||
if (in_array($error_code, $error_array)) {
|
if (in_array($error_code, $error_array)) {
|
||||||
unset($this->_expected_errors[$key][array_search($error_code, $error_array)]);
|
unset($this->_expected_errors[$key][array_search($error_code, $error_array)]);
|
||||||
$deleted = true;
|
$deleted = true;
|
||||||
|
@ -408,12 +395,10 @@ class PEAR
|
||||||
unset($this->_expected_errors[$key]);
|
unset($this->_expected_errors[$key]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $deleted;
|
return $deleted;
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ delExpect()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method deletes all occurences of the specified element from
|
* This method deletes all occurences of the specified element from
|
||||||
* the expected error codes stack.
|
* the expected error codes stack.
|
||||||
|
@ -426,34 +411,26 @@ class PEAR
|
||||||
function delExpect($error_code)
|
function delExpect($error_code)
|
||||||
{
|
{
|
||||||
$deleted = false;
|
$deleted = false;
|
||||||
|
|
||||||
if ((is_array($error_code) && (0 != count($error_code)))) {
|
if ((is_array($error_code) && (0 != count($error_code)))) {
|
||||||
// $error_code is a non-empty array here;
|
// $error_code is a non-empty array here; we walk through it trying
|
||||||
// we walk through it trying to unset all
|
// to unset all values
|
||||||
// values
|
|
||||||
foreach ($error_code as $key => $error) {
|
foreach ($error_code as $key => $error) {
|
||||||
if ($this->_checkDelExpect($error)) {
|
$deleted = $this->_checkDelExpect($error) ? true : false;
|
||||||
$deleted = true;
|
|
||||||
} else {
|
|
||||||
$deleted = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $deleted ? true : PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME
|
return $deleted ? true : PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME
|
||||||
} elseif (!empty($error_code)) {
|
} elseif (!empty($error_code)) {
|
||||||
// $error_code comes alone, trying to unset it
|
// $error_code comes alone, trying to unset it
|
||||||
if ($this->_checkDelExpect($error_code)) {
|
if ($this->_checkDelExpect($error_code)) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
}
|
||||||
|
|
||||||
return PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME
|
return PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// $error_code is empty
|
// $error_code is empty
|
||||||
return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME
|
return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ raiseError()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is a wrapper that returns an instance of the
|
* This method is a wrapper that returns an instance of the
|
||||||
|
@ -492,7 +469,7 @@ class PEAR
|
||||||
* @see PEAR::setErrorHandling
|
* @see PEAR::setErrorHandling
|
||||||
* @since PHP 4.0.5
|
* @since PHP 4.0.5
|
||||||
*/
|
*/
|
||||||
function raiseError($message = null,
|
function &raiseError($message = null,
|
||||||
$code = null,
|
$code = null,
|
||||||
$mode = null,
|
$mode = null,
|
||||||
$options = null,
|
$options = null,
|
||||||
|
@ -509,13 +486,20 @@ class PEAR
|
||||||
$message = $message->getMessage();
|
$message = $message->getMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($this) && isset($this->_expected_errors) && sizeof($this->_expected_errors) > 0 && sizeof($exp = end($this->_expected_errors))) {
|
if (
|
||||||
|
isset($this) &&
|
||||||
|
isset($this->_expected_errors) &&
|
||||||
|
count($this->_expected_errors) > 0 &&
|
||||||
|
count($exp = end($this->_expected_errors))
|
||||||
|
) {
|
||||||
if ($exp[0] == "*" ||
|
if ($exp[0] == "*" ||
|
||||||
(is_int(reset($exp)) && in_array($code, $exp)) ||
|
(is_int(reset($exp)) && in_array($code, $exp)) ||
|
||||||
(is_string(reset($exp)) && in_array($message, $exp))) {
|
(is_string(reset($exp)) && in_array($message, $exp))
|
||||||
|
) {
|
||||||
$mode = PEAR_ERROR_RETURN;
|
$mode = PEAR_ERROR_RETURN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// No mode given, try global ones
|
// No mode given, try global ones
|
||||||
if ($mode === null) {
|
if ($mode === null) {
|
||||||
// Class error handler
|
// Class error handler
|
||||||
|
@ -536,35 +520,49 @@ class PEAR
|
||||||
} else {
|
} else {
|
||||||
$ec = 'PEAR_Error';
|
$ec = 'PEAR_Error';
|
||||||
}
|
}
|
||||||
if ($skipmsg) {
|
|
||||||
return new $ec($code, $mode, $options, $userinfo);
|
if (intval(PHP_VERSION) < 5) {
|
||||||
} else {
|
// little non-eval hack to fix bug #12147
|
||||||
return new $ec($message, $code, $mode, $options, $userinfo);
|
include 'PEAR/FixPHP5PEARWarnings.php';
|
||||||
}
|
return $a;
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
if ($skipmsg) {
|
||||||
// {{{ throwError()
|
$a = new $ec($code, $mode, $options, $userinfo);
|
||||||
|
} else {
|
||||||
|
$a = new $ec($message, $code, $mode, $options, $userinfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $a;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simpler form of raiseError with fewer options. In most cases
|
* Simpler form of raiseError with fewer options. In most cases
|
||||||
* message, code and userinfo are enough.
|
* message, code and userinfo are enough.
|
||||||
*
|
*
|
||||||
* @param string $message
|
* @param mixed $message a text error message or a PEAR error object
|
||||||
*
|
*
|
||||||
|
* @param int $code a numeric error code (it is up to your class
|
||||||
|
* to define these if you want to use codes)
|
||||||
|
*
|
||||||
|
* @param string $userinfo If you need to pass along for example debug
|
||||||
|
* information, this parameter is meant for that.
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return object a PEAR error object
|
||||||
|
* @see PEAR::raiseError
|
||||||
*/
|
*/
|
||||||
function throwError($message = null,
|
function &throwError($message = null, $code = null, $userinfo = null)
|
||||||
$code = null,
|
|
||||||
$userinfo = null)
|
|
||||||
{
|
{
|
||||||
if (isset($this) && $this instanceof PEAR) {
|
if (isset($this) && is_a($this, 'PEAR')) {
|
||||||
return $this->raiseError($message, $code, null, null, $userinfo);
|
$a = &$this->raiseError($message, $code, null, null, $userinfo);
|
||||||
} else {
|
return $a;
|
||||||
return PEAR::raiseError($message, $code, null, null, $userinfo);
|
}
|
||||||
}
|
|
||||||
|
$a = &PEAR::raiseError($message, $code, null, null, $userinfo);
|
||||||
|
return $a;
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
function staticPushErrorHandling($mode, $options = null)
|
function staticPushErrorHandling($mode, $options = null)
|
||||||
{
|
{
|
||||||
$stack = &$GLOBALS['_PEAR_error_handler_stack'];
|
$stack = &$GLOBALS['_PEAR_error_handler_stack'];
|
||||||
|
@ -636,8 +634,6 @@ class PEAR
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// {{{ pushErrorHandling()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Push a new error handler on top of the error handler options stack. With this
|
* Push a new error handler on top of the error handler options stack. With this
|
||||||
* you can easily override the actual error handler for some code and restore
|
* you can easily override the actual error handler for some code and restore
|
||||||
|
@ -653,7 +649,7 @@ class PEAR
|
||||||
function pushErrorHandling($mode, $options = null)
|
function pushErrorHandling($mode, $options = null)
|
||||||
{
|
{
|
||||||
$stack = &$GLOBALS['_PEAR_error_handler_stack'];
|
$stack = &$GLOBALS['_PEAR_error_handler_stack'];
|
||||||
if (isset($this) && $this instanceof PEAR) {
|
if (isset($this) && is_a($this, 'PEAR')) {
|
||||||
$def_mode = &$this->_default_error_mode;
|
$def_mode = &$this->_default_error_mode;
|
||||||
$def_options = &$this->_default_error_options;
|
$def_options = &$this->_default_error_options;
|
||||||
} else {
|
} else {
|
||||||
|
@ -662,7 +658,7 @@ class PEAR
|
||||||
}
|
}
|
||||||
$stack[] = array($def_mode, $def_options);
|
$stack[] = array($def_mode, $def_options);
|
||||||
|
|
||||||
if (isset($this) && $this instanceof PEAR) {
|
if (isset($this) && is_a($this, 'PEAR')) {
|
||||||
$this->setErrorHandling($mode, $options);
|
$this->setErrorHandling($mode, $options);
|
||||||
} else {
|
} else {
|
||||||
PEAR::setErrorHandling($mode, $options);
|
PEAR::setErrorHandling($mode, $options);
|
||||||
|
@ -671,9 +667,6 @@ class PEAR
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ popErrorHandling()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pop the last error handler used
|
* Pop the last error handler used
|
||||||
*
|
*
|
||||||
|
@ -687,7 +680,7 @@ class PEAR
|
||||||
array_pop($stack);
|
array_pop($stack);
|
||||||
list($mode, $options) = $stack[sizeof($stack) - 1];
|
list($mode, $options) = $stack[sizeof($stack) - 1];
|
||||||
array_pop($stack);
|
array_pop($stack);
|
||||||
if (isset($this) && $this instanceof PEAR) {
|
if (isset($this) && is_a($this, 'PEAR')) {
|
||||||
$this->setErrorHandling($mode, $options);
|
$this->setErrorHandling($mode, $options);
|
||||||
} else {
|
} else {
|
||||||
PEAR::setErrorHandling($mode, $options);
|
PEAR::setErrorHandling($mode, $options);
|
||||||
|
@ -695,9 +688,6 @@ class PEAR
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ loadExtension()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OS independant PHP extension load. Remember to take care
|
* OS independant PHP extension load. Remember to take care
|
||||||
* on the correct extension name for case sensitive OSes.
|
* on the correct extension name for case sensitive OSes.
|
||||||
|
@ -707,11 +697,19 @@ class PEAR
|
||||||
*/
|
*/
|
||||||
function loadExtension($ext)
|
function loadExtension($ext)
|
||||||
{
|
{
|
||||||
if (!extension_loaded($ext)) {
|
if (extension_loaded($ext)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// if either returns true dl() will produce a FATAL error, stop that
|
// if either returns true dl() will produce a FATAL error, stop that
|
||||||
if ((ini_get('enable_dl') != 1) || (ini_get('safe_mode') == 1)) {
|
if (
|
||||||
|
function_exists('dl') === false ||
|
||||||
|
ini_get('enable_dl') != 1 ||
|
||||||
|
ini_get('safe_mode') == 1
|
||||||
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (OS_WINDOWS) {
|
if (OS_WINDOWS) {
|
||||||
$suffix = '.dll';
|
$suffix = '.dll';
|
||||||
} elseif (PHP_OS == 'HP-UX') {
|
} elseif (PHP_OS == 'HP-UX') {
|
||||||
|
@ -723,16 +721,15 @@ class PEAR
|
||||||
} else {
|
} else {
|
||||||
$suffix = '.so';
|
$suffix = '.so';
|
||||||
}
|
}
|
||||||
|
|
||||||
return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix);
|
return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix);
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
if (PEAR_ZE2) {
|
||||||
|
include_once 'PEAR5.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
// {{{ _PEAR_call_destructors()
|
|
||||||
|
|
||||||
function _PEAR_call_destructors()
|
function _PEAR_call_destructors()
|
||||||
{
|
{
|
||||||
global $_PEAR_destructor_object_list;
|
global $_PEAR_destructor_object_list;
|
||||||
|
@ -740,9 +737,16 @@ function _PEAR_call_destructors()
|
||||||
sizeof($_PEAR_destructor_object_list))
|
sizeof($_PEAR_destructor_object_list))
|
||||||
{
|
{
|
||||||
reset($_PEAR_destructor_object_list);
|
reset($_PEAR_destructor_object_list);
|
||||||
if (@PEAR::getStaticProperty('PEAR', 'destructlifo')) {
|
if (PEAR_ZE2) {
|
||||||
|
$destructLifoExists = PEAR5::getStaticProperty('PEAR', 'destructlifo');
|
||||||
|
} else {
|
||||||
|
$destructLifoExists = PEAR::getStaticProperty('PEAR', 'destructlifo');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($destructLifoExists) {
|
||||||
$_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list);
|
$_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (list($k, $objref) = each($_PEAR_destructor_object_list)) {
|
while (list($k, $objref) = each($_PEAR_destructor_object_list)) {
|
||||||
$classname = get_class($objref);
|
$classname = get_class($objref);
|
||||||
while ($classname) {
|
while ($classname) {
|
||||||
|
@ -761,19 +765,36 @@ function _PEAR_call_destructors()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now call the shutdown functions
|
// Now call the shutdown functions
|
||||||
if (is_array($GLOBALS['_PEAR_shutdown_funcs']) AND !empty($GLOBALS['_PEAR_shutdown_funcs'])) {
|
if (
|
||||||
|
isset($GLOBALS['_PEAR_shutdown_funcs']) &&
|
||||||
|
is_array($GLOBALS['_PEAR_shutdown_funcs']) &&
|
||||||
|
!empty($GLOBALS['_PEAR_shutdown_funcs'])
|
||||||
|
) {
|
||||||
foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) {
|
foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) {
|
||||||
call_user_func_array($value[0], $value[1]);
|
call_user_func_array($value[0], $value[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
/**
|
||||||
|
* Standard PEAR error class for PHP 4
|
||||||
|
*
|
||||||
|
* This class is supserseded by {@link PEAR_Exception} in PHP 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Stig Bakken <ssb@php.net>
|
||||||
|
* @author Tomas V.V. Cox <cox@idecnet.com>
|
||||||
|
* @author Gregory Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2006 The PHP Group
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/manual/en/core.pear.pear-error.php
|
||||||
|
* @see PEAR::raiseError(), PEAR::throwError()
|
||||||
|
* @since Class available since PHP 4.0.2
|
||||||
|
*/
|
||||||
class PEAR_Error
|
class PEAR_Error
|
||||||
{
|
{
|
||||||
// {{{ properties
|
|
||||||
|
|
||||||
var $error_message_prefix = '';
|
var $error_message_prefix = '';
|
||||||
var $mode = PEAR_ERROR_RETURN;
|
var $mode = PEAR_ERROR_RETURN;
|
||||||
var $level = E_USER_NOTICE;
|
var $level = E_USER_NOTICE;
|
||||||
|
@ -782,9 +803,6 @@ class PEAR_Error
|
||||||
var $userinfo = '';
|
var $userinfo = '';
|
||||||
var $backtrace = null;
|
var $backtrace = null;
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ constructor
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PEAR_Error constructor
|
* PEAR_Error constructor
|
||||||
*
|
*
|
||||||
|
@ -815,11 +833,20 @@ class PEAR_Error
|
||||||
$this->code = $code;
|
$this->code = $code;
|
||||||
$this->mode = $mode;
|
$this->mode = $mode;
|
||||||
$this->userinfo = $userinfo;
|
$this->userinfo = $userinfo;
|
||||||
if (function_exists("debug_backtrace")) {
|
|
||||||
if (@!PEAR::getStaticProperty('PEAR_Error', 'skiptrace')) {
|
if (PEAR_ZE2) {
|
||||||
|
$skiptrace = PEAR5::getStaticProperty('PEAR_Error', 'skiptrace');
|
||||||
|
} else {
|
||||||
|
$skiptrace = PEAR::getStaticProperty('PEAR_Error', 'skiptrace');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$skiptrace) {
|
||||||
$this->backtrace = debug_backtrace();
|
$this->backtrace = debug_backtrace();
|
||||||
|
if (isset($this->backtrace[0]) && isset($this->backtrace[0]['object'])) {
|
||||||
|
unset($this->backtrace[0]['object']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($mode & PEAR_ERROR_CALLBACK) {
|
if ($mode & PEAR_ERROR_CALLBACK) {
|
||||||
$this->level = E_USER_NOTICE;
|
$this->level = E_USER_NOTICE;
|
||||||
$this->callback = $options;
|
$this->callback = $options;
|
||||||
|
@ -827,20 +854,25 @@ class PEAR_Error
|
||||||
if ($options === null) {
|
if ($options === null) {
|
||||||
$options = E_USER_NOTICE;
|
$options = E_USER_NOTICE;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->level = $options;
|
$this->level = $options;
|
||||||
$this->callback = null;
|
$this->callback = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->mode & PEAR_ERROR_PRINT) {
|
if ($this->mode & PEAR_ERROR_PRINT) {
|
||||||
if (is_null($options) || is_int($options)) {
|
if (is_null($options) || is_int($options)) {
|
||||||
$format = "%s";
|
$format = "%s";
|
||||||
} else {
|
} else {
|
||||||
$format = $options;
|
$format = $options;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf($format, $this->getMessage());
|
printf($format, $this->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->mode & PEAR_ERROR_TRIGGER) {
|
if ($this->mode & PEAR_ERROR_TRIGGER) {
|
||||||
trigger_error($this->getMessage(), $this->level);
|
trigger_error($this->getMessage(), $this->level);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->mode & PEAR_ERROR_DIE) {
|
if ($this->mode & PEAR_ERROR_DIE) {
|
||||||
$msg = $this->getMessage();
|
$msg = $this->getMessage();
|
||||||
if (is_null($options) || is_int($options)) {
|
if (is_null($options) || is_int($options)) {
|
||||||
|
@ -853,19 +885,16 @@ class PEAR_Error
|
||||||
}
|
}
|
||||||
die(sprintf($format, $msg));
|
die(sprintf($format, $msg));
|
||||||
}
|
}
|
||||||
if ($this->mode & PEAR_ERROR_CALLBACK) {
|
|
||||||
if (is_callable($this->callback)) {
|
if ($this->mode & PEAR_ERROR_CALLBACK && is_callable($this->callback)) {
|
||||||
call_user_func($this->callback, $this);
|
call_user_func($this->callback, $this);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if ($this->mode & PEAR_ERROR_EXCEPTION) {
|
|
||||||
trigger_error("PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_ErrorStack for exceptions", E_USER_WARNING);
|
|
||||||
eval('$e = new Exception($this->message, $this->code);$e->PEAR_Error = $this;throw($e);');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// }}}
|
if ($this->mode & PEAR_ERROR_EXCEPTION) {
|
||||||
// {{{ getMode()
|
trigger_error("PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_Exception for exceptions", E_USER_WARNING);
|
||||||
|
eval('$e = new Exception($this->message, $this->code);throw($e);');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the error mode from an error object.
|
* Get the error mode from an error object.
|
||||||
|
@ -873,27 +902,22 @@ class PEAR_Error
|
||||||
* @return int error mode
|
* @return int error mode
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function getMode() {
|
function getMode()
|
||||||
|
{
|
||||||
return $this->mode;
|
return $this->mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ getCallback()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the callback function/method from an error object.
|
* Get the callback function/method from an error object.
|
||||||
*
|
*
|
||||||
* @return mixed callback function or object/method array
|
* @return mixed callback function or object/method array
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function getCallback() {
|
function getCallback()
|
||||||
|
{
|
||||||
return $this->callback;
|
return $this->callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ getMessage()
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the error message from an error object.
|
* Get the error message from an error object.
|
||||||
*
|
*
|
||||||
|
@ -905,10 +929,6 @@ class PEAR_Error
|
||||||
return ($this->error_message_prefix . $this->message);
|
return ($this->error_message_prefix . $this->message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ getCode()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get error code from an error object
|
* Get error code from an error object
|
||||||
*
|
*
|
||||||
|
@ -920,9 +940,6 @@ class PEAR_Error
|
||||||
return $this->code;
|
return $this->code;
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ getType()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the name of this error/exception.
|
* Get the name of this error/exception.
|
||||||
*
|
*
|
||||||
|
@ -934,9 +951,6 @@ class PEAR_Error
|
||||||
return get_class($this);
|
return get_class($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ getUserInfo()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get additional user-supplied information.
|
* Get additional user-supplied information.
|
||||||
*
|
*
|
||||||
|
@ -948,9 +962,6 @@ class PEAR_Error
|
||||||
return $this->userinfo;
|
return $this->userinfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ getDebugInfo()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get additional debug information supplied by the application.
|
* Get additional debug information supplied by the application.
|
||||||
*
|
*
|
||||||
|
@ -962,9 +973,6 @@ class PEAR_Error
|
||||||
return $this->getUserInfo();
|
return $this->getUserInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ getBacktrace()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the call backtrace from where the error was generated.
|
* Get the call backtrace from where the error was generated.
|
||||||
* Supported with PHP 4.3.0 or newer.
|
* Supported with PHP 4.3.0 or newer.
|
||||||
|
@ -975,15 +983,15 @@ class PEAR_Error
|
||||||
*/
|
*/
|
||||||
function getBacktrace($frame = null)
|
function getBacktrace($frame = null)
|
||||||
{
|
{
|
||||||
|
if (defined('PEAR_IGNORE_BACKTRACE')) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
if ($frame === null) {
|
if ($frame === null) {
|
||||||
return $this->backtrace;
|
return $this->backtrace;
|
||||||
}
|
}
|
||||||
return $this->backtrace[$frame];
|
return $this->backtrace[$frame];
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ addUserInfo()
|
|
||||||
|
|
||||||
function addUserInfo($info)
|
function addUserInfo($info)
|
||||||
{
|
{
|
||||||
if (empty($this->userinfo)) {
|
if (empty($this->userinfo)) {
|
||||||
|
@ -993,8 +1001,10 @@ class PEAR_Error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
function __toString()
|
||||||
// {{{ toString()
|
{
|
||||||
|
return $this->getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make a string representation of this object.
|
* Make a string representation of this object.
|
||||||
|
@ -1002,7 +1012,8 @@ class PEAR_Error
|
||||||
* @return string a string with an object summary
|
* @return string a string with an object summary
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function toString() {
|
function toString()
|
||||||
|
{
|
||||||
$modes = array();
|
$modes = array();
|
||||||
$levels = array(E_USER_NOTICE => 'notice',
|
$levels = array(E_USER_NOTICE => 'notice',
|
||||||
E_USER_WARNING => 'warning',
|
E_USER_WARNING => 'warning',
|
||||||
|
@ -1041,8 +1052,6 @@ class PEAR_Error
|
||||||
$this->error_message_prefix,
|
$this->error_message_prefix,
|
||||||
$this->userinfo);
|
$this->userinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1052,4 +1061,3 @@ class PEAR_Error
|
||||||
* c-basic-offset: 4
|
* c-basic-offset: 4
|
||||||
* End:
|
* End:
|
||||||
*/
|
*/
|
||||||
?>
|
|
||||||
|
|
|
@ -1,29 +1,31 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Class auto-loader
|
||||||
|
*
|
||||||
|
* PHP versions 4
|
||||||
|
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Stig Bakken <ssb@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: Autoloader.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/manual/en/core.ppm.php#core.ppm.pear-autoloader
|
||||||
|
* @since File available since Release 0.1
|
||||||
|
* @deprecated File deprecated in Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
|
||||||
// /* vim: set expandtab tabstop=4 shiftwidth=4: */
|
// /* vim: set expandtab tabstop=4 shiftwidth=4: */
|
||||||
// +----------------------------------------------------------------------+
|
|
||||||
// | PHP Version 5 |
|
|
||||||
// +----------------------------------------------------------------------+
|
|
||||||
// | Copyright (c) 1997-2004 The PHP Group |
|
|
||||||
// +----------------------------------------------------------------------+
|
|
||||||
// | This source file is subject to version 3.0 of the PHP license, |
|
|
||||||
// | that is bundled with this package in the file LICENSE, and is |
|
|
||||||
// | available through the world-wide-web at the following url: |
|
|
||||||
// | http://www.php.net/license/3_0.txt. |
|
|
||||||
// | If you did not receive a copy of the PHP license and are unable to |
|
|
||||||
// | obtain it through the world-wide-web, please send a note to |
|
|
||||||
// | license@php.net so we can mail you a copy immediately. |
|
|
||||||
// +----------------------------------------------------------------------+
|
|
||||||
// | Author: Stig Bakken <ssb@php.net> |
|
|
||||||
// | |
|
|
||||||
// +----------------------------------------------------------------------+
|
|
||||||
//
|
|
||||||
// $Id: Autoloader.php,v 1.11 2004/02/27 02:21:29 cellog Exp $
|
|
||||||
|
|
||||||
if (!extension_loaded("overload")) {
|
if (!extension_loaded("overload")) {
|
||||||
// die hard without ext/overload
|
// die hard without ext/overload
|
||||||
die("Rebuild PHP with the `overload' extension to use PEAR_Autoloader");
|
die("Rebuild PHP with the `overload' extension to use PEAR_Autoloader");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include for PEAR_Error and PEAR classes
|
||||||
|
*/
|
||||||
require_once "PEAR.php";
|
require_once "PEAR.php";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,7 +40,15 @@ require_once "PEAR.php";
|
||||||
* methods, an instance of each class providing separated methods is
|
* methods, an instance of each class providing separated methods is
|
||||||
* stored and called every time the aggregated method is called.
|
* stored and called every time the aggregated method is called.
|
||||||
*
|
*
|
||||||
* @author Stig Sæther Bakken <ssb@php.net>
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Stig Bakken <ssb@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/manual/en/core.ppm.php#core.ppm.pear-autoloader
|
||||||
|
* @since File available since Release 0.1
|
||||||
|
* @deprecated File deprecated in Release 1.4.0a1
|
||||||
*/
|
*/
|
||||||
class PEAR_Autoloader extends PEAR
|
class PEAR_Autoloader extends PEAR
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,47 +1,60 @@
|
||||||
<?php
|
<?php
|
||||||
//
|
/**
|
||||||
// +----------------------------------------------------------------------+
|
* PEAR_Builder for building PHP extensions (PECL packages)
|
||||||
// | PHP Version 5 |
|
*
|
||||||
// +----------------------------------------------------------------------+
|
* PHP versions 4 and 5
|
||||||
// | Copyright (c) 1997-2004 The PHP Group |
|
*
|
||||||
// +----------------------------------------------------------------------+
|
* @category pear
|
||||||
// | This source file is subject to version 3.0 of the PHP license, |
|
* @package PEAR
|
||||||
// | that is bundled with this package in the file LICENSE, and is |
|
* @author Stig Bakken <ssb@php.net>
|
||||||
// | available through the world-wide-web at the following url: |
|
* @author Greg Beaver <cellog@php.net>
|
||||||
// | http://www.php.net/license/3_0.txt. |
|
* @copyright 1997-2009 The Authors
|
||||||
// | If you did not receive a copy of the PHP license and are unable to |
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
// | obtain it through the world-wide-web, please send a note to |
|
* @version CVS: $Id: Builder.php 313024 2011-07-06 19:51:24Z dufuz $
|
||||||
// | license@php.net so we can mail you a copy immediately. |
|
* @link http://pear.php.net/package/PEAR
|
||||||
// +----------------------------------------------------------------------+
|
* @since File available since Release 0.1
|
||||||
// | Authors: Stig Sæther Bakken <ssb@php.net> |
|
*
|
||||||
// +----------------------------------------------------------------------+
|
* TODO: log output parameters in PECL command line
|
||||||
//
|
* TODO: msdev path in configuration
|
||||||
// $Id: Builder.php,v 1.16.2.3 2005/02/17 17:55:01 cellog Exp $
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Needed for extending PEAR_Builder
|
||||||
|
*/
|
||||||
require_once 'PEAR/Common.php';
|
require_once 'PEAR/Common.php';
|
||||||
|
require_once 'PEAR/PackageFile.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to handle building (compiling) extensions.
|
* Class to handle building (compiling) extensions.
|
||||||
*
|
*
|
||||||
* @author Stig Sæther Bakken <ssb@php.net>
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Stig Bakken <ssb@php.net>
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since PHP 4.0.2
|
||||||
|
* @see http://pear.php.net/manual/en/core.ppm.pear-builder.php
|
||||||
*/
|
*/
|
||||||
class PEAR_Builder extends PEAR_Common
|
class PEAR_Builder extends PEAR_Common
|
||||||
{
|
{
|
||||||
// {{{ properties
|
|
||||||
|
|
||||||
var $php_api_version = 0;
|
var $php_api_version = 0;
|
||||||
var $zend_module_api_no = 0;
|
var $zend_module_api_no = 0;
|
||||||
var $zend_extension_api_no = 0;
|
var $zend_extension_api_no = 0;
|
||||||
|
|
||||||
var $extensions_built = array();
|
var $extensions_built = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string Used for reporting when it is not possible to pass function
|
||||||
|
* via extra parameter, e.g. log, msdevCallback
|
||||||
|
*/
|
||||||
var $current_callback = null;
|
var $current_callback = null;
|
||||||
|
|
||||||
// used for msdev builds
|
// used for msdev builds
|
||||||
var $_lastline = null;
|
var $_lastline = null;
|
||||||
var $_firstline = null;
|
var $_firstline = null;
|
||||||
// }}}
|
|
||||||
// {{{ constructor
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PEAR_Builder constructor.
|
* PEAR_Builder constructor.
|
||||||
|
@ -56,35 +69,48 @@ class PEAR_Builder extends PEAR_Common
|
||||||
$this->setFrontendObject($ui);
|
$this->setFrontendObject($ui);
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
|
|
||||||
// {{{ _build_win32()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build an extension from source on windows.
|
* Build an extension from source on windows.
|
||||||
* requires msdev
|
* requires msdev
|
||||||
*/
|
*/
|
||||||
function _build_win32($descfile, $callback = null)
|
function _build_win32($descfile, $callback = null)
|
||||||
{
|
{
|
||||||
if (PEAR::isError($info = $this->infoFromDescriptionFile($descfile))) {
|
if (is_object($descfile)) {
|
||||||
return $info;
|
$pkg = $descfile;
|
||||||
|
$descfile = $pkg->getPackageFile();
|
||||||
|
} else {
|
||||||
|
$pf = &new PEAR_PackageFile($this->config, $this->debug);
|
||||||
|
$pkg = &$pf->fromPackageFile($descfile, PEAR_VALIDATE_NORMAL);
|
||||||
|
if (PEAR::isError($pkg)) {
|
||||||
|
return $pkg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$dir = dirname($descfile);
|
$dir = dirname($descfile);
|
||||||
$old_cwd = getcwd();
|
$old_cwd = getcwd();
|
||||||
|
|
||||||
if (!@chdir($dir)) {
|
if (!file_exists($dir) || !is_dir($dir) || !chdir($dir)) {
|
||||||
return $this->raiseError("could not chdir to $dir");
|
return $this->raiseError("could not chdir to $dir");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// packages that were in a .tar have the packagefile in this directory
|
||||||
|
$vdir = $pkg->getPackage() . '-' . $pkg->getVersion();
|
||||||
|
if (file_exists($dir) && is_dir($vdir)) {
|
||||||
|
if (!chdir($vdir)) {
|
||||||
|
return $this->raiseError("could not chdir to " . realpath($vdir));
|
||||||
|
}
|
||||||
|
|
||||||
|
$dir = getcwd();
|
||||||
|
}
|
||||||
|
|
||||||
$this->log(2, "building in $dir");
|
$this->log(2, "building in $dir");
|
||||||
|
|
||||||
$dsp = $info['package'].'.dsp';
|
$dsp = $pkg->getPackage().'.dsp';
|
||||||
if (!@is_file("$dir/$dsp")) {
|
if (!file_exists("$dir/$dsp")) {
|
||||||
return $this->raiseError("The DSP $dsp does not exist.");
|
return $this->raiseError("The DSP $dsp does not exist.");
|
||||||
}
|
}
|
||||||
// XXX TODO: make release build type configurable
|
// XXX TODO: make release build type configurable
|
||||||
$command = 'msdev '.$dsp.' /MAKE "'.$info['package']. ' - Release"';
|
$command = 'msdev '.$dsp.' /MAKE "'.$pkg->getPackage(). ' - Release"';
|
||||||
|
|
||||||
$this->current_callback = $callback;
|
|
||||||
$err = $this->_runCommand($command, array(&$this, 'msdevCallback'));
|
$err = $this->_runCommand($command, array(&$this, 'msdevCallback'));
|
||||||
if (PEAR::isError($err)) {
|
if (PEAR::isError($err)) {
|
||||||
return $err;
|
return $err;
|
||||||
|
@ -93,7 +119,7 @@ class PEAR_Builder extends PEAR_Common
|
||||||
// figure out the build platform and type
|
// figure out the build platform and type
|
||||||
$platform = 'Win32';
|
$platform = 'Win32';
|
||||||
$buildtype = 'Release';
|
$buildtype = 'Release';
|
||||||
if (preg_match('/.*?'.$info['package'].'\s-\s(\w+)\s(.*?)-+/i',$this->_firstline,$matches)) {
|
if (preg_match('/.*?'.$pkg->getPackage().'\s-\s(\w+)\s(.*?)-+/i',$this->_firstline,$matches)) {
|
||||||
$platform = $matches[1];
|
$platform = $matches[1];
|
||||||
$buildtype = $matches[2];
|
$buildtype = $matches[2];
|
||||||
}
|
}
|
||||||
|
@ -115,7 +141,7 @@ class PEAR_Builder extends PEAR_Common
|
||||||
// this regex depends on the build platform and type having been
|
// this regex depends on the build platform and type having been
|
||||||
// correctly identified above.
|
// correctly identified above.
|
||||||
$regex ='/.*?!IF\s+"\$\(CFG\)"\s+==\s+("'.
|
$regex ='/.*?!IF\s+"\$\(CFG\)"\s+==\s+("'.
|
||||||
$info['package'].'\s-\s'.
|
$pkg->getPackage().'\s-\s'.
|
||||||
$platform.'\s'.
|
$platform.'\s'.
|
||||||
$buildtype.'").*?'.
|
$buildtype.'").*?'.
|
||||||
'\/out:"(.*?)"/is';
|
'\/out:"(.*?)"/is';
|
||||||
|
@ -126,7 +152,8 @@ class PEAR_Builder extends PEAR_Common
|
||||||
} else {
|
} else {
|
||||||
return $this->raiseError("Could not retrieve output information from $dsp.");
|
return $this->raiseError("Could not retrieve output information from $dsp.");
|
||||||
}
|
}
|
||||||
if (@copy($outfile, "$dir/$out")) {
|
// realpath returns false if the file doesn't exist
|
||||||
|
if ($outfile && copy($outfile, "$dir/$out")) {
|
||||||
$outfile = "$dir/$out";
|
$outfile = "$dir/$out";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,10 +174,9 @@ class PEAR_Builder extends PEAR_Common
|
||||||
if (!$this->_firstline)
|
if (!$this->_firstline)
|
||||||
$this->_firstline = $data;
|
$this->_firstline = $data;
|
||||||
$this->_lastline = $data;
|
$this->_lastline = $data;
|
||||||
|
call_user_func($this->current_callback, $what, $data);
|
||||||
}
|
}
|
||||||
// }}}
|
|
||||||
|
|
||||||
// {{{ _harventInstDir
|
|
||||||
/**
|
/**
|
||||||
* @param string
|
* @param string
|
||||||
* @param string
|
* @param string
|
||||||
|
@ -191,16 +217,13 @@ class PEAR_Builder extends PEAR_Common
|
||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
|
|
||||||
// {{{ build()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build an extension from source. Runs "phpize" in the source
|
* Build an extension from source. Runs "phpize" in the source
|
||||||
* directory, but compiles in a temporary directory
|
* directory, but compiles in a temporary directory
|
||||||
* (/var/tmp/pear-build-USER/PACKAGE-VERSION).
|
* (TMPDIR/pear-build-USER/PACKAGE-VERSION).
|
||||||
*
|
*
|
||||||
* @param string $descfile path to XML package description file
|
* @param string|PEAR_PackageFile_v* $descfile path to XML package description file, or
|
||||||
|
* a PEAR_PackageFile object
|
||||||
*
|
*
|
||||||
* @param mixed $callback callback function used to report output,
|
* @param mixed $callback callback function used to report output,
|
||||||
* see PEAR_Builder::_runCommand for details
|
* see PEAR_Builder::_runCommand for details
|
||||||
|
@ -216,48 +239,97 @@ class PEAR_Builder extends PEAR_Common
|
||||||
* @access public
|
* @access public
|
||||||
*
|
*
|
||||||
* @see PEAR_Builder::_runCommand
|
* @see PEAR_Builder::_runCommand
|
||||||
* @see PEAR_Common::infoFromDescriptionFile
|
|
||||||
*/
|
*/
|
||||||
function build($descfile, $callback = null)
|
function build($descfile, $callback = null)
|
||||||
{
|
{
|
||||||
|
if (preg_match('/(\\/|\\\\|^)([^\\/\\\\]+)?php(.+)?$/',
|
||||||
|
$this->config->get('php_bin'), $matches)) {
|
||||||
|
if (isset($matches[2]) && strlen($matches[2]) &&
|
||||||
|
trim($matches[2]) != trim($this->config->get('php_prefix'))) {
|
||||||
|
$this->log(0, 'WARNING: php_bin ' . $this->config->get('php_bin') .
|
||||||
|
' appears to have a prefix ' . $matches[2] . ', but' .
|
||||||
|
' config variable php_prefix does not match');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($matches[3]) && strlen($matches[3]) &&
|
||||||
|
trim($matches[3]) != trim($this->config->get('php_suffix'))) {
|
||||||
|
$this->log(0, 'WARNING: php_bin ' . $this->config->get('php_bin') .
|
||||||
|
' appears to have a suffix ' . $matches[3] . ', but' .
|
||||||
|
' config variable php_suffix does not match');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->current_callback = $callback;
|
||||||
if (PEAR_OS == "Windows") {
|
if (PEAR_OS == "Windows") {
|
||||||
return $this->_build_win32($descfile, $callback);
|
return $this->_build_win32($descfile, $callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PEAR_OS != 'Unix') {
|
if (PEAR_OS != 'Unix') {
|
||||||
return $this->raiseError("building extensions not supported on this platform");
|
return $this->raiseError("building extensions not supported on this platform");
|
||||||
}
|
}
|
||||||
if (PEAR::isError($info = $this->infoFromDescriptionFile($descfile))) {
|
|
||||||
return $info;
|
if (is_object($descfile)) {
|
||||||
|
$pkg = $descfile;
|
||||||
|
$descfile = $pkg->getPackageFile();
|
||||||
|
if (is_a($pkg, 'PEAR_PackageFile_v1')) {
|
||||||
|
$dir = dirname($descfile);
|
||||||
|
} else {
|
||||||
|
$dir = $pkg->_config->get('temp_dir') . '/' . $pkg->getName();
|
||||||
|
// automatically delete at session end
|
||||||
|
$this->addTempFile($dir);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$pf = &new PEAR_PackageFile($this->config);
|
||||||
|
$pkg = &$pf->fromPackageFile($descfile, PEAR_VALIDATE_NORMAL);
|
||||||
|
if (PEAR::isError($pkg)) {
|
||||||
|
return $pkg;
|
||||||
}
|
}
|
||||||
$dir = dirname($descfile);
|
$dir = dirname($descfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find config. outside of normal path - e.g. config.m4
|
||||||
|
foreach (array_keys($pkg->getInstallationFileList()) as $item) {
|
||||||
|
if (stristr(basename($item), 'config.m4') && dirname($item) != '.') {
|
||||||
|
$dir .= DIRECTORY_SEPARATOR . dirname($item);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$old_cwd = getcwd();
|
$old_cwd = getcwd();
|
||||||
if (!@chdir($dir)) {
|
if (!file_exists($dir) || !is_dir($dir) || !chdir($dir)) {
|
||||||
return $this->raiseError("could not chdir to $dir");
|
return $this->raiseError("could not chdir to $dir");
|
||||||
}
|
}
|
||||||
$vdir = "$info[package]-$info[version]";
|
|
||||||
|
$vdir = $pkg->getPackage() . '-' . $pkg->getVersion();
|
||||||
if (is_dir($vdir)) {
|
if (is_dir($vdir)) {
|
||||||
chdir($vdir);
|
chdir($vdir);
|
||||||
}
|
}
|
||||||
|
|
||||||
$dir = getcwd();
|
$dir = getcwd();
|
||||||
$this->log(2, "building in $dir");
|
$this->log(2, "building in $dir");
|
||||||
$this->current_callback = $callback;
|
|
||||||
putenv('PATH=' . $this->config->get('bin_dir') . ':' . getenv('PATH'));
|
putenv('PATH=' . $this->config->get('bin_dir') . ':' . getenv('PATH'));
|
||||||
$err = $this->_runCommand("phpize", array(&$this, 'phpizeCallback'));
|
$err = $this->_runCommand($this->config->get('php_prefix')
|
||||||
|
. "phpize" .
|
||||||
|
$this->config->get('php_suffix'),
|
||||||
|
array(&$this, 'phpizeCallback'));
|
||||||
if (PEAR::isError($err)) {
|
if (PEAR::isError($err)) {
|
||||||
return $err;
|
return $err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$err) {
|
if (!$err) {
|
||||||
return $this->raiseError("`phpize' failed");
|
return $this->raiseError("`phpize' failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
// {{{ start of interactive part
|
// {{{ start of interactive part
|
||||||
$configure_command = "$dir/configure";
|
$configure_command = "$dir/configure";
|
||||||
if (isset($info['configure_options'])) {
|
$configure_options = $pkg->getConfigureOptions();
|
||||||
foreach ($info['configure_options'] as $o) {
|
if ($configure_options) {
|
||||||
|
foreach ($configure_options as $o) {
|
||||||
|
$default = array_key_exists('default', $o) ? $o['default'] : null;
|
||||||
list($r) = $this->ui->userDialog('build',
|
list($r) = $this->ui->userDialog('build',
|
||||||
array($o['prompt']),
|
array($o['prompt']),
|
||||||
array('text'),
|
array('text'),
|
||||||
array(@$o['default']));
|
array($default));
|
||||||
if (substr($o['name'], 0, 5) == 'with-' &&
|
if (substr($o['name'], 0, 5) == 'with-' &&
|
||||||
($r == 'yes' || $r == 'autodetect')) {
|
($r == 'yes' || $r == 'autodetect')) {
|
||||||
$configure_command .= " --$o[name]";
|
$configure_command .= " --$o[name]";
|
||||||
|
@ -272,37 +344,38 @@ class PEAR_Builder extends PEAR_Common
|
||||||
if (!$user=getenv('USER')) {
|
if (!$user=getenv('USER')) {
|
||||||
$user='defaultuser';
|
$user='defaultuser';
|
||||||
}
|
}
|
||||||
$build_basedir = "/var/tmp/pear-build-$user";
|
|
||||||
$build_dir = "$build_basedir/$info[package]-$info[version]";
|
$tmpdir = $this->config->get('temp_dir');
|
||||||
$inst_dir = "$build_basedir/install-$info[package]-$info[version]";
|
$build_basedir = System::mktemp(' -t "' . $tmpdir . '" -d "pear-build-' . $user . '"');
|
||||||
|
$build_dir = "$build_basedir/$vdir";
|
||||||
|
$inst_dir = "$build_basedir/install-$vdir";
|
||||||
$this->log(1, "building in $build_dir");
|
$this->log(1, "building in $build_dir");
|
||||||
if (is_dir($build_dir)) {
|
if (is_dir($build_dir)) {
|
||||||
System::rm('-rf', $build_dir);
|
System::rm(array('-rf', $build_dir));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!System::mkDir(array('-p', $build_dir))) {
|
if (!System::mkDir(array('-p', $build_dir))) {
|
||||||
return $this->raiseError("could not create build dir: $build_dir");
|
return $this->raiseError("could not create build dir: $build_dir");
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->addTempFile($build_dir);
|
$this->addTempFile($build_dir);
|
||||||
if (!System::mkDir(array('-p', $inst_dir))) {
|
if (!System::mkDir(array('-p', $inst_dir))) {
|
||||||
return $this->raiseError("could not create temporary install dir: $inst_dir");
|
return $this->raiseError("could not create temporary install dir: $inst_dir");
|
||||||
}
|
}
|
||||||
$this->addTempFile($inst_dir);
|
$this->addTempFile($inst_dir);
|
||||||
|
|
||||||
if (getenv('MAKE')) {
|
$make_command = getenv('MAKE') ? getenv('MAKE') : 'make';
|
||||||
$make_command = getenv('MAKE');
|
|
||||||
} else {
|
|
||||||
$make_command = 'make';
|
|
||||||
}
|
|
||||||
$to_run = array(
|
$to_run = array(
|
||||||
$configure_command,
|
$configure_command,
|
||||||
$make_command,
|
$make_command,
|
||||||
"$make_command INSTALL_ROOT=\"$inst_dir\" install",
|
"$make_command INSTALL_ROOT=\"$inst_dir\" install",
|
||||||
"find \"$inst_dir\" -ls"
|
"find \"$inst_dir\" | xargs ls -dils"
|
||||||
);
|
);
|
||||||
if (!@chdir($build_dir)) {
|
if (!file_exists($build_dir) || !is_dir($build_dir) || !chdir($build_dir)) {
|
||||||
return $this->raiseError("could not chdir to $build_dir");
|
return $this->raiseError("could not chdir to $build_dir");
|
||||||
}
|
}
|
||||||
putenv('PHP_PEAR_VERSION=@PEAR-VER@');
|
putenv('PHP_PEAR_VERSION=1.9.4');
|
||||||
foreach ($to_run as $cmd) {
|
foreach ($to_run as $cmd) {
|
||||||
$err = $this->_runCommand($cmd, $callback);
|
$err = $this->_runCommand($cmd, $callback);
|
||||||
if (PEAR::isError($err)) {
|
if (PEAR::isError($err)) {
|
||||||
|
@ -319,15 +392,14 @@ class PEAR_Builder extends PEAR_Common
|
||||||
return $this->raiseError("no `modules' directory found");
|
return $this->raiseError("no `modules' directory found");
|
||||||
}
|
}
|
||||||
$built_files = array();
|
$built_files = array();
|
||||||
$prefix = exec("php-config --prefix");
|
$prefix = exec($this->config->get('php_prefix')
|
||||||
|
. "php-config" .
|
||||||
|
$this->config->get('php_suffix') . " --prefix");
|
||||||
$this->_harvestInstDir($prefix, $inst_dir . DIRECTORY_SEPARATOR . $prefix, $built_files);
|
$this->_harvestInstDir($prefix, $inst_dir . DIRECTORY_SEPARATOR . $prefix, $built_files);
|
||||||
chdir($old_cwd);
|
chdir($old_cwd);
|
||||||
return $built_files;
|
return $built_files;
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ phpizeCallback()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Message callback function used when running the "phpize"
|
* Message callback function used when running the "phpize"
|
||||||
* program. Extracts the API numbers used. Ignores other message
|
* program. Extracts the API numbers used. Ignores other message
|
||||||
|
@ -361,9 +433,6 @@ class PEAR_Builder extends PEAR_Common
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ _runCommand()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run an external command, using a message callback to report
|
* Run an external command, using a message callback to report
|
||||||
* output. The command will be run through popen and output is
|
* output. The command will be run through popen and output is
|
||||||
|
@ -383,7 +452,7 @@ class PEAR_Builder extends PEAR_Common
|
||||||
function _runCommand($command, $callback = null)
|
function _runCommand($command, $callback = null)
|
||||||
{
|
{
|
||||||
$this->log(1, "running: $command");
|
$this->log(1, "running: $command");
|
||||||
$pp = @popen("$command 2>&1", "r");
|
$pp = popen("$command 2>&1", "r");
|
||||||
if (!$pp) {
|
if (!$pp) {
|
||||||
return $this->raiseError("failed to run `$command'");
|
return $this->raiseError("failed to run `$command'");
|
||||||
}
|
}
|
||||||
|
@ -402,13 +471,11 @@ class PEAR_Builder extends PEAR_Common
|
||||||
if ($callback && isset($olddbg)) {
|
if ($callback && isset($olddbg)) {
|
||||||
$callback[0]->debug = $olddbg;
|
$callback[0]->debug = $olddbg;
|
||||||
}
|
}
|
||||||
$exitcode = @pclose($pp);
|
|
||||||
|
$exitcode = is_resource($pp) ? pclose($pp) : -1;
|
||||||
return ($exitcode == 0);
|
return ($exitcode == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ log()
|
|
||||||
|
|
||||||
function log($level, $msg)
|
function log($level, $msg)
|
||||||
{
|
{
|
||||||
if ($this->current_callback) {
|
if ($this->current_callback) {
|
||||||
|
@ -419,8 +486,4 @@ class PEAR_Builder extends PEAR_Common
|
||||||
}
|
}
|
||||||
return PEAR_Common::log($level, $msg);
|
return PEAR_Common::log($level, $msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,68 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PEAR_ChannelFile_Parser for parsing channel.xml
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: Parser.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* base xml parser class
|
||||||
|
*/
|
||||||
|
require_once 'PEAR/XMLParser.php';
|
||||||
|
require_once 'PEAR/ChannelFile.php';
|
||||||
|
/**
|
||||||
|
* Parser for channel.xml
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
class PEAR_ChannelFile_Parser extends PEAR_XMLParser
|
||||||
|
{
|
||||||
|
var $_config;
|
||||||
|
var $_logger;
|
||||||
|
var $_registry;
|
||||||
|
|
||||||
|
function setConfig(&$c)
|
||||||
|
{
|
||||||
|
$this->_config = &$c;
|
||||||
|
$this->_registry = &$c->getRegistry();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setLogger(&$l)
|
||||||
|
{
|
||||||
|
$this->_logger = &$l;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parse($data, $file)
|
||||||
|
{
|
||||||
|
if (PEAR::isError($err = parent::parse($data, $file))) {
|
||||||
|
return $err;
|
||||||
|
}
|
||||||
|
|
||||||
|
$ret = new PEAR_ChannelFile;
|
||||||
|
$ret->setConfig($this->_config);
|
||||||
|
if (isset($this->_logger)) {
|
||||||
|
$ret->setLogger($this->_logger);
|
||||||
|
}
|
||||||
|
|
||||||
|
$ret->fromArray($this->_unserializedData);
|
||||||
|
// make sure the filelist is in the easy to read format needed
|
||||||
|
$ret->flattenFilelist();
|
||||||
|
$ret->setPackagefile($file, $archive);
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,25 +1,26 @@
|
||||||
<?php
|
<?php
|
||||||
//
|
/**
|
||||||
// +----------------------------------------------------------------------+
|
* PEAR_Command, command pattern class
|
||||||
// | PHP Version 5 |
|
*
|
||||||
// +----------------------------------------------------------------------+
|
* PHP versions 4 and 5
|
||||||
// | Copyright (c) 1997-2004 The PHP Group |
|
*
|
||||||
// +----------------------------------------------------------------------+
|
* @category pear
|
||||||
// | This source file is subject to version 3.0 of the PHP license, |
|
* @package PEAR
|
||||||
// | that is bundled with this package in the file LICENSE, and is |
|
* @author Stig Bakken <ssb@php.net>
|
||||||
// | available through the world-wide-web at the following url: |
|
* @author Greg Beaver <cellog@php.net>
|
||||||
// | http://www.php.net/license/3_0.txt. |
|
* @copyright 1997-2009 The Authors
|
||||||
// | If you did not receive a copy of the PHP license and are unable to |
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
// | obtain it through the world-wide-web, please send a note to |
|
* @version CVS: $Id: Command.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
// | license@php.net so we can mail you a copy immediately. |
|
* @link http://pear.php.net/package/PEAR
|
||||||
// +----------------------------------------------------------------------+
|
* @since File available since Release 0.1
|
||||||
// | Author: Stig Bakken <ssb@php.net> |
|
*/
|
||||||
// +----------------------------------------------------------------------+
|
|
||||||
//
|
|
||||||
// $Id: Command.php,v 1.24 2004/05/16 15:43:30 pajoye Exp $
|
|
||||||
|
|
||||||
|
/**
|
||||||
require_once "PEAR.php";
|
* Needed for error handling
|
||||||
|
*/
|
||||||
|
require_once 'PEAR.php';
|
||||||
|
require_once 'PEAR/Frontend.php';
|
||||||
|
require_once 'PEAR/XMLParser.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of commands and what classes they are implemented in.
|
* List of commands and what classes they are implemented in.
|
||||||
|
@ -27,6 +28,12 @@ require_once "PEAR.php";
|
||||||
*/
|
*/
|
||||||
$GLOBALS['_PEAR_Command_commandlist'] = array();
|
$GLOBALS['_PEAR_Command_commandlist'] = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of commands and their descriptions
|
||||||
|
* @var array command => description
|
||||||
|
*/
|
||||||
|
$GLOBALS['_PEAR_Command_commanddesc'] = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of shortcuts to common commands.
|
* List of shortcuts to common commands.
|
||||||
* @var array shortcut => command
|
* @var array shortcut => command
|
||||||
|
@ -39,18 +46,6 @@ $GLOBALS['_PEAR_Command_shortcuts'] = array();
|
||||||
*/
|
*/
|
||||||
$GLOBALS['_PEAR_Command_objects'] = array();
|
$GLOBALS['_PEAR_Command_objects'] = array();
|
||||||
|
|
||||||
/**
|
|
||||||
* Which user interface class is being used.
|
|
||||||
* @var string class name
|
|
||||||
*/
|
|
||||||
$GLOBALS['_PEAR_Command_uiclass'] = 'PEAR_Frontend_CLI';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Instance of $_PEAR_Command_uiclass.
|
|
||||||
* @var object
|
|
||||||
*/
|
|
||||||
$GLOBALS['_PEAR_Command_uiobject'] = null;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PEAR command class, a simple factory class for administrative
|
* PEAR command class, a simple factory class for administrative
|
||||||
* commands.
|
* commands.
|
||||||
|
@ -93,6 +88,15 @@ $GLOBALS['_PEAR_Command_uiobject'] = null;
|
||||||
* - DON'T USE EXIT OR DIE! Always use pear errors. From static
|
* - DON'T USE EXIT OR DIE! Always use pear errors. From static
|
||||||
* classes do PEAR::raiseError(), from other classes do
|
* classes do PEAR::raiseError(), from other classes do
|
||||||
* $this->raiseError().
|
* $this->raiseError().
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Stig Bakken <ssb@php.net>
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 0.1
|
||||||
*/
|
*/
|
||||||
class PEAR_Command
|
class PEAR_Command
|
||||||
{
|
{
|
||||||
|
@ -109,7 +113,7 @@ class PEAR_Command
|
||||||
* @access public
|
* @access public
|
||||||
* @static
|
* @static
|
||||||
*/
|
*/
|
||||||
function factory($command, &$config)
|
function &factory($command, &$config)
|
||||||
{
|
{
|
||||||
if (empty($GLOBALS['_PEAR_Command_commandlist'])) {
|
if (empty($GLOBALS['_PEAR_Command_commandlist'])) {
|
||||||
PEAR_Command::registerCommands();
|
PEAR_Command::registerCommands();
|
||||||
|
@ -118,13 +122,35 @@ class PEAR_Command
|
||||||
$command = $GLOBALS['_PEAR_Command_shortcuts'][$command];
|
$command = $GLOBALS['_PEAR_Command_shortcuts'][$command];
|
||||||
}
|
}
|
||||||
if (!isset($GLOBALS['_PEAR_Command_commandlist'][$command])) {
|
if (!isset($GLOBALS['_PEAR_Command_commandlist'][$command])) {
|
||||||
return PEAR::raiseError("unknown command `$command'");
|
$a = PEAR::raiseError("unknown command `$command'");
|
||||||
|
return $a;
|
||||||
}
|
}
|
||||||
$class = $GLOBALS['_PEAR_Command_commandlist'][$command];
|
$class = $GLOBALS['_PEAR_Command_commandlist'][$command];
|
||||||
|
if (!class_exists($class)) {
|
||||||
|
require_once $GLOBALS['_PEAR_Command_objects'][$class];
|
||||||
|
}
|
||||||
|
if (!class_exists($class)) {
|
||||||
|
$a = PEAR::raiseError("unknown command `$command'");
|
||||||
|
return $a;
|
||||||
|
}
|
||||||
|
$ui =& PEAR_Command::getFrontendObject();
|
||||||
|
$obj = &new $class($ui, $config);
|
||||||
|
return $obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ & getObject()
|
||||||
|
function &getObject($command)
|
||||||
|
{
|
||||||
|
$class = $GLOBALS['_PEAR_Command_commandlist'][$command];
|
||||||
|
if (!class_exists($class)) {
|
||||||
|
require_once $GLOBALS['_PEAR_Command_objects'][$class];
|
||||||
|
}
|
||||||
if (!class_exists($class)) {
|
if (!class_exists($class)) {
|
||||||
return PEAR::raiseError("unknown command `$command'");
|
return PEAR::raiseError("unknown command `$command'");
|
||||||
}
|
}
|
||||||
$ui =& PEAR_Command::getFrontendObject();
|
$ui =& PEAR_Command::getFrontendObject();
|
||||||
|
$config = &PEAR_Config::singleton();
|
||||||
$obj = &new $class($ui, $config);
|
$obj = &new $class($ui, $config);
|
||||||
return $obj;
|
return $obj;
|
||||||
}
|
}
|
||||||
|
@ -135,15 +161,13 @@ class PEAR_Command
|
||||||
/**
|
/**
|
||||||
* Get instance of frontend object.
|
* Get instance of frontend object.
|
||||||
*
|
*
|
||||||
* @return object
|
* @return object|PEAR_Error
|
||||||
* @static
|
* @static
|
||||||
*/
|
*/
|
||||||
function &getFrontendObject()
|
function &getFrontendObject()
|
||||||
{
|
{
|
||||||
if (empty($GLOBALS['_PEAR_Command_uiobject'])) {
|
$a = &PEAR_Frontend::singleton();
|
||||||
$GLOBALS['_PEAR_Command_uiobject'] = &new $GLOBALS['_PEAR_Command_uiclass'];
|
return $a;
|
||||||
}
|
|
||||||
return $GLOBALS['_PEAR_Command_uiobject'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
|
@ -159,59 +183,13 @@ class PEAR_Command
|
||||||
*/
|
*/
|
||||||
function &setFrontendClass($uiclass)
|
function &setFrontendClass($uiclass)
|
||||||
{
|
{
|
||||||
if (is_object($GLOBALS['_PEAR_Command_uiobject']) &&
|
$a = &PEAR_Frontend::setFrontendClass($uiclass);
|
||||||
is_a($GLOBALS['_PEAR_Command_uiobject'], $uiclass)) {
|
return $a;
|
||||||
return $GLOBALS['_PEAR_Command_uiobject'];
|
|
||||||
}
|
|
||||||
if (!class_exists($uiclass)) {
|
|
||||||
$file = str_replace('_', '/', $uiclass) . '.php';
|
|
||||||
if (PEAR_Command::isIncludeable($file)) {
|
|
||||||
include_once $file;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (class_exists($uiclass)) {
|
|
||||||
$obj = &new $uiclass;
|
|
||||||
// quick test to see if this class implements a few of the most
|
|
||||||
// important frontend methods
|
|
||||||
if (method_exists($obj, 'userConfirm')) {
|
|
||||||
$GLOBALS['_PEAR_Command_uiobject'] = &$obj;
|
|
||||||
$GLOBALS['_PEAR_Command_uiclass'] = $uiclass;
|
|
||||||
return $obj;
|
|
||||||
} else {
|
|
||||||
$err = PEAR::raiseError("not a frontend class: $uiclass");
|
|
||||||
return $err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$err = PEAR::raiseError("no such class: $uiclass");
|
|
||||||
return $err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
// {{{ setFrontendType()
|
// {{{ setFrontendType()
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ isIncludeable()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $path relative or absolute include path
|
|
||||||
* @return boolean
|
|
||||||
* @static
|
|
||||||
*/
|
|
||||||
function isIncludeable($path)
|
|
||||||
{
|
|
||||||
if (file_exists($path) && is_readable($path)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
$ipath = explode(PATH_SEPARATOR, ini_get('include_path'));
|
|
||||||
foreach ($ipath as $include) {
|
|
||||||
$test = realpath($include . DIRECTORY_SEPARATOR . $path);
|
|
||||||
if (file_exists($test) && is_readable($test)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set current frontend.
|
* Set current frontend.
|
||||||
*
|
*
|
||||||
|
@ -249,9 +227,13 @@ class PEAR_Command
|
||||||
*/
|
*/
|
||||||
function registerCommands($merge = false, $dir = null)
|
function registerCommands($merge = false, $dir = null)
|
||||||
{
|
{
|
||||||
|
$parser = new PEAR_XMLParser;
|
||||||
if ($dir === null) {
|
if ($dir === null) {
|
||||||
$dir = dirname(__FILE__) . '/Command';
|
$dir = dirname(__FILE__) . '/Command';
|
||||||
}
|
}
|
||||||
|
if (!is_dir($dir)) {
|
||||||
|
return PEAR::raiseError("registerCommands: opendir($dir) '$dir' does not exist or is not a directory");
|
||||||
|
}
|
||||||
$dp = @opendir($dir);
|
$dp = @opendir($dir);
|
||||||
if (empty($dp)) {
|
if (empty($dp)) {
|
||||||
return PEAR::raiseError("registerCommands: opendir($dir) failed");
|
return PEAR::raiseError("registerCommands: opendir($dir) failed");
|
||||||
|
@ -259,27 +241,58 @@ class PEAR_Command
|
||||||
if (!$merge) {
|
if (!$merge) {
|
||||||
$GLOBALS['_PEAR_Command_commandlist'] = array();
|
$GLOBALS['_PEAR_Command_commandlist'] = array();
|
||||||
}
|
}
|
||||||
while ($entry = readdir($dp)) {
|
|
||||||
if ($entry{0} == '.' || substr($entry, -4) != '.php' || $entry == 'Common.php') {
|
while ($file = readdir($dp)) {
|
||||||
|
if ($file{0} == '.' || substr($file, -4) != '.xml') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$class = "PEAR_Command_".substr($entry, 0, -4);
|
|
||||||
$file = "$dir/$entry";
|
$f = substr($file, 0, -4);
|
||||||
include_once $file;
|
$class = "PEAR_Command_" . $f;
|
||||||
// List of commands
|
// List of commands
|
||||||
if (empty($GLOBALS['_PEAR_Command_objects'][$class])) {
|
if (empty($GLOBALS['_PEAR_Command_objects'][$class])) {
|
||||||
$GLOBALS['_PEAR_Command_objects'][$class] = &new $class($ui, $config);
|
$GLOBALS['_PEAR_Command_objects'][$class] = "$dir/" . $f . '.php';
|
||||||
}
|
}
|
||||||
$implements = $GLOBALS['_PEAR_Command_objects'][$class]->getCommands();
|
|
||||||
|
$parser->parse(file_get_contents("$dir/$file"));
|
||||||
|
$implements = $parser->getData();
|
||||||
foreach ($implements as $command => $desc) {
|
foreach ($implements as $command => $desc) {
|
||||||
$GLOBALS['_PEAR_Command_commandlist'][$command] = $class;
|
if ($command == 'attribs') {
|
||||||
$GLOBALS['_PEAR_Command_commanddesc'][$command] = $desc;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($GLOBALS['_PEAR_Command_commandlist'][$command])) {
|
||||||
|
return PEAR::raiseError('Command "' . $command . '" already registered in ' .
|
||||||
|
'class "' . $GLOBALS['_PEAR_Command_commandlist'][$command] . '"');
|
||||||
|
}
|
||||||
|
|
||||||
|
$GLOBALS['_PEAR_Command_commandlist'][$command] = $class;
|
||||||
|
$GLOBALS['_PEAR_Command_commanddesc'][$command] = $desc['summary'];
|
||||||
|
if (isset($desc['shortcut'])) {
|
||||||
|
$shortcut = $desc['shortcut'];
|
||||||
|
if (isset($GLOBALS['_PEAR_Command_shortcuts'][$shortcut])) {
|
||||||
|
return PEAR::raiseError('Command shortcut "' . $shortcut . '" already ' .
|
||||||
|
'registered to command "' . $command . '" in class "' .
|
||||||
|
$GLOBALS['_PEAR_Command_commandlist'][$command] . '"');
|
||||||
}
|
}
|
||||||
$shortcuts = $GLOBALS['_PEAR_Command_objects'][$class]->getShortcuts();
|
|
||||||
foreach ($shortcuts as $shortcut => $command) {
|
|
||||||
$GLOBALS['_PEAR_Command_shortcuts'][$shortcut] = $command;
|
$GLOBALS['_PEAR_Command_shortcuts'][$shortcut] = $command;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isset($desc['options']) && $desc['options']) {
|
||||||
|
foreach ($desc['options'] as $oname => $option) {
|
||||||
|
if (isset($option['shortopt']) && strlen($option['shortopt']) > 1) {
|
||||||
|
return PEAR::raiseError('Option "' . $oname . '" short option "' .
|
||||||
|
$option['shortopt'] . '" must be ' .
|
||||||
|
'only 1 character in Command "' . $command . '" in class "' .
|
||||||
|
$class . '"');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ksort($GLOBALS['_PEAR_Command_shortcuts']);
|
||||||
|
ksort($GLOBALS['_PEAR_Command_commandlist']);
|
||||||
@closedir($dp);
|
@closedir($dp);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -343,11 +356,13 @@ class PEAR_Command
|
||||||
if (empty($GLOBALS['_PEAR_Command_commandlist'])) {
|
if (empty($GLOBALS['_PEAR_Command_commandlist'])) {
|
||||||
PEAR_Command::registerCommands();
|
PEAR_Command::registerCommands();
|
||||||
}
|
}
|
||||||
|
if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) {
|
||||||
|
$command = $GLOBALS['_PEAR_Command_shortcuts'][$command];
|
||||||
|
}
|
||||||
if (!isset($GLOBALS['_PEAR_Command_commandlist'][$command])) {
|
if (!isset($GLOBALS['_PEAR_Command_commandlist'][$command])) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
$class = $GLOBALS['_PEAR_Command_commandlist'][$command];
|
$obj = &PEAR_Command::getObject($command);
|
||||||
$obj = &$GLOBALS['_PEAR_Command_objects'][$class];
|
|
||||||
return $obj->getGetoptArgs($command, $short_args, $long_args);
|
return $obj->getGetoptArgs($command, $short_args, $long_args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -386,13 +401,14 @@ class PEAR_Command
|
||||||
function getHelp($command)
|
function getHelp($command)
|
||||||
{
|
{
|
||||||
$cmds = PEAR_Command::getCommands();
|
$cmds = PEAR_Command::getCommands();
|
||||||
|
if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) {
|
||||||
|
$command = $GLOBALS['_PEAR_Command_shortcuts'][$command];
|
||||||
|
}
|
||||||
if (isset($cmds[$command])) {
|
if (isset($cmds[$command])) {
|
||||||
$class = $cmds[$command];
|
$obj = &PEAR_Command::getObject($command);
|
||||||
return $GLOBALS['_PEAR_Command_objects'][$class]->getHelp($command);
|
return $obj->getHelp($command);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// }}}
|
// }}}
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
|
@ -1,43 +1,53 @@
|
||||||
<?php
|
<?php
|
||||||
//
|
/**
|
||||||
// +----------------------------------------------------------------------+
|
* PEAR_Command_Auth (login, logout commands)
|
||||||
// | PHP Version 5 |
|
*
|
||||||
// +----------------------------------------------------------------------+
|
* PHP versions 4 and 5
|
||||||
// | Copyright (c) 1997-2004 The PHP Group |
|
*
|
||||||
// +----------------------------------------------------------------------+
|
* @category pear
|
||||||
// | This source file is subject to version 3.0 of the PHP license, |
|
* @package PEAR
|
||||||
// | that is bundled with this package in the file LICENSE, and is |
|
* @author Stig Bakken <ssb@php.net>
|
||||||
// | available through the world-wide-web at the following url: |
|
* @author Greg Beaver <cellog@php.net>
|
||||||
// | http://www.php.net/license/3_0.txt. |
|
* @copyright 1997-2009 The Authors
|
||||||
// | If you did not receive a copy of the PHP license and are unable to |
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
// | obtain it through the world-wide-web, please send a note to |
|
* @version CVS: $Id: Auth.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
// | license@php.net so we can mail you a copy immediately. |
|
* @link http://pear.php.net/package/PEAR
|
||||||
// +----------------------------------------------------------------------+
|
* @since File available since Release 0.1
|
||||||
// | Author: Stig Bakken <ssb@php.net> |
|
* @deprecated since 1.8.0alpha1
|
||||||
// +----------------------------------------------------------------------+
|
*/
|
||||||
//
|
|
||||||
// $Id: Auth.php,v 1.15 2004/01/08 17:33:13 sniper Exp $
|
|
||||||
|
|
||||||
require_once "PEAR/Command/Common.php";
|
|
||||||
require_once "PEAR/Remote.php";
|
|
||||||
require_once "PEAR/Config.php";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PEAR commands for managing configuration data.
|
* base class
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
class PEAR_Command_Auth extends PEAR_Command_Common
|
require_once 'PEAR/Command/Channels.php';
|
||||||
{
|
|
||||||
// {{{ properties
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PEAR commands for login/logout
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Stig Bakken <ssb@php.net>
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 0.1
|
||||||
|
* @deprecated since 1.8.0alpha1
|
||||||
|
*/
|
||||||
|
class PEAR_Command_Auth extends PEAR_Command_Channels
|
||||||
|
{
|
||||||
var $commands = array(
|
var $commands = array(
|
||||||
'login' => array(
|
'login' => array(
|
||||||
'summary' => 'Connects and authenticates to remote server',
|
'summary' => 'Connects and authenticates to remote server [Deprecated in favor of channel-login]',
|
||||||
'shortcut' => 'li',
|
'shortcut' => 'li',
|
||||||
'function' => 'doLogin',
|
'function' => 'doLogin',
|
||||||
'options' => array(),
|
'options' => array(),
|
||||||
'doc' => '
|
'doc' => '<channel name>
|
||||||
Log in to the remote server. To use remote functions in the installer
|
WARNING: This function is deprecated in favor of using channel-login
|
||||||
|
|
||||||
|
Log in to a remote channel server. If <channel name> is not supplied,
|
||||||
|
the default channel is used. To use remote functions in the installer
|
||||||
that require any kind of privileges, you need to log in first. The
|
that require any kind of privileges, you need to log in first. The
|
||||||
username and password you enter here will be stored in your per-user
|
username and password you enter here will be stored in your per-user
|
||||||
PEAR configuration (~/.pearrc on Unix-like systems). After logging
|
PEAR configuration (~/.pearrc on Unix-like systems). After logging
|
||||||
|
@ -45,11 +55,13 @@ in, your username and password will be sent along in subsequent
|
||||||
operations on the remote server.',
|
operations on the remote server.',
|
||||||
),
|
),
|
||||||
'logout' => array(
|
'logout' => array(
|
||||||
'summary' => 'Logs out from the remote server',
|
'summary' => 'Logs out from the remote server [Deprecated in favor of channel-logout]',
|
||||||
'shortcut' => 'lo',
|
'shortcut' => 'lo',
|
||||||
'function' => 'doLogout',
|
'function' => 'doLogout',
|
||||||
'options' => array(),
|
'options' => array(),
|
||||||
'doc' => '
|
'doc' => '
|
||||||
|
WARNING: This function is deprecated in favor of using channel-logout
|
||||||
|
|
||||||
Logs out from the remote server. This command does not actually
|
Logs out from the remote server. This command does not actually
|
||||||
connect to the remote server, it only deletes the stored username and
|
connect to the remote server, it only deletes the stored username and
|
||||||
password from your user configuration.',
|
password from your user configuration.',
|
||||||
|
@ -57,10 +69,6 @@ password from your user configuration.',
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// }}}
|
|
||||||
|
|
||||||
// {{{ constructor
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PEAR_Command_Auth constructor.
|
* PEAR_Command_Auth constructor.
|
||||||
*
|
*
|
||||||
|
@ -68,88 +76,6 @@ password from your user configuration.',
|
||||||
*/
|
*/
|
||||||
function PEAR_Command_Auth(&$ui, &$config)
|
function PEAR_Command_Auth(&$ui, &$config)
|
||||||
{
|
{
|
||||||
parent::PEAR_Command_Common($ui, $config);
|
parent::PEAR_Command_Channels($ui, $config);
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
|
|
||||||
// {{{ doLogin()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Execute the 'login' command.
|
|
||||||
*
|
|
||||||
* @param string $command command name
|
|
||||||
*
|
|
||||||
* @param array $options option_name => value
|
|
||||||
*
|
|
||||||
* @param array $params list of additional parameters
|
|
||||||
*
|
|
||||||
* @return bool TRUE on success, FALSE for unknown commands, or
|
|
||||||
* a PEAR error on failure
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
function doLogin($command, $options, $params)
|
|
||||||
{
|
|
||||||
$server = $this->config->get('master_server');
|
|
||||||
$remote = new PEAR_Remote($this->config);
|
|
||||||
$username = $this->config->get('username');
|
|
||||||
if (empty($username)) {
|
|
||||||
$username = @$_ENV['USER'];
|
|
||||||
}
|
}
|
||||||
$this->ui->outputData("Logging in to $server.", $command);
|
|
||||||
|
|
||||||
list($username, $password) = $this->ui->userDialog(
|
|
||||||
$command,
|
|
||||||
array('Username', 'Password'),
|
|
||||||
array('text', 'password'),
|
|
||||||
array($username, '')
|
|
||||||
);
|
|
||||||
$username = trim($username);
|
|
||||||
$password = trim($password);
|
|
||||||
|
|
||||||
$this->config->set('username', $username);
|
|
||||||
$this->config->set('password', $password);
|
|
||||||
|
|
||||||
$remote->expectError(401);
|
|
||||||
$ok = $remote->call('logintest');
|
|
||||||
$remote->popExpect();
|
|
||||||
if ($ok === true) {
|
|
||||||
$this->ui->outputData("Logged in.", $command);
|
|
||||||
$this->config->store();
|
|
||||||
} else {
|
|
||||||
return $this->raiseError("Login failed!");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ doLogout()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Execute the 'logout' command.
|
|
||||||
*
|
|
||||||
* @param string $command command name
|
|
||||||
*
|
|
||||||
* @param array $options option_name => value
|
|
||||||
*
|
|
||||||
* @param array $params list of additional parameters
|
|
||||||
*
|
|
||||||
* @return bool TRUE on success, FALSE for unknown commands, or
|
|
||||||
* a PEAR error on failure
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
function doLogout($command, $options, $params)
|
|
||||||
{
|
|
||||||
$server = $this->config->get('master_server');
|
|
||||||
$this->ui->outputData("Logging out from $server.", $command);
|
|
||||||
$this->config->remove('username');
|
|
||||||
$this->config->remove('password');
|
|
||||||
$this->config->store();
|
|
||||||
}
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
<commands version="1.0">
|
||||||
|
<login>
|
||||||
|
<summary>Connects and authenticates to remote server [Deprecated in favor of channel-login]</summary>
|
||||||
|
<function>doLogin</function>
|
||||||
|
<shortcut>li</shortcut>
|
||||||
|
<options />
|
||||||
|
<doc><channel name>
|
||||||
|
WARNING: This function is deprecated in favor of using channel-login
|
||||||
|
|
||||||
|
Log in to a remote channel server. If <channel name> is not supplied,
|
||||||
|
the default channel is used. To use remote functions in the installer
|
||||||
|
that require any kind of privileges, you need to log in first. The
|
||||||
|
username and password you enter here will be stored in your per-user
|
||||||
|
PEAR configuration (~/.pearrc on Unix-like systems). After logging
|
||||||
|
in, your username and password will be sent along in subsequent
|
||||||
|
operations on the remote server.</doc>
|
||||||
|
</login>
|
||||||
|
<logout>
|
||||||
|
<summary>Logs out from the remote server [Deprecated in favor of channel-logout]</summary>
|
||||||
|
<function>doLogout</function>
|
||||||
|
<shortcut>lo</shortcut>
|
||||||
|
<options />
|
||||||
|
<doc>
|
||||||
|
WARNING: This function is deprecated in favor of using channel-logout
|
||||||
|
|
||||||
|
Logs out from the remote server. This command does not actually
|
||||||
|
connect to the remote server, it only deletes the stored username and
|
||||||
|
password from your user configuration.</doc>
|
||||||
|
</logout>
|
||||||
|
</commands>
|
|
@ -1,36 +1,42 @@
|
||||||
<?php
|
<?php
|
||||||
//
|
/**
|
||||||
// +----------------------------------------------------------------------+
|
* PEAR_Command_Auth (build command)
|
||||||
// | PHP Version 5 |
|
*
|
||||||
// +----------------------------------------------------------------------+
|
* PHP versions 4 and 5
|
||||||
// | Copyright (c) 1997-2004 The PHP Group |
|
*
|
||||||
// +----------------------------------------------------------------------+
|
* @category pear
|
||||||
// | This source file is subject to version 3.0 of the PHP license, |
|
* @package PEAR
|
||||||
// | that is bundled with this package in the file LICENSE, and is |
|
* @author Stig Bakken <ssb@php.net>
|
||||||
// | available through the world-wide-web at the following url: |
|
* @author Tomas V.V.Cox <cox@idecnet.com>
|
||||||
// | http://www.php.net/license/3_0.txt. |
|
* @author Greg Beaver <cellog@php.net>
|
||||||
// | If you did not receive a copy of the PHP license and are unable to |
|
* @copyright 1997-2009 The Authors
|
||||||
// | obtain it through the world-wide-web, please send a note to |
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
// | license@php.net so we can mail you a copy immediately. |
|
* @version CVS: $Id: Build.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
// +----------------------------------------------------------------------+
|
* @link http://pear.php.net/package/PEAR
|
||||||
// | Author: Stig Bakken <ssb@php.net> |
|
* @since File available since Release 0.1
|
||||||
// | Tomas V.V.Cox <cox@idecnet.com> |
|
*/
|
||||||
// | |
|
|
||||||
// +----------------------------------------------------------------------+
|
|
||||||
//
|
|
||||||
// $Id: Build.php,v 1.9 2004/01/08 17:33:13 sniper Exp $
|
|
||||||
|
|
||||||
require_once "PEAR/Command/Common.php";
|
/**
|
||||||
require_once "PEAR/Builder.php";
|
* base class
|
||||||
|
*/
|
||||||
|
require_once 'PEAR/Command/Common.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PEAR commands for building extensions.
|
* PEAR commands for building extensions.
|
||||||
*
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Stig Bakken <ssb@php.net>
|
||||||
|
* @author Tomas V.V.Cox <cox@idecnet.com>
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 0.1
|
||||||
*/
|
*/
|
||||||
class PEAR_Command_Build extends PEAR_Command_Common
|
class PEAR_Command_Build extends PEAR_Command_Common
|
||||||
{
|
{
|
||||||
// {{{ properties
|
|
||||||
|
|
||||||
var $commands = array(
|
var $commands = array(
|
||||||
'build' => array(
|
'build' => array(
|
||||||
'summary' => 'Build an Extension From C Source',
|
'summary' => 'Build an Extension From C Source',
|
||||||
|
@ -42,10 +48,6 @@ Builds one or more extensions contained in a package.'
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
// }}}
|
|
||||||
|
|
||||||
// {{{ constructor
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PEAR_Command_Build constructor.
|
* PEAR_Command_Build constructor.
|
||||||
*
|
*
|
||||||
|
@ -56,27 +58,23 @@ Builds one or more extensions contained in a package.'
|
||||||
parent::PEAR_Command_Common($ui, $config);
|
parent::PEAR_Command_Common($ui, $config);
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
|
|
||||||
// {{{ doBuild()
|
|
||||||
|
|
||||||
function doBuild($command, $options, $params)
|
function doBuild($command, $options, $params)
|
||||||
{
|
{
|
||||||
|
require_once 'PEAR/Builder.php';
|
||||||
if (sizeof($params) < 1) {
|
if (sizeof($params) < 1) {
|
||||||
$params[0] = 'package.xml';
|
$params[0] = 'package.xml';
|
||||||
}
|
}
|
||||||
|
|
||||||
$builder = &new PEAR_Builder($this->ui);
|
$builder = &new PEAR_Builder($this->ui);
|
||||||
$this->debug = $this->config->get('verbose');
|
$this->debug = $this->config->get('verbose');
|
||||||
$err = $builder->build($params[0], array(&$this, 'buildCallback'));
|
$err = $builder->build($params[0], array(&$this, 'buildCallback'));
|
||||||
if (PEAR::isError($err)) {
|
if (PEAR::isError($err)) {
|
||||||
return $err;
|
return $err;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ buildCallback()
|
|
||||||
|
|
||||||
function buildCallback($what, $data)
|
function buildCallback($what, $data)
|
||||||
{
|
{
|
||||||
if (($what == 'cmdoutput' && $this->debug > 1) ||
|
if (($what == 'cmdoutput' && $this->debug > 1) ||
|
||||||
|
@ -84,6 +82,4 @@ Builds one or more extensions contained in a package.'
|
||||||
$this->ui->outputData(rtrim($data), 'build');
|
$this->ui->outputData(rtrim($data), 'build');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
}
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
<commands version="1.0">
|
||||||
|
<build>
|
||||||
|
<summary>Build an Extension From C Source</summary>
|
||||||
|
<function>doBuild</function>
|
||||||
|
<shortcut>b</shortcut>
|
||||||
|
<options />
|
||||||
|
<doc>[package.xml]
|
||||||
|
Builds one or more extensions contained in a package.</doc>
|
||||||
|
</build>
|
||||||
|
</commands>
|
|
@ -0,0 +1,883 @@
|
||||||
|
<?php
|
||||||
|
// /* vim: set expandtab tabstop=4 shiftwidth=4: */
|
||||||
|
/**
|
||||||
|
* PEAR_Command_Channels (list-channels, update-channels, channel-delete, channel-add,
|
||||||
|
* channel-update, channel-info, channel-alias, channel-discover commands)
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Stig Bakken <ssb@php.net>
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: Channels.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* base class
|
||||||
|
*/
|
||||||
|
require_once 'PEAR/Command/Common.php';
|
||||||
|
|
||||||
|
define('PEAR_COMMAND_CHANNELS_CHANNEL_EXISTS', -500);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PEAR commands for managing channels.
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
class PEAR_Command_Channels extends PEAR_Command_Common
|
||||||
|
{
|
||||||
|
var $commands = array(
|
||||||
|
'list-channels' => array(
|
||||||
|
'summary' => 'List Available Channels',
|
||||||
|
'function' => 'doList',
|
||||||
|
'shortcut' => 'lc',
|
||||||
|
'options' => array(),
|
||||||
|
'doc' => '
|
||||||
|
List all available channels for installation.
|
||||||
|
',
|
||||||
|
),
|
||||||
|
'update-channels' => array(
|
||||||
|
'summary' => 'Update the Channel List',
|
||||||
|
'function' => 'doUpdateAll',
|
||||||
|
'shortcut' => 'uc',
|
||||||
|
'options' => array(),
|
||||||
|
'doc' => '
|
||||||
|
List all installed packages in all channels.
|
||||||
|
'
|
||||||
|
),
|
||||||
|
'channel-delete' => array(
|
||||||
|
'summary' => 'Remove a Channel From the List',
|
||||||
|
'function' => 'doDelete',
|
||||||
|
'shortcut' => 'cde',
|
||||||
|
'options' => array(),
|
||||||
|
'doc' => '<channel name>
|
||||||
|
Delete a channel from the registry. You may not
|
||||||
|
remove any channel that has installed packages.
|
||||||
|
'
|
||||||
|
),
|
||||||
|
'channel-add' => array(
|
||||||
|
'summary' => 'Add a Channel',
|
||||||
|
'function' => 'doAdd',
|
||||||
|
'shortcut' => 'ca',
|
||||||
|
'options' => array(),
|
||||||
|
'doc' => '<channel.xml>
|
||||||
|
Add a private channel to the channel list. Note that all
|
||||||
|
public channels should be synced using "update-channels".
|
||||||
|
Parameter may be either a local file or remote URL to a
|
||||||
|
channel.xml.
|
||||||
|
'
|
||||||
|
),
|
||||||
|
'channel-update' => array(
|
||||||
|
'summary' => 'Update an Existing Channel',
|
||||||
|
'function' => 'doUpdate',
|
||||||
|
'shortcut' => 'cu',
|
||||||
|
'options' => array(
|
||||||
|
'force' => array(
|
||||||
|
'shortopt' => 'f',
|
||||||
|
'doc' => 'will force download of new channel.xml if an existing channel name is used',
|
||||||
|
),
|
||||||
|
'channel' => array(
|
||||||
|
'shortopt' => 'c',
|
||||||
|
'arg' => 'CHANNEL',
|
||||||
|
'doc' => 'will force download of new channel.xml if an existing channel name is used',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'doc' => '[<channel.xml>|<channel name>]
|
||||||
|
Update a channel in the channel list directly. Note that all
|
||||||
|
public channels can be synced using "update-channels".
|
||||||
|
Parameter may be a local or remote channel.xml, or the name of
|
||||||
|
an existing channel.
|
||||||
|
'
|
||||||
|
),
|
||||||
|
'channel-info' => array(
|
||||||
|
'summary' => 'Retrieve Information on a Channel',
|
||||||
|
'function' => 'doInfo',
|
||||||
|
'shortcut' => 'ci',
|
||||||
|
'options' => array(),
|
||||||
|
'doc' => '<package>
|
||||||
|
List the files in an installed package.
|
||||||
|
'
|
||||||
|
),
|
||||||
|
'channel-alias' => array(
|
||||||
|
'summary' => 'Specify an alias to a channel name',
|
||||||
|
'function' => 'doAlias',
|
||||||
|
'shortcut' => 'cha',
|
||||||
|
'options' => array(),
|
||||||
|
'doc' => '<channel> <alias>
|
||||||
|
Specify a specific alias to use for a channel name.
|
||||||
|
The alias may not be an existing channel name or
|
||||||
|
alias.
|
||||||
|
'
|
||||||
|
),
|
||||||
|
'channel-discover' => array(
|
||||||
|
'summary' => 'Initialize a Channel from its server',
|
||||||
|
'function' => 'doDiscover',
|
||||||
|
'shortcut' => 'di',
|
||||||
|
'options' => array(),
|
||||||
|
'doc' => '[<channel.xml>|<channel name>]
|
||||||
|
Initialize a channel from its server and create a local channel.xml.
|
||||||
|
If <channel name> is in the format "<username>:<password>@<channel>" then
|
||||||
|
<username> and <password> will be set as the login username/password for
|
||||||
|
<channel>. Use caution when passing the username/password in this way, as
|
||||||
|
it may allow other users on your computer to briefly view your username/
|
||||||
|
password via the system\'s process list.
|
||||||
|
'
|
||||||
|
),
|
||||||
|
'channel-login' => array(
|
||||||
|
'summary' => 'Connects and authenticates to remote channel server',
|
||||||
|
'shortcut' => 'cli',
|
||||||
|
'function' => 'doLogin',
|
||||||
|
'options' => array(),
|
||||||
|
'doc' => '<channel name>
|
||||||
|
Log in to a remote channel server. If <channel name> is not supplied,
|
||||||
|
the default channel is used. To use remote functions in the installer
|
||||||
|
that require any kind of privileges, you need to log in first. The
|
||||||
|
username and password you enter here will be stored in your per-user
|
||||||
|
PEAR configuration (~/.pearrc on Unix-like systems). After logging
|
||||||
|
in, your username and password will be sent along in subsequent
|
||||||
|
operations on the remote server.',
|
||||||
|
),
|
||||||
|
'channel-logout' => array(
|
||||||
|
'summary' => 'Logs out from the remote channel server',
|
||||||
|
'shortcut' => 'clo',
|
||||||
|
'function' => 'doLogout',
|
||||||
|
'options' => array(),
|
||||||
|
'doc' => '<channel name>
|
||||||
|
Logs out from a remote channel server. If <channel name> is not supplied,
|
||||||
|
the default channel is used. This command does not actually connect to the
|
||||||
|
remote server, it only deletes the stored username and password from your user
|
||||||
|
configuration.',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PEAR_Command_Registry constructor.
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function PEAR_Command_Channels(&$ui, &$config)
|
||||||
|
{
|
||||||
|
parent::PEAR_Command_Common($ui, $config);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _sortChannels($a, $b)
|
||||||
|
{
|
||||||
|
return strnatcasecmp($a->getName(), $b->getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
function doList($command, $options, $params)
|
||||||
|
{
|
||||||
|
$reg = &$this->config->getRegistry();
|
||||||
|
$registered = $reg->getChannels();
|
||||||
|
usort($registered, array(&$this, '_sortchannels'));
|
||||||
|
$i = $j = 0;
|
||||||
|
$data = array(
|
||||||
|
'caption' => 'Registered Channels:',
|
||||||
|
'border' => true,
|
||||||
|
'headline' => array('Channel', 'Alias', 'Summary')
|
||||||
|
);
|
||||||
|
foreach ($registered as $channel) {
|
||||||
|
$data['data'][] = array($channel->getName(),
|
||||||
|
$channel->getAlias(),
|
||||||
|
$channel->getSummary());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($registered) === 0) {
|
||||||
|
$data = '(no registered channels)';
|
||||||
|
}
|
||||||
|
$this->ui->outputData($data, $command);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function doUpdateAll($command, $options, $params)
|
||||||
|
{
|
||||||
|
$reg = &$this->config->getRegistry();
|
||||||
|
$channels = $reg->getChannels();
|
||||||
|
|
||||||
|
$success = true;
|
||||||
|
foreach ($channels as $channel) {
|
||||||
|
if ($channel->getName() != '__uri') {
|
||||||
|
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
|
||||||
|
$err = $this->doUpdate('channel-update',
|
||||||
|
$options,
|
||||||
|
array($channel->getName()));
|
||||||
|
if (PEAR::isError($err)) {
|
||||||
|
$this->ui->outputData($err->getMessage(), $command);
|
||||||
|
$success = false;
|
||||||
|
} else {
|
||||||
|
$success &= $err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $success;
|
||||||
|
}
|
||||||
|
|
||||||
|
function doInfo($command, $options, $params)
|
||||||
|
{
|
||||||
|
if (count($params) !== 1) {
|
||||||
|
return $this->raiseError("No channel specified");
|
||||||
|
}
|
||||||
|
|
||||||
|
$reg = &$this->config->getRegistry();
|
||||||
|
$channel = strtolower($params[0]);
|
||||||
|
if ($reg->channelExists($channel)) {
|
||||||
|
$chan = $reg->getChannel($channel);
|
||||||
|
if (PEAR::isError($chan)) {
|
||||||
|
return $this->raiseError($chan);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (strpos($channel, '://')) {
|
||||||
|
$downloader = &$this->getDownloader();
|
||||||
|
$tmpdir = $this->config->get('temp_dir');
|
||||||
|
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
|
||||||
|
$loc = $downloader->downloadHttp($channel, $this->ui, $tmpdir);
|
||||||
|
PEAR::staticPopErrorHandling();
|
||||||
|
if (PEAR::isError($loc)) {
|
||||||
|
return $this->raiseError('Cannot open "' . $channel .
|
||||||
|
'" (' . $loc->getMessage() . ')');
|
||||||
|
} else {
|
||||||
|
$contents = implode('', file($loc));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!file_exists($params[0])) {
|
||||||
|
return $this->raiseError('Unknown channel "' . $channel . '"');
|
||||||
|
}
|
||||||
|
|
||||||
|
$fp = fopen($params[0], 'r');
|
||||||
|
if (!$fp) {
|
||||||
|
return $this->raiseError('Cannot open "' . $params[0] . '"');
|
||||||
|
}
|
||||||
|
|
||||||
|
$contents = '';
|
||||||
|
while (!feof($fp)) {
|
||||||
|
$contents .= fread($fp, 1024);
|
||||||
|
}
|
||||||
|
fclose($fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!class_exists('PEAR_ChannelFile')) {
|
||||||
|
require_once 'PEAR/ChannelFile.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
$chan = new PEAR_ChannelFile;
|
||||||
|
$chan->fromXmlString($contents);
|
||||||
|
$chan->validate();
|
||||||
|
if ($errs = $chan->getErrors(true)) {
|
||||||
|
foreach ($errs as $err) {
|
||||||
|
$this->ui->outputData($err['level'] . ': ' . $err['message']);
|
||||||
|
}
|
||||||
|
return $this->raiseError('Channel file "' . $params[0] . '" is not valid');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$chan) {
|
||||||
|
return $this->raiseError('Serious error: Channel "' . $params[0] .
|
||||||
|
'" has a corrupted registry entry');
|
||||||
|
}
|
||||||
|
|
||||||
|
$channel = $chan->getName();
|
||||||
|
$caption = 'Channel ' . $channel . ' Information:';
|
||||||
|
$data1 = array(
|
||||||
|
'caption' => $caption,
|
||||||
|
'border' => true);
|
||||||
|
$data1['data']['server'] = array('Name and Server', $chan->getName());
|
||||||
|
if ($chan->getAlias() != $chan->getName()) {
|
||||||
|
$data1['data']['alias'] = array('Alias', $chan->getAlias());
|
||||||
|
}
|
||||||
|
|
||||||
|
$data1['data']['summary'] = array('Summary', $chan->getSummary());
|
||||||
|
$validate = $chan->getValidationPackage();
|
||||||
|
$data1['data']['vpackage'] = array('Validation Package Name', $validate['_content']);
|
||||||
|
$data1['data']['vpackageversion'] =
|
||||||
|
array('Validation Package Version', $validate['attribs']['version']);
|
||||||
|
$d = array();
|
||||||
|
$d['main'] = $data1;
|
||||||
|
|
||||||
|
$data['data'] = array();
|
||||||
|
$data['caption'] = 'Server Capabilities';
|
||||||
|
$data['headline'] = array('Type', 'Version/REST type', 'Function Name/REST base');
|
||||||
|
if ($chan->supportsREST()) {
|
||||||
|
if ($chan->supportsREST()) {
|
||||||
|
$funcs = $chan->getFunctions('rest');
|
||||||
|
if (!isset($funcs[0])) {
|
||||||
|
$funcs = array($funcs);
|
||||||
|
}
|
||||||
|
foreach ($funcs as $protocol) {
|
||||||
|
$data['data'][] = array('rest', $protocol['attribs']['type'],
|
||||||
|
$protocol['_content']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$data['data'][] = array('No supported protocols');
|
||||||
|
}
|
||||||
|
|
||||||
|
$d['protocols'] = $data;
|
||||||
|
$data['data'] = array();
|
||||||
|
$mirrors = $chan->getMirrors();
|
||||||
|
if ($mirrors) {
|
||||||
|
$data['caption'] = 'Channel ' . $channel . ' Mirrors:';
|
||||||
|
unset($data['headline']);
|
||||||
|
foreach ($mirrors as $mirror) {
|
||||||
|
$data['data'][] = array($mirror['attribs']['host']);
|
||||||
|
$d['mirrors'] = $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($mirrors as $i => $mirror) {
|
||||||
|
$data['data'] = array();
|
||||||
|
$data['caption'] = 'Mirror ' . $mirror['attribs']['host'] . ' Capabilities';
|
||||||
|
$data['headline'] = array('Type', 'Version/REST type', 'Function Name/REST base');
|
||||||
|
if ($chan->supportsREST($mirror['attribs']['host'])) {
|
||||||
|
if ($chan->supportsREST($mirror['attribs']['host'])) {
|
||||||
|
$funcs = $chan->getFunctions('rest', $mirror['attribs']['host']);
|
||||||
|
if (!isset($funcs[0])) {
|
||||||
|
$funcs = array($funcs);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($funcs as $protocol) {
|
||||||
|
$data['data'][] = array('rest', $protocol['attribs']['type'],
|
||||||
|
$protocol['_content']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$data['data'][] = array('No supported protocols');
|
||||||
|
}
|
||||||
|
$d['mirrorprotocols' . $i] = $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->ui->outputData($d, 'channel-info');
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
function doDelete($command, $options, $params)
|
||||||
|
{
|
||||||
|
if (count($params) !== 1) {
|
||||||
|
return $this->raiseError('channel-delete: no channel specified');
|
||||||
|
}
|
||||||
|
|
||||||
|
$reg = &$this->config->getRegistry();
|
||||||
|
if (!$reg->channelExists($params[0])) {
|
||||||
|
return $this->raiseError('channel-delete: channel "' . $params[0] . '" does not exist');
|
||||||
|
}
|
||||||
|
|
||||||
|
$channel = $reg->channelName($params[0]);
|
||||||
|
if ($channel == 'pear.php.net') {
|
||||||
|
return $this->raiseError('Cannot delete the pear.php.net channel');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($channel == 'pecl.php.net') {
|
||||||
|
return $this->raiseError('Cannot delete the pecl.php.net channel');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($channel == 'doc.php.net') {
|
||||||
|
return $this->raiseError('Cannot delete the doc.php.net channel');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($channel == '__uri') {
|
||||||
|
return $this->raiseError('Cannot delete the __uri pseudo-channel');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PEAR::isError($err = $reg->listPackages($channel))) {
|
||||||
|
return $err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($err)) {
|
||||||
|
return $this->raiseError('Channel "' . $channel .
|
||||||
|
'" has installed packages, cannot delete');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$reg->deleteChannel($channel)) {
|
||||||
|
return $this->raiseError('Channel "' . $channel . '" deletion failed');
|
||||||
|
} else {
|
||||||
|
$this->config->deleteChannel($channel);
|
||||||
|
$this->ui->outputData('Channel "' . $channel . '" deleted', $command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function doAdd($command, $options, $params)
|
||||||
|
{
|
||||||
|
if (count($params) !== 1) {
|
||||||
|
return $this->raiseError('channel-add: no channel file specified');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strpos($params[0], '://')) {
|
||||||
|
$downloader = &$this->getDownloader();
|
||||||
|
$tmpdir = $this->config->get('temp_dir');
|
||||||
|
if (!file_exists($tmpdir)) {
|
||||||
|
require_once 'System.php';
|
||||||
|
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
|
||||||
|
$err = System::mkdir(array('-p', $tmpdir));
|
||||||
|
PEAR::staticPopErrorHandling();
|
||||||
|
if (PEAR::isError($err)) {
|
||||||
|
return $this->raiseError('channel-add: temp_dir does not exist: "' .
|
||||||
|
$tmpdir .
|
||||||
|
'" - You can change this location with "pear config-set temp_dir"');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_writable($tmpdir)) {
|
||||||
|
return $this->raiseError('channel-add: temp_dir is not writable: "' .
|
||||||
|
$tmpdir .
|
||||||
|
'" - You can change this location with "pear config-set temp_dir"');
|
||||||
|
}
|
||||||
|
|
||||||
|
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
|
||||||
|
$loc = $downloader->downloadHttp($params[0], $this->ui, $tmpdir, null, false);
|
||||||
|
PEAR::staticPopErrorHandling();
|
||||||
|
if (PEAR::isError($loc)) {
|
||||||
|
return $this->raiseError('channel-add: Cannot open "' . $params[0] .
|
||||||
|
'" (' . $loc->getMessage() . ')');
|
||||||
|
}
|
||||||
|
|
||||||
|
list($loc, $lastmodified) = $loc;
|
||||||
|
$contents = implode('', file($loc));
|
||||||
|
} else {
|
||||||
|
$lastmodified = $fp = false;
|
||||||
|
if (file_exists($params[0])) {
|
||||||
|
$fp = fopen($params[0], 'r');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$fp) {
|
||||||
|
return $this->raiseError('channel-add: cannot open "' . $params[0] . '"');
|
||||||
|
}
|
||||||
|
|
||||||
|
$contents = '';
|
||||||
|
while (!feof($fp)) {
|
||||||
|
$contents .= fread($fp, 1024);
|
||||||
|
}
|
||||||
|
fclose($fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!class_exists('PEAR_ChannelFile')) {
|
||||||
|
require_once 'PEAR/ChannelFile.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
$channel = new PEAR_ChannelFile;
|
||||||
|
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
|
||||||
|
$result = $channel->fromXmlString($contents);
|
||||||
|
PEAR::staticPopErrorHandling();
|
||||||
|
if (!$result) {
|
||||||
|
$exit = false;
|
||||||
|
if (count($errors = $channel->getErrors(true))) {
|
||||||
|
foreach ($errors as $error) {
|
||||||
|
$this->ui->outputData(ucfirst($error['level'] . ': ' . $error['message']));
|
||||||
|
if (!$exit) {
|
||||||
|
$exit = $error['level'] == 'error' ? true : false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($exit) {
|
||||||
|
return $this->raiseError('channel-add: invalid channel.xml file');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$reg = &$this->config->getRegistry();
|
||||||
|
if ($reg->channelExists($channel->getName())) {
|
||||||
|
return $this->raiseError('channel-add: Channel "' . $channel->getName() .
|
||||||
|
'" exists, use channel-update to update entry', PEAR_COMMAND_CHANNELS_CHANNEL_EXISTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
$ret = $reg->addChannel($channel, $lastmodified);
|
||||||
|
if (PEAR::isError($ret)) {
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$ret) {
|
||||||
|
return $this->raiseError('channel-add: adding Channel "' . $channel->getName() .
|
||||||
|
'" to registry failed');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->config->setChannels($reg->listChannels());
|
||||||
|
$this->config->writeConfigFile();
|
||||||
|
$this->ui->outputData('Adding Channel "' . $channel->getName() . '" succeeded', $command);
|
||||||
|
}
|
||||||
|
|
||||||
|
function doUpdate($command, $options, $params)
|
||||||
|
{
|
||||||
|
if (count($params) !== 1) {
|
||||||
|
return $this->raiseError("No channel file specified");
|
||||||
|
}
|
||||||
|
|
||||||
|
$tmpdir = $this->config->get('temp_dir');
|
||||||
|
if (!file_exists($tmpdir)) {
|
||||||
|
require_once 'System.php';
|
||||||
|
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
|
||||||
|
$err = System::mkdir(array('-p', $tmpdir));
|
||||||
|
PEAR::staticPopErrorHandling();
|
||||||
|
if (PEAR::isError($err)) {
|
||||||
|
return $this->raiseError('channel-add: temp_dir does not exist: "' .
|
||||||
|
$tmpdir .
|
||||||
|
'" - You can change this location with "pear config-set temp_dir"');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_writable($tmpdir)) {
|
||||||
|
return $this->raiseError('channel-add: temp_dir is not writable: "' .
|
||||||
|
$tmpdir .
|
||||||
|
'" - You can change this location with "pear config-set temp_dir"');
|
||||||
|
}
|
||||||
|
|
||||||
|
$reg = &$this->config->getRegistry();
|
||||||
|
$lastmodified = false;
|
||||||
|
if ((!file_exists($params[0]) || is_dir($params[0]))
|
||||||
|
&& $reg->channelExists(strtolower($params[0]))) {
|
||||||
|
$c = $reg->getChannel(strtolower($params[0]));
|
||||||
|
if (PEAR::isError($c)) {
|
||||||
|
return $this->raiseError($c);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->ui->outputData("Updating channel \"$params[0]\"", $command);
|
||||||
|
$dl = &$this->getDownloader(array());
|
||||||
|
// if force is specified, use a timestamp of "1" to force retrieval
|
||||||
|
$lastmodified = isset($options['force']) ? false : $c->lastModified();
|
||||||
|
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
|
||||||
|
$contents = $dl->downloadHttp('http://' . $c->getName() . '/channel.xml',
|
||||||
|
$this->ui, $tmpdir, null, $lastmodified);
|
||||||
|
PEAR::staticPopErrorHandling();
|
||||||
|
if (PEAR::isError($contents)) {
|
||||||
|
// Attempt to fall back to https
|
||||||
|
$this->ui->outputData("Channel \"$params[0]\" is not responding over http://, failed with message: " . $contents->getMessage());
|
||||||
|
$this->ui->outputData("Trying channel \"$params[0]\" over https:// instead");
|
||||||
|
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
|
||||||
|
$contents = $dl->downloadHttp('https://' . $c->getName() . '/channel.xml',
|
||||||
|
$this->ui, $tmpdir, null, $lastmodified);
|
||||||
|
PEAR::staticPopErrorHandling();
|
||||||
|
if (PEAR::isError($contents)) {
|
||||||
|
return $this->raiseError('Cannot retrieve channel.xml for channel "' .
|
||||||
|
$c->getName() . '" (' . $contents->getMessage() . ')');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
list($contents, $lastmodified) = $contents;
|
||||||
|
if (!$contents) {
|
||||||
|
$this->ui->outputData("Channel \"$params[0]\" is up to date");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$contents = implode('', file($contents));
|
||||||
|
if (!class_exists('PEAR_ChannelFile')) {
|
||||||
|
require_once 'PEAR/ChannelFile.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
$channel = new PEAR_ChannelFile;
|
||||||
|
$channel->fromXmlString($contents);
|
||||||
|
if (!$channel->getErrors()) {
|
||||||
|
// security check: is the downloaded file for the channel we got it from?
|
||||||
|
if (strtolower($channel->getName()) != strtolower($c->getName())) {
|
||||||
|
if (!isset($options['force'])) {
|
||||||
|
return $this->raiseError('ERROR: downloaded channel definition file' .
|
||||||
|
' for channel "' . $channel->getName() . '" from channel "' .
|
||||||
|
strtolower($c->getName()) . '"');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->ui->log(0, 'WARNING: downloaded channel definition file' .
|
||||||
|
' for channel "' . $channel->getName() . '" from channel "' .
|
||||||
|
strtolower($c->getName()) . '"');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (strpos($params[0], '://')) {
|
||||||
|
$dl = &$this->getDownloader();
|
||||||
|
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
|
||||||
|
$loc = $dl->downloadHttp($params[0],
|
||||||
|
$this->ui, $tmpdir, null, $lastmodified);
|
||||||
|
PEAR::staticPopErrorHandling();
|
||||||
|
if (PEAR::isError($loc)) {
|
||||||
|
return $this->raiseError("Cannot open " . $params[0] .
|
||||||
|
' (' . $loc->getMessage() . ')');
|
||||||
|
}
|
||||||
|
|
||||||
|
list($loc, $lastmodified) = $loc;
|
||||||
|
$contents = implode('', file($loc));
|
||||||
|
} else {
|
||||||
|
$fp = false;
|
||||||
|
if (file_exists($params[0])) {
|
||||||
|
$fp = fopen($params[0], 'r');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$fp) {
|
||||||
|
return $this->raiseError("Cannot open " . $params[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$contents = '';
|
||||||
|
while (!feof($fp)) {
|
||||||
|
$contents .= fread($fp, 1024);
|
||||||
|
}
|
||||||
|
fclose($fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!class_exists('PEAR_ChannelFile')) {
|
||||||
|
require_once 'PEAR/ChannelFile.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
$channel = new PEAR_ChannelFile;
|
||||||
|
$channel->fromXmlString($contents);
|
||||||
|
}
|
||||||
|
|
||||||
|
$exit = false;
|
||||||
|
if (count($errors = $channel->getErrors(true))) {
|
||||||
|
foreach ($errors as $error) {
|
||||||
|
$this->ui->outputData(ucfirst($error['level'] . ': ' . $error['message']));
|
||||||
|
if (!$exit) {
|
||||||
|
$exit = $error['level'] == 'error' ? true : false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($exit) {
|
||||||
|
return $this->raiseError('Invalid channel.xml file');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$reg->channelExists($channel->getName())) {
|
||||||
|
return $this->raiseError('Error: Channel "' . $channel->getName() .
|
||||||
|
'" does not exist, use channel-add to add an entry');
|
||||||
|
}
|
||||||
|
|
||||||
|
$ret = $reg->updateChannel($channel, $lastmodified);
|
||||||
|
if (PEAR::isError($ret)) {
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$ret) {
|
||||||
|
return $this->raiseError('Updating Channel "' . $channel->getName() .
|
||||||
|
'" in registry failed');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->config->setChannels($reg->listChannels());
|
||||||
|
$this->config->writeConfigFile();
|
||||||
|
$this->ui->outputData('Update of Channel "' . $channel->getName() . '" succeeded');
|
||||||
|
}
|
||||||
|
|
||||||
|
function &getDownloader()
|
||||||
|
{
|
||||||
|
if (!class_exists('PEAR_Downloader')) {
|
||||||
|
require_once 'PEAR/Downloader.php';
|
||||||
|
}
|
||||||
|
$a = new PEAR_Downloader($this->ui, array(), $this->config);
|
||||||
|
return $a;
|
||||||
|
}
|
||||||
|
|
||||||
|
function doAlias($command, $options, $params)
|
||||||
|
{
|
||||||
|
if (count($params) === 1) {
|
||||||
|
return $this->raiseError('No channel alias specified');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($params) !== 2 || (!empty($params[1]) && $params[1]{0} == '-')) {
|
||||||
|
return $this->raiseError(
|
||||||
|
'Invalid format, correct is: channel-alias channel alias');
|
||||||
|
}
|
||||||
|
|
||||||
|
$reg = &$this->config->getRegistry();
|
||||||
|
if (!$reg->channelExists($params[0], true)) {
|
||||||
|
$extra = '';
|
||||||
|
if ($reg->isAlias($params[0])) {
|
||||||
|
$extra = ' (use "channel-alias ' . $reg->channelName($params[0]) . ' ' .
|
||||||
|
strtolower($params[1]) . '")';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->raiseError('"' . $params[0] . '" is not a valid channel' . $extra);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($reg->isAlias($params[1])) {
|
||||||
|
return $this->raiseError('Channel "' . $reg->channelName($params[1]) . '" is ' .
|
||||||
|
'already aliased to "' . strtolower($params[1]) . '", cannot re-alias');
|
||||||
|
}
|
||||||
|
|
||||||
|
$chan = &$reg->getChannel($params[0]);
|
||||||
|
if (PEAR::isError($chan)) {
|
||||||
|
return $this->raiseError('Corrupt registry? Error retrieving channel "' . $params[0] .
|
||||||
|
'" information (' . $chan->getMessage() . ')');
|
||||||
|
}
|
||||||
|
|
||||||
|
// make it a local alias
|
||||||
|
if (!$chan->setAlias(strtolower($params[1]), true)) {
|
||||||
|
return $this->raiseError('Alias "' . strtolower($params[1]) .
|
||||||
|
'" is not a valid channel alias');
|
||||||
|
}
|
||||||
|
|
||||||
|
$reg->updateChannel($chan);
|
||||||
|
$this->ui->outputData('Channel "' . $chan->getName() . '" aliased successfully to "' .
|
||||||
|
strtolower($params[1]) . '"');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The channel-discover command
|
||||||
|
*
|
||||||
|
* @param string $command command name
|
||||||
|
* @param array $options option_name => value
|
||||||
|
* @param array $params list of additional parameters.
|
||||||
|
* $params[0] should contain a string with either:
|
||||||
|
* - <channel name> or
|
||||||
|
* - <username>:<password>@<channel name>
|
||||||
|
* @return null|PEAR_Error
|
||||||
|
*/
|
||||||
|
function doDiscover($command, $options, $params)
|
||||||
|
{
|
||||||
|
if (count($params) !== 1) {
|
||||||
|
return $this->raiseError("No channel server specified");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for the possible input format "<username>:<password>@<channel>"
|
||||||
|
if (preg_match('/^(.+):(.+)@(.+)\\z/', $params[0], $matches)) {
|
||||||
|
$username = $matches[1];
|
||||||
|
$password = $matches[2];
|
||||||
|
$channel = $matches[3];
|
||||||
|
} else {
|
||||||
|
$channel = $params[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
$reg = &$this->config->getRegistry();
|
||||||
|
if ($reg->channelExists($channel)) {
|
||||||
|
if (!$reg->isAlias($channel)) {
|
||||||
|
return $this->raiseError("Channel \"$channel\" is already initialized", PEAR_COMMAND_CHANNELS_CHANNEL_EXISTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->raiseError("A channel alias named \"$channel\" " .
|
||||||
|
'already exists, aliasing channel "' . $reg->channelName($channel)
|
||||||
|
. '"');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->pushErrorHandling(PEAR_ERROR_RETURN);
|
||||||
|
$err = $this->doAdd($command, $options, array('http://' . $channel . '/channel.xml'));
|
||||||
|
$this->popErrorHandling();
|
||||||
|
if (PEAR::isError($err)) {
|
||||||
|
if ($err->getCode() === PEAR_COMMAND_CHANNELS_CHANNEL_EXISTS) {
|
||||||
|
return $this->raiseError("Discovery of channel \"$channel\" failed (" .
|
||||||
|
$err->getMessage() . ')');
|
||||||
|
}
|
||||||
|
// Attempt fetch via https
|
||||||
|
$this->ui->outputData("Discovering channel $channel over http:// failed with message: " . $err->getMessage());
|
||||||
|
$this->ui->outputData("Trying to discover channel $channel over https:// instead");
|
||||||
|
$this->pushErrorHandling(PEAR_ERROR_RETURN);
|
||||||
|
$err = $this->doAdd($command, $options, array('https://' . $channel . '/channel.xml'));
|
||||||
|
$this->popErrorHandling();
|
||||||
|
if (PEAR::isError($err)) {
|
||||||
|
return $this->raiseError("Discovery of channel \"$channel\" failed (" .
|
||||||
|
$err->getMessage() . ')');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store username/password if they were given
|
||||||
|
// Arguably we should do a logintest on the channel here, but since
|
||||||
|
// that's awkward on a REST-based channel (even "pear login" doesn't
|
||||||
|
// do it for those), and XML-RPC is deprecated, it's fairly pointless.
|
||||||
|
if (isset($username)) {
|
||||||
|
$this->config->set('username', $username, 'user', $channel);
|
||||||
|
$this->config->set('password', $password, 'user', $channel);
|
||||||
|
$this->config->store();
|
||||||
|
$this->ui->outputData("Stored login for channel \"$channel\" using username \"$username\"", $command);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->ui->outputData("Discovery of channel \"$channel\" succeeded", $command);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the 'login' command.
|
||||||
|
*
|
||||||
|
* @param string $command command name
|
||||||
|
* @param array $options option_name => value
|
||||||
|
* @param array $params list of additional parameters
|
||||||
|
*
|
||||||
|
* @return bool TRUE on success or
|
||||||
|
* a PEAR error on failure
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function doLogin($command, $options, $params)
|
||||||
|
{
|
||||||
|
$reg = &$this->config->getRegistry();
|
||||||
|
|
||||||
|
// If a parameter is supplied, use that as the channel to log in to
|
||||||
|
$channel = isset($params[0]) ? $params[0] : $this->config->get('default_channel');
|
||||||
|
|
||||||
|
$chan = $reg->getChannel($channel);
|
||||||
|
if (PEAR::isError($chan)) {
|
||||||
|
return $this->raiseError($chan);
|
||||||
|
}
|
||||||
|
|
||||||
|
$server = $this->config->get('preferred_mirror', null, $channel);
|
||||||
|
$username = $this->config->get('username', null, $channel);
|
||||||
|
if (empty($username)) {
|
||||||
|
$username = isset($_ENV['USER']) ? $_ENV['USER'] : null;
|
||||||
|
}
|
||||||
|
$this->ui->outputData("Logging in to $server.", $command);
|
||||||
|
|
||||||
|
list($username, $password) = $this->ui->userDialog(
|
||||||
|
$command,
|
||||||
|
array('Username', 'Password'),
|
||||||
|
array('text', 'password'),
|
||||||
|
array($username, '')
|
||||||
|
);
|
||||||
|
$username = trim($username);
|
||||||
|
$password = trim($password);
|
||||||
|
|
||||||
|
$ourfile = $this->config->getConfFile('user');
|
||||||
|
if (!$ourfile) {
|
||||||
|
$ourfile = $this->config->getConfFile('system');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->config->set('username', $username, 'user', $channel);
|
||||||
|
$this->config->set('password', $password, 'user', $channel);
|
||||||
|
|
||||||
|
if ($chan->supportsREST()) {
|
||||||
|
$ok = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($ok !== true) {
|
||||||
|
return $this->raiseError('Login failed!');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->ui->outputData("Logged in.", $command);
|
||||||
|
// avoid changing any temporary settings changed with -d
|
||||||
|
$ourconfig = new PEAR_Config($ourfile, $ourfile);
|
||||||
|
$ourconfig->set('username', $username, 'user', $channel);
|
||||||
|
$ourconfig->set('password', $password, 'user', $channel);
|
||||||
|
$ourconfig->store();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the 'logout' command.
|
||||||
|
*
|
||||||
|
* @param string $command command name
|
||||||
|
* @param array $options option_name => value
|
||||||
|
* @param array $params list of additional parameters
|
||||||
|
*
|
||||||
|
* @return bool TRUE on success or
|
||||||
|
* a PEAR error on failure
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function doLogout($command, $options, $params)
|
||||||
|
{
|
||||||
|
$reg = &$this->config->getRegistry();
|
||||||
|
|
||||||
|
// If a parameter is supplied, use that as the channel to log in to
|
||||||
|
$channel = isset($params[0]) ? $params[0] : $this->config->get('default_channel');
|
||||||
|
|
||||||
|
$chan = $reg->getChannel($channel);
|
||||||
|
if (PEAR::isError($chan)) {
|
||||||
|
return $this->raiseError($chan);
|
||||||
|
}
|
||||||
|
|
||||||
|
$server = $this->config->get('preferred_mirror', null, $channel);
|
||||||
|
$this->ui->outputData("Logging out from $server.", $command);
|
||||||
|
$this->config->remove('username', 'user', $channel);
|
||||||
|
$this->config->remove('password', 'user', $channel);
|
||||||
|
$this->config->store();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,123 @@
|
||||||
|
<commands version="1.0">
|
||||||
|
<list-channels>
|
||||||
|
<summary>List Available Channels</summary>
|
||||||
|
<function>doList</function>
|
||||||
|
<shortcut>lc</shortcut>
|
||||||
|
<options />
|
||||||
|
<doc>
|
||||||
|
List all available channels for installation.
|
||||||
|
</doc>
|
||||||
|
</list-channels>
|
||||||
|
<update-channels>
|
||||||
|
<summary>Update the Channel List</summary>
|
||||||
|
<function>doUpdateAll</function>
|
||||||
|
<shortcut>uc</shortcut>
|
||||||
|
<options />
|
||||||
|
<doc>
|
||||||
|
List all installed packages in all channels.
|
||||||
|
</doc>
|
||||||
|
</update-channels>
|
||||||
|
<channel-delete>
|
||||||
|
<summary>Remove a Channel From the List</summary>
|
||||||
|
<function>doDelete</function>
|
||||||
|
<shortcut>cde</shortcut>
|
||||||
|
<options />
|
||||||
|
<doc><channel name>
|
||||||
|
Delete a channel from the registry. You may not
|
||||||
|
remove any channel that has installed packages.
|
||||||
|
</doc>
|
||||||
|
</channel-delete>
|
||||||
|
<channel-add>
|
||||||
|
<summary>Add a Channel</summary>
|
||||||
|
<function>doAdd</function>
|
||||||
|
<shortcut>ca</shortcut>
|
||||||
|
<options />
|
||||||
|
<doc><channel.xml>
|
||||||
|
Add a private channel to the channel list. Note that all
|
||||||
|
public channels should be synced using "update-channels".
|
||||||
|
Parameter may be either a local file or remote URL to a
|
||||||
|
channel.xml.
|
||||||
|
</doc>
|
||||||
|
</channel-add>
|
||||||
|
<channel-update>
|
||||||
|
<summary>Update an Existing Channel</summary>
|
||||||
|
<function>doUpdate</function>
|
||||||
|
<shortcut>cu</shortcut>
|
||||||
|
<options>
|
||||||
|
<force>
|
||||||
|
<shortopt>f</shortopt>
|
||||||
|
<doc>will force download of new channel.xml if an existing channel name is used</doc>
|
||||||
|
</force>
|
||||||
|
<channel>
|
||||||
|
<shortopt>c</shortopt>
|
||||||
|
<doc>will force download of new channel.xml if an existing channel name is used</doc>
|
||||||
|
<arg>CHANNEL</arg>
|
||||||
|
</channel>
|
||||||
|
</options>
|
||||||
|
<doc>[<channel.xml>|<channel name>]
|
||||||
|
Update a channel in the channel list directly. Note that all
|
||||||
|
public channels can be synced using "update-channels".
|
||||||
|
Parameter may be a local or remote channel.xml, or the name of
|
||||||
|
an existing channel.
|
||||||
|
</doc>
|
||||||
|
</channel-update>
|
||||||
|
<channel-info>
|
||||||
|
<summary>Retrieve Information on a Channel</summary>
|
||||||
|
<function>doInfo</function>
|
||||||
|
<shortcut>ci</shortcut>
|
||||||
|
<options />
|
||||||
|
<doc><package>
|
||||||
|
List the files in an installed package.
|
||||||
|
</doc>
|
||||||
|
</channel-info>
|
||||||
|
<channel-alias>
|
||||||
|
<summary>Specify an alias to a channel name</summary>
|
||||||
|
<function>doAlias</function>
|
||||||
|
<shortcut>cha</shortcut>
|
||||||
|
<options />
|
||||||
|
<doc><channel> <alias>
|
||||||
|
Specify a specific alias to use for a channel name.
|
||||||
|
The alias may not be an existing channel name or
|
||||||
|
alias.
|
||||||
|
</doc>
|
||||||
|
</channel-alias>
|
||||||
|
<channel-discover>
|
||||||
|
<summary>Initialize a Channel from its server</summary>
|
||||||
|
<function>doDiscover</function>
|
||||||
|
<shortcut>di</shortcut>
|
||||||
|
<options />
|
||||||
|
<doc>[<channel.xml>|<channel name>]
|
||||||
|
Initialize a channel from its server and create a local channel.xml.
|
||||||
|
If <channel name> is in the format "<username>:<password>@<channel>" then
|
||||||
|
<username> and <password> will be set as the login username/password for
|
||||||
|
<channel>. Use caution when passing the username/password in this way, as
|
||||||
|
it may allow other users on your computer to briefly view your username/
|
||||||
|
password via the system's process list.
|
||||||
|
</doc>
|
||||||
|
</channel-discover>
|
||||||
|
<channel-login>
|
||||||
|
<summary>Connects and authenticates to remote channel server</summary>
|
||||||
|
<function>doLogin</function>
|
||||||
|
<shortcut>cli</shortcut>
|
||||||
|
<options />
|
||||||
|
<doc><channel name>
|
||||||
|
Log in to a remote channel server. If <channel name> is not supplied,
|
||||||
|
the default channel is used. To use remote functions in the installer
|
||||||
|
that require any kind of privileges, you need to log in first. The
|
||||||
|
username and password you enter here will be stored in your per-user
|
||||||
|
PEAR configuration (~/.pearrc on Unix-like systems). After logging
|
||||||
|
in, your username and password will be sent along in subsequent
|
||||||
|
operations on the remote server.</doc>
|
||||||
|
</channel-login>
|
||||||
|
<channel-logout>
|
||||||
|
<summary>Logs out from the remote channel server</summary>
|
||||||
|
<function>doLogout</function>
|
||||||
|
<shortcut>clo</shortcut>
|
||||||
|
<options />
|
||||||
|
<doc><channel name>
|
||||||
|
Logs out from a remote channel server. If <channel name> is not supplied,
|
||||||
|
the default channel is used. This command does not actually connect to the
|
||||||
|
remote server, it only deletes the stored username and password from your user
|
||||||
|
configuration.</doc>
|
||||||
|
</channel-logout>
|
||||||
|
</commands>
|
|
@ -1,36 +1,52 @@
|
||||||
<?php
|
<?php
|
||||||
//
|
/**
|
||||||
// +----------------------------------------------------------------------+
|
* PEAR_Command_Common base class
|
||||||
// | PHP Version 5 |
|
*
|
||||||
// +----------------------------------------------------------------------+
|
* PHP versions 4 and 5
|
||||||
// | Copyright (c) 1997-2004 The PHP Group |
|
*
|
||||||
// +----------------------------------------------------------------------+
|
* @category pear
|
||||||
// | This source file is subject to version 3.0 of the PHP license, |
|
* @package PEAR
|
||||||
// | that is bundled with this package in the file LICENSE, and is |
|
* @author Stig Bakken <ssb@php.net>
|
||||||
// | available through the world-wide-web at the following url: |
|
* @author Greg Beaver <cellog@php.net>
|
||||||
// | http://www.php.net/license/3_0.txt. |
|
* @copyright 1997-2009 The Authors
|
||||||
// | If you did not receive a copy of the PHP license and are unable to |
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
// | obtain it through the world-wide-web, please send a note to |
|
* @version CVS: $Id: Common.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
// | license@php.net so we can mail you a copy immediately. |
|
* @link http://pear.php.net/package/PEAR
|
||||||
// +----------------------------------------------------------------------+
|
* @since File available since Release 0.1
|
||||||
// | Author: Stig Sæther Bakken <ssb@php.net> |
|
*/
|
||||||
// +----------------------------------------------------------------------+
|
|
||||||
//
|
|
||||||
// $Id: Common.php,v 1.24 2004/01/08 17:33:13 sniper Exp $
|
|
||||||
|
|
||||||
require_once "PEAR.php";
|
/**
|
||||||
|
* base class
|
||||||
|
*/
|
||||||
|
require_once 'PEAR.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PEAR commands base class
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Stig Bakken <ssb@php.net>
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 0.1
|
||||||
|
*/
|
||||||
class PEAR_Command_Common extends PEAR
|
class PEAR_Command_Common extends PEAR
|
||||||
{
|
{
|
||||||
// {{{ properties
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PEAR_Config object used to pass user system and configuration
|
* PEAR_Config object used to pass user system and configuration
|
||||||
* on when executing commands
|
* on when executing commands
|
||||||
*
|
*
|
||||||
* @var object
|
* @var PEAR_Config
|
||||||
*/
|
*/
|
||||||
var $config;
|
var $config;
|
||||||
|
/**
|
||||||
|
* @var PEAR_Registry
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
var $_registry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User Interface object, for all interaction with the user.
|
* User Interface object, for all interaction with the user.
|
||||||
|
@ -50,7 +66,7 @@ class PEAR_Command_Common extends PEAR
|
||||||
|
|
||||||
var $_deps_type_trans = array(
|
var $_deps_type_trans = array(
|
||||||
'pkg' => 'package',
|
'pkg' => 'package',
|
||||||
'extension' => 'extension',
|
'ext' => 'extension',
|
||||||
'php' => 'PHP',
|
'php' => 'PHP',
|
||||||
'prog' => 'external program',
|
'prog' => 'external program',
|
||||||
'ldlib' => 'external library for linking',
|
'ldlib' => 'external library for linking',
|
||||||
|
@ -60,9 +76,6 @@ class PEAR_Command_Common extends PEAR
|
||||||
'sapi' => 'SAPI backend'
|
'sapi' => 'SAPI backend'
|
||||||
);
|
);
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ constructor
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PEAR_Command_Common constructor.
|
* PEAR_Command_Common constructor.
|
||||||
*
|
*
|
||||||
|
@ -75,10 +88,6 @@ class PEAR_Command_Common extends PEAR
|
||||||
$this->ui = &$ui;
|
$this->ui = &$ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
|
|
||||||
// {{{ getCommands()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a list of all the commands defined by this class.
|
* Return a list of all the commands defined by this class.
|
||||||
* @return array list of commands
|
* @return array list of commands
|
||||||
|
@ -90,12 +99,10 @@ class PEAR_Command_Common extends PEAR
|
||||||
foreach (array_keys($this->commands) as $command) {
|
foreach (array_keys($this->commands) as $command) {
|
||||||
$ret[$command] = $this->commands[$command]['summary'];
|
$ret[$command] = $this->commands[$command]['summary'];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ getShortcuts()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a list of all the command shortcuts defined by this class.
|
* Return a list of all the command shortcuts defined by this class.
|
||||||
* @return array shortcut => command
|
* @return array shortcut => command
|
||||||
|
@ -109,28 +116,34 @@ class PEAR_Command_Common extends PEAR
|
||||||
$ret[$this->commands[$command]['shortcut']] = $command;
|
$ret[$this->commands[$command]['shortcut']] = $command;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ getOptions()
|
|
||||||
|
|
||||||
function getOptions($command)
|
function getOptions($command)
|
||||||
{
|
{
|
||||||
return @$this->commands[$command]['options'];
|
$shortcuts = $this->getShortcuts();
|
||||||
|
if (isset($shortcuts[$command])) {
|
||||||
|
$command = $shortcuts[$command];
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
if (isset($this->commands[$command]) &&
|
||||||
// {{{ getGetoptArgs()
|
isset($this->commands[$command]['options'])) {
|
||||||
|
return $this->commands[$command]['options'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
function getGetoptArgs($command, &$short_args, &$long_args)
|
function getGetoptArgs($command, &$short_args, &$long_args)
|
||||||
{
|
{
|
||||||
$short_args = "";
|
$short_args = '';
|
||||||
$long_args = array();
|
$long_args = array();
|
||||||
if (empty($this->commands[$command])) {
|
if (empty($this->commands[$command]) || empty($this->commands[$command]['options'])) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
reset($this->commands[$command]);
|
|
||||||
|
reset($this->commands[$command]['options']);
|
||||||
while (list($option, $info) = each($this->commands[$command]['options'])) {
|
while (list($option, $info) = each($this->commands[$command]['options'])) {
|
||||||
$larg = $sarg = '';
|
$larg = $sarg = '';
|
||||||
if (isset($info['arg'])) {
|
if (isset($info['arg'])) {
|
||||||
|
@ -144,15 +157,15 @@ class PEAR_Command_Common extends PEAR
|
||||||
$arg = $info['arg'];
|
$arg = $info['arg'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($info['shortopt'])) {
|
if (isset($info['shortopt'])) {
|
||||||
$short_args .= $info['shortopt'] . $sarg;
|
$short_args .= $info['shortopt'] . $sarg;
|
||||||
}
|
}
|
||||||
|
|
||||||
$long_args[] = $option . $larg;
|
$long_args[] = $option . $larg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ getHelp()
|
|
||||||
/**
|
/**
|
||||||
* Returns the help message for the given command
|
* Returns the help message for the given command
|
||||||
*
|
*
|
||||||
|
@ -164,23 +177,32 @@ class PEAR_Command_Common extends PEAR
|
||||||
function getHelp($command)
|
function getHelp($command)
|
||||||
{
|
{
|
||||||
$config = &PEAR_Config::singleton();
|
$config = &PEAR_Config::singleton();
|
||||||
$help = @$this->commands[$command]['doc'];
|
if (!isset($this->commands[$command])) {
|
||||||
|
return "No such command \"$command\"";
|
||||||
|
}
|
||||||
|
|
||||||
|
$help = null;
|
||||||
|
if (isset($this->commands[$command]['doc'])) {
|
||||||
|
$help = $this->commands[$command]['doc'];
|
||||||
|
}
|
||||||
|
|
||||||
if (empty($help)) {
|
if (empty($help)) {
|
||||||
// XXX (cox) Fallback to summary if there is no doc (show both?)
|
// XXX (cox) Fallback to summary if there is no doc (show both?)
|
||||||
if (!$help = @$this->commands[$command]['summary']) {
|
if (!isset($this->commands[$command]['summary'])) {
|
||||||
return "No help for command \"$command\"";
|
return "No help for command \"$command\"";
|
||||||
}
|
}
|
||||||
|
$help = $this->commands[$command]['summary'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (preg_match_all('/{config\s+([^\}]+)}/e', $help, $matches)) {
|
if (preg_match_all('/{config\s+([^\}]+)}/e', $help, $matches)) {
|
||||||
foreach($matches[0] as $k => $v) {
|
foreach($matches[0] as $k => $v) {
|
||||||
$help = preg_replace("/$v/", $config->get($matches[1][$k]), $help);
|
$help = preg_replace("/$v/", $config->get($matches[1][$k]), $help);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return array($help, $this->getHelpArgs($command));
|
return array($help, $this->getHelpArgs($command));
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ getHelpArgs()
|
|
||||||
/**
|
/**
|
||||||
* Returns the help for the accepted arguments of a command
|
* Returns the help for the accepted arguments of a command
|
||||||
*
|
*
|
||||||
|
@ -195,7 +217,7 @@ class PEAR_Command_Common extends PEAR
|
||||||
$help = "Options:\n";
|
$help = "Options:\n";
|
||||||
foreach ($this->commands[$command]['options'] as $k => $v) {
|
foreach ($this->commands[$command]['options'] as $k => $v) {
|
||||||
if (isset($v['arg'])) {
|
if (isset($v['arg'])) {
|
||||||
if ($v['arg']{0} == '(') {
|
if ($v['arg'][0] == '(') {
|
||||||
$arg = substr($v['arg'], 1, -1);
|
$arg = substr($v['arg'], 1, -1);
|
||||||
$sapp = " [$arg]";
|
$sapp = " [$arg]";
|
||||||
$lapp = "[=$arg]";
|
$lapp = "[=$arg]";
|
||||||
|
@ -206,44 +228,46 @@ class PEAR_Command_Common extends PEAR
|
||||||
} else {
|
} else {
|
||||||
$sapp = $lapp = "";
|
$sapp = $lapp = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($v['shortopt'])) {
|
if (isset($v['shortopt'])) {
|
||||||
$s = $v['shortopt'];
|
$s = $v['shortopt'];
|
||||||
@$help .= " -$s$sapp, --$k$lapp\n";
|
$help .= " -$s$sapp, --$k$lapp\n";
|
||||||
} else {
|
} else {
|
||||||
@$help .= " --$k$lapp\n";
|
$help .= " --$k$lapp\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
$p = " ";
|
$p = " ";
|
||||||
$doc = rtrim(str_replace("\n", "\n$p", $v['doc']));
|
$doc = rtrim(str_replace("\n", "\n$p", $v['doc']));
|
||||||
$help .= " $doc\n";
|
$help .= " $doc\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return $help;
|
return $help;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ run()
|
|
||||||
|
|
||||||
function run($command, $options, $params)
|
function run($command, $options, $params)
|
||||||
{
|
{
|
||||||
$func = @$this->commands[$command]['function'];
|
if (empty($this->commands[$command]['function'])) {
|
||||||
if (empty($func)) {
|
|
||||||
// look for shortcuts
|
// look for shortcuts
|
||||||
foreach (array_keys($this->commands) as $cmd) {
|
foreach (array_keys($this->commands) as $cmd) {
|
||||||
if (@$this->commands[$cmd]['shortcut'] == $command) {
|
if (isset($this->commands[$cmd]['shortcut']) && $this->commands[$cmd]['shortcut'] == $command) {
|
||||||
$command = $cmd;
|
if (empty($this->commands[$cmd]['function'])) {
|
||||||
$func = @$this->commands[$command]['function'];
|
|
||||||
if (empty($func)) {
|
|
||||||
return $this->raiseError("unknown command `$command'");
|
return $this->raiseError("unknown command `$command'");
|
||||||
|
} else {
|
||||||
|
$func = $this->commands[$cmd]['function'];
|
||||||
}
|
}
|
||||||
|
$command = $cmd;
|
||||||
|
|
||||||
|
//$command = $this->commands[$cmd]['function'];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
$func = $this->commands[$command]['function'];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->$func($command, $options, $params);
|
return $this->$func($command, $options, $params);
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
|
|
@ -1,74 +1,101 @@
|
||||||
<?php
|
<?php
|
||||||
//
|
/**
|
||||||
// +----------------------------------------------------------------------+
|
* PEAR_Command_Config (config-show, config-get, config-set, config-help, config-create commands)
|
||||||
// | PHP Version 5 |
|
*
|
||||||
// +----------------------------------------------------------------------+
|
* PHP versions 4 and 5
|
||||||
// | Copyright (c) 1997-2004 The PHP Group |
|
*
|
||||||
// +----------------------------------------------------------------------+
|
* @category pear
|
||||||
// | This source file is subject to version 3.0 of the PHP license, |
|
* @package PEAR
|
||||||
// | that is bundled with this package in the file LICENSE, and is |
|
* @author Stig Bakken <ssb@php.net>
|
||||||
// | available through the world-wide-web at the following url: |
|
* @author Greg Beaver <cellog@php.net>
|
||||||
// | http://www.php.net/license/3_0.txt. |
|
* @copyright 1997-2009 The Authors
|
||||||
// | If you did not receive a copy of the PHP license and are unable to |
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
// | obtain it through the world-wide-web, please send a note to |
|
* @version CVS: $Id: Config.php 313024 2011-07-06 19:51:24Z dufuz $
|
||||||
// | license@php.net so we can mail you a copy immediately. |
|
* @link http://pear.php.net/package/PEAR
|
||||||
// +----------------------------------------------------------------------+
|
* @since File available since Release 0.1
|
||||||
// | Author: Stig Bakken <ssb@php.net> |
|
*/
|
||||||
// | Tomas V.V.Cox <cox@idecnet.com> |
|
|
||||||
// | |
|
|
||||||
// +----------------------------------------------------------------------+
|
|
||||||
//
|
|
||||||
// $Id: Config.php,v 1.27 2004/06/15 16:48:49 pajoye Exp $
|
|
||||||
|
|
||||||
require_once "PEAR/Command/Common.php";
|
/**
|
||||||
require_once "PEAR/Config.php";
|
* base class
|
||||||
|
*/
|
||||||
|
require_once 'PEAR/Command/Common.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PEAR commands for managing configuration data.
|
* PEAR commands for managing configuration data.
|
||||||
*
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Stig Bakken <ssb@php.net>
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 0.1
|
||||||
*/
|
*/
|
||||||
class PEAR_Command_Config extends PEAR_Command_Common
|
class PEAR_Command_Config extends PEAR_Command_Common
|
||||||
{
|
{
|
||||||
// {{{ properties
|
|
||||||
|
|
||||||
var $commands = array(
|
var $commands = array(
|
||||||
'config-show' => array(
|
'config-show' => array(
|
||||||
'summary' => 'Show All Settings',
|
'summary' => 'Show All Settings',
|
||||||
'function' => 'doConfigShow',
|
'function' => 'doConfigShow',
|
||||||
'shortcut' => 'csh',
|
'shortcut' => 'csh',
|
||||||
'options' => array(),
|
'options' => array(
|
||||||
'doc' => '
|
'channel' => array(
|
||||||
|
'shortopt' => 'c',
|
||||||
|
'doc' => 'show configuration variables for another channel',
|
||||||
|
'arg' => 'CHAN',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'doc' => '[layer]
|
||||||
Displays all configuration values. An optional argument
|
Displays all configuration values. An optional argument
|
||||||
may be used to tell which configuration layer to display. Valid
|
may be used to tell which configuration layer to display. Valid
|
||||||
configuration layers are "user", "system" and "default".
|
configuration layers are "user", "system" and "default". To display
|
||||||
|
configurations for different channels, set the default_channel
|
||||||
|
configuration variable and run config-show again.
|
||||||
',
|
',
|
||||||
),
|
),
|
||||||
'config-get' => array(
|
'config-get' => array(
|
||||||
'summary' => 'Show One Setting',
|
'summary' => 'Show One Setting',
|
||||||
'function' => 'doConfigGet',
|
'function' => 'doConfigGet',
|
||||||
'shortcut' => 'cg',
|
'shortcut' => 'cg',
|
||||||
'options' => array(),
|
'options' => array(
|
||||||
|
'channel' => array(
|
||||||
|
'shortopt' => 'c',
|
||||||
|
'doc' => 'show configuration variables for another channel',
|
||||||
|
'arg' => 'CHAN',
|
||||||
|
),
|
||||||
|
),
|
||||||
'doc' => '<parameter> [layer]
|
'doc' => '<parameter> [layer]
|
||||||
Displays the value of one configuration parameter. The
|
Displays the value of one configuration parameter. The
|
||||||
first argument is the name of the parameter, an optional second argument
|
first argument is the name of the parameter, an optional second argument
|
||||||
may be used to tell which configuration layer to look in. Valid configuration
|
may be used to tell which configuration layer to look in. Valid configuration
|
||||||
layers are "user", "system" and "default". If no layer is specified, a value
|
layers are "user", "system" and "default". If no layer is specified, a value
|
||||||
will be picked from the first layer that defines the parameter, in the order
|
will be picked from the first layer that defines the parameter, in the order
|
||||||
just specified.
|
just specified. The configuration value will be retrieved for the channel
|
||||||
|
specified by the default_channel configuration variable.
|
||||||
',
|
',
|
||||||
),
|
),
|
||||||
'config-set' => array(
|
'config-set' => array(
|
||||||
'summary' => 'Change Setting',
|
'summary' => 'Change Setting',
|
||||||
'function' => 'doConfigSet',
|
'function' => 'doConfigSet',
|
||||||
'shortcut' => 'cs',
|
'shortcut' => 'cs',
|
||||||
'options' => array(),
|
'options' => array(
|
||||||
|
'channel' => array(
|
||||||
|
'shortopt' => 'c',
|
||||||
|
'doc' => 'show configuration variables for another channel',
|
||||||
|
'arg' => 'CHAN',
|
||||||
|
),
|
||||||
|
),
|
||||||
'doc' => '<parameter> <value> [layer]
|
'doc' => '<parameter> <value> [layer]
|
||||||
Sets the value of one configuration parameter. The first argument is
|
Sets the value of one configuration parameter. The first argument is
|
||||||
the name of the parameter, the second argument is the new value. Some
|
the name of the parameter, the second argument is the new value. Some
|
||||||
parameters are subject to validation, and the command will fail with
|
parameters are subject to validation, and the command will fail with
|
||||||
an error message if the new value does not make sense. An optional
|
an error message if the new value does not make sense. An optional
|
||||||
third argument may be used to specify in which layer to set the
|
third argument may be used to specify in which layer to set the
|
||||||
configuration parameter. The default layer is "user".
|
configuration parameter. The default layer is "user". The
|
||||||
|
configuration value will be set for the current channel, which
|
||||||
|
is controlled by the default_channel configuration variable.
|
||||||
',
|
',
|
||||||
),
|
),
|
||||||
'config-help' => array(
|
'config-help' => array(
|
||||||
|
@ -79,13 +106,28 @@ configuration parameter. The default layer is "user".
|
||||||
'doc' => '[parameter]
|
'doc' => '[parameter]
|
||||||
Displays help for a configuration parameter. Without arguments it
|
Displays help for a configuration parameter. Without arguments it
|
||||||
displays help for all configuration parameters.
|
displays help for all configuration parameters.
|
||||||
|
',
|
||||||
|
),
|
||||||
|
'config-create' => array(
|
||||||
|
'summary' => 'Create a Default configuration file',
|
||||||
|
'function' => 'doConfigCreate',
|
||||||
|
'shortcut' => 'coc',
|
||||||
|
'options' => array(
|
||||||
|
'windows' => array(
|
||||||
|
'shortopt' => 'w',
|
||||||
|
'doc' => 'create a config file for a windows install',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'doc' => '<root path> <filename>
|
||||||
|
Create a default configuration file with all directory configuration
|
||||||
|
variables set to subdirectories of <root path>, and save it as <filename>.
|
||||||
|
This is useful especially for creating a configuration file for a remote
|
||||||
|
PEAR installation (using the --remoteconfig option of install, upgrade,
|
||||||
|
and uninstall).
|
||||||
',
|
',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ constructor
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PEAR_Command_Config constructor.
|
* PEAR_Command_Config constructor.
|
||||||
*
|
*
|
||||||
|
@ -96,59 +138,83 @@ displays help for all configuration parameters.
|
||||||
parent::PEAR_Command_Common($ui, $config);
|
parent::PEAR_Command_Common($ui, $config);
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
|
|
||||||
// {{{ doConfigShow()
|
|
||||||
|
|
||||||
function doConfigShow($command, $options, $params)
|
function doConfigShow($command, $options, $params)
|
||||||
{
|
{
|
||||||
// $params[0] -> the layer
|
$layer = null;
|
||||||
if ($error = $this->_checkLayer(@$params[0])) {
|
if (is_array($params)) {
|
||||||
return $this->raiseError($error);
|
$layer = isset($params[0]) ? $params[0] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// $params[0] -> the layer
|
||||||
|
if ($error = $this->_checkLayer($layer)) {
|
||||||
|
return $this->raiseError("config-show:$error");
|
||||||
|
}
|
||||||
|
|
||||||
$keys = $this->config->getKeys();
|
$keys = $this->config->getKeys();
|
||||||
sort($keys);
|
sort($keys);
|
||||||
$data = array('caption' => 'Configuration:');
|
$channel = isset($options['channel']) ? $options['channel'] :
|
||||||
|
$this->config->get('default_channel');
|
||||||
|
$reg = &$this->config->getRegistry();
|
||||||
|
if (!$reg->channelExists($channel)) {
|
||||||
|
return $this->raiseError('Channel "' . $channel . '" does not exist');
|
||||||
|
}
|
||||||
|
|
||||||
|
$channel = $reg->channelName($channel);
|
||||||
|
$data = array('caption' => 'Configuration (channel ' . $channel . '):');
|
||||||
foreach ($keys as $key) {
|
foreach ($keys as $key) {
|
||||||
$type = $this->config->getType($key);
|
$type = $this->config->getType($key);
|
||||||
$value = $this->config->get($key, @$params[0]);
|
$value = $this->config->get($key, $layer, $channel);
|
||||||
if ($type == 'password' && $value) {
|
if ($type == 'password' && $value) {
|
||||||
$value = '********';
|
$value = '********';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($value === false) {
|
if ($value === false) {
|
||||||
$value = 'false';
|
$value = 'false';
|
||||||
} elseif ($value === true) {
|
} elseif ($value === true) {
|
||||||
$value = 'true';
|
$value = 'true';
|
||||||
}
|
}
|
||||||
|
|
||||||
$data['data'][$this->config->getGroup($key)][] = array($this->config->getPrompt($key) , $key, $value);
|
$data['data'][$this->config->getGroup($key)][] = array($this->config->getPrompt($key) , $key, $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach ($this->config->getLayers() as $layer) {
|
||||||
|
$data['data']['Config Files'][] = array(ucfirst($layer) . ' Configuration File', 'Filename' , $this->config->getConfFile($layer));
|
||||||
|
}
|
||||||
|
|
||||||
$this->ui->outputData($data, $command);
|
$this->ui->outputData($data, $command);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ doConfigGet()
|
|
||||||
|
|
||||||
function doConfigGet($command, $options, $params)
|
function doConfigGet($command, $options, $params)
|
||||||
{
|
{
|
||||||
// $params[0] -> the parameter
|
$args_cnt = is_array($params) ? count($params) : 0;
|
||||||
// $params[1] -> the layer
|
switch ($args_cnt) {
|
||||||
if ($error = $this->_checkLayer(@$params[1])) {
|
case 1:
|
||||||
return $this->raiseError($error);
|
$config_key = $params[0];
|
||||||
|
$layer = null;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
$config_key = $params[0];
|
||||||
|
$layer = $params[1];
|
||||||
|
if ($error = $this->_checkLayer($layer)) {
|
||||||
|
return $this->raiseError("config-get:$error");
|
||||||
}
|
}
|
||||||
if (sizeof($params) < 1 || sizeof($params) > 2) {
|
break;
|
||||||
|
case 0:
|
||||||
|
default:
|
||||||
return $this->raiseError("config-get expects 1 or 2 parameters");
|
return $this->raiseError("config-get expects 1 or 2 parameters");
|
||||||
} elseif (sizeof($params) == 1) {
|
|
||||||
$this->ui->outputData($this->config->get($params[0]), $command);
|
|
||||||
} else {
|
|
||||||
$data = $this->config->get($params[0], $params[1]);
|
|
||||||
$this->ui->outputData($data, $command);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
$reg = &$this->config->getRegistry();
|
||||||
// {{{ doConfigSet()
|
$channel = isset($options['channel']) ? $options['channel'] : $this->config->get('default_channel');
|
||||||
|
if (!$reg->channelExists($channel)) {
|
||||||
|
return $this->raiseError('Channel "' . $channel . '" does not exist');
|
||||||
|
}
|
||||||
|
|
||||||
|
$channel = $reg->channelName($channel);
|
||||||
|
$this->ui->outputData($this->config->get($config_key, $layer, $channel), $command);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
function doConfigSet($command, $options, $params)
|
function doConfigSet($command, $options, $params)
|
||||||
{
|
{
|
||||||
|
@ -156,34 +222,70 @@ displays help for all configuration parameters.
|
||||||
// $param[1] -> the value for the parameter
|
// $param[1] -> the value for the parameter
|
||||||
// $param[2] -> the layer
|
// $param[2] -> the layer
|
||||||
$failmsg = '';
|
$failmsg = '';
|
||||||
if (sizeof($params) < 2 || sizeof($params) > 3) {
|
if (count($params) < 2 || count($params) > 3) {
|
||||||
$failmsg .= "config-set expects 2 or 3 parameters";
|
$failmsg .= "config-set expects 2 or 3 parameters";
|
||||||
return PEAR::raiseError($failmsg);
|
return PEAR::raiseError($failmsg);
|
||||||
}
|
}
|
||||||
if ($error = $this->_checkLayer(@$params[2])) {
|
|
||||||
|
if (isset($params[2]) && ($error = $this->_checkLayer($params[2]))) {
|
||||||
$failmsg .= $error;
|
$failmsg .= $error;
|
||||||
return PEAR::raiseError($failmsg);
|
return PEAR::raiseError("config-set:$failmsg");
|
||||||
}
|
}
|
||||||
if (!call_user_func_array(array(&$this->config, 'set'), $params))
|
|
||||||
{
|
$channel = isset($options['channel']) ? $options['channel'] : $this->config->get('default_channel');
|
||||||
$failmsg = "config-set (" . implode(", ", $params) . ") failed";
|
$reg = &$this->config->getRegistry();
|
||||||
|
if (!$reg->channelExists($channel)) {
|
||||||
|
return $this->raiseError('Channel "' . $channel . '" does not exist');
|
||||||
|
}
|
||||||
|
|
||||||
|
$channel = $reg->channelName($channel);
|
||||||
|
if ($params[0] == 'default_channel' && !$reg->channelExists($params[1])) {
|
||||||
|
return $this->raiseError('Channel "' . $params[1] . '" does not exist');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($params[0] == 'preferred_mirror'
|
||||||
|
&& (
|
||||||
|
!$reg->mirrorExists($channel, $params[1]) &&
|
||||||
|
(!$reg->channelExists($params[1]) || $channel != $params[1])
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
$msg = 'Channel Mirror "' . $params[1] . '" does not exist';
|
||||||
|
$msg .= ' in your registry for channel "' . $channel . '".';
|
||||||
|
$msg .= "\n" . 'Attempt to run "pear channel-update ' . $channel .'"';
|
||||||
|
$msg .= ' if you believe this mirror should exist as you may';
|
||||||
|
$msg .= ' have outdated channel information.';
|
||||||
|
return $this->raiseError($msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($params) == 2) {
|
||||||
|
array_push($params, 'user');
|
||||||
|
$layer = 'user';
|
||||||
} else {
|
} else {
|
||||||
$this->config->store();
|
$layer = $params[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
array_push($params, $channel);
|
||||||
|
if (!call_user_func_array(array(&$this->config, 'set'), $params)) {
|
||||||
|
array_pop($params);
|
||||||
|
$failmsg = "config-set (" . implode(", ", $params) . ") failed, channel $channel";
|
||||||
|
} else {
|
||||||
|
$this->config->store($layer);
|
||||||
|
}
|
||||||
|
|
||||||
if ($failmsg) {
|
if ($failmsg) {
|
||||||
return $this->raiseError($failmsg);
|
return $this->raiseError($failmsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->ui->outputData('config-set succeeded', $command);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ doConfigHelp()
|
|
||||||
|
|
||||||
function doConfigHelp($command, $options, $params)
|
function doConfigHelp($command, $options, $params)
|
||||||
{
|
{
|
||||||
if (empty($params)) {
|
if (empty($params)) {
|
||||||
$params = $this->config->getKeys();
|
$params = $this->config->getKeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
$data['caption'] = "Config help" . ((count($params) == 1) ? " for $params[0]" : '');
|
$data['caption'] = "Config help" . ((count($params) == 1) ? " for $params[0]" : '');
|
||||||
$data['headline'] = array('Name', 'Type', 'Description');
|
$data['headline'] = array('Name', 'Type', 'Description');
|
||||||
$data['border'] = true;
|
$data['border'] = true;
|
||||||
|
@ -194,13 +296,103 @@ displays help for all configuration parameters.
|
||||||
$docs = rtrim($docs) . "\nValid set: " .
|
$docs = rtrim($docs) . "\nValid set: " .
|
||||||
implode(' ', $this->config->getSetValues($name));
|
implode(' ', $this->config->getSetValues($name));
|
||||||
}
|
}
|
||||||
|
|
||||||
$data['data'][] = array($name, $type, $docs);
|
$data['data'][] = array($name, $type, $docs);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->ui->outputData($data, $command);
|
$this->ui->outputData($data, $command);
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
function doConfigCreate($command, $options, $params)
|
||||||
// {{{ _checkLayer()
|
{
|
||||||
|
if (count($params) != 2) {
|
||||||
|
return PEAR::raiseError('config-create: must have 2 parameters, root path and ' .
|
||||||
|
'filename to save as');
|
||||||
|
}
|
||||||
|
|
||||||
|
$root = $params[0];
|
||||||
|
// Clean up the DIRECTORY_SEPARATOR mess
|
||||||
|
$ds2 = DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR;
|
||||||
|
$root = preg_replace(array('!\\\\+!', '!/+!', "!$ds2+!"),
|
||||||
|
array('/', '/', '/'),
|
||||||
|
$root);
|
||||||
|
if ($root{0} != '/') {
|
||||||
|
if (!isset($options['windows'])) {
|
||||||
|
return PEAR::raiseError('Root directory must be an absolute path beginning ' .
|
||||||
|
'with "/", was: "' . $root . '"');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!preg_match('/^[A-Za-z]:/', $root)) {
|
||||||
|
return PEAR::raiseError('Root directory must be an absolute path beginning ' .
|
||||||
|
'with "\\" or "C:\\", was: "' . $root . '"');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$windows = isset($options['windows']);
|
||||||
|
if ($windows) {
|
||||||
|
$root = str_replace('/', '\\', $root);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!file_exists($params[1]) && !@touch($params[1])) {
|
||||||
|
return PEAR::raiseError('Could not create "' . $params[1] . '"');
|
||||||
|
}
|
||||||
|
|
||||||
|
$params[1] = realpath($params[1]);
|
||||||
|
$config = &new PEAR_Config($params[1], '#no#system#config#', false, false);
|
||||||
|
if ($root{strlen($root) - 1} == '/') {
|
||||||
|
$root = substr($root, 0, strlen($root) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
$config->noRegistry();
|
||||||
|
$config->set('php_dir', $windows ? "$root\\pear\\php" : "$root/pear/php", 'user');
|
||||||
|
$config->set('data_dir', $windows ? "$root\\pear\\data" : "$root/pear/data");
|
||||||
|
$config->set('www_dir', $windows ? "$root\\pear\\www" : "$root/pear/www");
|
||||||
|
$config->set('cfg_dir', $windows ? "$root\\pear\\cfg" : "$root/pear/cfg");
|
||||||
|
$config->set('ext_dir', $windows ? "$root\\pear\\ext" : "$root/pear/ext");
|
||||||
|
$config->set('doc_dir', $windows ? "$root\\pear\\docs" : "$root/pear/docs");
|
||||||
|
$config->set('test_dir', $windows ? "$root\\pear\\tests" : "$root/pear/tests");
|
||||||
|
$config->set('cache_dir', $windows ? "$root\\pear\\cache" : "$root/pear/cache");
|
||||||
|
$config->set('download_dir', $windows ? "$root\\pear\\download" : "$root/pear/download");
|
||||||
|
$config->set('temp_dir', $windows ? "$root\\pear\\temp" : "$root/pear/temp");
|
||||||
|
$config->set('bin_dir', $windows ? "$root\\pear" : "$root/pear");
|
||||||
|
$config->writeConfigFile();
|
||||||
|
$this->_showConfig($config);
|
||||||
|
$this->ui->outputData('Successfully created default configuration file "' . $params[1] . '"',
|
||||||
|
$command);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _showConfig(&$config)
|
||||||
|
{
|
||||||
|
$params = array('user');
|
||||||
|
$keys = $config->getKeys();
|
||||||
|
sort($keys);
|
||||||
|
$channel = 'pear.php.net';
|
||||||
|
$data = array('caption' => 'Configuration (channel ' . $channel . '):');
|
||||||
|
foreach ($keys as $key) {
|
||||||
|
$type = $config->getType($key);
|
||||||
|
$value = $config->get($key, 'user', $channel);
|
||||||
|
if ($type == 'password' && $value) {
|
||||||
|
$value = '********';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($value === false) {
|
||||||
|
$value = 'false';
|
||||||
|
} elseif ($value === true) {
|
||||||
|
$value = 'true';
|
||||||
|
}
|
||||||
|
$data['data'][$config->getGroup($key)][] =
|
||||||
|
array($config->getPrompt($key) , $key, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($config->getLayers() as $layer) {
|
||||||
|
$data['data']['Config Files'][] =
|
||||||
|
array(ucfirst($layer) . ' Configuration File', 'Filename' ,
|
||||||
|
$config->getConfFile($layer));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->ui->outputData($data, 'config-show');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if a layer is defined or not
|
* Checks if a layer is defined or not
|
||||||
|
@ -216,10 +408,7 @@ displays help for all configuration parameters.
|
||||||
return " only the layers: \"" . implode('" or "', $layers) . "\" are supported";
|
return " only the layers: \"" . implode('" or "', $layers) . "\" are supported";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
<commands version="1.0">
|
||||||
|
<config-show>
|
||||||
|
<summary>Show All Settings</summary>
|
||||||
|
<function>doConfigShow</function>
|
||||||
|
<shortcut>csh</shortcut>
|
||||||
|
<options>
|
||||||
|
<channel>
|
||||||
|
<shortopt>c</shortopt>
|
||||||
|
<doc>show configuration variables for another channel</doc>
|
||||||
|
<arg>CHAN</arg>
|
||||||
|
</channel>
|
||||||
|
</options>
|
||||||
|
<doc>[layer]
|
||||||
|
Displays all configuration values. An optional argument
|
||||||
|
may be used to tell which configuration layer to display. Valid
|
||||||
|
configuration layers are "user", "system" and "default". To display
|
||||||
|
configurations for different channels, set the default_channel
|
||||||
|
configuration variable and run config-show again.
|
||||||
|
</doc>
|
||||||
|
</config-show>
|
||||||
|
<config-get>
|
||||||
|
<summary>Show One Setting</summary>
|
||||||
|
<function>doConfigGet</function>
|
||||||
|
<shortcut>cg</shortcut>
|
||||||
|
<options>
|
||||||
|
<channel>
|
||||||
|
<shortopt>c</shortopt>
|
||||||
|
<doc>show configuration variables for another channel</doc>
|
||||||
|
<arg>CHAN</arg>
|
||||||
|
</channel>
|
||||||
|
</options>
|
||||||
|
<doc><parameter> [layer]
|
||||||
|
Displays the value of one configuration parameter. The
|
||||||
|
first argument is the name of the parameter, an optional second argument
|
||||||
|
may be used to tell which configuration layer to look in. Valid configuration
|
||||||
|
layers are "user", "system" and "default". If no layer is specified, a value
|
||||||
|
will be picked from the first layer that defines the parameter, in the order
|
||||||
|
just specified. The configuration value will be retrieved for the channel
|
||||||
|
specified by the default_channel configuration variable.
|
||||||
|
</doc>
|
||||||
|
</config-get>
|
||||||
|
<config-set>
|
||||||
|
<summary>Change Setting</summary>
|
||||||
|
<function>doConfigSet</function>
|
||||||
|
<shortcut>cs</shortcut>
|
||||||
|
<options>
|
||||||
|
<channel>
|
||||||
|
<shortopt>c</shortopt>
|
||||||
|
<doc>show configuration variables for another channel</doc>
|
||||||
|
<arg>CHAN</arg>
|
||||||
|
</channel>
|
||||||
|
</options>
|
||||||
|
<doc><parameter> <value> [layer]
|
||||||
|
Sets the value of one configuration parameter. The first argument is
|
||||||
|
the name of the parameter, the second argument is the new value. Some
|
||||||
|
parameters are subject to validation, and the command will fail with
|
||||||
|
an error message if the new value does not make sense. An optional
|
||||||
|
third argument may be used to specify in which layer to set the
|
||||||
|
configuration parameter. The default layer is "user". The
|
||||||
|
configuration value will be set for the current channel, which
|
||||||
|
is controlled by the default_channel configuration variable.
|
||||||
|
</doc>
|
||||||
|
</config-set>
|
||||||
|
<config-help>
|
||||||
|
<summary>Show Information About Setting</summary>
|
||||||
|
<function>doConfigHelp</function>
|
||||||
|
<shortcut>ch</shortcut>
|
||||||
|
<options />
|
||||||
|
<doc>[parameter]
|
||||||
|
Displays help for a configuration parameter. Without arguments it
|
||||||
|
displays help for all configuration parameters.
|
||||||
|
</doc>
|
||||||
|
</config-help>
|
||||||
|
<config-create>
|
||||||
|
<summary>Create a Default configuration file</summary>
|
||||||
|
<function>doConfigCreate</function>
|
||||||
|
<shortcut>coc</shortcut>
|
||||||
|
<options>
|
||||||
|
<windows>
|
||||||
|
<shortopt>w</shortopt>
|
||||||
|
<doc>create a config file for a windows install</doc>
|
||||||
|
</windows>
|
||||||
|
</options>
|
||||||
|
<doc><root path> <filename>
|
||||||
|
Create a default configuration file with all directory configuration
|
||||||
|
variables set to subdirectories of <root path>, and save it as <filename>.
|
||||||
|
This is useful especially for creating a configuration file for a remote
|
||||||
|
PEAR installation (using the --remoteconfig option of install, upgrade,
|
||||||
|
and uninstall).
|
||||||
|
</doc>
|
||||||
|
</config-create>
|
||||||
|
</commands>
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,276 @@
|
||||||
|
<commands version="1.0">
|
||||||
|
<install>
|
||||||
|
<summary>Install Package</summary>
|
||||||
|
<function>doInstall</function>
|
||||||
|
<shortcut>i</shortcut>
|
||||||
|
<options>
|
||||||
|
<force>
|
||||||
|
<shortopt>f</shortopt>
|
||||||
|
<doc>will overwrite newer installed packages</doc>
|
||||||
|
</force>
|
||||||
|
<loose>
|
||||||
|
<shortopt>l</shortopt>
|
||||||
|
<doc>do not check for recommended dependency version</doc>
|
||||||
|
</loose>
|
||||||
|
<nodeps>
|
||||||
|
<shortopt>n</shortopt>
|
||||||
|
<doc>ignore dependencies, install anyway</doc>
|
||||||
|
</nodeps>
|
||||||
|
<register-only>
|
||||||
|
<shortopt>r</shortopt>
|
||||||
|
<doc>do not install files, only register the package as installed</doc>
|
||||||
|
</register-only>
|
||||||
|
<soft>
|
||||||
|
<shortopt>s</shortopt>
|
||||||
|
<doc>soft install, fail silently, or upgrade if already installed</doc>
|
||||||
|
</soft>
|
||||||
|
<nobuild>
|
||||||
|
<shortopt>B</shortopt>
|
||||||
|
<doc>don't build C extensions</doc>
|
||||||
|
</nobuild>
|
||||||
|
<nocompress>
|
||||||
|
<shortopt>Z</shortopt>
|
||||||
|
<doc>request uncompressed files when downloading</doc>
|
||||||
|
</nocompress>
|
||||||
|
<installroot>
|
||||||
|
<shortopt>R</shortopt>
|
||||||
|
<doc>root directory used when installing files (ala PHP's INSTALL_ROOT), use packagingroot for RPM</doc>
|
||||||
|
<arg>DIR</arg>
|
||||||
|
</installroot>
|
||||||
|
<packagingroot>
|
||||||
|
<shortopt>P</shortopt>
|
||||||
|
<doc>root directory used when packaging files, like RPM packaging</doc>
|
||||||
|
<arg>DIR</arg>
|
||||||
|
</packagingroot>
|
||||||
|
<ignore-errors>
|
||||||
|
<shortopt></shortopt>
|
||||||
|
<doc>force install even if there were errors</doc>
|
||||||
|
</ignore-errors>
|
||||||
|
<alldeps>
|
||||||
|
<shortopt>a</shortopt>
|
||||||
|
<doc>install all required and optional dependencies</doc>
|
||||||
|
</alldeps>
|
||||||
|
<onlyreqdeps>
|
||||||
|
<shortopt>o</shortopt>
|
||||||
|
<doc>install all required dependencies</doc>
|
||||||
|
</onlyreqdeps>
|
||||||
|
<offline>
|
||||||
|
<shortopt>O</shortopt>
|
||||||
|
<doc>do not attempt to download any urls or contact channels</doc>
|
||||||
|
</offline>
|
||||||
|
<pretend>
|
||||||
|
<shortopt>p</shortopt>
|
||||||
|
<doc>Only list the packages that would be downloaded</doc>
|
||||||
|
</pretend>
|
||||||
|
</options>
|
||||||
|
<doc>[channel/]<package> ...
|
||||||
|
Installs one or more PEAR packages. You can specify a package to
|
||||||
|
install in four ways:
|
||||||
|
|
||||||
|
"Package-1.0.tgz" : installs from a local file
|
||||||
|
|
||||||
|
"http://example.com/Package-1.0.tgz" : installs from
|
||||||
|
anywhere on the net.
|
||||||
|
|
||||||
|
"package.xml" : installs the package described in
|
||||||
|
package.xml. Useful for testing, or for wrapping a PEAR package in
|
||||||
|
another package manager such as RPM.
|
||||||
|
|
||||||
|
"Package[-version/state][.tar]" : queries your default channel's server
|
||||||
|
({config master_server}) and downloads the newest package with
|
||||||
|
the preferred quality/state ({config preferred_state}).
|
||||||
|
|
||||||
|
To retrieve Package version 1.1, use "Package-1.1," to retrieve
|
||||||
|
Package state beta, use "Package-beta." To retrieve an uncompressed
|
||||||
|
file, append .tar (make sure there is no file by the same name first)
|
||||||
|
|
||||||
|
To download a package from another channel, prefix with the channel name like
|
||||||
|
"channel/Package"
|
||||||
|
|
||||||
|
More than one package may be specified at once. It is ok to mix these
|
||||||
|
four ways of specifying packages.
|
||||||
|
</doc>
|
||||||
|
</install>
|
||||||
|
<upgrade>
|
||||||
|
<summary>Upgrade Package</summary>
|
||||||
|
<function>doInstall</function>
|
||||||
|
<shortcut>up</shortcut>
|
||||||
|
<options>
|
||||||
|
<channel>
|
||||||
|
<shortopt>c</shortopt>
|
||||||
|
<doc>upgrade packages from a specific channel</doc>
|
||||||
|
<arg>CHAN</arg>
|
||||||
|
</channel>
|
||||||
|
<force>
|
||||||
|
<shortopt>f</shortopt>
|
||||||
|
<doc>overwrite newer installed packages</doc>
|
||||||
|
</force>
|
||||||
|
<loose>
|
||||||
|
<shortopt>l</shortopt>
|
||||||
|
<doc>do not check for recommended dependency version</doc>
|
||||||
|
</loose>
|
||||||
|
<nodeps>
|
||||||
|
<shortopt>n</shortopt>
|
||||||
|
<doc>ignore dependencies, upgrade anyway</doc>
|
||||||
|
</nodeps>
|
||||||
|
<register-only>
|
||||||
|
<shortopt>r</shortopt>
|
||||||
|
<doc>do not install files, only register the package as upgraded</doc>
|
||||||
|
</register-only>
|
||||||
|
<nobuild>
|
||||||
|
<shortopt>B</shortopt>
|
||||||
|
<doc>don't build C extensions</doc>
|
||||||
|
</nobuild>
|
||||||
|
<nocompress>
|
||||||
|
<shortopt>Z</shortopt>
|
||||||
|
<doc>request uncompressed files when downloading</doc>
|
||||||
|
</nocompress>
|
||||||
|
<installroot>
|
||||||
|
<shortopt>R</shortopt>
|
||||||
|
<doc>root directory used when installing files (ala PHP's INSTALL_ROOT)</doc>
|
||||||
|
<arg>DIR</arg>
|
||||||
|
</installroot>
|
||||||
|
<ignore-errors>
|
||||||
|
<shortopt></shortopt>
|
||||||
|
<doc>force install even if there were errors</doc>
|
||||||
|
</ignore-errors>
|
||||||
|
<alldeps>
|
||||||
|
<shortopt>a</shortopt>
|
||||||
|
<doc>install all required and optional dependencies</doc>
|
||||||
|
</alldeps>
|
||||||
|
<onlyreqdeps>
|
||||||
|
<shortopt>o</shortopt>
|
||||||
|
<doc>install all required dependencies</doc>
|
||||||
|
</onlyreqdeps>
|
||||||
|
<offline>
|
||||||
|
<shortopt>O</shortopt>
|
||||||
|
<doc>do not attempt to download any urls or contact channels</doc>
|
||||||
|
</offline>
|
||||||
|
<pretend>
|
||||||
|
<shortopt>p</shortopt>
|
||||||
|
<doc>Only list the packages that would be downloaded</doc>
|
||||||
|
</pretend>
|
||||||
|
</options>
|
||||||
|
<doc><package> ...
|
||||||
|
Upgrades one or more PEAR packages. See documentation for the
|
||||||
|
"install" command for ways to specify a package.
|
||||||
|
|
||||||
|
When upgrading, your package will be updated if the provided new
|
||||||
|
package has a higher version number (use the -f option if you need to
|
||||||
|
upgrade anyway).
|
||||||
|
|
||||||
|
More than one package may be specified at once.
|
||||||
|
</doc>
|
||||||
|
</upgrade>
|
||||||
|
<upgrade-all>
|
||||||
|
<summary>Upgrade All Packages [Deprecated in favor of calling upgrade with no parameters]</summary>
|
||||||
|
<function>doUpgradeAll</function>
|
||||||
|
<shortcut>ua</shortcut>
|
||||||
|
<options>
|
||||||
|
<channel>
|
||||||
|
<shortopt>c</shortopt>
|
||||||
|
<doc>upgrade packages from a specific channel</doc>
|
||||||
|
<arg>CHAN</arg>
|
||||||
|
</channel>
|
||||||
|
<nodeps>
|
||||||
|
<shortopt>n</shortopt>
|
||||||
|
<doc>ignore dependencies, upgrade anyway</doc>
|
||||||
|
</nodeps>
|
||||||
|
<register-only>
|
||||||
|
<shortopt>r</shortopt>
|
||||||
|
<doc>do not install files, only register the package as upgraded</doc>
|
||||||
|
</register-only>
|
||||||
|
<nobuild>
|
||||||
|
<shortopt>B</shortopt>
|
||||||
|
<doc>don't build C extensions</doc>
|
||||||
|
</nobuild>
|
||||||
|
<nocompress>
|
||||||
|
<shortopt>Z</shortopt>
|
||||||
|
<doc>request uncompressed files when downloading</doc>
|
||||||
|
</nocompress>
|
||||||
|
<installroot>
|
||||||
|
<shortopt>R</shortopt>
|
||||||
|
<doc>root directory used when installing files (ala PHP's INSTALL_ROOT), use packagingroot for RPM</doc>
|
||||||
|
<arg>DIR</arg>
|
||||||
|
</installroot>
|
||||||
|
<ignore-errors>
|
||||||
|
<shortopt></shortopt>
|
||||||
|
<doc>force install even if there were errors</doc>
|
||||||
|
</ignore-errors>
|
||||||
|
<loose>
|
||||||
|
<shortopt></shortopt>
|
||||||
|
<doc>do not check for recommended dependency version</doc>
|
||||||
|
</loose>
|
||||||
|
</options>
|
||||||
|
<doc>
|
||||||
|
WARNING: This function is deprecated in favor of using the upgrade command with no params
|
||||||
|
|
||||||
|
Upgrades all packages that have a newer release available. Upgrades are
|
||||||
|
done only if there is a release available of the state specified in
|
||||||
|
"preferred_state" (currently {config preferred_state}), or a state considered
|
||||||
|
more stable.
|
||||||
|
</doc>
|
||||||
|
</upgrade-all>
|
||||||
|
<uninstall>
|
||||||
|
<summary>Un-install Package</summary>
|
||||||
|
<function>doUninstall</function>
|
||||||
|
<shortcut>un</shortcut>
|
||||||
|
<options>
|
||||||
|
<nodeps>
|
||||||
|
<shortopt>n</shortopt>
|
||||||
|
<doc>ignore dependencies, uninstall anyway</doc>
|
||||||
|
</nodeps>
|
||||||
|
<register-only>
|
||||||
|
<shortopt>r</shortopt>
|
||||||
|
<doc>do not remove files, only register the packages as not installed</doc>
|
||||||
|
</register-only>
|
||||||
|
<installroot>
|
||||||
|
<shortopt>R</shortopt>
|
||||||
|
<doc>root directory used when installing files (ala PHP's INSTALL_ROOT)</doc>
|
||||||
|
<arg>DIR</arg>
|
||||||
|
</installroot>
|
||||||
|
<ignore-errors>
|
||||||
|
<shortopt></shortopt>
|
||||||
|
<doc>force install even if there were errors</doc>
|
||||||
|
</ignore-errors>
|
||||||
|
<offline>
|
||||||
|
<shortopt>O</shortopt>
|
||||||
|
<doc>do not attempt to uninstall remotely</doc>
|
||||||
|
</offline>
|
||||||
|
</options>
|
||||||
|
<doc>[channel/]<package> ...
|
||||||
|
Uninstalls one or more PEAR packages. More than one package may be
|
||||||
|
specified at once. Prefix with channel name to uninstall from a
|
||||||
|
channel not in your default channel ({config default_channel})
|
||||||
|
</doc>
|
||||||
|
</uninstall>
|
||||||
|
<bundle>
|
||||||
|
<summary>Unpacks a Pecl Package</summary>
|
||||||
|
<function>doBundle</function>
|
||||||
|
<shortcut>bun</shortcut>
|
||||||
|
<options>
|
||||||
|
<destination>
|
||||||
|
<shortopt>d</shortopt>
|
||||||
|
<doc>Optional destination directory for unpacking (defaults to current path or "ext" if exists)</doc>
|
||||||
|
<arg>DIR</arg>
|
||||||
|
</destination>
|
||||||
|
<force>
|
||||||
|
<shortopt>f</shortopt>
|
||||||
|
<doc>Force the unpacking even if there were errors in the package</doc>
|
||||||
|
</force>
|
||||||
|
</options>
|
||||||
|
<doc><package>
|
||||||
|
Unpacks a Pecl Package into the selected location. It will download the
|
||||||
|
package if needed.
|
||||||
|
</doc>
|
||||||
|
</bundle>
|
||||||
|
<run-scripts>
|
||||||
|
<summary>Run Post-Install Scripts bundled with a package</summary>
|
||||||
|
<function>doRunScripts</function>
|
||||||
|
<shortcut>rs</shortcut>
|
||||||
|
<options />
|
||||||
|
<doc><package>
|
||||||
|
Run post-installation scripts in package <package>, if any exist.
|
||||||
|
</doc>
|
||||||
|
</run-scripts>
|
||||||
|
</commands>
|
|
@ -1,53 +1,58 @@
|
||||||
<?php
|
<?php
|
||||||
//
|
/**
|
||||||
// +----------------------------------------------------------------------+
|
* PEAR_Command_Mirror (download-all command)
|
||||||
// | PHP Version 5 |
|
*
|
||||||
// +----------------------------------------------------------------------+
|
* PHP versions 4 and 5
|
||||||
// | Copyright (c) 1997-2004 The PHP Group |
|
*
|
||||||
// +----------------------------------------------------------------------+
|
* @category pear
|
||||||
// | This source file is subject to version 3.0 of the PHP license, |
|
* @package PEAR
|
||||||
// | that is bundled with this package in the file LICENSE, and is |
|
* @author Alexander Merz <alexmerz@php.net>
|
||||||
// | available through the world-wide-web at the following url: |
|
* @copyright 1997-2009 The Authors
|
||||||
// | http://www.php.net/license/3_0.txt. |
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
// | If you did not receive a copy of the PHP license and are unable to |
|
* @version CVS: $Id: Mirror.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
// | obtain it through the world-wide-web, please send a note to |
|
* @link http://pear.php.net/package/PEAR
|
||||||
// | license@php.net so we can mail you a copy immediately. |
|
* @since File available since Release 1.2.0
|
||||||
// +----------------------------------------------------------------------+
|
*/
|
||||||
// | Author: Alexander Merz <alexmerz@php.net> |
|
|
||||||
// | |
|
|
||||||
// +----------------------------------------------------------------------+
|
|
||||||
//
|
|
||||||
// $Id: Mirror.php,v 1.5 2004/03/18 12:23:57 mj Exp $
|
|
||||||
|
|
||||||
require_once "PEAR/Command/Common.php";
|
/**
|
||||||
require_once "PEAR/Command.php";
|
* base class
|
||||||
require_once "PEAR/Remote.php";
|
*/
|
||||||
require_once "PEAR.php";
|
require_once 'PEAR/Command/Common.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PEAR commands for providing file mirrors
|
* PEAR commands for providing file mirrors
|
||||||
*
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Alexander Merz <alexmerz@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 1.2.0
|
||||||
*/
|
*/
|
||||||
class PEAR_Command_Mirror extends PEAR_Command_Common
|
class PEAR_Command_Mirror extends PEAR_Command_Common
|
||||||
{
|
{
|
||||||
// {{{ properties
|
|
||||||
|
|
||||||
var $commands = array(
|
var $commands = array(
|
||||||
'download-all' => array(
|
'download-all' => array(
|
||||||
'summary' => 'Downloads each available package from master_server',
|
'summary' => 'Downloads each available package from the default channel',
|
||||||
'function' => 'doDownloadAll',
|
'function' => 'doDownloadAll',
|
||||||
'shortcut' => 'da',
|
'shortcut' => 'da',
|
||||||
'options' => array(),
|
'options' => array(
|
||||||
|
'channel' =>
|
||||||
|
array(
|
||||||
|
'shortopt' => 'c',
|
||||||
|
'doc' => 'specify a channel other than the default channel',
|
||||||
|
'arg' => 'CHAN',
|
||||||
|
),
|
||||||
|
),
|
||||||
'doc' => '
|
'doc' => '
|
||||||
Requests a list of available packages from the package server
|
Requests a list of available packages from the default channel ({config default_channel})
|
||||||
(master_server) and downloads them to current working directory'
|
and downloads them to current working directory. Note: only
|
||||||
|
packages within preferred_state ({config preferred_state}) will be downloaded'
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
// }}}
|
|
||||||
|
|
||||||
// {{{ constructor
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PEAR_Command_Mirror constructor.
|
* PEAR_Command_Mirror constructor.
|
||||||
*
|
*
|
||||||
|
@ -60,9 +65,15 @@ class PEAR_Command_Mirror extends PEAR_Command_Common
|
||||||
parent::PEAR_Command_Common($ui, $config);
|
parent::PEAR_Command_Common($ui, $config);
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
/**
|
||||||
|
* For unit-testing
|
||||||
|
*/
|
||||||
|
function &factory($a)
|
||||||
|
{
|
||||||
|
$a = &PEAR_Command::factory($a, $this->config);
|
||||||
|
return $a;
|
||||||
|
}
|
||||||
|
|
||||||
// {{{ doDownloadAll()
|
|
||||||
/**
|
/**
|
||||||
* retrieves a list of avaible Packages from master server
|
* retrieves a list of avaible Packages from master server
|
||||||
* and downloads them
|
* and downloads them
|
||||||
|
@ -76,26 +87,53 @@ class PEAR_Command_Mirror extends PEAR_Command_Common
|
||||||
*/
|
*/
|
||||||
function doDownloadAll($command, $options, $params)
|
function doDownloadAll($command, $options, $params)
|
||||||
{
|
{
|
||||||
$this->config->set("php_dir", ".");
|
$savechannel = $this->config->get('default_channel');
|
||||||
$remote = &new PEAR_Remote($this->config);
|
$reg = &$this->config->getRegistry();
|
||||||
$remoteInfo = $remote->call("package.listAll");
|
$channel = isset($options['channel']) ? $options['channel'] :
|
||||||
|
$this->config->get('default_channel');
|
||||||
|
if (!$reg->channelExists($channel)) {
|
||||||
|
$this->config->set('default_channel', $savechannel);
|
||||||
|
return $this->raiseError('Channel "' . $channel . '" does not exist');
|
||||||
|
}
|
||||||
|
$this->config->set('default_channel', $channel);
|
||||||
|
|
||||||
|
$this->ui->outputData('Using Channel ' . $this->config->get('default_channel'));
|
||||||
|
$chan = $reg->getChannel($channel);
|
||||||
|
if (PEAR::isError($chan)) {
|
||||||
|
return $this->raiseError($chan);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
|
||||||
|
$base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
|
||||||
|
$rest = &$this->config->getREST('1.0', array());
|
||||||
|
$remoteInfo = array_flip($rest->listPackages($base, $channel));
|
||||||
|
}
|
||||||
|
|
||||||
if (PEAR::isError($remoteInfo)) {
|
if (PEAR::isError($remoteInfo)) {
|
||||||
return $remoteInfo;
|
return $remoteInfo;
|
||||||
}
|
}
|
||||||
$cmd = &PEAR_Command::factory("download", $this->config);
|
|
||||||
|
$cmd = &$this->factory("download");
|
||||||
if (PEAR::isError($cmd)) {
|
if (PEAR::isError($cmd)) {
|
||||||
return $cmd;
|
return $cmd;
|
||||||
}
|
}
|
||||||
foreach ($remoteInfo as $pkgn => $pkg) {
|
|
||||||
|
$this->ui->outputData('Using Preferred State of ' .
|
||||||
|
$this->config->get('preferred_state'));
|
||||||
|
$this->ui->outputData('Gathering release information, please wait...');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Error handling not neccesary, because already done by
|
* Error handling not necessary, because already done by
|
||||||
* the download command
|
* the download command
|
||||||
*/
|
*/
|
||||||
$cmd->run("download", array(), array($pkgn));
|
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
|
||||||
|
$err = $cmd->run('download', array('downloadonly' => true), array_keys($remoteInfo));
|
||||||
|
PEAR::staticPopErrorHandling();
|
||||||
|
$this->config->set('default_channel', $savechannel);
|
||||||
|
if (PEAR::isError($err)) {
|
||||||
|
$this->ui->outputData($err->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
}
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
<commands version="1.0">
|
||||||
|
<download-all>
|
||||||
|
<summary>Downloads each available package from the default channel</summary>
|
||||||
|
<function>doDownloadAll</function>
|
||||||
|
<shortcut>da</shortcut>
|
||||||
|
<options>
|
||||||
|
<channel>
|
||||||
|
<shortopt>c</shortopt>
|
||||||
|
<doc>specify a channel other than the default channel</doc>
|
||||||
|
<arg>CHAN</arg>
|
||||||
|
</channel>
|
||||||
|
</options>
|
||||||
|
<doc>
|
||||||
|
Requests a list of available packages from the default channel ({config default_channel})
|
||||||
|
and downloads them to current working directory. Note: only
|
||||||
|
packages within preferred_state ({config preferred_state}) will be downloaded</doc>
|
||||||
|
</download-all>
|
||||||
|
</commands>
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,237 @@
|
||||||
|
<commands version="1.0">
|
||||||
|
<package>
|
||||||
|
<summary>Build Package</summary>
|
||||||
|
<function>doPackage</function>
|
||||||
|
<shortcut>p</shortcut>
|
||||||
|
<options>
|
||||||
|
<nocompress>
|
||||||
|
<shortopt>Z</shortopt>
|
||||||
|
<doc>Do not gzip the package file</doc>
|
||||||
|
</nocompress>
|
||||||
|
<showname>
|
||||||
|
<shortopt>n</shortopt>
|
||||||
|
<doc>Print the name of the packaged file.</doc>
|
||||||
|
</showname>
|
||||||
|
</options>
|
||||||
|
<doc>[descfile] [descfile2]
|
||||||
|
Creates a PEAR package from its description file (usually called
|
||||||
|
package.xml). If a second packagefile is passed in, then
|
||||||
|
the packager will check to make sure that one is a package.xml
|
||||||
|
version 1.0, and the other is a package.xml version 2.0. The
|
||||||
|
package.xml version 1.0 will be saved as "package.xml" in the archive,
|
||||||
|
and the other as "package2.xml" in the archive"
|
||||||
|
</doc>
|
||||||
|
</package>
|
||||||
|
<package-validate>
|
||||||
|
<summary>Validate Package Consistency</summary>
|
||||||
|
<function>doPackageValidate</function>
|
||||||
|
<shortcut>pv</shortcut>
|
||||||
|
<options />
|
||||||
|
<doc>
|
||||||
|
</doc>
|
||||||
|
</package-validate>
|
||||||
|
<cvsdiff>
|
||||||
|
<summary>Run a "cvs diff" for all files in a package</summary>
|
||||||
|
<function>doCvsDiff</function>
|
||||||
|
<shortcut>cd</shortcut>
|
||||||
|
<options>
|
||||||
|
<quiet>
|
||||||
|
<shortopt>q</shortopt>
|
||||||
|
<doc>Be quiet</doc>
|
||||||
|
</quiet>
|
||||||
|
<reallyquiet>
|
||||||
|
<shortopt>Q</shortopt>
|
||||||
|
<doc>Be really quiet</doc>
|
||||||
|
</reallyquiet>
|
||||||
|
<date>
|
||||||
|
<shortopt>D</shortopt>
|
||||||
|
<doc>Diff against revision of DATE</doc>
|
||||||
|
<arg>DATE</arg>
|
||||||
|
</date>
|
||||||
|
<release>
|
||||||
|
<shortopt>R</shortopt>
|
||||||
|
<doc>Diff against tag for package release REL</doc>
|
||||||
|
<arg>REL</arg>
|
||||||
|
</release>
|
||||||
|
<revision>
|
||||||
|
<shortopt>r</shortopt>
|
||||||
|
<doc>Diff against revision REV</doc>
|
||||||
|
<arg>REV</arg>
|
||||||
|
</revision>
|
||||||
|
<context>
|
||||||
|
<shortopt>c</shortopt>
|
||||||
|
<doc>Generate context diff</doc>
|
||||||
|
</context>
|
||||||
|
<unified>
|
||||||
|
<shortopt>u</shortopt>
|
||||||
|
<doc>Generate unified diff</doc>
|
||||||
|
</unified>
|
||||||
|
<ignore-case>
|
||||||
|
<shortopt>i</shortopt>
|
||||||
|
<doc>Ignore case, consider upper- and lower-case letters equivalent</doc>
|
||||||
|
</ignore-case>
|
||||||
|
<ignore-whitespace>
|
||||||
|
<shortopt>b</shortopt>
|
||||||
|
<doc>Ignore changes in amount of white space</doc>
|
||||||
|
</ignore-whitespace>
|
||||||
|
<ignore-blank-lines>
|
||||||
|
<shortopt>B</shortopt>
|
||||||
|
<doc>Ignore changes that insert or delete blank lines</doc>
|
||||||
|
</ignore-blank-lines>
|
||||||
|
<brief>
|
||||||
|
<shortopt></shortopt>
|
||||||
|
<doc>Report only whether the files differ, no details</doc>
|
||||||
|
</brief>
|
||||||
|
<dry-run>
|
||||||
|
<shortopt>n</shortopt>
|
||||||
|
<doc>Don't do anything, just pretend</doc>
|
||||||
|
</dry-run>
|
||||||
|
</options>
|
||||||
|
<doc><package.xml>
|
||||||
|
Compares all the files in a package. Without any options, this
|
||||||
|
command will compare the current code with the last checked-in code.
|
||||||
|
Using the -r or -R option you may compare the current code with that
|
||||||
|
of a specific release.
|
||||||
|
</doc>
|
||||||
|
</cvsdiff>
|
||||||
|
<svntag>
|
||||||
|
<summary>Set SVN Release Tag</summary>
|
||||||
|
<function>doSvnTag</function>
|
||||||
|
<shortcut>sv</shortcut>
|
||||||
|
<options>
|
||||||
|
<quiet>
|
||||||
|
<shortopt>q</shortopt>
|
||||||
|
<doc>Be quiet</doc>
|
||||||
|
</quiet>
|
||||||
|
<slide>
|
||||||
|
<shortopt>F</shortopt>
|
||||||
|
<doc>Move (slide) tag if it exists</doc>
|
||||||
|
</slide>
|
||||||
|
<delete>
|
||||||
|
<shortopt>d</shortopt>
|
||||||
|
<doc>Remove tag</doc>
|
||||||
|
</delete>
|
||||||
|
<dry-run>
|
||||||
|
<shortopt>n</shortopt>
|
||||||
|
<doc>Don't do anything, just pretend</doc>
|
||||||
|
</dry-run>
|
||||||
|
</options>
|
||||||
|
<doc><package.xml> [files...]
|
||||||
|
Sets a SVN tag on all files in a package. Use this command after you have
|
||||||
|
packaged a distribution tarball with the "package" command to tag what
|
||||||
|
revisions of what files were in that release. If need to fix something
|
||||||
|
after running svntag once, but before the tarball is released to the public,
|
||||||
|
use the "slide" option to move the release tag.
|
||||||
|
|
||||||
|
to include files (such as a second package.xml, or tests not included in the
|
||||||
|
release), pass them as additional parameters.
|
||||||
|
</doc>
|
||||||
|
</svntag>
|
||||||
|
<cvstag>
|
||||||
|
<summary>Set CVS Release Tag</summary>
|
||||||
|
<function>doCvsTag</function>
|
||||||
|
<shortcut>ct</shortcut>
|
||||||
|
<options>
|
||||||
|
<quiet>
|
||||||
|
<shortopt>q</shortopt>
|
||||||
|
<doc>Be quiet</doc>
|
||||||
|
</quiet>
|
||||||
|
<reallyquiet>
|
||||||
|
<shortopt>Q</shortopt>
|
||||||
|
<doc>Be really quiet</doc>
|
||||||
|
</reallyquiet>
|
||||||
|
<slide>
|
||||||
|
<shortopt>F</shortopt>
|
||||||
|
<doc>Move (slide) tag if it exists</doc>
|
||||||
|
</slide>
|
||||||
|
<delete>
|
||||||
|
<shortopt>d</shortopt>
|
||||||
|
<doc>Remove tag</doc>
|
||||||
|
</delete>
|
||||||
|
<dry-run>
|
||||||
|
<shortopt>n</shortopt>
|
||||||
|
<doc>Don't do anything, just pretend</doc>
|
||||||
|
</dry-run>
|
||||||
|
</options>
|
||||||
|
<doc><package.xml> [files...]
|
||||||
|
Sets a CVS tag on all files in a package. Use this command after you have
|
||||||
|
packaged a distribution tarball with the "package" command to tag what
|
||||||
|
revisions of what files were in that release. If need to fix something
|
||||||
|
after running cvstag once, but before the tarball is released to the public,
|
||||||
|
use the "slide" option to move the release tag.
|
||||||
|
|
||||||
|
to include files (such as a second package.xml, or tests not included in the
|
||||||
|
release), pass them as additional parameters.
|
||||||
|
</doc>
|
||||||
|
</cvstag>
|
||||||
|
<package-dependencies>
|
||||||
|
<summary>Show package dependencies</summary>
|
||||||
|
<function>doPackageDependencies</function>
|
||||||
|
<shortcut>pd</shortcut>
|
||||||
|
<options />
|
||||||
|
<doc><package-file> or <package.xml> or <install-package-name>
|
||||||
|
List all dependencies the package has.
|
||||||
|
Can take a tgz / tar file, package.xml or a package name of an installed package.</doc>
|
||||||
|
</package-dependencies>
|
||||||
|
<sign>
|
||||||
|
<summary>Sign a package distribution file</summary>
|
||||||
|
<function>doSign</function>
|
||||||
|
<shortcut>si</shortcut>
|
||||||
|
<options>
|
||||||
|
<verbose>
|
||||||
|
<shortopt>v</shortopt>
|
||||||
|
<doc>Display GnuPG output</doc>
|
||||||
|
</verbose>
|
||||||
|
</options>
|
||||||
|
<doc><package-file>
|
||||||
|
Signs a package distribution (.tar or .tgz) file with GnuPG.</doc>
|
||||||
|
</sign>
|
||||||
|
<makerpm>
|
||||||
|
<summary>Builds an RPM spec file from a PEAR package</summary>
|
||||||
|
<function>doMakeRPM</function>
|
||||||
|
<shortcut>rpm</shortcut>
|
||||||
|
<options>
|
||||||
|
<spec-template>
|
||||||
|
<shortopt>t</shortopt>
|
||||||
|
<doc>Use FILE as RPM spec file template</doc>
|
||||||
|
<arg>FILE</arg>
|
||||||
|
</spec-template>
|
||||||
|
<rpm-pkgname>
|
||||||
|
<shortopt>p</shortopt>
|
||||||
|
<doc>Use FORMAT as format string for RPM package name, %s is replaced
|
||||||
|
by the PEAR package name, defaults to "PEAR::%s".</doc>
|
||||||
|
<arg>FORMAT</arg>
|
||||||
|
</rpm-pkgname>
|
||||||
|
</options>
|
||||||
|
<doc><package-file>
|
||||||
|
|
||||||
|
Creates an RPM .spec file for wrapping a PEAR package inside an RPM
|
||||||
|
package. Intended to be used from the SPECS directory, with the PEAR
|
||||||
|
package tarball in the SOURCES directory:
|
||||||
|
|
||||||
|
$ pear makerpm ../SOURCES/Net_Socket-1.0.tgz
|
||||||
|
Wrote RPM spec file PEAR::Net_Geo-1.0.spec
|
||||||
|
$ rpm -bb PEAR::Net_Socket-1.0.spec
|
||||||
|
...
|
||||||
|
Wrote: /usr/src/redhat/RPMS/i386/PEAR::Net_Socket-1.0-1.i386.rpm
|
||||||
|
</doc>
|
||||||
|
</makerpm>
|
||||||
|
<convert>
|
||||||
|
<summary>Convert a package.xml 1.0 to package.xml 2.0 format</summary>
|
||||||
|
<function>doConvert</function>
|
||||||
|
<shortcut>c2</shortcut>
|
||||||
|
<options>
|
||||||
|
<flat>
|
||||||
|
<shortopt>f</shortopt>
|
||||||
|
<doc>do not beautify the filelist.</doc>
|
||||||
|
</flat>
|
||||||
|
</options>
|
||||||
|
<doc>[descfile] [descfile2]
|
||||||
|
Converts a package.xml in 1.0 format into a package.xml
|
||||||
|
in 2.0 format. The new file will be named package2.xml by default,
|
||||||
|
and package.xml will be used as the old file by default.
|
||||||
|
This is not the most intelligent conversion, and should only be
|
||||||
|
used for automated conversion or learning the format.
|
||||||
|
</doc>
|
||||||
|
</convert>
|
||||||
|
</commands>
|
|
@ -0,0 +1,421 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PEAR_Command_Pickle (pickle command)
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 2005-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: Pickle.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since Release 1.4.1
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* base class
|
||||||
|
*/
|
||||||
|
require_once 'PEAR/Command/Common.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PEAR commands for login/logout
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 2005-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 1.4.1
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PEAR_Command_Pickle extends PEAR_Command_Common
|
||||||
|
{
|
||||||
|
var $commands = array(
|
||||||
|
'pickle' => array(
|
||||||
|
'summary' => 'Build PECL Package',
|
||||||
|
'function' => 'doPackage',
|
||||||
|
'shortcut' => 'pi',
|
||||||
|
'options' => array(
|
||||||
|
'nocompress' => array(
|
||||||
|
'shortopt' => 'Z',
|
||||||
|
'doc' => 'Do not gzip the package file'
|
||||||
|
),
|
||||||
|
'showname' => array(
|
||||||
|
'shortopt' => 'n',
|
||||||
|
'doc' => 'Print the name of the packaged file.',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'doc' => '[descfile]
|
||||||
|
Creates a PECL package from its package2.xml file.
|
||||||
|
|
||||||
|
An automatic conversion will be made to a package.xml 1.0 and written out to
|
||||||
|
disk in the current directory as "package.xml". Note that
|
||||||
|
only simple package.xml 2.0 will be converted. package.xml 2.0 with:
|
||||||
|
|
||||||
|
- dependency types other than required/optional PECL package/ext/php/pearinstaller
|
||||||
|
- more than one extsrcrelease or zendextsrcrelease
|
||||||
|
- zendextbinrelease, extbinrelease, phprelease, or bundle release type
|
||||||
|
- dependency groups
|
||||||
|
- ignore tags in release filelist
|
||||||
|
- tasks other than replace
|
||||||
|
- custom roles
|
||||||
|
|
||||||
|
will cause pickle to fail, and output an error message. If your package2.xml
|
||||||
|
uses any of these features, you are best off using PEAR_PackageFileManager to
|
||||||
|
generate both package.xml.
|
||||||
|
'
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PEAR_Command_Package constructor.
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function PEAR_Command_Pickle(&$ui, &$config)
|
||||||
|
{
|
||||||
|
parent::PEAR_Command_Common($ui, $config);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For unit-testing ease
|
||||||
|
*
|
||||||
|
* @return PEAR_Packager
|
||||||
|
*/
|
||||||
|
function &getPackager()
|
||||||
|
{
|
||||||
|
if (!class_exists('PEAR_Packager')) {
|
||||||
|
require_once 'PEAR/Packager.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
$a = &new PEAR_Packager;
|
||||||
|
return $a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For unit-testing ease
|
||||||
|
*
|
||||||
|
* @param PEAR_Config $config
|
||||||
|
* @param bool $debug
|
||||||
|
* @param string|null $tmpdir
|
||||||
|
* @return PEAR_PackageFile
|
||||||
|
*/
|
||||||
|
function &getPackageFile($config, $debug = false)
|
||||||
|
{
|
||||||
|
if (!class_exists('PEAR_Common')) {
|
||||||
|
require_once 'PEAR/Common.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!class_exists('PEAR_PackageFile')) {
|
||||||
|
require_once 'PEAR/PackageFile.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
$a = &new PEAR_PackageFile($config, $debug);
|
||||||
|
$common = new PEAR_Common;
|
||||||
|
$common->ui = $this->ui;
|
||||||
|
$a->setLogger($common);
|
||||||
|
return $a;
|
||||||
|
}
|
||||||
|
|
||||||
|
function doPackage($command, $options, $params)
|
||||||
|
{
|
||||||
|
$this->output = '';
|
||||||
|
$pkginfofile = isset($params[0]) ? $params[0] : 'package2.xml';
|
||||||
|
$packager = &$this->getPackager();
|
||||||
|
if (PEAR::isError($err = $this->_convertPackage($pkginfofile))) {
|
||||||
|
return $err;
|
||||||
|
}
|
||||||
|
|
||||||
|
$compress = empty($options['nocompress']) ? true : false;
|
||||||
|
$result = $packager->package($pkginfofile, $compress, 'package.xml');
|
||||||
|
if (PEAR::isError($result)) {
|
||||||
|
return $this->raiseError($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't want output, only the package file name just created
|
||||||
|
if (isset($options['showname'])) {
|
||||||
|
$this->ui->outputData($result, $command);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _convertPackage($packagexml)
|
||||||
|
{
|
||||||
|
$pkg = &$this->getPackageFile($this->config);
|
||||||
|
$pf2 = &$pkg->fromPackageFile($packagexml, PEAR_VALIDATE_NORMAL);
|
||||||
|
if (!is_a($pf2, 'PEAR_PackageFile_v2')) {
|
||||||
|
return $this->raiseError('Cannot process "' .
|
||||||
|
$packagexml . '", is not a package.xml 2.0');
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once 'PEAR/PackageFile/v1.php';
|
||||||
|
$pf = new PEAR_PackageFile_v1;
|
||||||
|
$pf->setConfig($this->config);
|
||||||
|
if ($pf2->getPackageType() != 'extsrc' && $pf2->getPackageType() != 'zendextsrc') {
|
||||||
|
return $this->raiseError('Cannot safely convert "' . $packagexml .
|
||||||
|
'", is not an extension source package. Using a PEAR_PackageFileManager-based ' .
|
||||||
|
'script is an option');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_array($pf2->getUsesRole())) {
|
||||||
|
return $this->raiseError('Cannot safely convert "' . $packagexml .
|
||||||
|
'", contains custom roles. Using a PEAR_PackageFileManager-based script or ' .
|
||||||
|
'the convert command is an option');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_array($pf2->getUsesTask())) {
|
||||||
|
return $this->raiseError('Cannot safely convert "' . $packagexml .
|
||||||
|
'", contains custom tasks. Using a PEAR_PackageFileManager-based script or ' .
|
||||||
|
'the convert command is an option');
|
||||||
|
}
|
||||||
|
|
||||||
|
$deps = $pf2->getDependencies();
|
||||||
|
if (isset($deps['group'])) {
|
||||||
|
return $this->raiseError('Cannot safely convert "' . $packagexml .
|
||||||
|
'", contains dependency groups. Using a PEAR_PackageFileManager-based script ' .
|
||||||
|
'or the convert command is an option');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($deps['required']['subpackage']) ||
|
||||||
|
isset($deps['optional']['subpackage'])) {
|
||||||
|
return $this->raiseError('Cannot safely convert "' . $packagexml .
|
||||||
|
'", contains subpackage dependencies. Using a PEAR_PackageFileManager-based '.
|
||||||
|
'script is an option');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($deps['required']['os'])) {
|
||||||
|
return $this->raiseError('Cannot safely convert "' . $packagexml .
|
||||||
|
'", contains os dependencies. Using a PEAR_PackageFileManager-based '.
|
||||||
|
'script is an option');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($deps['required']['arch'])) {
|
||||||
|
return $this->raiseError('Cannot safely convert "' . $packagexml .
|
||||||
|
'", contains arch dependencies. Using a PEAR_PackageFileManager-based '.
|
||||||
|
'script is an option');
|
||||||
|
}
|
||||||
|
|
||||||
|
$pf->setPackage($pf2->getPackage());
|
||||||
|
$pf->setSummary($pf2->getSummary());
|
||||||
|
$pf->setDescription($pf2->getDescription());
|
||||||
|
foreach ($pf2->getMaintainers() as $maintainer) {
|
||||||
|
$pf->addMaintainer($maintainer['role'], $maintainer['handle'],
|
||||||
|
$maintainer['name'], $maintainer['email']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$pf->setVersion($pf2->getVersion());
|
||||||
|
$pf->setDate($pf2->getDate());
|
||||||
|
$pf->setLicense($pf2->getLicense());
|
||||||
|
$pf->setState($pf2->getState());
|
||||||
|
$pf->setNotes($pf2->getNotes());
|
||||||
|
$pf->addPhpDep($deps['required']['php']['min'], 'ge');
|
||||||
|
if (isset($deps['required']['php']['max'])) {
|
||||||
|
$pf->addPhpDep($deps['required']['php']['max'], 'le');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($deps['required']['package'])) {
|
||||||
|
if (!isset($deps['required']['package'][0])) {
|
||||||
|
$deps['required']['package'] = array($deps['required']['package']);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($deps['required']['package'] as $dep) {
|
||||||
|
if (!isset($dep['channel'])) {
|
||||||
|
return $this->raiseError('Cannot safely convert "' . $packagexml . '"' .
|
||||||
|
' contains uri-based dependency on a package. Using a ' .
|
||||||
|
'PEAR_PackageFileManager-based script is an option');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($dep['channel'] != 'pear.php.net'
|
||||||
|
&& $dep['channel'] != 'pecl.php.net'
|
||||||
|
&& $dep['channel'] != 'doc.php.net') {
|
||||||
|
return $this->raiseError('Cannot safely convert "' . $packagexml . '"' .
|
||||||
|
' contains dependency on a non-standard channel package. Using a ' .
|
||||||
|
'PEAR_PackageFileManager-based script is an option');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($dep['conflicts'])) {
|
||||||
|
return $this->raiseError('Cannot safely convert "' . $packagexml . '"' .
|
||||||
|
' contains conflicts dependency. Using a ' .
|
||||||
|
'PEAR_PackageFileManager-based script is an option');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($dep['exclude'])) {
|
||||||
|
$this->ui->outputData('WARNING: exclude tags are ignored in conversion');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($dep['min'])) {
|
||||||
|
$pf->addPackageDep($dep['name'], $dep['min'], 'ge');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($dep['max'])) {
|
||||||
|
$pf->addPackageDep($dep['name'], $dep['max'], 'le');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($deps['required']['extension'])) {
|
||||||
|
if (!isset($deps['required']['extension'][0])) {
|
||||||
|
$deps['required']['extension'] = array($deps['required']['extension']);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($deps['required']['extension'] as $dep) {
|
||||||
|
if (isset($dep['conflicts'])) {
|
||||||
|
return $this->raiseError('Cannot safely convert "' . $packagexml . '"' .
|
||||||
|
' contains conflicts dependency. Using a ' .
|
||||||
|
'PEAR_PackageFileManager-based script is an option');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($dep['exclude'])) {
|
||||||
|
$this->ui->outputData('WARNING: exclude tags are ignored in conversion');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($dep['min'])) {
|
||||||
|
$pf->addExtensionDep($dep['name'], $dep['min'], 'ge');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($dep['max'])) {
|
||||||
|
$pf->addExtensionDep($dep['name'], $dep['max'], 'le');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($deps['optional']['package'])) {
|
||||||
|
if (!isset($deps['optional']['package'][0])) {
|
||||||
|
$deps['optional']['package'] = array($deps['optional']['package']);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($deps['optional']['package'] as $dep) {
|
||||||
|
if (!isset($dep['channel'])) {
|
||||||
|
return $this->raiseError('Cannot safely convert "' . $packagexml . '"' .
|
||||||
|
' contains uri-based dependency on a package. Using a ' .
|
||||||
|
'PEAR_PackageFileManager-based script is an option');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($dep['channel'] != 'pear.php.net'
|
||||||
|
&& $dep['channel'] != 'pecl.php.net'
|
||||||
|
&& $dep['channel'] != 'doc.php.net') {
|
||||||
|
return $this->raiseError('Cannot safely convert "' . $packagexml . '"' .
|
||||||
|
' contains dependency on a non-standard channel package. Using a ' .
|
||||||
|
'PEAR_PackageFileManager-based script is an option');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($dep['exclude'])) {
|
||||||
|
$this->ui->outputData('WARNING: exclude tags are ignored in conversion');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($dep['min'])) {
|
||||||
|
$pf->addPackageDep($dep['name'], $dep['min'], 'ge', 'yes');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($dep['max'])) {
|
||||||
|
$pf->addPackageDep($dep['name'], $dep['max'], 'le', 'yes');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($deps['optional']['extension'])) {
|
||||||
|
if (!isset($deps['optional']['extension'][0])) {
|
||||||
|
$deps['optional']['extension'] = array($deps['optional']['extension']);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($deps['optional']['extension'] as $dep) {
|
||||||
|
if (isset($dep['exclude'])) {
|
||||||
|
$this->ui->outputData('WARNING: exclude tags are ignored in conversion');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($dep['min'])) {
|
||||||
|
$pf->addExtensionDep($dep['name'], $dep['min'], 'ge', 'yes');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($dep['max'])) {
|
||||||
|
$pf->addExtensionDep($dep['name'], $dep['max'], 'le', 'yes');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$contents = $pf2->getContents();
|
||||||
|
$release = $pf2->getReleases();
|
||||||
|
if (isset($releases[0])) {
|
||||||
|
return $this->raiseError('Cannot safely process "' . $packagexml . '" contains '
|
||||||
|
. 'multiple extsrcrelease/zendextsrcrelease tags. Using a PEAR_PackageFileManager-based script ' .
|
||||||
|
'or the convert command is an option');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($configoptions = $pf2->getConfigureOptions()) {
|
||||||
|
foreach ($configoptions as $option) {
|
||||||
|
$default = isset($option['default']) ? $option['default'] : false;
|
||||||
|
$pf->addConfigureOption($option['name'], $option['prompt'], $default);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($release['filelist']['ignore'])) {
|
||||||
|
return $this->raiseError('Cannot safely process "' . $packagexml . '" contains '
|
||||||
|
. 'ignore tags. Using a PEAR_PackageFileManager-based script or the convert' .
|
||||||
|
' command is an option');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($release['filelist']['install']) &&
|
||||||
|
!isset($release['filelist']['install'][0])) {
|
||||||
|
$release['filelist']['install'] = array($release['filelist']['install']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($contents['dir']['attribs']['baseinstalldir'])) {
|
||||||
|
$baseinstalldir = $contents['dir']['attribs']['baseinstalldir'];
|
||||||
|
} else {
|
||||||
|
$baseinstalldir = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($contents['dir']['file'][0])) {
|
||||||
|
$contents['dir']['file'] = array($contents['dir']['file']);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($contents['dir']['file'] as $file) {
|
||||||
|
if ($baseinstalldir && !isset($file['attribs']['baseinstalldir'])) {
|
||||||
|
$file['attribs']['baseinstalldir'] = $baseinstalldir;
|
||||||
|
}
|
||||||
|
|
||||||
|
$processFile = $file;
|
||||||
|
unset($processFile['attribs']);
|
||||||
|
if (count($processFile)) {
|
||||||
|
foreach ($processFile as $name => $task) {
|
||||||
|
if ($name != $pf2->getTasksNs() . ':replace') {
|
||||||
|
return $this->raiseError('Cannot safely process "' . $packagexml .
|
||||||
|
'" contains tasks other than replace. Using a ' .
|
||||||
|
'PEAR_PackageFileManager-based script is an option.');
|
||||||
|
}
|
||||||
|
$file['attribs']['replace'][] = $task;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in_array($file['attribs']['role'], PEAR_Common::getFileRoles())) {
|
||||||
|
return $this->raiseError('Cannot safely convert "' . $packagexml .
|
||||||
|
'", contains custom roles. Using a PEAR_PackageFileManager-based script ' .
|
||||||
|
'or the convert command is an option');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($release['filelist']['install'])) {
|
||||||
|
foreach ($release['filelist']['install'] as $installas) {
|
||||||
|
if ($installas['attribs']['name'] == $file['attribs']['name']) {
|
||||||
|
$file['attribs']['install-as'] = $installas['attribs']['as'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$pf->addFile('/', $file['attribs']['name'], $file['attribs']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($pf2->getChangeLog()) {
|
||||||
|
$this->ui->outputData('WARNING: changelog is not translated to package.xml ' .
|
||||||
|
'1.0, use PEAR_PackageFileManager-based script if you need changelog-' .
|
||||||
|
'translation for package.xml 1.0');
|
||||||
|
}
|
||||||
|
|
||||||
|
$gen = &$pf->getDefaultGenerator();
|
||||||
|
$gen->toPackageFile('.');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
<commands version="1.0">
|
||||||
|
<pickle>
|
||||||
|
<summary>Build PECL Package</summary>
|
||||||
|
<function>doPackage</function>
|
||||||
|
<shortcut>pi</shortcut>
|
||||||
|
<options>
|
||||||
|
<nocompress>
|
||||||
|
<shortopt>Z</shortopt>
|
||||||
|
<doc>Do not gzip the package file</doc>
|
||||||
|
</nocompress>
|
||||||
|
<showname>
|
||||||
|
<shortopt>n</shortopt>
|
||||||
|
<doc>Print the name of the packaged file.</doc>
|
||||||
|
</showname>
|
||||||
|
</options>
|
||||||
|
<doc>[descfile]
|
||||||
|
Creates a PECL package from its package2.xml file.
|
||||||
|
|
||||||
|
An automatic conversion will be made to a package.xml 1.0 and written out to
|
||||||
|
disk in the current directory as "package.xml". Note that
|
||||||
|
only simple package.xml 2.0 will be converted. package.xml 2.0 with:
|
||||||
|
|
||||||
|
- dependency types other than required/optional PECL package/ext/php/pearinstaller
|
||||||
|
- more than one extsrcrelease or zendextsrcrelease
|
||||||
|
- zendextbinrelease, extbinrelease, phprelease, or bundle release type
|
||||||
|
- dependency groups
|
||||||
|
- ignore tags in release filelist
|
||||||
|
- tasks other than replace
|
||||||
|
- custom roles
|
||||||
|
|
||||||
|
will cause pickle to fail, and output an error message. If your package2.xml
|
||||||
|
uses any of these features, you are best off using PEAR_PackageFileManager to
|
||||||
|
generate both package.xml.
|
||||||
|
</doc>
|
||||||
|
</pickle>
|
||||||
|
</commands>
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,58 @@
|
||||||
|
<commands version="1.0">
|
||||||
|
<list>
|
||||||
|
<summary>List Installed Packages In The Default Channel</summary>
|
||||||
|
<function>doList</function>
|
||||||
|
<shortcut>l</shortcut>
|
||||||
|
<options>
|
||||||
|
<channel>
|
||||||
|
<shortopt>c</shortopt>
|
||||||
|
<doc>list installed packages from this channel</doc>
|
||||||
|
<arg>CHAN</arg>
|
||||||
|
</channel>
|
||||||
|
<allchannels>
|
||||||
|
<shortopt>a</shortopt>
|
||||||
|
<doc>list installed packages from all channels</doc>
|
||||||
|
</allchannels>
|
||||||
|
<channelinfo>
|
||||||
|
<shortopt>i</shortopt>
|
||||||
|
<doc>output fully channel-aware data, even on failure</doc>
|
||||||
|
</channelinfo>
|
||||||
|
</options>
|
||||||
|
<doc><package>
|
||||||
|
If invoked without parameters, this command lists the PEAR packages
|
||||||
|
installed in your php_dir ({config php_dir}). With a parameter, it
|
||||||
|
lists the files in a package.
|
||||||
|
</doc>
|
||||||
|
</list>
|
||||||
|
<list-files>
|
||||||
|
<summary>List Files In Installed Package</summary>
|
||||||
|
<function>doFileList</function>
|
||||||
|
<shortcut>fl</shortcut>
|
||||||
|
<options />
|
||||||
|
<doc><package>
|
||||||
|
List the files in an installed package.
|
||||||
|
</doc>
|
||||||
|
</list-files>
|
||||||
|
<shell-test>
|
||||||
|
<summary>Shell Script Test</summary>
|
||||||
|
<function>doShellTest</function>
|
||||||
|
<shortcut>st</shortcut>
|
||||||
|
<options />
|
||||||
|
<doc><package> [[relation] version]
|
||||||
|
Tests if a package is installed in the system. Will exit(1) if it is not.
|
||||||
|
<relation> The version comparison operator. One of:
|
||||||
|
<, lt, <=, le, >, gt, >=, ge, ==, =, eq, !=, <>, ne
|
||||||
|
<version> The version to compare with
|
||||||
|
</doc>
|
||||||
|
</shell-test>
|
||||||
|
<info>
|
||||||
|
<summary>Display information about a package</summary>
|
||||||
|
<function>doInfo</function>
|
||||||
|
<shortcut>in</shortcut>
|
||||||
|
<options />
|
||||||
|
<doc><package>
|
||||||
|
Displays information about a package. The package argument may be a
|
||||||
|
local package file, an URL to a package file, or the name of an
|
||||||
|
installed package.</doc>
|
||||||
|
</info>
|
||||||
|
</commands>
|
|
@ -1,33 +1,42 @@
|
||||||
<?php
|
<?php
|
||||||
// /* vim: set expandtab tabstop=4 shiftwidth=4: */
|
/**
|
||||||
// +----------------------------------------------------------------------+
|
* PEAR_Command_Remote (remote-info, list-upgrades, remote-list, search, list-all, download,
|
||||||
// | PHP Version 5 |
|
* clear-cache commands)
|
||||||
// +----------------------------------------------------------------------+
|
*
|
||||||
// | Copyright (c) 1997-2004 The PHP Group |
|
* PHP versions 4 and 5
|
||||||
// +----------------------------------------------------------------------+
|
*
|
||||||
// | This source file is subject to version 3.0 of the PHP license, |
|
* @category pear
|
||||||
// | that is bundled with this package in the file LICENSE, and is |
|
* @package PEAR
|
||||||
// | available through the world-wide-web at the following url: |
|
* @author Stig Bakken <ssb@php.net>
|
||||||
// | http://www.php.net/license/3_0.txt. |
|
* @author Greg Beaver <cellog@php.net>
|
||||||
// | If you did not receive a copy of the PHP license and are unable to |
|
* @copyright 1997-2009 The Authors
|
||||||
// | obtain it through the world-wide-web, please send a note to |
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
// | license@php.net so we can mail you a copy immediately. |
|
* @version CVS: $Id: Remote.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
// +----------------------------------------------------------------------+
|
* @link http://pear.php.net/package/PEAR
|
||||||
// | Author: Stig Bakken <ssb@php.net> |
|
* @since File available since Release 0.1
|
||||||
// | |
|
*/
|
||||||
// +----------------------------------------------------------------------+
|
|
||||||
//
|
|
||||||
// $Id: Remote.php,v 1.39 2004/04/03 15:56:00 cellog Exp $
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* base class
|
||||||
|
*/
|
||||||
require_once 'PEAR/Command/Common.php';
|
require_once 'PEAR/Command/Common.php';
|
||||||
require_once 'PEAR/Common.php';
|
require_once 'PEAR/REST.php';
|
||||||
require_once 'PEAR/Remote.php';
|
|
||||||
require_once 'PEAR/Registry.php';
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PEAR commands for remote server querying
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Stig Bakken <ssb@php.net>
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 0.1
|
||||||
|
*/
|
||||||
class PEAR_Command_Remote extends PEAR_Command_Common
|
class PEAR_Command_Remote extends PEAR_Command_Common
|
||||||
{
|
{
|
||||||
// {{{ command definitions
|
|
||||||
|
|
||||||
var $commands = array(
|
var $commands = array(
|
||||||
'remote-info' => array(
|
'remote-info' => array(
|
||||||
'summary' => 'Information About Remote Packages',
|
'summary' => 'Information About Remote Packages',
|
||||||
|
@ -41,16 +50,29 @@ Get details on a package from the server.',
|
||||||
'summary' => 'List Available Upgrades',
|
'summary' => 'List Available Upgrades',
|
||||||
'function' => 'doListUpgrades',
|
'function' => 'doListUpgrades',
|
||||||
'shortcut' => 'lu',
|
'shortcut' => 'lu',
|
||||||
'options' => array(),
|
'options' => array(
|
||||||
'doc' => '
|
'channelinfo' => array(
|
||||||
|
'shortopt' => 'i',
|
||||||
|
'doc' => 'output fully channel-aware data, even on failure',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'doc' => '[preferred_state]
|
||||||
List releases on the server of packages you have installed where
|
List releases on the server of packages you have installed where
|
||||||
a newer version is available with the same release state (stable etc.).'
|
a newer version is available with the same release state (stable etc.)
|
||||||
|
or the state passed as the second parameter.'
|
||||||
),
|
),
|
||||||
'remote-list' => array(
|
'remote-list' => array(
|
||||||
'summary' => 'List Remote Packages',
|
'summary' => 'List Remote Packages',
|
||||||
'function' => 'doRemoteList',
|
'function' => 'doRemoteList',
|
||||||
'shortcut' => 'rl',
|
'shortcut' => 'rl',
|
||||||
'options' => array(),
|
'options' => array(
|
||||||
|
'channel' =>
|
||||||
|
array(
|
||||||
|
'shortopt' => 'c',
|
||||||
|
'doc' => 'specify a channel other than the default channel',
|
||||||
|
'arg' => 'CHAN',
|
||||||
|
)
|
||||||
|
),
|
||||||
'doc' => '
|
'doc' => '
|
||||||
Lists the packages available on the configured server along with the
|
Lists the packages available on the configured server along with the
|
||||||
latest stable release of each package.',
|
latest stable release of each package.',
|
||||||
|
@ -59,16 +81,44 @@ latest stable release of each package.',
|
||||||
'summary' => 'Search remote package database',
|
'summary' => 'Search remote package database',
|
||||||
'function' => 'doSearch',
|
'function' => 'doSearch',
|
||||||
'shortcut' => 'sp',
|
'shortcut' => 'sp',
|
||||||
'options' => array(),
|
'options' => array(
|
||||||
'doc' => '
|
'channel' =>
|
||||||
Lists all packages which match the search parameters (first param
|
array(
|
||||||
is package name, second package info)',
|
'shortopt' => 'c',
|
||||||
|
'doc' => 'specify a channel other than the default channel',
|
||||||
|
'arg' => 'CHAN',
|
||||||
|
),
|
||||||
|
'allchannels' => array(
|
||||||
|
'shortopt' => 'a',
|
||||||
|
'doc' => 'search packages from all known channels',
|
||||||
|
),
|
||||||
|
'channelinfo' => array(
|
||||||
|
'shortopt' => 'i',
|
||||||
|
'doc' => 'output fully channel-aware data, even on failure',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'doc' => '[packagename] [packageinfo]
|
||||||
|
Lists all packages which match the search parameters. The first
|
||||||
|
parameter is a fragment of a packagename. The default channel
|
||||||
|
will be used unless explicitly overridden. The second parameter
|
||||||
|
will be used to match any portion of the summary/description',
|
||||||
),
|
),
|
||||||
'list-all' => array(
|
'list-all' => array(
|
||||||
'summary' => 'List All Packages',
|
'summary' => 'List All Packages',
|
||||||
'function' => 'doListAll',
|
'function' => 'doListAll',
|
||||||
'shortcut' => 'la',
|
'shortcut' => 'la',
|
||||||
'options' => array(),
|
'options' => array(
|
||||||
|
'channel' =>
|
||||||
|
array(
|
||||||
|
'shortopt' => 'c',
|
||||||
|
'doc' => 'specify a channel other than the default channel',
|
||||||
|
'arg' => 'CHAN',
|
||||||
|
),
|
||||||
|
'channelinfo' => array(
|
||||||
|
'shortopt' => 'i',
|
||||||
|
'doc' => 'output fully channel-aware data, even on failure',
|
||||||
|
),
|
||||||
|
),
|
||||||
'doc' => '
|
'doc' => '
|
||||||
Lists the packages available on the configured server along with the
|
Lists the packages available on the configured server along with the
|
||||||
latest stable release of each package.',
|
latest stable release of each package.',
|
||||||
|
@ -83,26 +133,23 @@ latest stable release of each package.',
|
||||||
'doc' => 'download an uncompressed (.tar) file',
|
'doc' => 'download an uncompressed (.tar) file',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
'doc' => '{package|package-version}
|
'doc' => '<package>...
|
||||||
Download a package tarball. The file will be named as suggested by the
|
Download package tarballs. The files will be named as suggested by the
|
||||||
server, for example if you download the DB package and the latest stable
|
server, for example if you download the DB package and the latest stable
|
||||||
version of DB is 1.2, the downloaded file will be DB-1.2.tgz.',
|
version of DB is 1.6.5, the downloaded file will be DB-1.6.5.tgz.',
|
||||||
),
|
),
|
||||||
'clear-cache' => array(
|
'clear-cache' => array(
|
||||||
'summary' => 'Clear XML-RPC Cache',
|
'summary' => 'Clear Web Services Cache',
|
||||||
'function' => 'doClearCache',
|
'function' => 'doClearCache',
|
||||||
'shortcut' => 'cc',
|
'shortcut' => 'cc',
|
||||||
'options' => array(),
|
'options' => array(),
|
||||||
'doc' => '
|
'doc' => '
|
||||||
Clear the XML-RPC cache. See also the cache_ttl configuration
|
Clear the REST cache. See also the cache_ttl configuration
|
||||||
parameter.
|
parameter.
|
||||||
',
|
',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ constructor
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PEAR_Command_Remote constructor.
|
* PEAR_Command_Remote constructor.
|
||||||
*
|
*
|
||||||
|
@ -113,98 +160,216 @@ parameter.
|
||||||
parent::PEAR_Command_Common($ui, $config);
|
parent::PEAR_Command_Common($ui, $config);
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
function _checkChannelForStatus($channel, $chan)
|
||||||
|
{
|
||||||
// {{{ doRemoteInfo()
|
if (PEAR::isError($chan)) {
|
||||||
|
$this->raiseError($chan);
|
||||||
|
}
|
||||||
|
if (!is_a($chan, 'PEAR_ChannelFile')) {
|
||||||
|
return $this->raiseError('Internal corruption error: invalid channel "' .
|
||||||
|
$channel . '"');
|
||||||
|
}
|
||||||
|
$rest = new PEAR_REST($this->config);
|
||||||
|
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
|
||||||
|
$mirror = $this->config->get('preferred_mirror', null,
|
||||||
|
$channel);
|
||||||
|
$a = $rest->downloadHttp('http://' . $channel .
|
||||||
|
'/channel.xml', $chan->lastModified());
|
||||||
|
PEAR::staticPopErrorHandling();
|
||||||
|
if (!PEAR::isError($a) && $a) {
|
||||||
|
$this->ui->outputData('WARNING: channel "' . $channel . '" has ' .
|
||||||
|
'updated its protocols, use "' . PEAR_RUNTYPE . ' channel-update ' . $channel .
|
||||||
|
'" to update');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function doRemoteInfo($command, $options, $params)
|
function doRemoteInfo($command, $options, $params)
|
||||||
{
|
{
|
||||||
if (sizeof($params) != 1) {
|
if (sizeof($params) != 1) {
|
||||||
return $this->raiseError("$command expects one param: the remote package name");
|
return $this->raiseError("$command expects one param: the remote package name");
|
||||||
}
|
}
|
||||||
$r = new PEAR_Remote($this->config);
|
$savechannel = $channel = $this->config->get('default_channel');
|
||||||
$info = $r->call('package.info', $params[0]);
|
$reg = &$this->config->getRegistry();
|
||||||
|
$package = $params[0];
|
||||||
|
$parsed = $reg->parsePackageName($package, $channel);
|
||||||
|
if (PEAR::isError($parsed)) {
|
||||||
|
return $this->raiseError('Invalid package name "' . $package . '"');
|
||||||
|
}
|
||||||
|
|
||||||
|
$channel = $parsed['channel'];
|
||||||
|
$this->config->set('default_channel', $channel);
|
||||||
|
$chan = $reg->getChannel($channel);
|
||||||
|
if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
|
||||||
|
return $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
$mirror = $this->config->get('preferred_mirror');
|
||||||
|
if ($chan->supportsREST($mirror) && $base = $chan->getBaseURL('REST1.0', $mirror)) {
|
||||||
|
$rest = &$this->config->getREST('1.0', array());
|
||||||
|
$info = $rest->packageInfo($base, $parsed['package'], $channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($info)) {
|
||||||
|
return $this->raiseError('No supported protocol was found');
|
||||||
|
}
|
||||||
|
|
||||||
if (PEAR::isError($info)) {
|
if (PEAR::isError($info)) {
|
||||||
|
$this->config->set('default_channel', $savechannel);
|
||||||
return $this->raiseError($info);
|
return $this->raiseError($info);
|
||||||
}
|
}
|
||||||
|
|
||||||
$reg = new PEAR_Registry($this->config->get('php_dir'));
|
if (!isset($info['name'])) {
|
||||||
$installed = $reg->packageInfo($info['name']);
|
return $this->raiseError('No remote package "' . $package . '" was found');
|
||||||
|
}
|
||||||
|
|
||||||
|
$installed = $reg->packageInfo($info['name'], null, $channel);
|
||||||
$info['installed'] = $installed['version'] ? $installed['version'] : '- no -';
|
$info['installed'] = $installed['version'] ? $installed['version'] : '- no -';
|
||||||
|
if (is_array($info['installed'])) {
|
||||||
|
$info['installed'] = $info['installed']['release'];
|
||||||
|
}
|
||||||
|
|
||||||
$this->ui->outputData($info, $command);
|
$this->ui->outputData($info, $command);
|
||||||
|
$this->config->set('default_channel', $savechannel);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ doRemoteList()
|
|
||||||
|
|
||||||
function doRemoteList($command, $options, $params)
|
function doRemoteList($command, $options, $params)
|
||||||
{
|
{
|
||||||
$r = new PEAR_Remote($this->config);
|
$savechannel = $channel = $this->config->get('default_channel');
|
||||||
|
$reg = &$this->config->getRegistry();
|
||||||
|
if (isset($options['channel'])) {
|
||||||
|
$channel = $options['channel'];
|
||||||
|
if (!$reg->channelExists($channel)) {
|
||||||
|
return $this->raiseError('Channel "' . $channel . '" does not exist');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->config->set('default_channel', $channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
$chan = $reg->getChannel($channel);
|
||||||
|
if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
|
||||||
|
return $e;
|
||||||
|
}
|
||||||
|
|
||||||
$list_options = false;
|
$list_options = false;
|
||||||
if ($this->config->get('preferred_state') == 'stable')
|
if ($this->config->get('preferred_state') == 'stable') {
|
||||||
$list_options = true;
|
$list_options = true;
|
||||||
$available = $r->call('package.listAll', $list_options);
|
}
|
||||||
|
|
||||||
|
$available = array();
|
||||||
|
if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
|
||||||
|
$base = $chan->getBaseURL('REST1.1', $this->config->get('preferred_mirror'))
|
||||||
|
) {
|
||||||
|
// use faster list-all if available
|
||||||
|
$rest = &$this->config->getREST('1.1', array());
|
||||||
|
$available = $rest->listAll($base, $list_options, true, false, false, $chan->getName());
|
||||||
|
} elseif ($chan->supportsREST($this->config->get('preferred_mirror')) &&
|
||||||
|
$base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
|
||||||
|
$rest = &$this->config->getREST('1.0', array());
|
||||||
|
$available = $rest->listAll($base, $list_options, true, false, false, $chan->getName());
|
||||||
|
}
|
||||||
|
|
||||||
if (PEAR::isError($available)) {
|
if (PEAR::isError($available)) {
|
||||||
|
$this->config->set('default_channel', $savechannel);
|
||||||
return $this->raiseError($available);
|
return $this->raiseError($available);
|
||||||
}
|
}
|
||||||
|
|
||||||
$i = $j = 0;
|
$i = $j = 0;
|
||||||
$data = array(
|
$data = array(
|
||||||
'caption' => 'Available packages:',
|
'caption' => 'Channel ' . $channel . ' Available packages:',
|
||||||
'border' => true,
|
'border' => true,
|
||||||
'headline' => array('Package', 'Version'),
|
'headline' => array('Package', 'Version'),
|
||||||
|
'channel' => $channel
|
||||||
);
|
);
|
||||||
foreach ($available as $name => $info) {
|
|
||||||
$data['data'][] = array($name, isset($info['stable']) ? $info['stable'] : '-n/a-');
|
|
||||||
}
|
|
||||||
if (count($available) == 0) {
|
if (count($available) == 0) {
|
||||||
$data = '(no packages installed yet)';
|
$data = '(no packages available yet)';
|
||||||
|
} else {
|
||||||
|
foreach ($available as $name => $info) {
|
||||||
|
$version = (isset($info['stable']) && $info['stable']) ? $info['stable'] : '-n/a-';
|
||||||
|
$data['data'][] = array($name, $version);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$this->ui->outputData($data, $command);
|
$this->ui->outputData($data, $command);
|
||||||
|
$this->config->set('default_channel', $savechannel);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ doListAll()
|
|
||||||
|
|
||||||
function doListAll($command, $options, $params)
|
function doListAll($command, $options, $params)
|
||||||
{
|
{
|
||||||
$r = new PEAR_Remote($this->config);
|
$savechannel = $channel = $this->config->get('default_channel');
|
||||||
$reg = new PEAR_Registry($this->config->get('php_dir'));
|
$reg = &$this->config->getRegistry();
|
||||||
|
if (isset($options['channel'])) {
|
||||||
|
$channel = $options['channel'];
|
||||||
|
if (!$reg->channelExists($channel)) {
|
||||||
|
return $this->raiseError("Channel \"$channel\" does not exist");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->config->set('default_channel', $channel);
|
||||||
|
}
|
||||||
|
|
||||||
$list_options = false;
|
$list_options = false;
|
||||||
if ($this->config->get('preferred_state') == 'stable')
|
if ($this->config->get('preferred_state') == 'stable') {
|
||||||
$list_options = true;
|
$list_options = true;
|
||||||
$available = $r->call('package.listAll', $list_options);
|
}
|
||||||
|
|
||||||
|
$chan = $reg->getChannel($channel);
|
||||||
|
if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
|
||||||
|
return $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
|
||||||
|
$base = $chan->getBaseURL('REST1.1', $this->config->get('preferred_mirror'))) {
|
||||||
|
// use faster list-all if available
|
||||||
|
$rest = &$this->config->getREST('1.1', array());
|
||||||
|
$available = $rest->listAll($base, $list_options, false, false, false, $chan->getName());
|
||||||
|
} elseif ($chan->supportsREST($this->config->get('preferred_mirror')) &&
|
||||||
|
$base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
|
||||||
|
$rest = &$this->config->getREST('1.0', array());
|
||||||
|
$available = $rest->listAll($base, $list_options, false, false, false, $chan->getName());
|
||||||
|
}
|
||||||
|
|
||||||
if (PEAR::isError($available)) {
|
if (PEAR::isError($available)) {
|
||||||
return $this->raiseError($available);
|
$this->config->set('default_channel', $savechannel);
|
||||||
}
|
return $this->raiseError('The package list could not be fetched from the remote server. Please try again. (Debug info: "' . $available->getMessage() . '")');
|
||||||
if (!is_array($available)) {
|
|
||||||
return $this->raiseError('The package list could not be fetched from the remote server. Please try again. (Debug info: "'.$available.'")');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$data = array(
|
$data = array(
|
||||||
'caption' => 'All packages:',
|
'caption' => 'All packages [Channel ' . $channel . ']:',
|
||||||
'border' => true,
|
'border' => true,
|
||||||
'headline' => array('Package', 'Latest', 'Local'),
|
'headline' => array('Package', 'Latest', 'Local'),
|
||||||
|
'channel' => $channel,
|
||||||
);
|
);
|
||||||
$local_pkgs = $reg->listPackages();
|
|
||||||
|
if (isset($options['channelinfo'])) {
|
||||||
|
// add full channelinfo
|
||||||
|
$data['caption'] = 'Channel ' . $channel . ' All packages:';
|
||||||
|
$data['headline'] = array('Channel', 'Package', 'Latest', 'Local',
|
||||||
|
'Description', 'Dependencies');
|
||||||
|
}
|
||||||
|
$local_pkgs = $reg->listPackages($channel);
|
||||||
|
|
||||||
foreach ($available as $name => $info) {
|
foreach ($available as $name => $info) {
|
||||||
$installed = $reg->packageInfo($name);
|
$installed = $reg->packageInfo($name, null, $channel);
|
||||||
|
if (is_array($installed['version'])) {
|
||||||
|
$installed['version'] = $installed['version']['release'];
|
||||||
|
}
|
||||||
$desc = $info['summary'];
|
$desc = $info['summary'];
|
||||||
if (isset($params[$name]))
|
if (isset($params[$name])) {
|
||||||
$desc .= "\n\n".$info['description'];
|
$desc .= "\n\n".$info['description'];
|
||||||
|
}
|
||||||
if (isset($options['mode']))
|
if (isset($options['mode']))
|
||||||
{
|
{
|
||||||
if ($options['mode'] == 'installed' && !isset($installed['version']))
|
if ($options['mode'] == 'installed' && !isset($installed['version'])) {
|
||||||
continue;
|
continue;
|
||||||
if ($options['mode'] == 'notinstalled' && isset($installed['version']))
|
}
|
||||||
|
if ($options['mode'] == 'notinstalled' && isset($installed['version'])) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
if ($options['mode'] == 'upgrades'
|
if ($options['mode'] == 'upgrades'
|
||||||
&& (!isset($installed['version']) || $installed['version'] == $info['stable']))
|
&& (!isset($installed['version']) || version_compare($installed['version'],
|
||||||
{
|
$info['stable'], '>='))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -213,32 +378,65 @@ parameter.
|
||||||
unset($local_pkgs[$pos]);
|
unset($local_pkgs[$pos]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$data['data'][$info['category']][] = array(
|
if (isset($info['stable']) && !$info['stable']) {
|
||||||
|
$info['stable'] = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($options['channelinfo'])) {
|
||||||
|
// add full channelinfo
|
||||||
|
if ($info['stable'] === $info['unstable']) {
|
||||||
|
$state = $info['state'];
|
||||||
|
} else {
|
||||||
|
$state = 'stable';
|
||||||
|
}
|
||||||
|
$latest = $info['stable'].' ('.$state.')';
|
||||||
|
$local = '';
|
||||||
|
if (isset($installed['version'])) {
|
||||||
|
$inst_state = $reg->packageInfo($name, 'release_state', $channel);
|
||||||
|
$local = $installed['version'].' ('.$inst_state.')';
|
||||||
|
}
|
||||||
|
|
||||||
|
$packageinfo = array(
|
||||||
|
$channel,
|
||||||
$name,
|
$name,
|
||||||
@$info['stable'],
|
$latest,
|
||||||
@$installed['version'],
|
$local,
|
||||||
@$desc,
|
isset($desc) ? $desc : null,
|
||||||
@$info['deps'],
|
isset($info['deps']) ? $info['deps'] : null,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$packageinfo = array(
|
||||||
|
$reg->channelAlias($channel) . '/' . $name,
|
||||||
|
isset($info['stable']) ? $info['stable'] : null,
|
||||||
|
isset($installed['version']) ? $installed['version'] : null,
|
||||||
|
isset($desc) ? $desc : null,
|
||||||
|
isset($info['deps']) ? $info['deps'] : null,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
$data['data'][$info['category']][] = $packageinfo;
|
||||||
foreach ($local_pkgs as $name) {
|
|
||||||
$info = $reg->packageInfo($name);
|
|
||||||
$data['data']['Local'][] = array(
|
|
||||||
$info['package'],
|
|
||||||
'',
|
|
||||||
$info['version'],
|
|
||||||
$info['summary'],
|
|
||||||
@$info['release_deps']
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isset($options['mode']) && in_array($options['mode'], array('notinstalled', 'upgrades'))) {
|
||||||
|
$this->config->set('default_channel', $savechannel);
|
||||||
$this->ui->outputData($data, $command);
|
$this->ui->outputData($data, $command);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
foreach ($local_pkgs as $name) {
|
||||||
// {{{ doSearch()
|
$info = &$reg->getPackage($name, $channel);
|
||||||
|
$data['data']['Local'][] = array(
|
||||||
|
$reg->channelAlias($channel) . '/' . $info->getPackage(),
|
||||||
|
'',
|
||||||
|
$info->getVersion(),
|
||||||
|
$info->getSummary(),
|
||||||
|
$info->getDeps()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->config->set('default_channel', $savechannel);
|
||||||
|
$this->ui->outputData($data, $command);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
function doSearch($command, $options, $params)
|
function doSearch($command, $options, $params)
|
||||||
{
|
{
|
||||||
|
@ -246,79 +444,187 @@ parameter.
|
||||||
&& (!isset($params[1]) || empty($params[1])))
|
&& (!isset($params[1]) || empty($params[1])))
|
||||||
{
|
{
|
||||||
return $this->raiseError('no valid search string supplied');
|
return $this->raiseError('no valid search string supplied');
|
||||||
};
|
}
|
||||||
|
|
||||||
|
$channelinfo = isset($options['channelinfo']);
|
||||||
|
$reg = &$this->config->getRegistry();
|
||||||
|
if (isset($options['allchannels'])) {
|
||||||
|
// search all channels
|
||||||
|
unset($options['allchannels']);
|
||||||
|
$channels = $reg->getChannels();
|
||||||
|
$errors = array();
|
||||||
|
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
|
||||||
|
foreach ($channels as $channel) {
|
||||||
|
if ($channel->getName() != '__uri') {
|
||||||
|
$options['channel'] = $channel->getName();
|
||||||
|
$ret = $this->doSearch($command, $options, $params);
|
||||||
|
if (PEAR::isError($ret)) {
|
||||||
|
$errors[] = $ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PEAR::staticPopErrorHandling();
|
||||||
|
if (count($errors) !== 0) {
|
||||||
|
// for now, only give first error
|
||||||
|
return PEAR::raiseError($errors[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$savechannel = $channel = $this->config->get('default_channel');
|
||||||
|
$package = strtolower($params[0]);
|
||||||
|
$summary = isset($params[1]) ? $params[1] : false;
|
||||||
|
if (isset($options['channel'])) {
|
||||||
|
$reg = &$this->config->getRegistry();
|
||||||
|
$channel = $options['channel'];
|
||||||
|
if (!$reg->channelExists($channel)) {
|
||||||
|
return $this->raiseError('Channel "' . $channel . '" does not exist');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->config->set('default_channel', $channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
$chan = $reg->getChannel($channel);
|
||||||
|
if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
|
||||||
|
return $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
|
||||||
|
$base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
|
||||||
|
$rest = &$this->config->getREST('1.0', array());
|
||||||
|
$available = $rest->listAll($base, false, false, $package, $summary, $chan->getName());
|
||||||
|
}
|
||||||
|
|
||||||
$r = new PEAR_Remote($this->config);
|
|
||||||
$reg = new PEAR_Registry($this->config->get('php_dir'));
|
|
||||||
$available = $r->call('package.listAll', true, false);
|
|
||||||
if (PEAR::isError($available)) {
|
if (PEAR::isError($available)) {
|
||||||
|
$this->config->set('default_channel', $savechannel);
|
||||||
return $this->raiseError($available);
|
return $this->raiseError($available);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!$available && !$channelinfo) {
|
||||||
|
// clean exit when not found, no error !
|
||||||
|
$data = 'no packages found that match pattern "' . $package . '", for channel '.$channel.'.';
|
||||||
|
$this->ui->outputData($data);
|
||||||
|
$this->config->set('default_channel', $channel);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($channelinfo) {
|
||||||
$data = array(
|
$data = array(
|
||||||
'caption' => 'Matched packages:',
|
'caption' => 'Matched packages, channel ' . $channel . ':',
|
||||||
|
'border' => true,
|
||||||
|
'headline' => array('Channel', 'Package', 'Stable/(Latest)', 'Local'),
|
||||||
|
'channel' => $channel
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$data = array(
|
||||||
|
'caption' => 'Matched packages, channel ' . $channel . ':',
|
||||||
'border' => true,
|
'border' => true,
|
||||||
'headline' => array('Package', 'Stable/(Latest)', 'Local'),
|
'headline' => array('Package', 'Stable/(Latest)', 'Local'),
|
||||||
|
'channel' => $channel
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$available && $channelinfo) {
|
||||||
|
unset($data['headline']);
|
||||||
|
$data['data'] = 'No packages found that match pattern "' . $package . '".';
|
||||||
|
$available = array();
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($available as $name => $info) {
|
foreach ($available as $name => $info) {
|
||||||
$found = (!empty($params[0]) && stristr($name, $params[0]) !== false);
|
$installed = $reg->packageInfo($name, null, $channel);
|
||||||
if (!$found && !(isset($params[1]) && !empty($params[1])
|
|
||||||
&& (stristr($info['summary'], $params[1]) !== false
|
|
||||||
|| stristr($info['description'], $params[1]) !== false)))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
|
|
||||||
$installed = $reg->packageInfo($name);
|
|
||||||
$desc = $info['summary'];
|
$desc = $info['summary'];
|
||||||
if (isset($params[$name]))
|
if (isset($params[$name]))
|
||||||
$desc .= "\n\n".$info['description'];
|
$desc .= "\n\n".$info['description'];
|
||||||
|
|
||||||
$unstable = '';
|
|
||||||
if ($info['unstable']) {
|
|
||||||
$unstable = '/(' . $info['unstable'] . $info['state'] . ')';
|
|
||||||
}
|
|
||||||
if (!isset($info['stable']) || !$info['stable']) {
|
if (!isset($info['stable']) || !$info['stable']) {
|
||||||
$info['stable'] = 'none';
|
$version_remote = 'none';
|
||||||
|
} else {
|
||||||
|
if ($info['unstable']) {
|
||||||
|
$version_remote = $info['unstable'];
|
||||||
|
} else {
|
||||||
|
$version_remote = $info['stable'];
|
||||||
}
|
}
|
||||||
$data['data'][$info['category']][] = array(
|
$version_remote .= ' ('.$info['state'].')';
|
||||||
|
}
|
||||||
|
$version = is_array($installed['version']) ? $installed['version']['release'] :
|
||||||
|
$installed['version'];
|
||||||
|
if ($channelinfo) {
|
||||||
|
$packageinfo = array(
|
||||||
|
$channel,
|
||||||
$name,
|
$name,
|
||||||
$info['stable'] . $unstable,
|
$version_remote,
|
||||||
$installed['version'],
|
$version,
|
||||||
|
$desc,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$packageinfo = array(
|
||||||
|
$name,
|
||||||
|
$version_remote,
|
||||||
|
$version,
|
||||||
$desc,
|
$desc,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (!isset($data['data'])) {
|
$data['data'][$info['category']][] = $packageinfo;
|
||||||
return $this->raiseError('no packages found');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->ui->outputData($data, $command);
|
$this->ui->outputData($data, $command);
|
||||||
|
$this->config->set('default_channel', $channel);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
function &getDownloader($options)
|
||||||
// {{{ doDownload()
|
{
|
||||||
|
if (!class_exists('PEAR_Downloader')) {
|
||||||
|
require_once 'PEAR/Downloader.php';
|
||||||
|
}
|
||||||
|
$a = &new PEAR_Downloader($this->ui, $options, $this->config);
|
||||||
|
return $a;
|
||||||
|
}
|
||||||
|
|
||||||
function doDownload($command, $options, $params)
|
function doDownload($command, $options, $params)
|
||||||
{
|
{
|
||||||
//$params[0] -> The package to download
|
// make certain that dependencies are ignored
|
||||||
if (count($params) != 1) {
|
$options['downloadonly'] = 1;
|
||||||
return PEAR::raiseError("download expects one argument: the package to download");
|
|
||||||
|
// eliminate error messages for preferred_state-related errors
|
||||||
|
/* TODO: Should be an option, but until now download does respect
|
||||||
|
prefered state */
|
||||||
|
/* $options['ignorepreferred_state'] = 1; */
|
||||||
|
// eliminate error messages for preferred_state-related errors
|
||||||
|
|
||||||
|
$downloader = &$this->getDownloader($options);
|
||||||
|
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
|
||||||
|
$e = $downloader->setDownloadDir(getcwd());
|
||||||
|
PEAR::staticPopErrorHandling();
|
||||||
|
if (PEAR::isError($e)) {
|
||||||
|
return $this->raiseError('Current directory is not writeable, cannot download');
|
||||||
}
|
}
|
||||||
$server = $this->config->get('master_server');
|
|
||||||
if (!ereg('^http://', $params[0])) {
|
$errors = array();
|
||||||
$getoption = isset($options['nocompress'])&&$options['nocompress']==1?'?uncompress=on':'';
|
$downloaded = array();
|
||||||
$pkgfile = "http://$server/get/$params[0]".$getoption;
|
$err = $downloader->download($params);
|
||||||
} else {
|
if (PEAR::isError($err)) {
|
||||||
$pkgfile = $params[0];
|
return $err;
|
||||||
}
|
}
|
||||||
$this->bytes_downloaded = 0;
|
|
||||||
$saved = PEAR_Common::downloadHttp($pkgfile, $this->ui, '.',
|
$errors = $downloader->getErrorMsgs();
|
||||||
array(&$this, 'downloadCallback'));
|
if (count($errors)) {
|
||||||
if (PEAR::isError($saved)) {
|
foreach ($errors as $error) {
|
||||||
return $this->raiseError($saved);
|
if ($error !== null) {
|
||||||
|
$this->ui->outputData($error);
|
||||||
}
|
}
|
||||||
$fname = basename($saved);
|
}
|
||||||
$this->ui->outputData("File $fname downloaded ($this->bytes_downloaded bytes)", $command);
|
|
||||||
|
return $this->raiseError("$command failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
$downloaded = $downloader->getDownloadedPackages();
|
||||||
|
foreach ($downloaded as $pkg) {
|
||||||
|
$this->ui->outputData("File $pkg[file] downloaded", $command);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,50 +635,95 @@ parameter.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ doListUpgrades()
|
|
||||||
|
|
||||||
function doListUpgrades($command, $options, $params)
|
function doListUpgrades($command, $options, $params)
|
||||||
{
|
{
|
||||||
include_once "PEAR/Registry.php";
|
require_once 'PEAR/Common.php';
|
||||||
$remote = new PEAR_Remote($this->config);
|
if (isset($params[0]) && !is_array(PEAR_Common::betterStates($params[0]))) {
|
||||||
if (empty($params[0])) {
|
return $this->raiseError($params[0] . ' is not a valid state (stable/beta/alpha/devel/etc.) try "pear help list-upgrades"');
|
||||||
$state = $this->config->get('preferred_state');
|
|
||||||
} else {
|
|
||||||
$state = $params[0];
|
|
||||||
}
|
}
|
||||||
$caption = 'Available Upgrades';
|
|
||||||
if (empty($state) || $state == 'any') {
|
$savechannel = $channel = $this->config->get('default_channel');
|
||||||
$latest = $remote->call("package.listLatestReleases");
|
$reg = &$this->config->getRegistry();
|
||||||
|
foreach ($reg->listChannels() as $channel) {
|
||||||
|
$inst = array_flip($reg->listPackages($channel));
|
||||||
|
if (!count($inst)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($channel == '__uri') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->config->set('default_channel', $channel);
|
||||||
|
$state = empty($params[0]) ? $this->config->get('preferred_state') : $params[0];
|
||||||
|
|
||||||
|
$caption = $channel . ' Available Upgrades';
|
||||||
|
$chan = $reg->getChannel($channel);
|
||||||
|
if (PEAR::isError($e = $this->_checkChannelForStatus($channel, $chan))) {
|
||||||
|
return $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
$latest = array();
|
||||||
|
$base2 = false;
|
||||||
|
$preferred_mirror = $this->config->get('preferred_mirror');
|
||||||
|
if ($chan->supportsREST($preferred_mirror) &&
|
||||||
|
(
|
||||||
|
//($base2 = $chan->getBaseURL('REST1.4', $preferred_mirror)) ||
|
||||||
|
($base = $chan->getBaseURL('REST1.0', $preferred_mirror))
|
||||||
|
)
|
||||||
|
|
||||||
|
) {
|
||||||
|
if ($base2) {
|
||||||
|
$rest = &$this->config->getREST('1.4', array());
|
||||||
|
$base = $base2;
|
||||||
|
} else {
|
||||||
|
$rest = &$this->config->getREST('1.0', array());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($state) || $state == 'any') {
|
||||||
|
$state = false;
|
||||||
} else {
|
} else {
|
||||||
$latest = $remote->call("package.listLatestReleases", $state);
|
|
||||||
$caption .= ' (' . implode(', ', PEAR_Common::betterStates($state, true)) . ')';
|
$caption .= ' (' . implode(', ', PEAR_Common::betterStates($state, true)) . ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
|
||||||
|
$latest = $rest->listLatestUpgrades($base, $state, $inst, $channel, $reg);
|
||||||
|
PEAR::staticPopErrorHandling();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PEAR::isError($latest)) {
|
||||||
|
$this->ui->outputData($latest->getMessage());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$caption .= ':';
|
$caption .= ':';
|
||||||
if (PEAR::isError($latest)) {
|
if (PEAR::isError($latest)) {
|
||||||
|
$this->config->set('default_channel', $savechannel);
|
||||||
return $latest;
|
return $latest;
|
||||||
}
|
}
|
||||||
$reg = new PEAR_Registry($this->config->get('php_dir'));
|
|
||||||
$inst = array_flip($reg->listPackages());
|
|
||||||
$data = array(
|
$data = array(
|
||||||
'caption' => $caption,
|
'caption' => $caption,
|
||||||
'border' => 1,
|
'border' => 1,
|
||||||
'headline' => array('Package', 'Local', 'Remote', 'Size'),
|
'headline' => array('Channel', 'Package', 'Local', 'Remote', 'Size'),
|
||||||
|
'channel' => $channel
|
||||||
);
|
);
|
||||||
|
|
||||||
foreach ((array)$latest as $pkg => $info) {
|
foreach ((array)$latest as $pkg => $info) {
|
||||||
$package = strtolower($pkg);
|
$package = strtolower($pkg);
|
||||||
if (!isset($inst[$package])) {
|
if (!isset($inst[$package])) {
|
||||||
// skip packages we don't have installed
|
// skip packages we don't have installed
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
extract($info);
|
extract($info);
|
||||||
$pkginfo = $reg->packageInfo($package);
|
$inst_version = $reg->packageInfo($package, 'version', $channel);
|
||||||
$inst_version = $pkginfo['version'];
|
$inst_state = $reg->packageInfo($package, 'release_state', $channel);
|
||||||
$inst_state = $pkginfo['release_state'];
|
|
||||||
if (version_compare("$version", "$inst_version", "le")) {
|
if (version_compare("$version", "$inst_version", "le")) {
|
||||||
// installed version is up-to-date
|
// installed version is up-to-date
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($filesize >= 20480) {
|
if ($filesize >= 20480) {
|
||||||
$filesize += 1024 - ($filesize % 1024);
|
$filesize += 1024 - ($filesize % 1024);
|
||||||
$fs = sprintf("%dkB", $filesize / 1024);
|
$fs = sprintf("%dkB", $filesize / 1024);
|
||||||
|
@ -382,54 +733,78 @@ parameter.
|
||||||
} else {
|
} else {
|
||||||
$fs = " -"; // XXX center instead
|
$fs = " -"; // XXX center instead
|
||||||
}
|
}
|
||||||
$data['data'][] = array($pkg, "$inst_version ($inst_state)", "$version ($state)", $fs);
|
|
||||||
|
$data['data'][] = array($channel, $pkg, "$inst_version ($inst_state)", "$version ($state)", $fs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isset($options['channelinfo'])) {
|
||||||
if (empty($data['data'])) {
|
if (empty($data['data'])) {
|
||||||
$this->ui->outputData('No upgrades available');
|
unset($data['headline']);
|
||||||
|
if (count($inst) == 0) {
|
||||||
|
$data['data'] = '(no packages installed)';
|
||||||
|
} else {
|
||||||
|
$data['data'] = '(no upgrades available)';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->ui->outputData($data, $command);
|
||||||
|
} else {
|
||||||
|
if (empty($data['data'])) {
|
||||||
|
$this->ui->outputData('Channel ' . $channel . ': No upgrades available');
|
||||||
} else {
|
} else {
|
||||||
$this->ui->outputData($data, $command);
|
$this->ui->outputData($data, $command);
|
||||||
}
|
}
|
||||||
return true;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
$this->config->set('default_channel', $savechannel);
|
||||||
// {{{ doClearCache()
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
function doClearCache($command, $options, $params)
|
function doClearCache($command, $options, $params)
|
||||||
{
|
{
|
||||||
$cache_dir = $this->config->get('cache_dir');
|
$cache_dir = $this->config->get('cache_dir');
|
||||||
$verbose = $this->config->get('verbose');
|
$verbose = $this->config->get('verbose');
|
||||||
$output = '';
|
$output = '';
|
||||||
|
if (!file_exists($cache_dir) || !is_dir($cache_dir)) {
|
||||||
|
return $this->raiseError("$cache_dir does not exist or is not a directory");
|
||||||
|
}
|
||||||
|
|
||||||
if (!($dp = @opendir($cache_dir))) {
|
if (!($dp = @opendir($cache_dir))) {
|
||||||
return $this->raiseError("opendir($cache_dir) failed: $php_errormsg");
|
return $this->raiseError("opendir($cache_dir) failed: $php_errormsg");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($verbose >= 1) {
|
if ($verbose >= 1) {
|
||||||
$output .= "reading directory $cache_dir\n";
|
$output .= "reading directory $cache_dir\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
$num = 0;
|
$num = 0;
|
||||||
while ($ent = readdir($dp)) {
|
while ($ent = readdir($dp)) {
|
||||||
if (preg_match('/^xmlrpc_cache_[a-z0-9]{32}$/', $ent)) {
|
if (preg_match('/rest.cache(file|id)\\z/', $ent)) {
|
||||||
$path = $cache_dir . DIRECTORY_SEPARATOR . $ent;
|
$path = $cache_dir . DIRECTORY_SEPARATOR . $ent;
|
||||||
|
if (file_exists($path)) {
|
||||||
$ok = @unlink($path);
|
$ok = @unlink($path);
|
||||||
|
} else {
|
||||||
|
$ok = false;
|
||||||
|
$php_errormsg = '';
|
||||||
|
}
|
||||||
|
|
||||||
if ($ok) {
|
if ($ok) {
|
||||||
if ($verbose >= 2) {
|
if ($verbose >= 2) {
|
||||||
$output .= "deleted $path\n";
|
$output .= "deleted $path\n";
|
||||||
}
|
}
|
||||||
$num++;
|
$num++;
|
||||||
} elseif ($verbose >= 1) {
|
} elseif ($verbose >= 1) {
|
||||||
$output .= "failed to delete $path\n";
|
$output .= "failed to delete $path $php_errormsg\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
closedir($dp);
|
closedir($dp);
|
||||||
if ($verbose >= 1) {
|
if ($verbose >= 1) {
|
||||||
$output .= "$num cache entries cleared\n";
|
$output .= "$num cache entries cleared\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->ui->outputData(rtrim($output), $command);
|
$this->ui->outputData(rtrim($output), $command);
|
||||||
return $num;
|
return $num;
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
<commands version="1.0">
|
||||||
|
<remote-info>
|
||||||
|
<summary>Information About Remote Packages</summary>
|
||||||
|
<function>doRemoteInfo</function>
|
||||||
|
<shortcut>ri</shortcut>
|
||||||
|
<options />
|
||||||
|
<doc><package>
|
||||||
|
Get details on a package from the server.</doc>
|
||||||
|
</remote-info>
|
||||||
|
<list-upgrades>
|
||||||
|
<summary>List Available Upgrades</summary>
|
||||||
|
<function>doListUpgrades</function>
|
||||||
|
<shortcut>lu</shortcut>
|
||||||
|
<options>
|
||||||
|
<channelinfo>
|
||||||
|
<shortopt>i</shortopt>
|
||||||
|
<doc>output fully channel-aware data, even on failure</doc>
|
||||||
|
</channelinfo>
|
||||||
|
</options>
|
||||||
|
<doc>[preferred_state]
|
||||||
|
List releases on the server of packages you have installed where
|
||||||
|
a newer version is available with the same release state (stable etc.)
|
||||||
|
or the state passed as the second parameter.</doc>
|
||||||
|
</list-upgrades>
|
||||||
|
<remote-list>
|
||||||
|
<summary>List Remote Packages</summary>
|
||||||
|
<function>doRemoteList</function>
|
||||||
|
<shortcut>rl</shortcut>
|
||||||
|
<options>
|
||||||
|
<channel>
|
||||||
|
<shortopt>c</shortopt>
|
||||||
|
<doc>specify a channel other than the default channel</doc>
|
||||||
|
<arg>CHAN</arg>
|
||||||
|
</channel>
|
||||||
|
</options>
|
||||||
|
<doc>
|
||||||
|
Lists the packages available on the configured server along with the
|
||||||
|
latest stable release of each package.</doc>
|
||||||
|
</remote-list>
|
||||||
|
<search>
|
||||||
|
<summary>Search remote package database</summary>
|
||||||
|
<function>doSearch</function>
|
||||||
|
<shortcut>sp</shortcut>
|
||||||
|
<options>
|
||||||
|
<channel>
|
||||||
|
<shortopt>c</shortopt>
|
||||||
|
<doc>specify a channel other than the default channel</doc>
|
||||||
|
<arg>CHAN</arg>
|
||||||
|
</channel>
|
||||||
|
<allchannels>
|
||||||
|
<shortopt>a</shortopt>
|
||||||
|
<doc>search packages from all known channels</doc>
|
||||||
|
</allchannels>
|
||||||
|
<channelinfo>
|
||||||
|
<shortopt>i</shortopt>
|
||||||
|
<doc>output fully channel-aware data, even on failure</doc>
|
||||||
|
</channelinfo>
|
||||||
|
</options>
|
||||||
|
<doc>[packagename] [packageinfo]
|
||||||
|
Lists all packages which match the search parameters. The first
|
||||||
|
parameter is a fragment of a packagename. The default channel
|
||||||
|
will be used unless explicitly overridden. The second parameter
|
||||||
|
will be used to match any portion of the summary/description</doc>
|
||||||
|
</search>
|
||||||
|
<list-all>
|
||||||
|
<summary>List All Packages</summary>
|
||||||
|
<function>doListAll</function>
|
||||||
|
<shortcut>la</shortcut>
|
||||||
|
<options>
|
||||||
|
<channel>
|
||||||
|
<shortopt>c</shortopt>
|
||||||
|
<doc>specify a channel other than the default channel</doc>
|
||||||
|
<arg>CHAN</arg>
|
||||||
|
</channel>
|
||||||
|
<channelinfo>
|
||||||
|
<shortopt>i</shortopt>
|
||||||
|
<doc>output fully channel-aware data, even on failure</doc>
|
||||||
|
</channelinfo>
|
||||||
|
</options>
|
||||||
|
<doc>
|
||||||
|
Lists the packages available on the configured server along with the
|
||||||
|
latest stable release of each package.</doc>
|
||||||
|
</list-all>
|
||||||
|
<download>
|
||||||
|
<summary>Download Package</summary>
|
||||||
|
<function>doDownload</function>
|
||||||
|
<shortcut>d</shortcut>
|
||||||
|
<options>
|
||||||
|
<nocompress>
|
||||||
|
<shortopt>Z</shortopt>
|
||||||
|
<doc>download an uncompressed (.tar) file</doc>
|
||||||
|
</nocompress>
|
||||||
|
</options>
|
||||||
|
<doc><package>...
|
||||||
|
Download package tarballs. The files will be named as suggested by the
|
||||||
|
server, for example if you download the DB package and the latest stable
|
||||||
|
version of DB is 1.6.5, the downloaded file will be DB-1.6.5.tgz.</doc>
|
||||||
|
</download>
|
||||||
|
<clear-cache>
|
||||||
|
<summary>Clear Web Services Cache</summary>
|
||||||
|
<function>doClearCache</function>
|
||||||
|
<shortcut>cc</shortcut>
|
||||||
|
<options />
|
||||||
|
<doc>
|
||||||
|
Clear the XML-RPC/REST cache. See also the cache_ttl configuration
|
||||||
|
parameter.
|
||||||
|
</doc>
|
||||||
|
</clear-cache>
|
||||||
|
</commands>
|
|
@ -0,0 +1,337 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PEAR_Command_Test (run-tests)
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Stig Bakken <ssb@php.net>
|
||||||
|
* @author Martin Jansen <mj@php.net>
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: Test.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since Release 0.1
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* base class
|
||||||
|
*/
|
||||||
|
require_once 'PEAR/Command/Common.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PEAR commands for login/logout
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Stig Bakken <ssb@php.net>
|
||||||
|
* @author Martin Jansen <mj@php.net>
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 0.1
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PEAR_Command_Test extends PEAR_Command_Common
|
||||||
|
{
|
||||||
|
var $commands = array(
|
||||||
|
'run-tests' => array(
|
||||||
|
'summary' => 'Run Regression Tests',
|
||||||
|
'function' => 'doRunTests',
|
||||||
|
'shortcut' => 'rt',
|
||||||
|
'options' => array(
|
||||||
|
'recur' => array(
|
||||||
|
'shortopt' => 'r',
|
||||||
|
'doc' => 'Run tests in child directories, recursively. 4 dirs deep maximum',
|
||||||
|
),
|
||||||
|
'ini' => array(
|
||||||
|
'shortopt' => 'i',
|
||||||
|
'doc' => 'actual string of settings to pass to php in format " -d setting=blah"',
|
||||||
|
'arg' => 'SETTINGS'
|
||||||
|
),
|
||||||
|
'realtimelog' => array(
|
||||||
|
'shortopt' => 'l',
|
||||||
|
'doc' => 'Log test runs/results as they are run',
|
||||||
|
),
|
||||||
|
'quiet' => array(
|
||||||
|
'shortopt' => 'q',
|
||||||
|
'doc' => 'Only display detail for failed tests',
|
||||||
|
),
|
||||||
|
'simple' => array(
|
||||||
|
'shortopt' => 's',
|
||||||
|
'doc' => 'Display simple output for all tests',
|
||||||
|
),
|
||||||
|
'package' => array(
|
||||||
|
'shortopt' => 'p',
|
||||||
|
'doc' => 'Treat parameters as installed packages from which to run tests',
|
||||||
|
),
|
||||||
|
'phpunit' => array(
|
||||||
|
'shortopt' => 'u',
|
||||||
|
'doc' => 'Search parameters for AllTests.php, and use that to run phpunit-based tests
|
||||||
|
If none is found, all .phpt tests will be tried instead.',
|
||||||
|
),
|
||||||
|
'tapoutput' => array(
|
||||||
|
'shortopt' => 't',
|
||||||
|
'doc' => 'Output run-tests.log in TAP-compliant format',
|
||||||
|
),
|
||||||
|
'cgi' => array(
|
||||||
|
'shortopt' => 'c',
|
||||||
|
'doc' => 'CGI php executable (needed for tests with POST/GET section)',
|
||||||
|
'arg' => 'PHPCGI',
|
||||||
|
),
|
||||||
|
'coverage' => array(
|
||||||
|
'shortopt' => 'x',
|
||||||
|
'doc' => 'Generate a code coverage report (requires Xdebug 2.0.0+)',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'doc' => '[testfile|dir ...]
|
||||||
|
Run regression tests with PHP\'s regression testing script (run-tests.php).',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
var $output;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PEAR_Command_Test constructor.
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function PEAR_Command_Test(&$ui, &$config)
|
||||||
|
{
|
||||||
|
parent::PEAR_Command_Common($ui, $config);
|
||||||
|
}
|
||||||
|
|
||||||
|
function doRunTests($command, $options, $params)
|
||||||
|
{
|
||||||
|
if (isset($options['phpunit']) && isset($options['tapoutput'])) {
|
||||||
|
return $this->raiseError('ERROR: cannot use both --phpunit and --tapoutput at the same time');
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once 'PEAR/Common.php';
|
||||||
|
require_once 'System.php';
|
||||||
|
$log = new PEAR_Common;
|
||||||
|
$log->ui = &$this->ui; // slightly hacky, but it will work
|
||||||
|
$tests = array();
|
||||||
|
$depth = isset($options['recur']) ? 14 : 1;
|
||||||
|
|
||||||
|
if (!count($params)) {
|
||||||
|
$params[] = '.';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($options['package'])) {
|
||||||
|
$oldparams = $params;
|
||||||
|
$params = array();
|
||||||
|
$reg = &$this->config->getRegistry();
|
||||||
|
foreach ($oldparams as $param) {
|
||||||
|
$pname = $reg->parsePackageName($param, $this->config->get('default_channel'));
|
||||||
|
if (PEAR::isError($pname)) {
|
||||||
|
return $this->raiseError($pname);
|
||||||
|
}
|
||||||
|
|
||||||
|
$package = &$reg->getPackage($pname['package'], $pname['channel']);
|
||||||
|
if (!$package) {
|
||||||
|
return PEAR::raiseError('Unknown package "' .
|
||||||
|
$reg->parsedPackageNameToString($pname) . '"');
|
||||||
|
}
|
||||||
|
|
||||||
|
$filelist = $package->getFilelist();
|
||||||
|
foreach ($filelist as $name => $atts) {
|
||||||
|
if (isset($atts['role']) && $atts['role'] != 'test') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($options['phpunit']) && preg_match('/AllTests\.php\\z/i', $name)) {
|
||||||
|
$params[] = $atts['installed_as'];
|
||||||
|
continue;
|
||||||
|
} elseif (!preg_match('/\.phpt\\z/', $name)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$params[] = $atts['installed_as'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($params as $p) {
|
||||||
|
if (is_dir($p)) {
|
||||||
|
if (isset($options['phpunit'])) {
|
||||||
|
$dir = System::find(array($p, '-type', 'f',
|
||||||
|
'-maxdepth', $depth,
|
||||||
|
'-name', 'AllTests.php'));
|
||||||
|
if (count($dir)) {
|
||||||
|
foreach ($dir as $p) {
|
||||||
|
$p = realpath($p);
|
||||||
|
if (!count($tests) ||
|
||||||
|
(count($tests) && strlen($p) < strlen($tests[0]))) {
|
||||||
|
// this is in a higher-level directory, use this one instead.
|
||||||
|
$tests = array($p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$args = array($p, '-type', 'f', '-name', '*.phpt');
|
||||||
|
} else {
|
||||||
|
if (isset($options['phpunit'])) {
|
||||||
|
if (preg_match('/AllTests\.php\\z/i', $p)) {
|
||||||
|
$p = realpath($p);
|
||||||
|
if (!count($tests) ||
|
||||||
|
(count($tests) && strlen($p) < strlen($tests[0]))) {
|
||||||
|
// this is in a higher-level directory, use this one instead.
|
||||||
|
$tests = array($p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file_exists($p) && preg_match('/\.phpt$/', $p)) {
|
||||||
|
$tests[] = $p;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!preg_match('/\.phpt\\z/', $p)) {
|
||||||
|
$p .= '.phpt';
|
||||||
|
}
|
||||||
|
|
||||||
|
$args = array(dirname($p), '-type', 'f', '-name', $p);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($options['recur'])) {
|
||||||
|
$args[] = '-maxdepth';
|
||||||
|
$args[] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
$dir = System::find($args);
|
||||||
|
$tests = array_merge($tests, $dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
$ini_settings = '';
|
||||||
|
if (isset($options['ini'])) {
|
||||||
|
$ini_settings .= $options['ini'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($_ENV['TEST_PHP_INCLUDE_PATH'])) {
|
||||||
|
$ini_settings .= " -d include_path={$_ENV['TEST_PHP_INCLUDE_PATH']}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($ini_settings) {
|
||||||
|
$this->ui->outputData('Using INI settings: "' . $ini_settings . '"');
|
||||||
|
}
|
||||||
|
|
||||||
|
$skipped = $passed = $failed = array();
|
||||||
|
$tests_count = count($tests);
|
||||||
|
$this->ui->outputData('Running ' . $tests_count . ' tests', $command);
|
||||||
|
$start = time();
|
||||||
|
if (isset($options['realtimelog']) && file_exists('run-tests.log')) {
|
||||||
|
unlink('run-tests.log');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($options['tapoutput'])) {
|
||||||
|
$tap = '1..' . $tests_count . "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once 'PEAR/RunTest.php';
|
||||||
|
$run = new PEAR_RunTest($log, $options);
|
||||||
|
$run->tests_count = $tests_count;
|
||||||
|
|
||||||
|
if (isset($options['coverage']) && extension_loaded('xdebug')){
|
||||||
|
$run->xdebug_loaded = true;
|
||||||
|
} else {
|
||||||
|
$run->xdebug_loaded = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$j = $i = 1;
|
||||||
|
foreach ($tests as $t) {
|
||||||
|
if (isset($options['realtimelog'])) {
|
||||||
|
$fp = @fopen('run-tests.log', 'a');
|
||||||
|
if ($fp) {
|
||||||
|
fwrite($fp, "Running test [$i / $tests_count] $t...");
|
||||||
|
fclose($fp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
|
||||||
|
if (isset($options['phpunit'])) {
|
||||||
|
$result = $run->runPHPUnit($t, $ini_settings);
|
||||||
|
} else {
|
||||||
|
$result = $run->run($t, $ini_settings, $j);
|
||||||
|
}
|
||||||
|
PEAR::staticPopErrorHandling();
|
||||||
|
if (PEAR::isError($result)) {
|
||||||
|
$this->ui->log($result->getMessage());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($options['tapoutput'])) {
|
||||||
|
$tap .= $result[0] . ' ' . $i . $result[1] . "\n";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($options['realtimelog'])) {
|
||||||
|
$fp = @fopen('run-tests.log', 'a');
|
||||||
|
if ($fp) {
|
||||||
|
fwrite($fp, "$result\n");
|
||||||
|
fclose($fp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($result == 'FAILED') {
|
||||||
|
$failed[] = $t;
|
||||||
|
}
|
||||||
|
if ($result == 'PASSED') {
|
||||||
|
$passed[] = $t;
|
||||||
|
}
|
||||||
|
if ($result == 'SKIPPED') {
|
||||||
|
$skipped[] = $t;
|
||||||
|
}
|
||||||
|
|
||||||
|
$j++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$total = date('i:s', time() - $start);
|
||||||
|
if (isset($options['tapoutput'])) {
|
||||||
|
$fp = @fopen('run-tests.log', 'w');
|
||||||
|
if ($fp) {
|
||||||
|
fwrite($fp, $tap, strlen($tap));
|
||||||
|
fclose($fp);
|
||||||
|
$this->ui->outputData('wrote TAP-format log to "' .realpath('run-tests.log') .
|
||||||
|
'"', $command);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (count($failed)) {
|
||||||
|
$output = "TOTAL TIME: $total\n";
|
||||||
|
$output .= count($passed) . " PASSED TESTS\n";
|
||||||
|
$output .= count($skipped) . " SKIPPED TESTS\n";
|
||||||
|
$output .= count($failed) . " FAILED TESTS:\n";
|
||||||
|
foreach ($failed as $failure) {
|
||||||
|
$output .= $failure . "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$mode = isset($options['realtimelog']) ? 'a' : 'w';
|
||||||
|
$fp = @fopen('run-tests.log', $mode);
|
||||||
|
|
||||||
|
if ($fp) {
|
||||||
|
fwrite($fp, $output, strlen($output));
|
||||||
|
fclose($fp);
|
||||||
|
$this->ui->outputData('wrote log to "' . realpath('run-tests.log') . '"', $command);
|
||||||
|
}
|
||||||
|
} elseif (file_exists('run-tests.log') && !is_dir('run-tests.log')) {
|
||||||
|
@unlink('run-tests.log');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->ui->outputData('TOTAL TIME: ' . $total);
|
||||||
|
$this->ui->outputData(count($passed) . ' PASSED TESTS', $command);
|
||||||
|
$this->ui->outputData(count($skipped) . ' SKIPPED TESTS', $command);
|
||||||
|
if (count($failed)) {
|
||||||
|
$this->ui->outputData(count($failed) . ' FAILED TESTS:', $command);
|
||||||
|
foreach ($failed as $failure) {
|
||||||
|
$this->ui->outputData($failure, $command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
<commands version="1.0">
|
||||||
|
<run-tests>
|
||||||
|
<summary>Run Regression Tests</summary>
|
||||||
|
<function>doRunTests</function>
|
||||||
|
<shortcut>rt</shortcut>
|
||||||
|
<options>
|
||||||
|
<recur>
|
||||||
|
<shortopt>r</shortopt>
|
||||||
|
<doc>Run tests in child directories, recursively. 4 dirs deep maximum</doc>
|
||||||
|
</recur>
|
||||||
|
<ini>
|
||||||
|
<shortopt>i</shortopt>
|
||||||
|
<doc>actual string of settings to pass to php in format " -d setting=blah"</doc>
|
||||||
|
<arg>SETTINGS</arg>
|
||||||
|
</ini>
|
||||||
|
<realtimelog>
|
||||||
|
<shortopt>l</shortopt>
|
||||||
|
<doc>Log test runs/results as they are run</doc>
|
||||||
|
</realtimelog>
|
||||||
|
<quiet>
|
||||||
|
<shortopt>q</shortopt>
|
||||||
|
<doc>Only display detail for failed tests</doc>
|
||||||
|
</quiet>
|
||||||
|
<simple>
|
||||||
|
<shortopt>s</shortopt>
|
||||||
|
<doc>Display simple output for all tests</doc>
|
||||||
|
</simple>
|
||||||
|
<package>
|
||||||
|
<shortopt>p</shortopt>
|
||||||
|
<doc>Treat parameters as installed packages from which to run tests</doc>
|
||||||
|
</package>
|
||||||
|
<phpunit>
|
||||||
|
<shortopt>u</shortopt>
|
||||||
|
<doc>Search parameters for AllTests.php, and use that to run phpunit-based tests
|
||||||
|
If none is found, all .phpt tests will be tried instead.</doc>
|
||||||
|
</phpunit>
|
||||||
|
<tapoutput>
|
||||||
|
<shortopt>t</shortopt>
|
||||||
|
<doc>Output run-tests.log in TAP-compliant format</doc>
|
||||||
|
</tapoutput>
|
||||||
|
<cgi>
|
||||||
|
<shortopt>c</shortopt>
|
||||||
|
<doc>CGI php executable (needed for tests with POST/GET section)</doc>
|
||||||
|
<arg>PHPCGI</arg>
|
||||||
|
</cgi>
|
||||||
|
<coverage>
|
||||||
|
<shortopt>x</shortopt>
|
||||||
|
<doc>Generate a code coverage report (requires Xdebug 2.0.0+)</doc>
|
||||||
|
</coverage>
|
||||||
|
</options>
|
||||||
|
<doc>[testfile|dir ...]
|
||||||
|
Run regression tests with PHP's regression testing script (run-tests.php).</doc>
|
||||||
|
</run-tests>
|
||||||
|
</commands>
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,769 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PEAR_DependencyDB, advanced installed packages dependency database
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Tomas V. V. Cox <cox@idecnet.com>
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: DependencyDB.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Needed for error handling
|
||||||
|
*/
|
||||||
|
require_once 'PEAR.php';
|
||||||
|
require_once 'PEAR/Config.php';
|
||||||
|
|
||||||
|
$GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'] = array();
|
||||||
|
/**
|
||||||
|
* Track dependency relationships between installed packages
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @author Tomas V.V.Cox <cox@idec.net.com>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
class PEAR_DependencyDB
|
||||||
|
{
|
||||||
|
// {{{ properties
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is initialized by {@link setConfig()}
|
||||||
|
* @var PEAR_Config
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $_config;
|
||||||
|
/**
|
||||||
|
* This is initialized by {@link setConfig()}
|
||||||
|
* @var PEAR_Registry
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $_registry;
|
||||||
|
/**
|
||||||
|
* Filename of the dependency DB (usually .depdb)
|
||||||
|
* @var string
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $_depdb = false;
|
||||||
|
/**
|
||||||
|
* File name of the lockfile (usually .depdblock)
|
||||||
|
* @var string
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $_lockfile = false;
|
||||||
|
/**
|
||||||
|
* Open file resource for locking the lockfile
|
||||||
|
* @var resource|false
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $_lockFp = false;
|
||||||
|
/**
|
||||||
|
* API version of this class, used to validate a file on-disk
|
||||||
|
* @var string
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $_version = '1.0';
|
||||||
|
/**
|
||||||
|
* Cached dependency database file
|
||||||
|
* @var array|null
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $_cache;
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ & singleton()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a raw dependency database. Calls setConfig() and assertDepsDB()
|
||||||
|
* @param PEAR_Config
|
||||||
|
* @param string|false full path to the dependency database, or false to use default
|
||||||
|
* @return PEAR_DependencyDB|PEAR_Error
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
function &singleton(&$config, $depdb = false)
|
||||||
|
{
|
||||||
|
$phpdir = $config->get('php_dir', null, 'pear.php.net');
|
||||||
|
if (!isset($GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'][$phpdir])) {
|
||||||
|
$a = new PEAR_DependencyDB;
|
||||||
|
$GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'][$phpdir] = &$a;
|
||||||
|
$a->setConfig($config, $depdb);
|
||||||
|
$e = $a->assertDepsDB();
|
||||||
|
if (PEAR::isError($e)) {
|
||||||
|
return $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'][$phpdir];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up the registry/location of dependency DB
|
||||||
|
* @param PEAR_Config|false
|
||||||
|
* @param string|false full path to the dependency database, or false to use default
|
||||||
|
*/
|
||||||
|
function setConfig(&$config, $depdb = false)
|
||||||
|
{
|
||||||
|
if (!$config) {
|
||||||
|
$this->_config = &PEAR_Config::singleton();
|
||||||
|
} else {
|
||||||
|
$this->_config = &$config;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->_registry = &$this->_config->getRegistry();
|
||||||
|
if (!$depdb) {
|
||||||
|
$this->_depdb = $this->_config->get('php_dir', null, 'pear.php.net') .
|
||||||
|
DIRECTORY_SEPARATOR . '.depdb';
|
||||||
|
} else {
|
||||||
|
$this->_depdb = $depdb;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->_lockfile = dirname($this->_depdb) . DIRECTORY_SEPARATOR . '.depdblock';
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
function hasWriteAccess()
|
||||||
|
{
|
||||||
|
if (!file_exists($this->_depdb)) {
|
||||||
|
$dir = $this->_depdb;
|
||||||
|
while ($dir && $dir != '.') {
|
||||||
|
$dir = dirname($dir); // cd ..
|
||||||
|
if ($dir != '.' && file_exists($dir)) {
|
||||||
|
if (is_writeable($dir)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return is_writeable($this->_depdb);
|
||||||
|
}
|
||||||
|
|
||||||
|
// {{{ assertDepsDB()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the dependency database, if it doesn't exist. Error if the database is
|
||||||
|
* newer than the code reading it.
|
||||||
|
* @return void|PEAR_Error
|
||||||
|
*/
|
||||||
|
function assertDepsDB()
|
||||||
|
{
|
||||||
|
if (!is_file($this->_depdb)) {
|
||||||
|
$this->rebuildDB();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$depdb = $this->_getDepDB();
|
||||||
|
// Datatype format has been changed, rebuild the Deps DB
|
||||||
|
if ($depdb['_version'] < $this->_version) {
|
||||||
|
$this->rebuildDB();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($depdb['_version']{0} > $this->_version{0}) {
|
||||||
|
return PEAR::raiseError('Dependency database is version ' .
|
||||||
|
$depdb['_version'] . ', and we are version ' .
|
||||||
|
$this->_version . ', cannot continue');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of installed packages that depend on this package
|
||||||
|
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array
|
||||||
|
* @return array|false
|
||||||
|
*/
|
||||||
|
function getDependentPackages(&$pkg)
|
||||||
|
{
|
||||||
|
$data = $this->_getDepDB();
|
||||||
|
if (is_object($pkg)) {
|
||||||
|
$channel = strtolower($pkg->getChannel());
|
||||||
|
$package = strtolower($pkg->getPackage());
|
||||||
|
} else {
|
||||||
|
$channel = strtolower($pkg['channel']);
|
||||||
|
$package = strtolower($pkg['package']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($data['packages'][$channel][$package])) {
|
||||||
|
return $data['packages'][$channel][$package];
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of the actual dependencies of installed packages that depend on
|
||||||
|
* a package.
|
||||||
|
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array
|
||||||
|
* @return array|false
|
||||||
|
*/
|
||||||
|
function getDependentPackageDependencies(&$pkg)
|
||||||
|
{
|
||||||
|
$data = $this->_getDepDB();
|
||||||
|
if (is_object($pkg)) {
|
||||||
|
$channel = strtolower($pkg->getChannel());
|
||||||
|
$package = strtolower($pkg->getPackage());
|
||||||
|
} else {
|
||||||
|
$channel = strtolower($pkg['channel']);
|
||||||
|
$package = strtolower($pkg['package']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$depend = $this->getDependentPackages($pkg);
|
||||||
|
if (!$depend) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$dependencies = array();
|
||||||
|
foreach ($depend as $info) {
|
||||||
|
$temp = $this->getDependencies($info);
|
||||||
|
foreach ($temp as $dep) {
|
||||||
|
if (
|
||||||
|
isset($dep['dep'], $dep['dep']['channel'], $dep['dep']['name']) &&
|
||||||
|
strtolower($dep['dep']['channel']) == $channel &&
|
||||||
|
strtolower($dep['dep']['name']) == $package
|
||||||
|
) {
|
||||||
|
if (!isset($dependencies[$info['channel']])) {
|
||||||
|
$dependencies[$info['channel']] = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($dependencies[$info['channel']][$info['package']])) {
|
||||||
|
$dependencies[$info['channel']][$info['package']] = array();
|
||||||
|
}
|
||||||
|
$dependencies[$info['channel']][$info['package']][] = $dep;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $dependencies;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of dependencies of this installed package
|
||||||
|
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array
|
||||||
|
* @return array|false
|
||||||
|
*/
|
||||||
|
function getDependencies(&$pkg)
|
||||||
|
{
|
||||||
|
if (is_object($pkg)) {
|
||||||
|
$channel = strtolower($pkg->getChannel());
|
||||||
|
$package = strtolower($pkg->getPackage());
|
||||||
|
} else {
|
||||||
|
$channel = strtolower($pkg['channel']);
|
||||||
|
$package = strtolower($pkg['package']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $this->_getDepDB();
|
||||||
|
if (isset($data['dependencies'][$channel][$package])) {
|
||||||
|
return $data['dependencies'][$channel][$package];
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether $parent depends on $child, near or deep
|
||||||
|
* @param array|PEAR_PackageFile_v2|PEAR_PackageFile_v2
|
||||||
|
* @param array|PEAR_PackageFile_v2|PEAR_PackageFile_v2
|
||||||
|
*/
|
||||||
|
function dependsOn($parent, $child)
|
||||||
|
{
|
||||||
|
$c = array();
|
||||||
|
$this->_getDepDB();
|
||||||
|
return $this->_dependsOn($parent, $child, $c);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _dependsOn($parent, $child, &$checked)
|
||||||
|
{
|
||||||
|
if (is_object($parent)) {
|
||||||
|
$channel = strtolower($parent->getChannel());
|
||||||
|
$package = strtolower($parent->getPackage());
|
||||||
|
} else {
|
||||||
|
$channel = strtolower($parent['channel']);
|
||||||
|
$package = strtolower($parent['package']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_object($child)) {
|
||||||
|
$depchannel = strtolower($child->getChannel());
|
||||||
|
$deppackage = strtolower($child->getPackage());
|
||||||
|
} else {
|
||||||
|
$depchannel = strtolower($child['channel']);
|
||||||
|
$deppackage = strtolower($child['package']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($checked[$channel][$package][$depchannel][$deppackage])) {
|
||||||
|
return false; // avoid endless recursion
|
||||||
|
}
|
||||||
|
|
||||||
|
$checked[$channel][$package][$depchannel][$deppackage] = true;
|
||||||
|
if (!isset($this->_cache['dependencies'][$channel][$package])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->_cache['dependencies'][$channel][$package] as $info) {
|
||||||
|
if (isset($info['dep']['uri'])) {
|
||||||
|
if (is_object($child)) {
|
||||||
|
if ($info['dep']['uri'] == $child->getURI()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} elseif (isset($child['uri'])) {
|
||||||
|
if ($info['dep']['uri'] == $child['uri']) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strtolower($info['dep']['channel']) == $depchannel &&
|
||||||
|
strtolower($info['dep']['name']) == $deppackage) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->_cache['dependencies'][$channel][$package] as $info) {
|
||||||
|
if (isset($info['dep']['uri'])) {
|
||||||
|
if ($this->_dependsOn(array(
|
||||||
|
'uri' => $info['dep']['uri'],
|
||||||
|
'package' => $info['dep']['name']), $child, $checked)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ($this->_dependsOn(array(
|
||||||
|
'channel' => $info['dep']['channel'],
|
||||||
|
'package' => $info['dep']['name']), $child, $checked)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register dependencies of a package that is being installed or upgraded
|
||||||
|
* @param PEAR_PackageFile_v2|PEAR_PackageFile_v2
|
||||||
|
*/
|
||||||
|
function installPackage(&$package)
|
||||||
|
{
|
||||||
|
$data = $this->_getDepDB();
|
||||||
|
unset($this->_cache);
|
||||||
|
$this->_setPackageDeps($data, $package);
|
||||||
|
$this->_writeDepDB($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove dependencies of a package that is being uninstalled, or upgraded.
|
||||||
|
*
|
||||||
|
* Upgraded packages first uninstall, then install
|
||||||
|
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array If an array, then it must have
|
||||||
|
* indices 'channel' and 'package'
|
||||||
|
*/
|
||||||
|
function uninstallPackage(&$pkg)
|
||||||
|
{
|
||||||
|
$data = $this->_getDepDB();
|
||||||
|
unset($this->_cache);
|
||||||
|
if (is_object($pkg)) {
|
||||||
|
$channel = strtolower($pkg->getChannel());
|
||||||
|
$package = strtolower($pkg->getPackage());
|
||||||
|
} else {
|
||||||
|
$channel = strtolower($pkg['channel']);
|
||||||
|
$package = strtolower($pkg['package']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($data['dependencies'][$channel][$package])) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($data['dependencies'][$channel][$package] as $dep) {
|
||||||
|
$found = false;
|
||||||
|
$depchannel = isset($dep['dep']['uri']) ? '__uri' : strtolower($dep['dep']['channel']);
|
||||||
|
$depname = strtolower($dep['dep']['name']);
|
||||||
|
if (isset($data['packages'][$depchannel][$depname])) {
|
||||||
|
foreach ($data['packages'][$depchannel][$depname] as $i => $info) {
|
||||||
|
if ($info['channel'] == $channel && $info['package'] == $package) {
|
||||||
|
$found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($found) {
|
||||||
|
unset($data['packages'][$depchannel][$depname][$i]);
|
||||||
|
if (!count($data['packages'][$depchannel][$depname])) {
|
||||||
|
unset($data['packages'][$depchannel][$depname]);
|
||||||
|
if (!count($data['packages'][$depchannel])) {
|
||||||
|
unset($data['packages'][$depchannel]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$data['packages'][$depchannel][$depname] =
|
||||||
|
array_values($data['packages'][$depchannel][$depname]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($data['dependencies'][$channel][$package]);
|
||||||
|
if (!count($data['dependencies'][$channel])) {
|
||||||
|
unset($data['dependencies'][$channel]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!count($data['dependencies'])) {
|
||||||
|
unset($data['dependencies']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!count($data['packages'])) {
|
||||||
|
unset($data['packages']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->_writeDepDB($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rebuild the dependency DB by reading registry entries.
|
||||||
|
* @return true|PEAR_Error
|
||||||
|
*/
|
||||||
|
function rebuildDB()
|
||||||
|
{
|
||||||
|
$depdb = array('_version' => $this->_version);
|
||||||
|
if (!$this->hasWriteAccess()) {
|
||||||
|
// allow startup for read-only with older Registry
|
||||||
|
return $depdb;
|
||||||
|
}
|
||||||
|
|
||||||
|
$packages = $this->_registry->listAllPackages();
|
||||||
|
if (PEAR::isError($packages)) {
|
||||||
|
return $packages;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($packages as $channel => $ps) {
|
||||||
|
foreach ($ps as $package) {
|
||||||
|
$package = $this->_registry->getPackage($package, $channel);
|
||||||
|
if (PEAR::isError($package)) {
|
||||||
|
return $package;
|
||||||
|
}
|
||||||
|
$this->_setPackageDeps($depdb, $package);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$error = $this->_writeDepDB($depdb);
|
||||||
|
if (PEAR::isError($error)) {
|
||||||
|
return $error;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->_cache = $depdb;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register usage of the dependency DB to prevent race conditions
|
||||||
|
* @param int one of the LOCK_* constants
|
||||||
|
* @return true|PEAR_Error
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _lock($mode = LOCK_EX)
|
||||||
|
{
|
||||||
|
if (stristr(php_uname(), 'Windows 9')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($mode != LOCK_UN && is_resource($this->_lockFp)) {
|
||||||
|
// XXX does not check type of lock (LOCK_SH/LOCK_EX)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$open_mode = 'w';
|
||||||
|
// XXX People reported problems with LOCK_SH and 'w'
|
||||||
|
if ($mode === LOCK_SH) {
|
||||||
|
if (!file_exists($this->_lockfile)) {
|
||||||
|
touch($this->_lockfile);
|
||||||
|
} elseif (!is_file($this->_lockfile)) {
|
||||||
|
return PEAR::raiseError('could not create Dependency lock file, ' .
|
||||||
|
'it exists and is not a regular file');
|
||||||
|
}
|
||||||
|
$open_mode = 'r';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_resource($this->_lockFp)) {
|
||||||
|
$this->_lockFp = @fopen($this->_lockfile, $open_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_resource($this->_lockFp)) {
|
||||||
|
return PEAR::raiseError("could not create Dependency lock file" .
|
||||||
|
(isset($php_errormsg) ? ": " . $php_errormsg : ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(int)flock($this->_lockFp, $mode)) {
|
||||||
|
switch ($mode) {
|
||||||
|
case LOCK_SH: $str = 'shared'; break;
|
||||||
|
case LOCK_EX: $str = 'exclusive'; break;
|
||||||
|
case LOCK_UN: $str = 'unlock'; break;
|
||||||
|
default: $str = 'unknown'; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PEAR::raiseError("could not acquire $str lock ($this->_lockfile)");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Release usage of dependency DB
|
||||||
|
* @return true|PEAR_Error
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _unlock()
|
||||||
|
{
|
||||||
|
$ret = $this->_lock(LOCK_UN);
|
||||||
|
if (is_resource($this->_lockFp)) {
|
||||||
|
fclose($this->_lockFp);
|
||||||
|
}
|
||||||
|
$this->_lockFp = null;
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the dependency database from disk, or return the cache
|
||||||
|
* @return array|PEAR_Error
|
||||||
|
*/
|
||||||
|
function _getDepDB()
|
||||||
|
{
|
||||||
|
if (!$this->hasWriteAccess()) {
|
||||||
|
return array('_version' => $this->_version);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($this->_cache)) {
|
||||||
|
return $this->_cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$fp = fopen($this->_depdb, 'r')) {
|
||||||
|
$err = PEAR::raiseError("Could not open dependencies file `".$this->_depdb."'");
|
||||||
|
return $err;
|
||||||
|
}
|
||||||
|
|
||||||
|
$rt = get_magic_quotes_runtime();
|
||||||
|
set_magic_quotes_runtime(0);
|
||||||
|
clearstatcache();
|
||||||
|
fclose($fp);
|
||||||
|
$data = unserialize(file_get_contents($this->_depdb));
|
||||||
|
set_magic_quotes_runtime($rt);
|
||||||
|
$this->_cache = $data;
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write out the dependency database to disk
|
||||||
|
* @param array the database
|
||||||
|
* @return true|PEAR_Error
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _writeDepDB(&$deps)
|
||||||
|
{
|
||||||
|
if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
|
||||||
|
return $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$fp = fopen($this->_depdb, 'wb')) {
|
||||||
|
$this->_unlock();
|
||||||
|
return PEAR::raiseError("Could not open dependencies file `".$this->_depdb."' for writing");
|
||||||
|
}
|
||||||
|
|
||||||
|
$rt = get_magic_quotes_runtime();
|
||||||
|
set_magic_quotes_runtime(0);
|
||||||
|
fwrite($fp, serialize($deps));
|
||||||
|
set_magic_quotes_runtime($rt);
|
||||||
|
fclose($fp);
|
||||||
|
$this->_unlock();
|
||||||
|
$this->_cache = $deps;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register all dependencies from a package in the dependencies database, in essence
|
||||||
|
* "installing" the package's dependency information
|
||||||
|
* @param array the database
|
||||||
|
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _setPackageDeps(&$data, &$pkg)
|
||||||
|
{
|
||||||
|
$pkg->setConfig($this->_config);
|
||||||
|
if ($pkg->getPackagexmlVersion() == '1.0') {
|
||||||
|
$gen = &$pkg->getDefaultGenerator();
|
||||||
|
$deps = $gen->dependenciesToV2();
|
||||||
|
} else {
|
||||||
|
$deps = $pkg->getDeps(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$deps) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($data)) {
|
||||||
|
$data = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($data['dependencies'])) {
|
||||||
|
$data['dependencies'] = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$channel = strtolower($pkg->getChannel());
|
||||||
|
$package = strtolower($pkg->getPackage());
|
||||||
|
|
||||||
|
if (!isset($data['dependencies'][$channel])) {
|
||||||
|
$data['dependencies'][$channel] = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$data['dependencies'][$channel][$package] = array();
|
||||||
|
if (isset($deps['required']['package'])) {
|
||||||
|
if (!isset($deps['required']['package'][0])) {
|
||||||
|
$deps['required']['package'] = array($deps['required']['package']);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($deps['required']['package'] as $dep) {
|
||||||
|
$this->_registerDep($data, $pkg, $dep, 'required');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($deps['optional']['package'])) {
|
||||||
|
if (!isset($deps['optional']['package'][0])) {
|
||||||
|
$deps['optional']['package'] = array($deps['optional']['package']);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($deps['optional']['package'] as $dep) {
|
||||||
|
$this->_registerDep($data, $pkg, $dep, 'optional');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($deps['required']['subpackage'])) {
|
||||||
|
if (!isset($deps['required']['subpackage'][0])) {
|
||||||
|
$deps['required']['subpackage'] = array($deps['required']['subpackage']);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($deps['required']['subpackage'] as $dep) {
|
||||||
|
$this->_registerDep($data, $pkg, $dep, 'required');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($deps['optional']['subpackage'])) {
|
||||||
|
if (!isset($deps['optional']['subpackage'][0])) {
|
||||||
|
$deps['optional']['subpackage'] = array($deps['optional']['subpackage']);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($deps['optional']['subpackage'] as $dep) {
|
||||||
|
$this->_registerDep($data, $pkg, $dep, 'optional');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($deps['group'])) {
|
||||||
|
if (!isset($deps['group'][0])) {
|
||||||
|
$deps['group'] = array($deps['group']);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($deps['group'] as $group) {
|
||||||
|
if (isset($group['package'])) {
|
||||||
|
if (!isset($group['package'][0])) {
|
||||||
|
$group['package'] = array($group['package']);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($group['package'] as $dep) {
|
||||||
|
$this->_registerDep($data, $pkg, $dep, 'optional',
|
||||||
|
$group['attribs']['name']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($group['subpackage'])) {
|
||||||
|
if (!isset($group['subpackage'][0])) {
|
||||||
|
$group['subpackage'] = array($group['subpackage']);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($group['subpackage'] as $dep) {
|
||||||
|
$this->_registerDep($data, $pkg, $dep, 'optional',
|
||||||
|
$group['attribs']['name']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($data['dependencies'][$channel][$package] == array()) {
|
||||||
|
unset($data['dependencies'][$channel][$package]);
|
||||||
|
if (!count($data['dependencies'][$channel])) {
|
||||||
|
unset($data['dependencies'][$channel]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array the database
|
||||||
|
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
|
||||||
|
* @param array the specific dependency
|
||||||
|
* @param required|optional whether this is a required or an optional dep
|
||||||
|
* @param string|false dependency group this dependency is from, or false for ordinary dep
|
||||||
|
*/
|
||||||
|
function _registerDep(&$data, &$pkg, $dep, $type, $group = false)
|
||||||
|
{
|
||||||
|
$info = array(
|
||||||
|
'dep' => $dep,
|
||||||
|
'type' => $type,
|
||||||
|
'group' => $group
|
||||||
|
);
|
||||||
|
|
||||||
|
$dep = array_map('strtolower', $dep);
|
||||||
|
$depchannel = isset($dep['channel']) ? $dep['channel'] : '__uri';
|
||||||
|
if (!isset($data['dependencies'])) {
|
||||||
|
$data['dependencies'] = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$channel = strtolower($pkg->getChannel());
|
||||||
|
$package = strtolower($pkg->getPackage());
|
||||||
|
|
||||||
|
if (!isset($data['dependencies'][$channel])) {
|
||||||
|
$data['dependencies'][$channel] = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($data['dependencies'][$channel][$package])) {
|
||||||
|
$data['dependencies'][$channel][$package] = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$data['dependencies'][$channel][$package][] = $info;
|
||||||
|
if (isset($data['packages'][$depchannel][$dep['name']])) {
|
||||||
|
$found = false;
|
||||||
|
foreach ($data['packages'][$depchannel][$dep['name']] as $i => $p) {
|
||||||
|
if ($p['channel'] == $channel && $p['package'] == $package) {
|
||||||
|
$found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!isset($data['packages'])) {
|
||||||
|
$data['packages'] = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($data['packages'][$depchannel])) {
|
||||||
|
$data['packages'][$depchannel] = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($data['packages'][$depchannel][$dep['name']])) {
|
||||||
|
$data['packages'][$depchannel][$dep['name']] = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$found = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$found) {
|
||||||
|
$data['packages'][$depchannel][$dep['name']][] = array(
|
||||||
|
'channel' => $channel,
|
||||||
|
'package' => $package
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,24 +1,4 @@
|
||||||
<?php
|
<?php
|
||||||
//
|
|
||||||
// +----------------------------------------------------------------------+
|
|
||||||
// | PHP Version 5 |
|
|
||||||
// +----------------------------------------------------------------------+
|
|
||||||
// | Copyright (c) 1997-2004 The PHP Group |
|
|
||||||
// +----------------------------------------------------------------------+
|
|
||||||
// | This source file is subject to version 3.0 of the PHP license, |
|
|
||||||
// | that is bundled with this package in the file LICENSE, and is |
|
|
||||||
// | available through the world-wide-web at the following url: |
|
|
||||||
// | http://www.php.net/license/3_0.txt. |
|
|
||||||
// | If you did not receive a copy of the PHP license and are unable to |
|
|
||||||
// | obtain it through the world-wide-web, please send a note to |
|
|
||||||
// | license@php.net so we can mail you a copy immediately. |
|
|
||||||
// +----------------------------------------------------------------------+
|
|
||||||
// | Author: Gregory Beaver <cellog@php.net> |
|
|
||||||
// | |
|
|
||||||
// +----------------------------------------------------------------------+
|
|
||||||
//
|
|
||||||
// $Id: ErrorStack.php,v 1.7.2.5 2005/01/01 21:26:51 cellog Exp $
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Error Stack Implementation
|
* Error Stack Implementation
|
||||||
*
|
*
|
||||||
|
@ -38,11 +18,13 @@
|
||||||
*
|
*
|
||||||
* Since version PEAR1.3.2, ErrorStack no longer instantiates an exception class. This can
|
* Since version PEAR1.3.2, ErrorStack no longer instantiates an exception class. This can
|
||||||
* still be done quite handily in an error callback or by manipulating the returned array
|
* still be done quite handily in an error callback or by manipulating the returned array
|
||||||
* @author Greg Beaver <cellog@php.net>
|
|
||||||
* @version PEAR1.3.2 (beta)
|
|
||||||
* @package PEAR_ErrorStack
|
|
||||||
* @category Debugging
|
* @category Debugging
|
||||||
* @license http://www.php.net/license/3_0.txt PHP License v3.0
|
* @package PEAR_ErrorStack
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 2004-2008 Greg Beaver
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: ErrorStack.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR_ErrorStack
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -149,9 +131,14 @@ define('PEAR_ERRORSTACK_ERR_OBJTOSTRING', 2);
|
||||||
* // local error stack
|
* // local error stack
|
||||||
* $local_stack = new PEAR_ErrorStack('MyPackage');
|
* $local_stack = new PEAR_ErrorStack('MyPackage');
|
||||||
* </code>
|
* </code>
|
||||||
* @copyright 2004 Gregory Beaver
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @version 1.9.4
|
||||||
* @package PEAR_ErrorStack
|
* @package PEAR_ErrorStack
|
||||||
* @license http://www.php.net/license/3_0.txt PHP License
|
* @category Debugging
|
||||||
|
* @copyright 2004-2008 Greg Beaver
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: ErrorStack.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR_ErrorStack
|
||||||
*/
|
*/
|
||||||
class PEAR_ErrorStack {
|
class PEAR_ErrorStack {
|
||||||
/**
|
/**
|
||||||
|
@ -281,8 +268,10 @@ class PEAR_ErrorStack {
|
||||||
'stack class "%stackclass%" is not a valid class name (should be like PEAR_ErrorStack)',
|
'stack class "%stackclass%" is not a valid class name (should be like PEAR_ErrorStack)',
|
||||||
false, $trace);
|
false, $trace);
|
||||||
}
|
}
|
||||||
return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package] =
|
$GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package] =
|
||||||
&new $stackClass($package, $msgCallback, $contextCallback, $throwPEAR_Error);
|
new $stackClass($package, $msgCallback, $contextCallback, $throwPEAR_Error);
|
||||||
|
|
||||||
|
return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -487,19 +476,10 @@ class PEAR_ErrorStack {
|
||||||
* @param array $backtrace Protected parameter: use this to pass in the
|
* @param array $backtrace Protected parameter: use this to pass in the
|
||||||
* {@link debug_backtrace()} that should be used
|
* {@link debug_backtrace()} that should be used
|
||||||
* to find error context
|
* to find error context
|
||||||
* @return PEAR_Error|array|Exception
|
* @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also
|
||||||
* if compatibility mode is on, a PEAR_Error is also
|
* thrown. If a PEAR_Error is returned, the userinfo
|
||||||
* thrown. If the class Exception exists, then one
|
* property is set to the following array:
|
||||||
* is returned to allow code like:
|
|
||||||
* <code>
|
|
||||||
* throw ($stack->push(MY_ERROR_CODE, 'error', array('username' => 'grob')));
|
|
||||||
* </code>
|
|
||||||
*
|
*
|
||||||
* The errorData property of the exception class will be set to the array
|
|
||||||
* that would normally be returned. If a PEAR_Error is returned, the userinfo
|
|
||||||
* property is set to the array
|
|
||||||
*
|
|
||||||
* Otherwise, an array is returned in this format:
|
|
||||||
* <code>
|
* <code>
|
||||||
* array(
|
* array(
|
||||||
* 'code' => $code,
|
* 'code' => $code,
|
||||||
|
@ -512,6 +492,8 @@ class PEAR_ErrorStack {
|
||||||
* //['repackage' => $err] repackaged error array/Exception class
|
* //['repackage' => $err] repackaged error array/Exception class
|
||||||
* );
|
* );
|
||||||
* </code>
|
* </code>
|
||||||
|
*
|
||||||
|
* Normally, the previous array is returned.
|
||||||
*/
|
*/
|
||||||
function push($code, $level = 'error', $params = array(), $msg = false,
|
function push($code, $level = 'error', $params = array(), $msg = false,
|
||||||
$repackage = false, $backtrace = false)
|
$repackage = false, $backtrace = false)
|
||||||
|
@ -538,16 +520,16 @@ class PEAR_ErrorStack {
|
||||||
'message' => $msg,
|
'message' => $msg,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if ($repackage) {
|
||||||
|
$err['repackage'] = $repackage;
|
||||||
|
}
|
||||||
|
|
||||||
// set up the error message, if necessary
|
// set up the error message, if necessary
|
||||||
if ($this->_msgCallback) {
|
if ($this->_msgCallback) {
|
||||||
$msg = call_user_func_array($this->_msgCallback,
|
$msg = call_user_func_array($this->_msgCallback,
|
||||||
array(&$this, $err));
|
array(&$this, $err));
|
||||||
$err['message'] = $msg;
|
$err['message'] = $msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($repackage) {
|
|
||||||
$err['repackage'] = $repackage;
|
|
||||||
}
|
|
||||||
$push = $log = true;
|
$push = $log = true;
|
||||||
$die = false;
|
$die = false;
|
||||||
// try the overriding callback first
|
// try the overriding callback first
|
||||||
|
@ -586,6 +568,9 @@ class PEAR_ErrorStack {
|
||||||
}
|
}
|
||||||
if ($push) {
|
if ($push) {
|
||||||
array_unshift($this->_errors, $err);
|
array_unshift($this->_errors, $err);
|
||||||
|
if (!isset($this->_errorsByLevel[$err['level']])) {
|
||||||
|
$this->_errorsByLevel[$err['level']] = array();
|
||||||
|
}
|
||||||
$this->_errorsByLevel[$err['level']][] = &$this->_errors[0];
|
$this->_errorsByLevel[$err['level']][] = &$this->_errors[0];
|
||||||
}
|
}
|
||||||
if ($log) {
|
if ($log) {
|
||||||
|
@ -617,13 +602,8 @@ class PEAR_ErrorStack {
|
||||||
* @param array $backtrace Protected parameter: use this to pass in the
|
* @param array $backtrace Protected parameter: use this to pass in the
|
||||||
* {@link debug_backtrace()} that should be used
|
* {@link debug_backtrace()} that should be used
|
||||||
* to find error context
|
* to find error context
|
||||||
* @return PEAR_Error|null|Exception
|
* @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also
|
||||||
* if compatibility mode is on, a PEAR_Error is also
|
* thrown. see docs for {@link push()}
|
||||||
* thrown. If the class Exception exists, then one
|
|
||||||
* is returned to allow code like:
|
|
||||||
* <code>
|
|
||||||
* throw ($stack->push(MY_ERROR_CODE, 'error', array('username' => 'grob')));
|
|
||||||
* </code>
|
|
||||||
* @static
|
* @static
|
||||||
*/
|
*/
|
||||||
function staticPush($package, $code, $level = 'error', $params = array(),
|
function staticPush($package, $code, $level = 'error', $params = array(),
|
||||||
|
@ -684,7 +664,31 @@ class PEAR_ErrorStack {
|
||||||
*/
|
*/
|
||||||
function pop()
|
function pop()
|
||||||
{
|
{
|
||||||
return @array_shift($this->_errors);
|
$err = @array_shift($this->_errors);
|
||||||
|
if (!is_null($err)) {
|
||||||
|
@array_pop($this->_errorsByLevel[$err['level']]);
|
||||||
|
if (!count($this->_errorsByLevel[$err['level']])) {
|
||||||
|
unset($this->_errorsByLevel[$err['level']]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pop an error off of the error stack, static method
|
||||||
|
*
|
||||||
|
* @param string package name
|
||||||
|
* @return boolean
|
||||||
|
* @since PEAR1.5.0a1
|
||||||
|
*/
|
||||||
|
function staticPop($package)
|
||||||
|
{
|
||||||
|
if ($package) {
|
||||||
|
if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->pop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -853,7 +857,7 @@ class PEAR_ErrorStack {
|
||||||
'line' => $filebacktrace['line']);
|
'line' => $filebacktrace['line']);
|
||||||
// rearrange for eval'd code or create function errors
|
// rearrange for eval'd code or create function errors
|
||||||
if (strpos($filebacktrace['file'], '(') &&
|
if (strpos($filebacktrace['file'], '(') &&
|
||||||
preg_match(';^(.*?)\((\d+)\) : (.*?)$;', $filebacktrace['file'],
|
preg_match(';^(.*?)\((\d+)\) : (.*?)\\z;', $filebacktrace['file'],
|
||||||
$matches)) {
|
$matches)) {
|
||||||
$ret['file'] = $matches[1];
|
$ret['file'] = $matches[1];
|
||||||
$ret['line'] = $matches[2] + 0;
|
$ret['line'] = $matches[2] + 0;
|
||||||
|
@ -910,7 +914,7 @@ class PEAR_ErrorStack {
|
||||||
$mainmsg = $stack->getErrorMessageTemplate($err['code']);
|
$mainmsg = $stack->getErrorMessageTemplate($err['code']);
|
||||||
}
|
}
|
||||||
$mainmsg = str_replace('%__msg%', $err['message'], $mainmsg);
|
$mainmsg = str_replace('%__msg%', $err['message'], $mainmsg);
|
||||||
if (count($err['params'])) {
|
if (is_array($err['params']) && count($err['params'])) {
|
||||||
foreach ($err['params'] as $name => $val) {
|
foreach ($err['params'] as $name => $val) {
|
||||||
if (is_array($val)) {
|
if (is_array($val)) {
|
||||||
// @ is needed in case $val is a multi-dimensional array
|
// @ is needed in case $val is a multi-dimensional array
|
||||||
|
|
|
@ -1,34 +1,27 @@
|
||||||
<?php
|
<?php
|
||||||
/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
|
/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
|
||||||
// +----------------------------------------------------------------------+
|
/**
|
||||||
// | PEAR_Exception |
|
* PEAR_Exception
|
||||||
// +----------------------------------------------------------------------+
|
*
|
||||||
// | Copyright (c) 2004 The PEAR Group |
|
* PHP versions 4 and 5
|
||||||
// +----------------------------------------------------------------------+
|
*
|
||||||
// | This source file is subject to version 3.0 of the PHP license, |
|
* @category pear
|
||||||
// | that is bundled with this package in the file LICENSE, and is |
|
* @package PEAR
|
||||||
// | available at through the world-wide-web at |
|
* @author Tomas V. V. Cox <cox@idecnet.com>
|
||||||
// | http://www.php.net/license/3_0.txt. |
|
* @author Hans Lellelid <hans@velum.net>
|
||||||
// | If you did not receive a copy of the PHP license and are unable to |
|
* @author Bertrand Mansion <bmansion@mamasam.com>
|
||||||
// | obtain it through the world-wide-web, please send a note to |
|
* @author Greg Beaver <cellog@php.net>
|
||||||
// | license@php.net so we can mail you a copy immediately. |
|
* @copyright 1997-2009 The Authors
|
||||||
// +----------------------------------------------------------------------+
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
// | Authors: Tomas V.V.Cox <cox@idecnet.com> |
|
* @version CVS: $Id: Exception.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
// | Hans Lellelid <hans@velum.net> |
|
* @link http://pear.php.net/package/PEAR
|
||||||
// | Bertrand Mansion <bmansion@mamasam.com> |
|
* @since File available since Release 1.3.3
|
||||||
// | Greg Beaver <cellog@php.net> |
|
*/
|
||||||
// +----------------------------------------------------------------------+
|
|
||||||
//
|
|
||||||
// $Id: Exception.php,v 1.4.2.2 2004/12/31 19:01:52 cellog Exp $
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base PEAR_Exception Class
|
* Base PEAR_Exception Class
|
||||||
*
|
*
|
||||||
* WARNING: This code should be considered stable, but the API is
|
|
||||||
* subject to immediate and drastic change, so API stability is
|
|
||||||
* at best alpha
|
|
||||||
*
|
|
||||||
* 1) Features:
|
* 1) Features:
|
||||||
*
|
*
|
||||||
* - Nestable exceptions (throw new PEAR_Exception($msg, $prev_exception))
|
* - Nestable exceptions (throw new PEAR_Exception($msg, $prev_exception))
|
||||||
|
@ -88,12 +81,17 @@
|
||||||
* }
|
* }
|
||||||
* </code>
|
* </code>
|
||||||
*
|
*
|
||||||
* @since PHP 5
|
* @category pear
|
||||||
* @package PEAR
|
* @package PEAR
|
||||||
* @version $Revision: 1.4.2.2 $
|
|
||||||
* @author Tomas V.V.Cox <cox@idecnet.com>
|
* @author Tomas V.V.Cox <cox@idecnet.com>
|
||||||
* @author Hans Lellelid <hans@velum.net>
|
* @author Hans Lellelid <hans@velum.net>
|
||||||
* @author Bertrand Mansion <bmansion@mamasam.com>
|
* @author Bertrand Mansion <bmansion@mamasam.com>
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 1.3.3
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class PEAR_Exception extends Exception
|
class PEAR_Exception extends Exception
|
||||||
|
@ -108,19 +106,31 @@ class PEAR_Exception extends Exception
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Supported signatures:
|
* Supported signatures:
|
||||||
* PEAR_Exception(string $message);
|
* - PEAR_Exception(string $message);
|
||||||
* PEAR_Exception(string $message, int $code);
|
* - PEAR_Exception(string $message, int $code);
|
||||||
* PEAR_Exception(string $message, Exception $cause);
|
* - PEAR_Exception(string $message, Exception $cause);
|
||||||
* PEAR_Exception(string $message, Exception $cause, int $code);
|
* - PEAR_Exception(string $message, Exception $cause, int $code);
|
||||||
* PEAR_Exception(string $message, array $causes);
|
* - PEAR_Exception(string $message, PEAR_Error $cause);
|
||||||
* PEAR_Exception(string $message, array $causes, int $code);
|
* - PEAR_Exception(string $message, PEAR_Error $cause, int $code);
|
||||||
|
* - PEAR_Exception(string $message, array $causes);
|
||||||
|
* - PEAR_Exception(string $message, array $causes, int $code);
|
||||||
|
* @param string exception message
|
||||||
|
* @param int|Exception|PEAR_Error|array|null exception cause
|
||||||
|
* @param int|null exception code or null
|
||||||
*/
|
*/
|
||||||
public function __construct($message, $p2 = null, $p3 = null)
|
public function __construct($message, $p2 = null, $p3 = null)
|
||||||
{
|
{
|
||||||
if (is_int($p2)) {
|
if (is_int($p2)) {
|
||||||
$code = $p2;
|
$code = $p2;
|
||||||
$this->cause = null;
|
$this->cause = null;
|
||||||
} elseif ($p2 instanceof Exception || is_array($p2)) {
|
} elseif (is_object($p2) || is_array($p2)) {
|
||||||
|
// using is_object allows both Exception and PEAR_Error
|
||||||
|
if (is_object($p2) && !($p2 instanceof Exception)) {
|
||||||
|
if (!class_exists('PEAR_Error') || !($p2 instanceof PEAR_Error)) {
|
||||||
|
throw new PEAR_Exception('exception cause must be Exception, ' .
|
||||||
|
'array, or PEAR_Error');
|
||||||
|
}
|
||||||
|
}
|
||||||
$code = $p3;
|
$code = $p3;
|
||||||
if (is_array($p2) && isset($p2['message'])) {
|
if (is_array($p2) && isset($p2['message'])) {
|
||||||
// fix potential problem of passing in a single warning
|
// fix potential problem of passing in a single warning
|
||||||
|
@ -234,13 +244,33 @@ class PEAR_Exception extends Exception
|
||||||
$cause['line'] = $trace[0]['line'];
|
$cause['line'] = $trace[0]['line'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$causes[] = $cause;
|
||||||
if ($this->cause instanceof PEAR_Exception) {
|
if ($this->cause instanceof PEAR_Exception) {
|
||||||
$this->cause->getCauseMessage($causes);
|
$this->cause->getCauseMessage($causes);
|
||||||
}
|
} elseif ($this->cause instanceof Exception) {
|
||||||
if (is_array($this->cause)) {
|
$causes[] = array('class' => get_class($this->cause),
|
||||||
|
'message' => $this->cause->getMessage(),
|
||||||
|
'file' => $this->cause->getFile(),
|
||||||
|
'line' => $this->cause->getLine());
|
||||||
|
} elseif (class_exists('PEAR_Error') && $this->cause instanceof PEAR_Error) {
|
||||||
|
$causes[] = array('class' => get_class($this->cause),
|
||||||
|
'message' => $this->cause->getMessage(),
|
||||||
|
'file' => 'unknown',
|
||||||
|
'line' => 'unknown');
|
||||||
|
} elseif (is_array($this->cause)) {
|
||||||
foreach ($this->cause as $cause) {
|
foreach ($this->cause as $cause) {
|
||||||
if ($cause instanceof PEAR_Exception) {
|
if ($cause instanceof PEAR_Exception) {
|
||||||
$cause->getCauseMessage($causes);
|
$cause->getCauseMessage($causes);
|
||||||
|
} elseif ($cause instanceof Exception) {
|
||||||
|
$causes[] = array('class' => get_class($cause),
|
||||||
|
'message' => $cause->getMessage(),
|
||||||
|
'file' => $cause->getFile(),
|
||||||
|
'line' => $cause->getLine());
|
||||||
|
} elseif (class_exists('PEAR_Error') && $cause instanceof PEAR_Error) {
|
||||||
|
$causes[] = array('class' => get_class($cause),
|
||||||
|
'message' => $cause->getMessage(),
|
||||||
|
'file' => 'unknown',
|
||||||
|
'line' => 'unknown');
|
||||||
} elseif (is_array($cause) && isset($cause['message'])) {
|
} elseif (is_array($cause) && isset($cause['message'])) {
|
||||||
// PEAR_ErrorStack warning
|
// PEAR_ErrorStack warning
|
||||||
$causes[] = array(
|
$causes[] = array(
|
||||||
|
@ -295,21 +325,21 @@ class PEAR_Exception extends Exception
|
||||||
$trace = $this->getTraceSafe();
|
$trace = $this->getTraceSafe();
|
||||||
$causes = array();
|
$causes = array();
|
||||||
$this->getCauseMessage($causes);
|
$this->getCauseMessage($causes);
|
||||||
$html = '<table border="1" cellspacing="0">' . "\n";
|
$html = '<table style="border: 1px" cellspacing="0">' . "\n";
|
||||||
foreach ($causes as $i => $cause) {
|
foreach ($causes as $i => $cause) {
|
||||||
$html .= '<tr><td colspan="3" bgcolor="#ff9999">'
|
$html .= '<tr><td colspan="3" style="background: #ff9999">'
|
||||||
. str_repeat('-', $i) . ' <b>' . $cause['class'] . '</b>: '
|
. str_repeat('-', $i) . ' <b>' . $cause['class'] . '</b>: '
|
||||||
. htmlspecialchars($cause['message']) . ' in <b>' . $cause['file'] . '</b> '
|
. htmlspecialchars($cause['message']) . ' in <b>' . $cause['file'] . '</b> '
|
||||||
. 'on line <b>' . $cause['line'] . '</b>'
|
. 'on line <b>' . $cause['line'] . '</b>'
|
||||||
. "</td></tr>\n";
|
. "</td></tr>\n";
|
||||||
}
|
}
|
||||||
$html .= '<tr><td colspan="3" bgcolor="#aaaaaa" align="center"><b>Exception trace</b></td></tr>' . "\n"
|
$html .= '<tr><td colspan="3" style="background-color: #aaaaaa; text-align: center; font-weight: bold;">Exception trace</td></tr>' . "\n"
|
||||||
. '<tr><td align="center" bgcolor="#cccccc" width="20"><b>#</b></td>'
|
. '<tr><td style="text-align: center; background: #cccccc; width:20px; font-weight: bold;">#</td>'
|
||||||
. '<td align="center" bgcolor="#cccccc"><b>Function</b></td>'
|
. '<td style="text-align: center; background: #cccccc; font-weight: bold;">Function</td>'
|
||||||
. '<td align="center" bgcolor="#cccccc"><b>Location</b></td></tr>' . "\n";
|
. '<td style="text-align: center; background: #cccccc; font-weight: bold;">Location</td></tr>' . "\n";
|
||||||
|
|
||||||
foreach ($trace as $k => $v) {
|
foreach ($trace as $k => $v) {
|
||||||
$html .= '<tr><td align="center">' . $k . '</td>'
|
$html .= '<tr><td style="text-align: center;">' . $k . '</td>'
|
||||||
. '<td>';
|
. '<td>';
|
||||||
if (!empty($v['class'])) {
|
if (!empty($v['class'])) {
|
||||||
$html .= $v['class'] . $v['type'];
|
$html .= $v['class'] . $v['type'];
|
||||||
|
@ -333,9 +363,11 @@ class PEAR_Exception extends Exception
|
||||||
}
|
}
|
||||||
$html .= '(' . implode(', ',$args) . ')'
|
$html .= '(' . implode(', ',$args) . ')'
|
||||||
. '</td>'
|
. '</td>'
|
||||||
. '<td>' . $v['file'] . ':' . $v['line'] . '</td></tr>' . "\n";
|
. '<td>' . (isset($v['file']) ? $v['file'] : 'unknown')
|
||||||
|
. ':' . (isset($v['line']) ? $v['line'] : 'unknown')
|
||||||
|
. '</td></tr>' . "\n";
|
||||||
}
|
}
|
||||||
$html .= '<tr><td align="center">' . ($k+1) . '</td>'
|
$html .= '<tr><td style="text-align: center;">' . ($k+1) . '</td>'
|
||||||
. '<td>{main}</td>'
|
. '<td>{main}</td>'
|
||||||
. '<td> </td></tr>' . "\n"
|
. '<td> </td></tr>' . "\n"
|
||||||
. '</table>';
|
. '</table>';
|
||||||
|
@ -355,5 +387,3 @@ class PEAR_Exception extends Exception
|
||||||
return $causeMsg . $this->getTraceAsString();
|
return $causeMsg . $this->getTraceAsString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?php
|
||||||
|
if ($skipmsg) {
|
||||||
|
$a = &new $ec($code, $mode, $options, $userinfo);
|
||||||
|
} else {
|
||||||
|
$a = &new $ec($message, $code, $mode, $options, $userinfo);
|
||||||
|
}
|
||||||
|
?>
|
|
@ -0,0 +1,228 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PEAR_Frontend, the singleton-based frontend for user input/output
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: Frontend.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include error handling
|
||||||
|
*/
|
||||||
|
//require_once 'PEAR.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Which user interface class is being used.
|
||||||
|
* @var string class name
|
||||||
|
*/
|
||||||
|
$GLOBALS['_PEAR_FRONTEND_CLASS'] = 'PEAR_Frontend_CLI';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instance of $_PEAR_Command_uiclass.
|
||||||
|
* @var object
|
||||||
|
*/
|
||||||
|
$GLOBALS['_PEAR_FRONTEND_SINGLETON'] = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Singleton-based frontend for PEAR user input/output
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
class PEAR_Frontend extends PEAR
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Retrieve the frontend object
|
||||||
|
* @return PEAR_Frontend_CLI|PEAR_Frontend_Web|PEAR_Frontend_Gtk
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
function &singleton($type = null)
|
||||||
|
{
|
||||||
|
if ($type === null) {
|
||||||
|
if (!isset($GLOBALS['_PEAR_FRONTEND_SINGLETON'])) {
|
||||||
|
$a = false;
|
||||||
|
return $a;
|
||||||
|
}
|
||||||
|
return $GLOBALS['_PEAR_FRONTEND_SINGLETON'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$a = PEAR_Frontend::setFrontendClass($type);
|
||||||
|
return $a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the frontend class that will be used by calls to {@link singleton()}
|
||||||
|
*
|
||||||
|
* Frontends are expected to conform to the PEAR naming standard of
|
||||||
|
* _ => DIRECTORY_SEPARATOR (PEAR_Frontend_CLI is in PEAR/Frontend/CLI.php)
|
||||||
|
* @param string $uiclass full class name
|
||||||
|
* @return PEAR_Frontend
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
function &setFrontendClass($uiclass)
|
||||||
|
{
|
||||||
|
if (is_object($GLOBALS['_PEAR_FRONTEND_SINGLETON']) &&
|
||||||
|
is_a($GLOBALS['_PEAR_FRONTEND_SINGLETON'], $uiclass)) {
|
||||||
|
return $GLOBALS['_PEAR_FRONTEND_SINGLETON'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!class_exists($uiclass)) {
|
||||||
|
$file = str_replace('_', '/', $uiclass) . '.php';
|
||||||
|
if (PEAR_Frontend::isIncludeable($file)) {
|
||||||
|
include_once $file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (class_exists($uiclass)) {
|
||||||
|
$obj = &new $uiclass;
|
||||||
|
// quick test to see if this class implements a few of the most
|
||||||
|
// important frontend methods
|
||||||
|
if (is_a($obj, 'PEAR_Frontend')) {
|
||||||
|
$GLOBALS['_PEAR_FRONTEND_SINGLETON'] = &$obj;
|
||||||
|
$GLOBALS['_PEAR_FRONTEND_CLASS'] = $uiclass;
|
||||||
|
return $obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
$err = PEAR::raiseError("not a frontend class: $uiclass");
|
||||||
|
return $err;
|
||||||
|
}
|
||||||
|
|
||||||
|
$err = PEAR::raiseError("no such class: $uiclass");
|
||||||
|
return $err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the frontend class that will be used by calls to {@link singleton()}
|
||||||
|
*
|
||||||
|
* Frontends are expected to be a descendant of PEAR_Frontend
|
||||||
|
* @param PEAR_Frontend
|
||||||
|
* @return PEAR_Frontend
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
function &setFrontendObject($uiobject)
|
||||||
|
{
|
||||||
|
if (is_object($GLOBALS['_PEAR_FRONTEND_SINGLETON']) &&
|
||||||
|
is_a($GLOBALS['_PEAR_FRONTEND_SINGLETON'], get_class($uiobject))) {
|
||||||
|
return $GLOBALS['_PEAR_FRONTEND_SINGLETON'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_a($uiobject, 'PEAR_Frontend')) {
|
||||||
|
$err = PEAR::raiseError('not a valid frontend class: (' .
|
||||||
|
get_class($uiobject) . ')');
|
||||||
|
return $err;
|
||||||
|
}
|
||||||
|
|
||||||
|
$GLOBALS['_PEAR_FRONTEND_SINGLETON'] = &$uiobject;
|
||||||
|
$GLOBALS['_PEAR_FRONTEND_CLASS'] = get_class($uiobject);
|
||||||
|
return $uiobject;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $path relative or absolute include path
|
||||||
|
* @return boolean
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
function isIncludeable($path)
|
||||||
|
{
|
||||||
|
if (file_exists($path) && is_readable($path)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$fp = @fopen($path, 'r', true);
|
||||||
|
if ($fp) {
|
||||||
|
fclose($fp);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param PEAR_Config
|
||||||
|
*/
|
||||||
|
function setConfig(&$config)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This can be overridden to allow session-based temporary file management
|
||||||
|
*
|
||||||
|
* By default, all files are deleted at the end of a session. The web installer
|
||||||
|
* needs to be able to sustain a list over many sessions in order to support
|
||||||
|
* user interaction with install scripts
|
||||||
|
*/
|
||||||
|
function addTempFile($file)
|
||||||
|
{
|
||||||
|
$GLOBALS['_PEAR_Common_tempfiles'][] = $file;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log an action
|
||||||
|
*
|
||||||
|
* @param string $msg the message to log
|
||||||
|
* @param boolean $append_crlf
|
||||||
|
* @return boolean true
|
||||||
|
* @abstract
|
||||||
|
*/
|
||||||
|
function log($msg, $append_crlf = true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run a post-installation script
|
||||||
|
*
|
||||||
|
* @param array $scripts array of post-install scripts
|
||||||
|
* @abstract
|
||||||
|
*/
|
||||||
|
function runPostinstallScripts(&$scripts)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display human-friendly output formatted depending on the
|
||||||
|
* $command parameter.
|
||||||
|
*
|
||||||
|
* This should be able to handle basic output data with no command
|
||||||
|
* @param mixed $data data structure containing the information to display
|
||||||
|
* @param string $command command from which this method was called
|
||||||
|
* @abstract
|
||||||
|
*/
|
||||||
|
function outputData($data, $command = '_default')
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a modal form dialog and return the given input
|
||||||
|
*
|
||||||
|
* A frontend that requires multiple requests to retrieve and process
|
||||||
|
* data must take these needs into account, and implement the request
|
||||||
|
* handling code.
|
||||||
|
* @param string $command command from which this method was called
|
||||||
|
* @param array $prompts associative array. keys are the input field names
|
||||||
|
* and values are the description
|
||||||
|
* @param array $types array of input field types (text, password,
|
||||||
|
* etc.) keys have to be the same like in $prompts
|
||||||
|
* @param array $defaults array of default values. again keys have
|
||||||
|
* to be the same like in $prompts. Do not depend
|
||||||
|
* on a default value being set.
|
||||||
|
* @return array input sent by the user
|
||||||
|
* @abstract
|
||||||
|
*/
|
||||||
|
function userDialog($command, $prompts, $types = array(), $defaults = array())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,30 +1,38 @@
|
||||||
<?php
|
<?php
|
||||||
/*
|
/**
|
||||||
+----------------------------------------------------------------------+
|
* PEAR_Frontend_CLI
|
||||||
| PHP Version 5 |
|
*
|
||||||
+----------------------------------------------------------------------+
|
* PHP versions 4 and 5
|
||||||
| Copyright (c) 1997-2004 The PHP Group |
|
*
|
||||||
+----------------------------------------------------------------------+
|
* @category pear
|
||||||
| This source file is subject to version 3.0 of the PHP license, |
|
* @package PEAR
|
||||||
| that is bundled with this package in the file LICENSE, and is |
|
* @author Stig Bakken <ssb@php.net>
|
||||||
| available through the world-wide-web at the following url: |
|
* @author Greg Beaver <cellog@php.net>
|
||||||
| http://www.php.net/license/3_0.txt. |
|
* @copyright 1997-2009 The Authors
|
||||||
| If you did not receive a copy of the PHP license and are unable to |
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
| obtain it through the world-wide-web, please send a note to |
|
* @version CVS: $Id: CLI.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
| license@php.net so we can mail you a copy immediately. |
|
* @link http://pear.php.net/package/PEAR
|
||||||
+----------------------------------------------------------------------+
|
* @since File available since Release 0.1
|
||||||
| Author: Stig Sæther Bakken <ssb@php.net> |
|
|
||||||
+----------------------------------------------------------------------+
|
|
||||||
|
|
||||||
$Id: CLI.php,v 1.41 2004/02/17 05:49:16 ssb Exp $
|
|
||||||
*/
|
*/
|
||||||
|
/**
|
||||||
|
* base class
|
||||||
|
*/
|
||||||
|
require_once 'PEAR/Frontend.php';
|
||||||
|
|
||||||
require_once "PEAR.php";
|
/**
|
||||||
|
* Command-line Frontend for the PEAR Installer
|
||||||
class PEAR_Frontend_CLI extends PEAR
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Stig Bakken <ssb@php.net>
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 0.1
|
||||||
|
*/
|
||||||
|
class PEAR_Frontend_CLI extends PEAR_Frontend
|
||||||
{
|
{
|
||||||
// {{{ properties
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* What type of user interface this frontend is for.
|
* What type of user interface this frontend is for.
|
||||||
* @var string
|
* @var string
|
||||||
|
@ -39,10 +47,6 @@ class PEAR_Frontend_CLI extends PEAR
|
||||||
'normal' => '',
|
'normal' => '',
|
||||||
);
|
);
|
||||||
|
|
||||||
// }}}
|
|
||||||
|
|
||||||
// {{{ constructor
|
|
||||||
|
|
||||||
function PEAR_Frontend_CLI()
|
function PEAR_Frontend_CLI()
|
||||||
{
|
{
|
||||||
parent::PEAR();
|
parent::PEAR();
|
||||||
|
@ -50,7 +54,6 @@ class PEAR_Frontend_CLI extends PEAR
|
||||||
if (function_exists('posix_isatty') && !posix_isatty(1)) {
|
if (function_exists('posix_isatty') && !posix_isatty(1)) {
|
||||||
// output is being redirected to a file or through a pipe
|
// output is being redirected to a file or through a pipe
|
||||||
} elseif ($term) {
|
} elseif ($term) {
|
||||||
// XXX can use ncurses extension here, if available
|
|
||||||
if (preg_match('/^(xterm|vt220|linux)/', $term)) {
|
if (preg_match('/^(xterm|vt220|linux)/', $term)) {
|
||||||
$this->term['bold'] = sprintf("%c%c%c%c", 27, 91, 49, 109);
|
$this->term['bold'] = sprintf("%c%c%c%c", 27, 91, 49, 109);
|
||||||
$this->term['normal'] = sprintf("%c%c%c", 27, 91, 109);
|
$this->term['normal'] = sprintf("%c%c%c", 27, 91, 109);
|
||||||
|
@ -63,107 +66,295 @@ class PEAR_Frontend_CLI extends PEAR
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
|
|
||||||
// {{{ displayLine(text)
|
|
||||||
|
|
||||||
function displayLine($text)
|
|
||||||
{
|
|
||||||
trigger_error("PEAR_Frontend_CLI::displayLine deprecated", E_USER_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
function _displayLine($text)
|
|
||||||
{
|
|
||||||
print "$this->lp$text\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ display(text)
|
|
||||||
|
|
||||||
function display($text)
|
|
||||||
{
|
|
||||||
trigger_error("PEAR_Frontend_CLI::display deprecated", E_USER_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
function _display($text)
|
|
||||||
{
|
|
||||||
print $text;
|
|
||||||
}
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ displayError(eobj)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param object PEAR_Error object
|
* @param object PEAR_Error object
|
||||||
*/
|
*/
|
||||||
function displayError($eobj)
|
function displayError($e)
|
||||||
{
|
{
|
||||||
return $this->_displayLine($eobj->getMessage());
|
return $this->_displayLine($e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ displayFatalError(eobj)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param object PEAR_Error object
|
* @param object PEAR_Error object
|
||||||
*/
|
*/
|
||||||
function displayFatalError($eobj)
|
function displayFatalError($eobj)
|
||||||
{
|
{
|
||||||
$this->displayError($eobj);
|
$this->displayError($eobj);
|
||||||
|
if (class_exists('PEAR_Config')) {
|
||||||
|
$config = &PEAR_Config::singleton();
|
||||||
|
if ($config->get('verbose') > 5) {
|
||||||
|
if (function_exists('debug_print_backtrace')) {
|
||||||
|
debug_print_backtrace();
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
$raised = false;
|
||||||
// {{{ displayHeading(title)
|
foreach (debug_backtrace() as $i => $frame) {
|
||||||
|
if (!$raised) {
|
||||||
function displayHeading($title)
|
if (isset($frame['class'])
|
||||||
{
|
&& strtolower($frame['class']) == 'pear'
|
||||||
trigger_error("PEAR_Frontend_CLI::displayHeading deprecated", E_USER_ERROR);
|
&& strtolower($frame['function']) == 'raiseerror'
|
||||||
|
) {
|
||||||
|
$raised = true;
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function _displayHeading($title)
|
$frame['class'] = !isset($frame['class']) ? '' : $frame['class'];
|
||||||
{
|
$frame['type'] = !isset($frame['type']) ? '' : $frame['type'];
|
||||||
print $this->lp.$this->bold($title)."\n";
|
$frame['function'] = !isset($frame['function']) ? '' : $frame['function'];
|
||||||
print $this->lp.str_repeat("=", strlen($title))."\n";
|
$frame['line'] = !isset($frame['line']) ? '' : $frame['line'];
|
||||||
|
$this->_displayLine("#$i: $frame[class]$frame[type]$frame[function] $frame[line]");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
exit(1);
|
||||||
// {{{ userDialog(prompt, [type], [default])
|
}
|
||||||
|
|
||||||
function userDialog($command, $prompts, $types = array(), $defaults = array())
|
/**
|
||||||
|
* Instruct the runInstallScript method to skip a paramgroup that matches the
|
||||||
|
* id value passed in.
|
||||||
|
*
|
||||||
|
* This method is useful for dynamically configuring which sections of a post-install script
|
||||||
|
* will be run based on the user's setup, which is very useful for making flexible
|
||||||
|
* post-install scripts without losing the cross-Frontend ability to retrieve user input
|
||||||
|
* @param string
|
||||||
|
*/
|
||||||
|
function skipParamgroup($id)
|
||||||
{
|
{
|
||||||
$result = array();
|
$this->_skipSections[$id] = true;
|
||||||
if (is_array($prompts)) {
|
}
|
||||||
$fp = fopen("php://stdin", "r");
|
|
||||||
|
function runPostinstallScripts(&$scripts)
|
||||||
|
{
|
||||||
|
foreach ($scripts as $i => $script) {
|
||||||
|
$this->runInstallScript($scripts[$i]->_params, $scripts[$i]->_obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $xml contents of postinstallscript tag
|
||||||
|
* @param object $script post-installation script
|
||||||
|
* @param string install|upgrade
|
||||||
|
*/
|
||||||
|
function runInstallScript($xml, &$script)
|
||||||
|
{
|
||||||
|
$this->_skipSections = array();
|
||||||
|
if (!is_array($xml) || !isset($xml['paramgroup'])) {
|
||||||
|
$script->run(array(), '_default');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$completedPhases = array();
|
||||||
|
if (!isset($xml['paramgroup'][0])) {
|
||||||
|
$xml['paramgroup'] = array($xml['paramgroup']);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($xml['paramgroup'] as $group) {
|
||||||
|
if (isset($this->_skipSections[$group['id']])) {
|
||||||
|
// the post-install script chose to skip this section dynamically
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($group['name'])) {
|
||||||
|
$paramname = explode('::', $group['name']);
|
||||||
|
if ($lastgroup['id'] != $paramname[0]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$group['name'] = $paramname[1];
|
||||||
|
if (!isset($answers)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($answers[$group['name']])) {
|
||||||
|
switch ($group['conditiontype']) {
|
||||||
|
case '=' :
|
||||||
|
if ($answers[$group['name']] != $group['value']) {
|
||||||
|
continue 2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '!=' :
|
||||||
|
if ($answers[$group['name']] == $group['value']) {
|
||||||
|
continue 2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'preg_match' :
|
||||||
|
if (!@preg_match('/' . $group['value'] . '/',
|
||||||
|
$answers[$group['name']])) {
|
||||||
|
continue 2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$lastgroup = $group;
|
||||||
|
if (isset($group['instructions'])) {
|
||||||
|
$this->_display($group['instructions']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($group['param'][0])) {
|
||||||
|
$group['param'] = array($group['param']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($group['param'])) {
|
||||||
|
if (method_exists($script, 'postProcessPrompts')) {
|
||||||
|
$prompts = $script->postProcessPrompts($group['param'], $group['id']);
|
||||||
|
if (!is_array($prompts) || count($prompts) != count($group['param'])) {
|
||||||
|
$this->outputData('postinstall', 'Error: post-install script did not ' .
|
||||||
|
'return proper post-processed prompts');
|
||||||
|
$prompts = $group['param'];
|
||||||
|
} else {
|
||||||
|
foreach ($prompts as $i => $var) {
|
||||||
|
if (!is_array($var) || !isset($var['prompt']) ||
|
||||||
|
!isset($var['name']) ||
|
||||||
|
($var['name'] != $group['param'][$i]['name']) ||
|
||||||
|
($var['type'] != $group['param'][$i]['type'])
|
||||||
|
) {
|
||||||
|
$this->outputData('postinstall', 'Error: post-install script ' .
|
||||||
|
'modified the variables or prompts, severe security risk. ' .
|
||||||
|
'Will instead use the defaults from the package.xml');
|
||||||
|
$prompts = $group['param'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$answers = $this->confirmDialog($prompts);
|
||||||
|
} else {
|
||||||
|
$answers = $this->confirmDialog($group['param']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((isset($answers) && $answers) || !isset($group['param'])) {
|
||||||
|
if (!isset($answers)) {
|
||||||
|
$answers = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
array_unshift($completedPhases, $group['id']);
|
||||||
|
if (!$script->run($answers, $group['id'])) {
|
||||||
|
$script->run($completedPhases, '_undoOnError');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$script->run($completedPhases, '_undoOnError');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ask for user input, confirm the answers and continue until the user is satisfied
|
||||||
|
* @param array an array of arrays, format array('name' => 'paramname', 'prompt' =>
|
||||||
|
* 'text to display', 'type' => 'string'[, default => 'default value'])
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
function confirmDialog($params)
|
||||||
|
{
|
||||||
|
$answers = $prompts = $types = array();
|
||||||
|
foreach ($params as $param) {
|
||||||
|
$prompts[$param['name']] = $param['prompt'];
|
||||||
|
$types[$param['name']] = $param['type'];
|
||||||
|
$answers[$param['name']] = isset($param['default']) ? $param['default'] : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$tried = false;
|
||||||
|
do {
|
||||||
|
if ($tried) {
|
||||||
|
$i = 1;
|
||||||
|
foreach ($answers as $var => $value) {
|
||||||
|
if (!strlen($value)) {
|
||||||
|
echo $this->bold("* Enter an answer for #" . $i . ": ({$prompts[$var]})\n");
|
||||||
|
}
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$answers = $this->userDialog('', $prompts, $types, $answers);
|
||||||
|
$tried = true;
|
||||||
|
} while (is_array($answers) && count(array_filter($answers)) != count($prompts));
|
||||||
|
|
||||||
|
return $answers;
|
||||||
|
}
|
||||||
|
|
||||||
|
function userDialog($command, $prompts, $types = array(), $defaults = array(), $screensize = 20)
|
||||||
|
{
|
||||||
|
if (!is_array($prompts)) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$testprompts = array_keys($prompts);
|
||||||
|
$result = $defaults;
|
||||||
|
|
||||||
|
reset($prompts);
|
||||||
|
if (count($prompts) === 1) {
|
||||||
foreach ($prompts as $key => $prompt) {
|
foreach ($prompts as $key => $prompt) {
|
||||||
$type = $types[$key];
|
$type = $types[$key];
|
||||||
$default = @$defaults[$key];
|
$default = @$defaults[$key];
|
||||||
if ($type == 'password') {
|
print "$prompt ";
|
||||||
system('stty -echo');
|
|
||||||
}
|
|
||||||
print "$this->lp$prompt ";
|
|
||||||
if ($default) {
|
if ($default) {
|
||||||
print "[$default] ";
|
print "[$default] ";
|
||||||
}
|
}
|
||||||
print ": ";
|
print ": ";
|
||||||
$line = fgets($fp, 2048);
|
|
||||||
if ($type == 'password') {
|
$line = fgets(STDIN, 2048);
|
||||||
system('stty echo');
|
$result[$key] = ($default && trim($line) == '') ? $default : trim($line);
|
||||||
print "\n";
|
|
||||||
}
|
|
||||||
if ($default && trim($line) == "") {
|
|
||||||
$result[$key] = $default;
|
|
||||||
} else {
|
|
||||||
$result[$key] = $line;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fclose($fp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
$first_run = true;
|
||||||
// {{{ userConfirm(prompt, [default])
|
while (true) {
|
||||||
|
$descLength = max(array_map('strlen', $prompts));
|
||||||
|
$descFormat = "%-{$descLength}s";
|
||||||
|
$last = count($prompts);
|
||||||
|
|
||||||
|
$i = 0;
|
||||||
|
foreach ($prompts as $n => $var) {
|
||||||
|
$res = isset($result[$n]) ? $result[$n] : null;
|
||||||
|
printf("%2d. $descFormat : %s\n", ++$i, $prompts[$n], $res);
|
||||||
|
}
|
||||||
|
print "\n1-$last, 'all', 'abort', or Enter to continue: ";
|
||||||
|
|
||||||
|
$tmp = trim(fgets(STDIN, 1024));
|
||||||
|
if (empty($tmp)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($tmp == 'abort') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($testprompts[(int)$tmp - 1])) {
|
||||||
|
$var = $testprompts[(int)$tmp - 1];
|
||||||
|
$desc = $prompts[$var];
|
||||||
|
$current = @$result[$var];
|
||||||
|
print "$desc [$current] : ";
|
||||||
|
$tmp = trim(fgets(STDIN, 1024));
|
||||||
|
if ($tmp !== '') {
|
||||||
|
$result[$var] = $tmp;
|
||||||
|
}
|
||||||
|
} elseif ($tmp == 'all') {
|
||||||
|
foreach ($prompts as $var => $desc) {
|
||||||
|
$current = $result[$var];
|
||||||
|
print "$desc [$current] : ";
|
||||||
|
$tmp = trim(fgets(STDIN, 1024));
|
||||||
|
if (trim($tmp) !== '') {
|
||||||
|
$result[$var] = trim($tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$first_run = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
function userConfirm($prompt, $default = 'yes')
|
function userConfirm($prompt, $default = 'yes')
|
||||||
{
|
{
|
||||||
|
@ -190,189 +381,22 @@ class PEAR_Frontend_CLI extends PEAR
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ startTable([params])
|
|
||||||
|
|
||||||
function startTable($params = array())
|
|
||||||
{
|
|
||||||
trigger_error("PEAR_Frontend_CLI::startTable deprecated", E_USER_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
function _startTable($params = array())
|
|
||||||
{
|
|
||||||
$params['table_data'] = array();
|
|
||||||
$params['widest'] = array(); // indexed by column
|
|
||||||
$params['highest'] = array(); // indexed by row
|
|
||||||
$params['ncols'] = 0;
|
|
||||||
$this->params = $params;
|
|
||||||
}
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ tableRow(columns, [rowparams], [colparams])
|
|
||||||
|
|
||||||
function tableRow($columns, $rowparams = array(), $colparams = array())
|
|
||||||
{
|
|
||||||
trigger_error("PEAR_Frontend_CLI::tableRow deprecated", E_USER_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
function _tableRow($columns, $rowparams = array(), $colparams = array())
|
|
||||||
{
|
|
||||||
$highest = 1;
|
|
||||||
for ($i = 0; $i < sizeof($columns); $i++) {
|
|
||||||
$col = &$columns[$i];
|
|
||||||
if (isset($colparams[$i]) && !empty($colparams[$i]['wrap'])) {
|
|
||||||
$col = wordwrap($col, $colparams[$i]['wrap'], "\n", 0);
|
|
||||||
}
|
|
||||||
if (strpos($col, "\n") !== false) {
|
|
||||||
$multiline = explode("\n", $col);
|
|
||||||
$w = 0;
|
|
||||||
foreach ($multiline as $n => $line) {
|
|
||||||
if (strlen($line) > $w) {
|
|
||||||
$w = strlen($line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$lines = sizeof($multiline);
|
|
||||||
} else {
|
|
||||||
$w = strlen($col);
|
|
||||||
}
|
|
||||||
if ($w > @$this->params['widest'][$i]) {
|
|
||||||
$this->params['widest'][$i] = $w;
|
|
||||||
}
|
|
||||||
$tmp = count_chars($columns[$i], 1);
|
|
||||||
// handle unix, mac and windows formats
|
|
||||||
$lines = (isset($tmp[10]) ? $tmp[10] : @$tmp[13]) + 1;
|
|
||||||
if ($lines > $highest) {
|
|
||||||
$highest = $lines;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (sizeof($columns) > $this->params['ncols']) {
|
|
||||||
$this->params['ncols'] = sizeof($columns);
|
|
||||||
}
|
|
||||||
$new_row = array(
|
|
||||||
'data' => $columns,
|
|
||||||
'height' => $highest,
|
|
||||||
'rowparams' => $rowparams,
|
|
||||||
'colparams' => $colparams,
|
|
||||||
);
|
|
||||||
$this->params['table_data'][] = $new_row;
|
|
||||||
}
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ endTable()
|
|
||||||
|
|
||||||
function endTable()
|
|
||||||
{
|
|
||||||
trigger_error("PEAR_Frontend_CLI::endTable deprecated", E_USER_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
function _endTable()
|
|
||||||
{
|
|
||||||
extract($this->params);
|
|
||||||
if (!empty($caption)) {
|
|
||||||
$this->_displayHeading($caption);
|
|
||||||
}
|
|
||||||
if (count($table_data) == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!isset($width)) {
|
|
||||||
$width = $widest;
|
|
||||||
} else {
|
|
||||||
for ($i = 0; $i < $ncols; $i++) {
|
|
||||||
if (!isset($width[$i])) {
|
|
||||||
$width[$i] = $widest[$i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$border = false;
|
|
||||||
if (empty($border)) {
|
|
||||||
$cellstart = '';
|
|
||||||
$cellend = ' ';
|
|
||||||
$rowend = '';
|
|
||||||
$padrowend = false;
|
|
||||||
$borderline = '';
|
|
||||||
} else {
|
|
||||||
$cellstart = '| ';
|
|
||||||
$cellend = ' ';
|
|
||||||
$rowend = '|';
|
|
||||||
$padrowend = true;
|
|
||||||
$borderline = '+';
|
|
||||||
foreach ($width as $w) {
|
|
||||||
$borderline .= str_repeat('-', $w + strlen($cellstart) + strlen($cellend) - 1);
|
|
||||||
$borderline .= '+';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($borderline) {
|
|
||||||
$this->_displayLine($borderline);
|
|
||||||
}
|
|
||||||
for ($i = 0; $i < sizeof($table_data); $i++) {
|
|
||||||
extract($table_data[$i]);
|
|
||||||
if (!is_array($rowparams)) {
|
|
||||||
$rowparams = array();
|
|
||||||
}
|
|
||||||
if (!is_array($colparams)) {
|
|
||||||
$colparams = array();
|
|
||||||
}
|
|
||||||
$rowlines = array();
|
|
||||||
if ($height > 1) {
|
|
||||||
for ($c = 0; $c < sizeof($data); $c++) {
|
|
||||||
$rowlines[$c] = preg_split('/(\r?\n|\r)/', $data[$c]);
|
|
||||||
if (sizeof($rowlines[$c]) < $height) {
|
|
||||||
$rowlines[$c] = array_pad($rowlines[$c], $height, '');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for ($c = 0; $c < sizeof($data); $c++) {
|
|
||||||
$rowlines[$c] = array($data[$c]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for ($r = 0; $r < $height; $r++) {
|
|
||||||
$rowtext = '';
|
|
||||||
for ($c = 0; $c < sizeof($data); $c++) {
|
|
||||||
if (isset($colparams[$c])) {
|
|
||||||
$attribs = array_merge($rowparams, $colparams);
|
|
||||||
} else {
|
|
||||||
$attribs = $rowparams;
|
|
||||||
}
|
|
||||||
$w = isset($width[$c]) ? $width[$c] : 0;
|
|
||||||
//$cell = $data[$c];
|
|
||||||
$cell = $rowlines[$c][$r];
|
|
||||||
$l = strlen($cell);
|
|
||||||
if ($l > $w) {
|
|
||||||
$cell = substr($cell, 0, $w);
|
|
||||||
}
|
|
||||||
if (isset($attribs['bold'])) {
|
|
||||||
$cell = $this->bold($cell);
|
|
||||||
}
|
|
||||||
if ($l < $w) {
|
|
||||||
// not using str_pad here because we may
|
|
||||||
// add bold escape characters to $cell
|
|
||||||
$cell .= str_repeat(' ', $w - $l);
|
|
||||||
}
|
|
||||||
|
|
||||||
$rowtext .= $cellstart . $cell . $cellend;
|
|
||||||
}
|
|
||||||
if (!$border) {
|
|
||||||
$rowtext = rtrim($rowtext);
|
|
||||||
}
|
|
||||||
$rowtext .= $rowend;
|
|
||||||
$this->_displayLine($rowtext);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($borderline) {
|
|
||||||
$this->_displayLine($borderline);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ outputData()
|
|
||||||
|
|
||||||
function outputData($data, $command = '_default')
|
function outputData($data, $command = '_default')
|
||||||
{
|
{
|
||||||
switch ($command) {
|
switch ($command) {
|
||||||
|
case 'channel-info':
|
||||||
|
foreach ($data as $type => $section) {
|
||||||
|
if ($type == 'main') {
|
||||||
|
$section['data'] = array_values($section['data']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->outputData($section);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'install':
|
case 'install':
|
||||||
case 'upgrade':
|
case 'upgrade':
|
||||||
case 'upgrade-all':
|
case 'upgrade-all':
|
||||||
if (isset($data['release_warnings'])) {
|
if (is_array($data) && isset($data['release_warnings'])) {
|
||||||
$this->_displayLine('');
|
$this->_displayLine('');
|
||||||
$this->_startTable(array(
|
$this->_startTable(array(
|
||||||
'border' => false,
|
'border' => false,
|
||||||
|
@ -382,7 +406,8 @@ class PEAR_Frontend_CLI extends PEAR
|
||||||
$this->_endTable();
|
$this->_endTable();
|
||||||
$this->_displayLine('');
|
$this->_displayLine('');
|
||||||
}
|
}
|
||||||
$this->_displayLine($data['data']);
|
|
||||||
|
$this->_displayLine(is_array($data) ? $data['data'] : $data);
|
||||||
break;
|
break;
|
||||||
case 'search':
|
case 'search':
|
||||||
$this->_startTable($data);
|
$this->_startTable($data);
|
||||||
|
@ -390,50 +415,76 @@ class PEAR_Frontend_CLI extends PEAR
|
||||||
$this->_tableRow($data['headline'], array('bold' => true), array(1 => array('wrap' => 55)));
|
$this->_tableRow($data['headline'], array('bold' => true), array(1 => array('wrap' => 55)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$packages = array();
|
||||||
foreach($data['data'] as $category) {
|
foreach($data['data'] as $category) {
|
||||||
foreach($category as $pkg) {
|
foreach($category as $name => $pkg) {
|
||||||
$this->_tableRow($pkg, null, array(1 => array('wrap' => 55)));
|
$packages[$pkg[0]] = $pkg;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
$p = array_keys($packages);
|
||||||
|
natcasesort($p);
|
||||||
|
foreach ($p as $name) {
|
||||||
|
$this->_tableRow($packages[$name], null, array(1 => array('wrap' => 55)));
|
||||||
|
}
|
||||||
|
|
||||||
$this->_endTable();
|
$this->_endTable();
|
||||||
break;
|
break;
|
||||||
case 'list-all':
|
case 'list-all':
|
||||||
|
if (!isset($data['data'])) {
|
||||||
|
$this->_displayLine('No packages in channel');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
$this->_startTable($data);
|
$this->_startTable($data);
|
||||||
if (isset($data['headline']) && is_array($data['headline'])) {
|
if (isset($data['headline']) && is_array($data['headline'])) {
|
||||||
$this->_tableRow($data['headline'], array('bold' => true), array(1 => array('wrap' => 55)));
|
$this->_tableRow($data['headline'], array('bold' => true), array(1 => array('wrap' => 55)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$packages = array();
|
||||||
foreach($data['data'] as $category) {
|
foreach($data['data'] as $category) {
|
||||||
foreach($category as $pkg) {
|
foreach($category as $name => $pkg) {
|
||||||
unset($pkg[3]);
|
$packages[$pkg[0]] = $pkg;
|
||||||
unset($pkg[4]);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$p = array_keys($packages);
|
||||||
|
natcasesort($p);
|
||||||
|
foreach ($p as $name) {
|
||||||
|
$pkg = $packages[$name];
|
||||||
|
unset($pkg[4], $pkg[5]);
|
||||||
$this->_tableRow($pkg, null, array(1 => array('wrap' => 55)));
|
$this->_tableRow($pkg, null, array(1 => array('wrap' => 55)));
|
||||||
}
|
}
|
||||||
};
|
|
||||||
$this->_endTable();
|
$this->_endTable();
|
||||||
break;
|
break;
|
||||||
case 'config-show':
|
case 'config-show':
|
||||||
$data['border'] = false;
|
$data['border'] = false;
|
||||||
$opts = array(0 => array('wrap' => 30),
|
$opts = array(
|
||||||
|
0 => array('wrap' => 30),
|
||||||
1 => array('wrap' => 20),
|
1 => array('wrap' => 20),
|
||||||
2 => array('wrap' => 35));
|
2 => array('wrap' => 35)
|
||||||
|
);
|
||||||
|
|
||||||
$this->_startTable($data);
|
$this->_startTable($data);
|
||||||
if (isset($data['headline']) && is_array($data['headline'])) {
|
if (isset($data['headline']) && is_array($data['headline'])) {
|
||||||
$this->_tableRow($data['headline'],
|
$this->_tableRow($data['headline'], array('bold' => true), $opts);
|
||||||
array('bold' => true),
|
|
||||||
$opts);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($data['data'] as $group) {
|
foreach ($data['data'] as $group) {
|
||||||
foreach ($group as $value) {
|
foreach ($group as $value) {
|
||||||
if ($value[2] == '') {
|
if ($value[2] == '') {
|
||||||
$value[2] = "<not set>";
|
$value[2] = "<not set>";
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->_tableRow($value, null, $opts);
|
$this->_tableRow($value, null, $opts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->_endTable();
|
$this->_endTable();
|
||||||
break;
|
break;
|
||||||
case 'remote-info':
|
case 'remote-info':
|
||||||
|
$d = $data;
|
||||||
$data = array(
|
$data = array(
|
||||||
'caption' => 'Package details:',
|
'caption' => 'Package details:',
|
||||||
'border' => false,
|
'border' => false,
|
||||||
|
@ -447,6 +498,13 @@ class PEAR_Frontend_CLI extends PEAR
|
||||||
array("Description", $data['description']),
|
array("Description", $data['description']),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (isset($d['deprecated']) && $d['deprecated']) {
|
||||||
|
$conf = &PEAR_Config::singleton();
|
||||||
|
$reg = $conf->getRegistry();
|
||||||
|
$name = $reg->parsedPackageNameToString($d['deprecated'], true);
|
||||||
|
$data['data'][] = array('Deprecated! use', $name);
|
||||||
|
}
|
||||||
default: {
|
default: {
|
||||||
if (is_array($data)) {
|
if (is_array($data)) {
|
||||||
$this->_startTable($data);
|
$this->_startTable($data);
|
||||||
|
@ -468,9 +526,14 @@ class PEAR_Frontend_CLI extends PEAR
|
||||||
array('bold' => true),
|
array('bold' => true),
|
||||||
$opts);
|
$opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_array($data['data'])) {
|
||||||
foreach($data['data'] as $row) {
|
foreach($data['data'] as $row) {
|
||||||
$this->_tableRow($row, null, $opts);
|
$this->_tableRow($row, null, $opts);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
$this->_tableRow(array($data['data']), null, $opts);
|
||||||
|
}
|
||||||
$this->_endTable();
|
$this->_endTable();
|
||||||
} else {
|
} else {
|
||||||
$this->_displayLine($data);
|
$this->_displayLine($data);
|
||||||
|
@ -479,31 +542,210 @@ class PEAR_Frontend_CLI extends PEAR
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ log(text)
|
|
||||||
|
|
||||||
|
|
||||||
function log($text, $append_crlf = true)
|
function log($text, $append_crlf = true)
|
||||||
{
|
{
|
||||||
if ($append_crlf) {
|
if ($append_crlf) {
|
||||||
return $this->_displayLine($text);
|
return $this->_displayLine($text);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->_display($text);
|
return $this->_display($text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ bold($text)
|
|
||||||
|
|
||||||
function bold($text)
|
function bold($text)
|
||||||
{
|
{
|
||||||
if (empty($this->term['bold'])) {
|
if (empty($this->term['bold'])) {
|
||||||
return strtoupper($text);
|
return strtoupper($text);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->term['bold'] . $text . $this->term['normal'];
|
return $this->term['bold'] . $text . $this->term['normal'];
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
function _displayHeading($title)
|
||||||
|
{
|
||||||
|
print $this->lp.$this->bold($title)."\n";
|
||||||
|
print $this->lp.str_repeat("=", strlen($title))."\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
function _startTable($params = array())
|
||||||
|
{
|
||||||
|
$params['table_data'] = array();
|
||||||
|
$params['widest'] = array(); // indexed by column
|
||||||
|
$params['highest'] = array(); // indexed by row
|
||||||
|
$params['ncols'] = 0;
|
||||||
|
$this->params = $params;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _tableRow($columns, $rowparams = array(), $colparams = array())
|
||||||
|
{
|
||||||
|
$highest = 1;
|
||||||
|
for ($i = 0; $i < count($columns); $i++) {
|
||||||
|
$col = &$columns[$i];
|
||||||
|
if (isset($colparams[$i]) && !empty($colparams[$i]['wrap'])) {
|
||||||
|
$col = wordwrap($col, $colparams[$i]['wrap']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strpos($col, "\n") !== false) {
|
||||||
|
$multiline = explode("\n", $col);
|
||||||
|
$w = 0;
|
||||||
|
foreach ($multiline as $n => $line) {
|
||||||
|
$len = strlen($line);
|
||||||
|
if ($len > $w) {
|
||||||
|
$w = $len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$lines = count($multiline);
|
||||||
|
} else {
|
||||||
|
$w = strlen($col);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($this->params['widest'][$i])) {
|
||||||
|
if ($w > $this->params['widest'][$i]) {
|
||||||
|
$this->params['widest'][$i] = $w;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$this->params['widest'][$i] = $w;
|
||||||
|
}
|
||||||
|
|
||||||
|
$tmp = count_chars($columns[$i], 1);
|
||||||
|
// handle unix, mac and windows formats
|
||||||
|
$lines = (isset($tmp[10]) ? $tmp[10] : (isset($tmp[13]) ? $tmp[13] : 0)) + 1;
|
||||||
|
if ($lines > $highest) {
|
||||||
|
$highest = $lines;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($columns) > $this->params['ncols']) {
|
||||||
|
$this->params['ncols'] = count($columns);
|
||||||
|
}
|
||||||
|
|
||||||
|
$new_row = array(
|
||||||
|
'data' => $columns,
|
||||||
|
'height' => $highest,
|
||||||
|
'rowparams' => $rowparams,
|
||||||
|
'colparams' => $colparams,
|
||||||
|
);
|
||||||
|
$this->params['table_data'][] = $new_row;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _endTable()
|
||||||
|
{
|
||||||
|
extract($this->params);
|
||||||
|
if (!empty($caption)) {
|
||||||
|
$this->_displayHeading($caption);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($table_data) === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($width)) {
|
||||||
|
$width = $widest;
|
||||||
|
} else {
|
||||||
|
for ($i = 0; $i < $ncols; $i++) {
|
||||||
|
if (!isset($width[$i])) {
|
||||||
|
$width[$i] = $widest[$i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$border = false;
|
||||||
|
if (empty($border)) {
|
||||||
|
$cellstart = '';
|
||||||
|
$cellend = ' ';
|
||||||
|
$rowend = '';
|
||||||
|
$padrowend = false;
|
||||||
|
$borderline = '';
|
||||||
|
} else {
|
||||||
|
$cellstart = '| ';
|
||||||
|
$cellend = ' ';
|
||||||
|
$rowend = '|';
|
||||||
|
$padrowend = true;
|
||||||
|
$borderline = '+';
|
||||||
|
foreach ($width as $w) {
|
||||||
|
$borderline .= str_repeat('-', $w + strlen($cellstart) + strlen($cellend) - 1);
|
||||||
|
$borderline .= '+';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($borderline) {
|
||||||
|
$this->_displayLine($borderline);
|
||||||
|
}
|
||||||
|
|
||||||
|
for ($i = 0; $i < count($table_data); $i++) {
|
||||||
|
extract($table_data[$i]);
|
||||||
|
if (!is_array($rowparams)) {
|
||||||
|
$rowparams = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($colparams)) {
|
||||||
|
$colparams = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$rowlines = array();
|
||||||
|
if ($height > 1) {
|
||||||
|
for ($c = 0; $c < count($data); $c++) {
|
||||||
|
$rowlines[$c] = preg_split('/(\r?\n|\r)/', $data[$c]);
|
||||||
|
if (count($rowlines[$c]) < $height) {
|
||||||
|
$rowlines[$c] = array_pad($rowlines[$c], $height, '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for ($c = 0; $c < count($data); $c++) {
|
||||||
|
$rowlines[$c] = array($data[$c]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ($r = 0; $r < $height; $r++) {
|
||||||
|
$rowtext = '';
|
||||||
|
for ($c = 0; $c < count($data); $c++) {
|
||||||
|
if (isset($colparams[$c])) {
|
||||||
|
$attribs = array_merge($rowparams, $colparams);
|
||||||
|
} else {
|
||||||
|
$attribs = $rowparams;
|
||||||
|
}
|
||||||
|
|
||||||
|
$w = isset($width[$c]) ? $width[$c] : 0;
|
||||||
|
//$cell = $data[$c];
|
||||||
|
$cell = $rowlines[$c][$r];
|
||||||
|
$l = strlen($cell);
|
||||||
|
if ($l > $w) {
|
||||||
|
$cell = substr($cell, 0, $w);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($attribs['bold'])) {
|
||||||
|
$cell = $this->bold($cell);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($l < $w) {
|
||||||
|
// not using str_pad here because we may
|
||||||
|
// add bold escape characters to $cell
|
||||||
|
$cell .= str_repeat(' ', $w - $l);
|
||||||
|
}
|
||||||
|
|
||||||
|
$rowtext .= $cellstart . $cell . $cellend;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$border) {
|
||||||
|
$rowtext = rtrim($rowtext);
|
||||||
|
}
|
||||||
|
|
||||||
|
$rowtext .= $rowend;
|
||||||
|
$this->_displayLine($rowtext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($borderline) {
|
||||||
|
$this->_displayLine($borderline);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function _displayLine($text)
|
||||||
|
{
|
||||||
|
print "$this->lp$text\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
function _display($text)
|
||||||
|
{
|
||||||
|
print $text;
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,276 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PEAR_Installer_Role
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: Role.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* base class for installer roles
|
||||||
|
*/
|
||||||
|
require_once 'PEAR/Installer/Role/Common.php';
|
||||||
|
require_once 'PEAR/XMLParser.php';
|
||||||
|
/**
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
class PEAR_Installer_Role
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Set up any additional configuration variables that file roles require
|
||||||
|
*
|
||||||
|
* Never call this directly, it is called by the PEAR_Config constructor
|
||||||
|
* @param PEAR_Config
|
||||||
|
* @access private
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
function initializeConfig(&$config)
|
||||||
|
{
|
||||||
|
if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) {
|
||||||
|
PEAR_Installer_Role::registerRoles();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $class => $info) {
|
||||||
|
if (!$info['config_vars']) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$config->_addConfigVars($class, $info['config_vars']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param PEAR_PackageFile_v2
|
||||||
|
* @param string role name
|
||||||
|
* @param PEAR_Config
|
||||||
|
* @return PEAR_Installer_Role_Common
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
function &factory($pkg, $role, &$config)
|
||||||
|
{
|
||||||
|
if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) {
|
||||||
|
PEAR_Installer_Role::registerRoles();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in_array($role, PEAR_Installer_Role::getValidRoles($pkg->getPackageType()))) {
|
||||||
|
$a = false;
|
||||||
|
return $a;
|
||||||
|
}
|
||||||
|
|
||||||
|
$a = 'PEAR_Installer_Role_' . ucfirst($role);
|
||||||
|
if (!class_exists($a)) {
|
||||||
|
require_once str_replace('_', '/', $a) . '.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
$b = new $a($config);
|
||||||
|
return $b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of file roles that are valid for the particular release type.
|
||||||
|
*
|
||||||
|
* For instance, src files serve no purpose in regular php releases.
|
||||||
|
* @param string
|
||||||
|
* @param bool clear cache
|
||||||
|
* @return array
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
function getValidRoles($release, $clear = false)
|
||||||
|
{
|
||||||
|
if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) {
|
||||||
|
PEAR_Installer_Role::registerRoles();
|
||||||
|
}
|
||||||
|
|
||||||
|
static $ret = array();
|
||||||
|
if ($clear) {
|
||||||
|
$ret = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($ret[$release])) {
|
||||||
|
return $ret[$release];
|
||||||
|
}
|
||||||
|
|
||||||
|
$ret[$release] = array();
|
||||||
|
foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) {
|
||||||
|
if (in_array($release, $okreleases['releasetypes'])) {
|
||||||
|
$ret[$release][] = strtolower(str_replace('PEAR_Installer_Role_', '', $role));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ret[$release];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of roles that require their files to be installed
|
||||||
|
*
|
||||||
|
* Most roles must be installed, but src and package roles, for instance
|
||||||
|
* are pseudo-roles. src files are compiled into a new extension. Package
|
||||||
|
* roles are actually fully bundled releases of a package
|
||||||
|
* @param bool clear cache
|
||||||
|
* @return array
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
function getInstallableRoles($clear = false)
|
||||||
|
{
|
||||||
|
if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) {
|
||||||
|
PEAR_Installer_Role::registerRoles();
|
||||||
|
}
|
||||||
|
|
||||||
|
static $ret;
|
||||||
|
if ($clear) {
|
||||||
|
unset($ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($ret)) {
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
$ret = array();
|
||||||
|
foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) {
|
||||||
|
if ($okreleases['installable']) {
|
||||||
|
$ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an array of roles that are affected by the baseinstalldir attribute
|
||||||
|
*
|
||||||
|
* Most roles ignore this attribute, and instead install directly into:
|
||||||
|
* PackageName/filepath
|
||||||
|
* so a tests file tests/file.phpt is installed into PackageName/tests/filepath.php
|
||||||
|
* @param bool clear cache
|
||||||
|
* @return array
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
function getBaseinstallRoles($clear = false)
|
||||||
|
{
|
||||||
|
if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) {
|
||||||
|
PEAR_Installer_Role::registerRoles();
|
||||||
|
}
|
||||||
|
|
||||||
|
static $ret;
|
||||||
|
if ($clear) {
|
||||||
|
unset($ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($ret)) {
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
$ret = array();
|
||||||
|
foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) {
|
||||||
|
if ($okreleases['honorsbaseinstall']) {
|
||||||
|
$ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an array of file roles that should be analyzed for PHP content at package time,
|
||||||
|
* like the "php" role.
|
||||||
|
* @param bool clear cache
|
||||||
|
* @return array
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
function getPhpRoles($clear = false)
|
||||||
|
{
|
||||||
|
if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) {
|
||||||
|
PEAR_Installer_Role::registerRoles();
|
||||||
|
}
|
||||||
|
|
||||||
|
static $ret;
|
||||||
|
if ($clear) {
|
||||||
|
unset($ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($ret)) {
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
$ret = array();
|
||||||
|
foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) {
|
||||||
|
if ($okreleases['phpfile']) {
|
||||||
|
$ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scan through the Command directory looking for classes
|
||||||
|
* and see what commands they implement.
|
||||||
|
* @param string which directory to look for classes, defaults to
|
||||||
|
* the Installer/Roles subdirectory of
|
||||||
|
* the directory from where this file (__FILE__) is
|
||||||
|
* included.
|
||||||
|
*
|
||||||
|
* @return bool TRUE on success, a PEAR error on failure
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
function registerRoles($dir = null)
|
||||||
|
{
|
||||||
|
$GLOBALS['_PEAR_INSTALLER_ROLES'] = array();
|
||||||
|
$parser = new PEAR_XMLParser;
|
||||||
|
if ($dir === null) {
|
||||||
|
$dir = dirname(__FILE__) . '/Role';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!file_exists($dir) || !is_dir($dir)) {
|
||||||
|
return PEAR::raiseError("registerRoles: opendir($dir) failed: does not exist/is not directory");
|
||||||
|
}
|
||||||
|
|
||||||
|
$dp = @opendir($dir);
|
||||||
|
if (empty($dp)) {
|
||||||
|
return PEAR::raiseError("registerRoles: opendir($dir) failed: $php_errmsg");
|
||||||
|
}
|
||||||
|
|
||||||
|
while ($entry = readdir($dp)) {
|
||||||
|
if ($entry{0} == '.' || substr($entry, -4) != '.xml') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$class = "PEAR_Installer_Role_".substr($entry, 0, -4);
|
||||||
|
// List of roles
|
||||||
|
if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'][$class])) {
|
||||||
|
$file = "$dir/$entry";
|
||||||
|
$parser->parse(file_get_contents($file));
|
||||||
|
$data = $parser->getData();
|
||||||
|
if (!is_array($data['releasetypes'])) {
|
||||||
|
$data['releasetypes'] = array($data['releasetypes']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$GLOBALS['_PEAR_INSTALLER_ROLES'][$class] = $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir($dp);
|
||||||
|
ksort($GLOBALS['_PEAR_INSTALLER_ROLES']);
|
||||||
|
PEAR_Installer_Role::getBaseinstallRoles(true);
|
||||||
|
PEAR_Installer_Role::getInstallableRoles(true);
|
||||||
|
PEAR_Installer_Role::getPhpRoles(true);
|
||||||
|
PEAR_Installer_Role::getValidRoles('****', true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,106 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PEAR_Installer_Role_Cfg
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 2007-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: Cfg.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since Release 1.7.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 2007-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 1.7.0
|
||||||
|
*/
|
||||||
|
class PEAR_Installer_Role_Cfg extends PEAR_Installer_Role_Common
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var PEAR_Installer
|
||||||
|
*/
|
||||||
|
var $installer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the md5 of the original file
|
||||||
|
*
|
||||||
|
* @var unknown_type
|
||||||
|
*/
|
||||||
|
var $md5 = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do any unusual setup here
|
||||||
|
* @param PEAR_Installer
|
||||||
|
* @param PEAR_PackageFile_v2
|
||||||
|
* @param array file attributes
|
||||||
|
* @param string file name
|
||||||
|
*/
|
||||||
|
function setup(&$installer, $pkg, $atts, $file)
|
||||||
|
{
|
||||||
|
$this->installer = &$installer;
|
||||||
|
$reg = &$this->installer->config->getRegistry();
|
||||||
|
$package = $reg->getPackage($pkg->getPackage(), $pkg->getChannel());
|
||||||
|
if ($package) {
|
||||||
|
$filelist = $package->getFilelist();
|
||||||
|
if (isset($filelist[$file]) && isset($filelist[$file]['md5sum'])) {
|
||||||
|
$this->md5 = $filelist[$file]['md5sum'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function processInstallation($pkg, $atts, $file, $tmp_path, $layer = null)
|
||||||
|
{
|
||||||
|
$test = parent::processInstallation($pkg, $atts, $file, $tmp_path, $layer);
|
||||||
|
if (@file_exists($test[2]) && @file_exists($test[3])) {
|
||||||
|
$md5 = md5_file($test[2]);
|
||||||
|
// configuration has already been installed, check for mods
|
||||||
|
if ($md5 !== $this->md5 && $md5 !== md5_file($test[3])) {
|
||||||
|
// configuration has been modified, so save our version as
|
||||||
|
// configfile-version
|
||||||
|
$old = $test[2];
|
||||||
|
$test[2] .= '.new-' . $pkg->getVersion();
|
||||||
|
// backup original and re-install it
|
||||||
|
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
|
||||||
|
$tmpcfg = $this->config->get('temp_dir');
|
||||||
|
$newloc = System::mkdir(array('-p', $tmpcfg));
|
||||||
|
if (!$newloc) {
|
||||||
|
// try temp_dir
|
||||||
|
$newloc = System::mktemp(array('-d'));
|
||||||
|
if (!$newloc || PEAR::isError($newloc)) {
|
||||||
|
PEAR::popErrorHandling();
|
||||||
|
return PEAR::raiseError('Could not save existing configuration file '.
|
||||||
|
$old . ', unable to install. Please set temp_dir ' .
|
||||||
|
'configuration variable to a writeable location and try again');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$newloc = $tmpcfg;
|
||||||
|
}
|
||||||
|
|
||||||
|
$temp_file = $newloc . DIRECTORY_SEPARATOR . uniqid('savefile');
|
||||||
|
if (!@copy($old, $temp_file)) {
|
||||||
|
PEAR::popErrorHandling();
|
||||||
|
return PEAR::raiseError('Could not save existing configuration file '.
|
||||||
|
$old . ', unable to install. Please set temp_dir ' .
|
||||||
|
'configuration variable to a writeable location and try again');
|
||||||
|
}
|
||||||
|
|
||||||
|
PEAR::popErrorHandling();
|
||||||
|
$this->installer->log(0, "WARNING: configuration file $old is being installed as $test[2], you should manually merge in changes to the existing configuration file");
|
||||||
|
$this->installer->addFileOperation('rename', array($temp_file, $old, false));
|
||||||
|
$this->installer->addFileOperation('delete', array($temp_file));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $test;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
<role version="1.0">
|
||||||
|
<releasetypes>php</releasetypes>
|
||||||
|
<releasetypes>extsrc</releasetypes>
|
||||||
|
<releasetypes>extbin</releasetypes>
|
||||||
|
<releasetypes>zendextsrc</releasetypes>
|
||||||
|
<releasetypes>zendextbin</releasetypes>
|
||||||
|
<installable>1</installable>
|
||||||
|
<locationconfig>cfg_dir</locationconfig>
|
||||||
|
<honorsbaseinstall />
|
||||||
|
<unusualbaseinstall>1</unusualbaseinstall>
|
||||||
|
<phpfile />
|
||||||
|
<executable />
|
||||||
|
<phpextension />
|
||||||
|
<config_vars />
|
||||||
|
</role>
|
|
@ -0,0 +1,174 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Base class for all installation roles.
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2006 The PHP Group
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: Common.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Base class for all installation roles.
|
||||||
|
*
|
||||||
|
* This class allows extensibility of file roles. Packages with complex
|
||||||
|
* customization can now provide custom file roles along with the possibility of
|
||||||
|
* adding configuration values to match.
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2006 The PHP Group
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
class PEAR_Installer_Role_Common
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var PEAR_Config
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
var $config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param PEAR_Config
|
||||||
|
*/
|
||||||
|
function PEAR_Installer_Role_Common(&$config)
|
||||||
|
{
|
||||||
|
$this->config = $config;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve configuration information about a file role from its XML info
|
||||||
|
*
|
||||||
|
* @param string $role Role Classname, as in "PEAR_Installer_Role_Data"
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
function getInfo($role)
|
||||||
|
{
|
||||||
|
if (empty($GLOBALS['_PEAR_INSTALLER_ROLES'][$role])) {
|
||||||
|
return PEAR::raiseError('Unknown Role class: "' . $role . '"');
|
||||||
|
}
|
||||||
|
return $GLOBALS['_PEAR_INSTALLER_ROLES'][$role];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is called for each file to set up the directories and files
|
||||||
|
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
|
||||||
|
* @param array attributes from the <file> tag
|
||||||
|
* @param string file name
|
||||||
|
* @return array an array consisting of:
|
||||||
|
*
|
||||||
|
* 1 the original, pre-baseinstalldir installation directory
|
||||||
|
* 2 the final installation directory
|
||||||
|
* 3 the full path to the final location of the file
|
||||||
|
* 4 the location of the pre-installation file
|
||||||
|
*/
|
||||||
|
function processInstallation($pkg, $atts, $file, $tmp_path, $layer = null)
|
||||||
|
{
|
||||||
|
$roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' .
|
||||||
|
ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this)))));
|
||||||
|
if (PEAR::isError($roleInfo)) {
|
||||||
|
return $roleInfo;
|
||||||
|
}
|
||||||
|
if (!$roleInfo['locationconfig']) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ($roleInfo['honorsbaseinstall']) {
|
||||||
|
$dest_dir = $save_destdir = $this->config->get($roleInfo['locationconfig'], $layer,
|
||||||
|
$pkg->getChannel());
|
||||||
|
if (!empty($atts['baseinstalldir'])) {
|
||||||
|
$dest_dir .= DIRECTORY_SEPARATOR . $atts['baseinstalldir'];
|
||||||
|
}
|
||||||
|
} elseif ($roleInfo['unusualbaseinstall']) {
|
||||||
|
$dest_dir = $save_destdir = $this->config->get($roleInfo['locationconfig'],
|
||||||
|
$layer, $pkg->getChannel()) . DIRECTORY_SEPARATOR . $pkg->getPackage();
|
||||||
|
if (!empty($atts['baseinstalldir'])) {
|
||||||
|
$dest_dir .= DIRECTORY_SEPARATOR . $atts['baseinstalldir'];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$dest_dir = $save_destdir = $this->config->get($roleInfo['locationconfig'],
|
||||||
|
$layer, $pkg->getChannel()) . DIRECTORY_SEPARATOR . $pkg->getPackage();
|
||||||
|
}
|
||||||
|
if (dirname($file) != '.' && empty($atts['install-as'])) {
|
||||||
|
$dest_dir .= DIRECTORY_SEPARATOR . dirname($file);
|
||||||
|
}
|
||||||
|
if (empty($atts['install-as'])) {
|
||||||
|
$dest_file = $dest_dir . DIRECTORY_SEPARATOR . basename($file);
|
||||||
|
} else {
|
||||||
|
$dest_file = $dest_dir . DIRECTORY_SEPARATOR . $atts['install-as'];
|
||||||
|
}
|
||||||
|
$orig_file = $tmp_path . DIRECTORY_SEPARATOR . $file;
|
||||||
|
|
||||||
|
// Clean up the DIRECTORY_SEPARATOR mess
|
||||||
|
$ds2 = DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR;
|
||||||
|
|
||||||
|
list($dest_dir, $dest_file, $orig_file) = preg_replace(array('!\\\\+!', '!/!', "!$ds2+!"),
|
||||||
|
array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR,
|
||||||
|
DIRECTORY_SEPARATOR),
|
||||||
|
array($dest_dir, $dest_file, $orig_file));
|
||||||
|
return array($save_destdir, $dest_dir, $dest_file, $orig_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the name of the configuration variable that specifies the location of this file
|
||||||
|
* @return string|false
|
||||||
|
*/
|
||||||
|
function getLocationConfig()
|
||||||
|
{
|
||||||
|
$roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' .
|
||||||
|
ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this)))));
|
||||||
|
if (PEAR::isError($roleInfo)) {
|
||||||
|
return $roleInfo;
|
||||||
|
}
|
||||||
|
return $roleInfo['locationconfig'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do any unusual setup here
|
||||||
|
* @param PEAR_Installer
|
||||||
|
* @param PEAR_PackageFile_v2
|
||||||
|
* @param array file attributes
|
||||||
|
* @param string file name
|
||||||
|
*/
|
||||||
|
function setup(&$installer, $pkg, $atts, $file)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
function isExecutable()
|
||||||
|
{
|
||||||
|
$roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' .
|
||||||
|
ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this)))));
|
||||||
|
if (PEAR::isError($roleInfo)) {
|
||||||
|
return $roleInfo;
|
||||||
|
}
|
||||||
|
return $roleInfo['executable'];
|
||||||
|
}
|
||||||
|
|
||||||
|
function isInstallable()
|
||||||
|
{
|
||||||
|
$roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' .
|
||||||
|
ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this)))));
|
||||||
|
if (PEAR::isError($roleInfo)) {
|
||||||
|
return $roleInfo;
|
||||||
|
}
|
||||||
|
return $roleInfo['installable'];
|
||||||
|
}
|
||||||
|
|
||||||
|
function isExtension()
|
||||||
|
{
|
||||||
|
$roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' .
|
||||||
|
ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this)))));
|
||||||
|
if (PEAR::isError($roleInfo)) {
|
||||||
|
return $roleInfo;
|
||||||
|
}
|
||||||
|
return $roleInfo['phpextension'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PEAR_Installer_Role_Data
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: Data.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
class PEAR_Installer_Role_Data extends PEAR_Installer_Role_Common {}
|
||||||
|
?>
|
|
@ -0,0 +1,15 @@
|
||||||
|
<role version="1.0">
|
||||||
|
<releasetypes>php</releasetypes>
|
||||||
|
<releasetypes>extsrc</releasetypes>
|
||||||
|
<releasetypes>extbin</releasetypes>
|
||||||
|
<releasetypes>zendextsrc</releasetypes>
|
||||||
|
<releasetypes>zendextbin</releasetypes>
|
||||||
|
<installable>1</installable>
|
||||||
|
<locationconfig>data_dir</locationconfig>
|
||||||
|
<honorsbaseinstall />
|
||||||
|
<unusualbaseinstall />
|
||||||
|
<phpfile />
|
||||||
|
<executable />
|
||||||
|
<phpextension />
|
||||||
|
<config_vars />
|
||||||
|
</role>
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PEAR_Installer_Role_Doc
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: Doc.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
class PEAR_Installer_Role_Doc extends PEAR_Installer_Role_Common {}
|
||||||
|
?>
|
|
@ -0,0 +1,15 @@
|
||||||
|
<role version="1.0">
|
||||||
|
<releasetypes>php</releasetypes>
|
||||||
|
<releasetypes>extsrc</releasetypes>
|
||||||
|
<releasetypes>extbin</releasetypes>
|
||||||
|
<releasetypes>zendextsrc</releasetypes>
|
||||||
|
<releasetypes>zendextbin</releasetypes>
|
||||||
|
<installable>1</installable>
|
||||||
|
<locationconfig>doc_dir</locationconfig>
|
||||||
|
<honorsbaseinstall />
|
||||||
|
<unusualbaseinstall />
|
||||||
|
<phpfile />
|
||||||
|
<executable />
|
||||||
|
<phpextension />
|
||||||
|
<config_vars />
|
||||||
|
</role>
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PEAR_Installer_Role_Ext
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: Ext.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
class PEAR_Installer_Role_Ext extends PEAR_Installer_Role_Common {}
|
||||||
|
?>
|
|
@ -0,0 +1,12 @@
|
||||||
|
<role version="1.0">
|
||||||
|
<releasetypes>extbin</releasetypes>
|
||||||
|
<releasetypes>zendextbin</releasetypes>
|
||||||
|
<installable>1</installable>
|
||||||
|
<locationconfig>ext_dir</locationconfig>
|
||||||
|
<honorsbaseinstall>1</honorsbaseinstall>
|
||||||
|
<unusualbaseinstall />
|
||||||
|
<phpfile />
|
||||||
|
<executable />
|
||||||
|
<phpextension>1</phpextension>
|
||||||
|
<config_vars />
|
||||||
|
</role>
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PEAR_Installer_Role_Php
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: Php.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
class PEAR_Installer_Role_Php extends PEAR_Installer_Role_Common {}
|
||||||
|
?>
|
|
@ -0,0 +1,15 @@
|
||||||
|
<role version="1.0">
|
||||||
|
<releasetypes>php</releasetypes>
|
||||||
|
<releasetypes>extsrc</releasetypes>
|
||||||
|
<releasetypes>extbin</releasetypes>
|
||||||
|
<releasetypes>zendextsrc</releasetypes>
|
||||||
|
<releasetypes>zendextbin</releasetypes>
|
||||||
|
<installable>1</installable>
|
||||||
|
<locationconfig>php_dir</locationconfig>
|
||||||
|
<honorsbaseinstall>1</honorsbaseinstall>
|
||||||
|
<unusualbaseinstall />
|
||||||
|
<phpfile>1</phpfile>
|
||||||
|
<executable />
|
||||||
|
<phpextension />
|
||||||
|
<config_vars />
|
||||||
|
</role>
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PEAR_Installer_Role_Script
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: Script.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
class PEAR_Installer_Role_Script extends PEAR_Installer_Role_Common {}
|
||||||
|
?>
|
|
@ -0,0 +1,15 @@
|
||||||
|
<role version="1.0">
|
||||||
|
<releasetypes>php</releasetypes>
|
||||||
|
<releasetypes>extsrc</releasetypes>
|
||||||
|
<releasetypes>extbin</releasetypes>
|
||||||
|
<releasetypes>zendextsrc</releasetypes>
|
||||||
|
<releasetypes>zendextbin</releasetypes>
|
||||||
|
<installable>1</installable>
|
||||||
|
<locationconfig>bin_dir</locationconfig>
|
||||||
|
<honorsbaseinstall>1</honorsbaseinstall>
|
||||||
|
<unusualbaseinstall />
|
||||||
|
<phpfile />
|
||||||
|
<executable>1</executable>
|
||||||
|
<phpextension />
|
||||||
|
<config_vars />
|
||||||
|
</role>
|
|
@ -0,0 +1,34 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PEAR_Installer_Role_Src
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: Src.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
class PEAR_Installer_Role_Src extends PEAR_Installer_Role_Common
|
||||||
|
{
|
||||||
|
function setup(&$installer, $pkg, $atts, $file)
|
||||||
|
{
|
||||||
|
$installer->source_files++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
|
@ -0,0 +1,12 @@
|
||||||
|
<role version="1.0">
|
||||||
|
<releasetypes>extsrc</releasetypes>
|
||||||
|
<releasetypes>zendextsrc</releasetypes>
|
||||||
|
<installable>1</installable>
|
||||||
|
<locationconfig>temp_dir</locationconfig>
|
||||||
|
<honorsbaseinstall />
|
||||||
|
<unusualbaseinstall />
|
||||||
|
<phpfile />
|
||||||
|
<executable />
|
||||||
|
<phpextension />
|
||||||
|
<config_vars />
|
||||||
|
</role>
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PEAR_Installer_Role_Test
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: Test.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
class PEAR_Installer_Role_Test extends PEAR_Installer_Role_Common {}
|
||||||
|
?>
|
|
@ -0,0 +1,15 @@
|
||||||
|
<role version="1.0">
|
||||||
|
<releasetypes>php</releasetypes>
|
||||||
|
<releasetypes>extsrc</releasetypes>
|
||||||
|
<releasetypes>extbin</releasetypes>
|
||||||
|
<releasetypes>zendextsrc</releasetypes>
|
||||||
|
<releasetypes>zendextbin</releasetypes>
|
||||||
|
<installable>1</installable>
|
||||||
|
<locationconfig>test_dir</locationconfig>
|
||||||
|
<honorsbaseinstall />
|
||||||
|
<unusualbaseinstall />
|
||||||
|
<phpfile />
|
||||||
|
<executable />
|
||||||
|
<phpextension />
|
||||||
|
<config_vars />
|
||||||
|
</role>
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PEAR_Installer_Role_Www
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 2007-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: Www.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since Release 1.7.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 2007-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 1.7.0
|
||||||
|
*/
|
||||||
|
class PEAR_Installer_Role_Www extends PEAR_Installer_Role_Common {}
|
||||||
|
?>
|
|
@ -0,0 +1,15 @@
|
||||||
|
<role version="1.0">
|
||||||
|
<releasetypes>php</releasetypes>
|
||||||
|
<releasetypes>extsrc</releasetypes>
|
||||||
|
<releasetypes>extbin</releasetypes>
|
||||||
|
<releasetypes>zendextsrc</releasetypes>
|
||||||
|
<releasetypes>zendextbin</releasetypes>
|
||||||
|
<installable>1</installable>
|
||||||
|
<locationconfig>www_dir</locationconfig>
|
||||||
|
<honorsbaseinstall>1</honorsbaseinstall>
|
||||||
|
<unusualbaseinstall />
|
||||||
|
<phpfile />
|
||||||
|
<executable />
|
||||||
|
<phpextension />
|
||||||
|
<config_vars />
|
||||||
|
</role>
|
|
@ -0,0 +1,492 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PEAR_PackageFile, package.xml parsing utility class
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: PackageFile.php 313024 2011-07-06 19:51:24Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* needed for PEAR_VALIDATE_* constants
|
||||||
|
*/
|
||||||
|
require_once 'PEAR/Validate.php';
|
||||||
|
/**
|
||||||
|
* Error code if the package.xml <package> tag does not contain a valid version
|
||||||
|
*/
|
||||||
|
define('PEAR_PACKAGEFILE_ERROR_NO_PACKAGEVERSION', 1);
|
||||||
|
/**
|
||||||
|
* Error code if the package.xml <package> tag version is not supported (version 1.0 and 1.1 are the only supported versions,
|
||||||
|
* currently
|
||||||
|
*/
|
||||||
|
define('PEAR_PACKAGEFILE_ERROR_INVALID_PACKAGEVERSION', 2);
|
||||||
|
/**
|
||||||
|
* Abstraction for the package.xml package description file
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
class PEAR_PackageFile
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var PEAR_Config
|
||||||
|
*/
|
||||||
|
var $_config;
|
||||||
|
var $_debug;
|
||||||
|
|
||||||
|
var $_logger = false;
|
||||||
|
/**
|
||||||
|
* @var boolean
|
||||||
|
*/
|
||||||
|
var $_rawReturn = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* helper for extracting Archive_Tar errors
|
||||||
|
* @var array
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $_extractErrors = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param PEAR_Config $config
|
||||||
|
* @param ? $debug
|
||||||
|
* @param string @tmpdir Optional temporary directory for uncompressing
|
||||||
|
* files
|
||||||
|
*/
|
||||||
|
function PEAR_PackageFile(&$config, $debug = false)
|
||||||
|
{
|
||||||
|
$this->_config = $config;
|
||||||
|
$this->_debug = $debug;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turn off validation - return a parsed package.xml without checking it
|
||||||
|
*
|
||||||
|
* This is used by the package-validate command
|
||||||
|
*/
|
||||||
|
function rawReturn()
|
||||||
|
{
|
||||||
|
$this->_rawReturn = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setLogger(&$l)
|
||||||
|
{
|
||||||
|
$this->_logger = &$l;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a PEAR_PackageFile_Parser_v* of a given version.
|
||||||
|
* @param int $version
|
||||||
|
* @return PEAR_PackageFile_Parser_v1|PEAR_PackageFile_Parser_v1
|
||||||
|
*/
|
||||||
|
function &parserFactory($version)
|
||||||
|
{
|
||||||
|
if (!in_array($version{0}, array('1', '2'))) {
|
||||||
|
$a = false;
|
||||||
|
return $a;
|
||||||
|
}
|
||||||
|
|
||||||
|
include_once 'PEAR/PackageFile/Parser/v' . $version{0} . '.php';
|
||||||
|
$version = $version{0};
|
||||||
|
$class = "PEAR_PackageFile_Parser_v$version";
|
||||||
|
$a = new $class;
|
||||||
|
return $a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For simpler unit-testing
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function getClassPrefix()
|
||||||
|
{
|
||||||
|
return 'PEAR_PackageFile_v';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a PEAR_PackageFile_v* of a given version.
|
||||||
|
* @param int $version
|
||||||
|
* @return PEAR_PackageFile_v1|PEAR_PackageFile_v1
|
||||||
|
*/
|
||||||
|
function &factory($version)
|
||||||
|
{
|
||||||
|
if (!in_array($version{0}, array('1', '2'))) {
|
||||||
|
$a = false;
|
||||||
|
return $a;
|
||||||
|
}
|
||||||
|
|
||||||
|
include_once 'PEAR/PackageFile/v' . $version{0} . '.php';
|
||||||
|
$version = $version{0};
|
||||||
|
$class = $this->getClassPrefix() . $version;
|
||||||
|
$a = new $class;
|
||||||
|
return $a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a PEAR_PackageFile_v* from its toArray() method
|
||||||
|
*
|
||||||
|
* WARNING: no validation is performed, the array is assumed to be valid,
|
||||||
|
* always parse from xml if you want validation.
|
||||||
|
* @param array $arr
|
||||||
|
* @return PEAR_PackageFileManager_v1|PEAR_PackageFileManager_v2
|
||||||
|
* @uses factory() to construct the returned object.
|
||||||
|
*/
|
||||||
|
function &fromArray($arr)
|
||||||
|
{
|
||||||
|
if (isset($arr['xsdversion'])) {
|
||||||
|
$obj = &$this->factory($arr['xsdversion']);
|
||||||
|
if ($this->_logger) {
|
||||||
|
$obj->setLogger($this->_logger);
|
||||||
|
}
|
||||||
|
|
||||||
|
$obj->setConfig($this->_config);
|
||||||
|
$obj->fromArray($arr);
|
||||||
|
return $obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($arr['package']['attribs']['version'])) {
|
||||||
|
$obj = &$this->factory($arr['package']['attribs']['version']);
|
||||||
|
} else {
|
||||||
|
$obj = &$this->factory('1.0');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->_logger) {
|
||||||
|
$obj->setLogger($this->_logger);
|
||||||
|
}
|
||||||
|
|
||||||
|
$obj->setConfig($this->_config);
|
||||||
|
$obj->fromArray($arr);
|
||||||
|
return $obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a PEAR_PackageFile_v* from an XML string.
|
||||||
|
* @access public
|
||||||
|
* @param string $data contents of package.xml file
|
||||||
|
* @param int $state package state (one of PEAR_VALIDATE_* constants)
|
||||||
|
* @param string $file full path to the package.xml file (and the files
|
||||||
|
* it references)
|
||||||
|
* @param string $archive optional name of the archive that the XML was
|
||||||
|
* extracted from, if any
|
||||||
|
* @return PEAR_PackageFile_v1|PEAR_PackageFile_v2
|
||||||
|
* @uses parserFactory() to construct a parser to load the package.
|
||||||
|
*/
|
||||||
|
function &fromXmlString($data, $state, $file, $archive = false)
|
||||||
|
{
|
||||||
|
if (preg_match('/<package[^>]+version=[\'"]([0-9]+\.[0-9]+)[\'"]/', $data, $packageversion)) {
|
||||||
|
if (!in_array($packageversion[1], array('1.0', '2.0', '2.1'))) {
|
||||||
|
return PEAR::raiseError('package.xml version "' . $packageversion[1] .
|
||||||
|
'" is not supported, only 1.0, 2.0, and 2.1 are supported.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$object = &$this->parserFactory($packageversion[1]);
|
||||||
|
if ($this->_logger) {
|
||||||
|
$object->setLogger($this->_logger);
|
||||||
|
}
|
||||||
|
|
||||||
|
$object->setConfig($this->_config);
|
||||||
|
$pf = $object->parse($data, $file, $archive);
|
||||||
|
if (PEAR::isError($pf)) {
|
||||||
|
return $pf;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->_rawReturn) {
|
||||||
|
return $pf;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$pf->validate($state)) {;
|
||||||
|
if ($this->_config->get('verbose') > 0
|
||||||
|
&& $this->_logger && $pf->getValidationWarnings(false)
|
||||||
|
) {
|
||||||
|
foreach ($pf->getValidationWarnings(false) as $warning) {
|
||||||
|
$this->_logger->log(0, 'ERROR: ' . $warning['message']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$a = PEAR::raiseError('Parsing of package.xml from file "' . $file . '" failed',
|
||||||
|
2, null, null, $pf->getValidationWarnings());
|
||||||
|
return $a;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->_logger && $pf->getValidationWarnings(false)) {
|
||||||
|
foreach ($pf->getValidationWarnings() as $warning) {
|
||||||
|
$this->_logger->log(0, 'WARNING: ' . $warning['message']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (method_exists($pf, 'flattenFilelist')) {
|
||||||
|
$pf->flattenFilelist(); // for v2
|
||||||
|
}
|
||||||
|
|
||||||
|
return $pf;
|
||||||
|
} elseif (preg_match('/<package[^>]+version=[\'"]([^"\']+)[\'"]/', $data, $packageversion)) {
|
||||||
|
$a = PEAR::raiseError('package.xml file "' . $file .
|
||||||
|
'" has unsupported package.xml <package> version "' . $packageversion[1] . '"');
|
||||||
|
return $a;
|
||||||
|
} else {
|
||||||
|
if (!class_exists('PEAR_ErrorStack')) {
|
||||||
|
require_once 'PEAR/ErrorStack.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
PEAR_ErrorStack::staticPush('PEAR_PackageFile',
|
||||||
|
PEAR_PACKAGEFILE_ERROR_NO_PACKAGEVERSION,
|
||||||
|
'warning', array('xml' => $data), 'package.xml "' . $file .
|
||||||
|
'" has no package.xml <package> version');
|
||||||
|
$object = &$this->parserFactory('1.0');
|
||||||
|
$object->setConfig($this->_config);
|
||||||
|
$pf = $object->parse($data, $file, $archive);
|
||||||
|
if (PEAR::isError($pf)) {
|
||||||
|
return $pf;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->_rawReturn) {
|
||||||
|
return $pf;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$pf->validate($state)) {
|
||||||
|
$a = PEAR::raiseError('Parsing of package.xml from file "' . $file . '" failed',
|
||||||
|
2, null, null, $pf->getValidationWarnings());
|
||||||
|
return $a;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->_logger && $pf->getValidationWarnings(false)) {
|
||||||
|
foreach ($pf->getValidationWarnings() as $warning) {
|
||||||
|
$this->_logger->log(0, 'WARNING: ' . $warning['message']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (method_exists($pf, 'flattenFilelist')) {
|
||||||
|
$pf->flattenFilelist(); // for v2
|
||||||
|
}
|
||||||
|
|
||||||
|
return $pf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a temporary file or directory. When the destructor is
|
||||||
|
* executed, all registered temporary files and directories are
|
||||||
|
* removed.
|
||||||
|
*
|
||||||
|
* @param string $file name of file or directory
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function addTempFile($file)
|
||||||
|
{
|
||||||
|
$GLOBALS['_PEAR_Common_tempfiles'][] = $file;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a PEAR_PackageFile_v* from a compresed Tar or Tgz file.
|
||||||
|
* @access public
|
||||||
|
* @param string contents of package.xml file
|
||||||
|
* @param int package state (one of PEAR_VALIDATE_* constants)
|
||||||
|
* @return PEAR_PackageFile_v1|PEAR_PackageFile_v2
|
||||||
|
* @using Archive_Tar to extract the files
|
||||||
|
* @using fromPackageFile() to load the package after the package.xml
|
||||||
|
* file is extracted.
|
||||||
|
*/
|
||||||
|
function &fromTgzFile($file, $state)
|
||||||
|
{
|
||||||
|
if (!class_exists('Archive_Tar')) {
|
||||||
|
require_once 'Archive/Tar.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
$tar = new Archive_Tar($file);
|
||||||
|
if ($this->_debug <= 1) {
|
||||||
|
$tar->pushErrorHandling(PEAR_ERROR_RETURN);
|
||||||
|
}
|
||||||
|
|
||||||
|
$content = $tar->listContent();
|
||||||
|
if ($this->_debug <= 1) {
|
||||||
|
$tar->popErrorHandling();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($content)) {
|
||||||
|
if (is_string($file) && strlen($file < 255) &&
|
||||||
|
(!file_exists($file) || !@is_file($file))) {
|
||||||
|
$ret = PEAR::raiseError("could not open file \"$file\"");
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
$file = realpath($file);
|
||||||
|
$ret = PEAR::raiseError("Could not get contents of package \"$file\"".
|
||||||
|
'. Invalid tgz file.');
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!count($content) && !@is_file($file)) {
|
||||||
|
$ret = PEAR::raiseError("could not open file \"$file\"");
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
$xml = null;
|
||||||
|
$origfile = $file;
|
||||||
|
foreach ($content as $file) {
|
||||||
|
$name = $file['filename'];
|
||||||
|
if ($name == 'package2.xml') { // allow a .tgz to distribute both versions
|
||||||
|
$xml = $name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($name == 'package.xml') {
|
||||||
|
$xml = $name;
|
||||||
|
break;
|
||||||
|
} elseif (preg_match('/package.xml$/', $name, $match)) {
|
||||||
|
$xml = $name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$tmpdir = System::mktemp('-t "' . $this->_config->get('temp_dir') . '" -d pear');
|
||||||
|
if ($tmpdir === false) {
|
||||||
|
$ret = PEAR::raiseError("there was a problem with getting the configured temp directory");
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
PEAR_PackageFile::addTempFile($tmpdir);
|
||||||
|
|
||||||
|
$this->_extractErrors();
|
||||||
|
PEAR::staticPushErrorHandling(PEAR_ERROR_CALLBACK, array($this, '_extractErrors'));
|
||||||
|
|
||||||
|
if (!$xml || !$tar->extractList(array($xml), $tmpdir)) {
|
||||||
|
$extra = implode("\n", $this->_extractErrors());
|
||||||
|
if ($extra) {
|
||||||
|
$extra = ' ' . $extra;
|
||||||
|
}
|
||||||
|
|
||||||
|
PEAR::staticPopErrorHandling();
|
||||||
|
$ret = PEAR::raiseError('could not extract the package.xml file from "' .
|
||||||
|
$origfile . '"' . $extra);
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
PEAR::staticPopErrorHandling();
|
||||||
|
$ret = &PEAR_PackageFile::fromPackageFile("$tmpdir/$xml", $state, $origfile);
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* helper callback for extracting Archive_Tar errors
|
||||||
|
*
|
||||||
|
* @param PEAR_Error|null $err
|
||||||
|
* @return array
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _extractErrors($err = null)
|
||||||
|
{
|
||||||
|
static $errors = array();
|
||||||
|
if ($err === null) {
|
||||||
|
$e = $errors;
|
||||||
|
$errors = array();
|
||||||
|
return $e;
|
||||||
|
}
|
||||||
|
$errors[] = $err->getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a PEAR_PackageFile_v* from a package.xml file.
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $descfile name of package xml file
|
||||||
|
* @param int $state package state (one of PEAR_VALIDATE_* constants)
|
||||||
|
* @param string|false $archive name of the archive this package.xml came
|
||||||
|
* from, if any
|
||||||
|
* @return PEAR_PackageFile_v1|PEAR_PackageFile_v2
|
||||||
|
* @uses PEAR_PackageFile::fromXmlString to create the oject after the
|
||||||
|
* XML is loaded from the package.xml file.
|
||||||
|
*/
|
||||||
|
function &fromPackageFile($descfile, $state, $archive = false)
|
||||||
|
{
|
||||||
|
$fp = false;
|
||||||
|
if (is_string($descfile) && strlen($descfile) < 255 &&
|
||||||
|
(
|
||||||
|
!file_exists($descfile) || !is_file($descfile) || !is_readable($descfile)
|
||||||
|
|| (!$fp = @fopen($descfile, 'r'))
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
$a = PEAR::raiseError("Unable to open $descfile");
|
||||||
|
return $a;
|
||||||
|
}
|
||||||
|
|
||||||
|
// read the whole thing so we only get one cdata callback
|
||||||
|
// for each block of cdata
|
||||||
|
fclose($fp);
|
||||||
|
$data = file_get_contents($descfile);
|
||||||
|
$ret = &PEAR_PackageFile::fromXmlString($data, $state, $descfile, $archive);
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a PEAR_PackageFile_v* from a .tgz archive or package.xml file.
|
||||||
|
*
|
||||||
|
* This method is able to extract information about a package from a .tgz
|
||||||
|
* archive or from a XML package definition file.
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $info file name
|
||||||
|
* @param int $state package state (one of PEAR_VALIDATE_* constants)
|
||||||
|
* @return PEAR_PackageFile_v1|PEAR_PackageFile_v2
|
||||||
|
* @uses fromPackageFile() if the file appears to be XML
|
||||||
|
* @uses fromTgzFile() to load all non-XML files
|
||||||
|
*/
|
||||||
|
function &fromAnyFile($info, $state)
|
||||||
|
{
|
||||||
|
if (is_dir($info)) {
|
||||||
|
$dir_name = realpath($info);
|
||||||
|
if (file_exists($dir_name . '/package.xml')) {
|
||||||
|
$info = PEAR_PackageFile::fromPackageFile($dir_name . '/package.xml', $state);
|
||||||
|
} elseif (file_exists($dir_name . '/package2.xml')) {
|
||||||
|
$info = PEAR_PackageFile::fromPackageFile($dir_name . '/package2.xml', $state);
|
||||||
|
} else {
|
||||||
|
$info = PEAR::raiseError("No package definition found in '$info' directory");
|
||||||
|
}
|
||||||
|
|
||||||
|
return $info;
|
||||||
|
}
|
||||||
|
|
||||||
|
$fp = false;
|
||||||
|
if (is_string($info) && strlen($info) < 255 &&
|
||||||
|
(file_exists($info) || ($fp = @fopen($info, 'r')))
|
||||||
|
) {
|
||||||
|
|
||||||
|
if ($fp) {
|
||||||
|
fclose($fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
$tmp = substr($info, -4);
|
||||||
|
if ($tmp == '.xml') {
|
||||||
|
$info = &PEAR_PackageFile::fromPackageFile($info, $state);
|
||||||
|
} elseif ($tmp == '.tar' || $tmp == '.tgz') {
|
||||||
|
$info = &PEAR_PackageFile::fromTgzFile($info, $state);
|
||||||
|
} else {
|
||||||
|
$fp = fopen($info, 'r');
|
||||||
|
$test = fread($fp, 5);
|
||||||
|
fclose($fp);
|
||||||
|
if ($test == '<?xml') {
|
||||||
|
$info = &PEAR_PackageFile::fromPackageFile($info, $state);
|
||||||
|
} else {
|
||||||
|
$info = &PEAR_PackageFile::fromTgzFile($info, $state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $info;
|
||||||
|
}
|
||||||
|
|
||||||
|
$info = PEAR::raiseError("Cannot open '$info' for parsing");
|
||||||
|
return $info;
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,893 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* package.xml generation class, package.xml version 2.0
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @author Stephan Schmidt (original XML_Serializer code)
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: v2.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* file/dir manipulation routines
|
||||||
|
*/
|
||||||
|
require_once 'System.php';
|
||||||
|
require_once 'XML/Util.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class converts a PEAR_PackageFile_v2 object into any output format.
|
||||||
|
*
|
||||||
|
* Supported output formats include array, XML string (using S. Schmidt's
|
||||||
|
* XML_Serializer, slightly customized)
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @author Stephan Schmidt (original XML_Serializer code)
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
class PEAR_PackageFile_Generator_v2
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* default options for the serialization
|
||||||
|
* @access private
|
||||||
|
* @var array $_defaultOptions
|
||||||
|
*/
|
||||||
|
var $_defaultOptions = array(
|
||||||
|
'indent' => ' ', // string used for indentation
|
||||||
|
'linebreak' => "\n", // string used for newlines
|
||||||
|
'typeHints' => false, // automatically add type hin attributes
|
||||||
|
'addDecl' => true, // add an XML declaration
|
||||||
|
'defaultTagName' => 'XML_Serializer_Tag', // tag used for indexed arrays or invalid names
|
||||||
|
'classAsTagName' => false, // use classname for objects in indexed arrays
|
||||||
|
'keyAttribute' => '_originalKey', // attribute where original key is stored
|
||||||
|
'typeAttribute' => '_type', // attribute for type (only if typeHints => true)
|
||||||
|
'classAttribute' => '_class', // attribute for class of objects (only if typeHints => true)
|
||||||
|
'scalarAsAttributes' => false, // scalar values (strings, ints,..) will be serialized as attribute
|
||||||
|
'prependAttributes' => '', // prepend string for attributes
|
||||||
|
'indentAttributes' => false, // indent the attributes, if set to '_auto', it will indent attributes so they all start at the same column
|
||||||
|
'mode' => 'simplexml', // use 'simplexml' to use parent name as tagname if transforming an indexed array
|
||||||
|
'addDoctype' => false, // add a doctype declaration
|
||||||
|
'doctype' => null, // supply a string or an array with id and uri ({@see XML_Util::getDoctypeDeclaration()}
|
||||||
|
'rootName' => 'package', // name of the root tag
|
||||||
|
'rootAttributes' => array(
|
||||||
|
'version' => '2.0',
|
||||||
|
'xmlns' => 'http://pear.php.net/dtd/package-2.0',
|
||||||
|
'xmlns:tasks' => 'http://pear.php.net/dtd/tasks-1.0',
|
||||||
|
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
|
||||||
|
'xsi:schemaLocation' => 'http://pear.php.net/dtd/tasks-1.0
|
||||||
|
http://pear.php.net/dtd/tasks-1.0.xsd
|
||||||
|
http://pear.php.net/dtd/package-2.0
|
||||||
|
http://pear.php.net/dtd/package-2.0.xsd',
|
||||||
|
), // attributes of the root tag
|
||||||
|
'attributesArray' => 'attribs', // all values in this key will be treated as attributes
|
||||||
|
'contentName' => '_content', // this value will be used directly as content, instead of creating a new tag, may only be used in conjuction with attributesArray
|
||||||
|
'beautifyFilelist' => false,
|
||||||
|
'encoding' => 'UTF-8',
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* options for the serialization
|
||||||
|
* @access private
|
||||||
|
* @var array $options
|
||||||
|
*/
|
||||||
|
var $options = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* current tag depth
|
||||||
|
* @var integer $_tagDepth
|
||||||
|
*/
|
||||||
|
var $_tagDepth = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* serilialized representation of the data
|
||||||
|
* @var string $_serializedData
|
||||||
|
*/
|
||||||
|
var $_serializedData = null;
|
||||||
|
/**
|
||||||
|
* @var PEAR_PackageFile_v2
|
||||||
|
*/
|
||||||
|
var $_packagefile;
|
||||||
|
/**
|
||||||
|
* @param PEAR_PackageFile_v2
|
||||||
|
*/
|
||||||
|
function PEAR_PackageFile_Generator_v2(&$packagefile)
|
||||||
|
{
|
||||||
|
$this->_packagefile = &$packagefile;
|
||||||
|
if (isset($this->_packagefile->encoding)) {
|
||||||
|
$this->_defaultOptions['encoding'] = $this->_packagefile->encoding;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function getPackagerVersion()
|
||||||
|
{
|
||||||
|
return '1.9.4';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param PEAR_Packager
|
||||||
|
* @param bool generate a .tgz or a .tar
|
||||||
|
* @param string|null temporary directory to package in
|
||||||
|
*/
|
||||||
|
function toTgz(&$packager, $compress = true, $where = null)
|
||||||
|
{
|
||||||
|
$a = null;
|
||||||
|
return $this->toTgz2($packager, $a, $compress, $where);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Package up both a package.xml and package2.xml for the same release
|
||||||
|
* @param PEAR_Packager
|
||||||
|
* @param PEAR_PackageFile_v1
|
||||||
|
* @param bool generate a .tgz or a .tar
|
||||||
|
* @param string|null temporary directory to package in
|
||||||
|
*/
|
||||||
|
function toTgz2(&$packager, &$pf1, $compress = true, $where = null)
|
||||||
|
{
|
||||||
|
require_once 'Archive/Tar.php';
|
||||||
|
if (!$this->_packagefile->isEquivalent($pf1)) {
|
||||||
|
return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: "' .
|
||||||
|
basename($pf1->getPackageFile()) .
|
||||||
|
'" is not equivalent to "' . basename($this->_packagefile->getPackageFile())
|
||||||
|
. '"');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($where === null) {
|
||||||
|
if (!($where = System::mktemp(array('-d')))) {
|
||||||
|
return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: mktemp failed');
|
||||||
|
}
|
||||||
|
} elseif (!@System::mkDir(array('-p', $where))) {
|
||||||
|
return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: "' . $where . '" could' .
|
||||||
|
' not be created');
|
||||||
|
}
|
||||||
|
|
||||||
|
$file = $where . DIRECTORY_SEPARATOR . 'package.xml';
|
||||||
|
if (file_exists($file) && !is_file($file)) {
|
||||||
|
return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: unable to save package.xml as' .
|
||||||
|
' "' . $file .'"');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->_packagefile->validate(PEAR_VALIDATE_PACKAGING)) {
|
||||||
|
return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: invalid package.xml');
|
||||||
|
}
|
||||||
|
|
||||||
|
$ext = $compress ? '.tgz' : '.tar';
|
||||||
|
$pkgver = $this->_packagefile->getPackage() . '-' . $this->_packagefile->getVersion();
|
||||||
|
$dest_package = getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext;
|
||||||
|
if (file_exists($dest_package) && !is_file($dest_package)) {
|
||||||
|
return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: cannot create tgz file "' .
|
||||||
|
$dest_package . '"');
|
||||||
|
}
|
||||||
|
|
||||||
|
$pkgfile = $this->_packagefile->getPackageFile();
|
||||||
|
if (!$pkgfile) {
|
||||||
|
return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: package file object must ' .
|
||||||
|
'be created from a real file');
|
||||||
|
}
|
||||||
|
|
||||||
|
$pkgdir = dirname(realpath($pkgfile));
|
||||||
|
$pkgfile = basename($pkgfile);
|
||||||
|
|
||||||
|
// {{{ Create the package file list
|
||||||
|
$filelist = array();
|
||||||
|
$i = 0;
|
||||||
|
$this->_packagefile->flattenFilelist();
|
||||||
|
$contents = $this->_packagefile->getContents();
|
||||||
|
if (isset($contents['bundledpackage'])) { // bundles of packages
|
||||||
|
$contents = $contents['bundledpackage'];
|
||||||
|
if (!isset($contents[0])) {
|
||||||
|
$contents = array($contents);
|
||||||
|
}
|
||||||
|
|
||||||
|
$packageDir = $where;
|
||||||
|
foreach ($contents as $i => $package) {
|
||||||
|
$fname = $package;
|
||||||
|
$file = $pkgdir . DIRECTORY_SEPARATOR . $fname;
|
||||||
|
if (!file_exists($file)) {
|
||||||
|
return $packager->raiseError("File does not exist: $fname");
|
||||||
|
}
|
||||||
|
|
||||||
|
$tfile = $packageDir . DIRECTORY_SEPARATOR . $fname;
|
||||||
|
System::mkdir(array('-p', dirname($tfile)));
|
||||||
|
copy($file, $tfile);
|
||||||
|
$filelist[$i++] = $tfile;
|
||||||
|
$packager->log(2, "Adding package $fname");
|
||||||
|
}
|
||||||
|
} else { // normal packages
|
||||||
|
$contents = $contents['dir']['file'];
|
||||||
|
if (!isset($contents[0])) {
|
||||||
|
$contents = array($contents);
|
||||||
|
}
|
||||||
|
|
||||||
|
$packageDir = $where;
|
||||||
|
foreach ($contents as $i => $file) {
|
||||||
|
$fname = $file['attribs']['name'];
|
||||||
|
$atts = $file['attribs'];
|
||||||
|
$orig = $file;
|
||||||
|
$file = $pkgdir . DIRECTORY_SEPARATOR . $fname;
|
||||||
|
if (!file_exists($file)) {
|
||||||
|
return $packager->raiseError("File does not exist: $fname");
|
||||||
|
}
|
||||||
|
|
||||||
|
$origperms = fileperms($file);
|
||||||
|
$tfile = $packageDir . DIRECTORY_SEPARATOR . $fname;
|
||||||
|
unset($orig['attribs']);
|
||||||
|
if (count($orig)) { // file with tasks
|
||||||
|
// run any package-time tasks
|
||||||
|
$contents = file_get_contents($file);
|
||||||
|
foreach ($orig as $tag => $raw) {
|
||||||
|
$tag = str_replace(
|
||||||
|
array($this->_packagefile->getTasksNs() . ':', '-'),
|
||||||
|
array('', '_'), $tag);
|
||||||
|
$task = "PEAR_Task_$tag";
|
||||||
|
$task = &new $task($this->_packagefile->_config,
|
||||||
|
$this->_packagefile->_logger,
|
||||||
|
PEAR_TASK_PACKAGE);
|
||||||
|
$task->init($raw, $atts, null);
|
||||||
|
$res = $task->startSession($this->_packagefile, $contents, $tfile);
|
||||||
|
if (!$res) {
|
||||||
|
continue; // skip this task
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PEAR::isError($res)) {
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
|
|
||||||
|
$contents = $res; // save changes
|
||||||
|
System::mkdir(array('-p', dirname($tfile)));
|
||||||
|
$wp = fopen($tfile, "wb");
|
||||||
|
fwrite($wp, $contents);
|
||||||
|
fclose($wp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!file_exists($tfile)) {
|
||||||
|
System::mkdir(array('-p', dirname($tfile)));
|
||||||
|
copy($file, $tfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
chmod($tfile, $origperms);
|
||||||
|
$filelist[$i++] = $tfile;
|
||||||
|
$this->_packagefile->setFileAttribute($fname, 'md5sum', md5_file($tfile), $i - 1);
|
||||||
|
$packager->log(2, "Adding file $fname");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
$name = $pf1 !== null ? 'package2.xml' : 'package.xml';
|
||||||
|
$packagexml = $this->toPackageFile($where, PEAR_VALIDATE_PACKAGING, $name);
|
||||||
|
if ($packagexml) {
|
||||||
|
$tar =& new Archive_Tar($dest_package, $compress);
|
||||||
|
$tar->setErrorHandling(PEAR_ERROR_RETURN); // XXX Don't print errors
|
||||||
|
// ----- Creates with the package.xml file
|
||||||
|
$ok = $tar->createModify(array($packagexml), '', $where);
|
||||||
|
if (PEAR::isError($ok)) {
|
||||||
|
return $packager->raiseError($ok);
|
||||||
|
} elseif (!$ok) {
|
||||||
|
return $packager->raiseError('PEAR_Packagefile_v2::toTgz(): adding ' . $name .
|
||||||
|
' failed');
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----- Add the content of the package
|
||||||
|
if (!$tar->addModify($filelist, $pkgver, $where)) {
|
||||||
|
return $packager->raiseError(
|
||||||
|
'PEAR_Packagefile_v2::toTgz(): tarball creation failed');
|
||||||
|
}
|
||||||
|
|
||||||
|
// add the package.xml version 1.0
|
||||||
|
if ($pf1 !== null) {
|
||||||
|
$pfgen = &$pf1->getDefaultGenerator();
|
||||||
|
$packagexml1 = $pfgen->toPackageFile($where, PEAR_VALIDATE_PACKAGING, 'package.xml', true);
|
||||||
|
if (!$tar->addModify(array($packagexml1), '', $where)) {
|
||||||
|
return $packager->raiseError(
|
||||||
|
'PEAR_Packagefile_v2::toTgz(): adding package.xml failed');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $dest_package;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toPackageFile($where = null, $state = PEAR_VALIDATE_NORMAL, $name = 'package.xml')
|
||||||
|
{
|
||||||
|
if (!$this->_packagefile->validate($state)) {
|
||||||
|
return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: invalid package.xml',
|
||||||
|
null, null, null, $this->_packagefile->getValidationWarnings());
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($where === null) {
|
||||||
|
if (!($where = System::mktemp(array('-d')))) {
|
||||||
|
return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: mktemp failed');
|
||||||
|
}
|
||||||
|
} elseif (!@System::mkDir(array('-p', $where))) {
|
||||||
|
return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: "' . $where . '" could' .
|
||||||
|
' not be created');
|
||||||
|
}
|
||||||
|
|
||||||
|
$newpkgfile = $where . DIRECTORY_SEPARATOR . $name;
|
||||||
|
$np = @fopen($newpkgfile, 'wb');
|
||||||
|
if (!$np) {
|
||||||
|
return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: unable to save ' .
|
||||||
|
"$name as $newpkgfile");
|
||||||
|
}
|
||||||
|
fwrite($np, $this->toXml($state));
|
||||||
|
fclose($np);
|
||||||
|
return $newpkgfile;
|
||||||
|
}
|
||||||
|
|
||||||
|
function &toV2()
|
||||||
|
{
|
||||||
|
return $this->_packagefile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an XML document based on the package info (as returned
|
||||||
|
* by the PEAR_Common::infoFrom* methods).
|
||||||
|
*
|
||||||
|
* @return string XML data
|
||||||
|
*/
|
||||||
|
function toXml($state = PEAR_VALIDATE_NORMAL, $options = array())
|
||||||
|
{
|
||||||
|
$this->_packagefile->setDate(date('Y-m-d'));
|
||||||
|
$this->_packagefile->setTime(date('H:i:s'));
|
||||||
|
if (!$this->_packagefile->validate($state)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_array($options)) {
|
||||||
|
$this->options = array_merge($this->_defaultOptions, $options);
|
||||||
|
} else {
|
||||||
|
$this->options = $this->_defaultOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
$arr = $this->_packagefile->getArray();
|
||||||
|
if (isset($arr['filelist'])) {
|
||||||
|
unset($arr['filelist']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($arr['_lastversion'])) {
|
||||||
|
unset($arr['_lastversion']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fix the notes a little bit
|
||||||
|
if (isset($arr['notes'])) {
|
||||||
|
// This trims out the indenting, needs fixing
|
||||||
|
$arr['notes'] = "\n" . trim($arr['notes']) . "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($arr['changelog']) && !empty($arr['changelog'])) {
|
||||||
|
// Fix for inconsistency how the array is filled depending on the changelog release amount
|
||||||
|
if (!isset($arr['changelog']['release'][0])) {
|
||||||
|
$release = $arr['changelog']['release'];
|
||||||
|
unset($arr['changelog']['release']);
|
||||||
|
|
||||||
|
$arr['changelog']['release'] = array();
|
||||||
|
$arr['changelog']['release'][0] = $release;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (array_keys($arr['changelog']['release']) as $key) {
|
||||||
|
$c =& $arr['changelog']['release'][$key];
|
||||||
|
if (isset($c['notes'])) {
|
||||||
|
// This trims out the indenting, needs fixing
|
||||||
|
$c['notes'] = "\n" . trim($c['notes']) . "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($state ^ PEAR_VALIDATE_PACKAGING && !isset($arr['bundle'])) {
|
||||||
|
$use = $this->_recursiveXmlFilelist($arr['contents']['dir']['file']);
|
||||||
|
unset($arr['contents']['dir']['file']);
|
||||||
|
if (isset($use['dir'])) {
|
||||||
|
$arr['contents']['dir']['dir'] = $use['dir'];
|
||||||
|
}
|
||||||
|
if (isset($use['file'])) {
|
||||||
|
$arr['contents']['dir']['file'] = $use['file'];
|
||||||
|
}
|
||||||
|
$this->options['beautifyFilelist'] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$arr['attribs']['packagerversion'] = '1.9.4';
|
||||||
|
if ($this->serialize($arr, $options)) {
|
||||||
|
return $this->_serializedData . "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function _recursiveXmlFilelist($list)
|
||||||
|
{
|
||||||
|
$dirs = array();
|
||||||
|
if (isset($list['attribs'])) {
|
||||||
|
$file = $list['attribs']['name'];
|
||||||
|
unset($list['attribs']['name']);
|
||||||
|
$attributes = $list['attribs'];
|
||||||
|
$this->_addDir($dirs, explode('/', dirname($file)), $file, $attributes);
|
||||||
|
} else {
|
||||||
|
foreach ($list as $a) {
|
||||||
|
$file = $a['attribs']['name'];
|
||||||
|
$attributes = $a['attribs'];
|
||||||
|
unset($a['attribs']);
|
||||||
|
$this->_addDir($dirs, explode('/', dirname($file)), $file, $attributes, $a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->_formatDir($dirs);
|
||||||
|
$this->_deFormat($dirs);
|
||||||
|
return $dirs;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _addDir(&$dirs, $dir, $file = null, $attributes = null, $tasks = null)
|
||||||
|
{
|
||||||
|
if (!$tasks) {
|
||||||
|
$tasks = array();
|
||||||
|
}
|
||||||
|
if ($dir == array() || $dir == array('.')) {
|
||||||
|
$dirs['file'][basename($file)] = $tasks;
|
||||||
|
$attributes['name'] = basename($file);
|
||||||
|
$dirs['file'][basename($file)]['attribs'] = $attributes;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$curdir = array_shift($dir);
|
||||||
|
if (!isset($dirs['dir'][$curdir])) {
|
||||||
|
$dirs['dir'][$curdir] = array();
|
||||||
|
}
|
||||||
|
$this->_addDir($dirs['dir'][$curdir], $dir, $file, $attributes, $tasks);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _formatDir(&$dirs)
|
||||||
|
{
|
||||||
|
if (!count($dirs)) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
$newdirs = array();
|
||||||
|
if (isset($dirs['dir'])) {
|
||||||
|
$newdirs['dir'] = $dirs['dir'];
|
||||||
|
}
|
||||||
|
if (isset($dirs['file'])) {
|
||||||
|
$newdirs['file'] = $dirs['file'];
|
||||||
|
}
|
||||||
|
$dirs = $newdirs;
|
||||||
|
if (isset($dirs['dir'])) {
|
||||||
|
uksort($dirs['dir'], 'strnatcasecmp');
|
||||||
|
foreach ($dirs['dir'] as $dir => $contents) {
|
||||||
|
$this->_formatDir($dirs['dir'][$dir]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isset($dirs['file'])) {
|
||||||
|
uksort($dirs['file'], 'strnatcasecmp');
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function _deFormat(&$dirs)
|
||||||
|
{
|
||||||
|
if (!count($dirs)) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
$newdirs = array();
|
||||||
|
if (isset($dirs['dir'])) {
|
||||||
|
foreach ($dirs['dir'] as $dir => $contents) {
|
||||||
|
$newdir = array();
|
||||||
|
$newdir['attribs']['name'] = $dir;
|
||||||
|
$this->_deFormat($contents);
|
||||||
|
foreach ($contents as $tag => $val) {
|
||||||
|
$newdir[$tag] = $val;
|
||||||
|
}
|
||||||
|
$newdirs['dir'][] = $newdir;
|
||||||
|
}
|
||||||
|
if (count($newdirs['dir']) == 1) {
|
||||||
|
$newdirs['dir'] = $newdirs['dir'][0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isset($dirs['file'])) {
|
||||||
|
foreach ($dirs['file'] as $name => $file) {
|
||||||
|
$newdirs['file'][] = $file;
|
||||||
|
}
|
||||||
|
if (count($newdirs['file']) == 1) {
|
||||||
|
$newdirs['file'] = $newdirs['file'][0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$dirs = $newdirs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reset all options to default options
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @see setOption(), XML_Unserializer()
|
||||||
|
*/
|
||||||
|
function resetOptions()
|
||||||
|
{
|
||||||
|
$this->options = $this->_defaultOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set an option
|
||||||
|
*
|
||||||
|
* You can use this method if you do not want to set all options in the constructor
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @see resetOption(), XML_Serializer()
|
||||||
|
*/
|
||||||
|
function setOption($name, $value)
|
||||||
|
{
|
||||||
|
$this->options[$name] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets several options at once
|
||||||
|
*
|
||||||
|
* You can use this method if you do not want to set all options in the constructor
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @see resetOption(), XML_Unserializer(), setOption()
|
||||||
|
*/
|
||||||
|
function setOptions($options)
|
||||||
|
{
|
||||||
|
$this->options = array_merge($this->options, $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* serialize data
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param mixed $data data to serialize
|
||||||
|
* @return boolean true on success, pear error on failure
|
||||||
|
*/
|
||||||
|
function serialize($data, $options = null)
|
||||||
|
{
|
||||||
|
// if options have been specified, use them instead
|
||||||
|
// of the previously defined ones
|
||||||
|
if (is_array($options)) {
|
||||||
|
$optionsBak = $this->options;
|
||||||
|
if (isset($options['overrideOptions']) && $options['overrideOptions'] == true) {
|
||||||
|
$this->options = array_merge($this->_defaultOptions, $options);
|
||||||
|
} else {
|
||||||
|
$this->options = array_merge($this->options, $options);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$optionsBak = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// start depth is zero
|
||||||
|
$this->_tagDepth = 0;
|
||||||
|
$this->_serializedData = '';
|
||||||
|
// serialize an array
|
||||||
|
if (is_array($data)) {
|
||||||
|
$tagName = isset($this->options['rootName']) ? $this->options['rootName'] : 'array';
|
||||||
|
$this->_serializedData .= $this->_serializeArray($data, $tagName, $this->options['rootAttributes']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// add doctype declaration
|
||||||
|
if ($this->options['addDoctype'] === true) {
|
||||||
|
$this->_serializedData = XML_Util::getDoctypeDeclaration($tagName, $this->options['doctype'])
|
||||||
|
. $this->options['linebreak']
|
||||||
|
. $this->_serializedData;
|
||||||
|
}
|
||||||
|
|
||||||
|
// build xml declaration
|
||||||
|
if ($this->options['addDecl']) {
|
||||||
|
$atts = array();
|
||||||
|
$encoding = isset($this->options['encoding']) ? $this->options['encoding'] : null;
|
||||||
|
$this->_serializedData = XML_Util::getXMLDeclaration('1.0', $encoding)
|
||||||
|
. $this->options['linebreak']
|
||||||
|
. $this->_serializedData;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ($optionsBak !== null) {
|
||||||
|
$this->options = $optionsBak;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the result of the serialization
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @return string serialized XML
|
||||||
|
*/
|
||||||
|
function getSerializedData()
|
||||||
|
{
|
||||||
|
if ($this->_serializedData === null) {
|
||||||
|
return $this->raiseError('No serialized data available. Use XML_Serializer::serialize() first.', XML_SERIALIZER_ERROR_NO_SERIALIZATION);
|
||||||
|
}
|
||||||
|
return $this->_serializedData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* serialize any value
|
||||||
|
*
|
||||||
|
* This method checks for the type of the value and calls the appropriate method
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @param mixed $value
|
||||||
|
* @param string $tagName
|
||||||
|
* @param array $attributes
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function _serializeValue($value, $tagName = null, $attributes = array())
|
||||||
|
{
|
||||||
|
if (is_array($value)) {
|
||||||
|
$xml = $this->_serializeArray($value, $tagName, $attributes);
|
||||||
|
} elseif (is_object($value)) {
|
||||||
|
$xml = $this->_serializeObject($value, $tagName);
|
||||||
|
} else {
|
||||||
|
$tag = array(
|
||||||
|
'qname' => $tagName,
|
||||||
|
'attributes' => $attributes,
|
||||||
|
'content' => $value
|
||||||
|
);
|
||||||
|
$xml = $this->_createXMLTag($tag);
|
||||||
|
}
|
||||||
|
return $xml;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* serialize an array
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @param array $array array to serialize
|
||||||
|
* @param string $tagName name of the root tag
|
||||||
|
* @param array $attributes attributes for the root tag
|
||||||
|
* @return string $string serialized data
|
||||||
|
* @uses XML_Util::isValidName() to check, whether key has to be substituted
|
||||||
|
*/
|
||||||
|
function _serializeArray(&$array, $tagName = null, $attributes = array())
|
||||||
|
{
|
||||||
|
$_content = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check for special attributes
|
||||||
|
*/
|
||||||
|
if ($this->options['attributesArray'] !== null) {
|
||||||
|
if (isset($array[$this->options['attributesArray']])) {
|
||||||
|
$attributes = $array[$this->options['attributesArray']];
|
||||||
|
unset($array[$this->options['attributesArray']]);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* check for special content
|
||||||
|
*/
|
||||||
|
if ($this->options['contentName'] !== null) {
|
||||||
|
if (isset($array[$this->options['contentName']])) {
|
||||||
|
$_content = $array[$this->options['contentName']];
|
||||||
|
unset($array[$this->options['contentName']]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* if mode is set to simpleXML, check whether
|
||||||
|
* the array is associative or indexed
|
||||||
|
*/
|
||||||
|
if (is_array($array) && $this->options['mode'] == 'simplexml') {
|
||||||
|
$indexed = true;
|
||||||
|
if (!count($array)) {
|
||||||
|
$indexed = false;
|
||||||
|
}
|
||||||
|
foreach ($array as $key => $val) {
|
||||||
|
if (!is_int($key)) {
|
||||||
|
$indexed = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($indexed && $this->options['mode'] == 'simplexml') {
|
||||||
|
$string = '';
|
||||||
|
foreach ($array as $key => $val) {
|
||||||
|
if ($this->options['beautifyFilelist'] && $tagName == 'dir') {
|
||||||
|
if (!isset($this->_curdir)) {
|
||||||
|
$this->_curdir = '';
|
||||||
|
}
|
||||||
|
$savedir = $this->_curdir;
|
||||||
|
if (isset($val['attribs'])) {
|
||||||
|
if ($val['attribs']['name'] == '/') {
|
||||||
|
$this->_curdir = '/';
|
||||||
|
} else {
|
||||||
|
if ($this->_curdir == '/') {
|
||||||
|
$this->_curdir = '';
|
||||||
|
}
|
||||||
|
$this->_curdir .= '/' . $val['attribs']['name'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$string .= $this->_serializeValue( $val, $tagName, $attributes);
|
||||||
|
if ($this->options['beautifyFilelist'] && $tagName == 'dir') {
|
||||||
|
$string .= ' <!-- ' . $this->_curdir . ' -->';
|
||||||
|
if (empty($savedir)) {
|
||||||
|
unset($this->_curdir);
|
||||||
|
} else {
|
||||||
|
$this->_curdir = $savedir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$string .= $this->options['linebreak'];
|
||||||
|
// do indentation
|
||||||
|
if ($this->options['indent'] !== null && $this->_tagDepth > 0) {
|
||||||
|
$string .= str_repeat($this->options['indent'], $this->_tagDepth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rtrim($string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->options['scalarAsAttributes'] === true) {
|
||||||
|
foreach ($array as $key => $value) {
|
||||||
|
if (is_scalar($value) && (XML_Util::isValidName($key) === true)) {
|
||||||
|
unset($array[$key]);
|
||||||
|
$attributes[$this->options['prependAttributes'].$key] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for empty array => create empty tag
|
||||||
|
if (empty($array)) {
|
||||||
|
$tag = array(
|
||||||
|
'qname' => $tagName,
|
||||||
|
'content' => $_content,
|
||||||
|
'attributes' => $attributes
|
||||||
|
);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$this->_tagDepth++;
|
||||||
|
$tmp = $this->options['linebreak'];
|
||||||
|
foreach ($array as $key => $value) {
|
||||||
|
// do indentation
|
||||||
|
if ($this->options['indent'] !== null && $this->_tagDepth > 0) {
|
||||||
|
$tmp .= str_repeat($this->options['indent'], $this->_tagDepth);
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy key
|
||||||
|
$origKey = $key;
|
||||||
|
// key cannot be used as tagname => use default tag
|
||||||
|
$valid = XML_Util::isValidName($key);
|
||||||
|
if (PEAR::isError($valid)) {
|
||||||
|
if ($this->options['classAsTagName'] && is_object($value)) {
|
||||||
|
$key = get_class($value);
|
||||||
|
} else {
|
||||||
|
$key = $this->options['defaultTagName'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$atts = array();
|
||||||
|
if ($this->options['typeHints'] === true) {
|
||||||
|
$atts[$this->options['typeAttribute']] = gettype($value);
|
||||||
|
if ($key !== $origKey) {
|
||||||
|
$atts[$this->options['keyAttribute']] = (string)$origKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if ($this->options['beautifyFilelist'] && $key == 'dir') {
|
||||||
|
if (!isset($this->_curdir)) {
|
||||||
|
$this->_curdir = '';
|
||||||
|
}
|
||||||
|
$savedir = $this->_curdir;
|
||||||
|
if (isset($value['attribs'])) {
|
||||||
|
if ($value['attribs']['name'] == '/') {
|
||||||
|
$this->_curdir = '/';
|
||||||
|
} else {
|
||||||
|
$this->_curdir .= '/' . $value['attribs']['name'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_string($value) && $value && ($value{strlen($value) - 1} == "\n")) {
|
||||||
|
$value .= str_repeat($this->options['indent'], $this->_tagDepth);
|
||||||
|
}
|
||||||
|
$tmp .= $this->_createXMLTag(array(
|
||||||
|
'qname' => $key,
|
||||||
|
'attributes' => $atts,
|
||||||
|
'content' => $value )
|
||||||
|
);
|
||||||
|
if ($this->options['beautifyFilelist'] && $key == 'dir') {
|
||||||
|
if (isset($value['attribs'])) {
|
||||||
|
$tmp .= ' <!-- ' . $this->_curdir . ' -->';
|
||||||
|
if (empty($savedir)) {
|
||||||
|
unset($this->_curdir);
|
||||||
|
} else {
|
||||||
|
$this->_curdir = $savedir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$tmp .= $this->options['linebreak'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->_tagDepth--;
|
||||||
|
if ($this->options['indent']!==null && $this->_tagDepth>0) {
|
||||||
|
$tmp .= str_repeat($this->options['indent'], $this->_tagDepth);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trim($tmp) === '') {
|
||||||
|
$tmp = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$tag = array(
|
||||||
|
'qname' => $tagName,
|
||||||
|
'content' => $tmp,
|
||||||
|
'attributes' => $attributes
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if ($this->options['typeHints'] === true) {
|
||||||
|
if (!isset($tag['attributes'][$this->options['typeAttribute']])) {
|
||||||
|
$tag['attributes'][$this->options['typeAttribute']] = 'array';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$string = $this->_createXMLTag($tag, false);
|
||||||
|
return $string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a tag from an array
|
||||||
|
* this method awaits an array in the following format
|
||||||
|
* array(
|
||||||
|
* 'qname' => $tagName,
|
||||||
|
* 'attributes' => array(),
|
||||||
|
* 'content' => $content, // optional
|
||||||
|
* 'namespace' => $namespace // optional
|
||||||
|
* 'namespaceUri' => $namespaceUri // optional
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @param array $tag tag definition
|
||||||
|
* @param boolean $replaceEntities whether to replace XML entities in content or not
|
||||||
|
* @return string $string XML tag
|
||||||
|
*/
|
||||||
|
function _createXMLTag($tag, $replaceEntities = true)
|
||||||
|
{
|
||||||
|
if ($this->options['indentAttributes'] !== false) {
|
||||||
|
$multiline = true;
|
||||||
|
$indent = str_repeat($this->options['indent'], $this->_tagDepth);
|
||||||
|
|
||||||
|
if ($this->options['indentAttributes'] == '_auto') {
|
||||||
|
$indent .= str_repeat(' ', (strlen($tag['qname'])+2));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$indent .= $this->options['indentAttributes'];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$indent = $multiline = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_array($tag['content'])) {
|
||||||
|
if (empty($tag['content'])) {
|
||||||
|
$tag['content'] = '';
|
||||||
|
}
|
||||||
|
} elseif(is_scalar($tag['content']) && (string)$tag['content'] == '') {
|
||||||
|
$tag['content'] = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_scalar($tag['content']) || is_null($tag['content'])) {
|
||||||
|
if ($this->options['encoding'] == 'UTF-8' &&
|
||||||
|
version_compare(phpversion(), '5.0.0', 'lt')
|
||||||
|
) {
|
||||||
|
$tag['content'] = utf8_encode($tag['content']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($replaceEntities === true) {
|
||||||
|
$replaceEntities = XML_UTIL_ENTITIES_XML;
|
||||||
|
}
|
||||||
|
|
||||||
|
$tag = XML_Util::createTagFromArray($tag, $replaceEntities, $multiline, $indent, $this->options['linebreak']);
|
||||||
|
} elseif (is_array($tag['content'])) {
|
||||||
|
$tag = $this->_serializeArray($tag['content'], $tag['qname'], $tag['attributes']);
|
||||||
|
} elseif (is_object($tag['content'])) {
|
||||||
|
$tag = $this->_serializeObject($tag['content'], $tag['qname'], $tag['attributes']);
|
||||||
|
} elseif (is_resource($tag['content'])) {
|
||||||
|
settype($tag['content'], 'string');
|
||||||
|
$tag = XML_Util::createTagFromArray($tag, $replaceEntities);
|
||||||
|
}
|
||||||
|
return $tag;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,459 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* package.xml parsing class, package.xml version 1.0
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: v1.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* package.xml abstraction class
|
||||||
|
*/
|
||||||
|
require_once 'PEAR/PackageFile/v1.php';
|
||||||
|
/**
|
||||||
|
* Parser for package.xml version 1.0
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: @PEAR-VER@
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
class PEAR_PackageFile_Parser_v1
|
||||||
|
{
|
||||||
|
var $_registry;
|
||||||
|
var $_config;
|
||||||
|
var $_logger;
|
||||||
|
/**
|
||||||
|
* BC hack to allow PEAR_Common::infoFromString() to sort of
|
||||||
|
* work with the version 2.0 format - there's no filelist though
|
||||||
|
* @param PEAR_PackageFile_v2
|
||||||
|
*/
|
||||||
|
function fromV2($packagefile)
|
||||||
|
{
|
||||||
|
$info = $packagefile->getArray(true);
|
||||||
|
$ret = new PEAR_PackageFile_v1;
|
||||||
|
$ret->fromArray($info['old']);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setConfig(&$c)
|
||||||
|
{
|
||||||
|
$this->_config = &$c;
|
||||||
|
$this->_registry = &$c->getRegistry();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setLogger(&$l)
|
||||||
|
{
|
||||||
|
$this->_logger = &$l;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string contents of package.xml file, version 1.0
|
||||||
|
* @return bool success of parsing
|
||||||
|
*/
|
||||||
|
function &parse($data, $file, $archive = false)
|
||||||
|
{
|
||||||
|
if (!extension_loaded('xml')) {
|
||||||
|
return PEAR::raiseError('Cannot create xml parser for parsing package.xml, no xml extension');
|
||||||
|
}
|
||||||
|
$xp = xml_parser_create();
|
||||||
|
if (!$xp) {
|
||||||
|
$a = &PEAR::raiseError('Cannot create xml parser for parsing package.xml');
|
||||||
|
return $a;
|
||||||
|
}
|
||||||
|
xml_set_object($xp, $this);
|
||||||
|
xml_set_element_handler($xp, '_element_start_1_0', '_element_end_1_0');
|
||||||
|
xml_set_character_data_handler($xp, '_pkginfo_cdata_1_0');
|
||||||
|
xml_parser_set_option($xp, XML_OPTION_CASE_FOLDING, false);
|
||||||
|
|
||||||
|
$this->element_stack = array();
|
||||||
|
$this->_packageInfo = array('provides' => array());
|
||||||
|
$this->current_element = false;
|
||||||
|
unset($this->dir_install);
|
||||||
|
$this->_packageInfo['filelist'] = array();
|
||||||
|
$this->filelist =& $this->_packageInfo['filelist'];
|
||||||
|
$this->dir_names = array();
|
||||||
|
$this->in_changelog = false;
|
||||||
|
$this->d_i = 0;
|
||||||
|
$this->cdata = '';
|
||||||
|
$this->_isValid = true;
|
||||||
|
|
||||||
|
if (!xml_parse($xp, $data, 1)) {
|
||||||
|
$code = xml_get_error_code($xp);
|
||||||
|
$line = xml_get_current_line_number($xp);
|
||||||
|
xml_parser_free($xp);
|
||||||
|
$a = &PEAR::raiseError(sprintf("XML error: %s at line %d",
|
||||||
|
$str = xml_error_string($code), $line), 2);
|
||||||
|
return $a;
|
||||||
|
}
|
||||||
|
|
||||||
|
xml_parser_free($xp);
|
||||||
|
|
||||||
|
$pf = new PEAR_PackageFile_v1;
|
||||||
|
$pf->setConfig($this->_config);
|
||||||
|
if (isset($this->_logger)) {
|
||||||
|
$pf->setLogger($this->_logger);
|
||||||
|
}
|
||||||
|
$pf->setPackagefile($file, $archive);
|
||||||
|
$pf->fromArray($this->_packageInfo);
|
||||||
|
return $pf;
|
||||||
|
}
|
||||||
|
// {{{ _unIndent()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unindent given string
|
||||||
|
*
|
||||||
|
* @param string $str The string that has to be unindented.
|
||||||
|
* @return string
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _unIndent($str)
|
||||||
|
{
|
||||||
|
// remove leading newlines
|
||||||
|
$str = preg_replace('/^[\r\n]+/', '', $str);
|
||||||
|
// find whitespace at the beginning of the first line
|
||||||
|
$indent_len = strspn($str, " \t");
|
||||||
|
$indent = substr($str, 0, $indent_len);
|
||||||
|
$data = '';
|
||||||
|
// remove the same amount of whitespace from following lines
|
||||||
|
foreach (explode("\n", $str) as $line) {
|
||||||
|
if (substr($line, 0, $indent_len) == $indent) {
|
||||||
|
$data .= substr($line, $indent_len) . "\n";
|
||||||
|
} elseif (trim(substr($line, 0, $indent_len))) {
|
||||||
|
$data .= ltrim($line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Support for package DTD v1.0:
|
||||||
|
// {{{ _element_start_1_0()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML parser callback for ending elements. Used for version 1.0
|
||||||
|
* packages.
|
||||||
|
*
|
||||||
|
* @param resource $xp XML parser resource
|
||||||
|
* @param string $name 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;
|
||||||
|
$spos = sizeof($this->element_stack) - 2;
|
||||||
|
$this->prev_element = ($spos >= 0) ? $this->element_stack[$spos] : '';
|
||||||
|
$this->current_attributes = $attribs;
|
||||||
|
$this->cdata = '';
|
||||||
|
switch ($name) {
|
||||||
|
case 'dir':
|
||||||
|
if ($this->in_changelog) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (array_key_exists('name', $attribs) && $attribs['name'] != '/') {
|
||||||
|
$attribs['name'] = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'),
|
||||||
|
$attribs['name']);
|
||||||
|
if (strrpos($attribs['name'], '/') === strlen($attribs['name']) - 1) {
|
||||||
|
$attribs['name'] = substr($attribs['name'], 0,
|
||||||
|
strlen($attribs['name']) - 1);
|
||||||
|
}
|
||||||
|
if (strpos($attribs['name'], '/') === 0) {
|
||||||
|
$attribs['name'] = substr($attribs['name'], 1);
|
||||||
|
}
|
||||||
|
$this->dir_names[] = $attribs['name'];
|
||||||
|
}
|
||||||
|
if (isset($attribs['baseinstalldir'])) {
|
||||||
|
$this->dir_install = $attribs['baseinstalldir'];
|
||||||
|
}
|
||||||
|
if (isset($attribs['role'])) {
|
||||||
|
$this->dir_role = $attribs['role'];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'file':
|
||||||
|
if ($this->in_changelog) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (isset($attribs['name'])) {
|
||||||
|
$path = '';
|
||||||
|
if (count($this->dir_names)) {
|
||||||
|
foreach ($this->dir_names as $dir) {
|
||||||
|
$path .= $dir . '/';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$path .= preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'),
|
||||||
|
$attribs['name']);
|
||||||
|
unset($attribs['name']);
|
||||||
|
$this->current_path = $path;
|
||||||
|
$this->filelist[$path] = $attribs;
|
||||||
|
// Set the baseinstalldir only if the file don't have this attrib
|
||||||
|
if (!isset($this->filelist[$path]['baseinstalldir']) &&
|
||||||
|
isset($this->dir_install))
|
||||||
|
{
|
||||||
|
$this->filelist[$path]['baseinstalldir'] = $this->dir_install;
|
||||||
|
}
|
||||||
|
// Set the Role
|
||||||
|
if (!isset($this->filelist[$path]['role']) && isset($this->dir_role)) {
|
||||||
|
$this->filelist[$path]['role'] = $this->dir_role;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'replace':
|
||||||
|
if (!$this->in_changelog) {
|
||||||
|
$this->filelist[$this->current_path]['replacements'][] = $attribs;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'maintainers':
|
||||||
|
$this->_packageInfo['maintainers'] = array();
|
||||||
|
$this->m_i = 0; // maintainers array index
|
||||||
|
break;
|
||||||
|
case 'maintainer':
|
||||||
|
// compatibility check
|
||||||
|
if (!isset($this->_packageInfo['maintainers'])) {
|
||||||
|
$this->_packageInfo['maintainers'] = array();
|
||||||
|
$this->m_i = 0;
|
||||||
|
}
|
||||||
|
$this->_packageInfo['maintainers'][$this->m_i] = array();
|
||||||
|
$this->current_maintainer =& $this->_packageInfo['maintainers'][$this->m_i];
|
||||||
|
break;
|
||||||
|
case 'changelog':
|
||||||
|
$this->_packageInfo['changelog'] = array();
|
||||||
|
$this->c_i = 0; // changelog array index
|
||||||
|
$this->in_changelog = true;
|
||||||
|
break;
|
||||||
|
case 'release':
|
||||||
|
if ($this->in_changelog) {
|
||||||
|
$this->_packageInfo['changelog'][$this->c_i] = array();
|
||||||
|
$this->current_release = &$this->_packageInfo['changelog'][$this->c_i];
|
||||||
|
} else {
|
||||||
|
$this->current_release = &$this->_packageInfo;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'deps':
|
||||||
|
if (!$this->in_changelog) {
|
||||||
|
$this->_packageInfo['release_deps'] = array();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'dep':
|
||||||
|
// dependencies array index
|
||||||
|
if (!$this->in_changelog) {
|
||||||
|
$this->d_i++;
|
||||||
|
isset($attribs['type']) ? ($attribs['type'] = strtolower($attribs['type'])) : false;
|
||||||
|
$this->_packageInfo['release_deps'][$this->d_i] = $attribs;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'configureoptions':
|
||||||
|
if (!$this->in_changelog) {
|
||||||
|
$this->_packageInfo['configure_options'] = array();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'configureoption':
|
||||||
|
if (!$this->in_changelog) {
|
||||||
|
$this->_packageInfo['configure_options'][] = $attribs;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'provides':
|
||||||
|
if (empty($attribs['type']) || empty($attribs['name'])) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$attribs['explicit'] = true;
|
||||||
|
$this->_packageInfo['provides']["$attribs[type];$attribs[name]"] = $attribs;
|
||||||
|
break;
|
||||||
|
case 'package' :
|
||||||
|
if (isset($attribs['version'])) {
|
||||||
|
$this->_packageInfo['xsdversion'] = trim($attribs['version']);
|
||||||
|
} else {
|
||||||
|
$this->_packageInfo['xsdversion'] = '1.0';
|
||||||
|
}
|
||||||
|
if (isset($attribs['packagerversion'])) {
|
||||||
|
$this->_packageInfo['packagerversion'] = $attribs['packagerversion'];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ _element_end_1_0()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML parser callback for ending elements. Used for version 1.0
|
||||||
|
* packages.
|
||||||
|
*
|
||||||
|
* @param resource $xp XML parser resource
|
||||||
|
* @param string $name name of ending element
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _element_end_1_0($xp, $name)
|
||||||
|
{
|
||||||
|
$data = trim($this->cdata);
|
||||||
|
switch ($name) {
|
||||||
|
case 'name':
|
||||||
|
switch ($this->prev_element) {
|
||||||
|
case 'package':
|
||||||
|
$this->_packageInfo['package'] = $data;
|
||||||
|
break;
|
||||||
|
case 'maintainer':
|
||||||
|
$this->current_maintainer['name'] = $data;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'extends' :
|
||||||
|
$this->_packageInfo['extends'] = $data;
|
||||||
|
break;
|
||||||
|
case 'summary':
|
||||||
|
$this->_packageInfo['summary'] = $data;
|
||||||
|
break;
|
||||||
|
case 'description':
|
||||||
|
$data = $this->_unIndent($this->cdata);
|
||||||
|
$this->_packageInfo['description'] = $data;
|
||||||
|
break;
|
||||||
|
case 'user':
|
||||||
|
$this->current_maintainer['handle'] = $data;
|
||||||
|
break;
|
||||||
|
case 'email':
|
||||||
|
$this->current_maintainer['email'] = $data;
|
||||||
|
break;
|
||||||
|
case 'role':
|
||||||
|
$this->current_maintainer['role'] = $data;
|
||||||
|
break;
|
||||||
|
case 'version':
|
||||||
|
if ($this->in_changelog) {
|
||||||
|
$this->current_release['version'] = $data;
|
||||||
|
} else {
|
||||||
|
$this->_packageInfo['version'] = $data;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'date':
|
||||||
|
if ($this->in_changelog) {
|
||||||
|
$this->current_release['release_date'] = $data;
|
||||||
|
} else {
|
||||||
|
$this->_packageInfo['release_date'] = $data;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'notes':
|
||||||
|
// try to "de-indent" release notes in case someone
|
||||||
|
// has been over-indenting their xml ;-)
|
||||||
|
// Trim only on the right side
|
||||||
|
$data = rtrim($this->_unIndent($this->cdata));
|
||||||
|
if ($this->in_changelog) {
|
||||||
|
$this->current_release['release_notes'] = $data;
|
||||||
|
} else {
|
||||||
|
$this->_packageInfo['release_notes'] = $data;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'warnings':
|
||||||
|
if ($this->in_changelog) {
|
||||||
|
$this->current_release['release_warnings'] = $data;
|
||||||
|
} else {
|
||||||
|
$this->_packageInfo['release_warnings'] = $data;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'state':
|
||||||
|
if ($this->in_changelog) {
|
||||||
|
$this->current_release['release_state'] = $data;
|
||||||
|
} else {
|
||||||
|
$this->_packageInfo['release_state'] = $data;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'license':
|
||||||
|
if ($this->in_changelog) {
|
||||||
|
$this->current_release['release_license'] = $data;
|
||||||
|
} else {
|
||||||
|
$this->_packageInfo['release_license'] = $data;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'dep':
|
||||||
|
if ($data && !$this->in_changelog) {
|
||||||
|
$this->_packageInfo['release_deps'][$this->d_i]['name'] = $data;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'dir':
|
||||||
|
if ($this->in_changelog) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
array_pop($this->dir_names);
|
||||||
|
break;
|
||||||
|
case 'file':
|
||||||
|
if ($this->in_changelog) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ($data) {
|
||||||
|
$path = '';
|
||||||
|
if (count($this->dir_names)) {
|
||||||
|
foreach ($this->dir_names as $dir) {
|
||||||
|
$path .= $dir . '/';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$path .= $data;
|
||||||
|
$this->filelist[$path] = $this->current_attributes;
|
||||||
|
// Set the baseinstalldir only if the file don't have this attrib
|
||||||
|
if (!isset($this->filelist[$path]['baseinstalldir']) &&
|
||||||
|
isset($this->dir_install))
|
||||||
|
{
|
||||||
|
$this->filelist[$path]['baseinstalldir'] = $this->dir_install;
|
||||||
|
}
|
||||||
|
// Set the Role
|
||||||
|
if (!isset($this->filelist[$path]['role']) && isset($this->dir_role)) {
|
||||||
|
$this->filelist[$path]['role'] = $this->dir_role;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'maintainer':
|
||||||
|
if (empty($this->_packageInfo['maintainers'][$this->m_i]['role'])) {
|
||||||
|
$this->_packageInfo['maintainers'][$this->m_i]['role'] = 'lead';
|
||||||
|
}
|
||||||
|
$this->m_i++;
|
||||||
|
break;
|
||||||
|
case 'release':
|
||||||
|
if ($this->in_changelog) {
|
||||||
|
$this->c_i++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'changelog':
|
||||||
|
$this->in_changelog = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
array_pop($this->element_stack);
|
||||||
|
$spos = sizeof($this->element_stack) - 1;
|
||||||
|
$this->current_element = ($spos > 0) ? $this->element_stack[$spos] : '';
|
||||||
|
$this->cdata = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
// {{{ _pkginfo_cdata_1_0()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML parser callback for character data. Used for version 1.0
|
||||||
|
* packages.
|
||||||
|
*
|
||||||
|
* @param resource $xp XML parser resource
|
||||||
|
* @param string $name character data
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _pkginfo_cdata_1_0($xp, $data)
|
||||||
|
{
|
||||||
|
if (isset($this->cdata)) {
|
||||||
|
$this->cdata .= $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
}
|
||||||
|
?>
|
|
@ -0,0 +1,113 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* package.xml parsing class, package.xml version 2.0
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: v2.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* base xml parser class
|
||||||
|
*/
|
||||||
|
require_once 'PEAR/XMLParser.php';
|
||||||
|
require_once 'PEAR/PackageFile/v2.php';
|
||||||
|
/**
|
||||||
|
* Parser for package.xml version 2.0
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: @PEAR-VER@
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
class PEAR_PackageFile_Parser_v2 extends PEAR_XMLParser
|
||||||
|
{
|
||||||
|
var $_config;
|
||||||
|
var $_logger;
|
||||||
|
var $_registry;
|
||||||
|
|
||||||
|
function setConfig(&$c)
|
||||||
|
{
|
||||||
|
$this->_config = &$c;
|
||||||
|
$this->_registry = &$c->getRegistry();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setLogger(&$l)
|
||||||
|
{
|
||||||
|
$this->_logger = &$l;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Unindent given string
|
||||||
|
*
|
||||||
|
* @param string $str The string that has to be unindented.
|
||||||
|
* @return string
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _unIndent($str)
|
||||||
|
{
|
||||||
|
// remove leading newlines
|
||||||
|
$str = preg_replace('/^[\r\n]+/', '', $str);
|
||||||
|
// find whitespace at the beginning of the first line
|
||||||
|
$indent_len = strspn($str, " \t");
|
||||||
|
$indent = substr($str, 0, $indent_len);
|
||||||
|
$data = '';
|
||||||
|
// remove the same amount of whitespace from following lines
|
||||||
|
foreach (explode("\n", $str) as $line) {
|
||||||
|
if (substr($line, 0, $indent_len) == $indent) {
|
||||||
|
$data .= substr($line, $indent_len) . "\n";
|
||||||
|
} else {
|
||||||
|
$data .= $line . "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* post-process data
|
||||||
|
*
|
||||||
|
* @param string $data
|
||||||
|
* @param string $element element name
|
||||||
|
*/
|
||||||
|
function postProcess($data, $element)
|
||||||
|
{
|
||||||
|
if ($element == 'notes') {
|
||||||
|
return trim($this->_unIndent($data));
|
||||||
|
}
|
||||||
|
return trim($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string
|
||||||
|
* @param string file name of the package.xml
|
||||||
|
* @param string|false name of the archive this package.xml came from, if any
|
||||||
|
* @param string class name to instantiate and return. This must be PEAR_PackageFile_v2 or
|
||||||
|
* a subclass
|
||||||
|
* @return PEAR_PackageFile_v2
|
||||||
|
*/
|
||||||
|
function &parse($data, $file, $archive = false, $class = 'PEAR_PackageFile_v2')
|
||||||
|
{
|
||||||
|
if (PEAR::isError($err = parent::parse($data, $file))) {
|
||||||
|
return $err;
|
||||||
|
}
|
||||||
|
|
||||||
|
$ret = new $class;
|
||||||
|
$ret->encoding = $this->encoding;
|
||||||
|
$ret->setConfig($this->_config);
|
||||||
|
if (isset($this->_logger)) {
|
||||||
|
$ret->setLogger($this->_logger);
|
||||||
|
}
|
||||||
|
|
||||||
|
$ret->fromArray($this->_unserializedData);
|
||||||
|
$ret->setPackagefile($file, $archive);
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,165 +1,201 @@
|
||||||
<?php
|
<?php
|
||||||
//
|
/**
|
||||||
// +----------------------------------------------------------------------+
|
* PEAR_Packager for generating releases
|
||||||
// | PHP Version 5 |
|
*
|
||||||
// +----------------------------------------------------------------------+
|
* PHP versions 4 and 5
|
||||||
// | Copyright (c) 1997-2004 The PHP Group |
|
*
|
||||||
// +----------------------------------------------------------------------+
|
* @category pear
|
||||||
// | This source file is subject to version 3.0 of the PHP license, |
|
* @package PEAR
|
||||||
// | that is bundled with this package in the file LICENSE, and is |
|
* @author Stig Bakken <ssb@php.net>
|
||||||
// | available through the world-wide-web at the following url: |
|
* @author Tomas V. V. Cox <cox@idecnet.com>
|
||||||
// | http://www.php.net/license/3_0.txt. |
|
* @author Greg Beaver <cellog@php.net>
|
||||||
// | If you did not receive a copy of the PHP license and are unable to |
|
* @copyright 1997-2009 The Authors
|
||||||
// | obtain it through the world-wide-web, please send a note to |
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
// | license@php.net so we can mail you a copy immediately. |
|
* @version CVS: $Id: Packager.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
// +----------------------------------------------------------------------+
|
* @link http://pear.php.net/package/PEAR
|
||||||
// | Authors: Stig Bakken <ssb@php.net> |
|
* @since File available since Release 0.1
|
||||||
// | Tomas V.V.Cox <cox@idecnet.com> |
|
*/
|
||||||
// +----------------------------------------------------------------------+
|
|
||||||
//
|
|
||||||
// $Id: Packager.php,v 1.53 2004/06/13 14:06:01 pajoye Exp $
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* base class
|
||||||
|
*/
|
||||||
require_once 'PEAR/Common.php';
|
require_once 'PEAR/Common.php';
|
||||||
|
require_once 'PEAR/PackageFile.php';
|
||||||
require_once 'System.php';
|
require_once 'System.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Administration class used to make a PEAR release tarball.
|
* Administration class used to make a PEAR release tarball.
|
||||||
*
|
*
|
||||||
* TODO:
|
* @category pear
|
||||||
* - add an extra param the dir where to place the created package
|
* @package PEAR
|
||||||
*
|
* @author Greg Beaver <cellog@php.net>
|
||||||
* @since PHP 4.0.2
|
* @copyright 1997-2009 The Authors
|
||||||
* @author Stig Bakken <ssb@php.net>
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 0.1
|
||||||
*/
|
*/
|
||||||
class PEAR_Packager extends PEAR_Common
|
class PEAR_Packager extends PEAR_Common
|
||||||
{
|
{
|
||||||
// {{{ constructor
|
/**
|
||||||
|
* @var PEAR_Registry
|
||||||
|
*/
|
||||||
|
var $_registry;
|
||||||
|
|
||||||
function PEAR_Packager()
|
function package($pkgfile = null, $compress = true, $pkg2 = null)
|
||||||
{
|
|
||||||
parent::PEAR_Common();
|
|
||||||
}
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
// {{{ destructor
|
|
||||||
|
|
||||||
function _PEAR_Packager()
|
|
||||||
{
|
|
||||||
parent::_PEAR_Common();
|
|
||||||
}
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
|
|
||||||
// {{{ package()
|
|
||||||
|
|
||||||
function package($pkgfile = null, $compress = true)
|
|
||||||
{
|
{
|
||||||
// {{{ validate supplied package.xml file
|
// {{{ validate supplied package.xml file
|
||||||
if (empty($pkgfile)) {
|
if (empty($pkgfile)) {
|
||||||
$pkgfile = 'package.xml';
|
$pkgfile = 'package.xml';
|
||||||
}
|
}
|
||||||
// $this->pkginfo gets populated inside
|
|
||||||
$pkginfo = $this->infoFromDescriptionFile($pkgfile);
|
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
|
||||||
if (PEAR::isError($pkginfo)) {
|
$pkg = &new PEAR_PackageFile($this->config, $this->debug);
|
||||||
return $this->raiseError($pkginfo);
|
$pf = &$pkg->fromPackageFile($pkgfile, PEAR_VALIDATE_NORMAL);
|
||||||
|
$main = &$pf;
|
||||||
|
PEAR::staticPopErrorHandling();
|
||||||
|
if (PEAR::isError($pf)) {
|
||||||
|
if (is_array($pf->getUserInfo())) {
|
||||||
|
foreach ($pf->getUserInfo() as $error) {
|
||||||
|
$this->log(0, 'Error: ' . $error['message']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$pkgdir = dirname(realpath($pkgfile));
|
$this->log(0, $pf->getMessage());
|
||||||
$pkgfile = basename($pkgfile);
|
return $this->raiseError("Cannot package, errors in package file");
|
||||||
|
}
|
||||||
|
|
||||||
$errors = $warnings = array();
|
foreach ($pf->getValidationWarnings() as $warning) {
|
||||||
$this->validatePackageInfo($pkginfo, $errors, $warnings, $pkgdir);
|
$this->log(1, 'Warning: ' . $warning['message']);
|
||||||
foreach ($warnings as $w) {
|
|
||||||
$this->log(1, "Warning: $w");
|
|
||||||
}
|
|
||||||
foreach ($errors as $e) {
|
|
||||||
$this->log(0, "Error: $e");
|
|
||||||
}
|
|
||||||
if (sizeof($errors) > 0) {
|
|
||||||
return $this->raiseError('Errors in package');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
|
if ($pkg2) {
|
||||||
|
$this->log(0, 'Attempting to process the second package file');
|
||||||
|
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
|
||||||
|
$pf2 = &$pkg->fromPackageFile($pkg2, PEAR_VALIDATE_NORMAL);
|
||||||
|
PEAR::staticPopErrorHandling();
|
||||||
|
if (PEAR::isError($pf2)) {
|
||||||
|
if (is_array($pf2->getUserInfo())) {
|
||||||
|
foreach ($pf2->getUserInfo() as $error) {
|
||||||
|
$this->log(0, 'Error: ' . $error['message']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->log(0, $pf2->getMessage());
|
||||||
|
return $this->raiseError("Cannot package, errors in second package file");
|
||||||
|
}
|
||||||
|
|
||||||
$pkgver = $pkginfo['package'] . '-' . $pkginfo['version'];
|
foreach ($pf2->getValidationWarnings() as $warning) {
|
||||||
|
$this->log(1, 'Warning: ' . $warning['message']);
|
||||||
|
}
|
||||||
|
|
||||||
// {{{ Create the package file list
|
if ($pf2->getPackagexmlVersion() == '2.0' ||
|
||||||
$filelist = array();
|
$pf2->getPackagexmlVersion() == '2.1'
|
||||||
$i = 0;
|
) {
|
||||||
|
$main = &$pf2;
|
||||||
foreach ($pkginfo['filelist'] as $fname => $atts) {
|
$other = &$pf;
|
||||||
$file = $pkgdir . DIRECTORY_SEPARATOR . $fname;
|
|
||||||
if (!file_exists($file)) {
|
|
||||||
return $this->raiseError("File does not exist: $fname");
|
|
||||||
} else {
|
} else {
|
||||||
$filelist[$i++] = $file;
|
$main = &$pf;
|
||||||
if (empty($pkginfo['filelist'][$fname]['md5sum'])) {
|
$other = &$pf2;
|
||||||
$md5sum = md5_file($file);
|
|
||||||
$pkginfo['filelist'][$fname]['md5sum'] = $md5sum;
|
|
||||||
}
|
}
|
||||||
$this->log(2, "Adding file $fname");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// }}}
|
|
||||||
|
|
||||||
// {{{ regenerate package.xml
|
if ($main->getPackagexmlVersion() != '2.0' &&
|
||||||
$new_xml = $this->xmlFromInfo($pkginfo);
|
$main->getPackagexmlVersion() != '2.1') {
|
||||||
if (PEAR::isError($new_xml)) {
|
return PEAR::raiseError('Error: cannot package two package.xml version 1.0, can ' .
|
||||||
return $this->raiseError($new_xml);
|
'only package together a package.xml 1.0 and package.xml 2.0');
|
||||||
}
|
}
|
||||||
if (!($tmpdir = System::mktemp(array('-d')))) {
|
|
||||||
return $this->raiseError("PEAR_Packager: mktemp failed");
|
|
||||||
}
|
|
||||||
$newpkgfile = $tmpdir . DIRECTORY_SEPARATOR . 'package.xml';
|
|
||||||
$np = @fopen($newpkgfile, 'wb');
|
|
||||||
if (!$np) {
|
|
||||||
return $this->raiseError("PEAR_Packager: unable to rewrite $pkgfile as $newpkgfile");
|
|
||||||
}
|
|
||||||
fwrite($np, $new_xml);
|
|
||||||
fclose($np);
|
|
||||||
// }}}
|
|
||||||
|
|
||||||
// {{{ TAR the Package -------------------------------------------
|
if ($other->getPackagexmlVersion() != '1.0') {
|
||||||
$ext = $compress ? '.tgz' : '.tar';
|
return PEAR::raiseError('Error: cannot package two package.xml version 2.0, can ' .
|
||||||
$dest_package = getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext;
|
'only package together a package.xml 1.0 and package.xml 2.0');
|
||||||
$tar =& new Archive_Tar($dest_package, $compress);
|
|
||||||
$tar->setErrorHandling(PEAR_ERROR_RETURN); // XXX Don't print errors
|
|
||||||
// ----- Creates with the package.xml file
|
|
||||||
$ok = $tar->createModify(array($newpkgfile), '', $tmpdir);
|
|
||||||
if (PEAR::isError($ok)) {
|
|
||||||
return $this->raiseError($ok);
|
|
||||||
} elseif (!$ok) {
|
|
||||||
return $this->raiseError('PEAR_Packager: tarball creation failed');
|
|
||||||
}
|
}
|
||||||
// ----- Add the content of the package
|
|
||||||
if (!$tar->addModify($filelist, $pkgver, $pkgdir)) {
|
|
||||||
return $this->raiseError('PEAR_Packager: tarball creation failed');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$main->setLogger($this);
|
||||||
|
if (!$main->validate(PEAR_VALIDATE_PACKAGING)) {
|
||||||
|
foreach ($main->getValidationWarnings() as $warning) {
|
||||||
|
$this->log(0, 'Error: ' . $warning['message']);
|
||||||
|
}
|
||||||
|
return $this->raiseError("Cannot package, errors in package");
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($main->getValidationWarnings() as $warning) {
|
||||||
|
$this->log(1, 'Warning: ' . $warning['message']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($pkg2) {
|
||||||
|
$other->setLogger($this);
|
||||||
|
$a = false;
|
||||||
|
if (!$other->validate(PEAR_VALIDATE_NORMAL) || $a = !$main->isEquivalent($other)) {
|
||||||
|
foreach ($other->getValidationWarnings() as $warning) {
|
||||||
|
$this->log(0, 'Error: ' . $warning['message']);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($main->getValidationWarnings() as $warning) {
|
||||||
|
$this->log(0, 'Error: ' . $warning['message']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($a) {
|
||||||
|
return $this->raiseError('The two package.xml files are not equivalent!');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->raiseError("Cannot package, errors in package");
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($other->getValidationWarnings() as $warning) {
|
||||||
|
$this->log(1, 'Warning: ' . $warning['message']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$gen = &$main->getDefaultGenerator();
|
||||||
|
$tgzfile = $gen->toTgz2($this, $other, $compress);
|
||||||
|
if (PEAR::isError($tgzfile)) {
|
||||||
|
return $tgzfile;
|
||||||
|
}
|
||||||
|
|
||||||
|
$dest_package = basename($tgzfile);
|
||||||
|
$pkgdir = dirname($pkgfile);
|
||||||
|
|
||||||
|
// TAR the Package -------------------------------------------
|
||||||
$this->log(1, "Package $dest_package done");
|
$this->log(1, "Package $dest_package done");
|
||||||
if (file_exists("$pkgdir/CVS/Root")) {
|
if (file_exists("$pkgdir/CVS/Root")) {
|
||||||
$cvsversion = preg_replace('/[^a-z0-9]/i', '_', $pkginfo['version']);
|
$cvsversion = preg_replace('/[^a-z0-9]/i', '_', $pf->getVersion());
|
||||||
|
$cvstag = "RELEASE_$cvsversion";
|
||||||
|
$this->log(1, 'Tag the released code with "pear cvstag ' .
|
||||||
|
$main->getPackageFile() . '"');
|
||||||
|
$this->log(1, "(or set the CVS tag $cvstag by hand)");
|
||||||
|
} elseif (file_exists("$pkgdir/.svn")) {
|
||||||
|
$svnversion = preg_replace('/[^a-z0-9]/i', '.', $pf->getVersion());
|
||||||
|
$svntag = $pf->getName() . "-$svnversion";
|
||||||
|
$this->log(1, 'Tag the released code with "pear svntag ' .
|
||||||
|
$main->getPackageFile() . '"');
|
||||||
|
$this->log(1, "(or set the SVN tag $svntag by hand)");
|
||||||
|
}
|
||||||
|
} else { // this branch is executed for single packagefile packaging
|
||||||
|
$gen = &$pf->getDefaultGenerator();
|
||||||
|
$tgzfile = $gen->toTgz($this, $compress);
|
||||||
|
if (PEAR::isError($tgzfile)) {
|
||||||
|
$this->log(0, $tgzfile->getMessage());
|
||||||
|
return $this->raiseError("Cannot package, errors in package");
|
||||||
|
}
|
||||||
|
|
||||||
|
$dest_package = basename($tgzfile);
|
||||||
|
$pkgdir = dirname($pkgfile);
|
||||||
|
|
||||||
|
// TAR the Package -------------------------------------------
|
||||||
|
$this->log(1, "Package $dest_package done");
|
||||||
|
if (file_exists("$pkgdir/CVS/Root")) {
|
||||||
|
$cvsversion = preg_replace('/[^a-z0-9]/i', '_', $pf->getVersion());
|
||||||
$cvstag = "RELEASE_$cvsversion";
|
$cvstag = "RELEASE_$cvsversion";
|
||||||
$this->log(1, "Tag the released code with `pear cvstag $pkgfile'");
|
$this->log(1, "Tag the released code with `pear cvstag $pkgfile'");
|
||||||
$this->log(1, "(or set the CVS tag $cvstag by hand)");
|
$this->log(1, "(or set the CVS tag $cvstag by hand)");
|
||||||
|
} elseif (file_exists("$pkgdir/.svn")) {
|
||||||
|
$svnversion = preg_replace('/[^a-z0-9]/i', '.', $pf->getVersion());
|
||||||
|
$svntag = $pf->getName() . "-$svnversion";
|
||||||
|
$this->log(1, "Tag the released code with `pear svntag $pkgfile'");
|
||||||
|
$this->log(1, "(or set the SVN tag $svntag by hand)");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// }}}
|
|
||||||
|
|
||||||
return $dest_package;
|
return $dest_package;
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// {{{ md5_file() utility function
|
|
||||||
if (!function_exists('md5_file')) {
|
|
||||||
function md5_file($file) {
|
|
||||||
if (!$fd = @fopen($file, 'r')) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$md5 = md5(fread($fd, filesize($file)));
|
|
||||||
fclose($fd);
|
|
||||||
return $md5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// }}}
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
|
@ -0,0 +1,483 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PEAR_REST
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: REST.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For downloading xml files
|
||||||
|
*/
|
||||||
|
require_once 'PEAR.php';
|
||||||
|
require_once 'PEAR/XMLParser.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Intelligently retrieve data, following hyperlinks if necessary, and re-directing
|
||||||
|
* as well
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
class PEAR_REST
|
||||||
|
{
|
||||||
|
var $config;
|
||||||
|
var $_options;
|
||||||
|
|
||||||
|
function PEAR_REST(&$config, $options = array())
|
||||||
|
{
|
||||||
|
$this->config = &$config;
|
||||||
|
$this->_options = $options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve REST data, but always retrieve the local cache if it is available.
|
||||||
|
*
|
||||||
|
* This is useful for elements that should never change, such as information on a particular
|
||||||
|
* release
|
||||||
|
* @param string full URL to this resource
|
||||||
|
* @param array|false contents of the accept-encoding header
|
||||||
|
* @param boolean if true, xml will be returned as a string, otherwise, xml will be
|
||||||
|
* parsed using PEAR_XMLParser
|
||||||
|
* @return string|array
|
||||||
|
*/
|
||||||
|
function retrieveCacheFirst($url, $accept = false, $forcestring = false, $channel = false)
|
||||||
|
{
|
||||||
|
$cachefile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR .
|
||||||
|
md5($url) . 'rest.cachefile';
|
||||||
|
|
||||||
|
if (file_exists($cachefile)) {
|
||||||
|
return unserialize(implode('', file($cachefile)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->retrieveData($url, $accept, $forcestring, $channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a remote REST resource
|
||||||
|
* @param string full URL to this resource
|
||||||
|
* @param array|false contents of the accept-encoding header
|
||||||
|
* @param boolean if true, xml will be returned as a string, otherwise, xml will be
|
||||||
|
* parsed using PEAR_XMLParser
|
||||||
|
* @return string|array
|
||||||
|
*/
|
||||||
|
function retrieveData($url, $accept = false, $forcestring = false, $channel = false)
|
||||||
|
{
|
||||||
|
$cacheId = $this->getCacheId($url);
|
||||||
|
if ($ret = $this->useLocalCache($url, $cacheId)) {
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
$file = $trieddownload = false;
|
||||||
|
if (!isset($this->_options['offline'])) {
|
||||||
|
$trieddownload = true;
|
||||||
|
$file = $this->downloadHttp($url, $cacheId ? $cacheId['lastChange'] : false, $accept, $channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PEAR::isError($file)) {
|
||||||
|
if ($file->getCode() !== -9276) {
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
|
|
||||||
|
$trieddownload = false;
|
||||||
|
$file = false; // use local copy if available on socket connect error
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$file) {
|
||||||
|
$ret = $this->getCache($url);
|
||||||
|
if (!PEAR::isError($ret) && $trieddownload) {
|
||||||
|
// reset the age of the cache if the server says it was unmodified
|
||||||
|
$result = $this->saveCache($url, $ret, null, true, $cacheId);
|
||||||
|
if (PEAR::isError($result)) {
|
||||||
|
return PEAR::raiseError($result->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_array($file)) {
|
||||||
|
$headers = $file[2];
|
||||||
|
$lastmodified = $file[1];
|
||||||
|
$content = $file[0];
|
||||||
|
} else {
|
||||||
|
$headers = array();
|
||||||
|
$lastmodified = false;
|
||||||
|
$content = $file;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($forcestring) {
|
||||||
|
$result = $this->saveCache($url, $content, $lastmodified, false, $cacheId);
|
||||||
|
if (PEAR::isError($result)) {
|
||||||
|
return PEAR::raiseError($result->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($headers['content-type'])) {
|
||||||
|
switch ($headers['content-type']) {
|
||||||
|
case 'text/xml' :
|
||||||
|
case 'application/xml' :
|
||||||
|
case 'text/plain' :
|
||||||
|
if ($headers['content-type'] === 'text/plain') {
|
||||||
|
$check = substr($content, 0, 5);
|
||||||
|
if ($check !== '<?xml') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$parser = new PEAR_XMLParser;
|
||||||
|
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
|
||||||
|
$err = $parser->parse($content);
|
||||||
|
PEAR::popErrorHandling();
|
||||||
|
if (PEAR::isError($err)) {
|
||||||
|
return PEAR::raiseError('Invalid xml downloaded from "' . $url . '": ' .
|
||||||
|
$err->getMessage());
|
||||||
|
}
|
||||||
|
$content = $parser->getData();
|
||||||
|
case 'text/html' :
|
||||||
|
default :
|
||||||
|
// use it as a string
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// assume XML
|
||||||
|
$parser = new PEAR_XMLParser;
|
||||||
|
$parser->parse($content);
|
||||||
|
$content = $parser->getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $this->saveCache($url, $content, $lastmodified, false, $cacheId);
|
||||||
|
if (PEAR::isError($result)) {
|
||||||
|
return PEAR::raiseError($result->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
|
||||||
|
function useLocalCache($url, $cacheid = null)
|
||||||
|
{
|
||||||
|
if ($cacheid === null) {
|
||||||
|
$cacheidfile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR .
|
||||||
|
md5($url) . 'rest.cacheid';
|
||||||
|
if (!file_exists($cacheidfile)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$cacheid = unserialize(implode('', file($cacheidfile)));
|
||||||
|
}
|
||||||
|
|
||||||
|
$cachettl = $this->config->get('cache_ttl');
|
||||||
|
// If cache is newer than $cachettl seconds, we use the cache!
|
||||||
|
if (time() - $cacheid['age'] < $cachettl) {
|
||||||
|
return $this->getCache($url);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCacheId($url)
|
||||||
|
{
|
||||||
|
$cacheidfile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR .
|
||||||
|
md5($url) . 'rest.cacheid';
|
||||||
|
|
||||||
|
if (!file_exists($cacheidfile)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$ret = unserialize(implode('', file($cacheidfile)));
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCache($url)
|
||||||
|
{
|
||||||
|
$cachefile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR .
|
||||||
|
md5($url) . 'rest.cachefile';
|
||||||
|
|
||||||
|
if (!file_exists($cachefile)) {
|
||||||
|
return PEAR::raiseError('No cached content available for "' . $url . '"');
|
||||||
|
}
|
||||||
|
|
||||||
|
return unserialize(implode('', file($cachefile)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string full URL to REST resource
|
||||||
|
* @param string original contents of the REST resource
|
||||||
|
* @param array HTTP Last-Modified and ETag headers
|
||||||
|
* @param bool if true, then the cache id file should be regenerated to
|
||||||
|
* trigger a new time-to-live value
|
||||||
|
*/
|
||||||
|
function saveCache($url, $contents, $lastmodified, $nochange = false, $cacheid = null)
|
||||||
|
{
|
||||||
|
$cache_dir = $this->config->get('cache_dir');
|
||||||
|
$d = $cache_dir . DIRECTORY_SEPARATOR . md5($url);
|
||||||
|
$cacheidfile = $d . 'rest.cacheid';
|
||||||
|
$cachefile = $d . 'rest.cachefile';
|
||||||
|
|
||||||
|
if (!is_dir($cache_dir)) {
|
||||||
|
if (System::mkdir(array('-p', $cache_dir)) === false) {
|
||||||
|
return PEAR::raiseError("The value of config option cache_dir ($cache_dir) is not a directory and attempts to create the directory failed.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($cacheid === null && $nochange) {
|
||||||
|
$cacheid = unserialize(implode('', file($cacheidfile)));
|
||||||
|
}
|
||||||
|
|
||||||
|
$idData = serialize(array(
|
||||||
|
'age' => time(),
|
||||||
|
'lastChange' => ($nochange ? $cacheid['lastChange'] : $lastmodified),
|
||||||
|
));
|
||||||
|
|
||||||
|
$result = $this->saveCacheFile($cacheidfile, $idData);
|
||||||
|
if (PEAR::isError($result)) {
|
||||||
|
return $result;
|
||||||
|
} elseif ($nochange) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $this->saveCacheFile($cachefile, serialize($contents));
|
||||||
|
if (PEAR::isError($result)) {
|
||||||
|
if (file_exists($cacheidfile)) {
|
||||||
|
@unlink($cacheidfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveCacheFile($file, $contents)
|
||||||
|
{
|
||||||
|
$len = strlen($contents);
|
||||||
|
|
||||||
|
$cachefile_fp = @fopen($file, 'xb'); // x is the O_CREAT|O_EXCL mode
|
||||||
|
if ($cachefile_fp !== false) { // create file
|
||||||
|
if (fwrite($cachefile_fp, $contents, $len) < $len) {
|
||||||
|
fclose($cachefile_fp);
|
||||||
|
return PEAR::raiseError("Could not write $file.");
|
||||||
|
}
|
||||||
|
} else { // update file
|
||||||
|
$cachefile_lstat = lstat($file);
|
||||||
|
$cachefile_fp = @fopen($file, 'wb');
|
||||||
|
if (!$cachefile_fp) {
|
||||||
|
return PEAR::raiseError("Could not open $file for writing.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$cachefile_fstat = fstat($cachefile_fp);
|
||||||
|
if (
|
||||||
|
$cachefile_lstat['mode'] == $cachefile_fstat['mode'] &&
|
||||||
|
$cachefile_lstat['ino'] == $cachefile_fstat['ino'] &&
|
||||||
|
$cachefile_lstat['dev'] == $cachefile_fstat['dev'] &&
|
||||||
|
$cachefile_fstat['nlink'] === 1
|
||||||
|
) {
|
||||||
|
if (fwrite($cachefile_fp, $contents, $len) < $len) {
|
||||||
|
fclose($cachefile_fp);
|
||||||
|
return PEAR::raiseError("Could not write $file.");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fclose($cachefile_fp);
|
||||||
|
$link = function_exists('readlink') ? readlink($file) : $file;
|
||||||
|
return PEAR::raiseError('SECURITY ERROR: Will not write to ' . $file . ' as it is symlinked to ' . $link . ' - Possible symlink attack');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose($cachefile_fp);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Efficiently Download a file through HTTP. Returns downloaded file as a string in-memory
|
||||||
|
* This is best used for small files
|
||||||
|
*
|
||||||
|
* If an HTTP proxy has been configured (http_proxy PEAR_Config
|
||||||
|
* setting), the proxy will be used.
|
||||||
|
*
|
||||||
|
* @param string $url the URL to download
|
||||||
|
* @param string $save_dir directory to save file in
|
||||||
|
* @param false|string|array $lastmodified header values to check against for caching
|
||||||
|
* use false to return the header values from this download
|
||||||
|
* @param false|array $accept Accept headers to send
|
||||||
|
* @return string|array Returns the contents of the downloaded file or a PEAR
|
||||||
|
* error on failure. If the error is caused by
|
||||||
|
* socket-related errors, the error object will
|
||||||
|
* have the fsockopen error code available through
|
||||||
|
* getCode(). If caching is requested, then return the header
|
||||||
|
* values.
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function downloadHttp($url, $lastmodified = null, $accept = false, $channel = false)
|
||||||
|
{
|
||||||
|
static $redirect = 0;
|
||||||
|
// always reset , so we are clean case of error
|
||||||
|
$wasredirect = $redirect;
|
||||||
|
$redirect = 0;
|
||||||
|
|
||||||
|
$info = parse_url($url);
|
||||||
|
if (!isset($info['scheme']) || !in_array($info['scheme'], array('http', 'https'))) {
|
||||||
|
return PEAR::raiseError('Cannot download non-http URL "' . $url . '"');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($info['host'])) {
|
||||||
|
return PEAR::raiseError('Cannot download from non-URL "' . $url . '"');
|
||||||
|
}
|
||||||
|
|
||||||
|
$host = isset($info['host']) ? $info['host'] : null;
|
||||||
|
$port = isset($info['port']) ? $info['port'] : null;
|
||||||
|
$path = isset($info['path']) ? $info['path'] : null;
|
||||||
|
$schema = (isset($info['scheme']) && $info['scheme'] == 'https') ? 'https' : 'http';
|
||||||
|
|
||||||
|
$proxy_host = $proxy_port = $proxy_user = $proxy_pass = '';
|
||||||
|
if ($this->config->get('http_proxy')&&
|
||||||
|
$proxy = parse_url($this->config->get('http_proxy'))
|
||||||
|
) {
|
||||||
|
$proxy_host = isset($proxy['host']) ? $proxy['host'] : null;
|
||||||
|
if ($schema === 'https') {
|
||||||
|
$proxy_host = 'ssl://' . $proxy_host;
|
||||||
|
}
|
||||||
|
|
||||||
|
$proxy_port = isset($proxy['port']) ? $proxy['port'] : 8080;
|
||||||
|
$proxy_user = isset($proxy['user']) ? urldecode($proxy['user']) : null;
|
||||||
|
$proxy_pass = isset($proxy['pass']) ? urldecode($proxy['pass']) : null;
|
||||||
|
$proxy_schema = (isset($proxy['scheme']) && $proxy['scheme'] == 'https') ? 'https' : 'http';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($port)) {
|
||||||
|
$port = (isset($info['scheme']) && $info['scheme'] == 'https') ? 443 : 80;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($proxy['host'])) {
|
||||||
|
$request = "GET $url HTTP/1.1\r\n";
|
||||||
|
} else {
|
||||||
|
$request = "GET $path HTTP/1.1\r\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$request .= "Host: $host\r\n";
|
||||||
|
$ifmodifiedsince = '';
|
||||||
|
if (is_array($lastmodified)) {
|
||||||
|
if (isset($lastmodified['Last-Modified'])) {
|
||||||
|
$ifmodifiedsince = 'If-Modified-Since: ' . $lastmodified['Last-Modified'] . "\r\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($lastmodified['ETag'])) {
|
||||||
|
$ifmodifiedsince .= "If-None-Match: $lastmodified[ETag]\r\n";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$ifmodifiedsince = ($lastmodified ? "If-Modified-Since: $lastmodified\r\n" : '');
|
||||||
|
}
|
||||||
|
|
||||||
|
$request .= $ifmodifiedsince .
|
||||||
|
"User-Agent: PEAR/1.9.4/PHP/" . PHP_VERSION . "\r\n";
|
||||||
|
|
||||||
|
$username = $this->config->get('username', null, $channel);
|
||||||
|
$password = $this->config->get('password', null, $channel);
|
||||||
|
|
||||||
|
if ($username && $password) {
|
||||||
|
$tmp = base64_encode("$username:$password");
|
||||||
|
$request .= "Authorization: Basic $tmp\r\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($proxy_host != '' && $proxy_user != '') {
|
||||||
|
$request .= 'Proxy-Authorization: Basic ' .
|
||||||
|
base64_encode($proxy_user . ':' . $proxy_pass) . "\r\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($accept) {
|
||||||
|
$request .= 'Accept: ' . implode(', ', $accept) . "\r\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$request .= "Accept-Encoding:\r\n";
|
||||||
|
$request .= "Connection: close\r\n";
|
||||||
|
$request .= "\r\n";
|
||||||
|
|
||||||
|
if ($proxy_host != '') {
|
||||||
|
$fp = @fsockopen($proxy_host, $proxy_port, $errno, $errstr, 15);
|
||||||
|
if (!$fp) {
|
||||||
|
return PEAR::raiseError("Connection to `$proxy_host:$proxy_port' failed: $errstr", -9276);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ($schema === 'https') {
|
||||||
|
$host = 'ssl://' . $host;
|
||||||
|
}
|
||||||
|
|
||||||
|
$fp = @fsockopen($host, $port, $errno, $errstr);
|
||||||
|
if (!$fp) {
|
||||||
|
return PEAR::raiseError("Connection to `$host:$port' failed: $errstr", $errno);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fwrite($fp, $request);
|
||||||
|
|
||||||
|
$headers = array();
|
||||||
|
$reply = 0;
|
||||||
|
while ($line = trim(fgets($fp, 1024))) {
|
||||||
|
if (preg_match('/^([^:]+):\s+(.*)\s*\\z/', $line, $matches)) {
|
||||||
|
$headers[strtolower($matches[1])] = trim($matches[2]);
|
||||||
|
} elseif (preg_match('|^HTTP/1.[01] ([0-9]{3}) |', $line, $matches)) {
|
||||||
|
$reply = (int)$matches[1];
|
||||||
|
if ($reply == 304 && ($lastmodified || ($lastmodified === false))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in_array($reply, array(200, 301, 302, 303, 305, 307))) {
|
||||||
|
return PEAR::raiseError("File $schema://$host:$port$path not valid (received: $line)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($reply != 200) {
|
||||||
|
if (!isset($headers['location'])) {
|
||||||
|
return PEAR::raiseError("File $schema://$host:$port$path not valid (redirected but no location)");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($wasredirect > 4) {
|
||||||
|
return PEAR::raiseError("File $schema://$host:$port$path not valid (redirection looped more than 5 times)");
|
||||||
|
}
|
||||||
|
|
||||||
|
$redirect = $wasredirect + 1;
|
||||||
|
return $this->downloadHttp($headers['location'], $lastmodified, $accept, $channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
$length = isset($headers['content-length']) ? $headers['content-length'] : -1;
|
||||||
|
|
||||||
|
$data = '';
|
||||||
|
while ($chunk = @fread($fp, 8192)) {
|
||||||
|
$data .= $chunk;
|
||||||
|
}
|
||||||
|
fclose($fp);
|
||||||
|
|
||||||
|
if ($lastmodified === false || $lastmodified) {
|
||||||
|
if (isset($headers['etag'])) {
|
||||||
|
$lastmodified = array('ETag' => $headers['etag']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($headers['last-modified'])) {
|
||||||
|
if (is_array($lastmodified)) {
|
||||||
|
$lastmodified['Last-Modified'] = $headers['last-modified'];
|
||||||
|
} else {
|
||||||
|
$lastmodified = $headers['last-modified'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return array($data, $lastmodified, $headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,871 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PEAR_REST_10
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: 10.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since Release 1.4.0a12
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For downloading REST xml/txt files
|
||||||
|
*/
|
||||||
|
require_once 'PEAR/REST.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implement REST 1.0
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 1.4.0a12
|
||||||
|
*/
|
||||||
|
class PEAR_REST_10
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var PEAR_REST
|
||||||
|
*/
|
||||||
|
var $_rest;
|
||||||
|
function PEAR_REST_10($config, $options = array())
|
||||||
|
{
|
||||||
|
$this->_rest = &new PEAR_REST($config, $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve information about a remote package to be downloaded from a REST server
|
||||||
|
*
|
||||||
|
* @param string $base The uri to prepend to all REST calls
|
||||||
|
* @param array $packageinfo an array of format:
|
||||||
|
* <pre>
|
||||||
|
* array(
|
||||||
|
* 'package' => 'packagename',
|
||||||
|
* 'channel' => 'channelname',
|
||||||
|
* ['state' => 'alpha' (or valid state),]
|
||||||
|
* -or-
|
||||||
|
* ['version' => '1.whatever']
|
||||||
|
* </pre>
|
||||||
|
* @param string $prefstate Current preferred_state config variable value
|
||||||
|
* @param bool $installed the installed version of this package to compare against
|
||||||
|
* @return array|false|PEAR_Error see {@link _returnDownloadURL()}
|
||||||
|
*/
|
||||||
|
function getDownloadURL($base, $packageinfo, $prefstate, $installed, $channel = false)
|
||||||
|
{
|
||||||
|
$states = $this->betterStates($prefstate, true);
|
||||||
|
if (!$states) {
|
||||||
|
return PEAR::raiseError('"' . $prefstate . '" is not a valid state');
|
||||||
|
}
|
||||||
|
|
||||||
|
$channel = $packageinfo['channel'];
|
||||||
|
$package = $packageinfo['package'];
|
||||||
|
$state = isset($packageinfo['state']) ? $packageinfo['state'] : null;
|
||||||
|
$version = isset($packageinfo['version']) ? $packageinfo['version'] : null;
|
||||||
|
$restFile = $base . 'r/' . strtolower($package) . '/allreleases.xml';
|
||||||
|
|
||||||
|
$info = $this->_rest->retrieveData($restFile, false, false, $channel);
|
||||||
|
if (PEAR::isError($info)) {
|
||||||
|
return PEAR::raiseError('No releases available for package "' .
|
||||||
|
$channel . '/' . $package . '"');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($info['r'])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$release = $found = false;
|
||||||
|
if (!is_array($info['r']) || !isset($info['r'][0])) {
|
||||||
|
$info['r'] = array($info['r']);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($info['r'] as $release) {
|
||||||
|
if (!isset($this->_rest->_options['force']) && ($installed &&
|
||||||
|
version_compare($release['v'], $installed, '<'))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($state)) {
|
||||||
|
// try our preferred state first
|
||||||
|
if ($release['s'] == $state) {
|
||||||
|
$found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// see if there is something newer and more stable
|
||||||
|
// bug #7221
|
||||||
|
if (in_array($release['s'], $this->betterStates($state), true)) {
|
||||||
|
$found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} elseif (isset($version)) {
|
||||||
|
if ($release['v'] == $version) {
|
||||||
|
$found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (in_array($release['s'], $states)) {
|
||||||
|
$found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->_returnDownloadURL($base, $package, $release, $info, $found, false, $channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDepDownloadURL($base, $xsdversion, $dependency, $deppackage,
|
||||||
|
$prefstate = 'stable', $installed = false, $channel = false)
|
||||||
|
{
|
||||||
|
$states = $this->betterStates($prefstate, true);
|
||||||
|
if (!$states) {
|
||||||
|
return PEAR::raiseError('"' . $prefstate . '" is not a valid state');
|
||||||
|
}
|
||||||
|
|
||||||
|
$channel = $dependency['channel'];
|
||||||
|
$package = $dependency['name'];
|
||||||
|
$state = isset($dependency['state']) ? $dependency['state'] : null;
|
||||||
|
$version = isset($dependency['version']) ? $dependency['version'] : null;
|
||||||
|
$restFile = $base . 'r/' . strtolower($package) . '/allreleases.xml';
|
||||||
|
|
||||||
|
$info = $this->_rest->retrieveData($restFile, false, false, $channel);
|
||||||
|
if (PEAR::isError($info)) {
|
||||||
|
return PEAR::raiseError('Package "' . $deppackage['channel'] . '/' . $deppackage['package']
|
||||||
|
. '" dependency "' . $channel . '/' . $package . '" has no releases');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($info) || !isset($info['r'])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$exclude = array();
|
||||||
|
$min = $max = $recommended = false;
|
||||||
|
if ($xsdversion == '1.0') {
|
||||||
|
switch ($dependency['rel']) {
|
||||||
|
case 'ge' :
|
||||||
|
$min = $dependency['version'];
|
||||||
|
break;
|
||||||
|
case 'gt' :
|
||||||
|
$min = $dependency['version'];
|
||||||
|
$exclude = array($dependency['version']);
|
||||||
|
break;
|
||||||
|
case 'eq' :
|
||||||
|
$recommended = $dependency['version'];
|
||||||
|
break;
|
||||||
|
case 'lt' :
|
||||||
|
$max = $dependency['version'];
|
||||||
|
$exclude = array($dependency['version']);
|
||||||
|
break;
|
||||||
|
case 'le' :
|
||||||
|
$max = $dependency['version'];
|
||||||
|
break;
|
||||||
|
case 'ne' :
|
||||||
|
$exclude = array($dependency['version']);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$min = isset($dependency['min']) ? $dependency['min'] : false;
|
||||||
|
$max = isset($dependency['max']) ? $dependency['max'] : false;
|
||||||
|
$recommended = isset($dependency['recommended']) ?
|
||||||
|
$dependency['recommended'] : false;
|
||||||
|
if (isset($dependency['exclude'])) {
|
||||||
|
if (!isset($dependency['exclude'][0])) {
|
||||||
|
$exclude = array($dependency['exclude']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$release = $found = false;
|
||||||
|
if (!is_array($info['r']) || !isset($info['r'][0])) {
|
||||||
|
$info['r'] = array($info['r']);
|
||||||
|
}
|
||||||
|
foreach ($info['r'] as $release) {
|
||||||
|
if (!isset($this->_rest->_options['force']) && ($installed &&
|
||||||
|
version_compare($release['v'], $installed, '<'))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (in_array($release['v'], $exclude)) { // skip excluded versions
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// allow newer releases to say "I'm OK with the dependent package"
|
||||||
|
if ($xsdversion == '2.0' && isset($release['co'])) {
|
||||||
|
if (!is_array($release['co']) || !isset($release['co'][0])) {
|
||||||
|
$release['co'] = array($release['co']);
|
||||||
|
}
|
||||||
|
foreach ($release['co'] as $entry) {
|
||||||
|
if (isset($entry['x']) && !is_array($entry['x'])) {
|
||||||
|
$entry['x'] = array($entry['x']);
|
||||||
|
} elseif (!isset($entry['x'])) {
|
||||||
|
$entry['x'] = array();
|
||||||
|
}
|
||||||
|
if ($entry['c'] == $deppackage['channel'] &&
|
||||||
|
strtolower($entry['p']) == strtolower($deppackage['package']) &&
|
||||||
|
version_compare($deppackage['version'], $entry['min'], '>=') &&
|
||||||
|
version_compare($deppackage['version'], $entry['max'], '<=') &&
|
||||||
|
!in_array($release['v'], $entry['x'])) {
|
||||||
|
$recommended = $release['v'];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($recommended) {
|
||||||
|
if ($release['v'] != $recommended) { // if we want a specific
|
||||||
|
// version, then skip all others
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
if (!in_array($release['s'], $states)) {
|
||||||
|
// the stability is too low, but we must return the
|
||||||
|
// recommended version if possible
|
||||||
|
return $this->_returnDownloadURL($base, $package, $release, $info, true, false, $channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($min && version_compare($release['v'], $min, 'lt')) { // skip too old versions
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ($max && version_compare($release['v'], $max, 'gt')) { // skip too new versions
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ($installed && version_compare($release['v'], $installed, '<')) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (in_array($release['s'], $states)) { // if in the preferred state...
|
||||||
|
$found = true; // ... then use it
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this->_returnDownloadURL($base, $package, $release, $info, $found, false, $channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Take raw data and return the array needed for processing a download URL
|
||||||
|
*
|
||||||
|
* @param string $base REST base uri
|
||||||
|
* @param string $package Package name
|
||||||
|
* @param array $release an array of format array('v' => version, 's' => state)
|
||||||
|
* describing the release to download
|
||||||
|
* @param array $info list of all releases as defined by allreleases.xml
|
||||||
|
* @param bool|null $found determines whether the release was found or this is the next
|
||||||
|
* best alternative. If null, then versions were skipped because
|
||||||
|
* of PHP dependency
|
||||||
|
* @return array|PEAR_Error
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _returnDownloadURL($base, $package, $release, $info, $found, $phpversion = false, $channel = false)
|
||||||
|
{
|
||||||
|
if (!$found) {
|
||||||
|
$release = $info['r'][0];
|
||||||
|
}
|
||||||
|
|
||||||
|
$packageLower = strtolower($package);
|
||||||
|
$pinfo = $this->_rest->retrieveCacheFirst($base . 'p/' . $packageLower . '/' .
|
||||||
|
'info.xml', false, false, $channel);
|
||||||
|
if (PEAR::isError($pinfo)) {
|
||||||
|
return PEAR::raiseError('Package "' . $package .
|
||||||
|
'" does not have REST info xml available');
|
||||||
|
}
|
||||||
|
|
||||||
|
$releaseinfo = $this->_rest->retrieveCacheFirst($base . 'r/' . $packageLower . '/' .
|
||||||
|
$release['v'] . '.xml', false, false, $channel);
|
||||||
|
if (PEAR::isError($releaseinfo)) {
|
||||||
|
return PEAR::raiseError('Package "' . $package . '" Version "' . $release['v'] .
|
||||||
|
'" does not have REST xml available');
|
||||||
|
}
|
||||||
|
|
||||||
|
$packagexml = $this->_rest->retrieveCacheFirst($base . 'r/' . $packageLower . '/' .
|
||||||
|
'deps.' . $release['v'] . '.txt', false, true, $channel);
|
||||||
|
if (PEAR::isError($packagexml)) {
|
||||||
|
return PEAR::raiseError('Package "' . $package . '" Version "' . $release['v'] .
|
||||||
|
'" does not have REST dependency information available');
|
||||||
|
}
|
||||||
|
|
||||||
|
$packagexml = unserialize($packagexml);
|
||||||
|
if (!$packagexml) {
|
||||||
|
$packagexml = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$allinfo = $this->_rest->retrieveData($base . 'r/' . $packageLower .
|
||||||
|
'/allreleases.xml', false, false, $channel);
|
||||||
|
if (PEAR::isError($allinfo)) {
|
||||||
|
return $allinfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($allinfo['r']) || !isset($allinfo['r'][0])) {
|
||||||
|
$allinfo['r'] = array($allinfo['r']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$compatible = false;
|
||||||
|
foreach ($allinfo['r'] as $release) {
|
||||||
|
if ($release['v'] != $releaseinfo['v']) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($release['co'])) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$compatible = array();
|
||||||
|
if (!is_array($release['co']) || !isset($release['co'][0])) {
|
||||||
|
$release['co'] = array($release['co']);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($release['co'] as $entry) {
|
||||||
|
$comp = array();
|
||||||
|
$comp['name'] = $entry['p'];
|
||||||
|
$comp['channel'] = $entry['c'];
|
||||||
|
$comp['min'] = $entry['min'];
|
||||||
|
$comp['max'] = $entry['max'];
|
||||||
|
if (isset($entry['x']) && !is_array($entry['x'])) {
|
||||||
|
$comp['exclude'] = $entry['x'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$compatible[] = $comp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($compatible) == 1) {
|
||||||
|
$compatible = $compatible[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$deprecated = false;
|
||||||
|
if (isset($pinfo['dc']) && isset($pinfo['dp'])) {
|
||||||
|
if (is_array($pinfo['dp'])) {
|
||||||
|
$deprecated = array('channel' => (string) $pinfo['dc'],
|
||||||
|
'package' => trim($pinfo['dp']['_content']));
|
||||||
|
} else {
|
||||||
|
$deprecated = array('channel' => (string) $pinfo['dc'],
|
||||||
|
'package' => trim($pinfo['dp']));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$return = array(
|
||||||
|
'version' => $releaseinfo['v'],
|
||||||
|
'info' => $packagexml,
|
||||||
|
'package' => $releaseinfo['p']['_content'],
|
||||||
|
'stability' => $releaseinfo['st'],
|
||||||
|
'compatible' => $compatible,
|
||||||
|
'deprecated' => $deprecated,
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($found) {
|
||||||
|
$return['url'] = $releaseinfo['g'];
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$return['php'] = $phpversion;
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
function listPackages($base, $channel = false)
|
||||||
|
{
|
||||||
|
$packagelist = $this->_rest->retrieveData($base . 'p/packages.xml', false, false, $channel);
|
||||||
|
if (PEAR::isError($packagelist)) {
|
||||||
|
return $packagelist;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($packagelist) || !isset($packagelist['p'])) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($packagelist['p'])) {
|
||||||
|
$packagelist['p'] = array($packagelist['p']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $packagelist['p'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List all categories of a REST server
|
||||||
|
*
|
||||||
|
* @param string $base base URL of the server
|
||||||
|
* @return array of categorynames
|
||||||
|
*/
|
||||||
|
function listCategories($base, $channel = false)
|
||||||
|
{
|
||||||
|
$categories = array();
|
||||||
|
|
||||||
|
// c/categories.xml does not exist;
|
||||||
|
// check for every package its category manually
|
||||||
|
// This is SLOOOWWWW : ///
|
||||||
|
$packagelist = $this->_rest->retrieveData($base . 'p/packages.xml', false, false, $channel);
|
||||||
|
if (PEAR::isError($packagelist)) {
|
||||||
|
return $packagelist;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($packagelist) || !isset($packagelist['p'])) {
|
||||||
|
$ret = array();
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($packagelist['p'])) {
|
||||||
|
$packagelist['p'] = array($packagelist['p']);
|
||||||
|
}
|
||||||
|
|
||||||
|
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
|
||||||
|
foreach ($packagelist['p'] as $package) {
|
||||||
|
$inf = $this->_rest->retrieveData($base . 'p/' . strtolower($package) . '/info.xml', false, false, $channel);
|
||||||
|
if (PEAR::isError($inf)) {
|
||||||
|
PEAR::popErrorHandling();
|
||||||
|
return $inf;
|
||||||
|
}
|
||||||
|
$cat = $inf['ca']['_content'];
|
||||||
|
if (!isset($categories[$cat])) {
|
||||||
|
$categories[$cat] = $inf['ca'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_values($categories);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List a category of a REST server
|
||||||
|
*
|
||||||
|
* @param string $base base URL of the server
|
||||||
|
* @param string $category name of the category
|
||||||
|
* @param boolean $info also download full package info
|
||||||
|
* @return array of packagenames
|
||||||
|
*/
|
||||||
|
function listCategory($base, $category, $info = false, $channel = false)
|
||||||
|
{
|
||||||
|
// gives '404 Not Found' error when category doesn't exist
|
||||||
|
$packagelist = $this->_rest->retrieveData($base.'c/'.urlencode($category).'/packages.xml', false, false, $channel);
|
||||||
|
if (PEAR::isError($packagelist)) {
|
||||||
|
return $packagelist;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($packagelist) || !isset($packagelist['p'])) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($packagelist['p']) ||
|
||||||
|
!isset($packagelist['p'][0])) { // only 1 pkg
|
||||||
|
$packagelist = array($packagelist['p']);
|
||||||
|
} else {
|
||||||
|
$packagelist = $packagelist['p'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($info == true) {
|
||||||
|
// get individual package info
|
||||||
|
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
|
||||||
|
foreach ($packagelist as $i => $packageitem) {
|
||||||
|
$url = sprintf('%s'.'r/%s/latest.txt',
|
||||||
|
$base,
|
||||||
|
strtolower($packageitem['_content']));
|
||||||
|
$version = $this->_rest->retrieveData($url, false, false, $channel);
|
||||||
|
if (PEAR::isError($version)) {
|
||||||
|
break; // skipit
|
||||||
|
}
|
||||||
|
$url = sprintf('%s'.'r/%s/%s.xml',
|
||||||
|
$base,
|
||||||
|
strtolower($packageitem['_content']),
|
||||||
|
$version);
|
||||||
|
$info = $this->_rest->retrieveData($url, false, false, $channel);
|
||||||
|
if (PEAR::isError($info)) {
|
||||||
|
break; // skipit
|
||||||
|
}
|
||||||
|
$packagelist[$i]['info'] = $info;
|
||||||
|
}
|
||||||
|
PEAR::popErrorHandling();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $packagelist;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function listAll($base, $dostable, $basic = true, $searchpackage = false, $searchsummary = false, $channel = false)
|
||||||
|
{
|
||||||
|
$packagelist = $this->_rest->retrieveData($base . 'p/packages.xml', false, false, $channel);
|
||||||
|
if (PEAR::isError($packagelist)) {
|
||||||
|
return $packagelist;
|
||||||
|
}
|
||||||
|
if ($this->_rest->config->get('verbose') > 0) {
|
||||||
|
$ui = &PEAR_Frontend::singleton();
|
||||||
|
$ui->log('Retrieving data...0%', true);
|
||||||
|
}
|
||||||
|
$ret = array();
|
||||||
|
if (!is_array($packagelist) || !isset($packagelist['p'])) {
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
if (!is_array($packagelist['p'])) {
|
||||||
|
$packagelist['p'] = array($packagelist['p']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// only search-packagename = quicksearch !
|
||||||
|
if ($searchpackage && (!$searchsummary || empty($searchpackage))) {
|
||||||
|
$newpackagelist = array();
|
||||||
|
foreach ($packagelist['p'] as $package) {
|
||||||
|
if (!empty($searchpackage) && stristr($package, $searchpackage) !== false) {
|
||||||
|
$newpackagelist[] = $package;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$packagelist['p'] = $newpackagelist;
|
||||||
|
}
|
||||||
|
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
|
||||||
|
$next = .1;
|
||||||
|
foreach ($packagelist['p'] as $progress => $package) {
|
||||||
|
if ($this->_rest->config->get('verbose') > 0) {
|
||||||
|
if ($progress / count($packagelist['p']) >= $next) {
|
||||||
|
if ($next == .5) {
|
||||||
|
$ui->log('50%', false);
|
||||||
|
} else {
|
||||||
|
$ui->log('.', false);
|
||||||
|
}
|
||||||
|
$next += .1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($basic) { // remote-list command
|
||||||
|
if ($dostable) {
|
||||||
|
$latest = $this->_rest->retrieveData($base . 'r/' . strtolower($package) .
|
||||||
|
'/stable.txt', false, false, $channel);
|
||||||
|
} else {
|
||||||
|
$latest = $this->_rest->retrieveData($base . 'r/' . strtolower($package) .
|
||||||
|
'/latest.txt', false, false, $channel);
|
||||||
|
}
|
||||||
|
if (PEAR::isError($latest)) {
|
||||||
|
$latest = false;
|
||||||
|
}
|
||||||
|
$info = array('stable' => $latest);
|
||||||
|
} else { // list-all command
|
||||||
|
$inf = $this->_rest->retrieveData($base . 'p/' . strtolower($package) . '/info.xml', false, false, $channel);
|
||||||
|
if (PEAR::isError($inf)) {
|
||||||
|
PEAR::popErrorHandling();
|
||||||
|
return $inf;
|
||||||
|
}
|
||||||
|
if ($searchpackage) {
|
||||||
|
$found = (!empty($searchpackage) && stristr($package, $searchpackage) !== false);
|
||||||
|
if (!$found && !(isset($searchsummary) && !empty($searchsummary)
|
||||||
|
&& (stristr($inf['s'], $searchsummary) !== false
|
||||||
|
|| stristr($inf['d'], $searchsummary) !== false)))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
$releases = $this->_rest->retrieveData($base . 'r/' . strtolower($package) .
|
||||||
|
'/allreleases.xml', false, false, $channel);
|
||||||
|
if (PEAR::isError($releases)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!isset($releases['r'][0])) {
|
||||||
|
$releases['r'] = array($releases['r']);
|
||||||
|
}
|
||||||
|
unset($latest);
|
||||||
|
unset($unstable);
|
||||||
|
unset($stable);
|
||||||
|
unset($state);
|
||||||
|
foreach ($releases['r'] as $release) {
|
||||||
|
if (!isset($latest)) {
|
||||||
|
if ($dostable && $release['s'] == 'stable') {
|
||||||
|
$latest = $release['v'];
|
||||||
|
$state = 'stable';
|
||||||
|
}
|
||||||
|
if (!$dostable) {
|
||||||
|
$latest = $release['v'];
|
||||||
|
$state = $release['s'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isset($stable) && $release['s'] == 'stable') {
|
||||||
|
$stable = $release['v'];
|
||||||
|
if (!isset($unstable)) {
|
||||||
|
$unstable = $stable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isset($unstable) && $release['s'] != 'stable') {
|
||||||
|
$latest = $unstable = $release['v'];
|
||||||
|
$state = $release['s'];
|
||||||
|
}
|
||||||
|
if (isset($latest) && !isset($state)) {
|
||||||
|
$state = $release['s'];
|
||||||
|
}
|
||||||
|
if (isset($latest) && isset($stable) && isset($unstable)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$deps = array();
|
||||||
|
if (!isset($unstable)) {
|
||||||
|
$unstable = false;
|
||||||
|
$state = 'stable';
|
||||||
|
if (isset($stable)) {
|
||||||
|
$latest = $unstable = $stable;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$latest = $unstable;
|
||||||
|
}
|
||||||
|
if (!isset($latest)) {
|
||||||
|
$latest = false;
|
||||||
|
}
|
||||||
|
if ($latest) {
|
||||||
|
$d = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/deps.' .
|
||||||
|
$latest . '.txt', false, false, $channel);
|
||||||
|
if (!PEAR::isError($d)) {
|
||||||
|
$d = unserialize($d);
|
||||||
|
if ($d) {
|
||||||
|
if (isset($d['required'])) {
|
||||||
|
if (!class_exists('PEAR_PackageFile_v2')) {
|
||||||
|
require_once 'PEAR/PackageFile/v2.php';
|
||||||
|
}
|
||||||
|
if (!isset($pf)) {
|
||||||
|
$pf = new PEAR_PackageFile_v2;
|
||||||
|
}
|
||||||
|
$pf->setDeps($d);
|
||||||
|
$tdeps = $pf->getDeps();
|
||||||
|
} else {
|
||||||
|
$tdeps = $d;
|
||||||
|
}
|
||||||
|
foreach ($tdeps as $dep) {
|
||||||
|
if ($dep['type'] !== 'pkg') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$deps[] = $dep;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isset($stable)) {
|
||||||
|
$stable = '-n/a-';
|
||||||
|
}
|
||||||
|
if (!$searchpackage) {
|
||||||
|
$info = array('stable' => $latest, 'summary' => $inf['s'], 'description' =>
|
||||||
|
$inf['d'], 'deps' => $deps, 'category' => $inf['ca']['_content'],
|
||||||
|
'unstable' => $unstable, 'state' => $state);
|
||||||
|
} else {
|
||||||
|
$info = array('stable' => $stable, 'summary' => $inf['s'], 'description' =>
|
||||||
|
$inf['d'], 'deps' => $deps, 'category' => $inf['ca']['_content'],
|
||||||
|
'unstable' => $unstable, 'state' => $state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$ret[$package] = $info;
|
||||||
|
}
|
||||||
|
PEAR::popErrorHandling();
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
function listLatestUpgrades($base, $pref_state, $installed, $channel, &$reg)
|
||||||
|
{
|
||||||
|
$packagelist = $this->_rest->retrieveData($base . 'p/packages.xml', false, false, $channel);
|
||||||
|
if (PEAR::isError($packagelist)) {
|
||||||
|
return $packagelist;
|
||||||
|
}
|
||||||
|
|
||||||
|
$ret = array();
|
||||||
|
if (!is_array($packagelist) || !isset($packagelist['p'])) {
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($packagelist['p'])) {
|
||||||
|
$packagelist['p'] = array($packagelist['p']);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($packagelist['p'] as $package) {
|
||||||
|
if (!isset($installed[strtolower($package)])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$inst_version = $reg->packageInfo($package, 'version', $channel);
|
||||||
|
$inst_state = $reg->packageInfo($package, 'release_state', $channel);
|
||||||
|
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
|
||||||
|
$info = $this->_rest->retrieveData($base . 'r/' . strtolower($package) .
|
||||||
|
'/allreleases.xml', false, false, $channel);
|
||||||
|
PEAR::popErrorHandling();
|
||||||
|
if (PEAR::isError($info)) {
|
||||||
|
continue; // no remote releases
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($info['r'])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$release = $found = false;
|
||||||
|
if (!is_array($info['r']) || !isset($info['r'][0])) {
|
||||||
|
$info['r'] = array($info['r']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// $info['r'] is sorted by version number
|
||||||
|
usort($info['r'], array($this, '_sortReleasesByVersionNumber'));
|
||||||
|
foreach ($info['r'] as $release) {
|
||||||
|
if ($inst_version && version_compare($release['v'], $inst_version, '<=')) {
|
||||||
|
// not newer than the one installed
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// new version > installed version
|
||||||
|
if (!$pref_state) {
|
||||||
|
// every state is a good state
|
||||||
|
$found = true;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
$new_state = $release['s'];
|
||||||
|
// if new state >= installed state: go
|
||||||
|
if (in_array($new_state, $this->betterStates($inst_state, true))) {
|
||||||
|
$found = true;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
// only allow to lower the state of package,
|
||||||
|
// if new state >= preferred state: go
|
||||||
|
if (in_array($new_state, $this->betterStates($pref_state, true))) {
|
||||||
|
$found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$found) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$relinfo = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/' .
|
||||||
|
$release['v'] . '.xml', false, false, $channel);
|
||||||
|
if (PEAR::isError($relinfo)) {
|
||||||
|
return $relinfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
$ret[$package] = array(
|
||||||
|
'version' => $release['v'],
|
||||||
|
'state' => $release['s'],
|
||||||
|
'filesize' => $relinfo['f'],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
function packageInfo($base, $package, $channel = false)
|
||||||
|
{
|
||||||
|
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
|
||||||
|
$pinfo = $this->_rest->retrieveData($base . 'p/' . strtolower($package) . '/info.xml', false, false, $channel);
|
||||||
|
if (PEAR::isError($pinfo)) {
|
||||||
|
PEAR::popErrorHandling();
|
||||||
|
return PEAR::raiseError('Unknown package: "' . $package . '" in channel "' . $channel . '"' . "\n". 'Debug: ' .
|
||||||
|
$pinfo->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
$releases = array();
|
||||||
|
$allreleases = $this->_rest->retrieveData($base . 'r/' . strtolower($package) .
|
||||||
|
'/allreleases.xml', false, false, $channel);
|
||||||
|
if (!PEAR::isError($allreleases)) {
|
||||||
|
if (!class_exists('PEAR_PackageFile_v2')) {
|
||||||
|
require_once 'PEAR/PackageFile/v2.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($allreleases['r']) || !isset($allreleases['r'][0])) {
|
||||||
|
$allreleases['r'] = array($allreleases['r']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$pf = new PEAR_PackageFile_v2;
|
||||||
|
foreach ($allreleases['r'] as $release) {
|
||||||
|
$ds = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/deps.' .
|
||||||
|
$release['v'] . '.txt', false, false, $channel);
|
||||||
|
if (PEAR::isError($ds)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($latest)) {
|
||||||
|
$latest = $release['v'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$pf->setDeps(unserialize($ds));
|
||||||
|
$ds = $pf->getDeps();
|
||||||
|
$info = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package)
|
||||||
|
. '/' . $release['v'] . '.xml', false, false, $channel);
|
||||||
|
|
||||||
|
if (PEAR::isError($info)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$releases[$release['v']] = array(
|
||||||
|
'doneby' => $info['m'],
|
||||||
|
'license' => $info['l'],
|
||||||
|
'summary' => $info['s'],
|
||||||
|
'description' => $info['d'],
|
||||||
|
'releasedate' => $info['da'],
|
||||||
|
'releasenotes' => $info['n'],
|
||||||
|
'state' => $release['s'],
|
||||||
|
'deps' => $ds ? $ds : array(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$latest = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
PEAR::popErrorHandling();
|
||||||
|
if (isset($pinfo['dc']) && isset($pinfo['dp'])) {
|
||||||
|
if (is_array($pinfo['dp'])) {
|
||||||
|
$deprecated = array('channel' => (string) $pinfo['dc'],
|
||||||
|
'package' => trim($pinfo['dp']['_content']));
|
||||||
|
} else {
|
||||||
|
$deprecated = array('channel' => (string) $pinfo['dc'],
|
||||||
|
'package' => trim($pinfo['dp']));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$deprecated = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($latest)) {
|
||||||
|
$latest = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'name' => $pinfo['n'],
|
||||||
|
'channel' => $pinfo['c'],
|
||||||
|
'category' => $pinfo['ca']['_content'],
|
||||||
|
'stable' => $latest,
|
||||||
|
'license' => $pinfo['l'],
|
||||||
|
'summary' => $pinfo['s'],
|
||||||
|
'description' => $pinfo['d'],
|
||||||
|
'releases' => $releases,
|
||||||
|
'deprecated' => $deprecated,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an array containing all of the states that are more stable than
|
||||||
|
* or equal to the passed in state
|
||||||
|
*
|
||||||
|
* @param string Release state
|
||||||
|
* @param boolean Determines whether to include $state in the list
|
||||||
|
* @return false|array False if $state is not a valid release state
|
||||||
|
*/
|
||||||
|
function betterStates($state, $include = false)
|
||||||
|
{
|
||||||
|
static $states = array('snapshot', 'devel', 'alpha', 'beta', 'stable');
|
||||||
|
$i = array_search($state, $states);
|
||||||
|
if ($i === false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($include) {
|
||||||
|
$i--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_slice($states, $i + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort releases by version number
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _sortReleasesByVersionNumber($a, $b)
|
||||||
|
{
|
||||||
|
if (version_compare($a['v'], $b['v'], '=')) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (version_compare($a['v'], $b['v'], '>')) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (version_compare($a['v'], $b['v'], '<')) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,341 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PEAR_REST_11 - implement faster list-all/remote-list command
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: 11.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since Release 1.4.3
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For downloading REST xml/txt files
|
||||||
|
*/
|
||||||
|
require_once 'PEAR/REST.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implement REST 1.1
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 1.4.3
|
||||||
|
*/
|
||||||
|
class PEAR_REST_11
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var PEAR_REST
|
||||||
|
*/
|
||||||
|
var $_rest;
|
||||||
|
|
||||||
|
function PEAR_REST_11($config, $options = array())
|
||||||
|
{
|
||||||
|
$this->_rest = &new PEAR_REST($config, $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
function listAll($base, $dostable, $basic = true, $searchpackage = false, $searchsummary = false, $channel = false)
|
||||||
|
{
|
||||||
|
$categorylist = $this->_rest->retrieveData($base . 'c/categories.xml', false, false, $channel);
|
||||||
|
if (PEAR::isError($categorylist)) {
|
||||||
|
return $categorylist;
|
||||||
|
}
|
||||||
|
|
||||||
|
$ret = array();
|
||||||
|
if (!is_array($categorylist['c']) || !isset($categorylist['c'][0])) {
|
||||||
|
$categorylist['c'] = array($categorylist['c']);
|
||||||
|
}
|
||||||
|
|
||||||
|
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
|
||||||
|
|
||||||
|
foreach ($categorylist['c'] as $progress => $category) {
|
||||||
|
$category = $category['_content'];
|
||||||
|
$packagesinfo = $this->_rest->retrieveData($base .
|
||||||
|
'c/' . urlencode($category) . '/packagesinfo.xml', false, false, $channel);
|
||||||
|
|
||||||
|
if (PEAR::isError($packagesinfo)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($packagesinfo) || !isset($packagesinfo['pi'])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($packagesinfo['pi']) || !isset($packagesinfo['pi'][0])) {
|
||||||
|
$packagesinfo['pi'] = array($packagesinfo['pi']);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($packagesinfo['pi'] as $packageinfo) {
|
||||||
|
if (empty($packageinfo)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$info = $packageinfo['p'];
|
||||||
|
$package = $info['n'];
|
||||||
|
$releases = isset($packageinfo['a']) ? $packageinfo['a'] : false;
|
||||||
|
unset($latest);
|
||||||
|
unset($unstable);
|
||||||
|
unset($stable);
|
||||||
|
unset($state);
|
||||||
|
|
||||||
|
if ($releases) {
|
||||||
|
if (!isset($releases['r'][0])) {
|
||||||
|
$releases['r'] = array($releases['r']);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($releases['r'] as $release) {
|
||||||
|
if (!isset($latest)) {
|
||||||
|
if ($dostable && $release['s'] == 'stable') {
|
||||||
|
$latest = $release['v'];
|
||||||
|
$state = 'stable';
|
||||||
|
}
|
||||||
|
if (!$dostable) {
|
||||||
|
$latest = $release['v'];
|
||||||
|
$state = $release['s'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($stable) && $release['s'] == 'stable') {
|
||||||
|
$stable = $release['v'];
|
||||||
|
if (!isset($unstable)) {
|
||||||
|
$unstable = $stable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($unstable) && $release['s'] != 'stable') {
|
||||||
|
$unstable = $release['v'];
|
||||||
|
$state = $release['s'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($latest) && !isset($state)) {
|
||||||
|
$state = $release['s'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($latest) && isset($stable) && isset($unstable)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($basic) { // remote-list command
|
||||||
|
if (!isset($latest)) {
|
||||||
|
$latest = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($dostable) {
|
||||||
|
// $state is not set if there are no releases
|
||||||
|
if (isset($state) && $state == 'stable') {
|
||||||
|
$ret[$package] = array('stable' => $latest);
|
||||||
|
} else {
|
||||||
|
$ret[$package] = array('stable' => '-n/a-');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$ret[$package] = array('stable' => $latest);
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// list-all command
|
||||||
|
if (!isset($unstable)) {
|
||||||
|
$unstable = false;
|
||||||
|
$state = 'stable';
|
||||||
|
if (isset($stable)) {
|
||||||
|
$latest = $unstable = $stable;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$latest = $unstable;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($latest)) {
|
||||||
|
$latest = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$deps = array();
|
||||||
|
if ($latest && isset($packageinfo['deps'])) {
|
||||||
|
if (!is_array($packageinfo['deps']) ||
|
||||||
|
!isset($packageinfo['deps'][0])
|
||||||
|
) {
|
||||||
|
$packageinfo['deps'] = array($packageinfo['deps']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$d = false;
|
||||||
|
foreach ($packageinfo['deps'] as $dep) {
|
||||||
|
if ($dep['v'] == $latest) {
|
||||||
|
$d = unserialize($dep['d']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($d) {
|
||||||
|
if (isset($d['required'])) {
|
||||||
|
if (!class_exists('PEAR_PackageFile_v2')) {
|
||||||
|
require_once 'PEAR/PackageFile/v2.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($pf)) {
|
||||||
|
$pf = new PEAR_PackageFile_v2;
|
||||||
|
}
|
||||||
|
|
||||||
|
$pf->setDeps($d);
|
||||||
|
$tdeps = $pf->getDeps();
|
||||||
|
} else {
|
||||||
|
$tdeps = $d;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($tdeps as $dep) {
|
||||||
|
if ($dep['type'] !== 'pkg') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$deps[] = $dep;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$info = array(
|
||||||
|
'stable' => $latest,
|
||||||
|
'summary' => $info['s'],
|
||||||
|
'description' => $info['d'],
|
||||||
|
'deps' => $deps,
|
||||||
|
'category' => $info['ca']['_content'],
|
||||||
|
'unstable' => $unstable,
|
||||||
|
'state' => $state
|
||||||
|
);
|
||||||
|
$ret[$package] = $info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PEAR::popErrorHandling();
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List all categories of a REST server
|
||||||
|
*
|
||||||
|
* @param string $base base URL of the server
|
||||||
|
* @return array of categorynames
|
||||||
|
*/
|
||||||
|
function listCategories($base, $channel = false)
|
||||||
|
{
|
||||||
|
$categorylist = $this->_rest->retrieveData($base . 'c/categories.xml', false, false, $channel);
|
||||||
|
if (PEAR::isError($categorylist)) {
|
||||||
|
return $categorylist;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($categorylist) || !isset($categorylist['c'])) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($categorylist['c']['_content'])) {
|
||||||
|
// only 1 category
|
||||||
|
$categorylist['c'] = array($categorylist['c']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $categorylist['c'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List packages in a category of a REST server
|
||||||
|
*
|
||||||
|
* @param string $base base URL of the server
|
||||||
|
* @param string $category name of the category
|
||||||
|
* @param boolean $info also download full package info
|
||||||
|
* @return array of packagenames
|
||||||
|
*/
|
||||||
|
function listCategory($base, $category, $info = false, $channel = false)
|
||||||
|
{
|
||||||
|
if ($info == false) {
|
||||||
|
$url = '%s'.'c/%s/packages.xml';
|
||||||
|
} else {
|
||||||
|
$url = '%s'.'c/%s/packagesinfo.xml';
|
||||||
|
}
|
||||||
|
$url = sprintf($url,
|
||||||
|
$base,
|
||||||
|
urlencode($category));
|
||||||
|
|
||||||
|
// gives '404 Not Found' error when category doesn't exist
|
||||||
|
$packagelist = $this->_rest->retrieveData($url, false, false, $channel);
|
||||||
|
if (PEAR::isError($packagelist)) {
|
||||||
|
return $packagelist;
|
||||||
|
}
|
||||||
|
if (!is_array($packagelist)) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($info == false) {
|
||||||
|
if (!isset($packagelist['p'])) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
if (!is_array($packagelist['p']) ||
|
||||||
|
!isset($packagelist['p'][0])) { // only 1 pkg
|
||||||
|
$packagelist = array($packagelist['p']);
|
||||||
|
} else {
|
||||||
|
$packagelist = $packagelist['p'];
|
||||||
|
}
|
||||||
|
return $packagelist;
|
||||||
|
}
|
||||||
|
|
||||||
|
// info == true
|
||||||
|
if (!isset($packagelist['pi'])) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($packagelist['pi']) ||
|
||||||
|
!isset($packagelist['pi'][0])) { // only 1 pkg
|
||||||
|
$packagelist_pre = array($packagelist['pi']);
|
||||||
|
} else {
|
||||||
|
$packagelist_pre = $packagelist['pi'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$packagelist = array();
|
||||||
|
foreach ($packagelist_pre as $i => $item) {
|
||||||
|
// compatibility with r/<latest.txt>.xml
|
||||||
|
if (isset($item['a']['r'][0])) {
|
||||||
|
// multiple releases
|
||||||
|
$item['p']['v'] = $item['a']['r'][0]['v'];
|
||||||
|
$item['p']['st'] = $item['a']['r'][0]['s'];
|
||||||
|
} elseif (isset($item['a'])) {
|
||||||
|
// first and only release
|
||||||
|
$item['p']['v'] = $item['a']['r']['v'];
|
||||||
|
$item['p']['st'] = $item['a']['r']['s'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$packagelist[$i] = array('attribs' => $item['p']['r'],
|
||||||
|
'_content' => $item['p']['n'],
|
||||||
|
'info' => $item['p']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $packagelist;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an array containing all of the states that are more stable than
|
||||||
|
* or equal to the passed in state
|
||||||
|
*
|
||||||
|
* @param string Release state
|
||||||
|
* @param boolean Determines whether to include $state in the list
|
||||||
|
* @return false|array False if $state is not a valid release state
|
||||||
|
*/
|
||||||
|
function betterStates($state, $include = false)
|
||||||
|
{
|
||||||
|
static $states = array('snapshot', 'devel', 'alpha', 'beta', 'stable');
|
||||||
|
$i = array_search($state, $states);
|
||||||
|
if ($i === false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ($include) {
|
||||||
|
$i--;
|
||||||
|
}
|
||||||
|
return array_slice($states, $i + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
|
@ -0,0 +1,299 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PEAR_REST_13
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: 13.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since Release 1.4.0a12
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For downloading REST xml/txt files
|
||||||
|
*/
|
||||||
|
require_once 'PEAR/REST.php';
|
||||||
|
require_once 'PEAR/REST/10.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implement REST 1.3
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 1.4.0a12
|
||||||
|
*/
|
||||||
|
class PEAR_REST_13 extends PEAR_REST_10
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Retrieve information about a remote package to be downloaded from a REST server
|
||||||
|
*
|
||||||
|
* This is smart enough to resolve the minimum PHP version dependency prior to download
|
||||||
|
* @param string $base The uri to prepend to all REST calls
|
||||||
|
* @param array $packageinfo an array of format:
|
||||||
|
* <pre>
|
||||||
|
* array(
|
||||||
|
* 'package' => 'packagename',
|
||||||
|
* 'channel' => 'channelname',
|
||||||
|
* ['state' => 'alpha' (or valid state),]
|
||||||
|
* -or-
|
||||||
|
* ['version' => '1.whatever']
|
||||||
|
* </pre>
|
||||||
|
* @param string $prefstate Current preferred_state config variable value
|
||||||
|
* @param bool $installed the installed version of this package to compare against
|
||||||
|
* @return array|false|PEAR_Error see {@link _returnDownloadURL()}
|
||||||
|
*/
|
||||||
|
function getDownloadURL($base, $packageinfo, $prefstate, $installed, $channel = false)
|
||||||
|
{
|
||||||
|
$states = $this->betterStates($prefstate, true);
|
||||||
|
if (!$states) {
|
||||||
|
return PEAR::raiseError('"' . $prefstate . '" is not a valid state');
|
||||||
|
}
|
||||||
|
|
||||||
|
$channel = $packageinfo['channel'];
|
||||||
|
$package = $packageinfo['package'];
|
||||||
|
$state = isset($packageinfo['state']) ? $packageinfo['state'] : null;
|
||||||
|
$version = isset($packageinfo['version']) ? $packageinfo['version'] : null;
|
||||||
|
$restFile = $base . 'r/' . strtolower($package) . '/allreleases2.xml';
|
||||||
|
|
||||||
|
$info = $this->_rest->retrieveData($restFile, false, false, $channel);
|
||||||
|
if (PEAR::isError($info)) {
|
||||||
|
return PEAR::raiseError('No releases available for package "' .
|
||||||
|
$channel . '/' . $package . '"');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($info['r'])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$release = $found = false;
|
||||||
|
if (!is_array($info['r']) || !isset($info['r'][0])) {
|
||||||
|
$info['r'] = array($info['r']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$skippedphp = false;
|
||||||
|
foreach ($info['r'] as $release) {
|
||||||
|
if (!isset($this->_rest->_options['force']) && ($installed &&
|
||||||
|
version_compare($release['v'], $installed, '<'))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($state)) {
|
||||||
|
// try our preferred state first
|
||||||
|
if ($release['s'] == $state) {
|
||||||
|
if (!isset($version) && version_compare($release['m'], phpversion(), '>')) {
|
||||||
|
// skip releases that require a PHP version newer than our PHP version
|
||||||
|
$skippedphp = $release;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// see if there is something newer and more stable
|
||||||
|
// bug #7221
|
||||||
|
if (in_array($release['s'], $this->betterStates($state), true)) {
|
||||||
|
if (!isset($version) && version_compare($release['m'], phpversion(), '>')) {
|
||||||
|
// skip releases that require a PHP version newer than our PHP version
|
||||||
|
$skippedphp = $release;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} elseif (isset($version)) {
|
||||||
|
if ($release['v'] == $version) {
|
||||||
|
if (!isset($this->_rest->_options['force']) &&
|
||||||
|
!isset($version) &&
|
||||||
|
version_compare($release['m'], phpversion(), '>')) {
|
||||||
|
// skip releases that require a PHP version newer than our PHP version
|
||||||
|
$skippedphp = $release;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (in_array($release['s'], $states)) {
|
||||||
|
if (version_compare($release['m'], phpversion(), '>')) {
|
||||||
|
// skip releases that require a PHP version newer than our PHP version
|
||||||
|
$skippedphp = $release;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$found && $skippedphp) {
|
||||||
|
$found = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->_returnDownloadURL($base, $package, $release, $info, $found, $skippedphp, $channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDepDownloadURL($base, $xsdversion, $dependency, $deppackage,
|
||||||
|
$prefstate = 'stable', $installed = false, $channel = false)
|
||||||
|
{
|
||||||
|
$states = $this->betterStates($prefstate, true);
|
||||||
|
if (!$states) {
|
||||||
|
return PEAR::raiseError('"' . $prefstate . '" is not a valid state');
|
||||||
|
}
|
||||||
|
|
||||||
|
$channel = $dependency['channel'];
|
||||||
|
$package = $dependency['name'];
|
||||||
|
$state = isset($dependency['state']) ? $dependency['state'] : null;
|
||||||
|
$version = isset($dependency['version']) ? $dependency['version'] : null;
|
||||||
|
$restFile = $base . 'r/' . strtolower($package) .'/allreleases2.xml';
|
||||||
|
|
||||||
|
$info = $this->_rest->retrieveData($restFile, false, false, $channel);
|
||||||
|
if (PEAR::isError($info)) {
|
||||||
|
return PEAR::raiseError('Package "' . $deppackage['channel'] . '/' . $deppackage['package']
|
||||||
|
. '" dependency "' . $channel . '/' . $package . '" has no releases');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($info) || !isset($info['r'])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$exclude = array();
|
||||||
|
$min = $max = $recommended = false;
|
||||||
|
if ($xsdversion == '1.0') {
|
||||||
|
$pinfo['package'] = $dependency['name'];
|
||||||
|
$pinfo['channel'] = 'pear.php.net'; // this is always true - don't change this
|
||||||
|
switch ($dependency['rel']) {
|
||||||
|
case 'ge' :
|
||||||
|
$min = $dependency['version'];
|
||||||
|
break;
|
||||||
|
case 'gt' :
|
||||||
|
$min = $dependency['version'];
|
||||||
|
$exclude = array($dependency['version']);
|
||||||
|
break;
|
||||||
|
case 'eq' :
|
||||||
|
$recommended = $dependency['version'];
|
||||||
|
break;
|
||||||
|
case 'lt' :
|
||||||
|
$max = $dependency['version'];
|
||||||
|
$exclude = array($dependency['version']);
|
||||||
|
break;
|
||||||
|
case 'le' :
|
||||||
|
$max = $dependency['version'];
|
||||||
|
break;
|
||||||
|
case 'ne' :
|
||||||
|
$exclude = array($dependency['version']);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$pinfo['package'] = $dependency['name'];
|
||||||
|
$min = isset($dependency['min']) ? $dependency['min'] : false;
|
||||||
|
$max = isset($dependency['max']) ? $dependency['max'] : false;
|
||||||
|
$recommended = isset($dependency['recommended']) ?
|
||||||
|
$dependency['recommended'] : false;
|
||||||
|
if (isset($dependency['exclude'])) {
|
||||||
|
if (!isset($dependency['exclude'][0])) {
|
||||||
|
$exclude = array($dependency['exclude']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$skippedphp = $found = $release = false;
|
||||||
|
if (!is_array($info['r']) || !isset($info['r'][0])) {
|
||||||
|
$info['r'] = array($info['r']);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($info['r'] as $release) {
|
||||||
|
if (!isset($this->_rest->_options['force']) && ($installed &&
|
||||||
|
version_compare($release['v'], $installed, '<'))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array($release['v'], $exclude)) { // skip excluded versions
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// allow newer releases to say "I'm OK with the dependent package"
|
||||||
|
if ($xsdversion == '2.0' && isset($release['co'])) {
|
||||||
|
if (!is_array($release['co']) || !isset($release['co'][0])) {
|
||||||
|
$release['co'] = array($release['co']);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($release['co'] as $entry) {
|
||||||
|
if (isset($entry['x']) && !is_array($entry['x'])) {
|
||||||
|
$entry['x'] = array($entry['x']);
|
||||||
|
} elseif (!isset($entry['x'])) {
|
||||||
|
$entry['x'] = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($entry['c'] == $deppackage['channel'] &&
|
||||||
|
strtolower($entry['p']) == strtolower($deppackage['package']) &&
|
||||||
|
version_compare($deppackage['version'], $entry['min'], '>=') &&
|
||||||
|
version_compare($deppackage['version'], $entry['max'], '<=') &&
|
||||||
|
!in_array($release['v'], $entry['x'])) {
|
||||||
|
if (version_compare($release['m'], phpversion(), '>')) {
|
||||||
|
// skip dependency releases that require a PHP version
|
||||||
|
// newer than our PHP version
|
||||||
|
$skippedphp = $release;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$recommended = $release['v'];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($recommended) {
|
||||||
|
if ($release['v'] != $recommended) { // if we want a specific
|
||||||
|
// version, then skip all others
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in_array($release['s'], $states)) {
|
||||||
|
// the stability is too low, but we must return the
|
||||||
|
// recommended version if possible
|
||||||
|
return $this->_returnDownloadURL($base, $package, $release, $info, true, false, $channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($min && version_compare($release['v'], $min, 'lt')) { // skip too old versions
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($max && version_compare($release['v'], $max, 'gt')) { // skip too new versions
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($installed && version_compare($release['v'], $installed, '<')) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array($release['s'], $states)) { // if in the preferred state...
|
||||||
|
if (version_compare($release['m'], phpversion(), '>')) {
|
||||||
|
// skip dependency releases that require a PHP version
|
||||||
|
// newer than our PHP version
|
||||||
|
$skippedphp = $release;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$found = true; // ... then use it
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$found && $skippedphp) {
|
||||||
|
$found = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->_returnDownloadURL($base, $package, $release, $info, $found, $skippedphp, $channel);
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,202 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PEAR_Task_Common, base class for installer tasks
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: Common.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
/**#@+
|
||||||
|
* Error codes for task validation routines
|
||||||
|
*/
|
||||||
|
define('PEAR_TASK_ERROR_NOATTRIBS', 1);
|
||||||
|
define('PEAR_TASK_ERROR_MISSING_ATTRIB', 2);
|
||||||
|
define('PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE', 3);
|
||||||
|
define('PEAR_TASK_ERROR_INVALID', 4);
|
||||||
|
/**#@-*/
|
||||||
|
define('PEAR_TASK_PACKAGE', 1);
|
||||||
|
define('PEAR_TASK_INSTALL', 2);
|
||||||
|
define('PEAR_TASK_PACKAGEANDINSTALL', 3);
|
||||||
|
/**
|
||||||
|
* A task is an operation that manipulates the contents of a file.
|
||||||
|
*
|
||||||
|
* Simple tasks operate on 1 file. Multiple tasks are executed after all files have been
|
||||||
|
* processed and installed, and are designed to operate on all files containing the task.
|
||||||
|
* The Post-install script task simply takes advantage of the fact that it will be run
|
||||||
|
* after installation, replace is a simple task.
|
||||||
|
*
|
||||||
|
* Combining tasks is possible, but ordering is significant.
|
||||||
|
*
|
||||||
|
* <file name="test.php" role="php">
|
||||||
|
* <tasks:replace from="@data-dir@" to="data_dir" type="pear-config"/>
|
||||||
|
* <tasks:postinstallscript/>
|
||||||
|
* </file>
|
||||||
|
*
|
||||||
|
* This will first replace any instance of @data-dir@ in the test.php file
|
||||||
|
* with the path to the current data directory. Then, it will include the
|
||||||
|
* test.php file and run the script it contains to configure the package post-installation.
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 1.4.0a1
|
||||||
|
* @abstract
|
||||||
|
*/
|
||||||
|
class PEAR_Task_Common
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Valid types for this version are 'simple' and 'multiple'
|
||||||
|
*
|
||||||
|
* - simple tasks operate on the contents of a file and write out changes to disk
|
||||||
|
* - multiple tasks operate on the contents of many files and write out the
|
||||||
|
* changes directly to disk
|
||||||
|
*
|
||||||
|
* Child task classes must override this property.
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
var $type = 'simple';
|
||||||
|
/**
|
||||||
|
* Determines which install phase this task is executed under
|
||||||
|
*/
|
||||||
|
var $phase = PEAR_TASK_INSTALL;
|
||||||
|
/**
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
var $config;
|
||||||
|
/**
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
var $registry;
|
||||||
|
/**
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
var $logger;
|
||||||
|
/**
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
var $installphase;
|
||||||
|
/**
|
||||||
|
* @param PEAR_Config
|
||||||
|
* @param PEAR_Common
|
||||||
|
*/
|
||||||
|
function PEAR_Task_Common(&$config, &$logger, $phase)
|
||||||
|
{
|
||||||
|
$this->config = &$config;
|
||||||
|
$this->registry = &$config->getRegistry();
|
||||||
|
$this->logger = &$logger;
|
||||||
|
$this->installphase = $phase;
|
||||||
|
if ($this->type == 'multiple') {
|
||||||
|
$GLOBALS['_PEAR_TASK_POSTINSTANCES'][get_class($this)][] = &$this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate the basic contents of a task tag.
|
||||||
|
* @param PEAR_PackageFile_v2
|
||||||
|
* @param array
|
||||||
|
* @param PEAR_Config
|
||||||
|
* @param array the entire parsed <file> tag
|
||||||
|
* @return true|array On error, return an array in format:
|
||||||
|
* array(PEAR_TASK_ERROR_???[, param1][, param2][, ...])
|
||||||
|
*
|
||||||
|
* For PEAR_TASK_ERROR_MISSING_ATTRIB, pass the attribute name in
|
||||||
|
* For PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE, pass the attribute name and an array
|
||||||
|
* of legal values in
|
||||||
|
* @static
|
||||||
|
* @abstract
|
||||||
|
*/
|
||||||
|
function validateXml($pkg, $xml, $config, $fileXml)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a task instance with the parameters
|
||||||
|
* @param array raw, parsed xml
|
||||||
|
* @param array attributes from the <file> tag containing this task
|
||||||
|
* @param string|null last installed version of this package
|
||||||
|
* @abstract
|
||||||
|
*/
|
||||||
|
function init($xml, $fileAttributes, $lastVersion)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Begin a task processing session. All multiple tasks will be processed after each file
|
||||||
|
* has been successfully installed, all simple tasks should perform their task here and
|
||||||
|
* return any errors using the custom throwError() method to allow forward compatibility
|
||||||
|
*
|
||||||
|
* This method MUST NOT write out any changes to disk
|
||||||
|
* @param PEAR_PackageFile_v2
|
||||||
|
* @param string file contents
|
||||||
|
* @param string the eventual final file location (informational only)
|
||||||
|
* @return string|false|PEAR_Error false to skip this file, PEAR_Error to fail
|
||||||
|
* (use $this->throwError), otherwise return the new contents
|
||||||
|
* @abstract
|
||||||
|
*/
|
||||||
|
function startSession($pkg, $contents, $dest)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is used to process each of the tasks for a particular multiple class
|
||||||
|
* type. Simple tasks need not implement this method.
|
||||||
|
* @param array an array of tasks
|
||||||
|
* @access protected
|
||||||
|
* @static
|
||||||
|
* @abstract
|
||||||
|
*/
|
||||||
|
function run($tasks)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @static
|
||||||
|
* @final
|
||||||
|
*/
|
||||||
|
function hasPostinstallTasks()
|
||||||
|
{
|
||||||
|
return isset($GLOBALS['_PEAR_TASK_POSTINSTANCES']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @static
|
||||||
|
* @final
|
||||||
|
*/
|
||||||
|
function runPostinstallTasks()
|
||||||
|
{
|
||||||
|
foreach ($GLOBALS['_PEAR_TASK_POSTINSTANCES'] as $class => $tasks) {
|
||||||
|
$err = call_user_func(array($class, 'run'),
|
||||||
|
$GLOBALS['_PEAR_TASK_POSTINSTANCES'][$class]);
|
||||||
|
if ($err) {
|
||||||
|
return PEAR_Task_Common::throwError($err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unset($GLOBALS['_PEAR_TASK_POSTINSTANCES']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines whether a role is a script
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
function isScript()
|
||||||
|
{
|
||||||
|
return $this->type == 'script';
|
||||||
|
}
|
||||||
|
|
||||||
|
function throwError($msg, $code = -1)
|
||||||
|
{
|
||||||
|
include_once 'PEAR.php';
|
||||||
|
return PEAR::raiseError($msg, $code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
|
@ -0,0 +1,323 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* <tasks:postinstallscript>
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: Postinstallscript.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Base class
|
||||||
|
*/
|
||||||
|
require_once 'PEAR/Task/Common.php';
|
||||||
|
/**
|
||||||
|
* Implements the postinstallscript file task.
|
||||||
|
*
|
||||||
|
* Note that post-install scripts are handled separately from installation, by the
|
||||||
|
* "pear run-scripts" command
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
class PEAR_Task_Postinstallscript extends PEAR_Task_Common
|
||||||
|
{
|
||||||
|
var $type = 'script';
|
||||||
|
var $_class;
|
||||||
|
var $_params;
|
||||||
|
var $_obj;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @var PEAR_PackageFile_v2
|
||||||
|
*/
|
||||||
|
var $_pkg;
|
||||||
|
var $_contents;
|
||||||
|
var $phase = PEAR_TASK_INSTALL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate the raw xml at parsing-time.
|
||||||
|
*
|
||||||
|
* This also attempts to validate the script to make sure it meets the criteria
|
||||||
|
* for a post-install script
|
||||||
|
* @param PEAR_PackageFile_v2
|
||||||
|
* @param array The XML contents of the <postinstallscript> tag
|
||||||
|
* @param PEAR_Config
|
||||||
|
* @param array the entire parsed <file> tag
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
function validateXml($pkg, $xml, $config, $fileXml)
|
||||||
|
{
|
||||||
|
if ($fileXml['role'] != 'php') {
|
||||||
|
return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
|
||||||
|
$fileXml['name'] . '" must be role="php"');
|
||||||
|
}
|
||||||
|
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
|
||||||
|
$file = $pkg->getFileContents($fileXml['name']);
|
||||||
|
if (PEAR::isError($file)) {
|
||||||
|
PEAR::popErrorHandling();
|
||||||
|
return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
|
||||||
|
$fileXml['name'] . '" is not valid: ' .
|
||||||
|
$file->getMessage());
|
||||||
|
} elseif ($file === null) {
|
||||||
|
return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
|
||||||
|
$fileXml['name'] . '" could not be retrieved for processing!');
|
||||||
|
} else {
|
||||||
|
$analysis = $pkg->analyzeSourceCode($file, true);
|
||||||
|
if (!$analysis) {
|
||||||
|
PEAR::popErrorHandling();
|
||||||
|
$warnings = '';
|
||||||
|
foreach ($pkg->getValidationWarnings() as $warn) {
|
||||||
|
$warnings .= $warn['message'] . "\n";
|
||||||
|
}
|
||||||
|
return array(PEAR_TASK_ERROR_INVALID, 'Analysis of post-install script "' .
|
||||||
|
$fileXml['name'] . '" failed: ' . $warnings);
|
||||||
|
}
|
||||||
|
if (count($analysis['declared_classes']) != 1) {
|
||||||
|
PEAR::popErrorHandling();
|
||||||
|
return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
|
||||||
|
$fileXml['name'] . '" must declare exactly 1 class');
|
||||||
|
}
|
||||||
|
$class = $analysis['declared_classes'][0];
|
||||||
|
if ($class != str_replace(array('/', '.php'), array('_', ''),
|
||||||
|
$fileXml['name']) . '_postinstall') {
|
||||||
|
PEAR::popErrorHandling();
|
||||||
|
return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
|
||||||
|
$fileXml['name'] . '" class "' . $class . '" must be named "' .
|
||||||
|
str_replace(array('/', '.php'), array('_', ''),
|
||||||
|
$fileXml['name']) . '_postinstall"');
|
||||||
|
}
|
||||||
|
if (!isset($analysis['declared_methods'][$class])) {
|
||||||
|
PEAR::popErrorHandling();
|
||||||
|
return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
|
||||||
|
$fileXml['name'] . '" must declare methods init() and run()');
|
||||||
|
}
|
||||||
|
$methods = array('init' => 0, 'run' => 1);
|
||||||
|
foreach ($analysis['declared_methods'][$class] as $method) {
|
||||||
|
if (isset($methods[$method])) {
|
||||||
|
unset($methods[$method]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (count($methods)) {
|
||||||
|
PEAR::popErrorHandling();
|
||||||
|
return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
|
||||||
|
$fileXml['name'] . '" must declare methods init() and run()');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PEAR::popErrorHandling();
|
||||||
|
$definedparams = array();
|
||||||
|
$tasksNamespace = $pkg->getTasksNs() . ':';
|
||||||
|
if (!isset($xml[$tasksNamespace . 'paramgroup']) && isset($xml['paramgroup'])) {
|
||||||
|
// in order to support the older betas, which did not expect internal tags
|
||||||
|
// to also use the namespace
|
||||||
|
$tasksNamespace = '';
|
||||||
|
}
|
||||||
|
if (isset($xml[$tasksNamespace . 'paramgroup'])) {
|
||||||
|
$params = $xml[$tasksNamespace . 'paramgroup'];
|
||||||
|
if (!is_array($params) || !isset($params[0])) {
|
||||||
|
$params = array($params);
|
||||||
|
}
|
||||||
|
foreach ($params as $param) {
|
||||||
|
if (!isset($param[$tasksNamespace . 'id'])) {
|
||||||
|
return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
|
||||||
|
$fileXml['name'] . '" <paramgroup> must have ' .
|
||||||
|
'an ' . $tasksNamespace . 'id> tag');
|
||||||
|
}
|
||||||
|
if (isset($param[$tasksNamespace . 'name'])) {
|
||||||
|
if (!in_array($param[$tasksNamespace . 'name'], $definedparams)) {
|
||||||
|
return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
|
||||||
|
$fileXml['name'] . '" ' . $tasksNamespace .
|
||||||
|
'paramgroup> id "' . $param[$tasksNamespace . 'id'] .
|
||||||
|
'" parameter "' . $param[$tasksNamespace . 'name'] .
|
||||||
|
'" has not been previously defined');
|
||||||
|
}
|
||||||
|
if (!isset($param[$tasksNamespace . 'conditiontype'])) {
|
||||||
|
return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
|
||||||
|
$fileXml['name'] . '" ' . $tasksNamespace .
|
||||||
|
'paramgroup> id "' . $param[$tasksNamespace . 'id'] .
|
||||||
|
'" must have a ' . $tasksNamespace .
|
||||||
|
'conditiontype> tag containing either "=", ' .
|
||||||
|
'"!=", or "preg_match"');
|
||||||
|
}
|
||||||
|
if (!in_array($param[$tasksNamespace . 'conditiontype'],
|
||||||
|
array('=', '!=', 'preg_match'))) {
|
||||||
|
return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
|
||||||
|
$fileXml['name'] . '" ' . $tasksNamespace .
|
||||||
|
'paramgroup> id "' . $param[$tasksNamespace . 'id'] .
|
||||||
|
'" must have a ' . $tasksNamespace .
|
||||||
|
'conditiontype> tag containing either "=", ' .
|
||||||
|
'"!=", or "preg_match"');
|
||||||
|
}
|
||||||
|
if (!isset($param[$tasksNamespace . 'value'])) {
|
||||||
|
return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
|
||||||
|
$fileXml['name'] . '" ' . $tasksNamespace .
|
||||||
|
'paramgroup> id "' . $param[$tasksNamespace . 'id'] .
|
||||||
|
'" must have a ' . $tasksNamespace .
|
||||||
|
'value> tag containing expected parameter value');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isset($param[$tasksNamespace . 'instructions'])) {
|
||||||
|
if (!is_string($param[$tasksNamespace . 'instructions'])) {
|
||||||
|
return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
|
||||||
|
$fileXml['name'] . '" ' . $tasksNamespace .
|
||||||
|
'paramgroup> id "' . $param[$tasksNamespace . 'id'] .
|
||||||
|
'" ' . $tasksNamespace . 'instructions> must be simple text');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isset($param[$tasksNamespace . 'param'])) {
|
||||||
|
continue; // <param> is no longer required
|
||||||
|
}
|
||||||
|
$subparams = $param[$tasksNamespace . 'param'];
|
||||||
|
if (!is_array($subparams) || !isset($subparams[0])) {
|
||||||
|
$subparams = array($subparams);
|
||||||
|
}
|
||||||
|
foreach ($subparams as $subparam) {
|
||||||
|
if (!isset($subparam[$tasksNamespace . 'name'])) {
|
||||||
|
return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
|
||||||
|
$fileXml['name'] . '" parameter for ' .
|
||||||
|
$tasksNamespace . 'paramgroup> id "' .
|
||||||
|
$param[$tasksNamespace . 'id'] . '" must have ' .
|
||||||
|
'a ' . $tasksNamespace . 'name> tag');
|
||||||
|
}
|
||||||
|
if (!preg_match('/[a-zA-Z0-9]+/',
|
||||||
|
$subparam[$tasksNamespace . 'name'])) {
|
||||||
|
return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
|
||||||
|
$fileXml['name'] . '" parameter "' .
|
||||||
|
$subparam[$tasksNamespace . 'name'] .
|
||||||
|
'" for ' . $tasksNamespace . 'paramgroup> id "' .
|
||||||
|
$param[$tasksNamespace . 'id'] .
|
||||||
|
'" is not a valid name. Must contain only alphanumeric characters');
|
||||||
|
}
|
||||||
|
if (!isset($subparam[$tasksNamespace . 'prompt'])) {
|
||||||
|
return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
|
||||||
|
$fileXml['name'] . '" parameter "' .
|
||||||
|
$subparam[$tasksNamespace . 'name'] .
|
||||||
|
'" for ' . $tasksNamespace . 'paramgroup> id "' .
|
||||||
|
$param[$tasksNamespace . 'id'] .
|
||||||
|
'" must have a ' . $tasksNamespace . 'prompt> tag');
|
||||||
|
}
|
||||||
|
if (!isset($subparam[$tasksNamespace . 'type'])) {
|
||||||
|
return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' .
|
||||||
|
$fileXml['name'] . '" parameter "' .
|
||||||
|
$subparam[$tasksNamespace . 'name'] .
|
||||||
|
'" for ' . $tasksNamespace . 'paramgroup> id "' .
|
||||||
|
$param[$tasksNamespace . 'id'] .
|
||||||
|
'" must have a ' . $tasksNamespace . 'type> tag');
|
||||||
|
}
|
||||||
|
$definedparams[] = $param[$tasksNamespace . 'id'] . '::' .
|
||||||
|
$subparam[$tasksNamespace . 'name'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a task instance with the parameters
|
||||||
|
* @param array raw, parsed xml
|
||||||
|
* @param array attributes from the <file> tag containing this task
|
||||||
|
* @param string|null last installed version of this package, if any (useful for upgrades)
|
||||||
|
*/
|
||||||
|
function init($xml, $fileattribs, $lastversion)
|
||||||
|
{
|
||||||
|
$this->_class = str_replace('/', '_', $fileattribs['name']);
|
||||||
|
$this->_filename = $fileattribs['name'];
|
||||||
|
$this->_class = str_replace ('.php', '', $this->_class) . '_postinstall';
|
||||||
|
$this->_params = $xml;
|
||||||
|
$this->_lastversion = $lastversion;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strip the tasks: namespace from internal params
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _stripNamespace($params = null)
|
||||||
|
{
|
||||||
|
if ($params === null) {
|
||||||
|
$params = array();
|
||||||
|
if (!is_array($this->_params)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
foreach ($this->_params as $i => $param) {
|
||||||
|
if (is_array($param)) {
|
||||||
|
$param = $this->_stripNamespace($param);
|
||||||
|
}
|
||||||
|
$params[str_replace($this->_pkg->getTasksNs() . ':', '', $i)] = $param;
|
||||||
|
}
|
||||||
|
$this->_params = $params;
|
||||||
|
} else {
|
||||||
|
$newparams = array();
|
||||||
|
foreach ($params as $i => $param) {
|
||||||
|
if (is_array($param)) {
|
||||||
|
$param = $this->_stripNamespace($param);
|
||||||
|
}
|
||||||
|
$newparams[str_replace($this->_pkg->getTasksNs() . ':', '', $i)] = $param;
|
||||||
|
}
|
||||||
|
return $newparams;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlike other tasks, the installed file name is passed in instead of the file contents,
|
||||||
|
* because this task is handled post-installation
|
||||||
|
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
|
||||||
|
* @param string file name
|
||||||
|
* @return bool|PEAR_Error false to skip this file, PEAR_Error to fail
|
||||||
|
* (use $this->throwError)
|
||||||
|
*/
|
||||||
|
function startSession($pkg, $contents)
|
||||||
|
{
|
||||||
|
if ($this->installphase != PEAR_TASK_INSTALL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// remove the tasks: namespace if present
|
||||||
|
$this->_pkg = $pkg;
|
||||||
|
$this->_stripNamespace();
|
||||||
|
$this->logger->log(0, 'Including external post-installation script "' .
|
||||||
|
$contents . '" - any errors are in this script');
|
||||||
|
include_once $contents;
|
||||||
|
if (class_exists($this->_class)) {
|
||||||
|
$this->logger->log(0, 'Inclusion succeeded');
|
||||||
|
} else {
|
||||||
|
return $this->throwError('init of post-install script class "' . $this->_class
|
||||||
|
. '" failed');
|
||||||
|
}
|
||||||
|
$this->_obj = new $this->_class;
|
||||||
|
$this->logger->log(1, 'running post-install script "' . $this->_class . '->init()"');
|
||||||
|
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
|
||||||
|
$res = $this->_obj->init($this->config, $pkg, $this->_lastversion);
|
||||||
|
PEAR::popErrorHandling();
|
||||||
|
if ($res) {
|
||||||
|
$this->logger->log(0, 'init succeeded');
|
||||||
|
} else {
|
||||||
|
return $this->throwError('init of post-install script "' . $this->_class .
|
||||||
|
'->init()" failed');
|
||||||
|
}
|
||||||
|
$this->_contents = $contents;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No longer used
|
||||||
|
* @see PEAR_PackageFile_v2::runPostinstallScripts()
|
||||||
|
* @param array an array of tasks
|
||||||
|
* @param string install or upgrade
|
||||||
|
* @access protected
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
function run()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
|
@ -0,0 +1,169 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* <tasks:postinstallscript> - read/write version
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: rw.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since Release 1.4.0a10
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Base class
|
||||||
|
*/
|
||||||
|
require_once 'PEAR/Task/Postinstallscript.php';
|
||||||
|
/**
|
||||||
|
* Abstracts the postinstallscript file task xml.
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 1.4.0a10
|
||||||
|
*/
|
||||||
|
class PEAR_Task_Postinstallscript_rw extends PEAR_Task_Postinstallscript
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* parent package file object
|
||||||
|
*
|
||||||
|
* @var PEAR_PackageFile_v2_rw
|
||||||
|
*/
|
||||||
|
var $_pkg;
|
||||||
|
/**
|
||||||
|
* Enter description here...
|
||||||
|
*
|
||||||
|
* @param PEAR_PackageFile_v2_rw $pkg
|
||||||
|
* @param PEAR_Config $config
|
||||||
|
* @param PEAR_Frontend $logger
|
||||||
|
* @param array $fileXml
|
||||||
|
* @return PEAR_Task_Postinstallscript_rw
|
||||||
|
*/
|
||||||
|
function PEAR_Task_Postinstallscript_rw(&$pkg, &$config, &$logger, $fileXml)
|
||||||
|
{
|
||||||
|
parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE);
|
||||||
|
$this->_contents = $fileXml;
|
||||||
|
$this->_pkg = &$pkg;
|
||||||
|
$this->_params = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
function validate()
|
||||||
|
{
|
||||||
|
return $this->validateXml($this->_pkg, $this->_params, $this->config, $this->_contents);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getName()
|
||||||
|
{
|
||||||
|
return 'postinstallscript';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add a simple <paramgroup> to the post-install script
|
||||||
|
*
|
||||||
|
* Order is significant, so call this method in the same
|
||||||
|
* sequence the users should see the paramgroups. The $params
|
||||||
|
* parameter should either be the result of a call to {@link getParam()}
|
||||||
|
* or an array of calls to getParam().
|
||||||
|
*
|
||||||
|
* Use {@link addConditionTypeGroup()} to add a <paramgroup> containing
|
||||||
|
* a <conditiontype> tag
|
||||||
|
* @param string $id <paramgroup> id as seen by the script
|
||||||
|
* @param array|false $params array of getParam() calls, or false for no params
|
||||||
|
* @param string|false $instructions
|
||||||
|
*/
|
||||||
|
function addParamGroup($id, $params = false, $instructions = false)
|
||||||
|
{
|
||||||
|
if ($params && isset($params[0]) && !isset($params[1])) {
|
||||||
|
$params = $params[0];
|
||||||
|
}
|
||||||
|
$stuff =
|
||||||
|
array(
|
||||||
|
$this->_pkg->getTasksNs() . ':id' => $id,
|
||||||
|
);
|
||||||
|
if ($instructions) {
|
||||||
|
$stuff[$this->_pkg->getTasksNs() . ':instructions'] = $instructions;
|
||||||
|
}
|
||||||
|
if ($params) {
|
||||||
|
$stuff[$this->_pkg->getTasksNs() . ':param'] = $params;
|
||||||
|
}
|
||||||
|
$this->_params[$this->_pkg->getTasksNs() . ':paramgroup'][] = $stuff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add a complex <paramgroup> to the post-install script with conditions
|
||||||
|
*
|
||||||
|
* This inserts a <paramgroup> with
|
||||||
|
*
|
||||||
|
* Order is significant, so call this method in the same
|
||||||
|
* sequence the users should see the paramgroups. The $params
|
||||||
|
* parameter should either be the result of a call to {@link getParam()}
|
||||||
|
* or an array of calls to getParam().
|
||||||
|
*
|
||||||
|
* Use {@link addParamGroup()} to add a simple <paramgroup>
|
||||||
|
*
|
||||||
|
* @param string $id <paramgroup> id as seen by the script
|
||||||
|
* @param string $oldgroup <paramgroup> id of the section referenced by
|
||||||
|
* <conditiontype>
|
||||||
|
* @param string $param name of the <param> from the older section referenced
|
||||||
|
* by <contitiontype>
|
||||||
|
* @param string $value value to match of the parameter
|
||||||
|
* @param string $conditiontype one of '=', '!=', 'preg_match'
|
||||||
|
* @param array|false $params array of getParam() calls, or false for no params
|
||||||
|
* @param string|false $instructions
|
||||||
|
*/
|
||||||
|
function addConditionTypeGroup($id, $oldgroup, $param, $value, $conditiontype = '=',
|
||||||
|
$params = false, $instructions = false)
|
||||||
|
{
|
||||||
|
if ($params && isset($params[0]) && !isset($params[1])) {
|
||||||
|
$params = $params[0];
|
||||||
|
}
|
||||||
|
$stuff = array(
|
||||||
|
$this->_pkg->getTasksNs() . ':id' => $id,
|
||||||
|
);
|
||||||
|
if ($instructions) {
|
||||||
|
$stuff[$this->_pkg->getTasksNs() . ':instructions'] = $instructions;
|
||||||
|
}
|
||||||
|
$stuff[$this->_pkg->getTasksNs() . ':name'] = $oldgroup . '::' . $param;
|
||||||
|
$stuff[$this->_pkg->getTasksNs() . ':conditiontype'] = $conditiontype;
|
||||||
|
$stuff[$this->_pkg->getTasksNs() . ':value'] = $value;
|
||||||
|
if ($params) {
|
||||||
|
$stuff[$this->_pkg->getTasksNs() . ':param'] = $params;
|
||||||
|
}
|
||||||
|
$this->_params[$this->_pkg->getTasksNs() . ':paramgroup'][] = $stuff;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getXml()
|
||||||
|
{
|
||||||
|
return $this->_params;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use to set up a param tag for use in creating a paramgroup
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
function getParam($name, $prompt, $type = 'string', $default = null)
|
||||||
|
{
|
||||||
|
if ($default !== null) {
|
||||||
|
return
|
||||||
|
array(
|
||||||
|
$this->_pkg->getTasksNs() . ':name' => $name,
|
||||||
|
$this->_pkg->getTasksNs() . ':prompt' => $prompt,
|
||||||
|
$this->_pkg->getTasksNs() . ':type' => $type,
|
||||||
|
$this->_pkg->getTasksNs() . ':default' => $default
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return
|
||||||
|
array(
|
||||||
|
$this->_pkg->getTasksNs() . ':name' => $name,
|
||||||
|
$this->_pkg->getTasksNs() . ':prompt' => $prompt,
|
||||||
|
$this->_pkg->getTasksNs() . ':type' => $type,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
|
@ -0,0 +1,176 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* <tasks:replace>
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: Replace.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Base class
|
||||||
|
*/
|
||||||
|
require_once 'PEAR/Task/Common.php';
|
||||||
|
/**
|
||||||
|
* Implements the replace file task.
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
class PEAR_Task_Replace extends PEAR_Task_Common
|
||||||
|
{
|
||||||
|
var $type = 'simple';
|
||||||
|
var $phase = PEAR_TASK_PACKAGEANDINSTALL;
|
||||||
|
var $_replacements;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate the raw xml at parsing-time.
|
||||||
|
* @param PEAR_PackageFile_v2
|
||||||
|
* @param array raw, parsed xml
|
||||||
|
* @param PEAR_Config
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
function validateXml($pkg, $xml, $config, $fileXml)
|
||||||
|
{
|
||||||
|
if (!isset($xml['attribs'])) {
|
||||||
|
return array(PEAR_TASK_ERROR_NOATTRIBS);
|
||||||
|
}
|
||||||
|
if (!isset($xml['attribs']['type'])) {
|
||||||
|
return array(PEAR_TASK_ERROR_MISSING_ATTRIB, 'type');
|
||||||
|
}
|
||||||
|
if (!isset($xml['attribs']['to'])) {
|
||||||
|
return array(PEAR_TASK_ERROR_MISSING_ATTRIB, 'to');
|
||||||
|
}
|
||||||
|
if (!isset($xml['attribs']['from'])) {
|
||||||
|
return array(PEAR_TASK_ERROR_MISSING_ATTRIB, 'from');
|
||||||
|
}
|
||||||
|
if ($xml['attribs']['type'] == 'pear-config') {
|
||||||
|
if (!in_array($xml['attribs']['to'], $config->getKeys())) {
|
||||||
|
return array(PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE, 'to', $xml['attribs']['to'],
|
||||||
|
$config->getKeys());
|
||||||
|
}
|
||||||
|
} elseif ($xml['attribs']['type'] == 'php-const') {
|
||||||
|
if (defined($xml['attribs']['to'])) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return array(PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE, 'to', $xml['attribs']['to'],
|
||||||
|
array('valid PHP constant'));
|
||||||
|
}
|
||||||
|
} elseif ($xml['attribs']['type'] == 'package-info') {
|
||||||
|
if (in_array($xml['attribs']['to'],
|
||||||
|
array('name', 'summary', 'channel', 'notes', 'extends', 'description',
|
||||||
|
'release_notes', 'license', 'release-license', 'license-uri',
|
||||||
|
'version', 'api-version', 'state', 'api-state', 'release_date',
|
||||||
|
'date', 'time'))) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return array(PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE, 'to', $xml['attribs']['to'],
|
||||||
|
array('name', 'summary', 'channel', 'notes', 'extends', 'description',
|
||||||
|
'release_notes', 'license', 'release-license', 'license-uri',
|
||||||
|
'version', 'api-version', 'state', 'api-state', 'release_date',
|
||||||
|
'date', 'time'));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return array(PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE, 'type', $xml['attribs']['type'],
|
||||||
|
array('pear-config', 'package-info', 'php-const'));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a task instance with the parameters
|
||||||
|
* @param array raw, parsed xml
|
||||||
|
* @param unused
|
||||||
|
*/
|
||||||
|
function init($xml, $attribs)
|
||||||
|
{
|
||||||
|
$this->_replacements = isset($xml['attribs']) ? array($xml) : $xml;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do a package.xml 1.0 replacement, with additional package-info fields available
|
||||||
|
*
|
||||||
|
* See validateXml() source for the complete list of allowed fields
|
||||||
|
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
|
||||||
|
* @param string file contents
|
||||||
|
* @param string the eventual final file location (informational only)
|
||||||
|
* @return string|false|PEAR_Error false to skip this file, PEAR_Error to fail
|
||||||
|
* (use $this->throwError), otherwise return the new contents
|
||||||
|
*/
|
||||||
|
function startSession($pkg, $contents, $dest)
|
||||||
|
{
|
||||||
|
$subst_from = $subst_to = array();
|
||||||
|
foreach ($this->_replacements as $a) {
|
||||||
|
$a = $a['attribs'];
|
||||||
|
$to = '';
|
||||||
|
if ($a['type'] == 'pear-config') {
|
||||||
|
if ($this->installphase == PEAR_TASK_PACKAGE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ($a['to'] == 'master_server') {
|
||||||
|
$chan = $this->registry->getChannel($pkg->getChannel());
|
||||||
|
if (!PEAR::isError($chan)) {
|
||||||
|
$to = $chan->getServer();
|
||||||
|
} else {
|
||||||
|
$this->logger->log(0, "$dest: invalid pear-config replacement: $a[to]");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ($this->config->isDefinedLayer('ftp')) {
|
||||||
|
// try the remote config file first
|
||||||
|
$to = $this->config->get($a['to'], 'ftp', $pkg->getChannel());
|
||||||
|
if (is_null($to)) {
|
||||||
|
// then default to local
|
||||||
|
$to = $this->config->get($a['to'], null, $pkg->getChannel());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$to = $this->config->get($a['to'], null, $pkg->getChannel());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (is_null($to)) {
|
||||||
|
$this->logger->log(0, "$dest: invalid pear-config replacement: $a[to]");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} elseif ($a['type'] == 'php-const') {
|
||||||
|
if ($this->installphase == PEAR_TASK_PACKAGE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (defined($a['to'])) {
|
||||||
|
$to = constant($a['to']);
|
||||||
|
} else {
|
||||||
|
$this->logger->log(0, "$dest: invalid php-const replacement: $a[to]");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ($t = $pkg->packageInfo($a['to'])) {
|
||||||
|
$to = $t;
|
||||||
|
} else {
|
||||||
|
$this->logger->log(0, "$dest: invalid package-info replacement: $a[to]");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!is_null($to)) {
|
||||||
|
$subst_from[] = $a['from'];
|
||||||
|
$subst_to[] = $to;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->logger->log(3, "doing " . sizeof($subst_from) .
|
||||||
|
" substitution(s) for $dest");
|
||||||
|
if (sizeof($subst_from)) {
|
||||||
|
$contents = str_replace($subst_from, $subst_to, $contents);
|
||||||
|
}
|
||||||
|
return $contents;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
|
@ -0,0 +1,61 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* <tasks:replace> - read/write version
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: rw.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since Release 1.4.0a10
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Base class
|
||||||
|
*/
|
||||||
|
require_once 'PEAR/Task/Replace.php';
|
||||||
|
/**
|
||||||
|
* Abstracts the replace task xml.
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 1.4.0a10
|
||||||
|
*/
|
||||||
|
class PEAR_Task_Replace_rw extends PEAR_Task_Replace
|
||||||
|
{
|
||||||
|
function PEAR_Task_Replace_rw(&$pkg, &$config, &$logger, $fileXml)
|
||||||
|
{
|
||||||
|
parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE);
|
||||||
|
$this->_contents = $fileXml;
|
||||||
|
$this->_pkg = &$pkg;
|
||||||
|
$this->_params = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
function validate()
|
||||||
|
{
|
||||||
|
return $this->validateXml($this->_pkg, $this->_params, $this->config, $this->_contents);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setInfo($from, $to, $type)
|
||||||
|
{
|
||||||
|
$this->_params = array('attribs' => array('from' => $from, 'to' => $to, 'type' => $type));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getName()
|
||||||
|
{
|
||||||
|
return 'replace';
|
||||||
|
}
|
||||||
|
|
||||||
|
function getXml()
|
||||||
|
{
|
||||||
|
return $this->_params;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
|
@ -0,0 +1,77 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* <tasks:unixeol>
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: Unixeol.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Base class
|
||||||
|
*/
|
||||||
|
require_once 'PEAR/Task/Common.php';
|
||||||
|
/**
|
||||||
|
* Implements the unix line endings file task.
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
class PEAR_Task_Unixeol extends PEAR_Task_Common
|
||||||
|
{
|
||||||
|
var $type = 'simple';
|
||||||
|
var $phase = PEAR_TASK_PACKAGE;
|
||||||
|
var $_replacements;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate the raw xml at parsing-time.
|
||||||
|
* @param PEAR_PackageFile_v2
|
||||||
|
* @param array raw, parsed xml
|
||||||
|
* @param PEAR_Config
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
function validateXml($pkg, $xml, $config, $fileXml)
|
||||||
|
{
|
||||||
|
if ($xml != '') {
|
||||||
|
return array(PEAR_TASK_ERROR_INVALID, 'no attributes allowed');
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a task instance with the parameters
|
||||||
|
* @param array raw, parsed xml
|
||||||
|
* @param unused
|
||||||
|
*/
|
||||||
|
function init($xml, $attribs)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace all line endings with line endings customized for the current OS
|
||||||
|
*
|
||||||
|
* See validateXml() source for the complete list of allowed fields
|
||||||
|
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
|
||||||
|
* @param string file contents
|
||||||
|
* @param string the eventual final file location (informational only)
|
||||||
|
* @return string|false|PEAR_Error false to skip this file, PEAR_Error to fail
|
||||||
|
* (use $this->throwError), otherwise return the new contents
|
||||||
|
*/
|
||||||
|
function startSession($pkg, $contents, $dest)
|
||||||
|
{
|
||||||
|
$this->logger->log(3, "replacing all line endings with \\n in $dest");
|
||||||
|
return preg_replace("/\r\n|\n\r|\r|\n/", "\n", $contents);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
|
@ -0,0 +1,56 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* <tasks:unixeol> - read/write version
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: rw.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since Release 1.4.0a10
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Base class
|
||||||
|
*/
|
||||||
|
require_once 'PEAR/Task/Unixeol.php';
|
||||||
|
/**
|
||||||
|
* Abstracts the unixeol task xml.
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 1.4.0a10
|
||||||
|
*/
|
||||||
|
class PEAR_Task_Unixeol_rw extends PEAR_Task_Unixeol
|
||||||
|
{
|
||||||
|
function PEAR_Task_Unixeol_rw(&$pkg, &$config, &$logger, $fileXml)
|
||||||
|
{
|
||||||
|
parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE);
|
||||||
|
$this->_contents = $fileXml;
|
||||||
|
$this->_pkg = &$pkg;
|
||||||
|
$this->_params = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
function validate()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getName()
|
||||||
|
{
|
||||||
|
return 'unixeol';
|
||||||
|
}
|
||||||
|
|
||||||
|
function getXml()
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
|
@ -0,0 +1,77 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* <tasks:windowseol>
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: Windowseol.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Base class
|
||||||
|
*/
|
||||||
|
require_once 'PEAR/Task/Common.php';
|
||||||
|
/**
|
||||||
|
* Implements the windows line endsings file task.
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
class PEAR_Task_Windowseol extends PEAR_Task_Common
|
||||||
|
{
|
||||||
|
var $type = 'simple';
|
||||||
|
var $phase = PEAR_TASK_PACKAGE;
|
||||||
|
var $_replacements;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate the raw xml at parsing-time.
|
||||||
|
* @param PEAR_PackageFile_v2
|
||||||
|
* @param array raw, parsed xml
|
||||||
|
* @param PEAR_Config
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
function validateXml($pkg, $xml, $config, $fileXml)
|
||||||
|
{
|
||||||
|
if ($xml != '') {
|
||||||
|
return array(PEAR_TASK_ERROR_INVALID, 'no attributes allowed');
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a task instance with the parameters
|
||||||
|
* @param array raw, parsed xml
|
||||||
|
* @param unused
|
||||||
|
*/
|
||||||
|
function init($xml, $attribs)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace all line endings with windows line endings
|
||||||
|
*
|
||||||
|
* See validateXml() source for the complete list of allowed fields
|
||||||
|
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
|
||||||
|
* @param string file contents
|
||||||
|
* @param string the eventual final file location (informational only)
|
||||||
|
* @return string|false|PEAR_Error false to skip this file, PEAR_Error to fail
|
||||||
|
* (use $this->throwError), otherwise return the new contents
|
||||||
|
*/
|
||||||
|
function startSession($pkg, $contents, $dest)
|
||||||
|
{
|
||||||
|
$this->logger->log(3, "replacing all line endings with \\r\\n in $dest");
|
||||||
|
return preg_replace("/\r\n|\n\r|\r|\n/", "\r\n", $contents);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
|
@ -0,0 +1,56 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* <tasks:windowseol> - read/write version
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: rw.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since Release 1.4.0a10
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Base class
|
||||||
|
*/
|
||||||
|
require_once 'PEAR/Task/Windowseol.php';
|
||||||
|
/**
|
||||||
|
* Abstracts the windowseol task xml.
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 1.4.0a10
|
||||||
|
*/
|
||||||
|
class PEAR_Task_Windowseol_rw extends PEAR_Task_Windowseol
|
||||||
|
{
|
||||||
|
function PEAR_Task_Windowseol_rw(&$pkg, &$config, &$logger, $fileXml)
|
||||||
|
{
|
||||||
|
parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE);
|
||||||
|
$this->_contents = $fileXml;
|
||||||
|
$this->_pkg = &$pkg;
|
||||||
|
$this->_params = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
function validate()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getName()
|
||||||
|
{
|
||||||
|
return 'windowseol';
|
||||||
|
}
|
||||||
|
|
||||||
|
function getXml()
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
|
@ -0,0 +1,629 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PEAR_Validate
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: Validate.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
/**#@+
|
||||||
|
* Constants for install stage
|
||||||
|
*/
|
||||||
|
define('PEAR_VALIDATE_INSTALLING', 1);
|
||||||
|
define('PEAR_VALIDATE_UNINSTALLING', 2); // this is not bit-mapped like the others
|
||||||
|
define('PEAR_VALIDATE_NORMAL', 3);
|
||||||
|
define('PEAR_VALIDATE_DOWNLOADING', 4); // this is not bit-mapped like the others
|
||||||
|
define('PEAR_VALIDATE_PACKAGING', 7);
|
||||||
|
/**#@-*/
|
||||||
|
require_once 'PEAR/Common.php';
|
||||||
|
require_once 'PEAR/Validator/PECL.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validation class for package.xml - channel-level advanced validation
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
class PEAR_Validate
|
||||||
|
{
|
||||||
|
var $packageregex = _PEAR_COMMON_PACKAGE_NAME_PREG;
|
||||||
|
/**
|
||||||
|
* @var PEAR_PackageFile_v1|PEAR_PackageFile_v2
|
||||||
|
*/
|
||||||
|
var $_packagexml;
|
||||||
|
/**
|
||||||
|
* @var int one of the PEAR_VALIDATE_* constants
|
||||||
|
*/
|
||||||
|
var $_state = PEAR_VALIDATE_NORMAL;
|
||||||
|
/**
|
||||||
|
* Format: ('error' => array('field' => name, 'reason' => reason), 'warning' => same)
|
||||||
|
* @var array
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $_failures = array('error' => array(), 'warning' => array());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override this method to handle validation of normal package names
|
||||||
|
* @param string
|
||||||
|
* @return bool
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function _validPackageName($name)
|
||||||
|
{
|
||||||
|
return (bool) preg_match('/^' . $this->packageregex . '\\z/', $name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string package name to validate
|
||||||
|
* @param string name of channel-specific validation package
|
||||||
|
* @final
|
||||||
|
*/
|
||||||
|
function validPackageName($name, $validatepackagename = false)
|
||||||
|
{
|
||||||
|
if ($validatepackagename) {
|
||||||
|
if (strtolower($name) == strtolower($validatepackagename)) {
|
||||||
|
return (bool) preg_match('/^[a-zA-Z0-9_]+(?:\.[a-zA-Z0-9_]+)*\\z/', $name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this->_validPackageName($name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This validates a bundle name, and bundle names must conform
|
||||||
|
* to the PEAR naming convention, so the method is final and static.
|
||||||
|
* @param string
|
||||||
|
* @final
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
function validGroupName($name)
|
||||||
|
{
|
||||||
|
return (bool) preg_match('/^' . _PEAR_COMMON_PACKAGE_NAME_PREG . '\\z/', $name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether $state represents a valid stability level
|
||||||
|
* @param string
|
||||||
|
* @return bool
|
||||||
|
* @static
|
||||||
|
* @final
|
||||||
|
*/
|
||||||
|
function validState($state)
|
||||||
|
{
|
||||||
|
return in_array($state, array('snapshot', 'devel', 'alpha', 'beta', 'stable'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of valid stability levels
|
||||||
|
* @return array
|
||||||
|
* @static
|
||||||
|
* @final
|
||||||
|
*/
|
||||||
|
function getValidStates()
|
||||||
|
{
|
||||||
|
return array('snapshot', 'devel', 'alpha', 'beta', 'stable');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether a version is a properly formatted version number that can be used
|
||||||
|
* by version_compare
|
||||||
|
* @param string
|
||||||
|
* @return bool
|
||||||
|
* @static
|
||||||
|
* @final
|
||||||
|
*/
|
||||||
|
function validVersion($ver)
|
||||||
|
{
|
||||||
|
return (bool) preg_match(PEAR_COMMON_PACKAGE_VERSION_PREG, $ver);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
|
||||||
|
*/
|
||||||
|
function setPackageFile(&$pf)
|
||||||
|
{
|
||||||
|
$this->_packagexml = &$pf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _addFailure($field, $reason)
|
||||||
|
{
|
||||||
|
$this->_failures['errors'][] = array('field' => $field, 'reason' => $reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _addWarning($field, $reason)
|
||||||
|
{
|
||||||
|
$this->_failures['warnings'][] = array('field' => $field, 'reason' => $reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getFailures()
|
||||||
|
{
|
||||||
|
$failures = $this->_failures;
|
||||||
|
$this->_failures = array('warnings' => array(), 'errors' => array());
|
||||||
|
return $failures;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int one of the PEAR_VALIDATE_* constants
|
||||||
|
*/
|
||||||
|
function validate($state = null)
|
||||||
|
{
|
||||||
|
if (!isset($this->_packagexml)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ($state !== null) {
|
||||||
|
$this->_state = $state;
|
||||||
|
}
|
||||||
|
$this->_failures = array('warnings' => array(), 'errors' => array());
|
||||||
|
$this->validatePackageName();
|
||||||
|
$this->validateVersion();
|
||||||
|
$this->validateMaintainers();
|
||||||
|
$this->validateDate();
|
||||||
|
$this->validateSummary();
|
||||||
|
$this->validateDescription();
|
||||||
|
$this->validateLicense();
|
||||||
|
$this->validateNotes();
|
||||||
|
if ($this->_packagexml->getPackagexmlVersion() == '1.0') {
|
||||||
|
$this->validateState();
|
||||||
|
$this->validateFilelist();
|
||||||
|
} elseif ($this->_packagexml->getPackagexmlVersion() == '2.0' ||
|
||||||
|
$this->_packagexml->getPackagexmlVersion() == '2.1') {
|
||||||
|
$this->validateTime();
|
||||||
|
$this->validateStability();
|
||||||
|
$this->validateDeps();
|
||||||
|
$this->validateMainFilelist();
|
||||||
|
$this->validateReleaseFilelist();
|
||||||
|
//$this->validateGlobalTasks();
|
||||||
|
$this->validateChangelog();
|
||||||
|
}
|
||||||
|
return !((bool) count($this->_failures['errors']));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function validatePackageName()
|
||||||
|
{
|
||||||
|
if ($this->_state == PEAR_VALIDATE_PACKAGING ||
|
||||||
|
$this->_state == PEAR_VALIDATE_NORMAL) {
|
||||||
|
if (($this->_packagexml->getPackagexmlVersion() == '2.0' ||
|
||||||
|
$this->_packagexml->getPackagexmlVersion() == '2.1') &&
|
||||||
|
$this->_packagexml->getExtends()) {
|
||||||
|
$version = $this->_packagexml->getVersion() . '';
|
||||||
|
$name = $this->_packagexml->getPackage();
|
||||||
|
$test = array_shift($a = explode('.', $version));
|
||||||
|
if ($test == '0') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
$vlen = strlen($test);
|
||||||
|
$majver = substr($name, strlen($name) - $vlen);
|
||||||
|
while ($majver && !is_numeric($majver{0})) {
|
||||||
|
$majver = substr($majver, 1);
|
||||||
|
}
|
||||||
|
if ($majver != $test) {
|
||||||
|
$this->_addWarning('package', "package $name extends package " .
|
||||||
|
$this->_packagexml->getExtends() . ' and so the name should ' .
|
||||||
|
'have a postfix equal to the major version like "' .
|
||||||
|
$this->_packagexml->getExtends() . $test . '"');
|
||||||
|
return true;
|
||||||
|
} elseif (substr($name, 0, strlen($name) - $vlen) !=
|
||||||
|
$this->_packagexml->getExtends()) {
|
||||||
|
$this->_addWarning('package', "package $name extends package " .
|
||||||
|
$this->_packagexml->getExtends() . ' and so the name must ' .
|
||||||
|
'be an extension like "' . $this->_packagexml->getExtends() .
|
||||||
|
$test . '"');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!$this->validPackageName($this->_packagexml->getPackage())) {
|
||||||
|
$this->_addFailure('name', 'package name "' .
|
||||||
|
$this->_packagexml->getPackage() . '" is invalid');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function validateVersion()
|
||||||
|
{
|
||||||
|
if ($this->_state != PEAR_VALIDATE_PACKAGING) {
|
||||||
|
if (!$this->validVersion($this->_packagexml->getVersion())) {
|
||||||
|
$this->_addFailure('version',
|
||||||
|
'Invalid version number "' . $this->_packagexml->getVersion() . '"');
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$version = $this->_packagexml->getVersion();
|
||||||
|
$versioncomponents = explode('.', $version);
|
||||||
|
if (count($versioncomponents) != 3) {
|
||||||
|
$this->_addWarning('version',
|
||||||
|
'A version number should have 3 decimals (x.y.z)');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
$name = $this->_packagexml->getPackage();
|
||||||
|
// version must be based upon state
|
||||||
|
switch ($this->_packagexml->getState()) {
|
||||||
|
case 'snapshot' :
|
||||||
|
return true;
|
||||||
|
case 'devel' :
|
||||||
|
if ($versioncomponents[0] . 'a' == '0a') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ($versioncomponents[0] == 0) {
|
||||||
|
$versioncomponents[0] = '0';
|
||||||
|
$this->_addWarning('version',
|
||||||
|
'version "' . $version . '" should be "' .
|
||||||
|
implode('.' ,$versioncomponents) . '"');
|
||||||
|
} else {
|
||||||
|
$this->_addWarning('version',
|
||||||
|
'packages with devel stability must be < version 1.0.0');
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
case 'alpha' :
|
||||||
|
case 'beta' :
|
||||||
|
// check for a package that extends a package,
|
||||||
|
// like Foo and Foo2
|
||||||
|
if ($this->_state == PEAR_VALIDATE_PACKAGING) {
|
||||||
|
if (substr($versioncomponents[2], 1, 2) == 'rc') {
|
||||||
|
$this->_addFailure('version', 'Release Candidate versions ' .
|
||||||
|
'must have capital RC, not lower-case rc');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!$this->_packagexml->getExtends()) {
|
||||||
|
if ($versioncomponents[0] == '1') {
|
||||||
|
if ($versioncomponents[2]{0} == '0') {
|
||||||
|
if ($versioncomponents[2] == '0') {
|
||||||
|
// version 1.*.0000
|
||||||
|
$this->_addWarning('version',
|
||||||
|
'version 1.' . $versioncomponents[1] .
|
||||||
|
'.0 probably should not be alpha or beta');
|
||||||
|
return true;
|
||||||
|
} elseif (strlen($versioncomponents[2]) > 1) {
|
||||||
|
// version 1.*.0RC1 or 1.*.0beta24 etc.
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
// version 1.*.0
|
||||||
|
$this->_addWarning('version',
|
||||||
|
'version 1.' . $versioncomponents[1] .
|
||||||
|
'.0 probably should not be alpha or beta');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$this->_addWarning('version',
|
||||||
|
'bugfix versions (1.3.x where x > 0) probably should ' .
|
||||||
|
'not be alpha or beta');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} elseif ($versioncomponents[0] != '0') {
|
||||||
|
$this->_addWarning('version',
|
||||||
|
'major versions greater than 1 are not allowed for packages ' .
|
||||||
|
'without an <extends> tag or an identical postfix (foo2 v2.0.0)');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ($versioncomponents[0] . 'a' == '0a') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ($versioncomponents[0] == 0) {
|
||||||
|
$versioncomponents[0] = '0';
|
||||||
|
$this->_addWarning('version',
|
||||||
|
'version "' . $version . '" should be "' .
|
||||||
|
implode('.' ,$versioncomponents) . '"');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$vlen = strlen($versioncomponents[0] . '');
|
||||||
|
$majver = substr($name, strlen($name) - $vlen);
|
||||||
|
while ($majver && !is_numeric($majver{0})) {
|
||||||
|
$majver = substr($majver, 1);
|
||||||
|
}
|
||||||
|
if (($versioncomponents[0] != 0) && $majver != $versioncomponents[0]) {
|
||||||
|
$this->_addWarning('version', 'first version number "' .
|
||||||
|
$versioncomponents[0] . '" must match the postfix of ' .
|
||||||
|
'package name "' . $name . '" (' .
|
||||||
|
$majver . ')');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ($versioncomponents[0] == $majver) {
|
||||||
|
if ($versioncomponents[2]{0} == '0') {
|
||||||
|
if ($versioncomponents[2] == '0') {
|
||||||
|
// version 2.*.0000
|
||||||
|
$this->_addWarning('version',
|
||||||
|
"version $majver." . $versioncomponents[1] .
|
||||||
|
'.0 probably should not be alpha or beta');
|
||||||
|
return false;
|
||||||
|
} elseif (strlen($versioncomponents[2]) > 1) {
|
||||||
|
// version 2.*.0RC1 or 2.*.0beta24 etc.
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
// version 2.*.0
|
||||||
|
$this->_addWarning('version',
|
||||||
|
"version $majver." . $versioncomponents[1] .
|
||||||
|
'.0 cannot be alpha or beta');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$this->_addWarning('version',
|
||||||
|
"bugfix versions ($majver.x.y where y > 0) should " .
|
||||||
|
'not be alpha or beta');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} elseif ($versioncomponents[0] != '0') {
|
||||||
|
$this->_addWarning('version',
|
||||||
|
"only versions 0.x.y and $majver.x.y are allowed for alpha/beta releases");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ($versioncomponents[0] . 'a' == '0a') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ($versioncomponents[0] == 0) {
|
||||||
|
$versioncomponents[0] = '0';
|
||||||
|
$this->_addWarning('version',
|
||||||
|
'version "' . $version . '" should be "' .
|
||||||
|
implode('.' ,$versioncomponents) . '"');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
case 'stable' :
|
||||||
|
if ($versioncomponents[0] == '0') {
|
||||||
|
$this->_addWarning('version', 'versions less than 1.0.0 cannot ' .
|
||||||
|
'be stable');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!is_numeric($versioncomponents[2])) {
|
||||||
|
if (preg_match('/\d+(rc|a|alpha|b|beta)\d*/i',
|
||||||
|
$versioncomponents[2])) {
|
||||||
|
$this->_addWarning('version', 'version "' . $version . '" or any ' .
|
||||||
|
'RC/beta/alpha version cannot be stable');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// check for a package that extends a package,
|
||||||
|
// like Foo and Foo2
|
||||||
|
if ($this->_packagexml->getExtends()) {
|
||||||
|
$vlen = strlen($versioncomponents[0] . '');
|
||||||
|
$majver = substr($name, strlen($name) - $vlen);
|
||||||
|
while ($majver && !is_numeric($majver{0})) {
|
||||||
|
$majver = substr($majver, 1);
|
||||||
|
}
|
||||||
|
if (($versioncomponents[0] != 0) && $majver != $versioncomponents[0]) {
|
||||||
|
$this->_addWarning('version', 'first version number "' .
|
||||||
|
$versioncomponents[0] . '" must match the postfix of ' .
|
||||||
|
'package name "' . $name . '" (' .
|
||||||
|
$majver . ')');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} elseif ($versioncomponents[0] > 1) {
|
||||||
|
$this->_addWarning('version', 'major version x in x.y.z may not be greater than ' .
|
||||||
|
'1 for any package that does not have an <extends> tag');
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function validateMaintainers()
|
||||||
|
{
|
||||||
|
// maintainers can only be truly validated server-side for most channels
|
||||||
|
// but allow this customization for those who wish it
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function validateDate()
|
||||||
|
{
|
||||||
|
if ($this->_state == PEAR_VALIDATE_NORMAL ||
|
||||||
|
$this->_state == PEAR_VALIDATE_PACKAGING) {
|
||||||
|
|
||||||
|
if (!preg_match('/(\d\d\d\d)\-(\d\d)\-(\d\d)/',
|
||||||
|
$this->_packagexml->getDate(), $res) ||
|
||||||
|
count($res) < 4
|
||||||
|
|| !checkdate($res[2], $res[3], $res[1])
|
||||||
|
) {
|
||||||
|
$this->_addFailure('date', 'invalid release date "' .
|
||||||
|
$this->_packagexml->getDate() . '"');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->_state == PEAR_VALIDATE_PACKAGING &&
|
||||||
|
$this->_packagexml->getDate() != date('Y-m-d')) {
|
||||||
|
$this->_addWarning('date', 'Release Date "' .
|
||||||
|
$this->_packagexml->getDate() . '" is not today');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function validateTime()
|
||||||
|
{
|
||||||
|
if (!$this->_packagexml->getTime()) {
|
||||||
|
// default of no time value set
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// packager automatically sets time, so only validate if pear validate is called
|
||||||
|
if ($this->_state = PEAR_VALIDATE_NORMAL) {
|
||||||
|
if (!preg_match('/\d\d:\d\d:\d\d/',
|
||||||
|
$this->_packagexml->getTime())) {
|
||||||
|
$this->_addFailure('time', 'invalid release time "' .
|
||||||
|
$this->_packagexml->getTime() . '"');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = preg_match('|\d{2}\:\d{2}\:\d{2}|', $this->_packagexml->getTime(), $matches);
|
||||||
|
if ($result === false || empty($matches)) {
|
||||||
|
$this->_addFailure('time', 'invalid release time "' .
|
||||||
|
$this->_packagexml->getTime() . '"');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function validateState()
|
||||||
|
{
|
||||||
|
// this is the closest to "final" php4 can get
|
||||||
|
if (!PEAR_Validate::validState($this->_packagexml->getState())) {
|
||||||
|
if (strtolower($this->_packagexml->getState() == 'rc')) {
|
||||||
|
$this->_addFailure('state', 'RC is not a state, it is a version ' .
|
||||||
|
'postfix, use ' . $this->_packagexml->getVersion() . 'RC1, state beta');
|
||||||
|
}
|
||||||
|
$this->_addFailure('state', 'invalid release state "' .
|
||||||
|
$this->_packagexml->getState() . '", must be one of: ' .
|
||||||
|
implode(', ', PEAR_Validate::getValidStates()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function validateStability()
|
||||||
|
{
|
||||||
|
$ret = true;
|
||||||
|
$packagestability = $this->_packagexml->getState();
|
||||||
|
$apistability = $this->_packagexml->getState('api');
|
||||||
|
if (!PEAR_Validate::validState($packagestability)) {
|
||||||
|
$this->_addFailure('state', 'invalid release stability "' .
|
||||||
|
$this->_packagexml->getState() . '", must be one of: ' .
|
||||||
|
implode(', ', PEAR_Validate::getValidStates()));
|
||||||
|
$ret = false;
|
||||||
|
}
|
||||||
|
$apistates = PEAR_Validate::getValidStates();
|
||||||
|
array_shift($apistates); // snapshot is not allowed
|
||||||
|
if (!in_array($apistability, $apistates)) {
|
||||||
|
$this->_addFailure('state', 'invalid API stability "' .
|
||||||
|
$this->_packagexml->getState('api') . '", must be one of: ' .
|
||||||
|
implode(', ', $apistates));
|
||||||
|
$ret = false;
|
||||||
|
}
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function validateSummary()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function validateDescription()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function validateLicense()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function validateNotes()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* for package.xml 2.0 only - channels can't use package.xml 1.0
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function validateDependencies()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* for package.xml 1.0 only
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _validateFilelist()
|
||||||
|
{
|
||||||
|
return true; // placeholder for now
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* for package.xml 2.0 only
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function validateMainFilelist()
|
||||||
|
{
|
||||||
|
return true; // placeholder for now
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* for package.xml 2.0 only
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function validateReleaseFilelist()
|
||||||
|
{
|
||||||
|
return true; // placeholder for now
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function validateChangelog()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function validateFilelist()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
function validateDeps()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Channel Validator for the pecl.php.net channel
|
||||||
|
*
|
||||||
|
* PHP 4 and PHP 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2006 The PHP Group
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version CVS: $Id: PECL.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since Release 1.4.0a5
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* This is the parent class for all validators
|
||||||
|
*/
|
||||||
|
require_once 'PEAR/Validate.php';
|
||||||
|
/**
|
||||||
|
* Channel Validator for the pecl.php.net channel
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 1.4.0a5
|
||||||
|
*/
|
||||||
|
class PEAR_Validator_PECL extends PEAR_Validate
|
||||||
|
{
|
||||||
|
function validateVersion()
|
||||||
|
{
|
||||||
|
if ($this->_state == PEAR_VALIDATE_PACKAGING) {
|
||||||
|
$version = $this->_packagexml->getVersion();
|
||||||
|
$versioncomponents = explode('.', $version);
|
||||||
|
$last = array_pop($versioncomponents);
|
||||||
|
if (substr($last, 1, 2) == 'rc') {
|
||||||
|
$this->_addFailure('version', 'Release Candidate versions must have ' .
|
||||||
|
'upper-case RC, not lower-case rc');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function validatePackageName()
|
||||||
|
{
|
||||||
|
$ret = parent::validatePackageName();
|
||||||
|
if ($this->_packagexml->getPackageType() == 'extsrc' ||
|
||||||
|
$this->_packagexml->getPackageType() == 'zendextsrc') {
|
||||||
|
if (strtolower($this->_packagexml->getPackage()) !=
|
||||||
|
strtolower($this->_packagexml->getProvidesExtension())) {
|
||||||
|
$this->_addWarning('providesextension', 'package name "' .
|
||||||
|
$this->_packagexml->getPackage() . '" is different from extension name "' .
|
||||||
|
$this->_packagexml->getProvidesExtension() . '"');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
|
@ -0,0 +1,253 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PEAR_XMLParser
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @author Stephan Schmidt (original XML_Unserializer code)
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license New BSD License
|
||||||
|
* @version CVS: $Id: XMLParser.php 313023 2011-07-06 19:17:11Z dufuz $
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since File available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parser for any xml file
|
||||||
|
* @category pear
|
||||||
|
* @package PEAR
|
||||||
|
* @author Greg Beaver <cellog@php.net>
|
||||||
|
* @author Stephan Schmidt (original XML_Unserializer code)
|
||||||
|
* @copyright 1997-2009 The Authors
|
||||||
|
* @license http://opensource.org/licenses/bsd-license New BSD License
|
||||||
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 1.4.0a1
|
||||||
|
*/
|
||||||
|
class PEAR_XMLParser
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* unserilialized data
|
||||||
|
* @var string $_serializedData
|
||||||
|
*/
|
||||||
|
var $_unserializedData = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* name of the root tag
|
||||||
|
* @var string $_root
|
||||||
|
*/
|
||||||
|
var $_root = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stack for all data that is found
|
||||||
|
* @var array $_dataStack
|
||||||
|
*/
|
||||||
|
var $_dataStack = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stack for all values that are generated
|
||||||
|
* @var array $_valStack
|
||||||
|
*/
|
||||||
|
var $_valStack = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* current tag depth
|
||||||
|
* @var int $_depth
|
||||||
|
*/
|
||||||
|
var $_depth = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The XML encoding to use
|
||||||
|
* @var string $encoding
|
||||||
|
*/
|
||||||
|
var $encoding = 'ISO-8859-1';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
function getData()
|
||||||
|
{
|
||||||
|
return $this->_unserializedData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string xml content
|
||||||
|
* @return true|PEAR_Error
|
||||||
|
*/
|
||||||
|
function parse($data)
|
||||||
|
{
|
||||||
|
if (!extension_loaded('xml')) {
|
||||||
|
include_once 'PEAR.php';
|
||||||
|
return PEAR::raiseError("XML Extension not found", 1);
|
||||||
|
}
|
||||||
|
$this->_dataStack = $this->_valStack = array();
|
||||||
|
$this->_depth = 0;
|
||||||
|
|
||||||
|
if (
|
||||||
|
strpos($data, 'encoding="UTF-8"')
|
||||||
|
|| strpos($data, 'encoding="utf-8"')
|
||||||
|
|| strpos($data, "encoding='UTF-8'")
|
||||||
|
|| strpos($data, "encoding='utf-8'")
|
||||||
|
) {
|
||||||
|
$this->encoding = 'UTF-8';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (version_compare(phpversion(), '5.0.0', 'lt') && $this->encoding == 'UTF-8') {
|
||||||
|
$data = utf8_decode($data);
|
||||||
|
$this->encoding = 'ISO-8859-1';
|
||||||
|
}
|
||||||
|
|
||||||
|
$xp = xml_parser_create($this->encoding);
|
||||||
|
xml_parser_set_option($xp, XML_OPTION_CASE_FOLDING, 0);
|
||||||
|
xml_set_object($xp, $this);
|
||||||
|
xml_set_element_handler($xp, 'startHandler', 'endHandler');
|
||||||
|
xml_set_character_data_handler($xp, 'cdataHandler');
|
||||||
|
if (!xml_parse($xp, $data)) {
|
||||||
|
$msg = xml_error_string(xml_get_error_code($xp));
|
||||||
|
$line = xml_get_current_line_number($xp);
|
||||||
|
xml_parser_free($xp);
|
||||||
|
include_once 'PEAR.php';
|
||||||
|
return PEAR::raiseError("XML Error: '$msg' on line '$line'", 2);
|
||||||
|
}
|
||||||
|
xml_parser_free($xp);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start element handler for XML parser
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @param object $parser XML parser object
|
||||||
|
* @param string $element XML element
|
||||||
|
* @param array $attribs attributes of XML tag
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function startHandler($parser, $element, $attribs)
|
||||||
|
{
|
||||||
|
$this->_depth++;
|
||||||
|
$this->_dataStack[$this->_depth] = null;
|
||||||
|
|
||||||
|
$val = array(
|
||||||
|
'name' => $element,
|
||||||
|
'value' => null,
|
||||||
|
'type' => 'string',
|
||||||
|
'childrenKeys' => array(),
|
||||||
|
'aggregKeys' => array()
|
||||||
|
);
|
||||||
|
|
||||||
|
if (count($attribs) > 0) {
|
||||||
|
$val['children'] = array();
|
||||||
|
$val['type'] = 'array';
|
||||||
|
$val['children']['attribs'] = $attribs;
|
||||||
|
}
|
||||||
|
|
||||||
|
array_push($this->_valStack, $val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* post-process data
|
||||||
|
*
|
||||||
|
* @param string $data
|
||||||
|
* @param string $element element name
|
||||||
|
*/
|
||||||
|
function postProcess($data, $element)
|
||||||
|
{
|
||||||
|
return trim($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End element handler for XML parser
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @param object XML parser object
|
||||||
|
* @param string
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function endHandler($parser, $element)
|
||||||
|
{
|
||||||
|
$value = array_pop($this->_valStack);
|
||||||
|
$data = $this->postProcess($this->_dataStack[$this->_depth], $element);
|
||||||
|
|
||||||
|
// adjust type of the value
|
||||||
|
switch (strtolower($value['type'])) {
|
||||||
|
// unserialize an array
|
||||||
|
case 'array':
|
||||||
|
if ($data !== '') {
|
||||||
|
$value['children']['_content'] = $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
$value['value'] = isset($value['children']) ? $value['children'] : array();
|
||||||
|
break;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* unserialize a null value
|
||||||
|
*/
|
||||||
|
case 'null':
|
||||||
|
$data = null;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* unserialize any scalar value
|
||||||
|
*/
|
||||||
|
default:
|
||||||
|
settype($data, $value['type']);
|
||||||
|
$value['value'] = $data;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$parent = array_pop($this->_valStack);
|
||||||
|
if ($parent === null) {
|
||||||
|
$this->_unserializedData = &$value['value'];
|
||||||
|
$this->_root = &$value['name'];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// parent has to be an array
|
||||||
|
if (!isset($parent['children']) || !is_array($parent['children'])) {
|
||||||
|
$parent['children'] = array();
|
||||||
|
if ($parent['type'] != 'array') {
|
||||||
|
$parent['type'] = 'array';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($value['name'])) {
|
||||||
|
// there already has been a tag with this name
|
||||||
|
if (in_array($value['name'], $parent['childrenKeys'])) {
|
||||||
|
// no aggregate has been created for this tag
|
||||||
|
if (!in_array($value['name'], $parent['aggregKeys'])) {
|
||||||
|
if (isset($parent['children'][$value['name']])) {
|
||||||
|
$parent['children'][$value['name']] = array($parent['children'][$value['name']]);
|
||||||
|
} else {
|
||||||
|
$parent['children'][$value['name']] = array();
|
||||||
|
}
|
||||||
|
array_push($parent['aggregKeys'], $value['name']);
|
||||||
|
}
|
||||||
|
array_push($parent['children'][$value['name']], $value['value']);
|
||||||
|
} else {
|
||||||
|
$parent['children'][$value['name']] = &$value['value'];
|
||||||
|
array_push($parent['childrenKeys'], $value['name']);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
array_push($parent['children'],$value['value']);
|
||||||
|
}
|
||||||
|
array_push($this->_valStack, $parent);
|
||||||
|
|
||||||
|
$this->_depth--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for character data
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @param object XML parser object
|
||||||
|
* @param string CDATA
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function cdataHandler($parser, $cdata)
|
||||||
|
{
|
||||||
|
$this->_dataStack[$this->_depth] .= $cdata;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This is only meant for PHP 5 to get rid of certain strict warning
|
||||||
|
* that doesn't get hidden since it's in the shutdown function
|
||||||
|
*/
|
||||||
|
class PEAR5
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* If you have a class that's mostly/entirely static, and you need static
|
||||||
|
* properties, you can use this method to simulate them. Eg. in your method(s)
|
||||||
|
* do this: $myVar = &PEAR5::getStaticProperty('myclass', 'myVar');
|
||||||
|
* You MUST use a reference, or they will not persist!
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $class The calling classname, to prevent clashes
|
||||||
|
* @param string $var The variable to retrieve.
|
||||||
|
* @return mixed A reference to the variable. If not set it will be
|
||||||
|
* auto initialised to NULL.
|
||||||
|
*/
|
||||||
|
static function &getStaticProperty($class, $var)
|
||||||
|
{
|
||||||
|
static $properties;
|
||||||
|
if (!isset($properties[$class])) {
|
||||||
|
$properties[$class] = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!array_key_exists($var, $properties[$class])) {
|
||||||
|
$properties[$class][$var] = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $properties[$class][$var];
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,26 +1,24 @@
|
||||||
<?php
|
<?php
|
||||||
//
|
/**
|
||||||
// +----------------------------------------------------------------------+
|
* File/Directory manipulation
|
||||||
// | PHP Version 5 |
|
*
|
||||||
// +----------------------------------------------------------------------+
|
* PHP versions 4 and 5
|
||||||
// | Copyright (c) 1997-2004 The PHP Group |
|
*
|
||||||
// +----------------------------------------------------------------------+
|
* @category pear
|
||||||
// | This source file is subject to version 3.0 of the PHP license, |
|
* @package System
|
||||||
// | that is bundled with this package in the file LICENSE, and is |
|
* @author Tomas V.V.Cox <cox@idecnet.com>
|
||||||
// | available through the world-wide-web at the following url: |
|
* @copyright 1997-2009 The Authors
|
||||||
// | http://www.php.net/license/3_0.txt. |
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
// | If you did not receive a copy of the PHP license and are unable to |
|
* @version CVS: $Id: System.php 313024 2011-07-06 19:51:24Z dufuz $
|
||||||
// | obtain it through the world-wide-web, please send a note to |
|
* @link http://pear.php.net/package/PEAR
|
||||||
// | license@php.net so we can mail you a copy immediately. |
|
* @since File available since Release 0.1
|
||||||
// +----------------------------------------------------------------------+
|
*/
|
||||||
// | Authors: Tomas V.V.Cox <cox@idecnet.com> |
|
|
||||||
// +----------------------------------------------------------------------+
|
|
||||||
//
|
|
||||||
// $Id: System.php,v 1.36 2004/06/15 16:33:46 pajoye Exp $
|
|
||||||
//
|
|
||||||
|
|
||||||
require_once( 'PEAR.php');
|
/**
|
||||||
require_once( 'Console/Getopt.php');
|
* base class
|
||||||
|
*/
|
||||||
|
require_once 'PEAR.php';
|
||||||
|
require_once 'Console/Getopt.php';
|
||||||
|
|
||||||
$GLOBALS['_System_temp_files'] = array();
|
$GLOBALS['_System_temp_files'] = array();
|
||||||
|
|
||||||
|
@ -31,7 +29,9 @@ $GLOBALS['_System_temp_files'] = array();
|
||||||
* Unix and Windows. The names and usage has been taken from its respectively
|
* Unix and Windows. The names and usage has been taken from its respectively
|
||||||
* GNU commands. The functions will return (bool) false on error and will
|
* GNU commands. The functions will return (bool) false on error and will
|
||||||
* trigger the error with the PHP trigger_error() function (you can silence
|
* trigger the error with the PHP trigger_error() function (you can silence
|
||||||
* the error by prefixing a '@' sign after the function call).
|
* the error by prefixing a '@' sign after the function call, but this
|
||||||
|
* is not recommended practice. Instead use an error handler with
|
||||||
|
* {@link set_error_handler()}).
|
||||||
*
|
*
|
||||||
* Documentation on this class you can find in:
|
* Documentation on this class you can find in:
|
||||||
* http://pear.php.net/manual/
|
* http://pear.php.net/manual/
|
||||||
|
@ -46,11 +46,15 @@ $GLOBALS['_System_temp_files'] = array();
|
||||||
*
|
*
|
||||||
* System::rm(array('-r', $file1, $dir1));
|
* System::rm(array('-r', $file1, $dir1));
|
||||||
*
|
*
|
||||||
|
* @category pear
|
||||||
* @package System
|
* @package System
|
||||||
* @author Tomas V.V. Cox <cox@idecnet.com>
|
* @author Tomas V.V. Cox <cox@idecnet.com>
|
||||||
* @version $Revision: 1.36 $
|
* @copyright 1997-2006 The PHP Group
|
||||||
* @access public
|
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||||
* @see http://pear.php.net/manual/
|
* @version Release: 1.9.4
|
||||||
|
* @link http://pear.php.net/package/PEAR
|
||||||
|
* @since Class available since Release 0.1
|
||||||
|
* @static
|
||||||
*/
|
*/
|
||||||
class System
|
class System
|
||||||
{
|
{
|
||||||
|
@ -61,14 +65,23 @@ class System
|
||||||
* @param string $short_options the allowed option short-tags
|
* @param string $short_options the allowed option short-tags
|
||||||
* @param string $long_options the allowed option long-tags
|
* @param string $long_options the allowed option long-tags
|
||||||
* @return array the given options and there values
|
* @return array the given options and there values
|
||||||
|
* @static
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
function _parseArgs($argv, $short_options, $long_options = null)
|
function _parseArgs($argv, $short_options, $long_options = null)
|
||||||
{
|
{
|
||||||
if (!is_array($argv) && $argv !== null) {
|
if (!is_array($argv) && $argv !== null) {
|
||||||
$argv = preg_split('/\s+/', $argv);
|
// Find all items, quoted or otherwise
|
||||||
|
preg_match_all("/(?:[\"'])(.*?)(?:['\"])|([^\s]+)/", $argv, $av);
|
||||||
|
$argv = $av[1];
|
||||||
|
foreach ($av[2] as $k => $a) {
|
||||||
|
if (empty($a)) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
return Console_Getopt::getopt2($argv, $short_options);
|
$argv[$k] = trim($a) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Console_Getopt::getopt2($argv, $short_options, $long_options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -77,6 +90,7 @@ class System
|
||||||
*
|
*
|
||||||
* @param mixed $error a PEAR error or a string with the error message
|
* @param mixed $error a PEAR error or a string with the error message
|
||||||
* @return bool false
|
* @return bool false
|
||||||
|
* @static
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
function raiseError($error)
|
function raiseError($error)
|
||||||
|
@ -108,37 +122,43 @@ class System
|
||||||
* @param string $sPath Name of the directory
|
* @param string $sPath Name of the directory
|
||||||
* @param integer $maxinst max. deep of the lookup
|
* @param integer $maxinst max. deep of the lookup
|
||||||
* @param integer $aktinst starting deep of the lookup
|
* @param integer $aktinst starting deep of the lookup
|
||||||
|
* @param bool $silent if true, do not emit errors.
|
||||||
* @return array the structure of the dir
|
* @return array the structure of the dir
|
||||||
|
* @static
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
|
function _dirToStruct($sPath, $maxinst, $aktinst = 0, $silent = false)
|
||||||
function _dirToStruct($sPath, $maxinst, $aktinst = 0)
|
|
||||||
{
|
{
|
||||||
$struct = array('dirs' => array(), 'files' => array());
|
$struct = array('dirs' => array(), 'files' => array());
|
||||||
if (($dir = @opendir($sPath)) === false) {
|
if (($dir = @opendir($sPath)) === false) {
|
||||||
|
if (!$silent) {
|
||||||
System::raiseError("Could not open dir $sPath");
|
System::raiseError("Could not open dir $sPath");
|
||||||
|
}
|
||||||
return $struct; // XXX could not open error
|
return $struct; // XXX could not open error
|
||||||
}
|
}
|
||||||
$struct['dirs'][] = $sPath; // XXX don't add if '.' or '..' ?
|
|
||||||
|
$struct['dirs'][] = $sPath = realpath($sPath); // XXX don't add if '.' or '..' ?
|
||||||
$list = array();
|
$list = array();
|
||||||
while ($file = readdir($dir)) {
|
while (false !== ($file = readdir($dir))) {
|
||||||
if ($file != '.' && $file != '..') {
|
if ($file != '.' && $file != '..') {
|
||||||
$list[] = $file;
|
$list[] = $file;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
closedir($dir);
|
closedir($dir);
|
||||||
sort($list);
|
natsort($list);
|
||||||
if ($aktinst < $maxinst || $maxinst == 0) {
|
if ($aktinst < $maxinst || $maxinst == 0) {
|
||||||
foreach ($list as $val) {
|
foreach ($list as $val) {
|
||||||
$path = $sPath . DIRECTORY_SEPARATOR . $val;
|
$path = $sPath . DIRECTORY_SEPARATOR . $val;
|
||||||
if (is_dir($path)) {
|
if (is_dir($path) && !is_link($path)) {
|
||||||
$tmp = System::_dirToStruct($path, $maxinst, $aktinst+1);
|
$tmp = System::_dirToStruct($path, $maxinst, $aktinst+1, $silent);
|
||||||
$struct = array_merge_recursive($tmp, $struct);
|
$struct = array_merge_recursive($struct, $tmp);
|
||||||
} else {
|
} else {
|
||||||
$struct['files'][] = $path;
|
$struct['files'][] = $path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $struct;
|
return $struct;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,6 +167,7 @@ class System
|
||||||
*
|
*
|
||||||
* @param array $files Array listing files and dirs
|
* @param array $files Array listing files and dirs
|
||||||
* @return array
|
* @return array
|
||||||
|
* @static
|
||||||
* @see System::_dirToStruct()
|
* @see System::_dirToStruct()
|
||||||
*/
|
*/
|
||||||
function _multipleToStruct($files)
|
function _multipleToStruct($files)
|
||||||
|
@ -154,13 +175,15 @@ class System
|
||||||
$struct = array('dirs' => array(), 'files' => array());
|
$struct = array('dirs' => array(), 'files' => array());
|
||||||
settype($files, 'array');
|
settype($files, 'array');
|
||||||
foreach ($files as $file) {
|
foreach ($files as $file) {
|
||||||
if (is_dir($file)) {
|
if (is_dir($file) && !is_link($file)) {
|
||||||
$tmp = System::_dirToStruct($file, 0);
|
$tmp = System::_dirToStruct($file, 0);
|
||||||
$struct = array_merge_recursive($tmp, $struct);
|
$struct = array_merge_recursive($tmp, $struct);
|
||||||
} else {
|
} else {
|
||||||
|
if (!in_array($file, $struct['files'])) {
|
||||||
$struct['files'][] = $file;
|
$struct['files'][] = $file;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return $struct;
|
return $struct;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,11 +193,12 @@ class System
|
||||||
*
|
*
|
||||||
* @param string $args the arguments for rm
|
* @param string $args the arguments for rm
|
||||||
* @return mixed PEAR_Error or true for success
|
* @return mixed PEAR_Error or true for success
|
||||||
|
* @static
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function rm($args)
|
function rm($args)
|
||||||
{
|
{
|
||||||
$opts = System::_parseArgs($args, 'rf'); // "f" do nothing but like it :-)
|
$opts = System::_parseArgs($args, 'rf'); // "f" does nothing but I like it :-)
|
||||||
if (PEAR::isError($opts)) {
|
if (PEAR::isError($opts)) {
|
||||||
return System::raiseError($opts);
|
return System::raiseError($opts);
|
||||||
}
|
}
|
||||||
|
@ -191,6 +215,8 @@ class System
|
||||||
$ret = false;
|
$ret = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rsort($struct['dirs']);
|
||||||
foreach ($struct['dirs'] as $dir) {
|
foreach ($struct['dirs'] as $dir) {
|
||||||
if (!@rmdir($dir)) {
|
if (!@rmdir($dir)) {
|
||||||
$ret = false;
|
$ret = false;
|
||||||
|
@ -208,11 +234,12 @@ class System
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make directories. Note that we use call_user_func('mkdir') to avoid
|
* Make directories.
|
||||||
* a problem with ZE2 calling System::mkDir instead of the native PHP func.
|
|
||||||
*
|
*
|
||||||
|
* The -p option will create parent directories
|
||||||
* @param string $args the name of the director(y|ies) to create
|
* @param string $args the name of the director(y|ies) to create
|
||||||
* @return bool True for success
|
* @return bool True for success
|
||||||
|
* @static
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function mkDir($args)
|
function mkDir($args)
|
||||||
|
@ -221,6 +248,7 @@ class System
|
||||||
if (PEAR::isError($opts)) {
|
if (PEAR::isError($opts)) {
|
||||||
return System::raiseError($opts);
|
return System::raiseError($opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
$mode = 0777; // default mode
|
$mode = 0777; // default mode
|
||||||
foreach ($opts[0] as $opt) {
|
foreach ($opts[0] as $opt) {
|
||||||
if ($opt[0] == 'p') {
|
if ($opt[0] == 'p') {
|
||||||
|
@ -237,27 +265,36 @@ class System
|
||||||
$mode = $opt[1];
|
$mode = $opt[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$ret = true;
|
$ret = true;
|
||||||
if (isset($create_parents)) {
|
if (isset($create_parents)) {
|
||||||
foreach ($opts[1] as $dir) {
|
foreach ($opts[1] as $dir) {
|
||||||
$dirstack = array();
|
$dirstack = array();
|
||||||
while (!@is_dir($dir) && $dir != DIRECTORY_SEPARATOR) {
|
while ((!file_exists($dir) || !is_dir($dir)) &&
|
||||||
|
$dir != DIRECTORY_SEPARATOR) {
|
||||||
array_unshift($dirstack, $dir);
|
array_unshift($dirstack, $dir);
|
||||||
$dir = dirname($dir);
|
$dir = dirname($dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
while ($newdir = array_shift($dirstack)) {
|
while ($newdir = array_shift($dirstack)) {
|
||||||
if (!call_user_func('mkdir', $newdir, $mode)) {
|
if (!is_writeable(dirname($newdir))) {
|
||||||
|
$ret = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mkdir($newdir, $mode)) {
|
||||||
$ret = false;
|
$ret = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
foreach($opts[1] as $dir) {
|
foreach($opts[1] as $dir) {
|
||||||
if (!@is_dir($dir) && !call_user_func('mkdir', $dir, $mode)) {
|
if ((@file_exists($dir) || !is_dir($dir)) && !mkdir($dir, $mode)) {
|
||||||
$ret = false;
|
$ret = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,6 +310,7 @@ class System
|
||||||
*
|
*
|
||||||
* @param string $args the arguments
|
* @param string $args the arguments
|
||||||
* @return boolean true on success
|
* @return boolean true on success
|
||||||
|
* @static
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function &cat($args)
|
function &cat($args)
|
||||||
|
@ -280,9 +318,11 @@ class System
|
||||||
$ret = null;
|
$ret = null;
|
||||||
$files = array();
|
$files = array();
|
||||||
if (!is_array($args)) {
|
if (!is_array($args)) {
|
||||||
$args = preg_split('/\s+/', $args);
|
$args = preg_split('/\s+/', $args, -1, PREG_SPLIT_NO_EMPTY);
|
||||||
}
|
}
|
||||||
for($i=0; $i < count($args); $i++) {
|
|
||||||
|
$count_args = count($args);
|
||||||
|
for ($i = 0; $i < $count_args; $i++) {
|
||||||
if ($args[$i] == '>') {
|
if ($args[$i] == '>') {
|
||||||
$mode = 'wb';
|
$mode = 'wb';
|
||||||
$outputfile = $args[$i+1];
|
$outputfile = $args[$i+1];
|
||||||
|
@ -295,6 +335,7 @@ class System
|
||||||
$files[] = $args[$i];
|
$files[] = $args[$i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$outputfd = false;
|
||||||
if (isset($mode)) {
|
if (isset($mode)) {
|
||||||
if (!$outputfd = fopen($outputfile, $mode)) {
|
if (!$outputfd = fopen($outputfile, $mode)) {
|
||||||
$err = System::raiseError("Could not open $outputfile");
|
$err = System::raiseError("Could not open $outputfile");
|
||||||
|
@ -308,7 +349,7 @@ class System
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
while ($cont = fread($fd, 2048)) {
|
while ($cont = fread($fd, 2048)) {
|
||||||
if (isset($outputfd)) {
|
if (is_resource($outputfd)) {
|
||||||
fwrite($outputfd, $cont);
|
fwrite($outputfd, $cont);
|
||||||
} else {
|
} else {
|
||||||
$ret .= $cont;
|
$ret .= $cont;
|
||||||
|
@ -316,7 +357,7 @@ class System
|
||||||
}
|
}
|
||||||
fclose($fd);
|
fclose($fd);
|
||||||
}
|
}
|
||||||
if (@is_resource($outputfd)) {
|
if (is_resource($outputfd)) {
|
||||||
fclose($outputfd);
|
fclose($outputfd);
|
||||||
}
|
}
|
||||||
return $ret;
|
return $ret;
|
||||||
|
@ -343,6 +384,7 @@ class System
|
||||||
* @param string $args The arguments
|
* @param string $args The arguments
|
||||||
* @return mixed the full path of the created (file|dir) or false
|
* @return mixed the full path of the created (file|dir) or false
|
||||||
* @see System::tmpdir()
|
* @see System::tmpdir()
|
||||||
|
* @static
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function mktemp($args = null)
|
function mktemp($args = null)
|
||||||
|
@ -352,6 +394,7 @@ class System
|
||||||
if (PEAR::isError($opts)) {
|
if (PEAR::isError($opts)) {
|
||||||
return System::raiseError($opts);
|
return System::raiseError($opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($opts[0] as $opt) {
|
foreach ($opts[0] as $opt) {
|
||||||
if ($opt[0] == 'd') {
|
if ($opt[0] == 'd') {
|
||||||
$tmp_is_dir = true;
|
$tmp_is_dir = true;
|
||||||
|
@ -359,25 +402,34 @@ class System
|
||||||
$tmpdir = $opt[1];
|
$tmpdir = $opt[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$prefix = (isset($opts[1][0])) ? $opts[1][0] : 'tmp';
|
$prefix = (isset($opts[1][0])) ? $opts[1][0] : 'tmp';
|
||||||
if (!isset($tmpdir)) {
|
if (!isset($tmpdir)) {
|
||||||
$tmpdir = System::tmpdir();
|
$tmpdir = System::tmpdir();
|
||||||
}
|
}
|
||||||
if (!System::mkDir("-p $tmpdir")) {
|
|
||||||
|
if (!System::mkDir(array('-p', $tmpdir))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$tmp = tempnam($tmpdir, $prefix);
|
$tmp = tempnam($tmpdir, $prefix);
|
||||||
if (isset($tmp_is_dir)) {
|
if (isset($tmp_is_dir)) {
|
||||||
unlink($tmp); // be careful possible race condition here
|
unlink($tmp); // be careful possible race condition here
|
||||||
if (!call_user_func('mkdir', $tmp, 0700)) {
|
if (!mkdir($tmp, 0700)) {
|
||||||
return System::raiseError("Unable to create temporary directory $tmpdir");
|
return System::raiseError("Unable to create temporary directory $tmpdir");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$GLOBALS['_System_temp_files'][] = $tmp;
|
$GLOBALS['_System_temp_files'][] = $tmp;
|
||||||
|
if (isset($tmp_is_dir)) {
|
||||||
|
//$GLOBALS['_System_temp_files'][] = dirname($tmp);
|
||||||
|
}
|
||||||
|
|
||||||
if ($first_time) {
|
if ($first_time) {
|
||||||
PEAR::registerShutdownFunc(array('System', '_removeTmpFiles'));
|
PEAR::registerShutdownFunc(array('System', '_removeTmpFiles'));
|
||||||
$first_time = false;
|
$first_time = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $tmp;
|
return $tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -385,6 +437,7 @@ class System
|
||||||
* Remove temporary files created my mkTemp. This function is executed
|
* Remove temporary files created my mkTemp. This function is executed
|
||||||
* at script shutdown time
|
* at script shutdown time
|
||||||
*
|
*
|
||||||
|
* @static
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
function _removeTmpFiles()
|
function _removeTmpFiles()
|
||||||
|
@ -393,6 +446,7 @@ class System
|
||||||
$delete = $GLOBALS['_System_temp_files'];
|
$delete = $GLOBALS['_System_temp_files'];
|
||||||
array_unshift($delete, '-r');
|
array_unshift($delete, '-r');
|
||||||
System::rm($delete);
|
System::rm($delete);
|
||||||
|
$GLOBALS['_System_temp_files'] = array();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -402,15 +456,19 @@ class System
|
||||||
* Note: php.ini-recommended removes the "E" from the variables_order setting,
|
* Note: php.ini-recommended removes the "E" from the variables_order setting,
|
||||||
* making unavaible the $_ENV array, that s why we do tests with _ENV
|
* making unavaible the $_ENV array, that s why we do tests with _ENV
|
||||||
*
|
*
|
||||||
* @return string The temporal directory on the system
|
* @static
|
||||||
|
* @return string The temporary directory on the system
|
||||||
*/
|
*/
|
||||||
function tmpdir()
|
function tmpdir()
|
||||||
{
|
{
|
||||||
if (OS_WINDOWS) {
|
if (OS_WINDOWS) {
|
||||||
|
if ($var = isset($_ENV['TMP']) ? $_ENV['TMP'] : getenv('TMP')) {
|
||||||
|
return $var;
|
||||||
|
}
|
||||||
if ($var = isset($_ENV['TEMP']) ? $_ENV['TEMP'] : getenv('TEMP')) {
|
if ($var = isset($_ENV['TEMP']) ? $_ENV['TEMP'] : getenv('TEMP')) {
|
||||||
return $var;
|
return $var;
|
||||||
}
|
}
|
||||||
if ($var = isset($_ENV['TMP']) ? $_ENV['TMP'] : getenv('TMP')) {
|
if ($var = isset($_ENV['USERPROFILE']) ? $_ENV['USERPROFILE'] : getenv('USERPROFILE')) {
|
||||||
return $var;
|
return $var;
|
||||||
}
|
}
|
||||||
if ($var = isset($_ENV['windir']) ? $_ENV['windir'] : getenv('windir')) {
|
if ($var = isset($_ENV['windir']) ? $_ENV['windir'] : getenv('windir')) {
|
||||||
|
@ -421,38 +479,60 @@ class System
|
||||||
if ($var = isset($_ENV['TMPDIR']) ? $_ENV['TMPDIR'] : getenv('TMPDIR')) {
|
if ($var = isset($_ENV['TMPDIR']) ? $_ENV['TMPDIR'] : getenv('TMPDIR')) {
|
||||||
return $var;
|
return $var;
|
||||||
}
|
}
|
||||||
return '/tmp';
|
return realpath('/tmp');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The "which" command (show the full path of a command)
|
* The "which" command (show the full path of a command)
|
||||||
*
|
*
|
||||||
* @param string $program The command to search for
|
* @param string $program The command to search for
|
||||||
|
* @param mixed $fallback Value to return if $program is not found
|
||||||
|
*
|
||||||
* @return mixed A string with the full path or false if not found
|
* @return mixed A string with the full path or false if not found
|
||||||
|
* @static
|
||||||
* @author Stig Bakken <ssb@php.net>
|
* @author Stig Bakken <ssb@php.net>
|
||||||
*/
|
*/
|
||||||
function which($program, $fallback = false)
|
function which($program, $fallback = false)
|
||||||
{
|
{
|
||||||
// is_executable() is not available on windows
|
// enforce API
|
||||||
if (OS_WINDOWS) {
|
if (!is_string($program) || '' == $program) {
|
||||||
$pear_is_executable = 'is_file';
|
return $fallback;
|
||||||
} else {
|
|
||||||
$pear_is_executable = 'is_executable';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// full path given
|
// full path given
|
||||||
if (basename($program) != $program) {
|
if (basename($program) != $program) {
|
||||||
return (@$pear_is_executable($program)) ? $program : $fallback;
|
$path_elements[] = dirname($program);
|
||||||
|
$program = basename($program);
|
||||||
|
} else {
|
||||||
|
// Honor safe mode
|
||||||
|
if (!ini_get('safe_mode') || !$path = ini_get('safe_mode_exec_dir')) {
|
||||||
|
$path = getenv('PATH');
|
||||||
|
if (!$path) {
|
||||||
|
$path = getenv('Path'); // some OSes are just stupid enough to do this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$path_elements = explode(PATH_SEPARATOR, $path);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OS_WINDOWS) {
|
||||||
|
$exe_suffixes = getenv('PATHEXT')
|
||||||
|
? explode(PATH_SEPARATOR, getenv('PATHEXT'))
|
||||||
|
: array('.exe','.bat','.cmd','.com');
|
||||||
|
// allow passing a command.exe param
|
||||||
|
if (strpos($program, '.') !== false) {
|
||||||
|
array_unshift($exe_suffixes, '');
|
||||||
|
}
|
||||||
|
// is_executable() is not available on windows for PHP4
|
||||||
|
$pear_is_executable = (function_exists('is_executable')) ? 'is_executable' : 'is_file';
|
||||||
|
} else {
|
||||||
|
$exe_suffixes = array('');
|
||||||
|
$pear_is_executable = 'is_executable';
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX FIXME honor safe mode
|
|
||||||
$path_delim = OS_WINDOWS ? ';' : ':';
|
|
||||||
$exe_suffixes = OS_WINDOWS ? array('.exe','.bat','.cmd','.com') : array('');
|
|
||||||
$path_elements = explode($path_delim, getenv('PATH'));
|
|
||||||
foreach ($exe_suffixes as $suff) {
|
foreach ($exe_suffixes as $suff) {
|
||||||
foreach ($path_elements as $dir) {
|
foreach ($path_elements as $dir) {
|
||||||
$file = $dir . DIRECTORY_SEPARATOR . $program . $suff;
|
$file = $dir . DIRECTORY_SEPARATOR . $program . $suff;
|
||||||
if (@is_file($file) && @$pear_is_executable($file)) {
|
if (@$pear_is_executable($file)) {
|
||||||
return $file;
|
return $file;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -481,6 +561,7 @@ class System
|
||||||
*
|
*
|
||||||
* @param mixed Either array or string with the command line
|
* @param mixed Either array or string with the command line
|
||||||
* @return array Array of found files
|
* @return array Array of found files
|
||||||
|
* @static
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
function find($args)
|
function find($args)
|
||||||
|
@ -488,11 +569,15 @@ class System
|
||||||
if (!is_array($args)) {
|
if (!is_array($args)) {
|
||||||
$args = preg_split('/\s+/', $args, -1, PREG_SPLIT_NO_EMPTY);
|
$args = preg_split('/\s+/', $args, -1, PREG_SPLIT_NO_EMPTY);
|
||||||
}
|
}
|
||||||
$dir = array_shift($args);
|
$dir = realpath(array_shift($args));
|
||||||
|
if (!$dir) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
$patterns = array();
|
$patterns = array();
|
||||||
$depth = 0;
|
$depth = 0;
|
||||||
$do_files = $do_dirs = true;
|
$do_files = $do_dirs = true;
|
||||||
for ($i = 0; $i < count($args); $i++) {
|
$args_count = count($args);
|
||||||
|
for ($i = 0; $i < $args_count; $i++) {
|
||||||
switch ($args[$i]) {
|
switch ($args[$i]) {
|
||||||
case '-type':
|
case '-type':
|
||||||
if (in_array($args[$i+1], array('d', 'f'))) {
|
if (in_array($args[$i+1], array('d', 'f'))) {
|
||||||
|
@ -505,10 +590,11 @@ class System
|
||||||
$i++;
|
$i++;
|
||||||
break;
|
break;
|
||||||
case '-name':
|
case '-name':
|
||||||
$patterns[] = "(" . preg_replace(array('/\./', '/\*/'),
|
$name = preg_quote($args[$i+1], '#');
|
||||||
array('\.', '.*'),
|
// our magic characters ? and * have just been escaped,
|
||||||
$args[$i+1])
|
// so now we change the escaped versions to PCRE operators
|
||||||
. ")";
|
$name = strtr($name, array('\?' => '.', '\*' => '.*'));
|
||||||
|
$patterns[] = '('.$name.')';
|
||||||
$i++;
|
$i++;
|
||||||
break;
|
break;
|
||||||
case '-maxdepth':
|
case '-maxdepth':
|
||||||
|
@ -516,7 +602,7 @@ class System
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$path = System::_dirToStruct($dir, $depth);
|
$path = System::_dirToStruct($dir, $depth, 0, true);
|
||||||
if ($do_files && $do_dirs) {
|
if ($do_files && $do_dirs) {
|
||||||
$files = array_merge($path['files'], $path['dirs']);
|
$files = array_merge($path['files'], $path['dirs']);
|
||||||
} elseif ($do_dirs) {
|
} elseif ($do_dirs) {
|
||||||
|
@ -525,10 +611,14 @@ class System
|
||||||
$files = $path['files'];
|
$files = $path['files'];
|
||||||
}
|
}
|
||||||
if (count($patterns)) {
|
if (count($patterns)) {
|
||||||
$patterns = implode('|', $patterns);
|
$dsq = preg_quote(DIRECTORY_SEPARATOR, '#');
|
||||||
|
$pattern = '#(^|'.$dsq.')'.implode('|', $patterns).'($|'.$dsq.')#';
|
||||||
$ret = array();
|
$ret = array();
|
||||||
for ($i = 0; $i < count($files); $i++) {
|
$files_count = count($files);
|
||||||
if (preg_match("#^$patterns\$#", $files[$i])) {
|
for ($i = 0; $i < $files_count; $i++) {
|
||||||
|
// only search in the part of the file below the current directory
|
||||||
|
$filepart = basename($files[$i]);
|
||||||
|
if (preg_match($pattern, $filepart)) {
|
||||||
$ret[] = $files[$i];
|
$ret[] = $files[$i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -537,4 +627,3 @@ class System
|
||||||
return $files;
|
return $files;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
?>
|
|
||||||
|
|
Loading…
Reference in New Issue