Subversion Repositories Applications.gtt

Compare Revisions

Ignore whitespace Rev 187 → Rev 186

/trunk/bibliotheque/pear/OS/Guess.php
File deleted
/trunk/bibliotheque/pear/scripts/pear.bat
File deleted
\ No newline at end of file
/trunk/bibliotheque/pear/scripts/pecl.sh
File deleted
/trunk/bibliotheque/pear/scripts/peclcmd.php
File deleted
/trunk/bibliotheque/pear/scripts/peardev.sh
File deleted
/trunk/bibliotheque/pear/scripts/pear.sh
File deleted
/trunk/bibliotheque/pear/scripts/pearcmd.php
File deleted
/trunk/bibliotheque/pear/scripts/pecl.bat
File deleted
\ No newline at end of file
/trunk/bibliotheque/pear/scripts/peardev.bat
File deleted
\ No newline at end of file
/trunk/bibliotheque/pear/System.php
File deleted
\ No newline at end of file
/trunk/bibliotheque/pear/DB/Pager.php
New file
0,0 → 1,250
<?php
//
// Pear DB Pager - Retrieve and return information of databases
// result sets
//
// Copyright (C) 2001 Tomas Von Veschler Cox <cox@idecnet.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
//
// $Id: Pager.php,v 1.3 2002/05/12 13:59:40 cox Exp $
 
require_once 'PEAR.php';
require_once 'DB.php';
 
/**
* This class handles all the stuff needed for displaying paginated results
* from a database query of Pear DB, in a very easy way.
* Documentation and examples of use, can be found in:
* http://vulcanonet.com/soft/pager/ (could be outdated)
*
* IMPORTANT!
* Since PEAR DB already support native row limit (more fast and avaible in
* all the drivers), there is no more need to use $pager->build() or
* the $pager->fetch*() methods.
*
* Usage example:
*
*< ?php
* require_once 'DB/Pager.php';
* $db = DB::connect('your DSN string');
* $from = 0; // The row to start to fetch from (you might want to get this
* // param from the $_GET array
* $limit = 10; // The number of results per page
* $maxpages = 10; // The number of pages for displaying in the pager (optional)
* $res = $db->limitQuery($sql, $from, $limit);
* $nrows = 0; // Alternative you could use $res->numRows()
* while ($row = $res->fetchrow()) {
* // XXX code for building the page here
* $nrows++;
* }
* $data = DB_Pager::getData($from, $limit, $nrows, $maxpages);
* // XXX code for building the pager here
* ? >
*
* @version 0.7
* @author Tomas V.V.Cox <cox@idecnet.com>
* @see http://vulcanonet.com/soft/pager/
*/
 
class DB_Pager extends PEAR
{
 
/**
* Constructor
*
* @param object $res A DB_result object from Pear_DB
* @param int $from The row to start fetching
* @param int $limit How many results per page
* @param int $numrows Pager will automatically
* find this param if is not given. If your Pear_DB backend extension
* doesn't support numrows(), you can manually calculate it
* and supply later to the constructor
* @deprecated
*/
function DB_Pager (&$res, $from, $limit, $numrows = null)
{
$this->res = $res;
$this->from = $from;
$this->limit = $limit;
$this->numrows = $numrows;
}
 
/**
* Calculates all the data needed by Pager to work
*
* @return mixed An assoc array with all the data (see getData)
* or DB_Error on error
* @see DB_Pager::getData
* @deprecated
*/
function build()
{
// if there is no numrows given, calculate it
if ($this->numrows === null) {
$this->numrows = $this->res->numrows();
if (DB::isError($this->numrows)) {
return $this->numrows;
}
}
$data = $this->getData($this->from, $this->limit, $this->numrows);
if (DB::isError($data)) {
return $data;
}
$this->current = $this->from - 1;
$this->top = $data['to'];
return $data;
}
 
/**
* @deprecated
*/
function fetchRow($mode=DB_FETCHMODE_DEFAULT)
{
$this->current++;
if ($this->current >= $this->top) {
return null;
}
return $this->res->fetchRow($mode, $this->current);
}
 
/**
* @deprecated
*/
function fetchInto(&$arr, $mode=DB_FETCHMODE_DEFAULT)
{
$this->current++;
if ($this->current >= $this->top) {
return null;
}
return $this->res->fetchInto($arr, $mode, $this->current);
}
 
/*
* Gets all the data needed to paginate results
* This is an associative array with the following
* values filled in:
*
* array(
* 'current' => X, // current page you are
* 'numrows' => X, // total number of results
* 'next' => X, // row number where next page starts
* 'prev' => X, // row number where prev page starts
* 'remain' => X, // number of results remaning *in next page*
* 'numpages'=> X, // total number of pages
* 'from' => X, // the row to start fetching
* 'to' => X, // the row to stop fetching
* 'limit' => X, // how many results per page
* 'maxpages' => X, // how many pages to show (google style)
* 'firstpage' => X, // the row number of the first page
* 'lastpage' => X, // the row number where the last page starts
* 'pages' => array( // assoc with page "number => start row"
* 1 => X,
* 2 => X,
* 3 => X
* )
* );
* @param int $from The row to start fetching
* @param int $limit How many results per page
* @param int $numrows Number of results from query
*
* @return array associative array with data or DB_error on error
*
*/
function &getData($from, $limit, $numrows, $maxpages = false)
{
if (empty($numrows) || ($numrows < 0)) {
return null;
}
$from = (empty($from)) ? 0 : $from;
 
if ($limit <= 0) {
return PEAR::raiseError (null, 'wrong "limit" param', null,
null, null, 'DB_Error', true);
}
 
// Total number of pages
$pages = ceil($numrows/$limit);
$data['numpages'] = $pages;
 
// first & last page
$data['firstpage'] = 1;
$data['lastpage'] = $pages;
 
// Build pages array
$data['pages'] = array();
for ($i=1; $i <= $pages; $i++) {
$offset = $limit * ($i-1);
$data['pages'][$i] = $offset;
// $from must point to one page
if ($from == $offset) {
// The current page we are
$data['current'] = $i;
}
}
if (!isset($data['current'])) {
return PEAR::raiseError (null, 'wrong "from" param', null,
null, null, 'DB_Error', true);
}
 
// Limit number of pages (goole algoritm)
if ($maxpages) {
$radio = floor($maxpages/2);
$minpage = $data['current'] - $radio;
if ($minpage < 1) {
$minpage = 1;
}
$maxpage = $data['current'] + $radio - 1;
if ($maxpage > $data['numpages']) {
$maxpage = $data['numpages'];
}
foreach (range($minpage, $maxpage) as $page) {
$tmp[$page] = $data['pages'][$page];
}
$data['pages'] = $tmp;
$data['maxpages'] = $maxpages;
} else {
$data['maxpages'] = null;
}
 
// Prev link
$prev = $from - $limit;
$data['prev'] = ($prev >= 0) ? $prev : null;
 
// Next link
$next = $from + $limit;
$data['next'] = ($next < $numrows) ? $next : null;
 
// Results remaining in next page & Last row to fetch
if ($data['current'] == $pages) {
$data['remain'] = 0;
$data['to'] = $numrows;
} else {
if ($data['current'] == ($pages - 1)) {
$data['remain'] = $numrows - ($limit*($pages-1));
} else {
$data['remain'] = $limit;
}
$data['to'] = $data['current'] * $limit;
}
$data['numrows'] = $numrows;
$data['from'] = $from + 1;
$data['limit'] = $limit;
 
return $data;
}
}
?>
/trunk/bibliotheque/pear/DB/NestedSet.php
New file
0,0 → 1,2747
<?php
//
// +----------------------------------------------------------------------+
// | PEAR :: DB_NestedSet |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.0 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |f
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Daniel Khan <dk@webcluster.at> |
// | Jason Rust <jason@rustyparts.com> |
// +----------------------------------------------------------------------+
// $Id: NestedSet.php,v 1.56 2003/10/07 00:11:26 datenpunk Exp $
//
 
// CREDITS:
// --------
// - Thanks to Kristian Koehntopp for publishing an explanation of the Nested Set
// technique and for the great work he did and does for the php community
// - Thanks to Daniel T. Gorski for his great tutorial on www.develnet.org
//
// - Thanks to my parents for ... just kidding :]
 
require_once 'PEAR.php';
 
// {{{ constants
 
// Error and message codes
define('NESE_ERROR_RECURSION', 'E100');
define('NESE_ERROR_NODRIVER', 'E200');
define('NESE_ERROR_NOHANDLER', 'E300');
define('NESE_ERROR_TBLOCKED', 'E010');
define('NESE_MESSAGE_UNKNOWN', 'E0');
define('NESE_ERROR_NOTSUPPORTED', 'E1');
define('NESE_ERROR_PARAM_MISSING','E400');
define('NESE_ERROR_NOT_FOUND', 'E500');
define('NESE_ERROR_WRONG_MPARAM', 'E2');
 
// for moving a node before another
define('NESE_MOVE_BEFORE', 'BE');
// for moving a node after another
define('NESE_MOVE_AFTER', 'AF');
// for moving a node below another
define('NESE_MOVE_BELOW', 'SUB');
 
 
// Sortorders
define('NESE_SORT_LEVEL', 'SLV');
define('NESE_SORT_PREORDER', 'SPO');
 
// }}}
// {{{ DB_NestedSet:: class
/**
* DB_NestedSet is a class for handling nested sets
*
* @author Daniel Khan <dk@webcluster.at>
* @package DB_NestedSet
* @version $Revision: 1.56 $
* @access public
*/
 
// }}}
class DB_NestedSet {
// {{{ properties
 
/**
* @var array The field parameters of the table with the nested set. Format: 'realFieldName' => 'fieldId'
* @access public
*/
var $params = array(
'STRID' => 'id',
'ROOTID'=> 'rootid',
'l' => 'l',
'r' => 'r',
'STREH' => 'norder',
'LEVEL' => 'level',
// 'parent'=>'parent', // Optional but very useful
'STRNA' => 'name'
);
 
// To be used with 2.0 - would be an api break atm
// var $quotedParams = array('name');
 
/**
* @var string The table with the actual tree data
* @access public
*/
var $node_table = 'tb_nodes';
 
/**
* @var string The table to handle locking
* @access public
*/
var $lock_table = 'tb_locks';
 
/**
* @var string The table used for sequences
* @access public
*/
var $sequence_table;
 
/**
* Secondary order field. Normally this is the order field, but can be changed to
* something else (i.e. the name field so that the tree can be shown alphabetically)
*
* @var string
* @access public
*/
var $secondarySort;
 
/**
* Used to store the secondary sort method set by the user while doing manipulative queries
*
* @var string
* @access private
*/
var $_userSecondarySort = false;
 
/**
* The default sorting field - will be set to the table column inside the constructor
*
* @var string
* @access private
*/
var $_defaultSecondarySort = 'norder';
 
/**
* @var int The time to live of the lock
* @access public
*/
var $lockTTL = 1;
 
/**
* @var bool Enable debugging statements?
* @access public
*/
var $debug = 0;
 
/**
* @var bool Lock the structure of the table?
* @access private
*/
var $_structureTableLock = false;
 
 
/**
* @var bool Don't allow unlocking (used inside of moves)
* @access private
*/
var $_lockExclusive = false;
 
/**
* @var object cache Optional PEAR::Cache object
* @access public
*/
var $cache = false;
 
/**
* Specify the sortMode of the query methods
* NESE_SORT_LEVEL is the 'old' sorting method and sorts a tree by level
* all nodes of level 1, all nodes of level 2,...
* NESE_SORT_PREORDER will sort doing a preorder walk.
* So all children of node x will come right after it
* Note that moving a node within it's siblings will obviously not change the output
* in this mode
*
* @var constant Order method (NESE_SORT_LEVEL|NESE_SORT_PREORDER)
* @access private
*/
var $_sortMode = NESE_SORT_LEVEL;
 
/**
* @var array Available sortModes
* @access private
*/
var $_sortModes = array(NESE_SORT_LEVEL, NESE_SORT_PREORDER);
 
/**
* @var array An array of field ids that must exist in the table
* @access private
*/
var $_requiredParams = array('id', 'rootid', 'l', 'r', 'norder', 'level');
 
/**
* @var bool Skip the callback events?
* @access private
*/
var $_skipCallbacks = false;
 
/**
* @var bool Do we want to use caching
* @access private
*/
var $_caching = false;
 
/**
* @var array The above parameters flipped for easy access
* @access private
*/
var $_flparams = array();
 
/**
*
* @var bool Temporary switch for cache
* @access private
*/
var $_restcache = false;
 
/**
* Used to determine the presence of listeners for an event in triggerEvent()
*
* If any event listeners are registered for an event, the event name will
* have a key set in this array, otherwise, it will not be set.
* @see triggerEvent()
* @var arrayg
* @access private
*/
var $_hasListeners = array();
 
 
/**
* @var string packagename
* @access private
*/
var $_packagename = 'DB_NestedSet';
 
/**
* @var int Majorversion
* @access private
*/
var $_majorversion = 1;
 
/**
* @var string Minorversion
* @access private
*/
var $_minorversion = '3';
 
/**
* @var array Used for mapping a cloned tree to the real tree for move_* operations
* @access private
*/
var $_relations = array();
 
/**
* Used for _internal_ tree conversion
* @var bool Turn off user param verification and id generation
* @access private
*/
var $_dumbmode = false;
 
/**
* @var array Map of error messages to their descriptions
*/
var $messages = array(
NESE_ERROR_RECURSION => '%s: This operation would lead to a recursion',
NESE_ERROR_TBLOCKED => 'The structure Table is locked for another database operation, please retry.',
NESE_ERROR_NODRIVER => 'The selected database driver %s wasn\'t found',
NESE_ERROR_NOTSUPPORTED => 'Method not supported yet',
NESE_ERROR_NOHANDLER => 'Event handler not found',
NESE_ERROR_PARAM_MISSING=> 'Parameter missing',
NESE_MESSAGE_UNKNOWN => 'Unknown error or message',
NESE_ERROR_NOT_FOUND => '%s: Node %s not found',
NESE_ERROR_WRONG_MPARAM => '%s: %s'
);
 
/**
* @var array The array of event listeners
* @access private
*/
var $eventListeners = array();
 
 
// }}}
// +---------------------------------------+
// | Base methods |
// +---------------------------------------+
// {{{ constructor
 
/**
* Constructor
*
* @param array $params Database column fields which should be returned
*
* @access private
* @return void
*/
function DB_NestedSet($params) {
 
if ($this->debug) {
$this->_debugMessage('DB_NestedSet()');
}
if (is_array($params) && count($params) > 0) {
$this->params = $params;
}
 
$this->_flparams = array_flip($this->params);
$this->sequence_table = $this->node_table . '_' . $this->_flparams['id'];
$this->secondarySort = $this->_flparams[$this->_defaultSecondarySort];
register_shutdown_function(array(&$this,'_DB_NestedSet'));
}
 
// }}}
// {{{ destructor
 
/**
* PEAR Destructor
* Releases all locks
* Closes open database connections
*
* @access private
* @return void
*/
function _DB_NestedSet() {
if ($this->debug) {
$this->_debugMessage('_DB_NestedSet()');
}
$this->_releaseLock(true);
}
 
// }}}
// {{{ factory
 
/**
* Handles the returning of a concrete instance of DB_NestedSet based on the driver.
* If the class given by $driver allready exists it will be used.
* If not the driver will be searched inside the default path ./NestedSet/
*
* @param string $driver The driver, such as DB or MDB
* @param string $dsn The dsn for connecting to the database
* @param array $params The field name params for the node table
*
* @static
* @access public
* @return object The DB_NestedSet object
*/
function & factory($driver, $dsn, $params = array()) {
 
$classname = 'DB_NestedSet_' . $driver;
if (!class_exists($classname)) {
$driverpath = dirname(__FILE__).'/NestedSet/'.$driver.'.php';
if(!file_exists($driverpath) || !$driver) {
return PEAR::raiseError("factory(): The database driver '$driver' wasn't found", NESE_ERROR_NODRIVER, PEAR_ERROR_TRIGGER, E_USER_ERROR);
}
include_once($driverpath);
}
return new $classname($dsn, $params);
}
 
// }}}
 
 
// }}}
// +----------------------------------------------+
// | NestedSet manipulation and query methods |
// |----------------------------------------------+
// | Querying the tree |
// +----------------------------------------------+
 
// {{{ getAllNodes()
 
/**
* Fetch the whole NestedSet
*
* @param bool $keepAsArray (optional) Keep the result as an array or transform it into
* a set of DB_NestedSet_Node objects?
* @param bool $aliasFields (optional) Should we alias the fields so they are the names
* of the parameter keys, or leave them as is?
* @param array $addSQL (optional) Array of additional params to pass to the query.
*
* @access public
* @return mixed False on error, or an array of nodes
*/
function getAllNodes($keepAsArray = false, $aliasFields = true, $addSQL = array()) {
if ($this->debug) {
$this->_debugMessage('getAllNodes()');
}
 
if($this->_sortMode == NESE_SORT_LEVEL) {
$sql = sprintf('SELECT %s %s FROM %s %s %s ORDER BY %s.%s, %s.%s ASC',
$this->_getSelectFields($aliasFields),
$this->_addSQL($addSQL, 'cols'),
$this->node_table,
$this->_addSQL($addSQL, 'join'),
$this->_addSQL($addSQL, 'append'),
$this->node_table,
$this->_flparams['level'],
$this->node_table,
$this->secondarySort);
} elseif ($this->_sortMode == NESE_SORT_PREORDER) {
$nodeSet = array();
$rootnodes = $this->getRootNodes(true);
foreach($rootnodes AS $rid=>$rootnode) {
$nodeSet = $nodeSet+$this->getBranch($rootnode, true);
}
return $nodeSet;
}
 
if (!$this->_caching) {
$nodeSet = $this->_processResultSet($sql, $keepAsArray, $aliasFields);
} else {
$nodeSet = $this->cache->call('DB_NestedSet->_processResultSet', $sql, $keepAsArray, $aliasFields);
}
 
if (!$this->_skipCallbacks && isset($this->_hasListeners['nodeLoad'])) {
// EVENT (nodeLoad)
foreach (array_keys($nodeSet) as $key) {
$this->triggerEvent('nodeLoad', $nodeSet[$key]);
}
}
return $nodeSet;
}
 
// }}}
// {{{ getRootNodes()
 
/**
* Fetches the first level (the rootnodes) of the NestedSet
*
* @param bool $keepAsArray (optional) Keep the result as an array or transform it into
* a set of DB_NestedSet_Node objects?
* @param bool $aliasFields (optional) Should we alias the fields so they are the names
* of the parameter keys, or leave them as is?
* @param array $addSQL (optional) Array of additional params to pass to the query.
*
* @see _addSQL()
* @access public
* @return mixed False on error, or an array of nodes
*/
function getRootNodes($keepAsArray = false, $aliasFields = true, $addSQL = array()) {
if ($this->debug) {
$this->_debugMessage('getRootNodes()');
}
$sql = sprintf('SELECT %s %s FROM %s %s WHERE %s.%s=%s.%s %s ORDER BY %s.%s ASC',
$this->_getSelectFields($aliasFields),
$this->_addSQL($addSQL, 'cols'),
$this->node_table,
$this->_addSQL($addSQL, 'join'),
$this->node_table,
$this->_flparams['id'],
$this->node_table,
$this->_flparams['rootid'],
$this->_addSQL($addSQL, 'append'),
$this->node_table,
$this->secondarySort);
 
if (!$this->_caching) {
$nodeSet = $this->_processResultSet($sql, $keepAsArray, $aliasFields);
} else {
$nodeSet = $this->cache->call('DB_NestedSet->_processResultSet', $sql, $keepAsArray, $aliasFields);
}
 
if (!$this->_skipCallbacks && isset($this->_hasListeners['nodeLoad'])) {
// EVENT (nodeLoad)
foreach (array_keys($nodeSet) as $key) {
$this->triggerEvent('nodeLoad', $nodeSet[$key]);
}
}
return $nodeSet;
}
 
// }}}
 
// {{{ getBranch()
 
/**
* Fetch the whole branch where a given node id is in
*
* @param int $id The node ID
* @param bool $keepAsArray (optional) Keep the result as an array or transform it into
* a set of DB_NestedSet_Node objects?
* @param bool $aliasFields (optional) Should we alias the fields so they are the names
* of the parameter keys, or leave them as is?
* @param array $addSQL (optional) Array of additional params to pass to the query.
*
* @see _addSQL()
* @access public
* @return mixed False on error, or an array of nodes
*/
function getBranch($id, $keepAsArray = false, $aliasFields = true, $addSQL = array()) {
if ($this->debug) {
$this->_debugMessage('getBranch($id)');
}
if (!($thisnode = $this->pickNode($id, true))) {
$epr = array('getBranch()', $id);
return $this->_raiseError(NESE_ERROR_NOT_FOUND, PEAR_ERROR_TRIGGER, E_USER_NOTICE, $epr);
}
if($this->_sortMode == NESE_SORT_LEVEL) {
$firstsort = $this->_flparams['level'];
$sql = sprintf('SELECT %s %s FROM %s %s WHERE %s.%s=%s %s ORDER BY %s.%s, %s.%s ASC',
$this->_getSelectFields($aliasFields),
$this->_addSQL($addSQL, 'cols'),
$this->node_table,
$this->_addSQL($addSQL, 'join'),
$this->node_table,
$this->_flparams['rootid'],
$thisnode['rootid'],
$this->_addSQL($addSQL, 'append'),
$this->node_table,
$firstsort,
$this->node_table,
$this->secondarySort);
} elseif($this->_sortMode == NESE_SORT_PREORDER) {
$firstsort = $this->_flparams['l'];
$sql = sprintf('SELECT %s %s FROM %s %s WHERE %s.%s=%s %s ORDER BY %s.%s ASC',
$this->_getSelectFields($aliasFields),
$this->_addSQL($addSQL, 'cols'),
$this->node_table,
$this->_addSQL($addSQL, 'join'),
$this->node_table,
$this->_flparams['rootid'],
$thisnode['rootid'],
$this->_addSQL($addSQL, 'append'),
$this->node_table,
$firstsort);
}
 
 
if (!$this->_caching) {
$nodeSet = $this->_processResultSet($sql, $keepAsArray, $aliasFields);
} else {
$nodeSet = $this->cache->call('DB_NestedSet->_processResultSet', $sql, $keepAsArray, $aliasFields);
}
 
if (!$this->_skipCallbacks && isset($this->_hasListeners['nodeLoad'])) {
// EVENT (nodeLoad)
foreach (array_keys($nodeSet) as $key) {
$this->triggerEvent('nodeLoad', $nodeSet[$key]);
}
}
if($this->_sortMode == NESE_SORT_PREORDER && ($this->params[$this->secondarySort] != $this->_defaultSecondarySort)) {
uasort($nodeSet, array($this, '_secSort'));
}
return $nodeSet;
}
 
// }}}
// {{{ getParents()
 
/**
* Fetch the parents of a node given by id
*
* @param int $id The node ID
* @param bool $keepAsArray (optional) Keep the result as an array or transform it into
* a set of DB_NestedSet_Node objects?
* @param bool $aliasFields (optional) Should we alias the fields so they are the names
* of the parameter keys, or leave them as is?
* @param array $addSQL (optional) Array of additional params to pass to the query.
*
* @see _addSQL()
* @access public
* @return mixed False on error, or an array of nodes
*/
function getParents($id, $keepAsArray = false, $aliasFields = true, $addSQL = array()) {
if ($this->debug) {
$this->_debugMessage('getParents($id)');
}
if (!($child = $this->pickNode($id, true))) {
$epr = array('getParents()', $id);
return $this->_raiseError(NESE_ERROR_NOT_FOUND, PEAR_ERROR_TRIGGER, E_USER_NOTICE, $epr);
}
 
$sql = sprintf('SELECT %s %s FROM %s %s
WHERE %s.%s=%s AND %s.%s<%s AND %s.%s<%s AND %s.%s>%s %s
ORDER BY %s.%s ASC',
$this->_getSelectFields($aliasFields),
$this->_addSQL($addSQL, 'cols'),
$this->node_table,
$this->_addSQL($addSQL, 'join'),
$this->node_table,
$this->_flparams['rootid'],
$child['rootid'],
$this->node_table,
$this->_flparams['level'],
$child['level'],
$this->node_table,
$this->_flparams['l'],
$child['l'],
$this->node_table,
$this->_flparams['r'],
$child['r'],
$this->_addSQL($addSQL, 'append'),
$this->node_table,
$this->_flparams['level']);
 
if (!$this->_caching) {
$nodeSet = $this->_processResultSet($sql, $keepAsArray, $aliasFields);
} else {
$nodeSet = $this->cache->call('DB_NestedSet->_processResultSet', $sql, $keepAsArray, $aliasFields);
}
 
if (!$this->_skipCallbacks && isset($this->_hasListeners['nodeLoad'])) {
// EVENT (nodeLoad)
foreach (array_keys($nodeSet) as $key) {
$this->triggerEvent('nodeLoad', $nodeSet[$key]);
}
}
return $nodeSet;
}
 
// }}}
// {{{ getParent()
 
/**
* Fetch the immediate parent of a node given by id
*
* @param int $id The node ID
* @param bool $keepAsArray (optional) Keep the result as an array or transform it into
* a set of DB_NestedSet_Node objects?
* @param bool $aliasFields (optional) Should we alias the fields so they are the names
* of the parameter keys, or leave them as is?
* @param array $addSQL (optional) Array of additional params to pass to the query.
*
* @see _addSQL()
* @access public
* @return mixed False on error, or the parent node
*/
function getParent($id, $keepAsArray = false, $aliasFields = true, $addSQL = array()) {
if ($this->debug) {
$this->_debugMessage('getParent($id)');
}
if (!($child = $this->pickNode($id, true))) {
$epr = array('getParent()', $id);
return $this->_raiseError(NESE_ERROR_NOT_FOUND, PEAR_ERROR_TRIGGER, E_USER_NOTICE, $epr);
}
 
if($child['id'] == $child['rootid']) {
return false;
}
 
// If parent node is set inside the db simply return it
if(isset($child['parent']) && !empty($child['parent'])) {
return $this->pickNode($child['parent'], $keepAsArray, $aliasFields, 'id', $addSQL);
}
 
$addSQL['append'] = sprintf('AND %s.%s = %s',
$this->node_table,
$this->_flparams['level'],
$child['level']-1);
 
$nodeSet = $this->getParents($id, $keepAsArray, $aliasFields, $addSQL);
 
if(!empty($nodeSet)) {
$keys = array_keys($nodeSet);
return $nodeSet[$keys[0]];
} else {
return false;
}
}
 
// }}}
// {{{ getSiblings)
 
/**
* Fetch all siblings of the node given by id
* Important: The node given by ID will also be returned
* Do a unset($array[$id]) on the result if you don't want that
*
* @param int $id The node ID
* @param bool $keepAsArray (optional) Keep the result as an array or transform it into
* a set of DB_NestedSet_Node objects?
* @param bool $aliasFields (optional) Should we alias the fields so they are the names
* of the parameter keys, or leave them as is?
* @param array $addSQL (optional) Array of additional params to pass to the query.
*
* @see _addSQL()
* @access public
* @return mixed False on error, or the parent node
*/
function getSiblings($id, $keepAsArray = false, $aliasFields = true, $addSQL = array()) {
if ($this->debug) {
$this->_debugMessage('getParents($id)');
}
 
if (!($sibling = $this->pickNode($id, true))) {
$epr = array('getSibling()', $id);
return $this->_raiseError(NESE_ERROR_NOT_FOUND, PEAR_ERROR_TRIGGER, E_USER_NOTICE, $epr);
}
 
$parent = $this->getParent($sibling, true);
 
return $this->getChildren($parent, $keepAsArray, $aliasFields, $addSQL);
}
 
// }}}
// {{{ getChildren()
 
/**
* Fetch the children _one level_ after of a node given by id
*
* @param int $id The node ID
* @param bool $keepAsArray (optional) Keep the result as an array or transform it into
* a set of DB_NestedSet_Node objects?
* @param bool $aliasFields (optional) Should we alias the fields so they are the names
* of the parameter keys, or leave them as is?
* @param bool $forceNorder (optional) Force the result to be ordered by the norder
* param (as opposed to the value of secondary sort). Used by the move and
* add methods.
* @param array $addSQL (optional) Array of additional params to pass to the query.
*
* @see _addSQL()
* @access public
* @return mixed False on error, or an array of nodes
*/
function getChildren($id, $keepAsArray = false, $aliasFields = true, $forceNorder = false, $addSQL = array()) {
if ($this->debug) {
$this->_debugMessage('getChildren($id)');
}
 
if (!($parent = $this->pickNode($id, true))) {
$epr = array('getChildren()', $id);
return $this->_raiseError(NESE_ERROR_NOT_FOUND, PEAR_ERROR_TRIGGER, E_USER_NOTICE, $epr);
}
if (!$parent || $parent['l'] == ($parent['r'] - 1)) {
return false;
}
 
$sql = sprintf('SELECT %s %s FROM %s %s
WHERE %s.%s=%s AND %s.%s=%s+1 AND %s.%s BETWEEN %s AND %s %s
ORDER BY %s.%s ASC',
$this->_getSelectFields($aliasFields),
$this->_addSQL($addSQL, 'cols'),
$this->node_table,
$this->_addSQL($addSQL, 'join'),
$this->node_table,
$this->_flparams['rootid'],
$parent['rootid'],
$this->node_table,
$this->_flparams['level'],
$parent['level'],
$this->node_table,
$this->_flparams['l'],
$parent['l'],
$parent['r'],
$this->_addSQL($addSQL, 'append'),
$this->node_table,
$this->secondarySort);
 
if (!$this->_caching) {
$nodeSet = $this->_processResultSet($sql, $keepAsArray, $aliasFields);
} else {
$nodeSet = $this->cache->call('DB_NestedSet->_processResultSet', $sql, $keepAsArray, $aliasFields);
}
 
if (!$this->_skipCallbacks && isset($this->_hasListeners['nodeLoad'])) {
// EVENT (nodeLoad)
foreach (array_keys($nodeSet) as $key) {
$this->triggerEvent('nodeLoad', $nodeSet[$key]);
}
}
return $nodeSet;
}
 
// }}}
// {{{ getSubBranch()
 
/**
* Fetch all the children of a node given by id
*
* getChildren only queries the immediate children
* getSubBranch returns all nodes below the given node
*
* @param string $id The node ID
* @param bool $keepAsArray (optional) Keep the result as an array or transform it into
* a set of DB_NestedSet_Node objects?
* @param bool $aliasFields (optional) Should we alias the fields so they are the names
* of the parameter keys, or leave them as is?
* @param array $addSQL (optional) Array of additional params to pass to the query.
*
* @see _addSQL()
* @access public
* @return mixed False on error, or an array of nodes
*/
function getSubBranch($id, $keepAsArray = false, $aliasFields = true, $addSQL = array()) {
 
if ($this->debug) {
$this->_debugMessage('getSubBranch($id)');
}
if (!($parent = $this->pickNode($id, true))) {
$epr = array('getSubBranch()', $id);
return $this->_raiseError(NESE_ERROR_NOT_FOUND, E_USER_NOTICE, $epr);
}
if($this->_sortMode == NESE_SORT_LEVEL) {
$firstsort = $this->_flparams['level'];
$sql = sprintf('SELECT %s %s FROM %s %s WHERE %s.%s BETWEEN %s AND %s AND %s.%s=%s AND %s.%s!=%s %s ORDER BY %s.%s, %s.%s ASC',
$this->_getSelectFields($aliasFields),
$this->_addSQL($addSQL, 'cols'),
$this->node_table,
$this->_addSQL($addSQL, 'join'),
$this->node_table,
$this->_flparams['l'],
$parent['l'],
$parent['r'],
$this->node_table,
$this->_flparams['rootid'],
$parent['rootid'],
$this->node_table,
$this->_flparams['id'],
$this->_addSQL($addSQL, 'append'),
$id,
$this->node_table,
$firstsort,
$this->node_table,
$this->secondarySort
);
} elseif($this->_sortMode == NESE_SORT_PREORDER) {
$firstsort = $this->_flparams['l'];
$firstsort = $this->_flparams['level'];
$sql = sprintf('SELECT %s %s FROM %s %s WHERE %s.%s BETWEEN %s AND %s AND %s.%s=%s AND %s.%s!=%s %s ORDER BY %s.%s ASC',
$this->_getSelectFields($aliasFields),
$this->_addSQL($addSQL, 'cols'),
$this->node_table,
$this->_addSQL($addSQL, 'join'),
$this->node_table,
$this->_flparams['l'],
$parent['l'],
$parent['r'],
$this->node_table,
$this->_flparams['rootid'],
$parent['rootid'],
$this->node_table,
$this->_flparams['id'],
$this->_addSQL($addSQL, 'append'),
$id,
$this->node_table,
$firstsort
);
}
 
if (!$this->_caching) {
$nodeSet = $this->_processResultSet($sql, $keepAsArray, $aliasFields);
} else {
$nodeSet = $this->cache->call('DB_NestedSet->_processResultSet', $sql, $keepAsArray, $aliasFields);
}
 
if (!$this->_skipCallbacks && isset($this->_hasListeners['nodeLoad'])) {
// EVENT (nodeLoad)
foreach (array_keys($nodeSet) as $key) {
$this->triggerEvent('nodeLoad', $nodeSet[$key]);
}
}
if($this->params[$this->secondarySort] != $this->_defaultSecondarySort) {
uasort($nodeSet, array($this, '_secSort'));
}
return $nodeSet;
}
 
// }}}
// {{{ pickNode()
 
/**
* Fetch the data of a node with the given id
*
* @param int $id The node id of the node to fetch
* @param bool $keepAsArray (optional) Keep the result as an array or transform it into
* a set of DB_NestedSet_Node objects?
* @param bool $aliasFields (optional) Should we alias the fields so they are the names
* of the parameter keys, or leave them as is?
* @param string $idfield (optional) Which field has to be compared with $id?
* This is can be used to pick a node by other values (e.g. it's name).
* @param array $addSQL (optional) Array of additional params to pass to the query.
*
* @see _addSQL()
* @access public
* @return mixed False on error, or an array of nodes
*/
function pickNode($id, $keepAsArray = false, $aliasFields = true, $idfield = 'id', $addSQL = array()) {
if ($this->debug) {
$this->_debugMessage('pickNode($id)');
}
 
if (is_object($id) && $id->id) {
return $id;
} elseif (is_array($id) && isset($id['id'])) {
return $id;
}
 
if(!$id) {
return false;
}
 
$sql = sprintf('SELECT %s %s FROM %s %s WHERE %s.%s=%s %s',
$this->_getSelectFields($aliasFields),
$this->_addSQL($addSQL, 'cols'),
$this->node_table,
$this->_addSQL($addSQL, 'join'),
$this->node_table,
$this->_flparams[$idfield],
$id,
$this->_addSQL($addSQL, 'append'));
 
if (!$this->_caching) {
$nodeSet = $this->_processResultSet($sql, $keepAsArray, $aliasFields);
} else {
$nodeSet = $this->cache->call('DB_NestedSet->_processResultSet', $sql, $keepAsArray, $aliasFields);
}
 
$nsKey = false;
 
if (!$this->_skipCallbacks && isset($this->_hasListeners['nodeLoad'])) {
// EVENT (nodeLoad)
foreach (array_keys($nodeSet) as $key) {
$this->triggerEvent('nodeLoad', $nodeSet[$key]);
$nsKey = $key;
}
} else {
foreach (array_keys($nodeSet) as $key) {
$nsKey = $key;
}
}
 
if (is_array($nodeSet) && $idfield != 'id') {
$id = $nsKey;
}
 
return isset($nodeSet[$id]) ? $nodeSet[$id] : false;
}
 
// }}}
// {{{ isParent()
 
/**
* See if a given node is a parent of another given node
*
* A node is considered to be a parent if it resides above the child
* So it doesn't mean that the node has to be an immediate parent.
* To get this information simply compare the levels of the two nodes
* after you know that you have a parent relation.
*
* @param mixed $parent The parent node as array or object
* @param mixed $child The child node as array or object
*
* @access public
* @return bool True if it's a parent
*/
function isParent($parent, $child) {
 
if ($this->debug) {
$this->_debugMessage('isParent($parent, $child)');
}
 
if (!isset($parent)|| !isset($child)) {
return false;
}
 
if (is_array($parent)) {
$p_rootid = $parent['rootid'];
$p_l = $parent['l'];
$p_r = $parent['r'];
 
} elseif (is_object($parent)) {
$p_rootid = $parent->rootid;
$p_l = $parent->l;
$p_r = $parent->r;
}
 
if (is_array($child)) {
$c_rootid = $child['rootid'];
$c_l = $child['l'];
$c_r = $child['r'];
} elseif (is_object($child)) {
$c_rootid = $child->rootid;
$c_l = $child->l;
$c_r = $child->r;
}
 
if (($p_rootid == $c_rootid) && ($p_l < $c_l && $p_r > $c_r)) {
return true;
}
 
return false;
}
 
 
// }}}
// +----------------------------------------------+
// | NestedSet manipulation and query methods |
// |----------------------------------------------+
// | insert / delete / update of nodes |
// +----------------------------------------------+
// | [PUBLIC] |
// +----------------------------------------------+
// {{{ createRootNode()
 
/**
* Creates a new root node
* Optionally it deletes the whole tree and creates one initial rootnode
*
* <pre>
* +-- root1 [target]
* |
* +-- root2 [new]
* |
* +-- root3
* </pre>
*
* @param array $values Hash with param => value pairs of the node (see $this->params)
* @param integer $id ID of target node (the rootnode after which the node should be inserted)
* @param bool $first Danger: Deletes and (re)init's the hole tree - sequences are reset
*
* @access public
* @return mixed The node id or false on error
*/
function createRootNode($values, $id = false, $first = false, $_pos = 'AF') {
 
if ($this->debug) {
$this->_debugMessage('createRootNode($values, $id = false, $first = false, $_pos = \'AF\')');
}
 
$this->_verifyUserValues('createRootNode()', $values);
 
if(!$first && (!$id || !$parent = $this->pickNode($id, true))) {
$epr = array('createRootNode()', $id);
return $this->_raiseError(NESE_ERROR_NOT_FOUND, PEAR_ERROR_TRIGGER, E_USER_ERROR, $epr);
} elseif($first && $id) {
 
// No notice for now.
// But tehese 2 params don't make sense together
$epr = array(
'createRootNode()',
'[id] AND [first] were passed - that doesn\'t make sense');
//$this->_raiseError(NESE_ERROR_WRONG_MPARAM, E_USER_WARNING, $epr);
}
 
// Try to aquire a table lock
if(PEAR::isError($lock=$this->_setLock())) {
return $lock;
}
 
$sql = array();
$addval = array();
$addval[$this->_flparams['level']] = 1;
 
// Shall we delete the existing tree (reinit)
if ($first) {
$dsql = sprintf('DELETE FROM %s',
$this->node_table);
$this->db->query($dsql);
$this->db->dropSequence($this->sequence_table);
// New order of the new node will be 1
$addval[$this->_flparams['norder']] = 1;
} else {
// Let's open a gap for the new node
if($_pos == NESE_MOVE_AFTER) {
$addval[$this->_flparams['norder']] = $parent['norder'] + 1;
$sql[] = sprintf('UPDATE %s SET %s=%s+1 WHERE %s=%s AND %s > %s',
$this->node_table,
$this->_flparams['norder'],
$this->_flparams['norder'],
$this->_flparams['id'],
$this->_flparams['rootid'],
$this->_flparams['norder'],
$parent['norder']);
} elseif($_pos == NESE_MOVE_BEFORE) {
$addval[$this->_flparams['norder']] = $parent['norder'];
$sql[] = sprintf('UPDATE %s SET %s=%s+1 WHERE %s=%s AND %s >= %s',
$this->node_table,
$this->_flparams['norder'],
$this->_flparams['norder'],
$this->_flparams['id'],
$this->_flparams['rootid'],
$this->_flparams['norder'],
$parent['norder']);
}
}
 
if(isset($this->_flparams['parent'])) {
$addval[$this->_flparams['parent']] = 0;
}
// Sequence of node id (equals to root id in this case
 
if(!$this->_dumbmode || !$node_id=isset($values[$this->_flparams['id']]) || !isset($values[$this->_flparams['rootid']])) {
$addval[$this->_flparams['rootid']] = $node_id = $addval[$this->_flparams['id']] = $this->db->nextId($this->sequence_table);
} else {
$node_id = $values[$this->_flparams['id']];
}
// Left/Right values for rootnodes
$addval[$this->_flparams['l']] = 1;
$addval[$this->_flparams['r']] = 2;
// Transform the node data hash to a query
if (!$qr = $this->_values2Query($values, $addval)) {
$this->_releaseLock();
return false;
}
 
// Insert the new node
$sql[] = sprintf('INSERT INTO %s SET %s',
$this->node_table,
$qr);
 
for($i=0;$i<count($sql);$i++) {
$res = $this->db->query($sql[$i]);
$this->_testFatalAbort($res, __FILE__, __LINE__);
}
 
// EVENT (nodeCreate)
 
if (!$this->_skipCallbacks && isset($this->_hasListeners['nodeCreate'])) {
$this->triggerEvent('nodeCreate', $this->pickNode($node_id));
}
$this->_releaseLock();
return $node_id;
}
 
// }}}
// {{{ createSubNode()
 
/**
* Creates a subnode
*
* <pre>
* +-- root1
* |
* +-\ root2 [target]
* | |
* | |-- subnode1 [new]
* |
* +-- root3
* </pre>
*
* @param integer $id Parent node ID
* @param array $values Hash with param => value pairs of the node (see $this->params)
*
* @access public
* @return mixed The node id or false on error
*/
function createSubNode($id, $values) {
if ($this->debug) {
$this->_debugMessage('createSubNode($id, $values)');
}
 
// invalid parent id, bail out
if (!($thisnode = $this->pickNode($id, true))) {
$epr = array('createSubNode()', $id);
return $this->_raiseError(NESE_ERROR_NOT_FOUND, PEAR_ERROR_TRIGGER, E_USER_ERROR, $epr);
}
 
// Try to aquire a table lock
if(PEAR::isError($lock = $this->_setLock())) {
return $lock;
}
 
$this->_verifyUserValues('createRootNode()', $values);
 
// Get the children of the target node
$children = $this->getChildren($id, true);
 
// We have children here
if ($thisnode['r']-1 != $thisnode['l']) {
// Get the last child
$last = array_pop($children);
// What we have to do is virtually an insert of a node after the last child
// So we don't have to proceed creating a subnode
$newNode = $this->createRightNode($last['id'], $values);
$this->_releaseLock();
return $newNode;
}
 
$sql = array();
$sql[] = sprintf('
UPDATE %s SET
%s=IF(%s>=%s, %s+2, %s),
%s=IF(%s>=%s, %s+2, %s)
WHERE %s=%s',
$this->node_table,
$this->_flparams['l'],
$this->_flparams['l'],
$thisnode['r'],
$this->_flparams['l'],
$this->_flparams['l'],
$this->_flparams['r'],
$this->_flparams['r'],
$thisnode['r'],
$this->_flparams['r'],
$this->_flparams['r'],
$this->_flparams['rootid'],
$thisnode['rootid']
);
 
$addval = array();
if(isset($this->_flparams['parent'])) {
$addval[$this->_flparams['parent']] = $thisnode['id'];
}
 
$addval[$this->_flparams['l']] = $thisnode['r'];
$addval[$this->_flparams['r']] = $thisnode['r'] + 1;
$addval[$this->_flparams['rootid']] = $thisnode['rootid'];
$addval[$this->_flparams['norder']] = 1;
$addval[$this->_flparams['level']] = $thisnode['level'] + 1;
 
if(!$this->_dumbmode || !$node_id=isset($values[$this->_flparams['id']])) {
$node_id = $addval[$this->_flparams['id']] = $this->db->nextId($this->sequence_table);
} else {
$node_id = $values[$this->_flparams['id']];
}
if (!$qr = $this->_values2Query($values, $addval)) {
$this->_releaseLock();
return false;
}
 
$sql[] = sprintf('INSERT INTO %s SET %s',
$this->node_table,
$qr);
for($i=0;$i<count($sql);$i++) {
$res = $this->db->query($sql[$i]);
$this->_testFatalAbort($res, __FILE__, __LINE__);
}
 
// EVENT (NodeCreate)
if (!$this->_skipCallbacks && isset($this->_hasListeners['nodeCreate'])) {
$thisnode = $this->pickNode($node_id);
$this->triggerEvent('nodeCreate', $this->pickNode($id));
}
$this->_releaseLock();
return $node_id;
}
 
// }}}
// {{{ createLeftNode()
/**
* Creates a node before a given node
* <pre>
* +-- root1
* |
* +-\ root2
* | |
* | |-- subnode2 [new]
* | |-- subnode1 [target]
* | |-- subnode3
* |
* +-- root3
* </pre>
*
* @param int $id Target node ID
* @param array $values Hash with param => value pairs of the node (see $this->params)
* @param bool $returnID Tell the method to return a node id instead of an object.
* ATTENTION: That the method defaults to return an object instead of the node id
* has been overseen and is basically a bug. We have to keep this to maintain BC.
* You will have to set $returnID to true to make it behave like the other creation methods.
* This flaw will get fixed with the next major version.
*
* @access public
* @return mixed The node id or false on error
*/
function createLeftNode($id, $values) {
 
if ($this->debug) {
$this->_debugMessage('createLeftNode($target, $values)');
}
 
$this->_verifyUserValues('createLeftode()', $values);
 
// invalid target node, bail out
if (!($thisnode = $this->pickNode($id, true))) {
$epr = array('createLeftNode()', $id);
return $this->_raiseError(NESE_ERROR_NOT_FOUND, PEAR_ERROR_TRIGGER, E_USER_ERROR, $epr);
}
 
if(PEAR::isError($lock=$this->_setLock())) {
return $lock;
}
 
 
// If the target node is a rootnode we virtually want to create a new root node
if ($thisnode['rootid'] == $thisnode['id']) {
return $this->createRootNode($values, $id, false, NESE_MOVE_BEFORE);
}
 
 
$addval = array();
$parent = $this->getParent($id, true);
if(isset($this->_flparams['parent'])) {
$addval[$this->_flparams['parent']] = $parent['id'];
}
 
$sql = array();
 
 
$sql[] = sprintf('UPDATE %s SET %s=%s+1
WHERE
%s=%s AND %s>=%s AND %s=%s AND %s BETWEEN %s AND %s',
$this->node_table,
$this->_flparams['norder'],
$this->_flparams['norder'],
$this->_flparams['rootid'],
$thisnode['rootid'],
$this->_flparams['norder'],
$thisnode['norder'],
$this->_flparams['level'],
$thisnode['level'],
$this->_flparams['l'],
$parent['l'],
$parent['r']);
 
 
// Update all nodes which have dependent left and right values
$sql[] = sprintf('
UPDATE %s SET
%s=IF(%s>=%s, %s+2, %s),
%s=IF(%s>=%s, %s+2, %s)
WHERE %s=%s',
$this->node_table,
$this->_flparams['l'],
$this->_flparams['l'],
$thisnode['l'],
$this->_flparams['l'],
$this->_flparams['l'],
$this->_flparams['r'],
$this->_flparams['r'],
$thisnode['r'],
$this->_flparams['r'],
$this->_flparams['r'],
$this->_flparams['rootid'],
$thisnode['rootid']
);
 
 
 
$addval[$this->_flparams['norder']] = $thisnode['norder'];
$addval[$this->_flparams['l']] = $thisnode['l'];
$addval[$this->_flparams['r']] = $thisnode['l']+1;
$addval[$this->_flparams['rootid']] = $thisnode['rootid'];
$addval[$this->_flparams['level']] = $thisnode['level'];
 
if(!$this->_dumbmode || !$node_id=isset($values[$this->_flparams['id']])) {
$node_id = $addval[$this->_flparams['id']] = $this->db->nextId($this->sequence_table);
} else {
$node_id = $values[$this->_flparams['id']];
}
if (!$qr = $this->_values2Query($values, $addval)) {
$this->_releaseLock();
return false;
}
 
// Insert the new node
$sql[] = sprintf('INSERT INTO %s SET %s',
$this->node_table,
$qr);
 
for($i=0;$i<count($sql);$i++) {
$res = $this->db->query($sql[$i]);
$this->_testFatalAbort($res, __FILE__, __LINE__);
}
 
// EVENT (NodeCreate)
if (!$this->_skipCallbacks && isset($this->_hasListeners['nodeCreate'])) {
$this->triggerEvent('nodeCreate', $this->pickNode($id));
}
$this->_releaseLock();
return $node_id;
}
 
/**
* Creates a node after a given node
* <pre>
* +-- root1
* |
* +-\ root2
* | |
* | |-- subnode1 [target]
* | |-- subnode2 [new]
* | |-- subnode3
* |
* +-- root3
* </pre>
*
* @param int $id Target node ID
* @param array $values Hash with param => value pairs of the node (see $this->params)
* @param bool $returnID Tell the method to return a node id instead of an object.
* ATTENTION: That the method defaults to return an object instead of the node id
* has been overseen and is basically a bug. We have to keep this to maintain BC.
* You will have to set $returnID to true to make it behave like the other creation methods.
* This flaw will get fixed with the next major version.
*
* @access public
* @return mixed The node id or false on error
*/
function createRightNode($id, $values) {
 
if ($this->debug) {
$this->_debugMessage('createRightNode($target, $values)');
}
 
$this->_verifyUserValues('createRootNode()', $values);
 
// invalid target node, bail out
if (!($thisnode = $this->pickNode($id, true))) {
$epr = array('createRightNode()', $id);
return $this->_raiseError(NESE_ERROR_NOT_FOUND, PEAR_ERROR_TRIGGER, E_USER_ERROR, $epr);
}
 
if(PEAR::isError($lock=$this->_setLock())) {
return $lock;
}
 
 
// If the target node is a rootnode we virtually want to create a new root node
if ($thisnode['rootid'] == $thisnode['id']) {
 
$nid = $this->createRootNode($values, $id);
$this->_releaseLock();
return $nid;
}
 
 
$addval = array();
$parent = $this->getParent($id, true);
if(isset($this->_flparams['parent'])) {
$addval[$this->_flparams['parent']] = $parent['id'];
}
 
$sql = array();
 
$sql[] = sprintf('UPDATE %s SET %s=%s+1
WHERE
%s=%s AND %s>%s AND %s=%s AND %s BETWEEN %s AND %s',
$this->node_table,
$this->_flparams['norder'],
$this->_flparams['norder'],
$this->_flparams['rootid'],
$thisnode['rootid'],
$this->_flparams['norder'],
$thisnode['norder'],
$this->_flparams['level'],
$thisnode['level'],
$this->_flparams['l'],
$parent['l'],
$parent['r']);
 
 
// Update all nodes which have dependent left and right values
 
 
$sql[] = sprintf('
UPDATE %s SET
%s=IF(%s>%s, %s+2, %s),
%s=IF(%s>%s, %s+2, %s)
WHERE %s=%s',
$this->node_table,
$this->_flparams['l'],
$this->_flparams['l'],
$thisnode['r'],
$this->_flparams['l'],
$this->_flparams['l'],
$this->_flparams['r'],
$this->_flparams['r'],
$thisnode['r'],
$this->_flparams['r'],
$this->_flparams['r'],
$this->_flparams['rootid'],
$thisnode['rootid']
);
 
$addval[$this->_flparams['norder']] = $thisnode['norder'] + 1;
$addval[$this->_flparams['l']] = $thisnode['r'] + 1;
$addval[$this->_flparams['r']] = $thisnode['r'] + 2;
$addval[$this->_flparams['rootid']] = $thisnode['rootid'];
$addval[$this->_flparams['level']] = $thisnode['level'];
 
if(!$this->_dumbmode || !isset($values[$this->_flparams['id']])) {
$node_id = $addval[$this->_flparams['id']] = $this->db->nextId($this->sequence_table);
} else {
$node_id = $values[$this->_flparams['id']];
}
if (!$qr = $this->_values2Query($values, $addval)) {
$this->_releaseLock();
return false;
}
 
// Insert the new node
$sql[] = sprintf('INSERT INTO %s SET %s', $this->node_table, $qr);
 
for($i=0;$i<count($sql);$i++) {
$res = $this->db->query($sql[$i]);
$this->_testFatalAbort($res, __FILE__, __LINE__);
}
 
// EVENT (NodeCreate)
if (!$this->_skipCallbacks && isset($this->_hasListeners['nodeCreate'])) {
$this->triggerEvent('nodeCreate', $this->pickNode($id));
}
$this->_releaseLock();
return $node_id;
}
 
// }}}
// {{{ deleteNode()
 
/**
* Deletes a node
*
* @param int $id ID of the node to be deleted
*
* @access public
* @return bool True if the delete succeeds
*/
function deleteNode($id) {
 
if ($this->debug) {
$this->_debugMessage("deleteNode($id)");
}
 
// invalid target node, bail out
if (!($thisnode = $this->pickNode($id, true))) {
$epr = array('deleteNode()', $id);
return $this->_raiseError(NESE_ERROR_NOT_FOUND, PEAR_ERROR_TRIGGER, E_USER_ERROR, $epr);
}
 
if (PEAR::isError($lock = $this->_setLock())) {
return $lock;
}
 
if (!$this->_skipCallbacks && isset($this->_hasListeners['nodeDelete'])) {
// EVENT (NodeDelete)
$this->triggerEvent('nodeDelete', $this->pickNode($id));
}
 
$parent = $this->getParent($id, true);
$len = $thisnode['r'] - $thisnode['l'] + 1;
 
 
$sql = array();
 
// Delete the node
$sql[] = sprintf('DELETE FROM %s WHERE %s BETWEEN %s AND %s AND %s=%s',
$this->node_table,
$this->_flparams['l'],
$thisnode['l'],
$thisnode['r'],
$this->_flparams['rootid'],
$thisnode['rootid']
);
 
if ($thisnode['id'] != $thisnode['rootid']) {
 
// The node isn't a rootnode so close the gap
$sql[] = sprintf('UPDATE %s SET
%s=IF(%s>%s, %s-%s, %s),
%s=IF(%s>%s, %s-%s, %s)
WHERE %s=%s AND
(%s>%s OR %s>%s)',
$this->node_table,
$this->_flparams['l'],
$this->_flparams['l'],
$thisnode['l'],
$this->_flparams['l'],
$len,
$this->_flparams['l'],
$this->_flparams['r'],
$this->_flparams['r'],
$thisnode['l'],
$this->_flparams['r'],
$len,
$this->_flparams['r'],
$this->_flparams['rootid'],
$thisnode['rootid'],
$this->_flparams['l'],
$thisnode['l'],
$this->_flparams['r'],
$thisnode['r']
);
 
// Re-order
 
$sql[] = sprintf('UPDATE %s SET %s=%s-1 WHERE %s=%s AND %s=%s AND %s>%s AND %s BETWEEN %s AND %s',
$this->node_table,
$this->_flparams['norder'],
$this->_flparams['norder'],
$this->_flparams['rootid'],
$thisnode['rootid'],
$this->_flparams['level'],
$thisnode['level'],
$this->_flparams['norder'],
$thisnode['norder'],
$this->_flparams['l'],
$parent['l'],
$parent['r']);
 
} else {
// A rootnode was deleted and we only have to close the gap inside the order
$sql[] = sprintf('UPDATE %s SET %s=%s+1 WHERE %s=%s AND %s > %s',
$this->node_table,
$this->_flparams['norder'],
$this->_flparams['norder'],
$this->_flparams['rootid'],
$this->_flparams['id'],
$this->_flparams['norder'],
$thisnode['norder']);
}
for($i=0;$i<count($sql);$i++) {
$res = $this->db->query($sql[$i]);
$this->_testFatalAbort($res, __FILE__, __LINE__);
}
$this->_releaseLock();
return true;
}
 
// }}}
// {{{ updateNode()
 
/**
* Changes the payload of a node
*
* @param int $id Node ID
* @param array $values Hash with param => value pairs of the node (see $this->params)
* @param bool $_intermal Internal use only. Used to skip value validation. Leave this as it is.
*
* @access public
* @return bool True if the update is successful
*/
function updateNode($id, $values, $_internal=false) {
if ($this->debug) {
$this->_debugMessage('updateNode($id, $values)');
}
 
if (PEAR::isError($lock = $this->_setLock())) {
return $lock;
}
 
if(!$_internal) {
$this->_verifyUserValues('createRootNode()', $values);
}
 
$eparams = array('values' => $values);
if (!$this->_skipCallbacks && isset($this->_hasListeners['nodeUpdate'])) {
// EVENT (NodeUpdate)
$this->triggerEvent('nodeUpdate', $this->pickNode($id), $eparams);
}
 
$addvalues = array();
if (!$qr = $this->_values2Query($values, $addvalues)) {
$this->_releaseLock();
return false;
}
 
$sql = sprintf('UPDATE %s SET %s WHERE %s = %s',
$this->node_table,
$qr,
$this->_flparams['id'],
$id);
$res = $this->db->query($sql);
$this->_testFatalAbort($res, __FILE__, __LINE__);
$this->_releaseLock();
return true;
}
 
 
 
// }}}
// +----------------------------------------------+
// | Moving and copying |
// |----------------------------------------------+
// | [PUBLIC] |
// +----------------------------------------------+
// {{{ moveTree()
 
/**
* Wrapper for node moving and copying
*
* @param int $id Source ID
* @param int $target Target ID
* @param constant $pos Position (use one of the NESE_MOVE_* constants)
* @param bool $copy Shall we create a copy
*
* @see _moveInsideLevel
* @see _moveAcross
* @see _moveRoot2Root
* @access public
* @return int ID of the moved node or false on error
*/
function moveTree($id, $targetid, $pos, $copy = false) {
 
if ($this->debug) {
$this->_debugMessage('moveTree($id, $target, $pos, $copy = false)');
}
if($id == $targetid && !$copy) {
// TRIGGER BOGUS MESSAGE
return false;
}
 
// Get information about source and target
if (!($source = $this->pickNode($id, true))) {
$epr = array('moveTree()', $id);
return $this->_raiseError(NESE_ERROR_NOT_FOUND, PEAR_ERROR_TRIGGER, E_USER_ERROR, $epr);
}
 
if (!($target = $this->pickNode($targetid, true))) {
$epr = array('moveTree()', $targetid);
return $this->_raiseError(NESE_ERROR_NOT_FOUND, PEAR_ERROR_TRIGGER, E_USER_ERROR, $epr);
}
 
if (PEAR::isError($lock = $this->_setLock(true))) {
return $lock;
}
 
$this->_relations = array();
// This operations don't need callbacks except the copy handler
// which ignores this setting
$this->_skipCallbacks = true;
 
if(!$copy) {
// We have a recursion - let's stop
if (($target['rootid'] == $source['rootid']) &&
(($source['l'] <= $target['l']) &&
($source['r'] >= $target['r']))) {
$this->_releaseLock(true);
$epr = array('moveTree()');
return $this->_raiseError(NESE_ERROR_RECURSION, PEAR_ERROR_RETURN, E_USER_NOTICE, $epr);
}
 
// Insert/move before or after
 
if (($source['rootid'] == $source['id']) &&
($target['rootid'] == $target['id'])) {
// We have to move a rootnode which is different from moving inside a tree
$nid = $this->_moveRoot2Root($source, $target, $pos, $copy);
$this->_releaseLock(true);
return $nid;
}
} elseif(($target['rootid'] == $source['rootid']) &&
(($source['l'] < $target['l']) &&
($source['r'] > $target['r']))) {
$this->_releaseLock(true);
$epr = array('moveTree()');
return $this->_raiseError(NESE_ERROR_RECURSION, PEAR_ERROR_RETURN, E_USER_NOTICE, $epr);
}
 
 
// We have to move between different levels and maybe subtrees - let's rock ;)
$this->_moveAcross($source, $target, $pos);
$this->_moveCleanup($copy);
$this->_releaseLock(true);
}
 
// }}}
// {{{ _moveAcross()
 
/**
* Moves nodes and trees to other subtrees or levels
*
* <pre>
* [+] <--------------------------------+
* +-[\] root1 [target] |
* <-------------------------+ |p
* +-\ root2 | |
* | | | |
* | |-- subnode1 [target] | |B
* | |-- subnode2 [new] |S |E
* | |-- subnode3 |U |F
* | |B |O
* +-\ root3 | |R
* |-- subnode 3.1 | |E
* |-\ subnode 3.2 [source] >--+------+
* |-- subnode 3.2.1
*</pre>
*
* @param object NodeCT $source Source node
* @param object NodeCT $target Target node
* @param string $pos Position [SUBnode/BEfore]
* @param bool $copy Shall we create a copy
*
* @access private
* @see moveTree
* @see _r_moveAcross
* @see _moveCleanup
*/
function _moveAcross($source, $target, $pos) {
if ($this->debug) {
$this->_debugMessage('_moveAcross($source, $target, $pos, $copy = false)');
}
 
// Get the current data from a node and exclude the id params which will be changed
// because of the node move
$values = array();
foreach($this->params as $key => $val) {
if ($source[$val] && !in_array($val, $this->_requiredParams)) {
$values[$key] = trim($source[$val]);
}
}
 
switch($pos) {
 
case NESE_MOVE_BEFORE:
$clone_id = $this->createLeftNode($target['id'], $values);
break;
 
case NESE_MOVE_AFTER:
$clone_id = $this->createRightNode($target['id'], $values);
break;
 
case NESE_MOVE_BELOW:
$clone_id = $this->createSubNode($target['id'], $values);
break;
}
 
 
$children = $this->getChildren($source['id'], true, true, true);
 
 
if ($children) {
$pos = NESE_MOVE_BELOW;
$sclone_id = $clone_id;
// Recurse through the child nodes
foreach($children AS $cid => $child) {
$sclone = $this->pickNode($sclone_id, true);
$sclone_id = $this->_moveAcross($child, $sclone, $pos);
 
$pos = NESE_MOVE_AFTER;
}
}
 
$this->_relations[$source['id']] = $clone_id;
return $clone_id;
}
 
// }}}
// {{{ _moveCleanup()
 
/**
* Deletes the old subtree (node) and writes the node id's into the cloned tree
*
*
* @param array $relations Hash in der Form $h[alteid]=neueid
* @param array $copy Are we in copy mode?
* @access private
*/
function _moveCleanup($copy = false) {
 
$relations = $this->_relations;
if ($this->debug) {
$this->_debugMessage('_moveCleanup($relations, $copy = false)');
}
 
$deletes = array();
$updates = array();
$tb = $this->node_table;
$fid = $this->_flparams['id'];
$froot = $this->_flparams['rootid'];
foreach($relations AS $key => $val) {
$clone = $this->pickNode($val);
if ($copy) {
// EVENT (NodeCopy)
 
$eparams = array('clone' => $clone);
 
if (!$this->_skipCallbacks && isset($this->_hasListeners['nodeCopy'])) {
$this->triggerEvent('nodeCopy', $this->pickNode($key), $eparams);
}
continue;
}
 
// No callbacks here because the node itself doesn't get changed
// Only it's position
// If one needs a callback here please let me know
 
$deletes[] = $key;
// It's isn't a rootnode
if ($clone->id != $clone->rootid) {
 
 
$sql = sprintf('UPDATE %s SET %s=%s WHERE %s = %s',
$this->node_table,
$fid,
$key,
$fid,
$val);
$updates[] = $sql;
} else {
$sql = sprintf('UPDATE %s SET %s=%s, %s=%s WHERE %s=%s',
$tb,
$fid,
$key,
$froot,
$val,
$fid,
$val);
 
$updates[] = $sql;
$orootid = $clone->rootid;
 
$sql = sprintf('UPDATE %s SET %s=%s WHERE %s=%s',
$tb,
$froot,
$key,
$froot,
$orootid);
$updates[] = $sql;
}
$this->_skipCallbacks = false;
}
 
if(!empty($deletes)) {
for($i=0;$i<count($deletes);$i++) {
$this->deleteNode($deletes[$i]);
}
}
 
if(!empty($updates)) {
for($i=0;$i<count($updates);$i++) {
$res = $this->db->query($updates[$i]);
$this->_testFatalAbort($res, __FILE__, __LINE__);
}
}
 
return true;
}
 
// }}}
// {{{ _moveRoot2Root()
 
/**
* Moves rootnodes
*
* <pre>
* +-- root1
* |
* +-\ root2
* | |
* | |-- subnode1 [target]
* | |-- subnode2 [new]
* | |-- subnode3
* |
* +-\ root3
* [|] <-----------------------+
* |-- subnode 3.1 [target] |
* |-\ subnode 3.2 [source] >--+
* |-- subnode 3.2.1
* </pre>
*
* @param object NodeCT $source Source
* @param object NodeCT $target Target
* @param string $pos BEfore | AFter
* @access private
* @see moveTree
*/
function _moveRoot2Root($source, $target, $pos) {
 
if ($this->debug) {
$this->_debugMessage('_moveRoot2Root($source, $target, $pos, $copy)');
}
if(PEAR::isError($lock=$this->_setLock())) {
return $lock;
}
 
$tb = $this->node_table;
$fid = $this->_flparams['id'];
$froot = $this->_flparams['rootid'];
$freh = $this->_flparams['norder'];
$s_order = $source['norder'];
$t_order = $target['norder'];
$s_id = $source['id'];
$t_id = $target['id'];
 
 
if ($s_order < $t_order) {
if ($pos == NESE_MOVE_BEFORE) {
$sql = "UPDATE $tb SET $freh=$freh-1
WHERE $freh BETWEEN $s_order AND $t_order AND
$fid!=$t_id AND
$fid!=$s_id AND
$froot=$fid";
$res = $this->db->query($sql);
$this->_testFatalAbort($res, __FILE__, __LINE__);
$sql = "UPDATE $tb SET $freh=$t_order -1 WHERE $fid=$s_id";
$res = $this->db->query($sql);
$this->_testFatalAbort($res, __FILE__, __LINE__);
}
elseif($pos == NESE_MOVE_AFTER) {
 
$sql = "UPDATE $tb SET $freh=$freh-1
WHERE $freh BETWEEN $s_order AND $t_order AND
$fid!=$s_id AND
$froot=$fid";
$res = $this->db->query($sql);
$this->_testFatalAbort($res, __FILE__, __LINE__);
 
$sql = "UPDATE $tb SET $freh=$t_order WHERE $fid=$s_id";
$res = $this->db->query($sql);
$this->_testFatalAbort($res, __FILE__, __LINE__);
}
}
 
if ($s_order > $t_order) {
if ($pos == NESE_MOVE_BEFORE) {
$sql = "UPDATE $tb SET $freh=$freh+1
WHERE $freh BETWEEN $t_order AND $s_order AND
$fid != $s_id AND
$froot=$fid";
$res = $this->db->query($sql);
$this->_testFatalAbort($res, __FILE__, __LINE__);
 
$sql = "UPDATE $tb SET $freh=$t_order WHERE $fid=$s_id";
$res = $this->db->query($sql);
$this->_testFatalAbort($res, __FILE__, __LINE__);
}
elseif ($pos == NESE_MOVE_AFTER) {
$sql = "UPDATE $tb SET $freh=$freh+1
WHERE $freh BETWEEN $t_order AND $s_order AND
$fid!=$t_id AND
$fid!=$s_id AND
$froot=$fid";
$res = $this->db->query($sql);
$this->_testFatalAbort($res, __FILE__, __LINE__);
 
$sql = "UPDATE $tb SET $freh=$t_order+1 WHERE $fid = $s_id";
$res = $this->db->query($sql);
$this->_testFatalAbort($res, __FILE__, __LINE__);
}
}
$this->_releaseLock();
return $source->id;
}
 
// }}}
// +-----------------------+
// | Helper methods |
// +-----------------------+
 
// }}}
// {{{ _secSort()
 
/**
* Callback for uasort used to sort siblings
*
* @access private
*/
function _secSort($node1, $node2) {
// Within the same level?
if($node1['level'] != $node2['level']) {
return strnatcmp($node1['l'], $node2['l']);
}
 
// Are they siblings?
$p1 = $this->getParent($node1);
$p2 = $this->getParent($node2);
if($p1['id'] != $p2['id']) {
return strnatcmp($node1['l'], $node2['l']);
}
 
// Same field value? Use the lft value then
$field = $this->params[$this->secondarySort];
if($node1[$field] == $node2[$field]) {
return strnatcmp($node1['l'], $node2[l]);
}
 
// Compare between siblings with different field value
return strnatcmp($node1[$field], $node2[$field]);
}
 
// }}}
// {{{ _addSQL()
 
/**
* Adds a specific type of SQL to a query string
*
* @param array $addSQL The array of SQL strings to add. Example value:
* $addSQL = array(
* 'cols' => 'tb2.col2, tb2.col3', // Additional tables/columns
* 'join' => 'LEFT JOIN tb1 USING(STRID)', // Join statement
* 'append' => 'GROUP by tb1.STRID'); // Group condition
* @param string $type The type of SQL. Can be 'cols', 'join', or 'append'.
*
* @access private
* @return string The SQL, properly formatted
*/
function _addSQL($addSQL, $type) {
if (!isset($addSQL[$type])) {
return '';
}
 
switch($type) {
case 'cols':
return ', ' . $addSQL[$type];
default:
return $addSQL[$type];
}
}
 
// }}}
// {{{ _getSelectFields()
 
/**
* Gets the select fields based on the params
*
* @param bool $aliasFields Should we alias the fields so they are the names of the
* parameter keys, or leave them as is?
*
* @access private
* @return string A string of query fields to select
*/
function _getSelectFields($aliasFields) {
$queryFields = array();
foreach ($this->params as $key => $val) {
$tmp_field = $this->node_table . '.' . $key;
if ($aliasFields) {
$tmp_field .= ' AS ' . $val;
}
$queryFields[] = $tmp_field;
}
 
$fields = implode(', ', $queryFields);
return $fields;
}
 
// }}}
// {{{ _processResultSet()
 
/**
* Processes a DB result set by checking for a DB error and then transforming the result
* into a set of DB_NestedSet_Node objects or leaving it as an array.
*
* @param string $sql The sql query to be done
* @param bool $keepAsArray Keep the result as an array or transform it into a set of
* DB_NestedSet_Node objects?
* @param bool $fieldsAreAliased Are the fields aliased?
*
* @access private
* @return mixed False on error or the transformed node set.
*/
function _processResultSet($sql, $keepAsArray, $fieldsAreAliased) {
$result = $this->db->getAll($sql);
if ($this->_testFatalAbort($result, __FILE__, __LINE__)) {
return false;
}
 
$nodes = array();
$idKey = $fieldsAreAliased ? 'id' : $this->_flparams['id'];
foreach ($result as $row) {
$node_id = $row[$idKey];
if ($keepAsArray) {
$nodes[$node_id] = $row;
} else {
// Create an instance of the node container
$nodes[$node_id] =& new DB_NestedSet_Node($row);
}
 
}
return $nodes;
}
 
// }}}
// {{{ _testFatalAbort()
 
/**
* Error Handler
*
* Tests if a given ressource is a PEAR error object
* ans raises a fatal error in case of an error object
*
* @param object PEAR::Error $errobj The object to test
* @param string $file The filename wher the error occured
* @param int $line The line number of the error
* @return void
* @access private
*/
function _testFatalAbort($errobj, $file, $line) {
if (!$this->_isDBError($errobj)) {
return false;
}
 
if ($this->debug) {
$this->_debugMessage('_testFatalAbort($errobj, $file, $line)');
}
if ($this->debug) {
$message = $errobj->getUserInfo();
$code = $errobj->getCode();
$msg = "$message ($code) in file $file at line $line";
} else {
$msg = $errobj->getMessage();
$code = $errobj->getCode(); }
 
PEAR::raiseError($msg, $code, PEAR_ERROR_TRIGGER, E_USER_ERROR);
}
 
// {{{ __raiseError()
 
/**
* @access private
*/
function _raiseError($code, $mode, $option, $epr=array()) {
$message = vsprintf($this->_getMessage($code), $epr);
return PEAR::raiseError($message, $code, $mode, $option);
}
 
// }}}
 
// {{{ addListener()
 
/**
* Add an event listener
*
* Adds an event listener and returns an ID for it
*
* @param string $event The ivent name
* @param string $listener The listener object
* @return string
* @access public
*/
function addListener($event, &$listener) {
$listenerID = uniqid('el');
$this->eventListeners[$event][$listenerID] =& $listener;
$this->_hasListeners[$event] = true;
return $listenerID;
}
 
// }}}
// {{{ removeListener()
 
/**
* Removes an event listener
*
* Removes the event listener with the given ID
*
* @param string $event The ivent name
* @param string $listenerID The listener's ID
* @return bool
* @access public
*/
function removeListener($event, $listenerID) {
unset($this->eventListeners[$event][$listenerID]);
if (!isset($this->eventListeners[$event]) ||
!is_array($this->eventListeners[$event]) ||
count($this->eventListeners[$event]) == 0) {
unset($this->_hasListeners[$event]);
}
return true;
}
 
// }}}
// {{{ triggerEvent()
 
/**
* Triggers and event an calls the event listeners
*
* @param string $event The Event that occured
* @param object node $node A Reference to the node object which was subject to changes
* @param array $eparams A associative array of params which may be needed by the handler
* @return bool
* @access public
*/
function triggerEvent($event, &$node, $eparams = false) {
if ($this->_skipCallbacks || !isset($this->_hasListeners[$event])) {
return false;
}
 
foreach($this->eventListeners[$event] as $key => $val) {
if (!method_exists($val, 'callEvent')) {
return new PEAR_Error($this->_getMessage(NESE_ERROR_NOHANDLER), NESE_ERROR_NOHANDLER);
}
 
$val->callEvent($event, $node, $eparams);
}
 
return true;
}
 
// }}}
// {{{ apiVersion()
 
function apiVersion() {
return array(
'package:'=>$this->_packagename,
'majorversion'=>$this->_majorversion,
'minorversion'=>$this->_minorversion,
'version'=>sprintf('%s.%s',$this->_majorversion, $this->_minorversion),
'revision'=>str_replace('$', '',"$Revision: 1.56 $")
);
}
 
// }}}
// {{{ setAttr()
 
/**
* Sets an object attribute
*
* @param array $attr An associative array with attributes
*
* @return bool
* @access public
*/
function setAttr($attr) {
static $hasSetSequence;
if (!isset($hasSetSequence)) {
$hasSetSequence = false;
}
 
if (!is_array($attr) || count($attr) == 0) {
return false;
}
 
foreach ($attr as $key => $val) {
$this->$key = $val;
if ($key == 'sequence_table') {
$hasSetSequence = true;
}
 
// only update sequence to reflect new table if they haven't set it manually
if (!$hasSetSequence && $key == 'node_table') {
$this->sequence_table = $this->node_table . '_' . $this->_flparams['id'];
}
if($key == 'cache' && is_object($val)) {
$this->_caching = true;
$GLOBALS['DB_NestedSet'] = & $this;
}
}
 
return true;
}
 
// }}}
// {{{ setsortMode()
/**
* This enables you to set specific options for each output method
*
* @param constant $sortMode
*
* @access public
* @return Current sortMode
*/
function setsortMode($sortMode=false) {
if($sortMode && in_array($sortMode, $this->_sortModes)) {
$this->_sortMode = $sortMode;
} else {
return $this->_sortMode;
}
return $this->_sortMode;
}
// }}}
// {{{ setDbOption()
 
/**
* Sets a db option. Example, setting the sequence table format
*
* @var string $option The option to set
* @var string $val The value of the option
*
* @access public
* @return void
*/
function setDbOption($option, $val) {
$this->db->setOption($option, $val);
}
 
// }}}
// {{{ testLock()
 
/**
* Tests if a database lock is set
*
* @access public
*/
function testLock() {
if ($this->debug) {
$this->_debugMessage('testLock()');
}
 
if($lockID = $this->_structureTableLock) {
return $lockID;
}
$this->_lockGC();
$sql = sprintf('SELECT lockID FROM %s WHERE lockTable=%s',
$this->lock_table,
$this->_quote($this->node_table)) ;
 
$res = $this->db->query($sql);
$this->_testFatalAbort($res, __FILE__, __LINE__);
 
if ($this->_numRows($res)) {
return new PEAR_Error($this->_getMessage(NESE_ERROR_TBLOCKED),NESE_ERROR_TBLOCKED);
}
 
return false;
}
 
// }}}
// {{{ _setLock()
 
/**
* @access private
*/
function _setLock($exclusive=false) {
$lock = $this->testLock();
if(PEAR::isError($lock)) {
return $lock;
}
 
if ($this->debug) {
$this->_debugMessage('_setLock()');
}
if($this->_caching) {
@$this->cache->flush('function_cache');
$this->_caching = false;
$this->_restcache = true;
}
 
if (!$lockID = $this->_structureTableLock) {
$lockID = $this->_structureTableLock = uniqid('lck-');
 
$sql = sprintf('INSERT INTO %s SET lockID=%s, lockTable=%s, lockStamp=%s',
$this->lock_table,
$this->_quote($lockID),
$this->_quote($this->node_table),
time());
 
} else {
$sql = sprintf('UPDATE %s set lockStamp=%s WHERE lockID=%s AND lockTable=%s',
$this->lock_table,
time(),
$this->_quote($lockID),
$this->_quote($this->node_table));
}
if($exclusive) {
$this->_lockExclusive = true;
}
 
$res = $this->db->query($sql);
$this->_testFatalAbort($res, __FILE__, __LINE__);
return $lockID;
}
 
// }}}
// {{{ _releaseLock()
 
/**
* @access private
*/
function _releaseLock($exclusive=false) {
if ($this->debug) {
$this->_debugMessage('_releaseLock()');
}
 
if($exclusive) {
$this->_lockExclusive = false;
}
 
if ((!$lockID = $this->_structureTableLock) || $this->_lockExclusive) {
return false;
}
 
$tb = $this->lock_table;
$stb = $this->node_table;
$sql = "DELETE FROM $tb
WHERE lockTable=" . $this->_quote($stb) . " AND
lockID=" . $this->_quote($lockID);
 
$res = $this->db->query($sql);
$this->_testFatalAbort($res, __FILE__, __LINE__);
$this->_structureTableLock = false;
if($this->_restcache) {
$this->_caching = true;
$this->_restcache = false;
}
return true;
}
 
// }}}
// {{{ _lockGC()
 
/**
* @access private
*/
function _lockGC() {
if ($this->debug) {
$this->_debugMessage('_lockGC()');
}
$tb = $this->lock_table;
$stb = $this->node_table;
$lockTTL = time() - $this->lockTTL;
$sql = "DELETE FROM $tb
WHERE lockTable=" . $this->_quote($stb) . " AND
lockStamp < $lockTTL";
 
$res = $this->db->query($sql);
$this->_testFatalAbort($res, __FILE__, __LINE__);
}
 
// }}}
// {{{ _values2Query()
 
/**
* @access private
*/
function _values2Query($values, $addval = false) {
 
if ($this->debug) {
$this->_debugMessage('_values2Query($values, $addval = false)');
}
if (is_array($addval)) {
$values = $values + $addval;
}
 
$arq = array();
foreach($values AS $key => $val) {
$k = trim($key);
$v = trim($val);
if ($k) {
// To be used with the next mahor version
// $iv = in_array($this->params[$k], $this->_quotedParams) ? $this->_quote($v) : $v;
$iv = $this->_quote($v);
$arq[] = "$k=$iv";
}
}
 
if (!is_array($arq) || count($arq) == 0) {
return false;
}
 
$query = implode(', ', $arq);
return $query;
}
 
// }}}
// {{{ _verifyUserValues()
 
/**
* Clean values from protected or unknown columns
*
* @var string $caller The calling method
* @var string $values The values array
*
* @access private
* @return void
*/
function _verifyUserValues($caller, &$values) {
 
if($this->_dumbmode) {
return true;
}
foreach($values AS $field=>$value) {
if(!isset($this->params[$field])) {
$epr = array(
$caller,
sprintf('Unknown column/param \'%s\'', $field));
$this->_raiseError(NESE_ERROR_WRONG_MPARAM, PEAR_ERROR_RETURN, E_USER_NOTICE, $epr);
unset($values[$field]);
} else {
$flip = $this->params[$field];
if(in_array($flip, $this->_requiredParams)) {
$epr = array(
$caller,
sprintf('\'%s\' is autogenerated and can\'t be passed - it will be ignored', $field));
$this->_raiseError(NESE_ERROR_WRONG_MPARAM, PEAR_ERROR_RETURN, E_USER_NOTICE, $epr);
unset($values[$field]);
}
}
}
}
 
// }}}
// {{{ _debugMessage()
 
/**
* @access private
*/
function _debugMessage($msg) {
if ($this->debug) {
$time = $this->_getmicrotime();
echo "$time::Debug:: $msg<br />\n";
}
}
 
// }}}
// {{{ _getMessage()
 
/**
* @access private
*/
function _getMessage($code) {
if ($this->debug) {
$this->_debugMessage('_getMessage($code)');
}
return isset($this->messages[$code]) ? $this->messages[$code] : $this->messages[NESE_MESSAGE_UNKNOWN];
 
}
 
// }}}
// {{{ _getmicrotime()
 
/**
* @access private
*/
function _getmicrotime() {
list($usec, $sec) = explode(' ', microtime());
return ((float)$usec + (float)$sec);
}
 
// }}}
// {{{ convertTreeModel()
 
/**
* Convert a <1.3 tree into a 1.3 tree format
*
* This will convert the tree into a format needed for some new features in
* 1.3. Your <1.3 tree will still work without converting but some new features
* like preorder sorting won't work as expected.
*
* <pre>
* Usage:
* - Create a new node table (tb_nodes2) from the current node table (tb_nodes1) (only copy the structure).
* - Create a nested set instance of the 'old' set (NeSe1) and one of the new set (NeSe2)
* - Now you have 2 identical objects where only node_table differs
* - Call DB_NestedSet::convertTreeModel(&$orig, &$copy);
* - After that you have a cleaned up copy of tb_nodes1 inside tb_nodes2
* </pre>
*
* @param object DB_NestedSet $orig Nested set we want to copy
* @param object DB_NestedSet $copy Object where the new tree is copied to
* @param integer $_parent ID of the parent node (private)
*
* @static
* @access public
* @return bool True uns success
*/
function convertTreeModel(&$orig, &$copy, $_parent=false) {
 
static $firstSet;
 
$isRoot = false;
if(!$_parent) {
if(!is_object($orig) || !is_object($copy)) {
return false;
}
if($orig->node_table == $copy->node_table) {
return false;
}
$copy->_dumbmode = true;
$orig->sortMode = NESE_SORT_LEVEL;
$copy->sortMode = NESE_SORT_LEVEL;
$sibl = $orig->getRootNodes(true);
$isRoot = true;
} else {
$sibl = $orig->getChildren($_parent, true);
}
 
if(empty($sibl)) {
return false;
}
 
foreach($sibl AS $sid=>$sibling) {
unset($sibling['l']);
unset($sibling['r']);
unset($sibling['norder']);
 
$values = array();
foreach($sibling AS $key=>$val) {
if(!isset($copy->_flparams[$key])) {
continue;
}
$values[$copy->_flparams[$key]] = $val;
}
 
if(!$firstSet) {
$psid = $copy->createRootNode($values, false, true);
$firstSet = true;
} elseif($isRoot) {
$psid = $copy->createRightNode($psid, $values);
} else {
$copy->createSubNode($_parent, $values);
}
 
DB_NestedSet::convertTreeModel($orig, $copy, $sid);
}
return true;
}
// }}}
// {{{ _numRows()
/**
* Fetches the number of rows the last query returned
* @access private
* @abstract
*/
function _numRows($res) {
}
// }}}
// {{{ _isDBError()
/**
* Returns true if a db return value is an error object
* @access private
* @abstract
*/
function _isDBError($err) {
}
// }}}
// {{{ quote()
/**
* Quotes a string to use it inside queries
* @access private
* @abstract
*/
function _quote($str) {
}
 
}
 
// {{{ DB_NestedSet_Node:: class
 
/**
* Generic class for node objects
*
* @autor Daniel Khan <dk@webcluster.at>;
* @version $Revision: 1.56 $
* @package DB_NestedSet
*
* @access private
*/
 
class DB_NestedSet_Node {
// {{{ constructor
 
/**
* Constructor
*/
function DB_NestedSet_Node($data) {
if (!is_array($data) || count($data) == 0) {
return new PEAR_ERROR($data, NESE_ERROR_PARAM_MISSING);
}
 
$this->setAttr($data);
return true;
}
 
// }}}
// {{{ setAttr()
 
function setAttr($data) {
if(!is_array($data) || count($data) == 0) {
return false;
}
 
foreach ($data as $key => $val) {
$this->$key = $val;
}
}
 
// }}}
 
}
// }}}
 
 
?>
/trunk/bibliotheque/pear/DB/mssql.php
6,7 → 6,7
* The PEAR DB driver for PHP's mssql extension
* for interacting with Microsoft SQL Server databases
*
* PHP version 5
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
18,9 → 18,9
* @package DB
* @author Sterling Hughes <sterling@php.net>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2007 The PHP Group
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$
* @version CVS: $Id: mssql.php,v 1.83 2005/03/07 18:24:51 danielc Exp $
* @link http://pear.php.net/package/DB
*/
 
35,21 → 35,13
*
* These methods overload the ones declared in DB_common.
*
* DB's mssql driver is only for Microsfoft SQL Server databases.
*
* If you're connecting to a Sybase database, you MUST specify "sybase"
* as the "phptype" in the DSN.
*
* This class only works correctly if you have compiled PHP using
* --with-mssql=[dir_to_FreeTDS].
*
* @category Database
* @package DB
* @author Sterling Hughes <sterling@php.net>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2007 The PHP Group
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.9.2
* @version Release: 1.7.6
* @link http://pear.php.net/package/DB
*/
class DB_mssql extends DB_common
97,40 → 89,19
*/
// XXX Add here error codes ie: 'S100E' => DB_ERROR_SYNTAX
var $errorcode_map = array(
102 => DB_ERROR_SYNTAX,
110 => DB_ERROR_VALUE_COUNT_ON_ROW,
155 => DB_ERROR_NOSUCHFIELD,
156 => DB_ERROR_SYNTAX,
170 => DB_ERROR_SYNTAX,
207 => DB_ERROR_NOSUCHFIELD,
208 => DB_ERROR_NOSUCHTABLE,
245 => DB_ERROR_INVALID_NUMBER,
319 => DB_ERROR_SYNTAX,
321 => DB_ERROR_NOSUCHFIELD,
325 => DB_ERROR_SYNTAX,
336 => DB_ERROR_SYNTAX,
515 => DB_ERROR_CONSTRAINT_NOT_NULL,
547 => DB_ERROR_CONSTRAINT,
1018 => DB_ERROR_SYNTAX,
1035 => DB_ERROR_SYNTAX,
1913 => DB_ERROR_ALREADY_EXISTS,
2209 => DB_ERROR_SYNTAX,
2223 => DB_ERROR_SYNTAX,
2248 => DB_ERROR_SYNTAX,
2256 => DB_ERROR_SYNTAX,
2257 => DB_ERROR_SYNTAX,
2627 => DB_ERROR_CONSTRAINT,
2714 => DB_ERROR_ALREADY_EXISTS,
3607 => DB_ERROR_DIVZERO,
3701 => DB_ERROR_NOSUCHTABLE,
7630 => DB_ERROR_SYNTAX,
8134 => DB_ERROR_DIVZERO,
9303 => DB_ERROR_SYNTAX,
9317 => DB_ERROR_SYNTAX,
9318 => DB_ERROR_SYNTAX,
9331 => DB_ERROR_SYNTAX,
9332 => DB_ERROR_SYNTAX,
15253 => DB_ERROR_SYNTAX,
);
 
/**
179,13 → 150,13
// {{{ constructor
 
/**
* This constructor calls <kbd>parent::__construct()</kbd>
* This constructor calls <kbd>$this->DB_common()</kbd>
*
* @return void
*/
function __construct()
function DB_mssql()
{
parent::__construct();
$this->DB_common();
}
 
// }}}
273,7 → 244,7
*/
function simpleQuery($query)
{
$ismanip = $this->_checkManip($query);
$ismanip = DB::isManip($query);
$this->last_query = $query;
if (!@mssql_select_db($this->_db, $this->connection)) {
return $this->mssqlRaiseError(DB_ERROR_NODBSELECTED);
345,7 → 316,7
}
}
if ($fetchmode & DB_FETCHMODE_ASSOC) {
$arr = @mssql_fetch_assoc($result);
$arr = @mssql_fetch_array($result, MSSQL_ASSOC);
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
$arr = array_change_key_case($arr, CASE_LOWER);
}
382,7 → 353,7
*/
function freeResult($result)
{
return is_resource($result) ? mssql_free_result($result) : false;
return @mssql_free_result($result);
}
 
// }}}
512,7 → 483,7
*/
function affectedRows()
{
if ($this->_last_query_manip) {
if (DB::isManip($this->last_query)) {
$res = @mssql_query('select @@rowcount', $this->connection);
if (!$res) {
return $this->mssqlRaiseError();
566,15 → 537,7
return $this->raiseError($result);
}
} elseif (!DB::isError($result)) {
$result = $this->query("SELECT IDENT_CURRENT('$seqname')");
if (DB::isError($result)) {
/* Fallback code for MS SQL Server 7.0, which doesn't have
* IDENT_CURRENT. This is *not* safe for concurrent
* requests, and really, if you're using it, you're in a
* world of hurt. Nevertheless, it's here to ensure BC. See
* bug #181 for the gory details.*/
$result = $this->query("SELECT @@IDENTITY FROM $seqname");
}
$result =& $this->query("SELECT @@IDENTITY FROM $seqname");
$repeat = 0;
} else {
$repeat = false;
624,27 → 587,6
}
 
// }}}
// {{{ escapeSimple()
 
/**
* Escapes a string in a manner suitable for SQL Server.
*
* @param string $str the string to be escaped
* @return string the escaped string
*
* @see DB_common::quoteSmart()
* @since Method available since Release 1.6.0
*/
function escapeSimple($str)
{
return str_replace(
array("'", "\\\r\n", "\\\n"),
array("''", "\\\\\r\n\r\n", "\\\\\n\n"),
$str
);
}
 
// }}}
// {{{ quoteIdentifier()
 
/**
803,22 → 745,16
}
 
for ($i = 0; $i < $count; $i++) {
if ($got_string) {
$flags = $this->_mssql_field_flags($result,
@mssql_field_name($id, $i));
if (DB::isError($flags)) {
return $flags;
}
} else {
$flags = '';
}
 
$res[$i] = array(
'table' => $got_string ? $case_func($result) : '',
'name' => $case_func(@mssql_field_name($id, $i)),
'type' => @mssql_field_type($id, $i),
'len' => @mssql_field_length($id, $i),
'flags' => $flags,
// We only support flags for table
'flags' => $got_string
? $this->_mssql_field_flags($result,
@mssql_field_name($id, $i))
: '',
);
if ($mode & DB_TABLEINFO_ORDER) {
$res['order'][$res[$i]['name']] = $i;
869,10 → 805,7
$tableName = $table;
 
// get unique and primary keys
$res = $this->getAll("EXEC SP_HELPINDEX $table", DB_FETCHMODE_ASSOC);
if (DB::isError($res)) {
return $res;
}
$res = $this->getAll("EXEC SP_HELPINDEX[$table]", DB_FETCHMODE_ASSOC);
 
foreach ($res as $val) {
$keys = explode(', ', $val['index_keys']);
895,10 → 828,7
}
 
// get auto_increment, not_null and timestamp
$res = $this->getAll("EXEC SP_COLUMNS $table", DB_FETCHMODE_ASSOC);
if (DB::isError($res)) {
return $res;
}
$res = $this->getAll("EXEC SP_COLUMNS[$table]", DB_FETCHMODE_ASSOC);
 
foreach ($res as $val) {
$val = array_change_key_case($val, CASE_LOWER);
/trunk/bibliotheque/pear/DB/DataObject.php
New file
0,0 → 1,3827
<?php
/**
* Object Based Database Query Builder and data store
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category Database
* @package DB_DataObject
* @author Alan Knowles <alan@akbkhome.com>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: DataObject.php,v 1.361 2005/07/06 06:13:09 alan_k Exp $
* @link http://pear.php.net/package/DB_DataObject
*/
 
/* ===========================================================================
*
* !!!!!!!!!!!!! W A R N I N G !!!!!!!!!!!
*
* THIS MAY SEGFAULT PHP IF YOU ARE USING THE ZEND OPTIMIZER (to fix it,
* just add "define('DB_DATAOBJECT_NO_OVERLOAD',true);" before you include
* this file. reducing the optimization level may also solve the segfault.
* ===========================================================================
*/
 
/**
* The main "DB_DataObject" class is really a base class for your own tables classes
*
* // Set up the class by creating an ini file (refer to the manual for more details
* [DB_DataObject]
* database = mysql:/username:password@host/database
* schema_location = /home/myapplication/database
* class_location = /home/myapplication/DBTables/
* clase_prefix = DBTables_
*
*
* //Start and initialize...................... - dont forget the &
* $config = parse_ini_file('example.ini',true);
* $options = &PEAR::getStaticProperty('DB_DataObject','options');
* $options = $config['DB_DataObject'];
*
* // example of a class (that does not use the 'auto generated tables data')
* class mytable extends DB_DataObject {
* // mandatory - set the table
* var $_database_dsn = "mysql://username:password@localhost/database";
* var $__table = "mytable";
* function table() {
* return array(
* 'id' => 1, // integer or number
* 'name' => 2, // string
* );
* }
* function keys() {
* return array('id');
* }
* }
*
* // use in the application
*
*
* Simple get one row
*
* $instance = new mytable;
* $instance->get("id",12);
* echo $instance->somedata;
*
*
* Get multiple rows
*
* $instance = new mytable;
* $instance->whereAdd("ID > 12");
* $instance->whereAdd("ID < 14");
* $instance->find();
* while ($instance->fetch()) {
* echo $instance->somedata;
* }
 
 
/**
* Needed classes
* - we use getStaticProperty from PEAR pretty extensively (cant remove it ATM)
*/
 
require_once 'PEAR.php';
 
/**
* We are setting a global fetchmode assoc constant of 2 to be compatible with
* both DB and MDB2
*/
define('DB_DATAOBJECT_FETCHMODE_ASSOC',2);
 
 
 
 
 
/**
* these are constants for the get_table array
* user to determine what type of escaping is required around the object vars.
*/
define('DB_DATAOBJECT_INT', 1); // does not require ''
define('DB_DATAOBJECT_STR', 2); // requires ''
 
define('DB_DATAOBJECT_DATE', 4); // is date #TODO
define('DB_DATAOBJECT_TIME', 8); // is time #TODO
define('DB_DATAOBJECT_BOOL', 16); // is boolean #TODO
define('DB_DATAOBJECT_TXT', 32); // is long text #TODO
define('DB_DATAOBJECT_BLOB', 64); // is blob type
 
 
define('DB_DATAOBJECT_NOTNULL', 128); // not null col.
define('DB_DATAOBJECT_MYSQLTIMESTAMP' , 256); // mysql timestamps (ignored by update/insert)
/*
* Define this before you include DataObjects.php to disable overload - if it segfaults due to Zend optimizer..
*/
//define('DB_DATAOBJECT_NO_OVERLOAD',true)
 
 
/**
* Theses are the standard error codes, most methods will fail silently - and return false
* to access the error message either use $table->_lastError
* or $last_error = PEAR::getStaticProperty('DB_DataObject','lastError');
* the code is $last_error->code, and the message is $last_error->message (a standard PEAR error)
*/
 
define('DB_DATAOBJECT_ERROR_INVALIDARGS', -1); // wrong args to function
define('DB_DATAOBJECT_ERROR_NODATA', -2); // no data available
define('DB_DATAOBJECT_ERROR_INVALIDCONFIG', -3); // something wrong with the config
define('DB_DATAOBJECT_ERROR_NOCLASS', -4); // no class exists
define('DB_DATAOBJECT_ERROR_INVALID_CALL' ,-7); // overlad getter/setter failure
 
/**
* Used in methods like delete() and count() to specify that the method should
* build the condition only out of the whereAdd's and not the object parameters.
*/
define('DB_DATAOBJECT_WHEREADD_ONLY', true);
 
/**
*
* storage for connection and result objects,
* it is done this way so that print_r()'ing the is smaller, and
* it reduces the memory size of the object.
* -- future versions may use $this->_connection = & PEAR object..
* although will need speed tests to see how this affects it.
* - includes sub arrays
* - connections = md5 sum mapp to pear db object
* - results = [id] => map to pear db object
* - resultseq = sequence id for results & results field
* - resultfields = [id] => list of fields return from query (for use with toArray())
* - ini = mapping of database to ini file results
* - links = mapping of database to links file
* - lasterror = pear error objects for last error event.
* - config = aliased view of PEAR::getStaticPropery('DB_DataObject','options') * done for performance.
* - array of loaded classes by autoload method - to stop it doing file access request over and over again!
*/
$GLOBALS['_DB_DATAOBJECT']['RESULTS'] = array();
$GLOBALS['_DB_DATAOBJECT']['RESULTSEQ'] = 1;
$GLOBALS['_DB_DATAOBJECT']['RESULTFIELDS'] = array();
$GLOBALS['_DB_DATAOBJECT']['CONNECTIONS'] = array();
$GLOBALS['_DB_DATAOBJECT']['INI'] = array();
$GLOBALS['_DB_DATAOBJECT']['LINKS'] = array();
$GLOBALS['_DB_DATAOBJECT']['SEQUENCE'] = array();
$GLOBALS['_DB_DATAOBJECT']['LASTERROR'] = null;
$GLOBALS['_DB_DATAOBJECT']['CONFIG'] = array();
$GLOBALS['_DB_DATAOBJECT']['CACHE'] = array();
$GLOBALS['_DB_DATAOBJECT']['OVERLOADED'] = false;
$GLOBALS['_DB_DATAOBJECT']['QUERYENDTIME'] = 0;
 
 
// this will be horrifically slow!!!!
// NOTE: Overload SEGFAULTS ON PHP4 + Zend Optimizer (see define before..)
// these two are BC/FC handlers for call in PHP4/5
 
if ( substr(phpversion(),0,1) == 5) {
class DB_DataObject_Overload
{
function __call($method,$args)
{
$return = null;
$this->_call($method,$args,$return);
return $return;
}
function __sleep()
{
return array_keys(get_object_vars($this)) ;
}
}
} else {
if (version_compare(phpversion(),'4.3.10','eq') && !defined('DB_DATAOBJECT_NO_OVERLOAD')) {
trigger_error(
"overload does not work with PHP4.3.10, either upgrade
(snaps.php.net) or more recent version
or define DB_DATAOBJECT_NO_OVERLOAD as per the manual.
",E_USER_ERROR);
}
 
if (!function_exists('clone')) {
// emulate clone - as per php_compact, slow but really the correct behaviour..
eval('function clone($t) { $r = $t; if (method_exists($r,"__clone")) { $r->__clone(); } return $r; }');
}
eval('
class DB_DataObject_Overload {
function __call($method,$args,&$return) {
return $this->_call($method,$args,$return);
}
}
');
}
 
 
 
 
/*
*
* @package DB_DataObject
* @author Alan Knowles <alan@akbkhome.com>
* @since PHP 4.0
*/
class DB_DataObject extends DB_DataObject_Overload
{
/**
* The Version - use this to check feature changes
*
* @access private
* @var string
*/
var $_DB_DataObject_version = "1.7.15";
 
/**
* The Database table (used by table extends)
*
* @access private
* @var string
*/
var $__table = ''; // database table
 
/**
* The Number of rows returned from a query
*
* @access public
* @var int
*/
var $N = 0; // Number of rows returned from a query
 
 
/* ============================================================= */
/* Major Public Methods */
/* (designed to be optionally then called with parent::method()) */
/* ============================================================= */
 
 
/**
* Get a result using key, value.
*
* for example
* $object->get("ID",1234);
* Returns Number of rows located (usually 1) for success,
* and puts all the table columns into this classes variables
*
* see the fetch example on how to extend this.
*
* if no value is entered, it is assumed that $key is a value
* and get will then use the first key in keys()
* to obtain the key.
*
* @param string $k column
* @param string $v value
* @access public
* @return int No. of rows
*/
function get($k = null, $v = null)
{
global $_DB_DATAOBJECT;
if (empty($_DB_DATAOBJECT['CONFIG'])) {
DB_DataObject::_loadConfig();
}
$keys = array();
if ($v === null) {
$v = $k;
$keys = $this->keys();
if (!$keys) {
$this->raiseError("No Keys available for {$this->__table}", DB_DATAOBJECT_ERROR_INVALIDCONFIG);
return false;
}
$k = $keys[0];
}
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("$k $v " .print_r($keys,true), "GET");
}
if ($v === null) {
$this->raiseError("No Value specified for get", DB_DATAOBJECT_ERROR_INVALIDARGS);
return false;
}
$this->$k = $v;
return $this->find(1);
}
 
/**
* An autoloading, caching static get method using key, value (based on get)
*
* Usage:
* $object = DB_DataObject::staticGet("DbTable_mytable",12);
* or
* $object = DB_DataObject::staticGet("DbTable_mytable","name","fred");
*
* or write it into your extended class:
* function &staticGet($k,$v=NULL) { return DB_DataObject::staticGet("This_Class",$k,$v); }
*
* @param string $class class name
* @param string $k column (or value if using keys)
* @param string $v value (optional)
* @access public
* @return object
*/
function &staticGet($class, $k, $v = null)
{
$lclass = strtolower($class);
global $_DB_DATAOBJECT;
if (empty($_DB_DATAOBJECT['CONFIG'])) {
DB_DataObject::_loadConfig();
}
 
 
$key = "$k:$v";
if ($v === null) {
$key = $k;
}
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
DB_DataObject::debug("$class $key","STATIC GET - TRY CACHE");
}
if (!empty($_DB_DATAOBJECT['CACHE'][$lclass][$key])) {
return $_DB_DATAOBJECT['CACHE'][$lclass][$key];
}
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
DB_DataObject::debug("$class $key","STATIC GET - NOT IN CACHE");
}
 
$obj = DB_DataObject::factory(substr($class,strlen($_DB_DATAOBJECT['CONFIG']['class_prefix'])));
if (PEAR::isError($obj)) {
DB_DataObject::raiseError("could not autoload $class", DB_DATAOBJECT_ERROR_NOCLASS);
return false;
}
if (!isset($_DB_DATAOBJECT['CACHE'][$lclass])) {
$_DB_DATAOBJECT['CACHE'][$lclass] = array();
}
if (!$obj->get($k,$v)) {
DB_DataObject::raiseError("No Data return from get $k $v", DB_DATAOBJECT_ERROR_NODATA);
return false;
}
$_DB_DATAOBJECT['CACHE'][$lclass][$key] = $obj;
return $_DB_DATAOBJECT['CACHE'][$lclass][$key];
}
 
/**
* find results, either normal or crosstable
*
* for example
*
* $object = new mytable();
* $object->ID = 1;
* $object->find();
*
*
* will set $object->N to number of rows, and expects next command to fetch rows
* will return $object->N
*
* @param boolean $n Fetch first result
* @access public
* @return mixed (number of rows returned, or true if numRows fetching is not supported)
*/
function find($n = false)
{
global $_DB_DATAOBJECT;
if (!isset($this->_query)) {
$this->raiseError(
"You cannot do two queries on the same object (copy it before finding)",
DB_DATAOBJECT_ERROR_INVALIDARGS);
return false;
}
if (empty($_DB_DATAOBJECT['CONFIG'])) {
DB_DataObject::_loadConfig();
}
 
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug($n, "__find",1);
}
if (!$this->__table) {
// xdebug can backtrace this!
php_error("NO \$__table SPECIFIED in class definition",E_USER_ERROR);
}
$this->N = 0;
$query_before = $this->_query;
$this->_build_condition($this->table()) ;
$quoteIdentifiers = !empty($_DB_DATAOBJECT['CONFIG']['quote_identifiers']);
$this->_connect();
$DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5];
/* We are checking for method modifyLimitQuery as it is PEAR DB specific */
$sql = 'SELECT ' .
$this->_query['data_select'] .
' FROM ' . ($quoteIdentifiers ? $DB->quoteIdentifier($this->__table) : $this->__table) . " " .
$this->_join .
$this->_query['condition'] . ' '.
$this->_query['group_by'] . ' '.
$this->_query['having'] . ' '.
$this->_query['order_by'] . ' ';
if ((!isset($_DB_DATAOBJECT['CONFIG']['db_driver'])) ||
($_DB_DATAOBJECT['CONFIG']['db_driver'] == 'DB')) {
/* PEAR DB specific */
if (isset($this->_query['limit_start']) && strlen($this->_query['limit_start'] . $this->_query['limit_count'])) {
$sql = $DB->modifyLimitQuery($sql,$this->_query['limit_start'], $this->_query['limit_count']);
}
} else {
/* theoretically MDB! */
if (isset($this->_query['limit_start']) && strlen($this->_query['limit_start'] . $this->_query['limit_count'])) {
$DB->setLimit($this->_query['limit_count'],$this->_query['limit_start']);
}
}
$this->_query($sql);
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("CHECK autofetchd $n", "__find", 1);
}
// unset the
if ($n && $this->N > 0 ) {
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("ABOUT TO AUTOFETCH", "__find", 1);
}
$this->fetch() ;
}
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("DONE", "__find", 1);
}
$this->_query = $query_before;
return $this->N;
}
 
/**
* fetches next row into this objects var's
*
* returns 1 on success 0 on failure
*
*
*
* Example
* $object = new mytable();
* $object->name = "fred";
* $object->find();
* $store = array();
* while ($object->fetch()) {
* echo $this->ID;
* $store[] = $object; // builds an array of object lines.
* }
*
* to add features to a fetch
* function fetch () {
* $ret = parent::fetch();
* $this->date_formated = date('dmY',$this->date);
* return $ret;
* }
*
* @access public
* @return boolean on success
*/
function fetch()
{
 
global $_DB_DATAOBJECT;
if (empty($_DB_DATAOBJECT['CONFIG'])) {
DB_DataObject::_loadConfig();
}
if (empty($this->N)) {
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("No data returned from FIND (eg. N is 0)","FETCH", 3);
}
return false;
}
if (empty($_DB_DATAOBJECT['RESULTS'][$this->_DB_resultid]) ||
!is_object($result = &$_DB_DATAOBJECT['RESULTS'][$this->_DB_resultid]))
{
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug('fetched on object after fetch completed (no results found)');
}
return false;
}
$array = $result->fetchRow(DB_DATAOBJECT_FETCHMODE_ASSOC);
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug(serialize($array),"FETCH");
}
 
if ($array === null) {
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$t= explode(' ',microtime());
$this->debug("Last Data Fetch'ed after " .
($t[0]+$t[1]- $_DB_DATAOBJECT['QUERYENDTIME'] ) .
" seconds",
"FETCH", 1);
}
// reduce the memory usage a bit... (but leave the id in, so count() works ok on it)
unset($_DB_DATAOBJECT['RESULTS'][$this->_DB_resultid]);
// this is probably end of data!!
//DB_DataObject::raiseError("fetch: no data returned", DB_DATAOBJECT_ERROR_NODATA);
return false;
}
if (!isset($_DB_DATAOBJECT['RESULTFIELDS'][$this->_DB_resultid])) {
// note: we dont declare this to keep the print_r size down.
$_DB_DATAOBJECT['RESULTFIELDS'][$this->_DB_resultid]= array_flip(array_keys($array));
}
foreach($array as $k=>$v) {
$kk = str_replace(".", "_", $k);
$kk = str_replace(" ", "_", $kk);
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("$kk = ". $array[$k], "fetchrow LINE", 3);
}
$this->$kk = $array[$k];
}
// set link flag
$this->_link_loaded=false;
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("{$this->__table} DONE", "fetchrow",2);
}
if (isset($this->_query) && empty($_DB_DATAOBJECT['CONFIG']['keep_query_after_fetch'])) {
unset($this->_query);
}
return true;
}
 
/**
* Adds a condition to the WHERE statement, defaults to AND
*
* $object->whereAdd(); //reset or cleaer ewhwer
* $object->whereAdd("ID > 20");
* $object->whereAdd("age > 20","OR");
*
* @param string $cond condition
* @param string $logic optional logic "OR" (defaults to "AND")
* @access public
* @return string|PEAR::Error - previous condition or Error when invalid args found
*/
function whereAdd($cond = false, $logic = 'AND')
{
if (!isset($this->_query)) {
return $this->raiseError(
"You cannot do two queries on the same object (clone it before finding)",
DB_DATAOBJECT_ERROR_INVALIDARGS);
}
if ($cond === false) {
$r = $this->_query['condition'];
$this->_query['condition'] = '';
return $r;
}
// check input...= 0 or ' ' == error!
if (!trim($cond)) {
return $this->raiseError("WhereAdd: No Valid Arguments", DB_DATAOBJECT_ERROR_INVALIDARGS);
}
$r = $this->_query['condition'];
if ($this->_query['condition']) {
$this->_query['condition'] .= " {$logic} {$cond}";
return $r;
}
$this->_query['condition'] = " WHERE {$cond}";
return $r;
}
 
/**
* Adds a order by condition
*
* $object->orderBy(); //clears order by
* $object->orderBy("ID");
* $object->orderBy("ID,age");
*
* @param string $order Order
* @access public
* @return none|PEAR::Error - invalid args only
*/
function orderBy($order = false)
{
if (!isset($this->_query)) {
$this->raiseError(
"You cannot do two queries on the same object (copy it before finding)",
DB_DATAOBJECT_ERROR_INVALIDARGS);
return false;
}
if ($order === false) {
$this->_query['order_by'] = '';
return;
}
// check input...= 0 or ' ' == error!
if (!trim($order)) {
return $this->raiseError("orderBy: No Valid Arguments", DB_DATAOBJECT_ERROR_INVALIDARGS);
}
if (!$this->_query['order_by']) {
$this->_query['order_by'] = " ORDER BY {$order} ";
return;
}
$this->_query['order_by'] .= " , {$order}";
}
 
/**
* Adds a group by condition
*
* $object->groupBy(); //reset the grouping
* $object->groupBy("ID DESC");
* $object->groupBy("ID,age");
*
* @param string $group Grouping
* @access public
* @return none|PEAR::Error - invalid args only
*/
function groupBy($group = false)
{
if (!isset($this->_query)) {
$this->raiseError(
"You cannot do two queries on the same object (copy it before finding)",
DB_DATAOBJECT_ERROR_INVALIDARGS);
return false;
}
if ($group === false) {
$this->_query['group_by'] = '';
return;
}
// check input...= 0 or ' ' == error!
if (!trim($group)) {
return $this->raiseError("groupBy: No Valid Arguments", DB_DATAOBJECT_ERROR_INVALIDARGS);
}
if (!$this->_query['group_by']) {
$this->_query['group_by'] = " GROUP BY {$group} ";
return;
}
$this->_query['group_by'] .= " , {$group}";
}
 
/**
* Adds a having clause
*
* $object->having(); //reset the grouping
* $object->having("sum(value) > 0 ");
*
* @param string $having condition
* @access public
* @return none|PEAR::Error - invalid args only
*/
function having($having = false)
{
if (!isset($this->_query)) {
$this->raiseError(
"You cannot do two queries on the same object (copy it before finding)",
DB_DATAOBJECT_ERROR_INVALIDARGS);
return false;
}
if ($having === false) {
$this->_query['having'] = '';
return;
}
// check input...= 0 or ' ' == error!
if (!trim($having)) {
return $this->raiseError("Having: No Valid Arguments", DB_DATAOBJECT_ERROR_INVALIDARGS);
}
if (!$this->_query['having']) {
$this->_query['having'] = " HAVING {$having} ";
return;
}
$this->_query['having'] .= " AND {$having}";
}
 
/**
* Sets the Limit
*
* $boject->limit(); // clear limit
* $object->limit(12);
* $object->limit(12,10);
*
* Note this will emit an error on databases other than mysql/postgress
* as there is no 'clean way' to implement it. - you should consider refering to
* your database manual to decide how you want to implement it.
*
* @param string $a limit start (or number), or blank to reset
* @param string $b number
* @access public
* @return none|PEAR::Error - invalid args only
*/
function limit($a = null, $b = null)
{
if (!isset($this->_query)) {
$this->raiseError(
"You cannot do two queries on the same object (copy it before finding)",
DB_DATAOBJECT_ERROR_INVALIDARGS);
return false;
}
if ($a === null) {
$this->_query['limit_start'] = '';
$this->_query['limit_count'] = '';
return;
}
// check input...= 0 or ' ' == error!
if ((!is_int($a) && ((string)((int)$a) !== (string)$a))
|| (($b !== null) && (!is_int($b) && ((string)((int)$b) !== (string)$b)))) {
return $this->raiseError("limit: No Valid Arguments", DB_DATAOBJECT_ERROR_INVALIDARGS);
}
global $_DB_DATAOBJECT;
$this->_connect();
$DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5];
$this->_query['limit_start'] = ($b == null) ? 0 : (int)$a;
$this->_query['limit_count'] = ($b == null) ? (int)$a : (int)$b;
}
 
/**
* Adds a select columns
*
* $object->selectAdd(); // resets select to nothing!
* $object->selectAdd("*"); // default select
* $object->selectAdd("unixtime(DATE) as udate");
* $object->selectAdd("DATE");
*
* to prepend distict:
* $object->selectAdd('distinct ' . $object->selectAdd());
*
* @param string $k
* @access public
* @return mixed null or old string if you reset it.
*/
function selectAdd($k = null)
{
if (!isset($this->_query)) {
$this->raiseError(
"You cannot do two queries on the same object (copy it before finding)",
DB_DATAOBJECT_ERROR_INVALIDARGS);
return false;
}
if ($k === null) {
$old = $this->_query['data_select'];
$this->_query['data_select'] = '';
return $old;
}
// check input...= 0 or ' ' == error!
if (!trim($k)) {
return $this->raiseError("selectAdd: No Valid Arguments", DB_DATAOBJECT_ERROR_INVALIDARGS);
}
if ($this->_query['data_select']) {
$this->_query['data_select'] .= ', ';
}
$this->_query['data_select'] .= " $k ";
}
/**
* Adds multiple Columns or objects to select with formating.
*
* $object->selectAs(null); // adds "table.colnameA as colnameA,table.colnameB as colnameB,......"
* // note with null it will also clear the '*' default select
* $object->selectAs(array('a','b'),'%s_x'); // adds "a as a_x, b as b_x"
* $object->selectAs(array('a','b'),'ddd_%s','ccc'); // adds "ccc.a as ddd_a, ccc.b as ddd_b"
* $object->selectAdd($object,'prefix_%s'); // calls $object->get_table and adds it all as
* objectTableName.colnameA as prefix_colnameA
*
* @param array|object|null the array or object to take column names from.
* @param string format in sprintf format (use %s for the colname)
* @param string table name eg. if you have joinAdd'd or send $from as an array.
* @access public
* @return void
*/
function selectAs($from = null,$format = '%s',$tableName=false)
{
global $_DB_DATAOBJECT;
if (!isset($this->_query)) {
$this->raiseError(
"You cannot do two queries on the same object (copy it before finding)",
DB_DATAOBJECT_ERROR_INVALIDARGS);
return false;
}
if ($from === null) {
// blank the '*'
$this->selectAdd();
$from = $this;
}
$table = $this->__table;
if (is_object($from)) {
$table = $from->__table;
$from = array_keys($from->table());
}
if ($tableName !== false) {
$table = $tableName;
}
$s = '%s';
if (!empty($_DB_DATAOBJECT['CONFIG']['quote_identifiers'])) {
$this->_connect();
$DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5];
$s = $DB->quoteIdentifier($s);
}
foreach ($from as $k) {
$this->selectAdd(sprintf("{$s}.{$s} as {$format}",$table,$k,$k));
}
$this->_query['data_select'] .= "\n";
}
/**
* Insert the current objects variables into the database
*
* Returns the ID of the inserted element (if auto increment or sequences are used.)
*
* for example
*
* Designed to be extended
*
* $object = new mytable();
* $object->name = "fred";
* echo $object->insert();
*
* @access public
* @return mixed false on failure, int when auto increment or sequence used, otherwise true on success
*/
function insert()
{
global $_DB_DATAOBJECT;
// we need to write to the connection (For nextid) - so us the real
// one not, a copyied on (as ret-by-ref fails with overload!)
if (!isset($_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5])) {
$this->_connect();
}
$quoteIdentifiers = !empty($_DB_DATAOBJECT['CONFIG']['quote_identifiers']);
$DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5];
$items = isset($_DB_DATAOBJECT['INI'][$this->_database][$this->__table]) ?
$_DB_DATAOBJECT['INI'][$this->_database][$this->__table] : $this->table();
if (!$items) {
$this->raiseError("insert:No table definition for {$this->__table}",
DB_DATAOBJECT_ERROR_INVALIDCONFIG);
return false;
}
$options = &$_DB_DATAOBJECT['CONFIG'];
 
 
$datasaved = 1;
$leftq = '';
$rightq = '';
$seqKeys = isset($_DB_DATAOBJECT['SEQUENCE'][$this->_database][$this->__table]) ?
$_DB_DATAOBJECT['SEQUENCE'][$this->_database][$this->__table] :
$this->sequenceKey();
$key = isset($seqKeys[0]) ? $seqKeys[0] : false;
$useNative = isset($seqKeys[1]) ? $seqKeys[1] : false;
$seq = isset($seqKeys[2]) ? $seqKeys[2] : false;
$dbtype = $_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->dsn["phptype"];
// nativeSequences or Sequences..
 
// big check for using sequences
if (($key !== false) && !$useNative) {
if (!$seq) {
$this->$key = $DB->nextId($this->__table);
} else {
$f = $DB->getOption('seqname_format');
$DB->setOption('seqname_format','%s');
$this->$key = $DB->nextId($seq);
$DB->setOption('seqname_format',$f);
}
}
 
 
 
foreach($items as $k => $v) {
// if we are using autoincrement - skip the column...
if ($key && ($k == $key) && $useNative) {
continue;
}
if (!isset($this->$k)) {
continue;
}
// dont insert data into mysql timestamps
// use query() if you really want to do this!!!!
if ($v & DB_DATAOBJECT_MYSQLTIMESTAMP) {
continue;
}
if ($leftq) {
$leftq .= ', ';
$rightq .= ', ';
}
$leftq .= ($quoteIdentifiers ? ($DB->quoteIdentifier($k) . ' ') : "$k ");
if (is_a($this->$k,'db_dataobject_cast')) {
$value = $this->$k->toString($v,$DB);
if (PEAR::isError($value)) {
$this->raiseError($value->getMessage() ,DB_DATAOBJECT_ERROR_INVALIDARG);
return false;
}
$rightq .= $value;
continue;
}
 
if ((strtolower($this->$k) === 'null') && !($v & DB_DATAOBJECT_NOTNULL)) {
$rightq .= " NULL ";
continue;
}
// DATE is empty... on a col. that can be null..
// note: this may be usefull for time as well..
if (!$this->$k &&
(($v & DB_DATAOBJECT_DATE) || ($v & DB_DATAOBJECT_TIME)) &&
!($v & DB_DATAOBJECT_NOTNULL)) {
$rightq .= " NULL ";
continue;
}
if ($v & DB_DATAOBJECT_STR) {
$rightq .= $this->_quote((string) (
($v & DB_DATAOBJECT_BOOL) ?
// this is thanks to the braindead idea of postgres to
// use t/f for boolean.
(($this->$k == 'f') ? 0 : (int)(bool) $this->$k) :
$this->$k
)) . " ";
continue;
}
if (is_numeric($this->$k)) {
$rightq .=" {$this->$k} ";
continue;
}
// at present we only cast to integers
// - V2 may store additional data about float/int
$rightq .= ' ' . intval($this->$k) . ' ';
 
}
// not sure why we let empty insert here.. - I guess to generate a blank row..
if ($leftq || $useNative) {
$table = ($quoteIdentifiers ? $DB->quoteIdentifier($this->__table) : $this->__table);
$r = $this->_query("INSERT INTO {$table} ($leftq) VALUES ($rightq) ");
if (PEAR::isError($r)) {
$this->raiseError($r);
return false;
}
if ($r < 1) {
return 0;
}
// now do we have an integer key!
if ($key && $useNative) {
switch ($dbtype) {
case 'mysql':
case 'mysqli':
$method = "{$dbtype}_insert_id";
$this->$key = $method(
$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->connection
);
break;
case 'mssql':
// note this is not really thread safe - you should wrapp it with
// transactions = eg.
// $db->query('BEGIN');
// $db->insert();
// $db->query('COMMIT');
$mssql_key = $DB->getOne("SELECT @@IDENTITY");
if (PEAR::isError($mssql_key)) {
$this->raiseError($r);
return false;
}
$this->$key = $mssql_key;
break;
case 'pgsql':
if (!$seq) {
$seq = $DB->getSequenceName($this->__table );
}
$pgsql_key = $DB->getOne("SELECT last_value FROM ".$seq);
if (PEAR::isError($pgsql_key)) {
$this->raiseError($r);
return false;
}
$this->$key = $pgsql_key;
break;
case 'ifx':
$this->$key = array_shift (
ifx_fetch_row (
ifx_query(
"select DBINFO('sqlca.sqlerrd1') FROM systables where tabid=1",
$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->connection,
IFX_SCROLL
),
"FIRST"
)
);
break;
}
}
 
if (isset($_DB_DATAOBJECT['CACHE'][strtolower(get_class($this))])) {
$this->_clear_cache();
}
if ($key) {
return $this->$key;
}
return true;
}
$this->raiseError("insert: No Data specifed for query", DB_DATAOBJECT_ERROR_NODATA);
return false;
}
 
/**
* Updates current objects variables into the database
* uses the keys() to decide how to update
* Returns the true on success
*
* for example
*
* $object = DB_DataObject::factory('mytable');
* $object->get("ID",234);
* $object->email="testing@test.com";
* if(!$object->update())
* echo "UPDATE FAILED";
*
* to only update changed items :
* $dataobject->get(132);
* $original = $dataobject; // clone/copy it..
* $dataobject->setFrom($_POST);
* if ($dataobject->validate()) {
* $dataobject->update($original);
* } // otherwise an error...
*
* performing global updates:
* $object = DB_DataObject::factory('mytable');
* $object->status = "dead";
* $object->whereAdd('age > 150');
* $object->update(DB_DATAOBJECT_WHEREADD_ONLY);
*
* @param object dataobject (optional) | DB_DATAOBJECT_WHEREADD_ONLY - used to only update changed items.
* @access public
* @return int rows affected or false on failure
*/
function update($dataObject = false)
{
global $_DB_DATAOBJECT;
// connect will load the config!
$this->_connect();
$original_query = isset($this->_query) ? $this->_query : null;
$items = isset($_DB_DATAOBJECT['INI'][$this->_database][$this->__table]) ?
$_DB_DATAOBJECT['INI'][$this->_database][$this->__table] : $this->table();
// only apply update against sequence key if it is set?????
$seq = $this->sequenceKey();
if ($seq[0] !== false) {
$keys = array($seq[0]);
if (empty($this->{$keys[0]}) && $dataObject !== true) {
$this->raiseError("update: trying to perform an update without
the key set, and argument to update is not
DB_DATAOBJECT_WHEREADD_ONLY
", DB_DATAOBJECT_ERROR_INVALIDARGS);
return false;
}
} else {
$keys = $this->keys();
}
if (!$items) {
$this->raiseError("update:No table definition for {$this->__table}", DB_DATAOBJECT_ERROR_INVALIDCONFIG);
return false;
}
$datasaved = 1;
$settings = '';
$this->_connect();
$DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5];
$dbtype = $DB->dsn["phptype"];
$quoteIdentifiers = !empty($_DB_DATAOBJECT['CONFIG']['quote_identifiers']);
foreach($items as $k => $v) {
if (!isset($this->$k)) {
continue;
}
// ignore stuff thats
// dont write things that havent changed..
if (($dataObject !== false) && isset($dataObject->$k) && ($dataObject->$k == $this->$k)) {
continue;
}
// - dont write keys to left.!!!
if (in_array($k,$keys)) {
continue;
}
// dont insert data into mysql timestamps
// use query() if you really want to do this!!!!
if ($v & DB_DATAOBJECT_MYSQLTIMESTAMP) {
continue;
}
if ($settings) {
$settings .= ', ';
}
$kSql = ($quoteIdentifiers ? $DB->quoteIdentifier($k) : $k);
if (is_a($this->$k,'db_dataobject_cast')) {
$value = $this->$k->toString($v,$DB);
if (PEAR::isError($value)) {
$this->raiseError($value->getMessage() ,DB_DATAOBJECT_ERROR_INVALIDARG);
return false;
}
$settings .= "$kSql = $value ";
continue;
}
// special values ... at least null is handled...
if ((strtolower($this->$k) === 'null') && !($v & DB_DATAOBJECT_NOTNULL)) {
$settings .= "$kSql = NULL ";
continue;
}
// DATE is empty... on a col. that can be null..
// note: this may be usefull for time as well..
if (!$this->$k &&
(($v & DB_DATAOBJECT_DATE) || ($v & DB_DATAOBJECT_TIME)) &&
!($v & DB_DATAOBJECT_NOTNULL)) {
$settings .= "$kSql = NULL ";
continue;
}
 
if ($v & DB_DATAOBJECT_STR) {
$settings .= "$kSql = ". $this->_quote((string) (
($v & DB_DATAOBJECT_BOOL) ?
// this is thanks to the braindead idea of postgres to
// use t/f for boolean.
(($this->$k == 'f') ? 0 : (int)(bool) $this->$k) :
$this->$k
)) . ' ';
continue;
}
if (is_numeric($this->$k)) {
$settings .= "$kSql = {$this->$k} ";
continue;
}
// at present we only cast to integers
// - V2 may store additional data about float/int
$settings .= "$kSql = " . intval($this->$k) . ' ';
}
 
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("got keys as ".serialize($keys),3);
}
if ($dataObject !== true) {
$this->_build_condition($items,$keys);
} else {
// prevent wiping out of data!
if (empty($this->_query['condition'])) {
$this->raiseError("update: global table update not available
do \$do->whereAdd('1=1'); if you really want to do that.
", DB_DATAOBJECT_ERROR_INVALIDARGS);
return false;
}
}
// echo " $settings, $this->condition ";
if ($settings && isset($this->_query) && $this->_query['condition']) {
$table = ($quoteIdentifiers ? $DB->quoteIdentifier($this->__table) : $this->__table);
$r = $this->_query("UPDATE {$table} SET {$settings} {$this->_query['condition']} ");
// restore original query conditions.
$this->_query = $original_query;
if (PEAR::isError($r)) {
$this->raiseError($r);
return false;
}
if ($r < 1) {
return 0;
}
 
$this->_clear_cache();
return $r;
}
// restore original query conditions.
$this->_query = $original_query;
// if you manually specified a dataobject, and there where no changes - then it's ok..
if ($dataObject !== false) {
return true;
}
$this->raiseError(
"update: No Data specifed for query $settings , {$this->_query['condition']}",
DB_DATAOBJECT_ERROR_NODATA);
return false;
}
 
/**
* Deletes items from table which match current objects variables
*
* Returns the true on success
*
* for example
*
* Designed to be extended
*
* $object = new mytable();
* $object->ID=123;
* echo $object->delete(); // builds a conditon
*
* $object = new mytable();
* $object->whereAdd('age > 12');
* $object->limit(1);
* $object->orderBy('age DESC');
* $object->delete(true); // dont use object vars, use the conditions, limit and order.
*
* @param bool $useWhere (optional) If DB_DATAOBJECT_WHEREADD_ONLY is passed in then
* we will build the condition only using the whereAdd's. Default is to
* build the condition only using the object parameters.
*
* @access public
* @return mixed True on success, false on failure, 0 on no data affected
*/
function delete($useWhere = false)
{
global $_DB_DATAOBJECT;
// connect will load the config!
$this->_connect();
$DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5];
$quoteIdentifiers = !empty($_DB_DATAOBJECT['CONFIG']['quote_identifiers']);
$extra_cond = ' ' . (isset($this->_query['order_by']) ? $this->_query['order_by'] : '');
if (!$useWhere) {
 
$keys = $this->keys();
$this->_query = array(); // as it's probably unset!
$this->_query['condition'] = ''; // default behaviour not to use where condition
$this->_build_condition($this->table(),$keys);
// if primary keys are not set then use data from rest of object.
if (!$this->_query['condition']) {
$this->_build_condition($this->table(),array(),$keys);
}
$extra_cond = '';
}
 
// don't delete without a condition
if (isset($this->_query) && $this->_query['condition']) {
$table = ($quoteIdentifiers ? $DB->quoteIdentifier($this->__table) : $this->__table);
$sql = "DELETE FROM {$table} {$this->_query['condition']}{$extra_cond}";
// add limit..
if (isset($this->_query['limit_start']) && strlen($this->_query['limit_start'] . $this->_query['limit_count'])) {
if (!isset($_DB_DATAOBJECT['CONFIG']['db_driver']) ||
($_DB_DATAOBJECT['CONFIG']['db_driver'] == 'DB')) {
// pear DB
$sql = $DB->modifyLimitQuery($sql,$this->_query['limit_start'], $this->_query['limit_count']);
} else {
// MDB
$DB->setLimit( $this->_query['limit_count'],$this->_query['limit_start']);
}
}
$r = $this->_query($sql);
if (PEAR::isError($r)) {
$this->raiseError($r);
return false;
}
if ($r < 1) {
return 0;
}
$this->_clear_cache();
return $r;
} else {
$this->raiseError("delete: No condition specifed for query", DB_DATAOBJECT_ERROR_NODATA);
return false;
}
}
 
/**
* fetches a specific row into this object variables
*
* Not recommended - better to use fetch()
*
* Returens true on success
*
* @param int $row row
* @access public
* @return boolean true on success
*/
function fetchRow($row = null)
{
global $_DB_DATAOBJECT;
if (empty($_DB_DATAOBJECT['CONFIG'])) {
$this->_loadConfig();
}
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("{$this->__table} $row of {$this->N}", "fetchrow",3);
}
if (!$this->__table) {
$this->raiseError("fetchrow: No table", DB_DATAOBJECT_ERROR_INVALIDCONFIG);
return false;
}
if ($row === null) {
$this->raiseError("fetchrow: No row specified", DB_DATAOBJECT_ERROR_INVALIDARGS);
return false;
}
if (!$this->N) {
$this->raiseError("fetchrow: No results avaiable", DB_DATAOBJECT_ERROR_NODATA);
return false;
}
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("{$this->__table} $row of {$this->N}", "fetchrow",3);
}
 
 
$result = &$_DB_DATAOBJECT['RESULTS'][$this->_DB_resultid];
$array = $result->fetchrow(DB_DATAOBJECT_FETCHMODE_ASSOC,$row);
if (!is_array($array)) {
$this->raiseError("fetchrow: No results available", DB_DATAOBJECT_ERROR_NODATA);
return false;
}
 
foreach($array as $k => $v) {
$kk = str_replace(".", "_", $k);
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("$kk = ". $array[$k], "fetchrow LINE", 3);
}
$this->$kk = $array[$k];
}
 
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("{$this->__table} DONE", "fetchrow", 3);
}
return true;
}
 
/**
* Find the number of results from a simple query
*
* for example
*
* $object = new mytable();
* $object->name = "fred";
* echo $object->count();
* echo $object->count(true); // dont use object vars.
* echo $object->count('distinct mycol'); count distinct mycol.
* echo $object->count('distinct mycol',true); // dont use object vars.
* echo $object->count('distinct'); // count distinct id (eg. the primary key)
*
*
* @param bool|string (optional)
* (true|false => see below not on whereAddonly)
* (string)
* "DISTINCT" => does a distinct count on the tables 'key' column
* otherwise => normally it counts primary keys - you can use
* this to do things like $do->count('distinct mycol');
*
* @param bool $whereAddOnly (optional) If DB_DATAOBJECT_WHEREADD_ONLY is passed in then
* we will build the condition only using the whereAdd's. Default is to
* build the condition using the object parameters as well.
*
* @access public
* @return int
*/
function count($countWhat = false,$whereAddOnly = false)
{
global $_DB_DATAOBJECT;
if (is_bool($countWhat)) {
$whereAddOnly = $countWhat;
}
$t = clone($this);
$quoteIdentifiers = !empty($_DB_DATAOBJECT['CONFIG']['quote_identifiers']);
$items = $t->table();
if (!isset($t->_query)) {
$this->raiseError(
"You cannot do run count after you have run fetch()",
DB_DATAOBJECT_ERROR_INVALIDARGS);
return false;
}
$this->_connect();
$DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5];
 
if (!$whereAddOnly && $items) {
$t->_build_condition($items);
}
$keys = $this->keys();
 
if (!$keys[0] && !is_string($countWhat)) {
$this->raiseError(
"You cannot do run count without keys - use \$do->keys('id');",
DB_DATAOBJECT_ERROR_INVALIDARGS,PEAR_ERROR_DIE);
return false;
}
$table = ($quoteIdentifiers ? $DB->quoteIdentifier($this->__table) : $this->__table);
$key_col = ($quoteIdentifiers ? $DB->quoteIdentifier($keys[0]) : $keys[0]);
$as = ($quoteIdentifiers ? $DB->quoteIdentifier('DATAOBJECT_NUM') : 'DATAOBJECT_NUM');
// support distinct on default keys.
$countWhat = (strtoupper($countWhat) == 'DISTINCT') ?
"DISTINCT {$table}.{$key_col}" : $countWhat;
$countWhat = is_string($countWhat) ? $countWhat : "{$table}.{$key_col}";
$r = $t->_query(
"SELECT count({$countWhat}) as $as
FROM $table {$t->_join} {$t->_query['condition']}");
if (PEAR::isError($r)) {
return false;
}
$result = &$_DB_DATAOBJECT['RESULTS'][$t->_DB_resultid];
$l = $result->fetchRow();
return $l[0];
}
 
/**
* sends raw query to database
*
* Since _query has to be a private 'non overwriteable method', this is a relay
*
* @param string $string SQL Query
* @access public
* @return void or DB_Error
*/
function query($string)
{
return $this->_query($string);
}
 
 
/**
* an escape wrapper around DB->escapeSimple()
* can be used when adding manual queries or clauses
* eg.
* $object->query("select * from xyz where abc like '". $object->escape($_GET['name']) . "'");
*
* @param string $string value to be escaped
* @access public
* @return string
*/
function escape($string)
{
global $_DB_DATAOBJECT;
$this->_connect();
$DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5];
// mdb uses escape...
$dd = empty($_DB_DATAOBJECT['CONFIG']['db_driver']) ? 'DB' : $_DB_DATAOBJECT['CONFIG']['db_driver'];
return ($dd == 'DB') ? $DB->escapeSimple($string) : $DB->escape($string);
}
 
/* ==================================================== */
/* Major Private Vars */
/* ==================================================== */
 
/**
* The Database connection dsn (as described in the PEAR DB)
* only used really if you are writing a very simple application/test..
* try not to use this - it is better stored in configuration files..
*
* @access private
* @var string
*/
var $_database_dsn = '';
 
/**
* The Database connection id (md5 sum of databasedsn)
*
* @access private
* @var string
*/
var $_database_dsn_md5 = '';
 
/**
* The Database name
* created in __connection
*
* @access private
* @var string
*/
var $_database = '';
 
/**
* The QUERY rules
* This replaces alot of the private variables
* used to build a query, it is unset after find() is run.
*
*
*
* @access private
* @var array
*/
var $_query = array(
'condition' => '', // the WHERE condition
'group_by' => '', // the GROUP BY condition
'order_by' => '', // the ORDER BY condition
'having' => '', // the HAVING condition
'limit_start' => '', // the LIMIT condition
'limit_count' => '', // the LIMIT condition
'data_select' => '*', // the columns to be SELECTed
);
 
/**
* Database result id (references global $_DB_DataObject[results]
*
* @access private
* @var integer
*/
var $_DB_resultid; // database result object
 
 
/* ============================================================== */
/* Table definition layer (started of very private but 'came out'*/
/* ============================================================== */
 
/**
* Autoload or manually load the table definitions
*
*
* usage :
* DB_DataObject::databaseStructure( 'databasename',
* parse_ini_file('mydb.ini',true),
* parse_ini_file('mydb.link.ini',true));
*
* obviously you dont have to use ini files.. (just return array similar to ini files..)
*
* It should append to the table structure array
*
*
* @param optional string name of database to assign / read
* @param optional array structure of database, and keys
* @param optional array table links
*
* @access public
* @return true or PEAR:error on wrong paramenters.. or false if no file exists..
* or the array(tablename => array(column_name=>type)) if called with 1 argument.. (databasename)
*/
function databaseStructure()
{
 
global $_DB_DATAOBJECT;
// Assignment code
if ($args = func_get_args()) {
if (count($args) == 1) {
// this returns all the tables and their structure..
$x = new DB_DataObject;
$x->_database = $args[0];
$this->_connect();
$DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5];
$tables = $DB->getListOf('tables');
require_once 'DB/DataObject/Generator.php';
foreach($tables as $table) {
$y = new DB_DataObject_Generator;
$y->fillTableSchema($x->_database,$table);
}
return $_DB_DATAOBJECT['INI'][$x->_database];
} else {
$_DB_DATAOBJECT['INI'][$args[0]] = isset($_DB_DATAOBJECT['INI'][$args[0]]) ?
$_DB_DATAOBJECT['INI'][$args[0]] + $args[1] : $args[1];
if (isset($args[1])) {
$_DB_DATAOBJECT['LINKS'][$args[0]] = isset($_DB_DATAOBJECT['LINKS'][$args[0]]) ?
$_DB_DATAOBJECT['LINKS'][$args[0]] + $args[2] : $args[2];
}
return true;
}
}
if (!$this->_database) {
$this->_connect();
}
// loaded already?
if (!empty($_DB_DATAOBJECT['INI'][$this->_database])) {
// database loaded - but this is table is not available..
if (empty($_DB_DATAOBJECT['INI'][$this->_database][$this->__table])) {
require_once 'DB/DataObject/Generator.php';
$x = new DB_DataObject_Generator;
$x->fillTableSchema($this->_database,$this->__table);
}
return true;
}
if (empty($_DB_DATAOBJECT['CONFIG'])) {
DB_DataObject::_loadConfig();
}
// if you supply this with arguments, then it will take those
// as the database and links array...
$schemas = isset($_DB_DATAOBJECT['CONFIG']['schema_location']) ?
array("{$_DB_DATAOBJECT['CONFIG']['schema_location']}/{$this->_database}.ini") :
array() ;
if (isset($_DB_DATAOBJECT['CONFIG']["ini_{$this->_database}"])) {
$schemas = is_array($_DB_DATAOBJECT['CONFIG']["ini_{$this->_database}"]) ?
$_DB_DATAOBJECT['CONFIG']["ini_{$this->_database}"] :
explode(PATH_SEPARATOR,$_DB_DATAOBJECT['CONFIG']["ini_{$this->_database}"]);
}
foreach ($schemas as $ini) {
$links =
isset($_DB_DATAOBJECT['CONFIG']["links_{$this->_database}"]) ?
$_DB_DATAOBJECT['CONFIG']["links_{$this->_database}"] :
str_replace('.ini','.links.ini',$ini);
 
if (file_exists($ini) && is_file($ini)) {
$_DB_DATAOBJECT['INI'][$this->_database] = parse_ini_file($ini, true);
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("Loaded ini file: $ini","databaseStructure",1);
}
} else {
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("Missing ini file: $ini","databaseStructure",1);
}
}
if (empty($_DB_DATAOBJECT['LINKS'][$this->_database]) && file_exists($links) && is_file($links)) {
/* not sure why $links = ... here - TODO check if that works */
$_DB_DATAOBJECT['LINKS'][$this->_database] = parse_ini_file($links, true);
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("Loaded links.ini file: $links","databaseStructure",1);
}
} else {
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("Missing links.ini file: $links","databaseStructure",1);
}
}
}
// now have we loaded the structure.. - if not try building it..
if (empty($_DB_DATAOBJECT['INI'][$this->_database][$this->__table])) {
require_once 'DB/DataObject/Generator.php';
$x = new DB_DataObject_Generator;
$x->fillTableSchema($this->_database,$this->__table);
}
return true;
}
 
 
 
 
/**
* Return or assign the name of the current table
*
*
* @param string optinal table name to set
* @access public
* @return string The name of the current table
*/
function tableName()
{
$args = func_get_args();
if (count($args)) {
$this->__table = $args[0];
}
return $this->__table;
}
/**
* Return or assign the name of the current database
*
* @param string optional database name to set
* @access public
* @return string The name of the current database
*/
function database()
{
$args = func_get_args();
if (count($args)) {
$this->_database = $args[0];
}
return $this->_database;
}
/**
* get/set an associative array of table columns
*
* @access public
* @param array key=>type array
* @return array (associative)
*/
function table()
{
// for temporary storage of database fields..
// note this is not declared as we dont want to bloat the print_r output
$args = func_get_args();
if (count($args)) {
$this->_database_fields = $args[0];
}
if (isset($this->_database_fields)) {
return $this->_database_fields;
}
global $_DB_DATAOBJECT;
if (!isset($_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5])) {
$this->_connect();
}
if (isset($_DB_DATAOBJECT['INI'][$this->_database][$this->__table])) {
return $_DB_DATAOBJECT['INI'][$this->_database][$this->__table];
}
$this->databaseStructure();
$ret = array();
if (isset($_DB_DATAOBJECT['INI'][$this->_database][$this->__table])) {
$ret = $_DB_DATAOBJECT['INI'][$this->_database][$this->__table];
}
return $ret;
}
 
/**
* get/set an array of table primary keys
*
* set usage: $do->keys('id','code');
*
* This is defined in the table definition if it gets it wrong,
* or you do not want to use ini tables, you can override this.
* @param string optional set the key
* @param * optional set more keys
* @access private
* @return array
*/
function keys()
{
// for temporary storage of database fields..
// note this is not declared as we dont want to bloat the print_r output
$args = func_get_args();
if (count($args)) {
$this->_database_keys = $args;
}
if (isset($this->_database_keys)) {
return $this->_database_keys;
}
global $_DB_DATAOBJECT;
if (!isset($_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5])) {
$this->_connect();
}
if (isset($_DB_DATAOBJECT['INI'][$this->_database][$this->__table."__keys"])) {
return array_keys($_DB_DATAOBJECT['INI'][$this->_database][$this->__table."__keys"]);
}
$this->databaseStructure();
if (isset($_DB_DATAOBJECT['INI'][$this->_database][$this->__table."__keys"])) {
return array_keys($_DB_DATAOBJECT['INI'][$this->_database][$this->__table."__keys"]);
}
return array();
}
/**
* get/set an sequence key
*
* by default it returns the first key from keys()
* set usage: $do->sequenceKey('id',true);
*
* override this to return array(false,false) if table has no real sequence key.
*
* @param string optional the key sequence/autoinc. key
* @param boolean optional use native increment. default false
* @param false|string optional native sequence name
* @access private
* @return array (column,use_native,sequence_name)
*/
function sequenceKey()
{
global $_DB_DATAOBJECT;
// call setting
if (!$this->_database) {
$this->_connect();
}
if (!isset($_DB_DATAOBJECT['SEQUENCE'][$this->_database])) {
$_DB_DATAOBJECT['SEQUENCE'][$this->_database] = array();
}
 
$args = func_get_args();
if (count($args)) {
$args[1] = isset($args[1]) ? $args[1] : false;
$args[2] = isset($args[2]) ? $args[2] : false;
$_DB_DATAOBJECT['SEQUENCE'][$this->_database][$this->__table] = $args;
}
if (isset($_DB_DATAOBJECT['SEQUENCE'][$this->_database][$this->__table])) {
return $_DB_DATAOBJECT['SEQUENCE'][$this->_database][$this->__table];
}
// end call setting (eg. $do->sequenceKeys(a,b,c); )
$keys = $this->keys();
if (!$keys) {
return $_DB_DATAOBJECT['SEQUENCE'][$this->_database][$this->__table]
= array(false,false,false);;
}
 
$table = isset($_DB_DATAOBJECT['INI'][$this->_database][$this->__table]) ?
$_DB_DATAOBJECT['INI'][$this->_database][$this->__table] : $this->table();
$dbtype = $_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->dsn['phptype'];
$usekey = $keys[0];
$seqname = false;
if (!empty($_DB_DATAOBJECT['CONFIG']['sequence_'.$this->__table])) {
$usekey = $_DB_DATAOBJECT['CONFIG']['sequence_'.$this->__table];
if (strpos($usekey,':') !== false) {
list($usekey,$seqname) = explode(':',$usekey);
}
}
// if the key is not an integer - then it's not a sequence or native
if (!($table[$usekey] & DB_DATAOBJECT_INT)) {
return $_DB_DATAOBJECT['SEQUENCE'][$this->_database][$this->__table] = array(false,false,false);
}
if (!empty($_DB_DATAOBJECT['CONFIG']['ignore_sequence_keys'])) {
$ignore = $_DB_DATAOBJECT['CONFIG']['ignore_sequence_keys'];
if (is_string($ignore) && (strtoupper($ignore) == 'ALL')) {
return $_DB_DATAOBJECT['SEQUENCE'][$this->_database][$this->__table] = array(false,false,$seqname);
}
if (is_string($ignore)) {
$ignore = $_DB_DATAOBJECT['CONFIG']['ignore_sequence_keys'] = explode(',',$ignore);
}
if (in_array($this->__table,$ignore)) {
return $_DB_DATAOBJECT['SEQUENCE'][$this->_database][$this->__table] = array(false,false,$seqname);
}
}
$realkeys = $_DB_DATAOBJECT['INI'][$this->_database][$this->__table."__keys"];
// if you are using an old ini file - go back to old behaviour...
if (is_numeric($realkeys[$usekey])) {
$realkeys[$usekey] = 'N';
}
// multiple unique primary keys without a native sequence...
if (($realkeys[$usekey] == 'K') && (count($keys) > 1)) {
return $_DB_DATAOBJECT['SEQUENCE'][$this->_database][$this->__table] = array(false,false,$seqname);
}
// use native sequence keys...
// technically postgres native here...
// we need to get the new improved tabledata sorted out first.
if ( in_array($dbtype , array( 'mysql', 'mysqli', 'mssql', 'ifx')) &&
($table[$usekey] & DB_DATAOBJECT_INT) &&
isset($realkeys[$usekey]) && ($realkeys[$usekey] == 'N')
) {
return $_DB_DATAOBJECT['SEQUENCE'][$this->_database][$this->__table] = array($usekey,true,$seqname);
}
// if not a native autoinc, and we have not assumed all primary keys are sequence
if (($realkeys[$usekey] != 'N') &&
!empty($_DB_DATAOBJECT['CONFIG']['dont_use_pear_sequences'])) {
return array(false,false,false);
}
// I assume it's going to try and be a nextval DB sequence.. (not native)
return $_DB_DATAOBJECT['SEQUENCE'][$this->_database][$this->__table] = array($usekey,false,$seqname);
}
/* =========================================================== */
/* Major Private Methods - the core part! */
/* =========================================================== */
 
/**
* clear the cache values for this class - normally done on insert/update etc.
*
* @access private
* @return void
*/
function _clear_cache()
{
global $_DB_DATAOBJECT;
$class = get_class($this);
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("Clearing Cache for ".$class,1);
}
if (!empty($_DB_DATAOBJECT['CACHE'][$class])) {
unset($_DB_DATAOBJECT['CACHE'][$class]);
}
}
 
/**
* backend wrapper for quoting, as MDB and DB do it differently...
*
* @access private
* @return string quoted
*/
function _quote($str)
{
global $_DB_DATAOBJECT;
return (empty($_DB_DATAOBJECT['CONFIG']['db_driver']) ||
($_DB_DATAOBJECT['CONFIG']['db_driver'] == 'DB'))
? $_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->quoteSmart($str)
: $_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->quote($str);
}
/**
* connects to the database
*
*
* TODO: tidy this up - This has grown to support a number of connection options like
* a) dynamic changing of ini file to change which database to connect to
* b) multi data via the table_{$table} = dsn ini option
* c) session based storage.
*
* @access private
* @return true | PEAR::error
*/
function _connect()
{
global $_DB_DATAOBJECT;
if (empty($_DB_DATAOBJECT['CONFIG'])) {
$this->_loadConfig();
}
 
// is it already connected ?
 
if ($this->_database_dsn_md5 && !empty($_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5])) {
if (PEAR::isError($_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5])) {
return $this->raiseError(
$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->message,
$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->code, PEAR_ERROR_DIE
);
}
 
if (!$this->_database) {
$this->_database = $_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->dsn['database'];
if (($_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->dsn['phptype'] == 'sqlite')
&& is_file($this->_database))
{
$this->_database = basename($this->_database);
}
}
// theoretically we have a md5, it's listed in connections and it's not an error.
// so everything is ok!
return true;
}
 
// it's not currently connected!
// try and work out what to use for the dsn !
 
$options= &$_DB_DATAOBJECT['CONFIG'];
$dsn = isset($this->_database_dsn) ? $this->_database_dsn : null;
 
if (!$dsn) {
if (!$this->_database) {
$this->_database = isset($options["table_{$this->__table}"]) ? $options["table_{$this->__table}"] : null;
}
if ($this->_database && !empty($options["database_{$this->_database}"])) {
$dsn = $options["database_{$this->_database}"];
} else if (!empty($options['database'])) {
$dsn = $options['database'];
}
}
// if still no database...
if (!$dsn) {
return $this->raiseError(
"No database name / dsn found anywhere",
DB_DATAOBJECT_ERROR_INVALIDCONFIG, PEAR_ERROR_DIE
);
}
 
$this->_database_dsn_md5 = md5($dsn);
 
if (!empty($_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5])) {
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("USING CACHED CONNECTION", "CONNECT",3);
}
if (!$this->_database) {
$this->_database = $_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->dsn["database"];
if (($_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->dsn['phptype'] == 'sqlite')
&& is_file($this->_database))
{
$this->_database = basename($this->_database);
}
}
return true;
}
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug("NEW CONNECTION", "CONNECT",3);
/* actualy make a connection */
$this->debug("{$dsn} {$this->_database_dsn_md5}", "CONNECT",3);
}
// Note this is verbose deliberatly!
if (!isset($_DB_DATAOBJECT['CONFIG']['db_driver']) ||
($_DB_DATAOBJECT['CONFIG']['db_driver'] == 'DB')) {
/* PEAR DB connect */
// this allows the setings of compatibility on DB
$db_options = PEAR::getStaticProperty('DB','options');
require_once 'DB.php';
if ($db_options) {
$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5] = DB::connect($dsn,$db_options);
} else {
$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5] = DB::connect($dsn);
}
} else {
/* assumption is MDB */
require_once 'MDB2.php';
// this allows the setings of compatibility on MDB2
$db_options = PEAR::getStaticProperty('MDB2','options');
if ($db_options) {
$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5] = MDB2::connect($dsn,$db_options);
} else {
$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5] = MDB2::connect($dsn);
}
}
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug(serialize($_DB_DATAOBJECT['CONNECTIONS']), "CONNECT",5);
}
if (PEAR::isError($_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5])) {
$this->debug($_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->toString(), "CONNECT FAILED",5);
return $this->raiseError(
"Connect failed, turn on debugging to 5 see why",
$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->code, PEAR_ERROR_DIE
);
 
}
 
if (!$this->_database) {
$this->_database = $_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->dsn["database"];
if (($_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->dsn['phptype'] == 'sqlite')
&& is_file($this->_database))
{
$this->_database = basename($this->_database);
}
}
// Oracle need to optimize for portibility - not sure exactly what this does though :)
$c = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5];
return true;
}
 
/**
* sends query to database - this is the private one that must work
* - internal functions use this rather than $this->query()
*
* @param string $string
* @access private
* @return mixed none or PEAR_Error
*/
function _query($string)
{
global $_DB_DATAOBJECT;
$this->_connect();
 
$DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5];
 
$options = &$_DB_DATAOBJECT['CONFIG'];
$_DB_driver = empty($_DB_DATAOBJECT['CONFIG']['db_driver']) ?
'DB': $_DB_DATAOBJECT['CONFIG']['db_driver'];
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug($string,$log="QUERY");
}
if (strtoupper($string) == 'BEGIN') {
if ($_DB_driver == 'DB') {
$DB->autoCommit(false);
} else {
$DB->beginTransaction();
}
// db backend adds begin anyway from now on..
return true;
}
if (strtoupper($string) == 'COMMIT') {
$res = $DB->commit();
if ($_DB_driver == 'DB') {
$DB->autoCommit(true);
}
return $res;
}
if (strtoupper($string) == 'ROLLBACK') {
$DB->rollback();
if ($_DB_driver == 'DB') {
$DB->autoCommit(true);
}
return true;
}
 
if (!empty($options['debug_ignore_updates']) &&
(strtolower(substr(trim($string), 0, 6)) != 'select') &&
(strtolower(substr(trim($string), 0, 4)) != 'show') &&
(strtolower(substr(trim($string), 0, 8)) != 'describe')) {
 
$this->debug('Disabling Update as you are in debug mode');
return $this->raiseError("Disabling Update as you are in debug mode", null) ;
 
}
//if (@$_DB_DATAOBJECT['CONFIG']['debug'] > 1) {
// this will only work when PEAR:DB supports it.
//$this->debug($DB->getAll('explain ' .$string,DB_DATAOBJECT_FETCHMODE_ASSOC), $log="sql",2);
//}
// some sim
$t= explode(' ',microtime());
$_DB_DATAOBJECT['QUERYENDTIME'] = $time = $t[0]+$t[1];
$result = $DB->query($string);
 
if (is_a($result,'DB_Error')) {
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug($result->toString(), "Query Error",1 );
}
return $this->raiseError($result);
}
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$t= explode(' ',microtime());
$_DB_DATAOBJECT['QUERYENDTIME'] = $t[0]+$t[1];
$this->debug('QUERY DONE IN '.($t[0]+$t[1]-$time)." seconds", 'query',1);
}
switch (strtolower(substr(trim($string),0,6))) {
case 'insert':
case 'update':
case 'delete':
if ($_DB_driver == 'DB') {
// pear DB specific
return $DB->affectedRows();
}
return $result;
}
if (is_object($result)) {
// lets hope that copying the result object is OK!
$_DB_resultid = $GLOBALS['_DB_DATAOBJECT']['RESULTSEQ']++;
$_DB_DATAOBJECT['RESULTS'][$_DB_resultid] = $result;
$this->_DB_resultid = $_DB_resultid;
}
$this->N = 0;
if (!empty($_DB_DATAOBJECT['CONFIG']['debug'])) {
$this->debug(serialize($result), 'RESULT',5);
}
if (method_exists($result, 'numrows')) {
$DB->expectError(DB_ERROR_UNSUPPORTED);
$this->N = $result->numrows();
if (is_a($this->N,'DB_Error')) {
$this->N = true;
}
$DB->popExpect();
}
}
 
/**
* Builds the WHERE based on the values of of this object
*
* @param mixed $keys
* @param array $filter (used by update to only uses keys in this filter list).
* @param array $negative_filter (used by delete to prevent deleting using the keys mentioned..)
* @access private
* @return string
*/
function _build_condition($keys, $filter = array(),$negative_filter=array())
{
global $_DB_DATAOBJECT;
$this->_connect();
$DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5];
$quoteIdentifiers = !empty($_DB_DATAOBJECT['CONFIG']['quote_identifiers']);
// if we dont have query vars.. - reset them.
if (!isset($this->_query)) {
$x = new DB_DataObject;
$this->_query= $x->_query;
}
 
foreach($keys as $k => $v) {
// index keys is an indexed array
/* these filter checks are a bit suspicious..
- need to check that update really wants to work this way */
 
if ($filter) {
if (!in_array($k, $filter)) {
continue;
}
}
if ($negative_filter) {
if (in_array($k, $negative_filter)) {
continue;
}
}
if (!isset($this->$k)) {
continue;
}
$kSql = $quoteIdentifiers
? ( $DB->quoteIdentifier($this->__table) . '.' . $DB->quoteIdentifier($k) )
: "{$this->__table}.{$k}";
if (is_a($this->$k,'db_dataobject_cast')) {
$dbtype = $DB->dsn["phptype"];
$value = $this->$k->toString($v,$DB);
if (PEAR::isError($value)) {
$this->raiseError($value->getMessage() ,DB_DATAOBJECT_ERROR_INVALIDARG);
return false;
}
if ((strtolower($value) === 'null') && !($v & DB_DATAOBJECT_NOTNULL)) {
$this->whereAdd(" $kSql IS NULL");
continue;
}
$this->whereAdd(" $kSql = $value");
continue;
}
if ((strtolower($this->$k) === 'null') && !($v & DB_DATAOBJECT_NOTNULL)) {
$this->whereAdd(" $kSql IS NULL");
continue;
}
 
if ($v & DB_DATAOBJECT_STR) {
$this->whereAdd(" $kSql = " . $this->_quote((string) (
($v & DB_DATAOBJECT_BOOL) ?
// this is thanks to the braindead idea of postgres to
// use t/f for boolean.
(($this->$k == 'f') ? 0 : (int)(bool) $this->$k) :
$this->$k
)) );
continue;
}
if (is_numeric($this->$k)) {
$this->whereAdd(" $kSql = {$this->$k}");
continue;
}
/* this is probably an error condition! */
$this->whereAdd(" $kSql = ".intval($this->$k));
}
}
 
/**
* autoload Class relating to a table
* (depreciated - use ::factory)
*
* @param string $table table
* @access private
* @return string classname on Success
*/
function staticAutoloadTable($table)
{
global $_DB_DATAOBJECT;
if (empty($_DB_DATAOBJECT['CONFIG'])) {
DB_DataObject::_loadConfig();
}
$p = isset($_DB_DATAOBJECT['CONFIG']['class_prefix']) ?
$_DB_DATAOBJECT['CONFIG']['class_prefix'] : '';
$class = $p . preg_replace('/[^A-Z0-9]/i','_',ucfirst($table));
$class = (class_exists($class)) ? $class : DB_DataObject::_autoloadClass($class);
return $class;
}
/**
* classic factory method for loading a table class
* usage: $do = DB_DataObject::factory('person')
* WARNING - this may emit a include error if the file does not exist..
* use @ to silence it (if you are sure it is acceptable)
* eg. $do = @DB_DataObject::factory('person')
*
* table name will eventually be databasename/table
* - and allow modular dataobjects to be written..
* (this also helps proxy creation)
*
*
* @param string $table tablename (use blank to create a new instance of the same class.)
* @access private
* @return DataObject|PEAR_Error
*/
 
function factory($table = '') {
global $_DB_DATAOBJECT;
if (empty($_DB_DATAOBJECT['CONFIG'])) {
DB_DataObject::_loadConfig();
}
if ($table === '') {
if (is_a($this,'DB_DataObject') && strlen($this->__table)) {
$table = $this->__table;
} else {
return DB_DataObject::raiseError(
"factory did not recieve a table name",
DB_DATAOBJECT_ERROR_INVALIDARGS);
}
}
$p = isset($_DB_DATAOBJECT['CONFIG']['class_prefix']) ?
$_DB_DATAOBJECT['CONFIG']['class_prefix'] : '';
$class = $p . preg_replace('/[^A-Z0-9]/i','_',ucfirst($table));
$class = (class_exists($class)) ? $class : DB_DataObject::_autoloadClass($class);
// proxy = full|light
if (!$class && isset($_DB_DATAOBJECT['CONFIG']['proxy'])) {
$proxyMethod = 'getProxy'.$_DB_DATAOBJECT['CONFIG']['proxy'];
require_once 'DB/DataObject/Generator.php';
$d = new DB_DataObject;
$d->__table = $table;
$d->_connect();
$x = new DB_DataObject_Generator;
return $x->$proxyMethod( $d->_database, $table);
}
if (!$class) {
return DB_DataObject::raiseError(
"factory could not find class $class from $table",
DB_DATAOBJECT_ERROR_INVALIDCONFIG);
}
 
return new $class;
}
/**
* autoload Class
*
* @param string $class Class
* @access private
* @return string classname on Success
*/
function _autoloadClass($class)
{
global $_DB_DATAOBJECT;
if (empty($_DB_DATAOBJECT['CONFIG'])) {
DB_DataObject::_loadConfig();
}
$table = substr($class,strlen($_DB_DATAOBJECT['CONFIG']['class_prefix']));
 
// only include the file if it exists - and barf badly if it has parse errors :)
if (!empty($_DB_DATAOBJECT['CONFIG']['proxy']) && empty($_DB_DATAOBJECT['CONFIG']['class_location'])) {
return false;
}
if (strpos($_DB_DATAOBJECT['CONFIG']['class_location'],'%s') !== false) {
$file = sprintf($_DB_DATAOBJECT['CONFIG']['class_location'], preg_replace('/[^A-Z0-9]/i','_',ucfirst($table)));
} else {
$file = $_DB_DATAOBJECT['CONFIG']['class_location'].'/'.preg_replace('/[^A-Z0-9]/i','_',ucfirst($table)).".php";
}
if (!file_exists($file)) {
$found = false;
foreach(explode(PATH_SEPARATOR, ini_get('include_path')) as $p) {
if (file_exists("$p/$file")) {
$file = "$p/$file";
$found = true;
break;
}
}
if (!$found) {
DB_DataObject::raiseError(
"autoload:Could not find class {$class} using class_location value",
DB_DATAOBJECT_ERROR_INVALIDCONFIG);
return false;
}
}
include_once $file;
if (!class_exists($class)) {
DB_DataObject::raiseError(
"autoload:Could not autoload {$class}",
DB_DATAOBJECT_ERROR_INVALIDCONFIG);
return false;
}
return $class;
}
/**
* Have the links been loaded?
* if they have it contains a array of those variables.
*
* @access private
* @var boolean | array
*/
var $_link_loaded = false;
/**
* Get the links associate array as defined by the links.ini file.
*
*
* Experimental... -
* Should look a bit like
* [local_col_name] => "related_tablename:related_col_name"
*
*
* @return array|null
* array = if there are links defined for this table.
* empty array - if there is a links.ini file, but no links on this table
* null - if no links.ini exists for this database (hence try auto_links).
* @access public
* @see DB_DataObject::getLinks(), DB_DataObject::getLink()
*/
function links()
{
global $_DB_DATAOBJECT;
if (empty($_DB_DATAOBJECT['CONFIG'])) {
$this->_loadConfig();
}
if (isset($_DB_DATAOBJECT['LINKS'][$this->_database][$this->__table])) {
return $_DB_DATAOBJECT['LINKS'][$this->_database][$this->__table];
}
$this->databaseStructure();
// if there is no link data at all on the file!
// we return null.
if (!isset($_DB_DATAOBJECT['LINKS'][$this->_database])) {
return null;
}
if (isset($_DB_DATAOBJECT['LINKS'][$this->_database][$this->__table])) {
return $_DB_DATAOBJECT['LINKS'][$this->_database][$this->__table];
}
return array();
}
/**
* load related objects
*
* There are two ways to use this, one is to set up a <dbname>.links.ini file
* into a static property named <dbname>.links and specifies the table joins,
* the other highly dependent on naming columns 'correctly' :)
* using colname = xxxxx_yyyyyy
* xxxxxx = related table; (yyyyy = user defined..)
* looks up table xxxxx, for value id=$this->xxxxx
* stores it in $this->_xxxxx_yyyyy
* you can change what object vars the links are stored in by
* changeing the format parameter
*
*
* @param string format (default _%s) where %s is the table name.
* @author Tim White <tim@cyface.com>
* @access public
* @return boolean , true on success
*/
function getLinks($format = '_%s')
{
// get table will load the options.
if ($this->_link_loaded) {
return true;
}
$this->_link_loaded = false;
$cols = $this->table();
$links = $this->links();
$loaded = array();
if ($links) {
foreach($links as $key => $match) {
list($table,$link) = explode(':', $match);
$k = sprintf($format, str_replace('.', '_', $key));
// makes sure that '.' is the end of the key;
if ($p = strpos($key,'.')) {
$key = substr($key, 0, $p);
}
$this->$k = $this->getLink($key, $table, $link);
if (is_object($this->$k)) {
$loaded[] = $k;
}
}
$this->_link_loaded = $loaded;
return true;
}
// this is the autonaming stuff..
// it sends the column name down to getLink and lets that sort it out..
// if there is a links file then it is not used!
// IT IS DEPRECIATED!!!! - USE
if (!is_null($links)) {
return false;
}
foreach (array_keys($cols) as $key) {
if (!($p = strpos($key, '_'))) {
continue;
}
// does the table exist.
$k =sprintf($format, $key);
$this->$k = $this->getLink($key);
if (is_object($this->$k)) {
$loaded[] = $k;
}
}
$this->_link_loaded = $loaded;
return true;
}
 
/**
* return name from related object
*
* There are two ways to use this, one is to set up a <dbname>.links.ini file
* into a static property named <dbname>.links and specifies the table joins,
* the other is highly dependant on naming columns 'correctly' :)
*
* NOTE: the naming convention is depreciated!!! - use links.ini
*
* using colname = xxxxx_yyyyyy
* xxxxxx = related table; (yyyyy = user defined..)
* looks up table xxxxx, for value id=$this->xxxxx
* stores it in $this->_xxxxx_yyyyy
*
* you can also use $this->getLink('thisColumnName','otherTable','otherTableColumnName')
*
*
* @param string $row either row or row.xxxxx
* @param string $table name of table to look up value in
* @param string $link name of column in other table to match
* @author Tim White <tim@cyface.com>
* @access public
* @return mixed object on success
*/
function &getLink($row, $table = null, $link = false)
{
// GUESS THE LINKED TABLE.. (if found - recursevly call self)
if ($table === null) {
$links = $this->links();
if (is_array($links)) {
if ($links[$row]) {
list($table,$link) = explode(':', $links[$row]);
if ($p = strpos($row,".")) {
$row = substr($row,0,$p);
}
return $r = &$this->getLink($row,$table,$link);
}
$this->raiseError(
"getLink: $row is not defined as a link (normally this is ok)",
DB_DATAOBJECT_ERROR_NODATA);
return false; // technically a possible error condition?
 
}
// use the old _ method - this shouldnt happen if called via getLinks()
if (!($p = strpos($row, '_'))) {
return null;
}
$table = substr($row, 0, $p);
return $r = &$this->getLink($row, $table);
 
}
if (!isset($this->$row)) {
$this->raiseError("getLink: row not set $row", DB_DATAOBJECT_ERROR_NODATA);
return false;
}
// check to see if we know anything about this table..
$obj = $this->factory($table);
if (!is_a($obj,'DB_DataObject')) {
$this->raiseError(
"getLink:Could not find class for row $row, table $table",
DB_DATAOBJECT_ERROR_INVALIDCONFIG);
return false;
}
if ($link) {
if ($obj->get($link, $this->$row)) {
return $obj;
}
return false;
}
if ($obj->get($this->$row)) {
return $obj;
}
return false;
}
 
/**
* IS THIS SUPPORTED/USED ANYMORE????
*return a list of options for a linked table
*
* This is highly dependant on naming columns 'correctly' :)
* using colname = xxxxx_yyyyyy
* xxxxxx = related table; (yyyyy = user defined..)
* looks up table xxxxx, for value id=$this->xxxxx
* stores it in $this->_xxxxx_yyyyy
*
* @access public
* @return array of results (empty array on failure)
*/
function &getLinkArray($row, $table = null)
{
$ret = array();
if (!$table) {
$links = $this->links();
if (is_array($links)) {
if (!isset($links[$row])) {
// failed..
return $ret;
}
list($table,$link) = explode(':',$links[$row]);
} else {
if (!($p = strpos($row,'_'))) {
return $ret;
}
$table = substr($row,0,$p);
}
}
$c = $this->factory($table);
if (!is_a($c,'DB_DataObject')) {
$this->raiseError(
"getLinkArray:Could not find class for row $row, table $table",
DB_DATAOBJECT_ERROR_INVALIDCONFIG
);
return $ret;
}
 
// if the user defined method list exists - use it...
if (method_exists($c, 'listFind')) {
$c->listFind($this->id);
} else {
$c->find();
}
while ($c->fetch()) {
$ret[] = $c;
}
return $ret;
}
 
/**
* The JOIN condition
*
* @access private
* @var string
*/
var $_join = '';
 
/**
* joinAdd - adds another dataobject to this, building a joined query.
*
* example (requires links.ini to be set up correctly)
* // get all the images for product 24
* $i = new DataObject_Image();
* $pi = new DataObjects_Product_image();
* $pi->product_id = 24; // set the product id to 24
* $i->joinAdd($pi); // add the product_image connectoin
* $i->find();
* while ($i->fetch()) {
* // do stuff
* }
* // an example with 2 joins
* // get all the images linked with products or productgroups
* $i = new DataObject_Image();
* $pi = new DataObject_Product_image();
* $pgi = new DataObject_Productgroup_image();
* $i->joinAdd($pi);
* $i->joinAdd($pgi);
* $i->find();
* while ($i->fetch()) {
* // do stuff
* }
*
*
* @param optional $obj object |array the joining object (no value resets the join)
* If you use an array here it should be in the format:
* array('local_column','remotetable:remote_column');
* if remotetable does not have a definition, you should
* use @ to hide the include error message..
*
*
* @param optional $joinType string 'LEFT'|'INNER'|'RIGHT'|'' Inner is default, '' indicates
* just select ... from a,b,c with no join and
* links are added as where items.
*
* @param optional $joinAs string if you want to select the table as anther name
* useful when you want to select multiple columsn
* from a secondary table.
* @param optional $joinCol string The column on This objects table to match (needed
* if this table links to the child object in
* multiple places eg.
* user->friend (is a link to another user)
* user->mother (is a link to another user..)
*
* @return none
* @access public
* @author Stijn de Reede <sjr@gmx.co.uk>
*/
function joinAdd($obj = false, $joinType='INNER', $joinAs=false, $joinCol=false)
{
global $_DB_DATAOBJECT;
if ($obj === false) {
$this->_join = '';
return;
}
// support for array as first argument
// this assumes that you dont have a links.ini for the specified table.
// and it doesnt exist as am extended dataobject!! - experimental.
$ofield = false; // object field
$tfield = false; // this field
$toTable = false;
if (is_array($obj)) {
$tfield = $obj[0];
list($toTable,$ofield) = explode(':',$obj[1]);
$obj = DB_DataObject::factory($toTable);
if (!$obj || is_a($obj,'PEAR_Error')) {
$obj = new DB_DataObject;
$obj->__table = $toTable;
}
$obj->_connect();
// set the table items to nothing.. - eg. do not try and match
// things in the child table...???
$items = array();
}
if (!is_object($obj)) {
$this->raiseError("joinAdd: called without an object", DB_DATAOBJECT_ERROR_NODATA,PEAR_ERROR_DIE);
}
/* make sure $this->_database is set. */
$this->_connect();
$DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5];
 
/* look up the links for obj table */
//print_r($obj->links());
if (!$ofield && ($olinks = $obj->links())) {
foreach ($olinks as $k => $v) {
/* link contains {this column} = {linked table}:{linked column} */
$ar = explode(':', $v);
if ($ar[0] == $this->__table) {
// you have explictly specified the column
// and the col is listed here..
// not sure if 1:1 table could cause probs here..
if ($joinCol !== false) {
$this->raiseError(
"joinAdd: You cannot target a join column in the " .
"'link from' table ({$obj->__table}). " .
"Either remove the fourth argument to joinAdd() ".
"({$joinCol}), or alter your links.ini file.",
DB_DATAOBJECT_ERROR_NODATA);
return false;
}
$ofield = $k;
$tfield = $ar[1];
break;
}
}
}
 
/* otherwise see if there are any links from this table to the obj. */
//print_r($this->links());
if (($ofield === false) && ($links = $this->links())) {
foreach ($links as $k => $v) {
/* link contains {this column} = {linked table}:{linked column} */
$ar = explode(':', $v);
if ($ar[0] == $obj->__table) {
if ($joinCol !== false) {
if ($k == $joinCol) {
$tfield = $k;
$ofield = $ar[1];
break;
} else {
continue;
}
} else {
$tfield = $k;
$ofield = $ar[1];
break;
}
}
}
}
/* did I find a conneciton between them? */
 
if ($ofield === false) {
$this->raiseError(
"joinAdd: {$obj->__table} has no link with {$this->__table}",
DB_DATAOBJECT_ERROR_NODATA);
return false;
}
$joinType = strtoupper($joinType);
// we default to joining as the same name (this is remvoed later..)
if ($joinAs === false) {
$joinAs = $obj->__table;
}
$quoteIdentifiers = !empty($_DB_DATAOBJECT['CONFIG']['quote_identifiers']);
// not sure how portable adding database prefixes is..
$objTable = $quoteIdentifiers ?
$DB->quoteIdentifier($obj->__table) :
$obj->__table ;
// as far as we know only mysql supports database prefixes..
if (
in_array($DB->dsn['phptype'],array('mysql','mysqli')) &&
($obj->_database != $this->_database) &&
strlen($obj->_database)
)
{
// prefix database (quoted if neccessary..)
$objTable = ($quoteIdentifiers
? $DB->quoteIdentifier($obj->_database)
: $obj->_database)
. '.' . $objTable;
}
// nested (join of joined objects..)
$appendJoin = '';
if ($obj->_join) {
// postgres allows nested queries, with ()'s
// not sure what the results are with other databases..
// may be unpredictable..
if (in_array($DB->dsn["phptype"],array('pgsql'))) {
$objTable = "($objTable {$obj->_join})";
} else {
$appendJoin = $obj->_join;
}
}
$table = $this->__table;
if ($quoteIdentifiers) {
$joinAs = $DB->quoteIdentifier($joinAs);
$table = $DB->quoteIdentifier($table);
$ofield = $DB->quoteIdentifier($ofield);
$tfield = $DB->quoteIdentifier($tfield);
}
// add database prefix if they are different databases
$fullJoinAs = '';
$addJoinAs = ($quoteIdentifiers ? $DB->quoteIdentifier($obj->__table) : $obj->__table) != $joinAs;
if ($addJoinAs) {
$fullJoinAs = "AS {$joinAs}";
} else {
// if
if (
in_array($DB->dsn['phptype'],array('mysql','mysqli')) &&
($obj->_database != $this->_database) &&
strlen($this->_database)
)
{
$joinAs = ($quoteIdentifiers ? $DB->quoteIdentifier($obj->_database) : $obj->_database) . '.' . $joinAs;
}
}
switch ($joinType) {
case 'INNER':
case 'LEFT':
case 'RIGHT': // others??? .. cross, left outer, right outer, natural..?
$this->_join .= "\n {$joinType} JOIN {$objTable} {$fullJoinAs}".
" ON {$joinAs}.{$ofield}={$table}.{$tfield} {$appendJoin} ";
break;
case '': // this is just a standard multitable select..
$this->_join .= "\n , {$objTable} {$fullJoinAs} {$appendJoin}";
$this->whereAdd("{$joinAs}.{$ofield}={$table}.{$tfield}");
}
// if obj only a dataobject - eg. no extended class has been defined..
// it obvioulsy cant work out what child elements might exist...
// untill we get on the fly querying of tables..
if ( strtolower(get_class($obj)) == 'db_dataobject') {
return true;
}
/* now add where conditions for anything that is set in the object */
$items = $obj->table();
// will return an array if no items..
// only fail if we where expecting it to work (eg. not joined on a array)
if (!$items) {
$this->raiseError(
"joinAdd: No table definition for {$obj->__table}",
DB_DATAOBJECT_ERROR_INVALIDCONFIG);
return false;
}
 
foreach($items as $k => $v) {
if (!isset($obj->$k)) {
continue;
}
$kSql = ($quoteIdentifiers ? $DB->quoteIdentifier($k) : $k);
if ($v & DB_DATAOBJECT_STR) {
$this->whereAdd("{$joinAs}.{$kSql} = " . $this->_quote((string) (
($v & DB_DATAOBJECT_BOOL) ?
// this is thanks to the braindead idea of postgres to
// use t/f for boolean.
(($obj->$k == 'f') ? 0 : (int)(bool) $obj->$k) :
$obj->$k
)));
continue;
}
if (is_numeric($obj->$k)) {
$this->whereAdd("{$joinAs}.{$kSql} = {$obj->$k}");
continue;
}
/* this is probably an error condition! */
$this->whereAdd("{$joinAs}.{$kSql} = 0");
}
if (!isset($this->_query)) {
$this->raiseError(
"joinAdd can not be run from a object that has had a query run on it,
clone the object or create a new one and use setFrom()",
DB_DATAOBJECT_ERROR_INVALIDARGS);
return false;
}
// and finally merge the whereAdd from the child..
if (!$obj->_query['condition']) {
return true;
}
$cond = preg_replace('/^\sWHERE/i','',$obj->_query['condition']);
$this->whereAdd("($cond)");
return true;
 
}
 
/**
* Copies items that are in the table definitions from an
* array or object into the current object
* will not override key values.
*
*
* @param array | object $from
* @param string $format eg. map xxxx_name to $object->name using 'xxxx_%s' (defaults to %s - eg. name -> $object->name
* @access public
* @return true on success or array of key=>setValue error message
*/
function setFrom(&$from, $format = '%s', $checkEmpty=false)
{
global $_DB_DATAOBJECT;
$keys = $this->keys();
$items = $this->table();
if (!$items) {
$this->raiseError(
"setFrom:Could not find table definition for {$this->__table}",
DB_DATAOBJECT_ERROR_INVALIDCONFIG);
return;
}
$overload_return = array();
foreach (array_keys($items) as $k) {
if (in_array($k,$keys)) {
continue; // dont overwrite keys
}
if (!$k) {
continue; // ignore empty keys!!! what
}
if (is_object($from) && isset($from->{sprintf($format,$k)})) {
$kk = (strtolower($k) == 'from') ? '_from' : $k;
if (method_exists($this,'set'.$kk)) {
$ret = $this->{'set'.$kk}($from->{sprintf($format,$k)});
if (is_string($ret)) {
$overload_return[$k] = $ret;
}
continue;
}
$this->$k = $from->{sprintf($format,$k)};
continue;
}
if (is_object($from)) {
continue;
}
if (!isset($from[sprintf($format,$k)])) {
continue;
}
$kk = (strtolower($k) == 'from') ? '_from' : $k;
if (method_exists($this,'set'. $kk)) {
$ret = $this->{'set'.$kk}($from[sprintf($format,$k)]);
if (is_string($ret)) {
$overload_return[$k] = $ret;
}
continue;
}
if (is_object($from[sprintf($format,$k)])) {
continue;
}
if (is_array($from[sprintf($format,$k)])) {
continue;
}
$ret = $this->fromValue($k,$from[sprintf($format,$k)]);
if ($ret !== true) {
$overload_return[$k] = 'Not A Valid Value';
}
//$this->$k = $from[sprintf($format,$k)];
}
if ($overload_return) {
return $overload_return;
}
return true;
}
 
/**
* Returns an associative array from the current data
* (kind of oblivates the idea behind DataObjects, but
* is usefull if you use it with things like QuickForms.
*
* you can use the format to return things like user[key]
* by sending it $object->toArray('user[%s]')
*
* will also return links converted to arrays.
*
* @param string sprintf format for array
* @param bool empty only return elemnts that have a value set.
*
* @access public
* @return array of key => value for row
*/
 
function toArray($format = '%s', $hideEmpty = false)
{
global $_DB_DATAOBJECT;
$ret = array();
$ar = isset($_DB_DATAOBJECT['RESULTFIELDS'][$this->_DB_resultid]) ?
array_merge($_DB_DATAOBJECT['RESULTFIELDS'][$this->_DB_resultid],$this->table()) :
$this->table();
 
foreach($ar as $k=>$v) {
if (!isset($this->$k)) {
if (!$hideEmpty) {
$ret[sprintf($format,$k)] = '';
}
continue;
}
// call the overloaded getXXXX() method. - except getLink and getLinks
if (method_exists($this,'get'.$k) && !in_array(strtolower($k),array('links','link'))) {
$ret[sprintf($format,$k)] = $this->{'get'.$k}();
continue;
}
// should this call toValue() ???
$ret[sprintf($format,$k)] = $this->$k;
}
if (!$this->_link_loaded) {
return $ret;
}
foreach($this->_link_loaded as $k) {
$ret[sprintf($format,$k)] = $this->$k->toArray();
}
return $ret;
}
 
/**
* validate - override this to set up your validation rules
*
* validate the current objects values either just testing strings/numbers or
* using the user defined validate{Row name}() methods.
* will attempt to call $this->validate{column_name}() - expects true = ok false = ERROR
* you can the use the validate Class from your own methods.
*
* This should really be in a extenal class - eg. DB_DataObject_Validate.
*
* @access public
* @return array of validation results or true
*/
function validate()
{
require_once 'Validate.php';
$table = $this->table();
$ret = array();
$seq = $this->sequenceKey();
foreach($table as $key => $val) {
// call user defined validation always...
$method = "Validate" . ucfirst($key);
if (method_exists($this, $method)) {
$ret[$key] = $this->$method();
continue;
}
// if not null - and it's not set.......
if (!isset($this->$key) && ($val & DB_DATAOBJECT_NOTNULL)) {
// dont check empty sequence key values..
if (($key == $seq[0]) && ($seq[1] == true)) {
continue;
}
$ret[$key] = false;
continue;
}
if (is_string($this->$key) && (strtolower($this->$key) == 'null') && ($val & DB_DATAOBJECT_NOTNULL)) {
$ret[$key] = false;
continue;
}
// ignore things that are not set. ?
if (!isset($this->$key)) {
continue;
}
// if the string is empty.. assume it is ok..
if (!is_object($this->$key) && !is_array($this->$key) && !strlen((string) $this->$key)) {
continue;
}
switch (true) {
// todo: date time.....
case ($val & DB_DATAOBJECT_STR):
$ret[$key] = Validate::string($this->$key, VALIDATE_PUNCTUATION . VALIDATE_NAME);
continue;
case ($val & DB_DATAOBJECT_INT):
$ret[$key] = Validate::number($this->$key, array('decimal'=>'.'));
continue;
}
}
 
foreach ($ret as $key => $val) {
if ($val === false) {
return $ret;
}
}
return true; // everything is OK.
}
 
/**
* Gets the DB object related to an object - so you can use funky peardb stuf with it :)
*
* @access public
* @return object The DB connection
*/
function &getDatabaseConnection()
{
global $_DB_DATAOBJECT;
 
if (($e = $this->_connect()) !== true) {
return $e;
}
if (!isset($_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5])) {
return false;
}
return $_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5];
}
/**
* Gets the DB result object related to the objects active query
* - so you can use funky pear stuff with it - like pager for example.. :)
*
* @access public
* @return object The DB result object
*/
function &getDatabaseResult()
{
global $_DB_DATAOBJECT;
$this->_connect();
if (!isset($_DB_DATAOBJECT['RESULTS'][$this->_DB_resultid])) {
return false;
}
return $_DB_DATAOBJECT['RESULTS'][$this->_DB_resultid];
}
 
/**
* Overload Extension support
* - enables setCOLNAME/getCOLNAME
* if you define a set/get method for the item it will be called.
* otherwise it will just return/set the value.
* NOTE this currently means that a few Names are NO-NO's
* eg. links,link,linksarray, from, Databaseconnection,databaseresult
*
* note
* - set is automatically called by setFrom.
* - get is automatically called by toArray()
*
* setters return true on success. = strings on failure
* getters return the value!
*
* this fires off trigger_error - if any problems.. pear_error,
* has problems with 4.3.2RC2 here
*
* @access public
* @return true?
* @see overload
*/
 
function _call($method,$params,&$return) {
//$this->debug("ATTEMPTING OVERLOAD? $method");
// ignore constructors : - mm
if (strtolower($method) == strtolower(get_class($this))) {
return true;
}
$type = strtolower(substr($method,0,3));
$class = get_class($this);
if (($type != 'set') && ($type != 'get')) {
return false;
}
// deal with naming conflick of setFrom = this is messy ATM!
if (strtolower($method) == 'set_from') {
$return = $this->toValue('from',isset($params[0]) ? $params[0] : null);
return true;
}
$element = substr($method,3);
// dont you just love php's case insensitivity!!!!
$array = array_keys(get_class_vars($class));
/* php5 version which segfaults on 5.0.3 */
if (class_exists('ReflectionClass')) {
$reflection = new ReflectionClass($class);
$array = array_keys($reflection->getdefaultProperties());
}
if (!in_array($element,$array)) {
// munge case
foreach($array as $k) {
$case[strtolower($k)] = $k;
}
if ((substr(phpversion(),0,1) == 5) && isset($case[strtolower($element)])) {
trigger_error("PHP5 set/get calls should match the case of the variable",E_USER_WARNING);
$element = strtolower($element);
}
// does it really exist?
if (!isset($case[$element])) {
return false;
}
// use the mundged case
$element = $case[$element]; // real case !
}
if ($type == 'get') {
$return = $this->toValue($element,isset($params[0]) ? $params[0] : null);
return true;
}
$return = $this->fromValue($element, $params[0]);
return true;
}
/**
* standard set* implementation.
*
* takes data and uses it to set dates/strings etc.
* normally called from __call..
*
* Current supports
* date = using (standard time format, or unixtimestamp).... so you could create a method :
* function setLastread($string) { $this->fromValue('lastread',strtotime($string)); }
*
* time = using strtotime
* datetime = using same as date - accepts iso standard or unixtimestamp.
* string = typecast only..
*
* TODO: add formater:: eg. d/m/Y for date! ???
*
* @param string column of database
* @param mixed value to assign
*
* @return true| false (False on error)
* @access public
* @see DB_DataObject::_call
*/
function fromValue($col,$value)
{
$cols = $this->table();
// dont know anything about this col..
if (!isset($cols[$col])) {
$this->$col = $value;
return true;
}
//echo "FROM VALUE $col, {$cols[$col]}, $value\n";
switch (true) {
// set to null and column is can be null...
case ((strtolower($value) == 'null') && (!($cols[$col] & DB_DATAOBJECT_NOTNULL))):
case (is_object($value) && is_a($value,'DB_DataObject_Cast')):
$this->$col = $value;
return true;
// fail on setting null on a not null field..
case ((strtolower($value) == 'null') && ($cols[$col] & DB_DATAOBJECT_NOTNULL)):
return false;
case (($cols[$col] & DB_DATAOBJECT_DATE) && ($cols[$col] & DB_DATAOBJECT_TIME)):
// empty values get set to '' (which is inserted/updated as NULl
if (!$value) {
$this->$col = '';
}
if (is_numeric($value)) {
$this->$col = date('Y-m-d H:i:s', $value);
return true;
}
// eak... - no way to validate date time otherwise...
$this->$col = (string) $value;
return true;
case ($cols[$col] & DB_DATAOBJECT_DATE):
// empty values get set to '' (which is inserted/updated as NULl
if (!$value) {
$this->$col = '';
return true;
}
if (is_numeric($value)) {
$this->$col = date('Y-m-d',$value);
return true;
}
// try date!!!!
require_once 'Date.php';
$x = new Date($value);
$this->$col = $x->format("%Y-%m-%d");
return true;
case ($cols[$col] & DB_DATAOBJECT_TIME):
// empty values get set to '' (which is inserted/updated as NULl
if (!$value) {
$this->$col = '';
}
$guess = strtotime($value);
if ($guess != -1) {
$this->$col = date('H:i:s', $guess);
return $return = true;
}
// otherwise an error in type...
return false;
case ($cols[$col] & DB_DATAOBJECT_STR):
$this->$col = (string) $value;
return true;
// todo : floats numerics and ints...
default:
$this->$col = $value;
return true;
}
}
/**
* standard get* implementation.
*
* with formaters..
* supported formaters:
* date/time : %d/%m/%Y (eg. php strftime) or pear::Date
* numbers : %02d (eg. sprintf)
* NOTE you will get unexpected results with times like 0000-00-00 !!!
*
*
*
* @param string column of database
* @param format foramt
*
* @return true Description
* @access public
* @see DB_DataObject::_call(),strftime(),Date::format()
*/
function toValue($col,$format = null)
{
if (is_null($format)) {
return $this->$col;
}
$cols = $this->table();
switch (true) {
case (($cols[$col] & DB_DATAOBJECT_DATE) && ($cols[$col] & DB_DATAOBJECT_TIME)):
if (!$this->$col) {
return '';
}
$guess = strtotime($this->$col);
if ($guess != -1) {
return strftime($format, $guess);
}
// eak... - no way to validate date time otherwise...
return $this->$col;
case ($cols[$col] & DB_DATAOBJECT_DATE):
if (!$this->$col) {
return '';
}
$guess = strtotime($this->$col);
if ($guess != -1) {
return strftime($format,$guess);
}
// try date!!!!
require_once 'Date.php';
$x = new Date($this->$col);
return $x->format($format);
case ($cols[$col] & DB_DATAOBJECT_TIME):
if (!$this->$col) {
return '';
}
$guess = strtotime($this->$col);
if ($guess > -1) {
return strftime($format, $guess);
}
// otherwise an error in type...
return $this->$col;
case ($cols[$col] & DB_DATAOBJECT_MYSQLTIMESTAMP):
if (!$this->$col) {
return '';
}
require_once 'Date.php';
$x = new Date($this->$col);
return $x->format($format);
case ($cols[$col] & DB_DATAOBJECT_BOOLEAN):
if ($cols[$col] & DB_DATAOBJECT_STR) {
// it's a 't'/'f' !
return ($cols[$col] == 't');
}
return (bool) $cols[$col];
default:
return sprintf($format,$this->col);
}
 
}
/* ----------------------- Debugger ------------------ */
 
/**
* Debugger. - use this in your extended classes to output debugging information.
*
* Uses DB_DataObject::DebugLevel(x) to turn it on
*
* @param string $message - message to output
* @param string $logtype - bold at start
* @param string $level - output level
* @access public
* @return none
*/
function debug($message, $logtype = 0, $level = 1)
{
global $_DB_DATAOBJECT;
 
if (empty($_DB_DATAOBJECT['CONFIG']['debug']) ||
(is_numeric($_DB_DATAOBJECT['CONFIG']['debug']) && $_DB_DATAOBJECT['CONFIG']['debug'] < $level)) {
return;
}
// this is a bit flaky due to php's wonderfull class passing around crap..
// but it's about as good as it gets..
$class = (isset($this) && is_a($this,'DB_DataObject')) ? get_class($this) : 'DB_DataObject';
if (!is_string($message)) {
$message = print_r($message,true);
}
if (!is_numeric( $_DB_DATAOBJECT['CONFIG']['debug']) && is_callable( $_DB_DATAOBJECT['CONFIG']['debug'])) {
return call_user_func($_DB_DATAOBJECT['CONFIG']['debug'], $class, $message, $logtype, $level);
}
if (!ini_get('html_errors')) {
echo "$class : $logtype : $message\n";
flush();
return;
}
if (!is_string($message)) {
$message = print_r($message,true);
}
echo "<code><B>$class: $logtype:</B> $message</code><BR>\n";
flush();
}
 
/**
* sets and returns debug level
* eg. DB_DataObject::debugLevel(4);
*
* @param int $v level
* @access public
* @return none
*/
function debugLevel($v = null)
{
global $_DB_DATAOBJECT;
if (empty($_DB_DATAOBJECT['CONFIG'])) {
DB_DataObject::_loadConfig();
}
if ($v !== null) {
$r = isset($_DB_DATAOBJECT['CONFIG']['debug']) ? $_DB_DATAOBJECT['CONFIG']['debug'] : 0;
$_DB_DATAOBJECT['CONFIG']['debug'] = $v;
return $r;
}
return isset($_DB_DATAOBJECT['CONFIG']['debug']) ? $_DB_DATAOBJECT['CONFIG']['debug'] : 0;
}
 
/**
* Last Error that has occured
* - use $this->_lastError or
* $last_error = &PEAR::getStaticProperty('DB_DataObject','lastError');
*
* @access public
* @var object PEAR_Error (or false)
*/
var $_lastError = false;
 
/**
* Default error handling is to create a pear error, but never return it.
* if you need to handle errors you should look at setting the PEAR_Error callback
* this is due to the fact it would wreck havoc on the internal methods!
*
* @param int $message message
* @param int $type type
* @param int $behaviour behaviour (die or continue!);
* @access public
* @return error object
*/
function raiseError($message, $type = null, $behaviour = null)
{
global $_DB_DATAOBJECT;
if ($behaviour == PEAR_ERROR_DIE && !empty($_DB_DATAOBJECT['CONFIG']['dont_die'])) {
$behaviour = null;
}
$error = &PEAR::getStaticProperty('DB_DataObject','lastError');
if (PEAR::isError($message)) {
$error = $message;
} else {
require_once 'DB/DataObject/Error.php';
$error = PEAR::raiseError($message, $type, $behaviour,
$opts=null, $userinfo=null, 'DB_DataObject_Error'
);
}
// this will never work totally with PHP's object model.
// as this is passed on static calls (like staticGet in our case)
 
if (isset($this) && is_object($this) && is_subclass_of($this,'db_dataobject')) {
$this->_lastError = $error;
}
 
$_DB_DATAOBJECT['LASTERROR'] = $error;
 
// no checks for production here?.......
DB_DataObject::debug($message,"ERROR",1);
return $error;
}
 
/**
* Define the global $_DB_DATAOBJECT['CONFIG'] as an alias to PEAR::getStaticProperty('DB_DataObject','options');
*
* After Profiling DB_DataObject, I discoved that the debug calls where taking
* considerable time (well 0.1 ms), so this should stop those calls happening. as
* all calls to debug are wrapped with direct variable queries rather than actually calling the funciton
* THIS STILL NEEDS FURTHER INVESTIGATION
*
* @access public
* @return object an error object
*/
function _loadConfig()
{
global $_DB_DATAOBJECT;
 
$_DB_DATAOBJECT['CONFIG'] = &PEAR::getStaticProperty('DB_DataObject','options');
 
 
}
/**
* Free global arrays associated with this object.
*
* Note: as we now store resultfields in a global, it is never freed, if you do alot of calls to find(),
* memory will grow gradually.
*
*
* @access public
* @return none
*/
function free()
{
global $_DB_DATAOBJECT;
if (isset($_DB_DATAOBJECT['RESULTFIELDS'][$this->_DB_resultid])) {
unset($_DB_DATAOBJECT['RESULTFIELDS'][$this->_DB_resultid]);
}
if (isset($_DB_DATAOBJECT['RESULTS'][$this->_DB_resultid])) {
unset($_DB_DATAOBJECT['RESULTS'][$this->_DB_resultid]);
}
// this is a huge bug in DB!
if (isset($_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5])) {
$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]->num_rows = array();
}
}
/* ---- LEGACY BC METHODS - NOT DOCUMENTED - See Documentation on New Methods. ---*/
function _get_table() { return $this->table(); }
function _get_keys() { return $this->keys(); }
}
// technially 4.3.2RC1 was broken!!
// looks like 4.3.3 may have problems too....
if (!defined('DB_DATAOBJECT_NO_OVERLOAD')) {
 
if ((phpversion() != '4.3.2-RC1') && (version_compare( phpversion(), "4.3.1") > 0)) {
if (version_compare( phpversion(), "5") < 0) {
overload('DB_DataObject');
}
$GLOBALS['_DB_DATAOBJECT']['OVERLOADED'] = true;
}
}
 
/trunk/bibliotheque/pear/DB/sqlite.php
6,7 → 6,7
* The PEAR DB driver for PHP's sqlite extension
* for interacting with SQLite databases
*
* PHP version 5
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
19,9 → 19,9
* @author Urs Gehrig <urs@circle.ch>
* @author Mika Tuupola <tuupola@appelsiini.net>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2007 The PHP Group
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 3.0
* @version CVS: $Id$
* @version CVS: $Id: sqlite.php,v 1.109 2005/03/10 01:22:48 danielc Exp $
* @link http://pear.php.net/package/DB
*/
 
45,9 → 45,9
* @author Urs Gehrig <urs@circle.ch>
* @author Mika Tuupola <tuupola@appelsiini.net>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2007 The PHP Group
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0 3.0
* @version Release: 1.9.2
* @version Release: 1.7.6
* @link http://pear.php.net/package/DB
*/
class DB_sqlite extends DB_common
152,13 → 152,13
// {{{ constructor
 
/**
* This constructor calls <kbd>parent::__construct()</kbd>
* This constructor calls <kbd>$this->DB_common()</kbd>
*
* @return void
*/
function __construct()
function DB_sqlite()
{
parent::__construct();
$this->DB_common();
}
 
// }}}
182,7 → 182,7
* 'portability' => DB_PORTABILITY_ALL,
* );
*
* $db = DB::connect($dsn, $options);
* $db =& DB::connect($dsn, $options);
* if (PEAR::isError($db)) {
* die($db->getMessage());
* }
204,11 → 204,7
$this->dbsyntax = $dsn['dbsyntax'];
}
 
if (!$dsn['database']) {
return $this->sqliteRaiseError(DB_ERROR_ACCESS_VIOLATION);
}
 
if ($dsn['database'] !== ':memory:') {
if ($dsn['database']) {
if (!file_exists($dsn['database'])) {
if (!touch($dsn['database'])) {
return $this->sqliteRaiseError(DB_ERROR_NOT_FOUND);
233,12 → 229,14
if (!is_readable($dsn['database'])) {
return $this->sqliteRaiseError(DB_ERROR_ACCESS_VIOLATION);
}
} else {
return $this->sqliteRaiseError(DB_ERROR_ACCESS_VIOLATION);
}
 
$connect_function = $persistent ? 'sqlite_popen' : 'sqlite_open';
 
// track_errors must remain on for simpleQuery()
@ini_set('track_errors', 1);
ini_set('track_errors', 1);
$php_errormsg = '';
 
if (!$this->connection = @$connect_function($dsn['database'])) {
282,7 → 280,7
*/
function simpleQuery($query)
{
$ismanip = $this->_checkManip($query);
$ismanip = DB::isManip($query);
$this->last_query = $query;
$query = $this->modifyQuery($query);
 
359,16 → 357,6
if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) {
$arr = array_change_key_case($arr, CASE_LOWER);
}
 
/* Remove extraneous " characters from the fields in the result.
* Fixes bug #11716. */
if (is_array($arr) && count($arr) > 0) {
$strippedArr = array();
foreach ($arr as $field => $value) {
$strippedArr[trim($field, '"')] = $value;
}
$arr = $strippedArr;
}
} else {
$arr = @sqlite_fetch_array($result, SQLITE_NUM);
}
739,11 → 727,6
function errorCode($errormsg)
{
static $error_regexps;
// PHP 5.2+ prepends the function name to $php_errormsg, so we need
// this hack to work around it, per bug #9599.
$errormsg = preg_replace('/^sqlite[a-z_]+\(\): /', '', $errormsg);
if (!isset($error_regexps)) {
$error_regexps = array(
'/^no such table:/' => DB_ERROR_NOSUCHTABLE,
755,7 → 738,6
'/uniqueness constraint failed/' => DB_ERROR_CONSTRAINT,
'/may not be NULL/' => DB_ERROR_CONSTRAINT_NOT_NULL,
'/^no such column:/' => DB_ERROR_NOSUCHFIELD,
'/no column named/' => DB_ERROR_NOSUCHFIELD,
'/column not present in both tables/i' => DB_ERROR_NOSUCHFIELD,
'/^near ".*": syntax error$/' => DB_ERROR_SYNTAX,
'/[0-9]+ values for [0-9]+ columns/i' => DB_ERROR_VALUE_COUNT_ON_ROW,
829,9 → 811,6
$flags = '';
if ($id[$i]['pk']) {
$flags .= 'primary_key ';
if (strtoupper($type) == 'INTEGER') {
$flags .= 'auto_increment ';
}
}
if ($id[$i]['notnull']) {
$flags .= 'not_null ';
/trunk/bibliotheque/pear/DB/oci8.php
6,7 → 6,7
* The PEAR DB driver for PHP's oci8 extension
* for interacting with Oracle databases
*
* PHP version 5
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
18,9 → 18,9
* @package DB
* @author James L. Pine <jlp@valinux.com>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2007 The PHP Group
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$
* @version CVS: $Id: oci8.php,v 1.103 2005/04/11 15:10:22 danielc Exp $
* @link http://pear.php.net/package/DB
*/
 
45,9 → 45,9
* @package DB
* @author James L. Pine <jlp@valinux.com>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2007 The PHP Group
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.9.2
* @version Release: 1.7.6
* @link http://pear.php.net/package/DB
*/
class DB_oci8 extends DB_common
94,25 → 94,24
* @var array
*/
var $errorcode_map = array(
1 => DB_ERROR_CONSTRAINT,
900 => DB_ERROR_SYNTAX,
904 => DB_ERROR_NOSUCHFIELD,
913 => DB_ERROR_VALUE_COUNT_ON_ROW,
921 => DB_ERROR_SYNTAX,
923 => DB_ERROR_SYNTAX,
942 => DB_ERROR_NOSUCHTABLE,
955 => DB_ERROR_ALREADY_EXISTS,
1400 => DB_ERROR_CONSTRAINT_NOT_NULL,
1401 => DB_ERROR_INVALID,
1407 => DB_ERROR_CONSTRAINT_NOT_NULL,
1418 => DB_ERROR_NOT_FOUND,
1476 => DB_ERROR_DIVZERO,
1722 => DB_ERROR_INVALID_NUMBER,
2289 => DB_ERROR_NOSUCHTABLE,
2291 => DB_ERROR_CONSTRAINT,
2292 => DB_ERROR_CONSTRAINT,
2449 => DB_ERROR_CONSTRAINT,
12899 => DB_ERROR_INVALID,
1 => DB_ERROR_CONSTRAINT,
900 => DB_ERROR_SYNTAX,
904 => DB_ERROR_NOSUCHFIELD,
913 => DB_ERROR_VALUE_COUNT_ON_ROW,
921 => DB_ERROR_SYNTAX,
923 => DB_ERROR_SYNTAX,
942 => DB_ERROR_NOSUCHTABLE,
955 => DB_ERROR_ALREADY_EXISTS,
1400 => DB_ERROR_CONSTRAINT_NOT_NULL,
1401 => DB_ERROR_INVALID,
1407 => DB_ERROR_CONSTRAINT_NOT_NULL,
1418 => DB_ERROR_NOT_FOUND,
1476 => DB_ERROR_DIVZERO,
1722 => DB_ERROR_INVALID_NUMBER,
2289 => DB_ERROR_NOSUCHTABLE,
2291 => DB_ERROR_CONSTRAINT,
2292 => DB_ERROR_CONSTRAINT,
2449 => DB_ERROR_CONSTRAINT,
);
 
/**
161,25 → 160,18
*/
var $manip_query = array();
 
/**
* Store of prepared SQL queries.
* @var array
* @access private
*/
var $_prepared_queries = array();
 
 
// }}}
// {{{ constructor
 
/**
* This constructor calls <kbd>parent::__construct()</kbd>
* This constructor calls <kbd>$this->DB_common()</kbd>
*
* @return void
*/
function __construct()
function DB_oci8()
{
parent::__construct();
$this->DB_common();
}
 
// }}}
224,13 → 216,6
$this->dbsyntax = $dsn['dbsyntax'];
}
 
// Backwards compatibility with DB < 1.7.0
if (empty($dsn['database']) && !empty($dsn['hostspec'])) {
$db = $dsn['hostspec'];
} else {
$db = $dsn['database'];
}
 
if (function_exists('oci_connect')) {
if (isset($dsn['new_link'])
&& ($dsn['new_link'] == 'true' || $dsn['new_link'] === true))
240,8 → 225,12
$connect_function = $persistent ? 'oci_pconnect'
: 'oci_connect';
}
if (isset($this->dsn['port']) && $this->dsn['port']) {
$db = '//'.$db.':'.$this->dsn['port'];
 
// Backwards compatibility with DB < 1.7.0
if (empty($dsn['database']) && !empty($dsn['hostspec'])) {
$db = $dsn['hostspec'];
} else {
$db = $dsn['database'];
}
 
$char = empty($dsn['charset']) ? null : $dsn['charset'];
259,10 → 248,10
}
} else {
$connect_function = $persistent ? 'OCIPLogon' : 'OCILogon';
if ($db) {
if ($dsn['hostspec']) {
$this->connection = @$connect_function($dsn['username'],
$dsn['password'],
$db);
$dsn['hostspec']);
} elseif ($dsn['username'] || $dsn['password']) {
$this->connection = @$connect_function($dsn['username'],
$dsn['password']);
333,7 → 322,7
return $this->oci8RaiseError($result);
}
$this->last_stmt = $result;
if ($this->_checkManip($query)) {
if (DB::isManip($query)) {
return DB_OK;
} else {
@ocisetprefetch($result, $this->options['result_buffering']);
426,7 → 415,7
*/
function freeResult($result)
{
return is_resource($result) ? OCIFreeStatement($result) : false;
return @OCIFreeStatement($result);
}
 
/**
452,7 → 441,6
if (isset($this->prepare_types[(int)$stmt])) {
unset($this->prepare_types[(int)$stmt]);
unset($this->manip_query[(int)$stmt]);
unset($this->_prepared_queries[(int)$stmt]);
} else {
return false;
}
488,18 → 476,20
$save_query = $this->last_query;
$save_stmt = $this->last_stmt;
 
$count = $this->query($countquery);
if (count($this->_data)) {
$smt = $this->prepare('SELECT COUNT(*) FROM ('.$this->last_query.')');
$count = $this->execute($smt, $this->_data);
} else {
$count =& $this->query($countquery);
}
 
// Restore the last query and statement.
$this->last_query = $save_query;
$this->last_stmt = $save_stmt;
if (DB::isError($count) ||
DB::isError($row = $count->fetchRow(DB_FETCHMODE_ORDERED)))
{
$this->last_query = $save_query;
$this->last_stmt = $save_stmt;
return $this->raiseError(DB_ERROR_NOT_CAPABLE);
}
 
return $row[0];
}
return $this->raiseError(DB_ERROR_NOT_CAPABLE);
600,7 → 590,6
}
$this->prepare_types[(int)$stmt] = $types;
$this->manip_query[(int)$stmt] = DB::isManip($query);
$this->_prepared_queries[(int)$stmt] = $newquery;
return $stmt;
}
 
631,12 → 620,11
{
$data = (array)$data;
$this->last_parameters = $data;
$this->last_query = $this->_prepared_queries[(int)$stmt];
$this->_data = $data;
 
$types = $this->prepare_types[(int)$stmt];
$types =& $this->prepare_types[(int)$stmt];
if (count($types) != count($data)) {
$tmp = $this->raiseError(DB_ERROR_MISMATCH);
$tmp =& $this->raiseError(DB_ERROR_MISMATCH);
return $tmp;
}
 
655,24 → 643,16
} elseif ($types[$i] == DB_PARAM_OPAQUE) {
$fp = @fopen($data[$key], 'rb');
if (!$fp) {
$tmp = $this->raiseError(DB_ERROR_ACCESS_VIOLATION);
$tmp =& $this->raiseError(DB_ERROR_ACCESS_VIOLATION);
return $tmp;
}
$data[$key] = fread($fp, filesize($data[$key]));
fclose($fp);
} elseif ($types[$i] == DB_PARAM_SCALAR) {
// Floats have to be converted to a locale-neutral
// representation.
if (is_float($data[$key])) {
$data[$key] = $this->quoteFloat($data[$key]);
}
}
if (!@OCIBindByName($stmt, ':bind' . $i, $data[$key], -1)) {
$tmp = $this->oci8RaiseError($stmt);
return $tmp;
}
$this->last_query = preg_replace("/:bind$i(?!\d)/",
$this->quoteSmart($data[$key]), $this->last_query, 1);
$i++;
}
if ($this->autocommit) {
685,14 → 665,11
return $tmp;
}
$this->last_stmt = $stmt;
if ($this->manip_query[(int)$stmt] || $this->_next_query_manip) {
$this->_last_query_manip = true;
$this->_next_query_manip = false;
if ($this->manip_query[(int)$stmt]) {
$tmp = DB_OK;
} else {
$this->_last_query_manip = false;
@ocisetprefetch($stmt, $this->options['result_buffering']);
$tmp = new DB_result($this, $stmt);
$tmp =& new DB_result($this, $stmt);
}
return $tmp;
}
820,7 → 797,7
if (count($params)) {
$result = $this->prepare("SELECT * FROM ($query) "
. 'WHERE NULL = NULL');
$tmp = $this->execute($result, $params);
$tmp =& $this->execute($result, $params);
} else {
$q_fields = "SELECT * FROM ($query) WHERE NULL = NULL";
 
880,7 → 857,7
$repeat = 0;
do {
$this->expectError(DB_ERROR_NOSUCHTABLE);
$result = $this->query("SELECT ${seqname}.nextval FROM dual");
$result =& $this->query("SELECT ${seqname}.nextval FROM dual");
$this->popExpect();
if ($ondemand && DB::isError($result) &&
$result->getCode() == DB_ERROR_NOSUCHTABLE) {
1038,7 → 1015,7
if (!@OCIExecute($stmt, OCI_DEFAULT)) {
return $this->oci8RaiseError($stmt);
}
 
$i = 0;
while (@OCIFetch($stmt)) {
$res[$i] = array(
1121,8 → 1098,6
return 'SELECT table_name FROM user_tables';
case 'synonyms':
return 'SELECT synonym_name FROM user_synonyms';
case 'views':
return 'SELECT view_name FROM user_views';
default:
return null;
}
1129,23 → 1104,7
}
 
// }}}
// {{{ quoteFloat()
 
/**
* Formats a float value for use within a query in a locale-independent
* manner.
*
* @param float the float value to be quoted.
* @return string the quoted string.
* @see DB_common::quoteSmart()
* @since Method available since release 1.7.8.
*/
function quoteFloat($float) {
return $this->escapeSimple(str_replace(',', '.', strval(floatval($float))));
}
// }}}
 
}
 
/*
/trunk/bibliotheque/pear/DB/QueryTool.php
New file
0,0 → 1,63
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
 
/**
* Contains the DB_QueryTool class
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category Database
* @package DB_QueryTool
* @author Wolfram Kriesing <wk@visionp.de>
* @author Paolo Panto <wk@visionp.de>
* @copyright 2003-2005 Wolfram Kriesing, Paolo Panto
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: QueryTool.php,v 1.4 2005/02/25 16:38:27 quipo Exp $
* @link http://pear.php.net/package/DB_QueryTool
*/
 
/**
* require the DB_QueryTool_EasyJoin class
*/
require_once 'DB/QueryTool/EasyJoin.php';
 
/**
* MDB_QueryTool class
*
* This class should be extended; it's here to make it easy using the base
* class of the package by its package name.
* Since I tried to seperate the functionality a bit inside the
* really working classes i decided to have this class here just to
* provide the name, since the functionality inside the other
* classes might be restructured a bit but this name always stays.
*
* @category Database
* @package DB_QueryTool
* @author Wolfram Kriesing <wk@visionp.de>
* @copyright 2003-2005 Wolfram Kriesing
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @link http://pear.php.net/package/DB_QueryTool
*/
class DB_QueryTool extends DB_QueryTool_EasyJoin
{
// {{{ DB_QueryTool()
 
/**
* call parent constructor
* @param mixed $dsn DSN string, DSN array or DB object
* @param array $options
*/
function DB_QueryTool($dsn=false, $options=array())
{
parent::__construct($dsn, $options);
}
 
// }}}
}
?>
/trunk/bibliotheque/pear/DB/storage.php
5,7 → 5,7
/**
* Provides an object interface to a table row
*
* PHP version 5
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
16,9 → 16,9
* @category Database
* @package DB
* @author Stig Bakken <stig@php.net>
* @copyright 1997-2007 The PHP Group
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$
* @version CVS: $Id: storage.php,v 1.21 2005/02/02 02:54:51 danielc Exp $
* @link http://pear.php.net/package/DB
*/
 
36,9 → 36,9
* @category Database
* @package DB
* @author Stig Bakken <stig@php.net>
* @copyright 1997-2007 The PHP Group
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.9.2
* @version Release: 1.7.6
* @link http://pear.php.net/package/DB
*/
class DB_storage extends PEAR
94,7 → 94,7
* a reference to this object
*
*/
function __construct($table, $keycolumn, &$dbh, $validator = null)
function DB_storage($table, $keycolumn, &$dbh, $validator = null)
{
$this->PEAR('DB_Error');
$this->_table = $table;
293,7 → 293,7
function &create($table, &$data)
{
$classname = strtolower(get_class($this));
$obj = new $classname($table);
$obj =& new $classname($table);
foreach ($data as $name => $value) {
$obj->_properties[$name] = true;
$obj->$name = &$value;
445,8 → 445,6
*/
function store()
{
$params = array();
$vars = array();
foreach ($this->_changes as $name => $foo) {
$params[] = &$this->$name;
$vars[] = $name . ' = ?';
/trunk/bibliotheque/pear/DB/mysql.php
6,7 → 6,7
* The PEAR DB driver for PHP's mysql extension
* for interacting with MySQL databases
*
* PHP version 5
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
18,9 → 18,9
* @package DB
* @author Stig Bakken <ssb@php.net>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2007 The PHP Group
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$
* @version CVS: $Id: mysql.php,v 1.117 2005/03/29 15:03:26 danielc Exp $
* @link http://pear.php.net/package/DB
*/
 
39,9 → 39,9
* @package DB
* @author Stig Bakken <ssb@php.net>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2007 The PHP Group
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.9.2
* @version Release: 1.7.6
* @link http://pear.php.net/package/DB
*/
class DB_mysql extends DB_common
111,9 → 111,6
1146 => DB_ERROR_NOSUCHTABLE,
1216 => DB_ERROR_CONSTRAINT,
1217 => DB_ERROR_CONSTRAINT,
1356 => DB_ERROR_DIVZERO,
1451 => DB_ERROR_CONSTRAINT,
1452 => DB_ERROR_CONSTRAINT,
);
 
/**
162,13 → 159,13
// {{{ constructor
 
/**
* This constructor calls <kbd>parent::__construct()</kbd>
* This constructor calls <kbd>$this->DB_common()</kbd>
*
* @return void
*/
function __construct()
function DB_mysql()
{
parent::__construct();
$this->DB_common();
}
 
// }}}
239,10 → 236,10
$this->connection = @call_user_func_array($connect_function,
$params);
} else {
@ini_set('track_errors', 1);
ini_set('track_errors', 1);
$this->connection = @call_user_func_array($connect_function,
$params);
@ini_set('track_errors', $ini);
ini_set('track_errors', $ini);
}
 
if (!$this->connection) {
300,7 → 297,7
*/
function simpleQuery($query)
{
$ismanip = $this->_checkManip($query);
$ismanip = DB::isManip($query);
$this->last_query = $query;
$query = $this->modifyQuery($query);
if ($this->_db) {
422,7 → 419,7
*/
function freeResult($result)
{
return is_resource($result) ? mysql_free_result($result) : false;
return @mysql_free_result($result);
}
 
// }}}
558,7 → 555,7
*/
function affectedRows()
{
if ($this->_last_query_manip) {
if (DB::isManip($this->last_query)) {
return @mysql_affected_rows($this->connection);
} else {
return 0;
755,10 → 752,9
 
/**
* Quotes a string so it can be safely used as a table or column name
* (WARNING: using names that require this is a REALLY BAD IDEA)
*
* WARNING: Older versions of MySQL can't handle the backtick
* character (<kbd>`</kbd>) in table or column names.
* MySQL can't handle the backtick character (<kbd>`</kbd>) in
* table or column names.
*
* @param string $str identifier name to be quoted
*
769,10 → 765,21
*/
function quoteIdentifier($str)
{
return '`' . str_replace('`', '``', $str) . '`';
return '`' . $str . '`';
}
 
// }}}
// {{{ quote()
 
/**
* @deprecated Deprecated in release 1.6.0
*/
function quote($str)
{
return $this->quoteSmart($str);
}
 
// }}}
// {{{ escapeSimple()
 
/**
845,7 → 852,7
*/
function modifyLimitQuery($query, $from, $count, $params = array())
{
if (DB::isManip($query) || $this->_next_query_manip) {
if (DB::isManip($query)) {
return $query . " LIMIT $count";
} else {
return $query . " LIMIT $from, $count";
921,19 → 928,12
function tableInfo($result, $mode = null)
{
if (is_string($result)) {
// Fix for bug #11580.
if ($this->_db) {
if (!@mysql_select_db($this->_db, $this->connection)) {
return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED);
}
}
/*
* Probably received a table name.
* Create a result resource identifier.
*/
$id = @mysql_query("SELECT * FROM $result LIMIT 0",
$this->connection);
$id = @mysql_list_fields($this->dsn['database'],
$result, $this->connection);
$got_string = true;
} elseif (isset($result->result)) {
/*
/trunk/bibliotheque/pear/DB/fbsql.php
6,7 → 6,7
* The PEAR DB driver for PHP's fbsql extension
* for interacting with FrontBase databases
*
* PHP version 5
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
18,9 → 18,9
* @package DB
* @author Frank M. Kromann <frank@frontbase.com>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2007 The PHP Group
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$
* @version CVS: $Id: fbsql.php,v 1.82 2005/03/04 23:12:36 danielc Exp $
* @link http://pear.php.net/package/DB
*/
 
39,9 → 39,9
* @package DB
* @author Frank M. Kromann <frank@frontbase.com>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2007 The PHP Group
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.9.2
* @version Release: 1.7.6
* @link http://pear.php.net/package/DB
* @since Class functional since Release 1.7.0
*/
124,13 → 124,13
// {{{ constructor
 
/**
* This constructor calls <kbd>parent::__construct()</kbd>
* This constructor calls <kbd>$this->DB_common()</kbd>
*
* @return void
*/
function __construct()
function DB_fbsql()
{
parent::__construct();
$this->DB_common();
}
 
// }}}
171,10 → 171,10
$this->connection = @call_user_func_array($connect_function,
$params);
} else {
@ini_set('track_errors', 1);
ini_set('track_errors', 1);
$this->connection = @call_user_func_array($connect_function,
$params);
@ini_set('track_errors', $ini);
ini_set('track_errors', $ini);
}
 
if (!$this->connection) {
229,7 → 229,7
}
// Determine which queries that should return data, and which
// should return an error code only.
if ($this->_checkManip($query)) {
if (DB::isManip($query)) {
return DB_OK;
}
return $result;
320,7 → 320,7
*/
function freeResult($result)
{
return is_resource($result) ? fbsql_free_result($result) : false;
return @fbsql_free_result($result);
}
 
// }}}
353,7 → 353,7
*/
function commit()
{
@fbsql_commit($this->connection);
@fbsql_commit();
}
 
// }}}
366,7 → 366,7
*/
function rollback()
{
@fbsql_rollback($this->connection);
@fbsql_rollback();
}
 
// }}}
431,7 → 431,7
*/
function affectedRows()
{
if ($this->_last_query_manip) {
if (DB::isManip($this->last_query)) {
$result = @fbsql_affected_rows($this->connection);
} else {
$result = 0;
543,7 → 543,7
*/
function modifyLimitQuery($query, $from, $count, $params = array())
{
if (DB::isManip($query) || $this->_next_query_manip) {
if (DB::isManip($query)) {
return preg_replace('/^([\s(])*SELECT/i',
"\\1SELECT TOP($count)", $query);
} else {
553,37 → 553,38
}
 
// }}}
// {{{ quoteBoolean()
// {{{ quoteSmart()
 
/**
* Formats a boolean value for use within a query in a locale-independent
* manner.
* Formats input so it can be safely used in a query
*
* @param boolean the boolean value to be quoted.
* @return string the quoted string.
* @param mixed $in the data to be formatted
*
* @return mixed the formatted data. The format depends on the input's
* PHP type:
* + null = the string <samp>NULL</samp>
* + boolean = string <samp>TRUE</samp> or <samp>FALSE</samp>
* + integer or double = the unquoted number
* + other (including strings and numeric strings) =
* the data escaped according to FrontBase's settings
* then encapsulated between single quotes
*
* @see DB_common::quoteSmart()
* @since Method available since release 1.7.8.
* @since Method available since Release 1.6.0
*/
function quoteBoolean($boolean) {
return $boolean ? 'TRUE' : 'FALSE';
function quoteSmart($in)
{
if (is_int($in) || is_double($in)) {
return $in;
} elseif (is_bool($in)) {
return $in ? 'TRUE' : 'FALSE';
} elseif (is_null($in)) {
return 'NULL';
} else {
return "'" . $this->escapeSimple($in) . "'";
}
}
// }}}
// {{{ quoteFloat()
 
/**
* Formats a float value for use within a query in a locale-independent
* manner.
*
* @param float the float value to be quoted.
* @return string the quoted string.
* @see DB_common::quoteSmart()
* @since Method available since release 1.7.8.
*/
function quoteFloat($float) {
return $this->escapeSimple(str_replace(',', '.', strval(floatval($float))));
}
// }}}
// {{{ fbsqlRaiseError()
 
/trunk/bibliotheque/pear/DB/odbc.php
6,7 → 6,7
* The PEAR DB driver for PHP's odbc extension
* for interacting with databases via ODBC connections
*
* PHP version 5
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
18,9 → 18,9
* @package DB
* @author Stig Bakken <ssb@php.net>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2007 The PHP Group
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$
* @version CVS: $Id: odbc.php,v 1.78 2005/02/28 01:42:17 danielc Exp $
* @link http://pear.php.net/package/DB
*/
 
42,9 → 42,9
* @package DB
* @author Stig Bakken <ssb@php.net>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2007 The PHP Group
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.9.2
* @version Release: 1.7.6
* @link http://pear.php.net/package/DB
*/
class DB_odbc extends DB_common
153,13 → 153,13
// {{{ constructor
 
/**
* This constructor calls <kbd>parent::__construct()</kbd>
* This constructor calls <kbd>$this->DB_common()</kbd>
*
* @return void
*/
function __construct()
function DB_odbc()
{
parent::__construct();
$this->DB_common();
}
 
// }}}
266,7 → 266,7
}
// Determine which queries that should return data, and which
// should return an error code only.
if ($this->_checkManip($query)) {
if (DB::isManip($query)) {
$this->affected = $result; // For affectedRows()
return DB_OK;
}
367,7 → 367,7
*/
function freeResult($result)
{
return is_resource($result) ? odbc_free_result($result) : false;
return @odbc_free_result($result);
}
 
// }}}
481,6 → 481,18
}
 
// }}}
// {{{ quote()
 
/**
* @deprecated Deprecated in release 1.6.0
* @internal
*/
function quote($str)
{
return $this->quoteSmart($str);
}
 
// }}}
// {{{ nextId()
 
/**
/trunk/bibliotheque/pear/DB/msql.php
10,7 → 10,7
* 4.3.11 and 5.0.4. Make sure your version of PHP meets or exceeds
* those versions.
*
* PHP version 5
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
21,9 → 21,9
* @category Database
* @package DB
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2007 The PHP Group
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$
* @version CVS: $Id: msql.php,v 1.57 2005/02/22 07:26:46 danielc Exp $
* @link http://pear.php.net/package/DB
*/
 
45,9 → 45,9
* @category Database
* @package DB
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2007 The PHP Group
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.9.2
* @version Release: 1.7.6
* @link http://pear.php.net/package/DB
* @since Class not functional until Release 1.7.0
*/
126,13 → 126,13
// {{{ constructor
 
/**
* This constructor calls <kbd>parent::__construct()</kbd>
* This constructor calls <kbd>$this->DB_common()</kbd>
*
* @return void
*/
function __construct()
function DB_msql()
{
parent::__construct();
$this->DB_common();
}
 
// }}}
153,7 → 153,7
* 'portability' => DB_PORTABILITY_ALL,
* );
*
* $db = DB::connect($dsn, $options);
* $db =& DB::connect($dsn, $options);
* if (PEAR::isError($db)) {
* die($db->getMessage());
* }
190,10 → 190,10
$this->connection = @call_user_func_array($connect_function,
$params);
} else {
@ini_set('track_errors', 1);
ini_set('track_errors', 1);
$this->connection = @call_user_func_array($connect_function,
$params);
@ini_set('track_errors', $ini);
ini_set('track_errors', $ini);
}
 
if (!$this->connection) {
251,7 → 251,7
}
// Determine which queries that should return data, and which
// should return an error code only.
if ($this->_checkManip($query)) {
if (DB::isManip($query)) {
$this->_result = $result;
return DB_OK;
} else {
350,7 → 350,7
*/
function freeResult($result)
{
return is_resource($result) ? msql_free_result($result) : false;
return @msql_free_result($result);
}
 
// }}}
443,7 → 443,7
$repeat = false;
do {
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$result = $this->query("SELECT _seq FROM ${seqname}");
$result =& $this->query("SELECT _seq FROM ${seqname}");
$this->popErrorHandling();
if ($ondemand && DB::isError($result) &&
$result->getCode() == DB_ERROR_NOSUCHTABLE) {
531,22 → 531,6
}
 
// }}}
// {{{ quoteFloat()
 
/**
* Formats a float value for use within a query in a locale-independent
* manner.
*
* @param float the float value to be quoted.
* @return string the quoted string.
* @see DB_common::quoteSmart()
* @since Method available since release 1.7.8.
*/
function quoteFloat($float) {
return $this->escapeSimple(str_replace(',', '.', strval(floatval($float))));
}
// }}}
// {{{ escapeSimple()
 
/**
614,11 → 598,6
function errorCode($errormsg)
{
static $error_regexps;
// PHP 5.2+ prepends the function name to $php_errormsg, so we need
// this hack to work around it, per bug #9599.
$errormsg = preg_replace('/^msql[a-z_]+\(\): /', '', $errormsg);
 
if (!isset($error_regexps)) {
$error_regexps = array(
'/^Access to database denied/i'
/trunk/bibliotheque/pear/DB/dbase.php
6,7 → 6,7
* The PEAR DB driver for PHP's dbase extension
* for interacting with dBase databases
*
* PHP version 5
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
18,9 → 18,9
* @package DB
* @author Tomas V.V. Cox <cox@idecnet.com>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2007 The PHP Group
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$
* @version CVS: $Id: dbase.php,v 1.39 2005/02/19 23:25:25 danielc Exp $
* @link http://pear.php.net/package/DB
*/
 
39,9 → 39,9
* @package DB
* @author Tomas V.V. Cox <cox@idecnet.com>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2007 The PHP Group
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.9.2
* @version Release: 1.7.6
* @link http://pear.php.net/package/DB
*/
class DB_dbase extends DB_common
140,13 → 140,13
// {{{ constructor
 
/**
* This constructor calls <kbd>parent::__construct()</kbd>
* This constructor calls <kbd>$this->DB_common()</kbd>
*
* @return void
*/
function __construct()
function DB_dbase()
{
parent::__construct();
$this->DB_common();
}
 
// }}}
188,7 → 188,7
* 'portability' => DB_PORTABILITY_ALL,
* );
*
* $db = DB::connect($dsn, $options);
* $db =& DB::connect($dsn, $options);
* if (PEAR::isError($db)) {
* die($db->getMessage());
* }
214,7 → 214,7
* Turn track_errors on for entire script since $php_errormsg
* is the only way to find errors from the dbase extension.
*/
@ini_set('track_errors', 1);
ini_set('track_errors', 1);
$php_errormsg = '';
 
if (!file_exists($dsn['database'])) {
273,7 → 273,7
{
// emulate result resources
$this->res_row[(int)$this->result] = 0;
$tmp = new DB_result($this, $this->result++);
$tmp =& new DB_result($this, $this->result++);
return $tmp;
}
 
326,26 → 326,6
}
 
// }}}
// {{{ freeResult()
 
/**
* Deletes the result set and frees the memory occupied by the result set.
*
* This method is a no-op for dbase, as there aren't result resources in
* the same sense as most other database backends.
*
* @param resource $result PHP's query result resource
*
* @return bool TRUE on success, FALSE if $result is invalid
*
* @see DB_result::free()
*/
function freeResult($result)
{
return true;
}
 
// }}}
// {{{ numCols()
 
/**
388,21 → 368,41
}
 
// }}}
// {{{ quoteBoolean()
// {{{ quoteSmart()
 
/**
* Formats a boolean value for use within a query in a locale-independent
* manner.
* Formats input so it can be safely used in a query
*
* @param boolean the boolean value to be quoted.
* @return string the quoted string.
* @param mixed $in the data to be formatted
*
* @return mixed the formatted data. The format depends on the input's
* PHP type:
* + null = the string <samp>NULL</samp>
* + boolean = <samp>T</samp> if true or
* <samp>F</samp> if false. Use the <kbd>Logical</kbd>
* data type.
* + integer or double = the unquoted number
* + other (including strings and numeric strings) =
* the data with single quotes escaped by preceeding
* single quotes then the whole string is encapsulated
* between single quotes
*
* @see DB_common::quoteSmart()
* @since Method available since release 1.7.8.
* @since Method available since Release 1.6.0
*/
function quoteBoolean($boolean) {
return $boolean ? 'T' : 'F';
function quoteSmart($in)
{
if (is_int($in) || is_double($in)) {
return $in;
} elseif (is_bool($in)) {
return $in ? 'T' : 'F';
} elseif (is_null($in)) {
return 'NULL';
} else {
return "'" . $this->escapeSimple($in) . "'";
}
}
 
// }}}
// {{{ tableInfo()
 
/trunk/bibliotheque/pear/DB/mysqli.php
6,7 → 6,7
* The PEAR DB driver for PHP's mysqli extension
* for interacting with MySQL databases
*
* PHP version 5
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
17,9 → 17,9
* @category Database
* @package DB
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2007 The PHP Group
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$
* @version CVS: $Id: mysqli.php,v 1.69 2005/03/04 23:12:36 danielc Exp $
* @link http://pear.php.net/package/DB
*/
 
41,9 → 41,9
* @category Database
* @package DB
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2007 The PHP Group
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.9.2
* @version Release: 1.7.6
* @link http://pear.php.net/package/DB
* @since Class functional since Release 1.6.3
*/
114,9 → 114,6
1146 => DB_ERROR_NOSUCHTABLE,
1216 => DB_ERROR_CONSTRAINT,
1217 => DB_ERROR_CONSTRAINT,
1356 => DB_ERROR_DIVZERO,
1451 => DB_ERROR_CONSTRAINT,
1452 => DB_ERROR_CONSTRAINT,
);
 
/**
213,10 → 210,6
MYSQLI_TYPE_VAR_STRING => 'varchar',
MYSQLI_TYPE_STRING => 'char',
MYSQLI_TYPE_GEOMETRY => 'geometry',
/* These constants are conditionally compiled in ext/mysqli, so we'll
* define them by number rather than constant. */
16 => 'bit',
246 => 'decimal',
);
 
 
224,13 → 217,13
// {{{ constructor
 
/**
* This constructor calls <kbd>parent::__construct()</kbd>
* This constructor calls <kbd>$this->DB_common()</kbd>
*
* @return void
*/
function __construct()
function DB_mysqli()
{
parent::__construct();
$this->DB_common();
}
 
// }}}
271,7 → 264,7
* 'ssl' => true,
* );
*
* $db = DB::connect($dsn, $options);
* $db =& DB::connect($dsn, $options);
* if (PEAR::isError($db)) {
* die($db->getMessage());
* }
294,10 → 287,10
}
 
$ini = ini_get('track_errors');
@ini_set('track_errors', 1);
ini_set('track_errors', 1);
$php_errormsg = '';
 
if (((int) $this->getOption('ssl')) === 1) {
if ($this->getOption('ssl') === true) {
$init = mysqli_init();
mysqli_ssl_set(
$init,
329,7 → 322,7
);
}
 
@ini_set('track_errors', $ini);
ini_set('track_errors', $ini);
 
if (!$this->connection) {
if (($err = @mysqli_connect_error()) != '') {
379,7 → 372,7
*/
function simpleQuery($query)
{
$ismanip = $this->_checkManip($query);
$ismanip = DB::isManip($query);
$this->last_query = $query;
$query = $this->modifyQuery($query);
if ($this->_db) {
497,11 → 490,7
*/
function freeResult($result)
{
if (! $result instanceof mysqli_result) {
return false;
}
mysqli_free_result($result);
return true;
return @mysqli_free_result($result);
}
 
// }}}
637,7 → 626,7
*/
function affectedRows()
{
if ($this->_last_query_manip) {
if (DB::isManip($this->last_query)) {
return @mysqli_affected_rows($this->connection);
} else {
return 0;
834,10 → 823,9
 
/**
* Quotes a string so it can be safely used as a table or column name
* (WARNING: using names that require this is a REALLY BAD IDEA)
*
* WARNING: Older versions of MySQL can't handle the backtick
* character (<kbd>`</kbd>) in table or column names.
* MySQL can't handle the backtick character (<kbd>`</kbd>) in
* table or column names.
*
* @param string $str identifier name to be quoted
*
848,7 → 836,7
*/
function quoteIdentifier($str)
{
return '`' . str_replace('`', '``', $str) . '`';
return '`' . $str . '`';
}
 
// }}}
890,7 → 878,7
*/
function modifyLimitQuery($query, $from, $count, $params = array())
{
if (DB::isManip($query) || $this->_next_query_manip) {
if (DB::isManip($query)) {
return $query . " LIMIT $count";
} else {
return $query . " LIMIT $from, $count";
966,13 → 954,6
function tableInfo($result, $mode = null)
{
if (is_string($result)) {
// Fix for bug #11580.
if ($this->_db) {
if (!@mysqli_select_db($this->connection, $this->_db)) {
return $this->mysqliRaiseError(DB_ERROR_NODBSELECTED);
}
}
 
/*
* Probably received a table name.
* Create a result resource identifier.
997,7 → 978,7
$got_string = false;
}
 
if (!is_object($id) || !is_a($id, 'mysqli_result')) {
if (!is_a($id, 'mysqli_result')) {
return $this->mysqliRaiseError(DB_ERROR_NEED_MORE_DATA);
}
 
1034,12 → 1015,7
'type' => isset($this->mysqli_types[$tmp->type])
? $this->mysqli_types[$tmp->type]
: 'unknown',
// http://bugs.php.net/?id=36579
// Doc Bug #36579: mysqli_fetch_field length handling
// https://bugs.php.net/bug.php?id=62426
// Bug #62426: mysqli_fetch_field_direct returns incorrect
// length on UTF8 fields
'len' => $tmp->length,
'len' => $tmp->max_length,
'flags' => $flags,
);
 
/trunk/bibliotheque/pear/DB/ldap.php
New file
0,0 → 1,994
<?php
//
// Pear DB LDAP - Database independent query interface definition
// for PHP's LDAP extension.
//
// Copyright (c) 2002-2003 Ludovico Magnocavallo <ludo@sumatrasolutions.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// Contributors
// - Piotr Roszatycki <dexter@debian.org>
// DB_ldap::base() method, support for LDAP sequences, various fixes
// - Aaron Spencer Hawley <aaron dot hawley at uvm dot edu>
// fix to use port number if present in DB_ldap->connect()
//
// $Id: ldap.php,v 1.22 2005/06/16 19:17:54 ludoo Exp $
//
 
require_once 'DB.php';
require_once 'DB/common.php';
 
define("DB_ERROR_BIND_FAILED", -26);
define("DB_ERROR_UNKNOWN_LDAP_ACTION", -27);
 
/**
* LDAP result class
*
* LDAP_result extends DB_result to provide specific LDAP
* result methods.
*
* @version 1.0
* @author Ludovico Magnocavallo <ludo@sumatrasolutions.com>
* @package DB
*/
 
class LDAP_result extends DB_result
{
 
// {{{ properties
 
/**
* data returned from ldap_entries()
* @access private
*/
var $_entries = null;
/**
* result rows as hash of records
* @access private
*/
var $_recordset = null;
/**
* current record as hash
* @access private
*/
var $_record = null;
 
// }}}
// {{{ constructor
 
/**
* class constructor, calls DB_result constructor
* @param ref $dbh reference to the db instance
* @param resource $result ldap command result
*/
function LDAP_result(&$dbh, $result)
{
$this->DB_result($dbh, $result);
}
 
/**
* fetch rows of data into $this->_recordset
*
* called once as soon as something needs to be returned
* @access private
* @param resource $result ldap command result
* @return boolean true
*/
function getRows() {
if ($this->_recordset === null) {
// begin processing result into recordset
$this->_entries = ldap_get_entries($this->dbh->connection, $this->result);
$this->row_counter = $this->_entries['count'];
$i = 1;
$rs_template = array();
if (count($this->dbh->attributes) > 0) {
reset($this->dbh->attributes);
while (list($a_index, $a_name) = each($this->dbh->attributes)) $rs_template[$a_name] = '';
}
while (list($entry_idx, $entry) = each($this->_entries)) {
// begin first loop, iterate through entries
if (!empty($this->dbh->limit_from) && ($i < $this->dbh->limit_from)) continue;
if (!empty($this->dbh->limit_count) && ($i > $this->dbh->limit_count)) break;
$rs = $rs_template;
if (!is_array($entry)) continue;
while (list($attr, $attr_values) = each($entry)) {
// begin second loop, iterate through attributes
if (is_int($attr) || $attr == 'count') continue;
if (is_string($attr_values)) $rs[$attr] = $attr_values;
else {
$value = '';
while (list($value_idx, $attr_value) = each($attr_values)) {
// begin third loop, iterate through attribute values
if (!is_int($value_idx)) continue;
if (empty($value)) $value = $attr_value;
else {
if (is_array($value)) $value[] = $attr_value;
else $value = array($value, $attr_value);
}
// else $value .= "\n$attr_value";
// end third loop
}
$rs[$attr] = $value;
}
// end second loop
}
reset($rs);
$this->_recordset[$entry_idx] = $rs;
$i++;
// end first loop
}
$this->_entries = null;
if (!is_array($this->_recordset))
$this->_recordset = array();
if (!empty($this->dbh->sorting)) {
$sorting_method = (!empty($this->dbh->sorting_method) ? $this->dbh->sorting_method : 'cmp');
uksort($this->_recordset, array(&$this, $sorting_method));
}
reset($this->_recordset);
// end processing result into recordset
}
return DB_OK;
}
 
 
/**
* Fetch and return a row of data (it uses driver->fetchInto for that)
* @param int $fetchmode format of fetched row
* @param int $rownum the row number to fetch
*
* @return array a row of data, NULL on no more rows or PEAR_Error on error
*
* @access public
*/
function &fetchRow($fetchmode = DB_FETCHMODE_DEFAULT, $rownum=null)
{
$this->getRows();
if (count($this->_recordset) == 0) return null;
if ($this->_record !== null) $this->_record = next($this->_recordset);
else $this->_record = current($this->_recordset);
$row = $this->_record;
return $row;
}
 
 
/**
* Fetch a row of data into an existing variable.
*
* @param mixed $arr reference to data containing the row
* @param integer $fetchmode format of fetched row
* @param integer $rownum the row number to fetch
*
* @return mixed DB_OK on success, NULL on no more rows or
* a DB_Error object on error
*
* @access public
*/
 
function fetchInto(&$ar, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum = null)
{
$this->getRows();
if ($this->_record !== null) $this->_record = next($this->_recordset);
else $this->_record = current($this->_recordset);
$ar = $this->_record;
if (!$ar) {
return null;
}
return DB_OK;
}
 
/**
* return all records
*
* returns a hash of all records, basically returning
* a copy of $this->_recordset
* @param integer $fetchmode format of fetched row
* @param integer $rownum the row number to fetch (not used, here for interface compatibility)
*
* @return mixed DB_OK on success, NULL on no more rows or
* a DB_Error object on error
*
* @access public
*/
function fetchAll($fetchmode = DB_FETCHMODE_DEFAULT, $rownum = null)
{
$this->getRows();
return($this->_recordset);
}
 
/**
* Get the the number of columns in a result set.
*
* @return int the number of columns, or a DB error
*
* @access public
*/
function numCols($result)
{
$this->getRows();
return(count(array_keys($this->_record)));
}
 
function cmp($a, $b)
{
return(strcmp(strtolower($this->_recordset[$a][$this->dbh->sorting]), strtolower($this->_recordset[$b][$this->dbh->sorting])));
}
 
/**
* Get the number of rows in a result set.
*
* @return int the number of rows, or a DB error
*
* @access public
*/
function numRows()
{
$this->getRows();
return $this->row_counter;
}
 
/**
* Get the next result if a batch of queries was executed.
*
* @return bool true if a new result is available or false if not.
*
* @access public
*/
function nextResult()
{
return $this->dbh->nextResult($this->result);
}
 
/**
* Frees the resources allocated for this result set.
* @return int error code
*
* @access public
*/
function free()
{
$this->_recordset = null;
$this->_record = null;
ldap_free_result($this->result);
$this->result = null;
return true;
}
 
/**
* @deprecated
*/
function tableInfo($mode = null)
{
return $this->dbh->tableInfo($this->result, $mode);
}
 
/**
* returns the actual rows number
* @return integer
*/
function getRowCounter()
{
$this->getRows();
return $this->row_counter;
}
}
 
/**
* LDAP DB interface class
*
* LDAP extends DB_common to provide DB compliant
* access to LDAP servers
*
* @version 1.0
* @author Ludovico Magnocavallo <ludo@sumatrasolutions.com>
* @package DB
*/
 
class DB_ldap extends DB_common
{
// {{{ properties
 
/**
* LDAP connection
* @access private
*/
var $connection;
/**
* base dn
* @access private
*/
var $base = '';
/**
* default base dn
* @access private
*/
var $d_base = '';
/**
* query base dn
* @access private
*/
var $q_base = '';
/**
* array of LDAP actions that only manipulate data
* returning a true/false value
* @access private
*/
var $manip = array('add', 'compare', 'delete', 'modify', 'mod_add', 'mod_del', 'mod_replace', 'rename');
/**
* store the default real LDAP action to perform
* @access private
*/
var $action = 'search';
/**
* store the real LDAP action to perform
* (ie PHP ldap function to call) for a query
* @access private
*/
var $q_action = '';
/**
* store optional parameters passed
* to the real LDAP action
* @access private
*/
var $q_params = array();
 
// }}}
 
/**
* Constructor, calls DB_common constructor
*
* @see DB_common::DB_common()
*/
function DB_ldap()
{
$this->DB_common();
$this->phptype = 'ldap';
$this->dbsyntax = 'ldap';
$this->features = array(
'prepare' => false,
'pconnect' => false,
'transactions' => false,
'limit' => false
);
$this->errorcode_map = array(
0x10 => DB_ERROR_NOSUCHFIELD, // LDAP_NO_SUCH_ATTRIBUTE
0x11 => DB_ERROR_INVALID, // LDAP_UNDEFINED_TYPE
0x12 => DB_ERROR_INVALID, // LDAP_INAPPROPRIATE_MATCHING
0x13 => DB_ERROR_INVALID, // LDAP_CONSTRAINT_VIOLATION
0x14 => DB_ERROR_ALREADY_EXISTS, // LDAP_TYPE_OR_VALUE_EXISTS
0x15 => DB_ERROR_INVALID, // LDAP_INVALID_SYNTAX
0x20 => DB_ERROR_NOT_FOUND, // LDAP_NO_SUCH_OBJECT
0x21 => DB_ERROR_NOT_FOUND, // LDAP_ALIAS_PROBLEM
0x22 => DB_ERROR_INVALID, // LDAP_INVALID_DN_SYNTAX
0x23 => DB_ERROR_INVALID, // LDAP_IS_LEAF
0x24 => DB_ERROR_INVALID, // LDAP_ALIAS_DEREF_PROBLEM
0x30 => DB_ERROR_ACCESS_VIOLATION, // LDAP_INAPPROPRIATE_AUTH
0x31 => DB_ERROR_ACCESS_VIOLATION, // LDAP_INVALID_CREDENTIALS
0x32 => DB_ERROR_ACCESS_VIOLATION, // LDAP_INSUFFICIENT_ACCESS
0x40 => DB_ERROR_MISMATCH, // LDAP_NAMING_VIOLATION
0x41 => DB_ERROR_MISMATCH, // LDAP_OBJECT_CLASS_VIOLATION
0x44 => DB_ERROR_ALREADY_EXISTS, // LDAP_ALREADY_EXISTS
0x51 => DB_ERROR_CONNECT_FAILED, // LDAP_SERVER_DOWN
0x57 => DB_ERROR_SYNTAX // LDAP_FILTER_ERROR
);
}
 
/**
* Connect and bind to LDAP server with either anonymous or authenticated bind depending on dsn info
*
* @param array $dsninfo dsn info as passed by DB::connect()
* @param boolean $persistent kept for interface compatibility
* @return DB_OK if successfully connected. A DB error code is returned on failure.
*/
function connect($dsninfo, $persistent = false)
{
if (!PEAR::loadExtension('ldap'))
return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
 
$this->dsn = $dsninfo;
$user = $dsninfo['username'];
$pw = $dsninfo['password'];
$host = $dsninfo['hostspec'];
$port = $dsninfo['port'];
$this->base = $dsninfo['database'];
$this->d_base = $this->base;
 
if (empty($host)) {
return $this->raiseError("no host specified $host");
} // else ...
 
if (isset($port)) {
$conn = ldap_connect($host, $port);
} else {
$conn = ldap_connect($host);
}
if (!$conn) {
return $this->raiseError(DB_ERROR_CONNECT_FAILED);
}
if ($user && $pw) {
$bind = @ldap_bind($conn, $user, $pw);
} else {
$bind = @ldap_bind($conn);
}
if (!$bind) {
return $this->raiseError(DB_ERROR_BIND_FAILED);
}
$this->connection = $conn;
return DB_OK;
}
 
/**
* Unbinds from LDAP server
*
* @return int ldap_unbind() return value
*/
function disconnect()
{
$ret = @ldap_unbind($this->connection);
$this->connection = null;
return $ret;
}
 
 
/**
* Performs a request against the LDAP server
*
* The type of request (and the corresponding PHP ldap function called)
* depend on two additional parameters, added in respect to the
* DB_common interface.
*
* @param string $filter text of the request to send to the LDAP server
* @param string $action type of request to perform, defaults to search (ldap_search())
* @param array $params array of additional parameters to pass to the PHP ldap function requested
* @return result from ldap function or DB Error object if no result
*/
function simpleQuery($filter, $action = null, $params = null)
{
if ($action === null) {
$action = (!empty($this->q_action) ? $this->q_action : $this->action);
}
if ($params === null) {
$params = (count($this->q_params) > 0 ? $this->q_params : array());
}
if (!$this->isManip($action)) {
$base = $this->q_base ? $this->q_base : $this->base;
$attributes = array();
$attrsonly = 0;
$sizelimit = 0;
$timelimit = 0;
$deref = LDAP_DEREF_NEVER;
$sorting = '';
$sorting_method = '';
reset($params);
while (list($k, $v) = each($params)) {
if (isset(${$k})) ${$k} = $v;
}
$this->sorting = $sorting;
$this->sorting_method = $sorting_method;
$this->attributes = $attributes;
# double escape char for filter: '(o=Przedsi\C4\99biorstwo)' => '(o=Przedsi\\C4\\99biorstwo)'
$filter = str_replace('\\', '\\\\', $filter);
$this->last_query = $filter;
if ($action == 'search')
$result = @ldap_search($this->connection, $base, $filter, $attributes, $attrsonly, $sizelimit, $timelimit, $deref);
else if ($action == 'list')
$result = @ldap_list($this->connection, $base, $filter, $attributes, $attrsonly, $sizelimit, $timelimit, $deref);
else if ($action == 'read')
$result = @ldap_read($this->connection, $base, $filter, $attributes, $attrsonly, $sizelimit, $timelimit, $deref);
else
return $this->ldapRaiseError(DB_ERROR_UNKNOWN_LDAP_ACTION);
if (!$result) {
return $this->ldapRaiseError();
}
} else {
# If first argument is an array, it contains the entry with DN.
if (is_array($filter)) {
$entry = $filter;
$filter = $entry["dn"];
} else {
$entry = array();
}
unset($entry["dn"]);
$attribute = '';
$value = '';
$newrdn = '';
$newparent = '';
$deleteoldrdn = false;
reset($params);
while (list($k, $v) = each($params)) {
if (isset(${$k})) ${$k} = $v;
}
$this->last_query = $filter;
if ($action == 'add')
$result = @ldap_add($this->connection, $filter, $entry);
else if ($action == 'compare')
$result = @ldap_add($this->connection, $filter, $attribute, $value);
else if ($action == 'delete')
$result = @ldap_delete($this->connection, $filter);
else if ($action == 'modify')
$result = @ldap_modify($this->connection, $filter, $entry);
else if ($action == 'mod_add')
$result = @ldap_mod_add($this->connection, $filter, $entry);
else if ($action == 'mod_del')
$result = @ldap_mod_del($this->connection, $filter, $entry);
else if ($action == 'mod_replace')
$result = @ldap_mod_replace($this->connection, $filter, $entry);
else if ($action == 'rename')
$result = @ldap_rename($this->connection, $filter, $newrdn, $newparent, $deleteoldrdn);
else
return $this->ldapRaiseError(DB_ERROR_UNKNOWN_LDAP_ACTION);
if (!$result) {
return $this->ldapRaiseError();
}
}
$this->freeQuery();
return $result;
}
 
/**
* Executes a query performing variables substitution in the query text
*
* @param string $stmt text of the request to send to the LDAP server
* @param array $data query variables values to substitute
* @param string $action type of request to perform, defaults to search (ldap_search())
* @param array $params array of additional parameters to pass to the PHP ldap function requested
* @return LDAP_result object or DB Error object if no result
* @see DB_common::executeEmulateQuery $this->simpleQuery()
*/
function execute($stmt, $data = false, $action = null, $params = array())
{
$this->q_params = $params;
$realquery = $this->executeEmulateQuery($stmt, $data);
if (DB::isError($realquery)) {
return $realquery;
}
$result = $this->simpleQuery($realquery);
if (DB::isError($result) || $result === DB_OK) {
return $result;
} else {
return new LDAP_result($this, $result);
}
}
 
/**
* Executes multiple queries performing variables substitution for each query
*
* @param string $stmt text of the request to send to the LDAP server
* @param array $data query variables values to substitute
* @param string $action type of request to perform, defaults to search (ldap_search())
* @param array $params array of additional parameters to pass to the PHP ldap function requested
* @return LDAP_result object or DB Error object if no result
* @see DB_common::executeMultiple
*/
function executeMultiple($stmt, &$data, $action = null, $params = array())
{
$this->q_action = $action ? $action : $this->action;
$this->q_params = $params;
return(parent::executeMultiple($stmt, $data));
}
 
/**
* Executes a query substituting variables if any are present
*
* @param string $query text of the request to send to the LDAP server
* @param array $data query variables values to substitute
* @param string $action type of request to perform, defaults to search (ldap_search())
* @param array $params array of additional parameters to pass to the PHP ldap function requested
* @return LDAP_result object or DB Error object if no result
* @see DB_common::prepare() $this->execute()$this->simpleQuery()
*/
function &query($query, $data = array(), $action = null, $params = array()) {
// $this->q_action = $action ? $action : $this->action;
// $this->q_params = $params;
if (sizeof($data) > 0) {
$sth = $this->prepare($query);
if (DB::isError($sth)) {
return $sth;
}
return $this->execute($sth, $data);
} else {
$result = $this->simpleQuery($query);
if (DB::isError($result) || $result === DB_OK) {
return $result;
} else {
return new LDAP_result($this, $result);
}
}
}
 
/**
* Modifies a query to return only a set of rows, stores $from and $count for LDAP_result
*
* @param string $query text of the request to send to the LDAP server
* @param int $from record position from which to start returning data
* @param int $count number of records to return
* @return modified query text (no modifications are made, see above)
*/
function modifyLimitQuery($query, $from, $count)
{
$this->limit_from = $from;
$this->limit_count = $count;
return $query;
}
 
/**
* Executes a query returning only a specified number of rows
*
* This method only saves the $from and $count parameters for LDAP_result
* where the actual records processing takes place
*
* @param string $query text of the request to send to the LDAP server
* @param int $from record position from which to start returning data
* @param int $count number of records to return
* @param string $action type of request to perform, defaults to search (ldap_search())
* @param array $params array of additional parameters to pass to the PHP ldap function requested
* @return LDAP_result object or DB Error object if no result
*/
function limitQuery($query, $from, $count, $action = null, $params = array())
{
$query = $this->modifyLimitQuery($query, $from, $count);
$this->q_action = $action ? $action : $this->action;
$this->q_params = $params;
return $this->query($query, $action, $params);
}
 
/**
* Fetch the first column of the first row of data returned from
* a query. Takes care of doing the query and freeing the results
* when finished.
*
* @param $query the SQL query
* @param $data if supplied, prepare/execute will be used
* with this array as execute parameters
* @param string $action type of request to perform, defaults to search (ldap_search())
* @param array $params array of additional parameters to pass to the PHP ldap function requested
* @return array
* @see DB_common::getOne()
* @access public
*/
function &getOne($query, $data = array(), $action = null, $params = array())
{
$this->q_action = $action ? $action : $this->action;
$this->q_params = $params;
return(parent::getOne($query, $data));
}
 
/**
* Fetch the first row of data returned from a query. Takes care
* of doing the query and freeing the results when finished.
*
* @param $query the SQL query
* @param $fetchmode the fetch mode to use
* @param $data array if supplied, prepare/execute will be used
* with this array as execute parameters
* @param string $action type of request to perform, defaults to search (ldap_search())
* @param array $params array of additional parameters to pass to the PHP ldap function requested
* @access public
* @return array the first row of results as an array indexed from
* 0, or a DB error code.
* @see DB_common::getRow()
* @access public
*/
function &getRow($query,
$data = null,
$fetchmode = DB_FETCHMODE_DEFAULT,
$action = null, $params = array())
{
$this->q_action = $action ? $action : $this->action;
$this->q_params = $params;
return(parent::getRow($query, $data, $fetchmode));
}
 
/**
* Fetch the first column of data returned from a query. Takes care
* of doing the query and freeing the results when finished.
*
* @param $query the SQL query
* @param $col which column to return (integer [column number,
* starting at 0] or string [column name])
* @param $data array if supplied, prepare/execute will be used
* with this array as execute parameters
* @param string $action type of request to perform, defaults to search (ldap_search())
* @param array $params array of additional parameters to pass to the PHP ldap function requested
* @access public
* @return array an indexed array with the data from the first
* row at index 0, or a DB error code.
* @see DB_common::getCol()
* @access public
*/
function &getCol($query, $col = 0, $data = array(), $action = null, $params = array())
{
$this->q_action = $action ? $action : $this->action;
$this->q_params = $params;
return(parent::getCol($query, $col, $data));
}
 
/**
* Calls DB_common::getAssoc()
*
* @param $query the SQL query
* @param $force_array (optional) used only when the query returns
* exactly two columns. If true, the values of the returned array
* will be one-element arrays instead of scalars.
* starting at 0] or string [column name])
* @param array $data if supplied, prepare/execute will be used
* with this array as execute parameters
* @param $fetchmode the fetch mode to use
* @param boolean $group see DB_Common::getAssoc()
* @param string $action type of request to perform, defaults to search (ldap_search())
* @param array $params array of additional parameters to pass to the PHP ldap function requested
* @access public
* @return array an indexed array with the data from the first
* row at index 0, or a DB error code.
* @see DB_common::getAssoc()
* @access public
*/
function &getAssoc($query, $force_array = false, $data = array(),
$fetchmode = DB_FETCHMODE_ORDERED, $group = false,
$action = null, $params = array())
{
$this->q_action = $action ? $action : $this->action;
$this->q_params = $params;
return(parent::getAssoc($query, $force_array, $data, $fetchmode, $group));
}
 
/**
* Fetch all the rows returned from a query.
*
* @param $query the SQL query
* @param array $data if supplied, prepare/execute will be used
* with this array as execute parameters
* @param $fetchmode the fetch mode to use
* @param string $action type of request to perform, defaults to search (ldap_search())
* @param array $params array of additional parameters to pass to the PHP ldap function requested
* @access public
* @return array an nested array, or a DB error
* @see DB_common::getAll()
*/
function &getAll($query,
$data = null,
$fetchmode = DB_FETCHMODE_DEFAULT,
$action = null, $params = array())
{
$this->q_action = $action ? $action : $this->action;
$this->q_params = $params;
return(parent::getAll($query, $data, $fetchmode));
}
 
function numRows($result)
{
return $result->numRows();
}
 
function getTables()
{
return $this->ldapRaiseError(DB_ERROR_NOT_CAPABLE);
}
 
function getListOf($type)
{
return $this->ldapRaiseError(DB_ERROR_NOT_CAPABLE);
}
 
function isManip($action)
{
return(in_array($action, $this->manip));
}
 
function freeResult()
{
return true;
}
 
function freeQuery($query = '')
{
$this->q_action = '';
$this->q_base = '';
$this->q_params = array();
$this->attributes = null;
$this->sorting = '';
return true;
}
 
// Deprecated, will be removed in future releases.
function base($base = null)
{
$this->q_base = ($base !== null) ? $base : null;
return true;
}
 
function ldapSetBase($base = null)
{
$this->base = ($base !== null) ? $base : $this->d_base;
$this->q_base = '';
return true;
}
 
function ldapSetAction($action = 'search')
{
if ($action != 'search' && $action != 'list' && $action != 'read') {
return $this->ldapRaiseError(DB_ERROR_UNKNOWN_LDAP_ACTION);
}
$this->action = $action;
$this->q_action = '';
return true;
}
 
/**
* Get the next value in a sequence.
*
* LDAP provides transactions for only one entry and we need to
* prevent race condition. If unique value before and after modify
* aren't equal then wait and try again.
*
* The name of sequence is LDAP DN of entry.
*
* @access public
* @param string $seq_name the DN of the sequence
* @param bool $ondemand whether to create the sequence on demand
* @return a sequence integer, or a DB error
*/
function nextId($seq_name, $ondemand = true)
{
$repeat = 0;
do {
// Get the sequence entry
$this->base($seq_name);
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$data = $this->getRow("objectClass=*");
$this->popErrorHandling();
 
if (DB::isError($data)) {
// DB_ldap doesn't use DB_ERROR_NOT_FOUND
if ($ondemand && $repeat == 0
&& $data->getCode() == DB_ERROR) {
// Try to create sequence and repeat
$repeat = 1;
$data = $this->createSequence($seq_name);
if (DB::isError($data)) {
return $this->ldapRaiseError($data);
}
} else {
// Other error
return $this->ldapRaiseError($data);
}
} else {
// Increment sequence value
$data["cn"]++;
// Unique identificator of transaction
$seq_unique = mt_rand();
$data["uid"] = $seq_unique;
// Modify the LDAP entry
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$data = $this->simpleQuery($data, 'modify');
$this->popErrorHandling();
if (DB::isError($data)) {
return $this->ldapRaiseError($data);
}
// Get the entry and check if it contains our unique value
$this->base($seq_name);
$data = $this->getRow("objectClass=*");
if (DB::isError($data)) {
return $this->ldapRaiseError($data);
}
if ($data["uid"] != $seq_unique) {
// It is not our entry. Wait a little time and repeat
sleep(1);
$repeat = 1;
} else {
$repeat = 0;
}
}
} while ($repeat);
 
if (DB::isError($data)) {
return $data;
}
return $data["cn"];
}
 
/**
* Create the sequence
*
* The sequence entry is based on core schema with extensibleObject,
* so it should work with any LDAP server which doesn't check schema
* or supports extensibleObject object class.
*
* Sequence name have to be DN started with "sn=$seq_id,", i.e.:
*
* $seq_name = "sn=uidNumber,ou=sequences,dc=php,dc=net";
*
* dn: $seq_name
* objectClass: top
* objectClass: extensibleObject
* sn: $seq_id
* cn: $seq_value
* uid: $seq_uniq
*
* @param string $seq_name the DN of the sequence
* @return mixed DB_OK on success or DB error on error
* @access public
*/
function createSequence($seq_name)
{
// Extract $seq_id from DN
ereg("^([^,]*),", $seq_name, $regs);
$seq_id = $regs[1];
 
// Create the sequence entry
$data = array(
dn => $seq_name,
objectclass => array("top", "extensibleObject"),
sn => $seq_id,
cn => 0,
uid => 0
);
 
// Add the LDAP entry
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$data = $this->simpleQuery($data, 'add');
$this->popErrorHandling();
return $data;
}
 
/**
* Drop a sequence
*
* @param string $seq_name the DN of the sequence
* @return mixed DB_OK on success or DB error on error
* @access public
*/
function dropSequence($seq_name)
{
// Delete the sequence entry
$data = array(
dn => $seq_name,
);
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$data = $this->simpleQuery($data, 'delete');
$this->popErrorHandling();
return $data;
}
 
// {{{ ldapRaiseError()
 
function ldapRaiseError($errno = null)
{
if ($errno === null) {
$errno = $this->errorCode(ldap_errno($this->connection));
}
if ($this->q_action !== null) {
return $this->raiseError($errno, null, null,
sprintf('%s base="%s" filter="%s"',
$this->q_action, $this->q_base, $this->last_query
),
$errno == DB_ERROR_UNKNOWN_LDAP_ACTION ? null : @ldap_error($this->connection));
} else {
return $this->raiseError($errno, null, null, "???",
@ldap_error($this->connection));
}
}
 
// }}}
 
}
 
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/
?>
/trunk/bibliotheque/pear/DB/ibase.php
9,7 → 9,7
* While this class works with PHP 4, PHP's InterBase extension is
* unstable in PHP 4. Use PHP 5.
*
* PHP version 5
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
21,9 → 21,9
* @package DB
* @author Sterling Hughes <sterling@php.net>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2007 The PHP Group
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$
* @version CVS: $Id: ibase.php,v 1.109 2005/03/04 23:12:36 danielc Exp $
* @link http://pear.php.net/package/DB
*/
 
47,9 → 47,9
* @package DB
* @author Sterling Hughes <sterling@php.net>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2007 The PHP Group
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.9.2
* @version Release: 1.7.6
* @link http://pear.php.net/package/DB
* @since Class became stable in Release 1.7.0
*/
123,7 → 123,6
-625 => DB_ERROR_CONSTRAINT_NOT_NULL,
-803 => DB_ERROR_CONSTRAINT,
-804 => DB_ERROR_VALUE_COUNT_ON_ROW,
// -902 => // Covers too many errors, need to use regex on msg
-904 => DB_ERROR_CONNECT_FAILED,
-922 => DB_ERROR_NOSUCHDB,
-923 => DB_ERROR_CONNECT_FAILED,
180,13 → 179,13
// {{{ constructor
 
/**
* This constructor calls <kbd>parent::__construct()</kbd>
* This constructor calls <kbd>$this->DB_common()</kbd>
*
* @return void
*/
function __construct()
function DB_ibase()
{
parent::__construct();
$this->DB_common();
}
 
// }}}
276,7 → 275,7
*/
function simpleQuery($query)
{
$ismanip = $this->_checkManip($query);
$ismanip = DB::isManip($query);
$this->last_query = $query;
$query = $this->modifyQuery($query);
$result = @ibase_query($this->connection, $query);
413,7 → 412,7
*/
function freeResult($result)
{
return is_resource($result) ? ibase_free_result($result) : false;
return @ibase_free_result($result);
}
 
// }}}
421,7 → 420,8
 
function freeQuery($query)
{
return is_resource($query) ? ibase_free_query($query) : false;
@ibase_free_query($query);
return true;
}
 
// }}}
521,14 → 521,8
$this->last_query = $query;
$newquery = $this->modifyQuery($newquery);
$stmt = @ibase_prepare($this->connection, $newquery);
 
if ($stmt === false) {
$stmt = $this->ibaseRaiseError();
} else {
$this->prepare_types[(int)$stmt] = $types;
$this->manip_query[(int)$stmt] = DB::isManip($query);
}
 
$this->prepare_types[(int)$stmt] = $types;
$this->manip_query[(int)$stmt] = DB::isManip($query);
return $stmt;
}
 
553,9 → 547,9
$data = (array)$data;
$this->last_parameters = $data;
 
$types = $this->prepare_types[(int)$stmt];
$types =& $this->prepare_types[(int)$stmt];
if (count($types) != count($data)) {
$tmp = $this->raiseError(DB_ERROR_MISMATCH);
$tmp =& $this->raiseError(DB_ERROR_MISMATCH);
return $tmp;
}
 
574,7 → 568,7
} elseif ($types[$i] == DB_PARAM_OPAQUE) {
$fp = @fopen($data[$key], 'rb');
if (!$fp) {
$tmp = $this->raiseError(DB_ERROR_ACCESS_VIOLATION);
$tmp =& $this->raiseError(DB_ERROR_ACCESS_VIOLATION);
return $tmp;
}
$data[$key] = fread($fp, filesize($data[$key]));
587,7 → 581,7
 
$res = call_user_func_array('ibase_execute', $data);
if (!$res) {
$tmp = $this->ibaseRaiseError();
$tmp =& $this->ibaseRaiseError();
return $tmp;
}
/* XXX need this?
595,13 → 589,10
@ibase_commit($this->connection);
}*/
$this->last_stmt = $stmt;
if ($this->manip_query[(int)$stmt] || $this->_next_query_manip) {
$this->_last_query_manip = true;
$this->_next_query_manip = false;
if ($this->manip_query[(int)$stmt]) {
$tmp = DB_OK;
} else {
$this->_last_query_manip = false;
$tmp = new DB_result($this, $res);
$tmp =& new DB_result($this, $res);
}
return $tmp;
}
707,7 → 698,7
$repeat = 0;
do {
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$result = $this->query("SELECT GEN_ID(${sqn}, 1) "
$result =& $this->query("SELECT GEN_ID(${sqn}, 1) "
. 'FROM RDB$GENERATORS '
. "WHERE RDB\$GENERATOR_NAME='${sqn}'");
$this->popErrorHandling();
865,7 → 856,7
if ($errno === null) {
$errno = $this->errorCode($this->errorNative());
}
$tmp = $this->raiseError($errno, null, null, null, @ibase_errmsg());
$tmp =& $this->raiseError($errno, null, null, null, @ibase_errmsg());
return $tmp;
}
 
916,8 → 907,6
$error_regexps = array(
'/generator .* is not defined/'
=> DB_ERROR_SYNTAX, // for compat. w ibase_errcode()
'/violation of [\w ]+ constraint/i'
=> DB_ERROR_CONSTRAINT,
'/table.*(not exist|not found|unknown)/i'
=> DB_ERROR_NOSUCHTABLE,
'/table .* already exists/i'
928,6 → 917,8
=> DB_ERROR_NOT_FOUND,
'/validation error for column .* value "\*\*\* null/i'
=> DB_ERROR_CONSTRAINT_NOT_NULL,
'/violation of [\w ]+ constraint/i'
=> DB_ERROR_CONSTRAINT,
'/conversion error from string/i'
=> DB_ERROR_INVALID_NUMBER,
'/no permission for/i'
934,8 → 925,6
=> DB_ERROR_ACCESS_VIOLATION,
'/arithmetic exception, numeric overflow, or string truncation/i'
=> DB_ERROR_INVALID,
'/feature is not supported/i'
=> DB_ERROR_NOT_CAPABLE,
);
}
 
/trunk/bibliotheque/pear/DB/sybase.php
6,7 → 6,7
* The PEAR DB driver for PHP's sybase extension
* for interacting with Sybase databases
*
* PHP version 5
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
19,9 → 19,9
* @author Sterling Hughes <sterling@php.net>
* @author Antônio Carlos Venâncio Júnior <floripa@php.net>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2007 The PHP Group
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$
* @version CVS: $Id: sybase.php,v 1.78 2005/02/20 00:44:48 danielc Exp $
* @link http://pear.php.net/package/DB
*/
 
44,9 → 44,9
* @author Sterling Hughes <sterling@php.net>
* @author Antônio Carlos Venâncio Júnior <floripa@php.net>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2007 The PHP Group
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.9.2
* @version Release: 1.7.6
* @link http://pear.php.net/package/DB
*/
class DB_sybase extends DB_common
141,13 → 141,13
// {{{ constructor
 
/**
* This constructor calls <kbd>parent::__construct()</kbd>
* This constructor calls <kbd>$this->DB_common()</kbd>
*
* @return void
*/
function __construct()
function DB_sybase()
{
parent::__construct();
$this->DB_common();
}
 
// }}}
248,9 → 248,9
*/
function simpleQuery($query)
{
$ismanip = $this->_checkManip($query);
$ismanip = DB::isManip($query);
$this->last_query = $query;
if ($this->_db && !@sybase_select_db($this->_db, $this->connection)) {
if (!@sybase_select_db($this->_db, $this->connection)) {
return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
}
$query = $this->modifyQuery($query);
370,7 → 370,7
*/
function freeResult($result)
{
return is_resource($result) ? sybase_free_result($result) : false;
return @sybase_free_result($result);
}
 
// }}}
435,7 → 435,7
*/
function affectedRows()
{
if ($this->_last_query_manip) {
if (DB::isManip($this->last_query)) {
$result = @sybase_affected_rows($this->connection);
} else {
$result = 0;
462,7 → 462,7
function nextId($seq_name, $ondemand = true)
{
$seqname = $this->getSequenceName($seq_name);
if ($this->_db && !@sybase_select_db($this->_db, $this->connection)) {
if (!@sybase_select_db($this->_db, $this->connection)) {
return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
}
$repeat = 0;
479,7 → 479,7
return $this->raiseError($result);
}
} elseif (!DB::isError($result)) {
$result = $this->query("SELECT @@IDENTITY FROM $seqname");
$result =& $this->query("SELECT @@IDENTITY FROM $seqname");
$repeat = 0;
} else {
$repeat = false;
529,22 → 529,6
}
 
// }}}
// {{{ quoteFloat()
 
/**
* Formats a float value for use within a query in a locale-independent
* manner.
*
* @param float the float value to be quoted.
* @return string the quoted string.
* @see DB_common::quoteSmart()
* @since Method available since release 1.7.8.
*/
function quoteFloat($float) {
return $this->escapeSimple(str_replace(',', '.', strval(floatval($float))));
}
// }}}
// {{{ autoCommit()
 
/**
574,7 → 558,7
function commit()
{
if ($this->transaction_opcount > 0) {
if ($this->_db && !@sybase_select_db($this->_db, $this->connection)) {
if (!@sybase_select_db($this->_db, $this->connection)) {
return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
}
$result = @sybase_query('COMMIT', $this->connection);
597,7 → 581,7
function rollback()
{
if ($this->transaction_opcount > 0) {
if ($this->_db && !@sybase_select_db($this->_db, $this->connection)) {
if (!@sybase_select_db($this->_db, $this->connection)) {
return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
}
$result = @sybase_query('ROLLBACK', $this->connection);
658,11 → 642,6
function errorCode($errormsg)
{
static $error_regexps;
// PHP 5.2+ prepends the function name to $php_errormsg, so we need
// this hack to work around it, per bug #9599.
$errormsg = preg_replace('/^sybase[a-z_]+\(\): /', '', $errormsg);
if (!isset($error_regexps)) {
$error_regexps = array(
'/Incorrect syntax near/'
695,8 → 674,6
=> DB_ERROR_ALREADY_EXISTS,
'/^There are fewer columns in the INSERT statement than values specified/i'
=> DB_ERROR_VALUE_COUNT_ON_ROW,
'/Divide by zero/i'
=> DB_ERROR_DIVZERO,
);
}
 
737,7 → 714,7
* Probably received a table name.
* Create a result resource identifier.
*/
if ($this->_db && !@sybase_select_db($this->_db, $this->connection)) {
if (!@sybase_select_db($this->_db, $this->connection)) {
return $this->sybaseRaiseError(DB_ERROR_NODBSELECTED);
}
$id = @sybase_query("SELECT * FROM $result WHERE 1=0",
834,24 → 811,14
$flags = array();
$tableName = $table;
 
/* We're running sp_helpindex directly because it doesn't exist in
* older versions of ASE -- unfortunately, we can't just use
* DB::isError() because the user may be using callback error
* handling. */
$res = @sybase_query("sp_helpindex $table", $this->connection);
// get unique/primary keys
$res = $this->getAll("sp_helpindex $table", DB_FETCHMODE_ASSOC);
 
if ($res === false || $res === true) {
// Fake a valid response for BC reasons.
if (!isset($res[0]['index_description'])) {
return '';
}
 
while (($val = sybase_fetch_assoc($res)) !== false) {
if (!isset($val['index_keys'])) {
/* No useful information returned. Break and be done with
* it, which preserves the pre-1.7.9 behaviour. */
break;
}
 
foreach ($res as $val) {
$keys = explode(', ', trim($val['index_keys']));
 
if (sizeof($keys) > 1) {
867,8 → 834,6
}
}
 
sybase_free_result($res);
 
}
 
if (array_key_exists($column, $flags)) {
/trunk/bibliotheque/pear/DB/pgsql.php
6,7 → 6,7
* The PEAR DB driver for PHP's pgsql extension
* for interacting with PostgreSQL databases
*
* PHP version 5
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
19,9 → 19,9
* @author Rui Hirokawa <hirokawa@php.net>
* @author Stig Bakken <ssb@php.net>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2007 The PHP Group
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$
* @version CVS: $Id: pgsql.php,v 1.126 2005/03/04 23:12:36 danielc Exp $
* @link http://pear.php.net/package/DB
*/
 
41,9 → 41,9
* @author Rui Hirokawa <hirokawa@php.net>
* @author Stig Bakken <ssb@php.net>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2007 The PHP Group
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.9.2
* @version Release: 1.7.6
* @link http://pear.php.net/package/DB
*/
class DB_pgsql extends DB_common
148,13 → 148,13
// {{{ constructor
 
/**
* This constructor calls <kbd>parent::__construct()</kbd>
* This constructor calls <kbd>$this->DB_common()</kbd>
*
* @return void
*/
function __construct()
function DB_pgsql()
{
parent::__construct();
$this->DB_common();
}
 
// }}}
193,7 → 193,7
* 'portability' => DB_PORTABILITY_ALL,
* );
*
* $db = DB::connect($dsn, $options);
* $db =& DB::connect($dsn, $options);
* if (PEAR::isError($db)) {
* die($db->getMessage());
* }
277,10 → 277,10
$this->connection = @call_user_func_array($connect_function,
$params);
} else {
@ini_set('track_errors', 1);
ini_set('track_errors', 1);
$this->connection = @call_user_func_array($connect_function,
$params);
@ini_set('track_errors', $ini);
ini_set('track_errors', $ini);
}
 
if (!$this->connection) {
320,7 → 320,7
*/
function simpleQuery($query)
{
$ismanip = $this->_checkManip($query);
$ismanip = DB::isManip($query);
$this->last_query = $query;
$query = $this->modifyQuery($query);
if (!$this->autocommit && $ismanip) {
336,26 → 336,19
if (!$result) {
return $this->pgsqlRaiseError();
}
 
/*
* Determine whether queries produce affected rows, result or nothing.
*
* This logic was introduced in version 1.1 of the file by ssb,
* though the regex has been modified slightly since then.
*
* PostgreSQL commands:
* ABORT, ALTER, BEGIN, CLOSE, CLUSTER, COMMIT, COPY,
* CREATE, DECLARE, DELETE, DROP TABLE, EXPLAIN, FETCH,
* GRANT, INSERT, LISTEN, LOAD, LOCK, MOVE, NOTIFY, RESET,
* REVOKE, ROLLBACK, SELECT, SELECT INTO, SET, SHOW,
* UNLISTEN, UPDATE, VACUUM, WITH
*/
// Determine which queries that should return data, and which
// should return an error code only.
if ($ismanip) {
$this->affected = @pg_affected_rows($result);
return DB_OK;
} elseif (preg_match('/^\s*\(*\s*(SELECT|EXPLAIN|FETCH|SHOW|WITH)\s/si',
$query))
{
} elseif (preg_match('/^\s*\(*\s*(SELECT|EXPLAIN|SHOW)\s/si', $query)) {
/* PostgreSQL commands:
ABORT, ALTER, BEGIN, CLOSE, CLUSTER, COMMIT, COPY,
CREATE, DECLARE, DELETE, DROP TABLE, EXPLAIN, FETCH,
GRANT, INSERT, LISTEN, LOAD, LOCK, MOVE, NOTIFY, RESET,
REVOKE, ROLLBACK, SELECT, SELECT INTO, SET, SHOW,
UNLISTEN, UPDATE, VACUUM
*/
$this->row[(int)$result] = 0; // reset the row counter.
$numrows = $this->numRows($result);
if (is_object($numrows)) {
466,21 → 459,50
}
 
// }}}
// {{{ quoteBoolean()
// {{{ quote()
 
/**
* Formats a boolean value for use within a query in a locale-independent
* manner.
* @deprecated Deprecated in release 1.6.0
* @internal
*/
function quote($str)
{
return $this->quoteSmart($str);
}
 
// }}}
// {{{ quoteSmart()
 
/**
* Formats input so it can be safely used in a query
*
* @param boolean the boolean value to be quoted.
* @return string the quoted string.
* @param mixed $in the data to be formatted
*
* @return mixed the formatted data. The format depends on the input's
* PHP type:
* + null = the string <samp>NULL</samp>
* + boolean = string <samp>TRUE</samp> or <samp>FALSE</samp>
* + integer or double = the unquoted number
* + other (including strings and numeric strings) =
* the data escaped according to MySQL's settings
* then encapsulated between single quotes
*
* @see DB_common::quoteSmart()
* @since Method available since release 1.7.8.
* @since Method available since Release 1.6.0
*/
function quoteBoolean($boolean) {
return $boolean ? 'TRUE' : 'FALSE';
function quoteSmart($in)
{
if (is_int($in) || is_double($in)) {
return $in;
} elseif (is_bool($in)) {
return $in ? 'TRUE' : 'FALSE';
} elseif (is_null($in)) {
return 'NULL';
} else {
return "'" . $this->escapeSimple($in) . "'";
}
}
 
// }}}
// {{{ escapeSimple()
 
490,6 → 512,9
* {@internal PostgreSQL treats a backslash as an escape character,
* so they are escaped as well.
*
* Not using pg_escape_string() yet because it requires PostgreSQL
* to be at version 7.2 or greater.}}
*
* @param string $str the string to be escaped
*
* @return string the escaped string
499,21 → 524,7
*/
function escapeSimple($str)
{
if (function_exists('pg_escape_string')) {
/* This fixes an undocumented BC break in PHP 5.2.0 which changed
* the prototype of pg_escape_string. I'm not thrilled about having
* to sniff the PHP version, quite frankly, but it's the only way
* to deal with the problem. Revision 1.331.2.13.2.10 on
* php-src/ext/pgsql/pgsql.c (PHP_5_2 branch) is to blame, for the
* record. */
if (version_compare(PHP_VERSION, '5.2.0', '>=')) {
return pg_escape_string($this->connection, $str);
} else {
return pg_escape_string($str);
}
} else {
return str_replace("'", "''", str_replace('\\', '\\\\', $str));
}
return str_replace("'", "''", str_replace('\\', '\\\\', $str));
}
 
// }}}
664,7 → 675,7
$repeat = false;
do {
$this->pushErrorHandling(PEAR_ERROR_RETURN);
$result = $this->query("SELECT NEXTVAL('${seqname}')");
$result =& $this->query("SELECT NEXTVAL('${seqname}')");
$this->popErrorHandling();
if ($ondemand && DB::isError($result) &&
$result->getCode() == DB_ERROR_NOSUCHTABLE) {
768,10 → 779,6
function pgsqlRaiseError($errno = null)
{
$native = $this->errorNative();
if (!$native) {
$native = 'Database connection has been lost.';
$errno = DB_ERROR_CONNECT_FAILED;
}
if ($errno === null) {
$errno = $this->errorCode($native);
}
808,12 → 815,12
static $error_regexps;
if (!isset($error_regexps)) {
$error_regexps = array(
'/column .* (of relation .*)?does not exist/i'
=> DB_ERROR_NOSUCHFIELD,
'/(relation|sequence|table).*does not exist|class .* not found/i'
=> DB_ERROR_NOSUCHTABLE,
'/index .* does not exist/'
=> DB_ERROR_NOT_FOUND,
'/column .* does not exist/i'
=> DB_ERROR_NOSUCHFIELD,
'/relation .* already exists/i'
=> DB_ERROR_ALREADY_EXISTS,
'/(divide|division) by zero$/i'
969,23 → 976,12
{
$field_name = @pg_fieldname($resource, $num_field);
 
// Check if there's a schema in $table_name and update things
// accordingly.
$from = 'pg_attribute f, pg_class tab, pg_type typ';
if (strpos($table_name, '.') !== false) {
$from .= ', pg_namespace nsp';
list($schema, $table) = explode('.', $table_name);
$tableWhere = "tab.relname = '$table' AND tab.relnamespace = nsp.oid AND nsp.nspname = '$schema'";
} else {
$tableWhere = "tab.relname = '$table_name'";
}
 
$result = @pg_exec($this->connection, "SELECT f.attnotnull, f.atthasdef
FROM $from
FROM pg_attribute f, pg_class tab, pg_type typ
WHERE tab.relname = typ.typname
AND typ.typrelid = f.attrelid
AND f.attname = '$field_name'
AND $tableWhere");
AND tab.relname = '$table_name'");
if (@pg_numrows($result) > 0) {
$row = @pg_fetch_row($result, 0);
$flags = ($row[0] == 't') ? 'not_null ' : '';
992,10 → 988,10
 
if ($row[1] == 't') {
$result = @pg_exec($this->connection, "SELECT a.adsrc
FROM $from, pg_attrdef a
FROM pg_attribute f, pg_class tab, pg_type typ, pg_attrdef a
WHERE tab.relname = typ.typname AND typ.typrelid = f.attrelid
AND f.attrelid = a.adrelid AND f.attname = '$field_name'
AND $tableWhere AND f.attnum = a.adnum");
AND tab.relname = '$table_name' AND f.attnum = a.adnum");
$row = @pg_fetch_row($result, 0);
$num = preg_replace("/'(.*)'::\w+/", "\\1", $row[0]);
$flags .= 'default_' . rawurlencode($num) . ' ';
1004,12 → 1000,12
$flags = '';
}
$result = @pg_exec($this->connection, "SELECT i.indisunique, i.indisprimary, i.indkey
FROM $from, pg_index i
FROM pg_attribute f, pg_class tab, pg_type typ, pg_index i
WHERE tab.relname = typ.typname
AND typ.typrelid = f.attrelid
AND f.attrelid = i.indrelid
AND f.attname = '$field_name'
AND $tableWhere");
AND tab.relname = '$table_name'");
$count = @pg_numrows($result);
 
for ($i = 0; $i < $count ; $i++) {
1070,9 → 1066,6
. ' FROM pg_catalog.pg_tables'
. ' WHERE schemaname NOT IN'
. " ('pg_catalog', 'information_schema', 'pg_toast')";
case 'schema.views':
return "SELECT schemaname || '.' || viewname from pg_views WHERE schemaname"
. " NOT IN ('information_schema', 'pg_catalog')";
case 'views':
// Table cols: viewname | viewowner | definition
return 'SELECT viewname from pg_views WHERE schemaname'
1091,26 → 1084,7
}
 
// }}}
// {{{ _checkManip()
 
/**
* Checks if the given query is a manipulation query. This also takes into
* account the _next_query_manip flag and sets the _last_query_manip flag
* (and resets _next_query_manip) according to the result.
*
* @param string The query to check.
*
* @return boolean true if the query is a manipulation query, false
* otherwise
*
* @access protected
*/
function _checkManip($query)
{
return (preg_match('/^\s*(SAVEPOINT|RELEASE)\s+/i', $query)
|| parent::_checkManip($query));
}
 
}
 
/*
/trunk/bibliotheque/pear/DB/ifx.php
6,7 → 6,7
* The PEAR DB driver for PHP's ifx extension
* for interacting with Informix databases
*
* PHP version 5
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
18,9 → 18,9
* @package DB
* @author Tomas V.V.Cox <cox@idecnet.com>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2007 The PHP Group
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$
* @version CVS: $Id: ifx.php,v 1.70 2005/02/20 00:44:48 danielc Exp $
* @link http://pear.php.net/package/DB
*/
 
46,9 → 46,9
* @package DB
* @author Tomas V.V.Cox <cox@idecnet.com>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2007 The PHP Group
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.9.2
* @version Release: 1.7.6
* @link http://pear.php.net/package/DB
*/
class DB_ifx extends DB_common
101,7 → 101,6
'-236' => DB_ERROR_VALUE_COUNT_ON_ROW,
'-239' => DB_ERROR_CONSTRAINT,
'-253' => DB_ERROR_SYNTAX,
'-268' => DB_ERROR_CONSTRAINT,
'-292' => DB_ERROR_CONSTRAINT_NOT_NULL,
'-310' => DB_ERROR_ALREADY_EXISTS,
'-316' => DB_ERROR_ALREADY_EXISTS,
114,7 → 113,6
'-691' => DB_ERROR_CONSTRAINT,
'-692' => DB_ERROR_CONSTRAINT,
'-703' => DB_ERROR_CONSTRAINT_NOT_NULL,
'-1202' => DB_ERROR_DIVZERO,
'-1204' => DB_ERROR_INVALID_DATE,
'-1205' => DB_ERROR_INVALID_DATE,
'-1206' => DB_ERROR_INVALID_DATE,
167,13 → 165,13
// {{{ constructor
 
/**
* This constructor calls <kbd>parent::__construct()</kbd>
* This constructor calls <kbd>$this->DB_common()</kbd>
*
* @return void
*/
function __construct()
function DB_ifx()
{
parent::__construct();
$this->DB_common();
}
 
// }}}
245,10 → 243,10
*/
function simpleQuery($query)
{
$ismanip = $this->_checkManip($query);
$ismanip = DB::isManip($query);
$this->last_query = $query;
$this->affected = null;
if (preg_match('/(SELECT|EXECUTE)/i', $query)) { //TESTME: Use !DB::isManip()?
if (preg_match('/(SELECT)/i', $query)) { //TESTME: Use !DB::isManip()?
// the scroll is needed for fetching absolute row numbers
// in a select query result
$result = @ifx_query($query, $this->connection, IFX_SCROLL);
270,7 → 268,7
$this->affected = @ifx_affected_rows($result);
// Determine which queries should return data, and which
// should return an error code only.
if (preg_match('/(SELECT|EXECUTE)/i', $query)) {
if (preg_match('/(SELECT)/i', $query)) {
return $result;
}
// XXX Testme: free results inside a transaction
311,7 → 309,7
*/
function affectedRows()
{
if ($this->_last_query_manip) {
if (DB::isManip($this->last_query)) {
return $this->affected;
} else {
return 0;
422,7 → 420,7
*/
function freeResult($result)
{
return is_resource($result) ? ifx_free_result($result) : false;
return @ifx_free_result($result);
}
 
// }}}
536,7 → 534,7
*/
function errorCode($nativecode)
{
if (preg_match('/SQLCODE=(.*)]/', $nativecode, $match)) {
if (ereg('SQLCODE=(.*)]', $nativecode, $match)) {
$code = $match[1];
if (isset($this->errorcode_map[$code])) {
return $this->errorcode_map[$code];
/trunk/bibliotheque/pear/DB/common.php
5,7 → 5,7
/**
* Contains the DB_common base class
*
* PHP version 5
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
18,9 → 18,9
* @author Stig Bakken <ssb@php.net>
* @author Tomas V.V. Cox <cox@idecnet.com>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2007 The PHP Group
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$
* @version CVS: $Id: common.php,v 1.137 2005/04/07 14:27:35 danielc Exp $
* @link http://pear.php.net/package/DB
*/
 
40,9 → 40,9
* @author Stig Bakken <ssb@php.net>
* @author Tomas V.V. Cox <cox@idecnet.com>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2007 The PHP Group
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.9.2
* @version Release: 1.7.6
* @link http://pear.php.net/package/DB
*/
class DB_common extends PEAR
121,22 → 121,7
*/
var $prepared_queries = array();
 
/**
* Flag indicating that the last query was a manipulation query.
* @access protected
* @var boolean
*/
var $_last_query_manip = false;
 
/**
* Flag indicating that the next query <em>must</em> be a manipulation
* query.
* @access protected
* @var boolean
*/
var $_next_query_manip = false;
 
 
// }}}
// {{{ DB_common
 
145,7 → 130,7
*
* @return void
*/
function __construct()
function DB_common()
{
$this->PEAR('DB_Error');
}
204,7 → 189,7
function __wakeup()
{
if ($this->was_connected) {
$this->connect($this->dsn, $this->options['persistent']);
$this->connect($this->dsn, $this->options);
}
}
 
261,7 → 246,7
*/
function quoteString($string)
{
$string = $this->quoteSmart($string);
$string = $this->quote($string);
if ($string{0} == "'") {
return substr($string, 1, -1);
}
284,7 → 269,8
*/
function quote($string = null)
{
return $this->quoteSmart($string);
return ($string === null) ? 'NULL'
: "'" . str_replace("'", "''", $string) . "'";
}
 
// }}}
438,57 → 424,18
*/
function quoteSmart($in)
{
if (is_int($in)) {
if (is_int($in) || is_double($in)) {
return $in;
} elseif (is_float($in)) {
return $this->quoteFloat($in);
} elseif (is_bool($in)) {
return $this->quoteBoolean($in);
return $in ? 1 : 0;
} elseif (is_null($in)) {
return 'NULL';
} else {
if ($this->dbsyntax == 'access'
&& preg_match('/^#.+#$/', $in))
{
return $this->escapeSimple($in);
}
return "'" . $this->escapeSimple($in) . "'";
}
}
 
// }}}
// {{{ quoteBoolean()
 
/**
* Formats a boolean value for use within a query in a locale-independent
* manner.
*
* @param boolean the boolean value to be quoted.
* @return string the quoted string.
* @see DB_common::quoteSmart()
* @since Method available since release 1.7.8.
*/
function quoteBoolean($boolean) {
return $boolean ? '1' : '0';
}
// }}}
// {{{ quoteFloat()
 
/**
* Formats a float value for use within a query in a locale-independent
* manner.
*
* @param float the float value to be quoted.
* @return string the quoted string.
* @see DB_common::quoteSmart()
* @since Method available since release 1.7.8.
*/
function quoteFloat($float) {
return "'".$this->escapeSimple(str_replace(',', '.', strval(floatval($float))))."'";
}
// }}}
// {{{ escapeSimple()
 
/**
890,7 → 837,7
if (DB::isError($sth)) {
return $sth;
}
$ret = $this->execute($sth, array_values($fields_values));
$ret =& $this->execute($sth, array_values($fields_values));
$this->freePrepared($sth);
return $ret;
 
984,7 → 931,7
* "'it''s good'",
* 'filename.txt'
* );
* $res = $db->execute($sth, $data);
* $res =& $db->execute($sth, $data);
* </code>
*
* @param resource $stmt a DB statement resource returned from prepare()
1013,7 → 960,7
if ($result === DB_OK || DB::isError($result)) {
return $result;
} else {
$tmp = new DB_result($this, $result);
$tmp =& new DB_result($this, $result);
return $tmp;
}
}
1094,7 → 1041,7
function executeMultiple($stmt, $data)
{
foreach ($data as $value) {
$res = $this->execute($stmt, $value);
$res =& $this->execute($stmt, $value);
if (DB::isError($res)) {
return $res;
}
1207,7 → 1154,7
if (DB::isError($sth)) {
return $sth;
}
$ret = $this->execute($sth, $params);
$ret =& $this->execute($sth, $params);
$this->freePrepared($sth, false);
return $ret;
} else {
1216,7 → 1163,7
if ($result === DB_OK || DB::isError($result)) {
return $result;
} else {
$tmp = new DB_result($this, $result);
$tmp =& new DB_result($this, $result);
return $tmp;
}
}
1247,8 → 1194,8
if (DB::isError($query)){
return $query;
}
$result = $this->query($query, $params);
if (is_object($result) && is_a($result, 'DB_result')) {
$result =& $this->query($query, $params);
if (is_a($result, 'DB_result')) {
$result->setOption('limit_from', $from);
$result->setOption('limit_count', $count);
}
1282,10 → 1229,10
if (DB::isError($sth)) {
return $sth;
}
$res = $this->execute($sth, $params);
$res =& $this->execute($sth, $params);
$this->freePrepared($sth);
} else {
$res = $this->query($query);
$res =& $this->query($query);
}
 
if (DB::isError($res)) {
1346,10 → 1293,10
if (DB::isError($sth)) {
return $sth;
}
$res = $this->execute($sth, $params);
$res =& $this->execute($sth, $params);
$this->freePrepared($sth);
} else {
$res = $this->query($query);
$res =& $this->query($query);
}
 
if (DB::isError($res)) {
1397,10 → 1344,10
return $sth;
}
 
$res = $this->execute($sth, $params);
$res =& $this->execute($sth, $params);
$this->freePrepared($sth);
} else {
$res = $this->query($query);
$res =& $this->query($query);
}
 
if (DB::isError($res)) {
1413,7 → 1360,7
$ret = array();
} else {
if (!array_key_exists($col, $row)) {
$ret = $this->raiseError(DB_ERROR_NOSUCHFIELD);
$ret =& $this->raiseError(DB_ERROR_NOSUCHFIELD);
} else {
$ret = array($row[$col]);
while (is_array($row = $res->fetchRow($fetchmode))) {
1529,10 → 1476,10
return $sth;
}
 
$res = $this->execute($sth, $params);
$res =& $this->execute($sth, $params);
$this->freePrepared($sth);
} else {
$res = $this->query($query);
$res =& $this->query($query);
}
 
if (DB::isError($res)) {
1544,7 → 1491,7
$cols = $res->numCols();
 
if ($cols < 2) {
$tmp = $this->raiseError(DB_ERROR_TRUNCATED);
$tmp =& $this->raiseError(DB_ERROR_TRUNCATED);
return $tmp;
}
 
1656,10 → 1603,10
return $sth;
}
 
$res = $this->execute($sth, $params);
$res =& $this->execute($sth, $params);
$this->freePrepared($sth);
} else {
$res = $this->query($query);
$res =& $this->query($query);
}
 
if ($res === DB_OK || DB::isError($res)) {
1680,7 → 1627,7
$res->free();
 
if (DB::isError($row)) {
$tmp = $this->raiseError($row);
$tmp =& $this->raiseError($row);
return $tmp;
}
return $results;
1867,10 → 1814,6
* query and native error code.
* @param mixed native error code, integer or string depending the
* backend
* @param mixed dummy parameter for E_STRICT compatibility with
* PEAR::raiseError
* @param mixed dummy parameter for E_STRICT compatibility with
* PEAR::raiseError
*
* @return object the PEAR_Error object
*
1877,8 → 1820,7
* @see PEAR_Error
*/
function &raiseError($code = DB_ERROR, $mode = null, $options = null,
$userinfo = null, $nativecode = null, $dummy1 = null,
$dummy2 = null)
$userinfo = null, $nativecode = null)
{
// The error is yet a DB error object
if (is_object($code)) {
2161,52 → 2103,6
}
 
// }}}
// {{{ nextQueryIsManip()
 
/**
* Sets (or unsets) a flag indicating that the next query will be a
* manipulation query, regardless of the usual DB::isManip() heuristics.
*
* @param boolean true to set the flag overriding the isManip() behaviour,
* false to clear it and fall back onto isManip()
*
* @return void
*
* @access public
*/
function nextQueryIsManip($manip)
{
$this->_next_query_manip = $manip;
}
 
// }}}
// {{{ _checkManip()
 
/**
* Checks if the given query is a manipulation query. This also takes into
* account the _next_query_manip flag and sets the _last_query_manip flag
* (and resets _next_query_manip) according to the result.
*
* @param string The query to check.
*
* @return boolean true if the query is a manipulation query, false
* otherwise
*
* @access protected
*/
function _checkManip($query)
{
if ($this->_next_query_manip || DB::isManip($query)) {
$this->_last_query_manip = true;
} else {
$this->_last_query_manip = false;
}
$this->_next_query_manip = false;
return $this->_last_query_manip;
$manip = $this->_next_query_manip;
}
 
// }}}
// {{{ _rtrimArrayValues()
 
/**
/trunk/bibliotheque/pear/PEAR/Common.php
4,13 → 4,20
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Common.php,v 1.157 2006/05/12 02:38:58 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1.0
* @deprecated File deprecated since Release 1.4.0a1
21,37 → 28,39
*/
require_once 'PEAR.php';
 
// {{{ constants and globals
 
/**
* PEAR_Common error when an invalid PHP file is passed to PEAR_Common::analyzeSourceCode()
*/
define('PEAR_COMMON_ERROR_INVALIDPHP', 1);
define('_PEAR_COMMON_PACKAGE_NAME_PREG', '[A-Za-z][a-zA-Z0-9_]+');
define('PEAR_COMMON_PACKAGE_NAME_PREG', '/^' . _PEAR_COMMON_PACKAGE_NAME_PREG . '\\z/');
define('PEAR_COMMON_PACKAGE_NAME_PREG', '/^' . _PEAR_COMMON_PACKAGE_NAME_PREG . '$/');
 
// this should allow: 1, 1.0, 1.0RC1, 1.0dev, 1.0dev123234234234, 1.0a1, 1.0b1, 1.0pl1
define('_PEAR_COMMON_PACKAGE_VERSION_PREG', '\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?');
define('PEAR_COMMON_PACKAGE_VERSION_PREG', '/^' . _PEAR_COMMON_PACKAGE_VERSION_PREG . '\\z/i');
define('PEAR_COMMON_PACKAGE_VERSION_PREG', '/^' . _PEAR_COMMON_PACKAGE_VERSION_PREG . '$/i');
 
// XXX far from perfect :-)
define('_PEAR_COMMON_PACKAGE_DOWNLOAD_PREG', '(' . _PEAR_COMMON_PACKAGE_NAME_PREG .
')(-([.0-9a-zA-Z]+))?');
define('PEAR_COMMON_PACKAGE_DOWNLOAD_PREG', '/^' . _PEAR_COMMON_PACKAGE_DOWNLOAD_PREG .
'\\z/');
'$/');
 
define('_PEAR_CHANNELS_NAME_PREG', '[A-Za-z][a-zA-Z0-9\.]+');
define('PEAR_CHANNELS_NAME_PREG', '/^' . _PEAR_CHANNELS_NAME_PREG . '\\z/');
define('PEAR_CHANNELS_NAME_PREG', '/^' . _PEAR_CHANNELS_NAME_PREG . '$/');
 
// this should allow any dns or IP address, plus a path - NO UNDERSCORES ALLOWED
define('_PEAR_CHANNELS_SERVER_PREG', '[a-zA-Z0-9\-]+(?:\.[a-zA-Z0-9\-]+)*(\/[a-zA-Z0-9\-]+)*');
define('PEAR_CHANNELS_SERVER_PREG', '/^' . _PEAR_CHANNELS_SERVER_PREG . '\\z/i');
define('PEAR_CHANNELS_SERVER_PREG', '/^' . _PEAR_CHANNELS_SERVER_PREG . '$/i');
 
define('_PEAR_CHANNELS_PACKAGE_PREG', '(' ._PEAR_CHANNELS_SERVER_PREG . ')\/('
. _PEAR_COMMON_PACKAGE_NAME_PREG . ')');
define('PEAR_CHANNELS_PACKAGE_PREG', '/^' . _PEAR_CHANNELS_PACKAGE_PREG . '\\z/i');
define('PEAR_CHANNELS_PACKAGE_PREG', '/^' . _PEAR_CHANNELS_PACKAGE_PREG . '$/i');
 
define('_PEAR_COMMON_CHANNEL_DOWNLOAD_PREG', '(' . _PEAR_CHANNELS_NAME_PREG . ')::('
. _PEAR_COMMON_PACKAGE_NAME_PREG . ')(-([.0-9a-zA-Z]+))?');
define('PEAR_COMMON_CHANNEL_DOWNLOAD_PREG', '/^' . _PEAR_COMMON_CHANNEL_DOWNLOAD_PREG . '\\z/');
define('PEAR_COMMON_CHANNEL_DOWNLOAD_PREG', '/^' . _PEAR_COMMON_CHANNEL_DOWNLOAD_PREG . '$/');
 
/**
* List of temporary files and directories registered by
108,6 → 117,8
*/
$GLOBALS['_PEAR_Common_script_phases'] = array('pre-install', 'post-install', 'pre-uninstall', 'post-uninstall', 'pre-build', 'post-build', 'pre-configure', 'post-configure', 'pre-setup', 'post-setup');
 
// }}}
 
/**
* Class providing common functionality for PEAR administration classes.
* @category pear
115,9 → 126,9
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
* @deprecated This class will disappear, and its components will be spread
125,19 → 136,8
*/
class PEAR_Common extends PEAR
{
/**
* User Interface object (PEAR_Frontend_* class). If null,
* the log() method uses print.
* @var object
*/
var $ui = null;
// {{{ properties
 
/**
* Configuration object (PEAR_Config).
* @var PEAR_Config
*/
var $config = null;
 
/** stack of elements, gives some sort of XML context */
var $element_stack = array();
 
150,9 → 150,27
/** assoc with information about a package */
var $pkginfo = array();
 
/**
* User Interface object (PEAR_Frontend_* class). If null,
* the log() method uses print.
* @var object
*/
var $ui = null;
 
/**
* Configuration object (PEAR_Config).
* @var object
*/
var $config = null;
 
var $current_path = null;
 
/**
* PEAR_SourceAnalyzer instance
* @var object
*/
var $source_analyzer = null;
/**
* Flag variable used to mark a valid package file
* @var boolean
* @access private
159,18 → 177,25
*/
var $_validPackageFile;
 
// }}}
 
// {{{ constructor
 
/**
* PEAR_Common constructor
*
* @access public
*/
function __construct()
function PEAR_Common()
{
parent::__construct();
parent::PEAR();
$this->config = &PEAR_Config::singleton();
$this->debug = $this->config->get('verbose');
}
 
// }}}
// {{{ destructor
 
/**
* PEAR_Common destructor
*
186,7 → 211,6
if (!class_exists('System')) {
require_once 'System.php';
}
 
System::rm(array('-rf', $file));
} elseif (file_exists($file)) {
unlink($file);
194,6 → 218,9
}
}
 
// }}}
// {{{ addTempFile()
 
/**
* Register a temporary file or directory. When the destructor is
* executed, all registered temporary files and directories are
213,6 → 240,9
PEAR_Frontend::addTempFile($file);
}
 
// }}}
// {{{ mkDirHier()
 
/**
* Wrapper to System::mkDir(), creates a directory as well as
* any necessary parent directories.
225,7 → 255,6
*/
function mkDirHier($dir)
{
// Only used in Installer - move it there ?
$this->log(2, "+ create dir $dir");
if (!class_exists('System')) {
require_once 'System.php';
233,6 → 262,9
return System::mkDir(array('-p', $dir));
}
 
// }}}
// {{{ log()
 
/**
* Logging method.
*
240,14 → 272,16
* @param string $msg message to write to the log
*
* @return void
*
* @access public
* @static
*/
public function log($level, $msg, $append_crlf = true)
function log($level, $msg, $append_crlf = true)
{
if ($this->debug >= $level) {
if (!class_exists('PEAR_Frontend')) {
require_once 'PEAR/Frontend.php';
}
 
$ui = &PEAR_Frontend::singleton();
if (is_a($ui, 'PEAR_Frontend')) {
$ui->log($msg, $append_crlf);
257,6 → 291,9
}
}
 
// }}}
// {{{ mkTempDir()
 
/**
* Create and register a temporary directory.
*
270,20 → 307,25
*/
function mkTempDir($tmpdir = '')
{
$topt = $tmpdir ? array('-t', $tmpdir) : array();
if ($tmpdir) {
$topt = array('-t', $tmpdir);
} else {
$topt = array();
}
$topt = array_merge($topt, array('-d', 'pear'));
if (!class_exists('System')) {
require_once 'System.php';
}
 
if (!$tmpdir = System::mktemp($topt)) {
return false;
}
 
$this->addTempFile($tmpdir);
return $tmpdir;
}
 
// }}}
// {{{ setFrontendObject()
 
/**
* Set object that represents the frontend to be used.
*
296,173 → 338,11
$this->ui = &$ui;
}
 
/**
* 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);
}
// }}}
 
/**
* Get the valid roles for a PEAR package maintainer
*
* @return array
*/
public static function getUserRoles()
{
return $GLOBALS['_PEAR_Common_maintainer_roles'];
}
// {{{ infoFromTgzFile()
 
/**
* Get the valid package release states of packages
*
* @return array
*/
public static function getReleaseStates()
{
return $GLOBALS['_PEAR_Common_release_states'];
}
 
/**
* Get the implemented dependency types (php, ext, pkg etc.)
*
* @return array
*/
public static function getDependencyTypes()
{
return $GLOBALS['_PEAR_Common_dependency_types'];
}
 
/**
* Get the implemented dependency relations (has, lt, ge etc.)
*
* @return array
*/
public static function getDependencyRelations()
{
return $GLOBALS['_PEAR_Common_dependency_relations'];
}
 
/**
* Get the implemented file roles
*
* @return array
*/
public static function getFileRoles()
{
return $GLOBALS['_PEAR_Common_file_roles'];
}
 
/**
* Get the implemented file replacement types in
*
* @return array
*/
public static function getReplacementTypes()
{
return $GLOBALS['_PEAR_Common_replacement_types'];
}
 
/**
* Get the implemented file replacement types in
*
* @return array
*/
public static function getProvideTypes()
{
return $GLOBALS['_PEAR_Common_provide_types'];
}
 
/**
* Get the implemented file replacement types in
*
* @return array
*/
public static function getScriptPhases()
{
return $GLOBALS['_PEAR_Common_script_phases'];
}
 
/**
* Test whether a string contains a valid package name.
*
* @param string $name the package name to test
*
* @return bool
*
* @access public
*/
function validPackageName($name)
{
return (bool)preg_match(PEAR_COMMON_PACKAGE_NAME_PREG, $name);
}
 
/**
* Test whether a string contains a valid package version.
*
* @param string $ver the package version to test
*
* @return bool
*
* @access public
*/
function validPackageVersion($ver)
{
return (bool)preg_match(PEAR_COMMON_PACKAGE_VERSION_PREG, $ver);
}
 
/**
* @param string $path relative or absolute include path
* @return boolean
*/
public 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;
}
 
function _postProcessChecks($pf)
{
if (!PEAR::isError($pf)) {
return $this->_postProcessValidPackagexml($pf);
}
 
$errs = $pf->getUserinfo();
if (is_array($errs)) {
foreach ($errs as $error) {
$e = $this->raiseError($error['message'], $error['code'], null, null, $error);
}
}
 
return $pf;
}
 
/**
* Returns information about a package file. Expects the name of
* a gzipped tar file as input.
*
476,11 → 356,23
*/
function infoFromTgzFile($file)
{
$packagefile = new PEAR_PackageFile($this->config);
$packagefile = &new PEAR_PackageFile($this->config);
$pf = &$packagefile->fromTgzFile($file, PEAR_VALIDATE_NORMAL);
return $this->_postProcessChecks($pf);
if (PEAR::isError($pf)) {
$errs = $pf->getUserinfo();
if (is_array($errs)) {
foreach ($errs as $error) {
$e = $this->raiseError($error['message'], $error['code'], null, null, $error);
}
}
return $pf;
}
return $this->_postProcessValidPackagexml($pf);
}
 
// }}}
// {{{ infoFromDescriptionFile()
 
/**
* Returns information about a package file. Expects the name of
* a package xml file as input.
495,11 → 387,23
*/
function infoFromDescriptionFile($descfile)
{
$packagefile = new PEAR_PackageFile($this->config);
$packagefile = &new PEAR_PackageFile($this->config);
$pf = &$packagefile->fromPackageFile($descfile, PEAR_VALIDATE_NORMAL);
return $this->_postProcessChecks($pf);
if (PEAR::isError($pf)) {
$errs = $pf->getUserinfo();
if (is_array($errs)) {
foreach ($errs as $error) {
$e = $this->raiseError($error['message'], $error['code'], null, null, $error);
}
}
return $pf;
}
return $this->_postProcessValidPackagexml($pf);
}
 
// }}}
// {{{ infoFromString()
 
/**
* Returns information about a package file. Expects the contents
* of a package xml file as input.
514,10 → 418,20
*/
function infoFromString($data)
{
$packagefile = new PEAR_PackageFile($this->config);
$packagefile = &new PEAR_PackageFile($this->config);
$pf = &$packagefile->fromXmlString($data, PEAR_VALIDATE_NORMAL, false);
return $this->_postProcessChecks($pf);
if (PEAR::isError($pf)) {
$errs = $pf->getUserinfo();
if (is_array($errs)) {
foreach ($errs as $error) {
$e = $this->raiseError($error['message'], $error['code'], null, null, $error);
}
}
return $pf;
}
return $this->_postProcessValidPackagexml($pf);
}
// }}}
 
/**
* @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
525,24 → 439,37
*/
function _postProcessValidPackagexml(&$pf)
{
if (!is_a($pf, 'PEAR_PackageFile_v2')) {
if (is_a($pf, 'PEAR_PackageFile_v2')) {
// sort of make this into a package.xml 1.0-style array
// changelog is not converted to old format.
$arr = $pf->toArray(true);
$arr = array_merge($arr, $arr['old']);
unset($arr['old']);
unset($arr['xsdversion']);
unset($arr['contents']);
unset($arr['compatible']);
unset($arr['channel']);
unset($arr['uri']);
unset($arr['dependencies']);
unset($arr['phprelease']);
unset($arr['extsrcrelease']);
unset($arr['zendextsrcrelease']);
unset($arr['extbinrelease']);
unset($arr['zendextbinrelease']);
unset($arr['bundle']);
unset($arr['lead']);
unset($arr['developer']);
unset($arr['helper']);
unset($arr['contributor']);
$arr['filelist'] = $pf->getFilelist();
$this->pkginfo = $arr;
return $arr;
} else {
$this->pkginfo = $pf->toArray();
return $this->pkginfo;
}
 
// sort of make this into a package.xml 1.0-style array
// changelog is not converted to old format.
$arr = $pf->toArray(true);
$arr = array_merge($arr, $arr['old']);
unset($arr['old'], $arr['xsdversion'], $arr['contents'], $arr['compatible'],
$arr['channel'], $arr['uri'], $arr['dependencies'], $arr['phprelease'],
$arr['extsrcrelease'], $arr['zendextsrcrelease'], $arr['extbinrelease'],
$arr['zendextbinrelease'], $arr['bundle'], $arr['lead'], $arr['developer'],
$arr['helper'], $arr['contributor']);
$arr['filelist'] = $pf->getFilelist();
$this->pkginfo = $arr;
return $arr;
}
// {{{ infoFromAny()
 
/**
* Returns package information from different sources
558,7 → 485,7
function infoFromAny($info)
{
if (is_string($info) && file_exists($info)) {
$packagefile = new PEAR_PackageFile($this->config);
$packagefile = &new PEAR_PackageFile($this->config);
$pf = &$packagefile->fromAnyFile($info, PEAR_VALIDATE_NORMAL);
if (PEAR::isError($pf)) {
$errs = $pf->getUserinfo();
567,16 → 494,16
$e = $this->raiseError($error['message'], $error['code'], null, null, $error);
}
}
 
return $pf;
}
 
return $this->_postProcessValidPackagexml($pf);
}
 
return $info;
}
 
// }}}
// {{{ xmlFromInfo()
 
/**
* Return an XML document based on the package info (as returned
* by the PEAR_Common::infoFrom* methods).
590,13 → 517,16
*/
function xmlFromInfo($pkginfo)
{
$config = &PEAR_Config::singleton();
$packagefile = new PEAR_PackageFile($config);
$config = &PEAR_Config::singleton();
$packagefile = &new PEAR_PackageFile($config);
$pf = &$packagefile->fromArray($pkginfo);
$gen = &$pf->getDefaultGenerator();
return $gen->toXml(PEAR_VALIDATE_PACKAGING);
}
 
// }}}
// {{{ validatePackageInfo()
 
/**
* Validate XML package definition file.
*
612,8 → 542,8
*/
function validatePackageInfo($info, &$errors, &$warnings, $dir_prefix = '')
{
$config = &PEAR_Config::singleton();
$packagefile = new PEAR_PackageFile($config);
$config = &PEAR_Config::singleton();
$packagefile = &new PEAR_PackageFile($config);
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
if (strpos($info, '<?xml') !== false) {
$pf = &$packagefile->fromXmlString($info, PEAR_VALIDATE_NORMAL, '');
620,7 → 550,6
} else {
$pf = &$packagefile->fromAnyFile($info, PEAR_VALIDATE_NORMAL);
}
 
PEAR::staticPopErrorHandling();
if (PEAR::isError($pf)) {
$errs = $pf->getUserinfo();
633,13 → 562,14
}
}
}
 
return false;
}
 
return true;
}
 
// }}}
// {{{ buildProvidesArray()
 
/**
* Build a "provides" array from data returned by
* analyzeSourceCode(). The format of the built array is like
666,7 → 596,6
if (isset($this->_packageName)) {
$pn = $this->_packageName;
}
 
$pnl = strlen($pn);
foreach ($srcinfo['declared_classes'] as $class) {
$key = "class;$class";
673,7 → 602,6
if (isset($this->pkginfo['provides'][$key])) {
continue;
}
 
$this->pkginfo['provides'][$key] =
array('file'=> $file, 'type' => 'class', 'name' => $class);
if (isset($srcinfo['inheritance'][$class])) {
681,7 → 609,6
$srcinfo['inheritance'][$class];
}
}
 
foreach ($srcinfo['declared_methods'] as $class => $methods) {
foreach ($methods as $method) {
$function = "$class::$method";
690,7 → 617,6
isset($this->pkginfo['provides'][$key])) {
continue;
}
 
$this->pkginfo['provides'][$key] =
array('file'=> $file, 'type' => 'function', 'name' => $function);
}
701,16 → 627,17
if ($function{0} == '_' || isset($this->pkginfo['provides'][$key])) {
continue;
}
 
if (!strstr($function, '::') && strncasecmp($function, $pn, $pnl)) {
$warnings[] = "in1 " . $file . ": function \"$function\" not prefixed with package name \"$pn\"";
}
 
$this->pkginfo['provides'][$key] =
array('file'=> $file, 'type' => 'function', 'name' => $function);
}
}
 
// }}}
// {{{ analyzeSourceCode()
 
/**
* Analyze the source code of the given PHP file
*
720,28 → 647,231
*/
function analyzeSourceCode($file)
{
if (!class_exists('PEAR_PackageFile_v2_Validator')) {
require_once 'PEAR/PackageFile/v2/Validator.php';
if (!function_exists("token_get_all")) {
return false;
}
if (!defined('T_DOC_COMMENT')) {
define('T_DOC_COMMENT', T_COMMENT);
}
if (!defined('T_INTERFACE')) {
define('T_INTERFACE', -1);
}
if (!defined('T_IMPLEMENTS')) {
define('T_IMPLEMENTS', -1);
}
if (!$fp = @fopen($file, "r")) {
return false;
}
fclose($fp);
$contents = file_get_contents($file);
$tokens = token_get_all($contents);
/*
for ($i = 0; $i < sizeof($tokens); $i++) {
@list($token, $data) = $tokens[$i];
if (is_string($token)) {
var_dump($token);
} else {
print token_name($token) . ' ';
var_dump(rtrim($data));
}
}
*/
$look_for = 0;
$paren_level = 0;
$bracket_level = 0;
$brace_level = 0;
$lastphpdoc = '';
$current_class = '';
$current_interface = '';
$current_class_level = -1;
$current_function = '';
$current_function_level = -1;
$declared_classes = array();
$declared_interfaces = array();
$declared_functions = array();
$declared_methods = array();
$used_classes = array();
$used_functions = array();
$extends = array();
$implements = array();
$nodeps = array();
$inquote = false;
$interface = false;
for ($i = 0; $i < sizeof($tokens); $i++) {
if (is_array($tokens[$i])) {
list($token, $data) = $tokens[$i];
} else {
$token = $tokens[$i];
$data = '';
}
if ($inquote) {
if ($token != '"') {
continue;
} else {
$inquote = false;
continue;
}
}
switch ($token) {
case T_WHITESPACE:
continue;
case ';':
if ($interface) {
$current_function = '';
$current_function_level = -1;
}
break;
case '"':
$inquote = true;
break;
case T_CURLY_OPEN:
case T_DOLLAR_OPEN_CURLY_BRACES:
case '{': $brace_level++; continue 2;
case '}':
$brace_level--;
if ($current_class_level == $brace_level) {
$current_class = '';
$current_class_level = -1;
}
if ($current_function_level == $brace_level) {
$current_function = '';
$current_function_level = -1;
}
continue 2;
case '[': $bracket_level++; continue 2;
case ']': $bracket_level--; continue 2;
case '(': $paren_level++; continue 2;
case ')': $paren_level--; continue 2;
case T_INTERFACE:
$interface = true;
case T_CLASS:
if (($current_class_level != -1) || ($current_function_level != -1)) {
PEAR::raiseError("Parser error: invalid PHP found in file \"$file\"",
PEAR_COMMON_ERROR_INVALIDPHP);
return false;
}
case T_FUNCTION:
case T_NEW:
case T_EXTENDS:
case T_IMPLEMENTS:
$look_for = $token;
continue 2;
case T_STRING:
if (version_compare(zend_version(), '2.0', '<')) {
if (in_array(strtolower($data),
array('public', 'private', 'protected', 'abstract',
'interface', 'implements', 'throw')
)) {
PEAR::raiseError('Error: PHP5 token encountered in ' . $file .
'packaging should be done in PHP 5');
return false;
}
}
if ($look_for == T_CLASS) {
$current_class = $data;
$current_class_level = $brace_level;
$declared_classes[] = $current_class;
} elseif ($look_for == T_INTERFACE) {
$current_interface = $data;
$current_class_level = $brace_level;
$declared_interfaces[] = $current_interface;
} elseif ($look_for == T_IMPLEMENTS) {
$implements[$current_class] = $data;
} elseif ($look_for == T_EXTENDS) {
$extends[$current_class] = $data;
} elseif ($look_for == T_FUNCTION) {
if ($current_class) {
$current_function = "$current_class::$data";
$declared_methods[$current_class][] = $data;
} elseif ($current_interface) {
$current_function = "$current_interface::$data";
$declared_methods[$current_interface][] = $data;
} else {
$current_function = $data;
$declared_functions[] = $current_function;
}
$current_function_level = $brace_level;
$m = array();
} elseif ($look_for == T_NEW) {
$used_classes[$data] = true;
}
$look_for = 0;
continue 2;
case T_VARIABLE:
$look_for = 0;
continue 2;
case T_DOC_COMMENT:
case T_COMMENT:
if (preg_match('!^/\*\*\s!', $data)) {
$lastphpdoc = $data;
if (preg_match_all('/@nodep\s+(\S+)/', $lastphpdoc, $m)) {
$nodeps = array_merge($nodeps, $m[1]);
}
}
continue 2;
case T_DOUBLE_COLON:
if (!($tokens[$i - 1][0] == T_WHITESPACE || $tokens[$i - 1][0] == T_STRING)) {
PEAR::raiseError("Parser error: invalid PHP found in file \"$file\"",
PEAR_COMMON_ERROR_INVALIDPHP);
return false;
}
$class = $tokens[$i - 1][1];
if (strtolower($class) != 'parent') {
$used_classes[$class] = true;
}
continue 2;
}
}
return array(
"source_file" => $file,
"declared_classes" => $declared_classes,
"declared_interfaces" => $declared_interfaces,
"declared_methods" => $declared_methods,
"declared_functions" => $declared_functions,
"used_classes" => array_diff(array_keys($used_classes), $nodeps),
"inheritance" => $extends,
"implements" => $implements,
);
}
 
$a = new PEAR_PackageFile_v2_Validator;
return $a->analyzeSourceCode($file);
// }}}
// {{{ betterStates()
 
/**
* 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);
}
 
// }}}
// {{{ detectDependencies()
 
function detectDependencies($any, $status_callback = null)
{
if (!function_exists("token_get_all")) {
return false;
}
 
if (PEAR::isError($info = $this->infoFromAny($any))) {
return $this->raiseError($info);
}
 
if (!is_array($info)) {
return false;
}
 
$deps = array();
$used_c = $decl_c = $decl_f = $decl_m = array();
foreach ($info['filelist'] as $file => $fa) {
752,11 → 882,9
$decl_m = @array_merge($decl_m, $tmp['declared_methods']);
$inheri = @array_merge($inheri, $tmp['inheritance']);
}
 
$used_c = array_unique($used_c);
$decl_c = array_unique($decl_c);
$undecl_c = array_diff($used_c, $decl_c);
 
return array('used_classes' => $used_c,
'declared_classes' => $decl_c,
'declared_methods' => $decl_m,
766,7 → 894,159
);
}
 
// }}}
// {{{ getUserRoles()
 
/**
* Get the valid roles for a PEAR package maintainer
*
* @return array
* @static
*/
function getUserRoles()
{
return $GLOBALS['_PEAR_Common_maintainer_roles'];
}
 
// }}}
// {{{ getReleaseStates()
 
/**
* Get the valid package release states of packages
*
* @return array
* @static
*/
function getReleaseStates()
{
return $GLOBALS['_PEAR_Common_release_states'];
}
 
// }}}
// {{{ getDependencyTypes()
 
/**
* Get the implemented dependency types (php, ext, pkg etc.)
*
* @return array
* @static
*/
function getDependencyTypes()
{
return $GLOBALS['_PEAR_Common_dependency_types'];
}
 
// }}}
// {{{ getDependencyRelations()
 
/**
* Get the implemented dependency relations (has, lt, ge etc.)
*
* @return array
* @static
*/
function getDependencyRelations()
{
return $GLOBALS['_PEAR_Common_dependency_relations'];
}
 
// }}}
// {{{ getFileRoles()
 
/**
* Get the implemented file roles
*
* @return array
* @static
*/
function getFileRoles()
{
return $GLOBALS['_PEAR_Common_file_roles'];
}
 
// }}}
// {{{ getReplacementTypes()
 
/**
* Get the implemented file replacement types in
*
* @return array
* @static
*/
function getReplacementTypes()
{
return $GLOBALS['_PEAR_Common_replacement_types'];
}
 
// }}}
// {{{ getProvideTypes()
 
/**
* Get the implemented file replacement types in
*
* @return array
* @static
*/
function getProvideTypes()
{
return $GLOBALS['_PEAR_Common_provide_types'];
}
 
// }}}
// {{{ getScriptPhases()
 
/**
* Get the implemented file replacement types in
*
* @return array
* @static
*/
function getScriptPhases()
{
return $GLOBALS['_PEAR_Common_script_phases'];
}
 
// }}}
// {{{ validPackageName()
 
/**
* Test whether a string contains a valid package name.
*
* @param string $name the package name to test
*
* @return bool
*
* @access public
*/
function validPackageName($name)
{
return (bool)preg_match(PEAR_COMMON_PACKAGE_NAME_PREG, $name);
}
 
 
// }}}
// {{{ validPackageVersion()
 
/**
* Test whether a string contains a valid package version.
*
* @param string $ver the package version to test
*
* @return bool
*
* @access public
*/
function validPackageVersion($ver)
{
return (bool)preg_match(PEAR_COMMON_PACKAGE_VERSION_PREG, $ver);
}
 
 
// }}}
 
// {{{ downloadHttp()
 
/**
* Download a file through HTTP. Considers suggested file name in
* Content-disposition: header and can run a callback function for
* different events. The callback will be called with two
801,38 → 1081,46
* @param string $save_dir (optional) directory to save file in
* @param mixed $callback (optional) function/method to call for status
* updates
* @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
* @param false|string $channel Channel to use for retrieving
* authentication
*
* @return mixed Returns the full path 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.
* If $lastmodified was given and the there are no changes,
* boolean false is returned.
* @return string Returns the full path 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().
*
* @access public
* @deprecated in favor of PEAR_Downloader::downloadHttp()
*/
function downloadHttp(
$url, &$ui, $save_dir = '.', $callback = null, $lastmodified = null,
$accept = false, $channel = false
) {
function downloadHttp($url, &$ui, $save_dir = '.', $callback = null)
{
if (!class_exists('PEAR_Downloader')) {
require_once 'PEAR/Downloader.php';
}
return PEAR_Downloader::_downloadHttp(
$this, $url, $ui, $save_dir, $callback, $lastmodified,
$accept, $channel
);
return PEAR_Downloader::downloadHttp($url, $ui, $save_dir, $callback);
}
 
// }}}
 
/**
* @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;
}
}
 
require_once 'PEAR/Config.php';
require_once 'PEAR/PackageFile.php';
?>
/trunk/bibliotheque/pear/PEAR/Remote.php
New file
0,0 → 1,498
<?php
/**
* PEAR_Remote
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Remote.php,v 1.79 2006/03/27 04:33:11 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
 
/**
* needed for PEAR_Error
*/
require_once 'PEAR.php';
require_once 'PEAR/Config.php';
 
/**
* This is a class for doing remote operations against the central
* PEAR database.
*
* @nodep XML_RPC_Value
* @nodep XML_RPC_Message
* @nodep XML_RPC_Client
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
class PEAR_Remote extends PEAR
{
// {{{ properties
 
var $config = null;
var $cache = null;
/**
* @var PEAR_Registry
* @access private
*/
var $_registry;
 
// }}}
 
// {{{ PEAR_Remote(config_object)
 
function PEAR_Remote(&$config)
{
$this->PEAR();
$this->config = &$config;
$this->_registry = &$this->config->getRegistry();
}
 
// }}}
// {{{ setRegistry()
function setRegistry(&$reg)
{
$this->_registry = &$reg;
}
// }}}
// {{{ getCache()
 
 
function getCache($args)
{
$id = md5(serialize($args));
$cachedir = $this->config->get('cache_dir');
$filename = $cachedir . DIRECTORY_SEPARATOR . 'xmlrpc_cache_' . $id;
if (!file_exists($filename)) {
return null;
}
 
$fp = fopen($filename, 'rb');
if (!$fp) {
return null;
}
fclose($fp);
$content = file_get_contents($filename);
$result = array(
'age' => time() - filemtime($filename),
'lastChange' => filemtime($filename),
'content' => unserialize($content),
);
return $result;
}
 
// }}}
 
// {{{ saveCache()
 
function saveCache($args, $data)
{
$id = md5(serialize($args));
$cachedir = $this->config->get('cache_dir');
if (!file_exists($cachedir)) {
System::mkdir(array('-p', $cachedir));
}
$filename = $cachedir.'/xmlrpc_cache_'.$id;
 
$fp = @fopen($filename, "wb");
if ($fp) {
fwrite($fp, serialize($data));
fclose($fp);
}
}
 
// }}}
 
// {{{ clearCache()
 
function clearCache($method, $args)
{
array_unshift($args, $method);
array_unshift($args, $this->config->get('default_channel')); // cache by channel
$id = md5(serialize($args));
$cachedir = $this->config->get('cache_dir');
$filename = $cachedir.'/xmlrpc_cache_'.$id;
if (file_exists($filename)) {
@unlink($filename);
}
}
 
// }}}
// {{{ call(method, [args...])
 
function call($method)
{
$_args = $args = func_get_args();
 
$server_channel = $this->config->get('default_channel');
$channel = $this->_registry->getChannel($server_channel);
if (!PEAR::isError($channel)) {
$mirror = $this->config->get('preferred_mirror');
if ($channel->getMirror($mirror)) {
if ($channel->supports('xmlrpc', $method, $mirror)) {
$server_channel = $server_host = $mirror; // use the preferred mirror
$server_port = $channel->getPort($mirror);
} elseif (!$channel->supports('xmlrpc', $method)) {
return $this->raiseError("Channel $server_channel does not " .
"support xml-rpc method $method");
}
}
if (!isset($server_host)) {
if (!$channel->supports('xmlrpc', $method)) {
return $this->raiseError("Channel $server_channel does not support " .
"xml-rpc method $method");
} else {
$server_host = $server_channel;
$server_port = $channel->getPort();
}
}
} else {
return $this->raiseError("Unknown channel '$server_channel'");
}
 
array_unshift($_args, $server_channel); // cache by channel
$this->cache = $this->getCache($_args);
$cachettl = $this->config->get('cache_ttl');
// If cache is newer than $cachettl seconds, we use the cache!
if ($this->cache !== null && $this->cache['age'] < $cachettl) {
return $this->cache['content'];
}
$fp = false;
if (extension_loaded("xmlrpc")) {
$result = call_user_func_array(array(&$this, 'call_epi'), $args);
if (!PEAR::isError($result)) {
$this->saveCache($_args, $result);
}
return $result;
} elseif (!($fp = fopen('XML/RPC.php', 'r', true))) {
return $this->raiseError("For this remote PEAR operation you need to load the xmlrpc extension or install XML_RPC");
}
include_once 'XML/RPC.php';
if ($fp) {
fclose($fp);
}
 
array_shift($args);
$username = $this->config->get('username');
$password = $this->config->get('password');
$eargs = array();
foreach($args as $arg) {
$eargs[] = $this->_encode($arg);
}
$f = new XML_RPC_Message($method, $eargs);
if ($this->cache !== null) {
$maxAge = '?maxAge='.$this->cache['lastChange'];
} else {
$maxAge = '';
}
$proxy_host = $proxy_port = $proxy_user = $proxy_pass = '';
if ($proxy = parse_url($this->config->get('http_proxy'))) {
$proxy_host = isset($proxy['host']) ? $proxy['host'] : null;
if (isset($proxy['scheme']) && $proxy['scheme'] == 'https') {
$proxy_host = 'https://' . $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;
}
$shost = $server_host;
if ($channel->getSSL()) {
$shost = "https://$shost";
}
$c = new XML_RPC_Client('/' . $channel->getPath('xmlrpc')
. $maxAge, $shost, $server_port, $proxy_host, $proxy_port,
$proxy_user, $proxy_pass);
if ($username && $password) {
$c->setCredentials($username, $password);
}
if ($this->config->get('verbose') >= 3) {
$c->setDebug(1);
}
$r = $c->send($f);
if (!$r) {
return $this->raiseError("XML_RPC send failed");
}
$v = $r->value();
if ($e = $r->faultCode()) {
if ($e == $GLOBALS['XML_RPC_err']['http_error'] && strstr($r->faultString(), '304 Not Modified') !== false) {
return $this->cache['content'];
}
return $this->raiseError($r->faultString(), $e);
}
 
$result = XML_RPC_decode($v);
$this->saveCache($_args, $result);
return $result;
}
 
// }}}
 
// {{{ call_epi(method, [args...])
 
function call_epi($method)
{
if (!extension_loaded("xmlrpc")) {
return $this->raiseError("xmlrpc extension is not loaded");
}
$server_channel = $this->config->get('default_channel');
$channel = $this->_registry->getChannel($server_channel);
if (!PEAR::isError($channel)) {
$mirror = $this->config->get('preferred_mirror');
if ($channel->getMirror($mirror)) {
if ($channel->supports('xmlrpc', $method, $mirror)) {
$server_channel = $server_host = $mirror; // use the preferred mirror
$server_port = $channel->getPort($mirror);
} elseif (!$channel->supports('xmlrpc', $method)) {
return $this->raiseError("Channel $server_channel does not " .
"support xml-rpc method $method");
}
}
if (!isset($server_host)) {
if (!$channel->supports('xmlrpc', $method)) {
return $this->raiseError("Channel $server_channel does not support " .
"xml-rpc method $method");
} else {
$server_host = $server_channel;
$server_port = $channel->getPort();
}
}
} else {
return $this->raiseError("Unknown channel '$server_channel'");
}
$params = func_get_args();
array_shift($params);
$method = str_replace("_", ".", $method);
$request = xmlrpc_encode_request($method, $params);
if ($http_proxy = $this->config->get('http_proxy')) {
$proxy = parse_url($http_proxy);
$proxy_host = $proxy_port = $proxy_user = $proxy_pass = '';
$proxy_host = isset($proxy['host']) ? $proxy['host'] : null;
if (isset($proxy['scheme']) && $proxy['scheme'] == 'https') {
$proxy_host = 'https://' . $proxy_host;
}
$proxy_port = isset($proxy['port']) ? $proxy['port'] : null;
$proxy_user = isset($proxy['user']) ? urldecode($proxy['user']) : null;
$proxy_pass = isset($proxy['pass']) ? urldecode($proxy['pass']) : null;
$fp = @fsockopen($proxy_host, $proxy_port);
$use_proxy = true;
if ($channel->getSSL()) {
$server_host = "https://$server_host";
}
} else {
$use_proxy = false;
$ssl = $channel->getSSL();
$fp = @fsockopen(($ssl ? 'ssl://' : '') . $server_host, $server_port);
if (!$fp) {
$server_host = "$ssl$server_host"; // for error-reporting
}
}
if (!$fp && $http_proxy) {
return $this->raiseError("PEAR_Remote::call: fsockopen(`$proxy_host', $proxy_port) failed");
} elseif (!$fp) {
return $this->raiseError("PEAR_Remote::call: fsockopen(`$server_host', $server_port) failed");
}
$len = strlen($request);
$req_headers = "Host: $server_host:$server_port\r\n" .
"Content-type: text/xml\r\n" .
"Content-length: $len\r\n";
$username = $this->config->get('username');
$password = $this->config->get('password');
if ($username && $password) {
$req_headers .= "Cookie: PEAR_USER=$username; PEAR_PW=$password\r\n";
$tmp = base64_encode("$username:$password");
$req_headers .= "Authorization: Basic $tmp\r\n";
}
if ($this->cache !== null) {
$maxAge = '?maxAge='.$this->cache['lastChange'];
} else {
$maxAge = '';
}
 
if ($use_proxy && $proxy_host != '' && $proxy_user != '') {
$req_headers .= 'Proxy-Authorization: Basic '
.base64_encode($proxy_user.':'.$proxy_pass)
."\r\n";
}
 
if ($this->config->get('verbose') > 3) {
print "XMLRPC REQUEST HEADERS:\n";
var_dump($req_headers);
print "XMLRPC REQUEST BODY:\n";
var_dump($request);
}
 
if ($use_proxy && $proxy_host != '') {
$post_string = "POST http://".$server_host;
if ($proxy_port > '') {
$post_string .= ':'.$server_port;
}
} else {
$post_string = "POST ";
}
 
$path = '/' . $channel->getPath('xmlrpc');
fwrite($fp, ($post_string . $path . "$maxAge HTTP/1.0\r\n$req_headers\r\n$request"));
$response = '';
$line1 = fgets($fp, 2048);
if (!preg_match('!^HTTP/[0-9\.]+ (\d+) (.*)!', $line1, $matches)) {
return $this->raiseError("PEAR_Remote: invalid HTTP response from XML-RPC server");
}
switch ($matches[1]) {
case "200": // OK
break;
case "304": // Not Modified
return $this->cache['content'];
case "401": // Unauthorized
if ($username && $password) {
return $this->raiseError("PEAR_Remote ($server_host:$server_port) " .
": authorization failed", 401);
} else {
return $this->raiseError("PEAR_Remote ($server_host:$server_port) " .
": authorization required, please log in first", 401);
}
default:
return $this->raiseError("PEAR_Remote ($server_host:$server_port) : " .
"unexpected HTTP response", (int)$matches[1], null, null,
"$matches[1] $matches[2]");
}
while (trim(fgets($fp, 2048)) != ''); // skip rest of headers
while ($chunk = fread($fp, 10240)) {
$response .= $chunk;
}
fclose($fp);
if ($this->config->get('verbose') > 3) {
print "XMLRPC RESPONSE:\n";
var_dump($response);
}
$ret = xmlrpc_decode($response);
if (is_array($ret) && isset($ret['__PEAR_TYPE__'])) {
if ($ret['__PEAR_TYPE__'] == 'error') {
if (isset($ret['__PEAR_CLASS__'])) {
$class = $ret['__PEAR_CLASS__'];
} else {
$class = "PEAR_Error";
}
if ($ret['code'] === '') $ret['code'] = null;
if ($ret['message'] === '') $ret['message'] = null;
if ($ret['userinfo'] === '') $ret['userinfo'] = null;
if (strtolower($class) == 'db_error') {
$ret = $this->raiseError(PEAR::errorMessage($ret['code']),
$ret['code'], null, null,
$ret['userinfo']);
} else {
$ret = $this->raiseError($ret['message'], $ret['code'],
null, null, $ret['userinfo']);
}
}
} elseif (is_array($ret) && sizeof($ret) == 1 && isset($ret[0])
&& is_array($ret[0]) &&
!empty($ret[0]['faultString']) &&
!empty($ret[0]['faultCode'])) {
extract($ret[0]);
$faultString = "XML-RPC Server Fault: " .
str_replace("\n", " ", $faultString);
return $this->raiseError($faultString, $faultCode);
} elseif (is_array($ret) && sizeof($ret) == 2 && !empty($ret['faultString']) &&
!empty($ret['faultCode'])) {
extract($ret);
$faultString = "XML-RPC Server Fault: " .
str_replace("\n", " ", $faultString);
return $this->raiseError($faultString, $faultCode);
}
return $ret;
}
 
// }}}
 
// {{{ _encode
 
// a slightly extended version of XML_RPC_encode
function _encode($php_val)
{
global $XML_RPC_Boolean, $XML_RPC_Int, $XML_RPC_Double;
global $XML_RPC_String, $XML_RPC_Array, $XML_RPC_Struct;
 
$type = gettype($php_val);
$xmlrpcval = new XML_RPC_Value;
 
switch($type) {
case "array":
reset($php_val);
$firstkey = key($php_val);
end($php_val);
$lastkey = key($php_val);
reset($php_val);
if ($firstkey === 0 && is_int($lastkey) &&
($lastkey + 1) == count($php_val)) {
$is_continuous = true;
reset($php_val);
$size = count($php_val);
for ($expect = 0; $expect < $size; $expect++, next($php_val)) {
if (key($php_val) !== $expect) {
$is_continuous = false;
break;
}
}
if ($is_continuous) {
reset($php_val);
$arr = array();
while (list($k, $v) = each($php_val)) {
$arr[$k] = $this->_encode($v);
}
$xmlrpcval->addArray($arr);
break;
}
}
// fall though if not numerical and continuous
case "object":
$arr = array();
while (list($k, $v) = each($php_val)) {
$arr[$k] = $this->_encode($v);
}
$xmlrpcval->addStruct($arr);
break;
case "integer":
$xmlrpcval->addScalar($php_val, $XML_RPC_Int);
break;
case "double":
$xmlrpcval->addScalar($php_val, $XML_RPC_Double);
break;
case "string":
case "NULL":
$xmlrpcval->addScalar($php_val, $XML_RPC_String);
break;
case "boolean":
$xmlrpcval->addScalar($php_val, $XML_RPC_Boolean);
break;
case "unknown type":
default:
return null;
}
return $xmlrpcval;
}
 
// }}}
 
}
 
?>
/trunk/bibliotheque/pear/PEAR/Exception.php
5,6 → 5,12
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Tomas V. V. Cox <cox@idecnet.com>
11,8 → 17,9
* @author Hans Lellelid <hans@velum.net>
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Exception.php,v 1.26 2006/10/30 03:47:48 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.3.3
*/
86,9 → 93,9
* @author Hans Lellelid <hans@velum.net>
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.3.3
*
253,9 → 260,7
'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');
'message' => $this->cause->getMessage());
} elseif (is_array($this->cause)) {
foreach ($this->cause as $cause) {
if ($cause instanceof PEAR_Exception) {
267,9 → 272,7
'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');
'message' => $cause->getMessage());
} elseif (is_array($cause) && isset($cause['message'])) {
// PEAR_ErrorStack warning
$causes[] = array(
288,7 → 291,7
}
 
public function getTraceSafe()
{
{
if (!isset($this->_trace)) {
$this->_trace = $this->getTrace();
if (empty($this->_trace)) {
324,21 → 327,21
$trace = $this->getTraceSafe();
$causes = array();
$this->getCauseMessage($causes);
$html = '<table style="border: 1px" cellspacing="0">' . "\n";
$html = '<table border="1" cellspacing="0">' . "\n";
foreach ($causes as $i => $cause) {
$html .= '<tr><td colspan="3" style="background: #ff9999">'
$html .= '<tr><td colspan="3" bgcolor="#ff9999">'
. str_repeat('-', $i) . ' <b>' . $cause['class'] . '</b>: '
. htmlspecialchars($cause['message']) . ' in <b>' . $cause['file'] . '</b> '
. 'on line <b>' . $cause['line'] . '</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 style="text-align: center; background: #cccccc; width:20px; font-weight: bold;">#</td>'
. '<td style="text-align: center; background: #cccccc; font-weight: bold;">Function</td>'
. '<td style="text-align: center; background: #cccccc; font-weight: bold;">Location</td></tr>' . "\n";
$html .= '<tr><td colspan="3" bgcolor="#aaaaaa" align="center"><b>Exception trace</b></td></tr>' . "\n"
. '<tr><td align="center" bgcolor="#cccccc" width="20"><b>#</b></td>'
. '<td align="center" bgcolor="#cccccc"><b>Function</b></td>'
. '<td align="center" bgcolor="#cccccc"><b>Location</b></td></tr>' . "\n";
 
foreach ($trace as $k => $v) {
$html .= '<tr><td style="text-align: center;">' . $k . '</td>'
$html .= '<tr><td align="center">' . $k . '</td>'
. '<td>';
if (!empty($v['class'])) {
$html .= $v['class'] . $v['type'];
366,7 → 369,7
. ':' . (isset($v['line']) ? $v['line'] : 'unknown')
. '</td></tr>' . "\n";
}
$html .= '<tr><td style="text-align: center;">' . ($k+1) . '</td>'
$html .= '<tr><td align="center">' . ($k+1) . '</td>'
. '<td>{main}</td>'
. '<td>&nbsp;</td></tr>' . "\n"
. '</table>';
385,4 → 388,6
}
return $causeMsg . $this->getTraceAsString();
}
}
}
 
?>
/trunk/bibliotheque/pear/PEAR/Validator/PECL.php
8,7 → 8,8
* @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
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: PECL.php,v 1.8 2006/05/12 02:38:58 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a5
*/
21,9 → 22,9
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a5
*/
/trunk/bibliotheque/pear/PEAR/Config.php
4,12 → 4,19
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Config.php,v 1.137 2006/11/19 21:33:00 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
21,6 → 28,7
require_once 'PEAR/Registry.php';
require_once 'PEAR/Installer/Role.php';
require_once 'System.php';
require_once 'PEAR/Remote.php';
 
/**
* Last created PEAR_Config instance.
41,11 → 49,8
 
// default channel and preferred mirror is based on whether we are invoked through
// the "pear" or the "pecl" command
if (!defined('PEAR_RUNTYPE')) {
define('PEAR_RUNTYPE', 'pear');
}
 
if (PEAR_RUNTYPE == 'pear') {
if (!defined('PEAR_RUNTYPE') || PEAR_RUNTYPE == 'pear') {
define('PEAR_CONFIG_DEFAULT_CHANNEL', 'pear.php.net');
} else {
define('PEAR_CONFIG_DEFAULT_CHANNEL', 'pecl.php.net');
79,20 → 84,14
if (getenv('PHP_PEAR_INSTALL_DIR')) {
define('PEAR_CONFIG_DEFAULT_PHP_DIR', getenv('PHP_PEAR_INSTALL_DIR'));
} else {
if (@file_exists($PEAR_INSTALL_DIR) && is_dir($PEAR_INSTALL_DIR)) {
define('PEAR_CONFIG_DEFAULT_PHP_DIR', $PEAR_INSTALL_DIR);
if (file_exists($PEAR_INSTALL_DIR) && is_dir($PEAR_INSTALL_DIR)) {
define('PEAR_CONFIG_DEFAULT_PHP_DIR',
$PEAR_INSTALL_DIR);
} else {
define('PEAR_CONFIG_DEFAULT_PHP_DIR', $PEAR_INSTALL_DIR);
}
}
 
// Default for metadata_dir
if (getenv('PHP_PEAR_METADATA_DIR')) {
define('PEAR_CONFIG_DEFAULT_METADATA_DIR', getenv('PHP_PEAR_METADATA_DIR'));
} else {
define('PEAR_CONFIG_DEFAULT_METADATA_DIR', '');
}
 
// Default for ext_dir
if (getenv('PHP_PEAR_EXTENSION_DIR')) {
define('PEAR_CONFIG_DEFAULT_EXT_DIR', getenv('PHP_PEAR_EXTENSION_DIR'));
132,34 → 131,6
$PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'data');
}
 
// Default for cfg_dir
if (getenv('PHP_PEAR_CFG_DIR')) {
define('PEAR_CONFIG_DEFAULT_CFG_DIR', getenv('PHP_PEAR_CFG_DIR'));
} else {
define('PEAR_CONFIG_DEFAULT_CFG_DIR',
$PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'cfg');
}
 
// Default for www_dir
if (getenv('PHP_PEAR_WWW_DIR')) {
define('PEAR_CONFIG_DEFAULT_WWW_DIR', getenv('PHP_PEAR_WWW_DIR'));
} else {
define('PEAR_CONFIG_DEFAULT_WWW_DIR',
$PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'www');
}
 
// Default for man_dir
if (getenv('PHP_PEAR_MAN_DIR')) {
define('PEAR_CONFIG_DEFAULT_MAN_DIR', getenv('PHP_PEAR_MAN_DIR'));
} else {
if (defined('PHP_MANDIR')) { // Added in PHP5.3.7
define('PEAR_CONFIG_DEFAULT_MAN_DIR', PHP_MANDIR);
} else {
define('PEAR_CONFIG_DEFAULT_MAN_DIR', PHP_PREFIX . DIRECTORY_SEPARATOR .
'local' . DIRECTORY_SEPARATOR .'man');
}
}
 
// Default for test_dir
if (getenv('PHP_PEAR_TEST_DIR')) {
define('PEAR_CONFIG_DEFAULT_TEST_DIR', getenv('PHP_PEAR_TEST_DIR'));
262,14 → 233,16
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
class PEAR_Config extends PEAR
{
// {{{ properties
 
/**
* Array of config files used.
*
281,7 → 254,7
);
 
var $layers = array();
 
/**
* Configuration data, two-dimensional array where the first
* dimension is the config layer ('user', 'system' and 'default'),
299,7 → 272,7
'system' => array(),
'default' => array(),
);
 
/**
* Configuration values that can be set for a channel
*
308,9 → 281,9
* @access private
*/
var $_channelConfigInfo = array(
'php_dir', 'ext_dir', 'doc_dir', 'bin_dir', 'data_dir', 'cfg_dir',
'test_dir', 'www_dir', 'php_bin', 'php_prefix', 'php_suffix', 'username',
'password', 'verbose', 'preferred_state', 'umask', 'preferred_mirror', 'php_ini'
'php_dir', 'ext_dir', 'doc_dir', 'bin_dir', 'data_dir',
'test_dir', 'php_bin', 'username', 'password', 'verbose',
'preferred_state', 'umask', 'preferred_mirror',
);
 
/**
444,27 → 417,6
'prompt' => 'PEAR data directory',
'group' => 'File Locations (Advanced)',
),
'cfg_dir' => array(
'type' => 'directory',
'default' => PEAR_CONFIG_DEFAULT_CFG_DIR,
'doc' => 'directory where modifiable configuration files are installed',
'prompt' => 'PEAR configuration file directory',
'group' => 'File Locations (Advanced)',
),
'www_dir' => array(
'type' => 'directory',
'default' => PEAR_CONFIG_DEFAULT_WWW_DIR,
'doc' => 'directory where www frontend files (html/js) are installed',
'prompt' => 'PEAR www files directory',
'group' => 'File Locations (Advanced)',
),
'man_dir' => array(
'type' => 'directory',
'default' => PEAR_CONFIG_DEFAULT_MAN_DIR,
'doc' => 'directory where unix manual pages are installed',
'prompt' => 'Systems manpage files directory',
'group' => 'File Locations (Advanced)',
),
'test_dir' => array(
'type' => 'directory',
'default' => PEAR_CONFIG_DEFAULT_TEST_DIR,
475,7 → 427,7
'cache_dir' => array(
'type' => 'directory',
'default' => PEAR_CONFIG_DEFAULT_CACHE_DIR,
'doc' => 'directory which is used for web service cache',
'doc' => 'directory which is used for XMLRPC cache',
'prompt' => 'PEAR Installer cache directory',
'group' => 'File Locations (Advanced)',
),
488,7 → 440,7
),
'download_dir' => array(
'type' => 'directory',
'default' => PEAR_CONFIG_DEFAULT_DOWNLOAD_DIR,
'default' => PEAR_CONFIG_DEFAULT_CACHE_DIR,
'doc' => 'directory which is used for all downloaded files',
'prompt' => 'PEAR Installer download directory',
'group' => 'File Locations (Advanced)',
500,20 → 452,6
'prompt' => 'PHP CLI/CGI binary',
'group' => 'File Locations (Advanced)',
),
'php_prefix' => array(
'type' => 'string',
'default' => '',
'doc' => '--program-prefix for php_bin\'s ./configure, used for pecl installs',
'prompt' => '--program-prefix passed to PHP\'s ./configure',
'group' => 'File Locations (Advanced)',
),
'php_suffix' => array(
'type' => 'string',
'default' => '',
'doc' => '--program-suffix for php_bin\'s ./configure, used for pecl installs',
'prompt' => '--program-suffix passed to PHP\'s ./configure',
'group' => 'File Locations (Advanced)',
),
'php_ini' => array(
'type' => 'file',
'default' => '',
521,13 → 459,6
'prompt' => 'php.ini location',
'group' => 'File Locations (Advanced)',
),
'metadata_dir' => array(
'type' => 'directory',
'default' => PEAR_CONFIG_DEFAULT_METADATA_DIR,
'doc' => 'directory where metadata files are installed (registry, filemap, channels, ...)',
'prompt' => 'PEAR metadata directory',
'group' => 'File Locations (Advanced)',
),
// Maintainers
'username' => array(
'type' => 'string',
610,6 → 541,10
// __channels is reserved - used for channel-specific configuration
);
 
// }}}
 
// {{{ PEAR_Config([file], [defaults_file])
 
/**
* Constructor.
*
624,10 → 559,10
*
* @see PEAR_Config::singleton
*/
function __construct($user_file = '', $system_file = '', $ftp_file = false,
function PEAR_Config($user_file = '', $system_file = '', $ftp_file = false,
$strict = true)
{
parent::__construct();
$this->PEAR();
PEAR_Installer_Role::initializeConfig($this);
$sl = DIRECTORY_SEPARATOR;
if (empty($user_file)) {
637,18 → 572,16
$user_file = getenv('HOME') . $sl . '.pearrc';
}
}
 
if (empty($system_file)) {
$system_file = PEAR_CONFIG_SYSCONFDIR . $sl;
if (OS_WINDOWS) {
$system_file .= 'pearsys.ini';
$system_file = PEAR_CONFIG_SYSCONFDIR . $sl . 'pearsys.ini';
} else {
$system_file .= 'pear.conf';
$system_file = PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.conf';
}
}
 
$this->layers = array_keys($this->configuration);
$this->files['user'] = $user_file;
$this->files['user'] = $user_file;
$this->files['system'] = $system_file;
if ($user_file && file_exists($user_file)) {
$this->pushErrorHandling(PEAR_ERROR_RETURN);
659,7 → 592,7
}
}
 
if ($system_file && @file_exists($system_file)) {
if ($system_file && file_exists($system_file)) {
$this->mergeConfigFile($system_file, false, 'system', $strict);
if ($this->_errorsFound > 0) {
return;
679,33 → 612,15
$this->configuration['default'][$key] = $info['default'];
}
 
$this->_registry['default'] = new PEAR_Registry(
$this->configuration['default']['php_dir'], false, false,
$this->configuration['default']['metadata_dir']);
$this->_registry['default']->setConfig($this, false);
$this->_registry['default'] = &new PEAR_Registry($this->configuration['default']['php_dir']);
$this->_registry['default']->setConfig($this);
$this->_regInitialized['default'] = false;
//$GLOBALS['_PEAR_Config_instance'] = &$this;
}
 
/**
* Return the default locations of user and system configuration files
*/
public static function getDefaultConfigFiles()
{
$sl = DIRECTORY_SEPARATOR;
if (OS_WINDOWS) {
return array(
'user' => PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.ini',
'system' => PEAR_CONFIG_SYSCONFDIR . $sl . 'pearsys.ini'
);
}
// }}}
// {{{ singleton([file], [defaults_file])
 
return array(
'user' => getenv('HOME') . $sl . '.pearrc',
'system' => PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.conf'
);
}
 
/**
* Static singleton method. If you want to keep only one instance
* of this class in use, this method will give you a reference to
717,15 → 632,17
*
* @return object an existing or new PEAR_Config instance
*
* @access public
*
* @see PEAR_Config::PEAR_Config
*/
public static function &singleton($user_file = '', $system_file = '', $strict = true)
function &singleton($user_file = '', $system_file = '', $strict = true)
{
if (is_object($GLOBALS['_PEAR_Config_instance'])) {
return $GLOBALS['_PEAR_Config_instance'];
}
 
$t_conf = new PEAR_Config($user_file, $system_file, false, $strict);
$t_conf = &new PEAR_Config($user_file, $system_file, false, $strict);
if ($t_conf->_errorsFound > 0) {
return $t_conf->lastError;
}
734,6 → 651,9
return $GLOBALS['_PEAR_Config_instance'];
}
 
// }}}
// {{{ validConfiguration()
 
/**
* Determine whether any configuration files have been detected, and whether a
* registry object can be retrieved from this configuration.
745,10 → 665,12
if ($this->isDefinedLayer('user') || $this->isDefinedLayer('system')) {
return true;
}
 
return false;
}
 
// }}}
// {{{ readConfigFile([file], [layer])
 
/**
* Reads configuration data from a file. All existing values in
* the config layer are discarded and replaced with data from the
769,26 → 691,26
}
 
$data = $this->_readConfigDataFrom($file);
 
if (PEAR::isError($data)) {
if (!$strict) {
if ($strict) {
$this->_errorsFound++;
$this->lastError = $data;
 
return $data;
} else {
return true;
}
 
$this->_errorsFound++;
$this->lastError = $data;
 
return $data;
} else {
$this->files[$layer] = $file;
}
 
$this->files[$layer] = $file;
$this->_decodeInput($data);
$this->configuration[$layer] = $data;
$this->_setupChannels();
if (!$this->_noRegistry && ($phpdir = $this->get('php_dir', $layer, 'pear.php.net'))) {
$this->_registry[$layer] = new PEAR_Registry(
$phpdir, false, false,
$this->get('metadata_dir', $layer, 'pear.php.net'));
$this->_registry[$layer]->setConfig($this, false);
$this->_registry[$layer] = &new PEAR_Registry($phpdir);
$this->_registry[$layer]->setConfig($this);
$this->_regInitialized[$layer] = false;
} else {
unset($this->_registry[$layer]);
796,6 → 718,8
return true;
}
 
// }}}
 
/**
* @param string url to the remote config file, like ftp://www.example.com/pear/config.ini
* @return true|PEAR_Error
811,64 → 735,61
require_once 'PEAR/FTP.php';
}
}
 
if (!class_exists('PEAR_FTP')) {
return PEAR::raiseError('PEAR_RemoteInstaller must be installed to use remote config');
}
 
$this->_ftp = new PEAR_FTP;
$this->_ftp->pushErrorHandling(PEAR_ERROR_RETURN);
$e = $this->_ftp->init($path);
if (PEAR::isError($e)) {
if (class_exists('PEAR_FTP')) {
$this->_ftp = &new PEAR_FTP;
$this->_ftp->pushErrorHandling(PEAR_ERROR_RETURN);
$e = $this->_ftp->init($path);
if (PEAR::isError($e)) {
$this->_ftp->popErrorHandling();
return $e;
}
$tmp = System::mktemp('-d');
PEAR_Common::addTempFile($tmp);
$e = $this->_ftp->get(basename($path), $tmp . DIRECTORY_SEPARATOR .
'pear.ini', false, FTP_BINARY);
if (PEAR::isError($e)) {
$this->_ftp->popErrorHandling();
return $e;
}
PEAR_Common::addTempFile($tmp . DIRECTORY_SEPARATOR . 'pear.ini');
$this->_ftp->disconnect();
$this->_ftp->popErrorHandling();
return $e;
}
 
$tmp = System::mktemp('-d');
PEAR_Common::addTempFile($tmp);
$e = $this->_ftp->get(basename($path), $tmp . DIRECTORY_SEPARATOR .
'pear.ini', false, FTP_BINARY);
if (PEAR::isError($e)) {
$this->_ftp->popErrorHandling();
return $e;
}
 
PEAR_Common::addTempFile($tmp . DIRECTORY_SEPARATOR . 'pear.ini');
$this->_ftp->disconnect();
$this->_ftp->popErrorHandling();
$this->files['ftp'] = $tmp . DIRECTORY_SEPARATOR . 'pear.ini';
$e = $this->readConfigFile(null, 'ftp');
if (PEAR::isError($e)) {
return $e;
}
 
$fail = array();
foreach ($this->configuration_info as $key => $val) {
if (in_array($this->getGroup($key),
array('File Locations', 'File Locations (Advanced)')) &&
$this->getType($key) == 'directory') {
// any directory configs must be set for this to work
if (!isset($this->configuration['ftp'][$key])) {
$fail[] = $key;
$this->files['ftp'] = $tmp . DIRECTORY_SEPARATOR . 'pear.ini';
$e = $this->readConfigFile(null, 'ftp');
if (PEAR::isError($e)) {
return $e;
}
$fail = array();
foreach ($this->configuration_info as $key => $val) {
if (in_array($this->getGroup($key),
array('File Locations', 'File Locations (Advanced)')) &&
$this->getType($key) == 'directory') {
// any directory configs must be set for this to work
if (!isset($this->configuration['ftp'][$key])) {
$fail[] = $key;
}
}
}
if (count($fail)) {
$fail = '"' . implode('", "', $fail) . '"';
unset($this->files['ftp']);
unset($this->configuration['ftp']);
return PEAR::raiseError('ERROR: Ftp configuration file must set all ' .
'directory configuration variables. These variables were not set: ' .
$fail);
} else {
return true;
}
} else {
return PEAR::raiseError('PEAR_RemoteInstaller must be installed to use remote config');
}
 
if (!count($fail)) {
return true;
}
 
$fail = '"' . implode('", "', $fail) . '"';
unset($this->files['ftp']);
unset($this->configuration['ftp']);
return PEAR::raiseError('ERROR: Ftp configuration file must set all ' .
'directory configuration variables. These variables were not set: ' .
$fail);
} while (false); // poor man's catch
unset($this->files['ftp']);
return PEAR::raiseError('no remote host specified');
}
 
// {{{ _setupChannels()
/**
* Reads the existing configurations and creates the _channels array from it
*/
887,20 → 808,26
$this->setChannels($this->_channels);
}
 
// }}}
// {{{ deleteChannel(channel)
 
function deleteChannel($channel)
{
$ch = strtolower($channel);
foreach ($this->configuration as $layer => $data) {
if (isset($data['__channels']) && isset($data['__channels'][$ch])) {
unset($this->configuration[$layer]['__channels'][$ch]);
if (isset($data['__channels'])) {
if (isset($data['__channels'][strtolower($channel)])) {
unset($this->configuration[$layer]['__channels'][strtolower($channel)]);
}
}
}
 
$this->_channels = array_flip($this->_channels);
unset($this->_channels[$ch]);
unset($this->_channels[strtolower($channel)]);
$this->_channels = array_flip($this->_channels);
}
 
// }}}
// {{{ mergeConfigFile(file, [override], [layer])
 
/**
* Merges data into a config layer from a file. Does the same
* thing as readConfigFile, except it does not replace all
916,23 → 843,20
if (empty($this->files[$layer])) {
return $this->raiseError("unknown config layer `$layer'");
}
 
if ($file === null) {
$file = $this->files[$layer];
}
 
$data = $this->_readConfigDataFrom($file);
if (PEAR::isError($data)) {
if (!$strict) {
if ($strict) {
$this->_errorsFound++;
$this->lastError = $data;
 
return $data;
} else {
return true;
}
 
$this->_errorsFound++;
$this->lastError = $data;
 
return $data;
}
 
$this->_decodeInput($data);
if ($override) {
$this->configuration[$layer] =
941,13 → 865,10
$this->configuration[$layer] =
PEAR_Config::arrayMergeRecursive($data, $this->configuration[$layer]);
}
 
$this->_setupChannels();
if (!$this->_noRegistry && ($phpdir = $this->get('php_dir', $layer, 'pear.php.net'))) {
$this->_registry[$layer] = new PEAR_Registry(
$phpdir, false, false,
$this->get('metadata_dir', $layer, 'pear.php.net'));
$this->_registry[$layer]->setConfig($this, false);
$this->_registry[$layer] = &new PEAR_Registry($phpdir);
$this->_registry[$layer]->setConfig($this);
$this->_regInitialized[$layer] = false;
} else {
unset($this->_registry[$layer]);
955,12 → 876,15
return true;
}
 
// }}}
// {{{ arrayMergeRecursive($arr2, $arr1)
/**
* @param array
* @param array
* @return array
* @static
*/
public static function arrayMergeRecursive($arr2, $arr1)
function arrayMergeRecursive($arr2, $arr1)
{
$ret = array();
foreach ($arr2 as $key => $data) {
979,10 → 903,12
unset($arr1[$key]);
}
}
 
return array_merge($ret, $arr1);
}
 
// }}}
// {{{ writeConfigFile([file], [layer])
 
/**
* Writes data into a config layer from a file.
*
1004,15 → 930,12
}
return true;
}
 
if (empty($this->files[$layer])) {
return $this->raiseError("unknown config file type `$layer'");
}
 
if ($file === null) {
$file = $this->files[$layer];
}
 
$data = ($data === null) ? $this->configuration[$layer] : $data;
$this->_encodeOutput($data);
$opt = array('-p', dirname($file));
1019,16 → 942,13
if (!@System::mkDir($opt)) {
return $this->raiseError("could not create directory: " . dirname($file));
}
 
if (file_exists($file) && is_file($file) && !is_writeable($file)) {
return $this->raiseError("no write access to $file!");
}
 
$fp = @fopen($file, "w");
if (!$fp) {
return $this->raiseError("PEAR_Config::writeConfigFile fopen('$file','w') failed ($php_errormsg)");
}
 
$contents = "#PEAR_Config 0.9\n" . serialize($data);
if (!@fwrite($fp, $contents)) {
return $this->raiseError("PEAR_Config::writeConfigFile: fwrite failed ($php_errormsg)");
1036,12 → 956,17
return true;
}
 
// }}}
// {{{ _readConfigDataFrom(file)
 
/**
* Reads configuration data from a file and returns the parsed data
* in an array.
*
* @param string file to read from
*
* @return array configuration data or a PEAR error on failure
*
* @access private
*/
function _readConfigDataFrom($file)
1050,17 → 975,19
if (file_exists($file)) {
$fp = @fopen($file, "r");
}
 
if (!$fp) {
return $this->raiseError("PEAR_Config::readConfigFile fopen('$file','r') failed");
}
 
$size = filesize($file);
$rt = get_magic_quotes_runtime();
set_magic_quotes_runtime(0);
fclose($fp);
$contents = file_get_contents($file);
if (empty($contents)) {
return $this->raiseError('Configuration file "' . $file . '" is empty');
}
set_magic_quotes_runtime($rt);
 
$version = false;
if (preg_match('/^#PEAR_Config\s+(\S+)\s+/si', $contents, $matches)) {
1072,8 → 999,8
$version = '0.1';
}
}
if ($version && version_compare("$version", '1', '<')) {
 
if ($version && version_compare("$version", '1', '<')) {
// no '@', it is possible that unserialize
// raises a notice but it seems to block IO to
// STDOUT if a '@' is used and a notice is raise
1092,124 → 1019,116
$error = "PEAR_Config: bad data in $file";
$err = $this->raiseError($error);
return $err;
} else {
$data = array();
}
 
$data = array();
}
// add parsing of newer formats here...
} else {
$err = $this->raiseError("$file: unknown version `$version'");
return $err;
return $err;
}
 
return $data;
}
 
// }}}
// {{{ getConfFile(layer)
/**
* Gets the file used for storing the config for a layer
*
* @param string $layer 'user' or 'system'
*/
 
function getConfFile($layer)
{
return $this->files[$layer];
}
 
// }}}
 
/**
* @param string Configuration class name, used for detecting duplicate calls
* @param array information on a role as parsed from its xml file
* @return true|PEAR_Error
* @access private
*/
function _addConfigVars($class, $vars)
function _addConfigVars($vars)
{
static $called = array();
if (isset($called[$class])) {
return;
}
 
$called[$class] = 1;
if (count($vars) > 3) {
return $this->raiseError('Roles can only define 3 new config variables or less');
}
 
foreach ($vars as $name => $var) {
if (!is_array($var)) {
return $this->raiseError('Configuration information must be an array');
}
 
if (!isset($var['type'])) {
return $this->raiseError('Configuration information must contain a type');
} elseif (!in_array($var['type'],
array('string', 'mask', 'password', 'directory', 'file', 'set'))) {
return $this->raiseError(
'Configuration type must be one of directory, file, string, ' .
'mask, set, or password');
} else {
if (!in_array($var['type'],
array('string', 'mask', 'password', 'directory', 'file', 'set'))) {
return $this->raiseError(
'Configuration type must be one of directory, file, string, ' .
'mask, set, or password');
}
}
if (!isset($var['default'])) {
return $this->raiseError(
'Configuration information must contain a default value ("default" index)');
}
 
if (is_array($var['default'])) {
$real_default = '';
foreach ($var['default'] as $config_var => $val) {
if (strpos($config_var, 'text') === 0) {
$real_default .= $val;
} elseif (strpos($config_var, 'constant') === 0) {
if (!defined($val)) {
} else {
if (is_array($var['default'])) {
$real_default = '';
foreach ($var['default'] as $config_var => $val) {
if (strpos($config_var, 'text') === 0) {
$real_default .= $val;
} elseif (strpos($config_var, 'constant') === 0) {
if (defined($val)) {
$real_default .= constant($val);
} else {
return $this->raiseError(
'Unknown constant "' . $val . '" requested in ' .
'default value for configuration variable "' .
$name . '"');
}
} elseif (isset($this->configuration_info[$config_var])) {
$real_default .=
$this->configuration_info[$config_var]['default'];
} else {
return $this->raiseError(
'Unknown constant "' . $val . '" requested in ' .
'Unknown request for "' . $config_var . '" value in ' .
'default value for configuration variable "' .
$name . '"');
}
 
$real_default .= constant($val);
} elseif (isset($this->configuration_info[$config_var])) {
$real_default .=
$this->configuration_info[$config_var]['default'];
} else {
return $this->raiseError(
'Unknown request for "' . $config_var . '" value in ' .
'default value for configuration variable "' .
$name . '"');
}
$var['default'] = $real_default;
}
$var['default'] = $real_default;
if ($var['type'] == 'integer') {
$var['default'] = (integer) $var['default'];
}
}
 
if ($var['type'] == 'integer') {
$var['default'] = (integer) $var['default'];
}
 
if (!isset($var['doc'])) {
return $this->raiseError(
'Configuration information must contain a summary ("doc" index)');
}
 
if (!isset($var['prompt'])) {
return $this->raiseError(
'Configuration information must contain a simple prompt ("prompt" index)');
}
 
if (!isset($var['group'])) {
return $this->raiseError(
'Configuration information must contain a simple group ("group" index)');
}
 
if (isset($this->configuration_info[$name])) {
return $this->raiseError('Configuration variable "' . $name .
'" already exists');
}
 
$this->configuration_info[$name] = $var;
// fix bug #7351: setting custom config variable in a channel fails
$this->_channelConfigInfo[] = $name;
}
 
return true;
}
 
// {{{ _encodeOutput(&data)
 
/**
* Encodes/scrambles configuration data before writing to files.
* Currently, 'password' values will be base64-encoded as to avoid
1216,7 → 1135,9
* that people spot cleartext passwords by accident.
*
* @param array (reference) array to encode values in
*
* @return bool TRUE on success
*
* @access private
*/
function _encodeOutput(&$data)
1227,11 → 1148,9
$this->_encodeOutput($data['__channels'][$channel]);
}
}
 
if (!isset($this->configuration_info[$key])) {
continue;
}
 
$type = $this->configuration_info[$key]['type'];
switch ($type) {
// we base64-encode passwords so they are at least
1246,15 → 1165,19
}
}
}
 
return true;
}
 
// }}}
// {{{ _decodeInput(&data)
 
/**
* Decodes/unscrambles configuration data after reading from files.
*
* @param array (reference) array to encode values in
*
* @return bool TRUE on success
*
* @access private
*
* @see PEAR_Config::_encodeOutput
1264,7 → 1187,6
if (!is_array($data)) {
return true;
}
 
foreach ($data as $key => $value) {
if ($key == '__channels') {
foreach ($data['__channels'] as $channel => $blah) {
1271,11 → 1193,9
$this->_decodeInput($data['__channels'][$channel]);
}
}
 
if (!isset($this->configuration_info[$key])) {
continue;
}
 
$type = $this->configuration_info[$key]['type'];
switch ($type) {
case 'password': {
1288,10 → 1208,11
}
}
}
 
return true;
}
 
// }}}
// {{{ getDefaultChannel([layer])
/**
* Retrieve the default channel.
*
1313,28 → 1234,27
} elseif (isset($this->configuration[$layer]['default_channel'])) {
$ret = $this->configuration[$layer]['default_channel'];
}
 
if ($ret == 'pear.php.net' && defined('PEAR_RUNTYPE') && PEAR_RUNTYPE == 'pecl') {
$ret = 'pecl.php.net';
}
 
if ($ret) {
if ($ret != 'pear.php.net') {
$this->_lazyChannelSetup();
}
 
return $ret;
}
 
return PEAR_CONFIG_DEFAULT_CHANNEL;
}
 
// {{{ get(key, [layer])
/**
* Returns a configuration value, prioritizing layers as per the
* layers property.
*
* @param string config key
*
* @return mixed the config value, or NULL if not found
*
* @access public
*/
function get($key, $layer = null, $channel = false)
1342,15 → 1262,12
if (!isset($this->configuration_info[$key])) {
return null;
}
 
if ($key == '__channels') {
return null;
}
 
if ($key == 'default_channel') {
return $this->getDefaultChannel($layer);
}
 
if (!$channel) {
$channel = $this->getDefaultChannel();
} elseif ($channel != 'pear.php.net') {
1357,7 → 1274,7
$this->_lazyChannelSetup();
}
$channel = strtolower($channel);
 
$test = (in_array($key, $this->_channelConfigInfo)) ?
$this->_getChannelValue($key, $layer, $channel) :
null;
1371,7 → 1288,6
}
return $test;
}
 
if ($layer === null) {
foreach ($this->layers as $layer) {
if (isset($this->configuration[$layer][$key])) {
1383,15 → 1299,13
return $this->_prependPath($test, $this->_installRoot);
}
}
 
if ($key == 'preferred_mirror') {
$reg = &$this->getRegistry();
if (is_object($reg)) {
$chan = $reg->getChannel($channel);
$chan = &$reg->getChannel($channel);
if (PEAR::isError($chan)) {
return $channel;
}
 
if (!$chan->getMirror($test) && $chan->getName() != $test) {
return $channel; // mirror does not exist
}
1409,33 → 1323,33
return $this->_prependPath($test, $this->_installRoot);
}
}
 
if ($key == 'preferred_mirror') {
$reg = &$this->getRegistry();
if (is_object($reg)) {
$chan = $reg->getChannel($channel);
$chan = &$reg->getChannel($channel);
if (PEAR::isError($chan)) {
return $channel;
}
 
if (!$chan->getMirror($test) && $chan->getName() != $test) {
return $channel; // mirror does not exist
}
}
}
 
return $test;
}
 
return null;
}
 
// }}}
// {{{ _getChannelValue(key, value, [layer])
/**
* Returns a channel-specific configuration value, prioritizing layers as per the
* layers property.
*
* @param string config key
*
* @return mixed the config value, or NULL if not found
*
* @access private
*/
function _getChannelValue($key, $layer, $channel)
1443,7 → 1357,6
if ($key == '__channels' || $channel == 'pear.php.net') {
return null;
}
 
$ret = null;
if ($layer === null) {
foreach ($this->layers as $ilayer) {
1455,35 → 1368,33
} elseif (isset($this->configuration[$layer]['__channels'][$channel][$key])) {
$ret = $this->configuration[$layer]['__channels'][$channel][$key];
}
 
if ($key != 'preferred_mirror') {
return $ret;
}
 
 
if ($ret !== null) {
$reg = &$this->getRegistry($layer);
if (is_object($reg)) {
$chan = $reg->getChannel($channel);
if (PEAR::isError($chan)) {
return $channel;
if ($key == 'preferred_mirror') {
if ($ret !== null) {
$reg = &$this->getRegistry($layer);
if (is_object($reg)) {
$chan = &$reg->getChannel($channel);
if (PEAR::isError($chan)) {
return $channel;
}
if (!$chan->getMirror($ret) && $chan->getName() != $ret) {
return $channel; // mirror does not exist
}
}
 
if (!$chan->getMirror($ret) && $chan->getName() != $ret) {
return $channel; // mirror does not exist
}
return $ret;
}
 
return $ret;
if ($channel != $this->getDefaultChannel($layer)) {
return $channel; // we must use the channel name as the preferred mirror
// if the user has not chosen an alternate
} else {
return $this->getDefaultChannel($layer);
}
}
return $ret;
}
 
if ($channel != $this->getDefaultChannel($layer)) {
return $channel; // we must use the channel name as the preferred mirror
// if the user has not chosen an alternate
}
 
return $this->getDefaultChannel($layer);
}
// }}}
// {{{ set(key, value, [layer])
 
/**
* Set a config value in a specific layer (defaults to 'user').
1502,11 → 1413,9
if ($key == '__channels') {
return false;
}
 
if (!isset($this->configuration[$layer])) {
return false;
}
 
if ($key == 'default_channel') {
// can only set this value globally
$channel = 'pear.php.net';
1514,29 → 1423,24
$this->_lazyChannelSetup($layer);
}
}
 
if ($key == 'preferred_mirror') {
if ($channel == '__uri') {
return false; // can't set the __uri pseudo-channel's mirror
}
 
$reg = &$this->getRegistry($layer);
if (is_object($reg)) {
$chan = $reg->getChannel($channel ? $channel : 'pear.php.net');
$chan = &$reg->getChannel($channel ? $channel : 'pear.php.net');
if (PEAR::isError($chan)) {
return false;
}
 
if (!$chan->getMirror($value) && $chan->getName() != $value) {
return false; // mirror does not exist
}
}
}
 
if (!isset($this->configuration_info[$key])) {
if (empty($this->configuration_info[$key])) {
return false;
}
 
extract($this->configuration_info[$key]);
switch ($type) {
case 'integer':
1557,11 → 1461,9
break;
}
}
 
if (!$channel) {
$channel = $this->get('default_channel', null, 'pear.php.net');
}
 
if (!in_array($channel, $this->_channels)) {
$this->_lazyChannelSetup($layer);
$reg = &$this->getRegistry($layer);
1568,63 → 1470,56
if ($reg) {
$channel = $reg->channelName($channel);
}
 
if (!in_array($channel, $this->_channels)) {
return false;
}
}
 
if ($channel != 'pear.php.net') {
if (in_array($key, $this->_channelConfigInfo)) {
$this->configuration[$layer]['__channels'][$channel][$key] = $value;
return true;
} else {
return false;
}
 
return false;
}
 
if ($key == 'default_channel') {
if (!isset($reg)) {
$reg = &$this->getRegistry($layer);
if (!$reg) {
$reg = &$this->getRegistry();
} else {
if ($key == 'default_channel') {
if (!isset($reg)) {
$reg = &$this->getRegistry($layer);
if (!$reg) {
$reg = &$this->getRegistry();
}
}
if ($reg) {
$value = $reg->channelName($value);
}
if (!$value) {
return false;
}
}
 
if ($reg) {
$value = $reg->channelName($value);
}
 
if (!$value) {
return false;
}
}
 
$this->configuration[$layer][$key] = $value;
if ($key == 'php_dir' && !$this->_noRegistry) {
if (!isset($this->_registry[$layer]) ||
$value != $this->_registry[$layer]->install_dir) {
$this->_registry[$layer] = new PEAR_Registry($value);
$this->_registry[$layer] = &new PEAR_Registry($value);
$this->_regInitialized[$layer] = false;
$this->_registry[$layer]->setConfig($this, false);
$this->_registry[$layer]->setConfig($this);
}
}
 
return true;
}
 
// }}}
function _lazyChannelSetup($uselayer = false)
{
if ($this->_noRegistry) {
return;
}
 
$merge = false;
foreach ($this->_registry as $layer => $p) {
if ($uselayer && $uselayer != $layer) {
continue;
}
 
if (!$this->_regInitialized[$layer]) {
if ($layer == 'default' && isset($this->_registry['user']) ||
isset($this->_registry['system'])) {
1631,13 → 1526,10
// only use the default registry if there are no alternatives
continue;
}
 
if (!is_object($this->_registry[$layer])) {
if ($phpdir = $this->get('php_dir', $layer, 'pear.php.net')) {
$this->_registry[$layer] = new PEAR_Registry(
$phpdir, false, false,
$this->get('metadata_dir', $layer, 'pear.php.net'));
$this->_registry[$layer]->setConfig($this, false);
$this->_registry[$layer] = &new PEAR_Registry($phpdir);
$this->_registry[$layer]->setConfig($this);
$this->_regInitialized[$layer] = false;
} else {
unset($this->_registry[$layer]);
1644,7 → 1536,6
return;
}
}
 
$this->setChannels($this->_registry[$layer]->listChannels(), $merge);
$this->_regInitialized[$layer] = true;
$merge = true;
1651,7 → 1542,8
}
}
}
 
// {{{ setChannels()
/**
* Set the list of channels.
*
1665,19 → 1557,16
if (!is_array($channels)) {
return false;
}
 
if ($merge) {
$this->_channels = array_merge($this->_channels, $channels);
} else {
$this->_channels = $channels;
}
 
foreach ($channels as $channel) {
$channel = strtolower($channel);
if ($channel == 'pear.php.net') {
continue;
}
 
foreach ($this->layers as $layer) {
if (!isset($this->configuration[$layer]['__channels'])) {
$this->configuration[$layer]['__channels'] = array();
1688,10 → 1577,12
}
}
}
 
return true;
}
 
// }}}
// {{{ getType(key)
 
/**
* Get the type of a config value.
*
1711,10 → 1602,14
return false;
}
 
// }}}
// {{{ getDocs(key)
 
/**
* Get the documentation for a config value.
*
* @param string config key
*
* @return string documentation string
*
* @access public
1725,14 → 1620,16
if (isset($this->configuration_info[$key])) {
return $this->configuration_info[$key]['doc'];
}
 
return false;
}
// }}}
// {{{ getPrompt(key)
 
/**
* Get the short documentation for a config value.
*
* @param string config key
*
* @return string short documentation string
*
* @access public
1743,14 → 1640,16
if (isset($this->configuration_info[$key])) {
return $this->configuration_info[$key]['prompt'];
}
 
return false;
}
// }}}
// {{{ getGroup(key)
 
/**
* Get the parameter group for a config key.
*
* @param string config key
*
* @return string parameter group
*
* @access public
1761,10 → 1660,12
if (isset($this->configuration_info[$key])) {
return $this->configuration_info[$key]['group'];
}
 
return false;
}
 
// }}}
// {{{ getGroups()
 
/**
* Get the list of parameter groups.
*
1779,14 → 1680,17
foreach ($this->configuration_info as $key => $info) {
$tmp[$info['group']] = 1;
}
 
return array_keys($tmp);
}
 
// }}}
// {{{ getGroupKeys()
 
/**
* Get the list of the parameters in a group.
*
* @param string $group parameter group
*
* @return array list of parameters in $group
*
* @access public
1800,15 → 1704,18
$keys[] = $key;
}
}
 
return $keys;
}
 
// }}}
// {{{ getSetValues(key)
 
/**
* Get the list of allowed set values for a config value. Returns
* NULL for config values that are not sets.
*
* @param string config key
*
* @return array enumerated array of set values, or NULL if the
* config key is unknown or not a set
*
1826,13 → 1733,14
if (key($valid_set) === 0) {
return $valid_set;
}
 
return array_keys($valid_set);
}
 
return null;
}
 
// }}}
// {{{ getKeys()
 
/**
* Get all the current config keys.
*
1850,30 → 1758,29
$keys = array_merge($keys, $configs);
}
}
 
unset($test['__channels']);
$keys = array_merge($keys, $test);
 
}
return array_keys($keys);
}
 
// }}}
// {{{ remove(key, [layer])
 
/**
* Remove the a config key from a specific config layer.
*
* @param string config key
*
* @param string (optional) config layer
* @param string (optional) channel (defaults to default channel)
*
* @return bool TRUE on success, FALSE on failure
*
* @access public
*/
function remove($key, $layer = 'user', $channel = null)
function remove($key, $layer = 'user')
{
if ($channel === null) {
$channel = $this->getDefaultChannel();
}
 
$channel = $this->getDefaultChannel();
if ($channel !== 'pear.php.net') {
if (isset($this->configuration[$layer]['__channels'][$channel][$key])) {
unset($this->configuration[$layer]['__channels'][$channel][$key]);
1880,20 → 1787,23
return true;
}
}
 
if (isset($this->configuration[$layer][$key])) {
unset($this->configuration[$layer][$key]);
return true;
}
 
return false;
}
 
// }}}
// {{{ removeLayer(layer)
 
/**
* Temporarily remove an entire config layer. USE WITH CARE!
*
* @param string config key
*
* @param string (optional) config layer
*
* @return bool TRUE on success, FALSE on failure
*
* @access public
1904,14 → 1814,17
$this->configuration[$layer] = array();
return true;
}
 
return false;
}
 
// }}}
// {{{ store([layer])
 
/**
* Stores configuration data in a layer.
*
* @param string config layer to store
*
* @return bool TRUE on success, or PEAR error on failure
*
* @access public
1921,7 → 1834,29
return $this->writeConfigFile(null, $layer, $data);
}
 
// }}}
// {{{ toDefault(key)
 
/**
* Unset the user-defined value of a config key, reverting the
* value to the system-defined one.
*
* @param string config key
*
* @return bool TRUE on success, FALSE on failure
*
* @access public
*/
function toDefault($key)
{
trigger_error("PEAR_Config::toDefault() deprecated, use PEAR_Config::remove() instead", E_USER_NOTICE);
return $this->remove($key, 'user');
}
 
// }}}
// {{{ definedBy(key)
 
/**
* Tells what config layer that gets to define a key.
*
* @param string config key
1946,7 → 1881,6
return $layer;
}
}
 
if (isset($this->configuration[$layer][$key])) {
if ($returnchannel) {
return array('layer' => $layer, 'channel' => 'pear.php.net');
1954,14 → 1888,37
return $layer;
}
}
 
return '';
}
 
// }}}
// {{{ isDefaulted(key)
 
/**
* Tells whether a config value has a system-defined value.
*
* @param string config key
*
* @return bool
*
* @access public
*
* @deprecated
*/
function isDefaulted($key)
{
trigger_error("PEAR_Config::isDefaulted() deprecated, use PEAR_Config::definedBy() instead", E_USER_NOTICE);
return $this->definedBy($key) == 'system';
}
 
// }}}
// {{{ isDefined(key)
 
/**
* Tells whether a given key exists as a config value.
*
* @param string config key
*
* @return bool whether <config key> exists in this object
*
* @access public
1973,14 → 1930,17
return true;
}
}
 
return false;
}
 
// }}}
// {{{ isDefinedLayer(key)
 
/**
* Tells whether a given config layer exists.
*
* @param string config layer
*
* @return bool whether <config layer> exists in this object
*
* @access public
1990,6 → 1950,9
return isset($this->configuration[$layer]);
}
 
// }}}
// {{{ getLayers()
 
/**
* Returns the layers defined (except the 'default' one)
*
2002,10 → 1965,13
return array_keys($cf);
}
 
// }}}
// {{{ apiVersion()
function apiVersion()
{
return '1.1';
}
// }}}
 
/**
* @return PEAR_Registry
2012,7 → 1978,11
*/
function &getRegistry($use = null)
{
$layer = $use === null ? 'user' : $use;
if ($use === null) {
$layer = 'user';
} else {
$layer = $use;
}
if (isset($this->_registry[$layer])) {
return $this->_registry[$layer];
} elseif ($use === null && isset($this->_registry['system'])) {
2022,13 → 1992,12
} elseif ($use) {
$a = false;
return $a;
} else {
// only go here if null was passed in
echo "CRITICAL ERROR: Registry could not be initialized from any value";
exit(1);
}
 
// only go here if null was passed in
echo "CRITICAL ERROR: Registry could not be initialized from any value";
exit(1);
}
 
/**
* This is to allow customization like the use of installroot
* @param PEAR_Registry
2039,16 → 2008,13
if ($this->_noRegistry) {
return false;
}
 
if (!in_array($layer, array('user', 'system'))) {
return false;
}
 
$this->_registry[$layer] = &$reg;
if (is_object($reg)) {
$this->_registry[$layer]->setConfig($this, false);
$this->_registry[$layer]->setConfig($this);
}
 
return true;
}
 
2058,6 → 2024,15
}
 
/**
* @return PEAR_Remote
*/
function &getRemote()
{
$remote = &new PEAR_Remote($this);
return $remote;
}
 
/**
* @return PEAR_REST
*/
function &getREST($version, $options = array())
2066,8 → 2041,7
if (!class_exists($class = 'PEAR_REST_' . $version)) {
require_once 'PEAR/REST/' . $version . '.php';
}
 
$remote = new $class($this, $options);
$remote = &new $class($this, $options);
return $remote;
}
 
2080,12 → 2054,14
{
if (isset($this->_ftp)) {
return $this->_ftp;
} else {
$a = false;
return $a;
}
 
$a = false;
return $a;
}
 
// {{{ _prependPath($path, $prepend)
 
function _prependPath($path, $prepend)
{
if (strlen($prepend) > 0) {
2102,6 → 2078,7
}
return $path;
}
// }}}
 
/**
* @param string|false installation directory to prepend to all _dir variables, or false to
2120,12 → 2097,12
continue;
}
$this->_registry[$layer] =
new PEAR_Registry(
$this->get('php_dir', $layer, 'pear.php.net'), false, false,
$this->get('metadata_dir', $layer, 'pear.php.net'));
$this->_registry[$layer]->setConfig($this, false);
&new PEAR_Registry($this->get('php_dir', $layer, 'pear.php.net'));
$this->_registry[$layer]->setConfig($this);
$this->_regInitialized[$layer] = false;
}
}
}
}
 
?>
/trunk/bibliotheque/pear/PEAR/Registry.php
4,13 → 4,20
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Registry.php,v 1.159 2006/12/20 19:34:03 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
21,10 → 28,10
require_once 'PEAR.php';
require_once 'PEAR/DependencyDB.php';
 
define('PEAR_REGISTRY_ERROR_LOCK', -2);
define('PEAR_REGISTRY_ERROR_FORMAT', -3);
define('PEAR_REGISTRY_ERROR_FILE', -4);
define('PEAR_REGISTRY_ERROR_CONFLICT', -5);
define('PEAR_REGISTRY_ERROR_LOCK', -2);
define('PEAR_REGISTRY_ERROR_FORMAT', -3);
define('PEAR_REGISTRY_ERROR_FILE', -4);
define('PEAR_REGISTRY_ERROR_CONFLICT', -5);
define('PEAR_REGISTRY_ERROR_CHANNEL_FILE', -6);
 
/**
34,14 → 41,16
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_Registry extends PEAR
{
// {{{ properties
 
/**
* File containing all channel information.
* @var string
103,11 → 112,6
var $_peclChannel;
 
/**
* @var false|PEAR_ChannelFile
*/
var $_docChannel;
 
/**
* @var PEAR_DependencyDB
*/
var $_dependencyDB;
116,7 → 120,10
* @var PEAR_Config
*/
var $_config;
// }}}
 
// {{{ constructor
 
/**
* PEAR_Registry constructor.
*
130,61 → 137,43
*
* @access public
*/
function __construct($pear_install_dir = PEAR_INSTALL_DIR, $pear_channel = false,
$pecl_channel = false, $pear_metadata_dir = '')
function PEAR_Registry($pear_install_dir = PEAR_INSTALL_DIR, $pear_channel = false,
$pecl_channel = false)
{
parent::__construct();
$this->setInstallDir($pear_install_dir, $pear_metadata_dir);
parent::PEAR();
$ds = DIRECTORY_SEPARATOR;
$this->install_dir = $pear_install_dir;
$this->channelsdir = $pear_install_dir.$ds.'.channels';
$this->statedir = $pear_install_dir.$ds.'.registry';
$this->filemap = $pear_install_dir.$ds.'.filemap';
$this->lockfile = $pear_install_dir.$ds.'.lock';
$this->_pearChannel = $pear_channel;
$this->_peclChannel = $pecl_channel;
$this->_config = false;
$this->_config = false;
}
 
function setInstallDir($pear_install_dir = PEAR_INSTALL_DIR, $pear_metadata_dir = '')
{
$ds = DIRECTORY_SEPARATOR;
$this->install_dir = $pear_install_dir;
if (!$pear_metadata_dir) {
$pear_metadata_dir = $pear_install_dir;
}
$this->channelsdir = $pear_metadata_dir.$ds.'.channels';
$this->statedir = $pear_metadata_dir.$ds.'.registry';
$this->filemap = $pear_metadata_dir.$ds.'.filemap';
$this->lockfile = $pear_metadata_dir.$ds.'.lock';
}
 
function hasWriteAccess()
{
if (!file_exists($this->install_dir)) {
$dir = $this->install_dir;
while ($dir && $dir != '.') {
$olddir = $dir;
$dir = dirname($dir);
$dir = dirname($dir); // cd ..
if ($dir != '.' && file_exists($dir)) {
if (is_writeable($dir)) {
return true;
} else {
return false;
}
 
return false;
}
 
if ($dir == $olddir) { // this can happen in safe mode
return @is_writable($dir);
}
}
 
return false;
}
 
return is_writeable($this->install_dir);
}
 
function setConfig(&$config, $resetInstallDir = true)
function setConfig(&$config)
{
$this->_config = &$config;
if ($resetInstallDir) {
$this->setInstallDir($config->get('php_dir'), $config->get('metadata_dir'));
}
}
 
function _initializeChannelDirs()
196,7 → 185,6
if (!is_dir($this->channelsdir) ||
!file_exists($this->channelsdir . $ds . 'pear.php.net.reg') ||
!file_exists($this->channelsdir . $ds . 'pecl.php.net.reg') ||
!file_exists($this->channelsdir . $ds . 'doc.php.net.reg') ||
!file_exists($this->channelsdir . $ds . '__uri.reg')) {
if (!file_exists($this->channelsdir . $ds . 'pear.php.net.reg')) {
$pear_channel = $this->_pearChannel;
204,8 → 192,8
if (!class_exists('PEAR_ChannelFile')) {
require_once 'PEAR/ChannelFile.php';
}
 
$pear_channel = new PEAR_ChannelFile;
$pear_channel->setName('pear.php.net');
$pear_channel->setAlias('pear');
$pear_channel->setServer('pear.php.net');
$pear_channel->setSummary('PHP Extension and Application Repository');
212,17 → 200,13
$pear_channel->setDefaultPEARProtocols();
$pear_channel->setBaseURL('REST1.0', 'http://pear.php.net/rest/');
$pear_channel->setBaseURL('REST1.1', 'http://pear.php.net/rest/');
$pear_channel->setBaseURL('REST1.3', 'http://pear.php.net/rest/');
//$pear_channel->setBaseURL('REST1.4', 'http://pear.php.net/rest/');
} else {
$pear_channel->setServer('pear.php.net');
$pear_channel->setName('pear.php.net');
$pear_channel->setAlias('pear');
}
 
$pear_channel->validate();
$this->_addChannel($pear_channel);
}
 
if (!file_exists($this->channelsdir . $ds . 'pecl.php.net.reg')) {
$pecl_channel = $this->_peclChannel;
if (!is_a($pecl_channel, 'PEAR_ChannelFile') || !$pecl_channel->validate()) {
229,8 → 213,8
if (!class_exists('PEAR_ChannelFile')) {
require_once 'PEAR/ChannelFile.php';
}
 
$pecl_channel = new PEAR_ChannelFile;
$pecl_channel->setName('pecl.php.net');
$pecl_channel->setAlias('pecl');
$pecl_channel->setServer('pecl.php.net');
$pecl_channel->setSummary('PHP Extension Community Library');
239,53 → 223,24
$pecl_channel->setBaseURL('REST1.1', 'http://pecl.php.net/rest/');
$pecl_channel->setValidationPackage('PEAR_Validator_PECL', '1.0');
} else {
$pecl_channel->setServer('pecl.php.net');
$pecl_channel->setName('pecl.php.net');
$pecl_channel->setAlias('pecl');
}
 
$pecl_channel->validate();
$this->_addChannel($pecl_channel);
}
 
if (!file_exists($this->channelsdir . $ds . 'doc.php.net.reg')) {
$doc_channel = $this->_docChannel;
if (!is_a($doc_channel, 'PEAR_ChannelFile') || !$doc_channel->validate()) {
if (!class_exists('PEAR_ChannelFile')) {
require_once 'PEAR/ChannelFile.php';
}
 
$doc_channel = new PEAR_ChannelFile;
$doc_channel->setAlias('phpdocs');
$doc_channel->setServer('doc.php.net');
$doc_channel->setSummary('PHP Documentation Team');
$doc_channel->setDefaultPEARProtocols();
$doc_channel->setBaseURL('REST1.0', 'http://doc.php.net/rest/');
$doc_channel->setBaseURL('REST1.1', 'http://doc.php.net/rest/');
$doc_channel->setBaseURL('REST1.3', 'http://doc.php.net/rest/');
} else {
$doc_channel->setServer('doc.php.net');
$doc_channel->setAlias('doc');
}
 
$doc_channel->validate();
$this->_addChannel($doc_channel);
}
 
if (!file_exists($this->channelsdir . $ds . '__uri.reg')) {
if (!class_exists('PEAR_ChannelFile')) {
require_once 'PEAR/ChannelFile.php';
}
 
$private = new PEAR_ChannelFile;
$private->setName('__uri');
$private->setDefaultPEARProtocols();
$private->setBaseURL('REST1.0', '****');
$private->addFunction('xmlrpc', '1.0', '****');
$private->setSummary('Pseudo-channel for static packages');
$this->_addChannel($private);
}
$this->_rebuildFileMap();
}
 
$running = false;
}
}
299,13 → 254,12
$handle = opendir($this->statedir)) {
$dest = $this->statedir . $ds;
while (false !== ($file = readdir($handle))) {
if (preg_match('/^.*[A-Z].*\.reg\\z/', $file)) {
if (preg_match('/^.*[A-Z].*\.reg$/', $file)) {
rename($dest . $file, $dest . strtolower($file));
}
}
closedir($handle);
}
 
$this->_initializeChannelDirs();
if (!file_exists($this->filemap)) {
$this->_rebuildFileMap();
320,22 → 274,24
if (!$initializing) {
$initializing = true;
if (!$this->_config) { // never used?
$file = OS_WINDOWS ? 'pear.ini' : '.pearrc';
$this->_config = new PEAR_Config($this->statedir . DIRECTORY_SEPARATOR .
if (OS_WINDOWS) {
$file = 'pear.ini';
} else {
$file = '.pearrc';
}
$this->_config = &new PEAR_Config($this->statedir . DIRECTORY_SEPARATOR .
$file);
$this->_config->setRegistry($this);
$this->_config->set('php_dir', $this->install_dir);
}
 
$this->_dependencyDB = &PEAR_DependencyDB::singleton($this->_config);
if (PEAR::isError($this->_dependencyDB)) {
// attempt to recover by removing the dep db
if (file_exists($this->_config->get('metadata_dir', null, 'pear.php.net') .
if (file_exists($this->_config->get('php_dir', null, 'pear.php.net') .
DIRECTORY_SEPARATOR . '.depdb')) {
@unlink($this->_config->get('metadata_dir', null, 'pear.php.net') .
@unlink($this->_config->get('php_dir', null, 'pear.php.net') .
DIRECTORY_SEPARATOR . '.depdb');
}
 
$this->_dependencyDB = &PEAR_DependencyDB::singleton($this->_config);
if (PEAR::isError($this->_dependencyDB)) {
echo $this->_dependencyDB->getMessage();
343,11 → 299,12
exit(1);
}
}
 
$initializing = false;
}
}
}
// }}}
// {{{ destructor
 
/**
* PEAR_Registry destructor. Makes sure no locks are forgotten.
362,6 → 319,10
}
}
 
// }}}
 
// {{{ _assertStateDir()
 
/**
* Make sure the directory where we keep registry files exists.
*
375,13 → 336,11
if ($channel && $this->_getChannelFromAlias($channel) != 'pear.php.net') {
return $this->_assertChannelStateDir($channel);
}
 
static $init = false;
if (!file_exists($this->statedir)) {
if (!$this->hasWriteAccess()) {
return false;
}
 
require_once 'System.php';
if (!System::mkdir(array('-p', $this->statedir))) {
return $this->raiseError("could not create directory '{$this->statedir}'");
391,12 → 350,10
return $this->raiseError('Cannot create directory ' . $this->statedir . ', ' .
'it already exists and is not a directory');
}
 
$ds = DIRECTORY_SEPARATOR;
if (!file_exists($this->channelsdir)) {
if (!file_exists($this->channelsdir . $ds . 'pear.php.net.reg') ||
!file_exists($this->channelsdir . $ds . 'pecl.php.net.reg') ||
!file_exists($this->channelsdir . $ds . 'doc.php.net.reg') ||
!file_exists($this->channelsdir . $ds . '__uri.reg')) {
$init = true;
}
404,7 → 361,6
return $this->raiseError('Cannot create directory ' . $this->channelsdir . ', ' .
'it already exists and is not a directory');
}
 
if ($init) {
static $running = false;
if (!$running) {
416,10 → 372,12
} else {
$this->_initializeDepDB();
}
 
return true;
}
 
// }}}
// {{{ _assertChannelStateDir()
 
/**
* Make sure the directory where we keep registry files exists for a non-standard channel.
*
438,18 → 396,15
}
return $this->_assertStateDir($channel);
}
 
$channelDir = $this->_channelDirectoryName($channel);
if (!is_dir($this->channelsdir) ||
!file_exists($this->channelsdir . $ds . 'pear.php.net.reg')) {
$this->_initializeChannelDirs();
}
 
if (!file_exists($channelDir)) {
if (!$this->hasWriteAccess()) {
return false;
}
 
require_once 'System.php';
if (!System::mkdir(array('-p', $channelDir))) {
return $this->raiseError("could not create directory '" . $channelDir .
459,10 → 414,12
return $this->raiseError("could not create directory '" . $channelDir .
"', already exists and is not a directory");
}
 
return true;
}
 
// }}}
// {{{ _assertChannelDir()
 
/**
* Make sure the directory where we keep registry files for channels exists
*
477,7 → 434,6
if (!$this->hasWriteAccess()) {
return false;
}
 
require_once 'System.php';
if (!System::mkdir(array('-p', $this->channelsdir))) {
return $this->raiseError("could not create directory '{$this->channelsdir}'");
485,13 → 441,12
} elseif (!is_dir($this->channelsdir)) {
return $this->raiseError("could not create directory '{$this->channelsdir}" .
"', it already exists and is not a directory");
}
 
if (!file_exists($this->channelsdir . DIRECTORY_SEPARATOR . '.alias')) {
if (!$this->hasWriteAccess()) {
return false;
}
 
require_once 'System.php';
if (!System::mkdir(array('-p', $this->channelsdir . DIRECTORY_SEPARATOR . '.alias'))) {
return $this->raiseError("could not create directory '{$this->channelsdir}/.alias'");
499,11 → 454,14
} elseif (!is_dir($this->channelsdir . DIRECTORY_SEPARATOR . '.alias')) {
return $this->raiseError("could not create directory '{$this->channelsdir}" .
"/.alias', it already exists and is not a directory");
}
 
return true;
}
 
// }}}
// {{{ _packageFileName()
 
/**
* Get the name of the file where data for a given package is stored.
*
520,10 → 478,12
return $this->_channelDirectoryName($channel) . DIRECTORY_SEPARATOR .
strtolower($package) . '.reg';
}
 
return $this->statedir . DIRECTORY_SEPARATOR . strtolower($package) . '.reg';
}
 
// }}}
// {{{ _channelFileName()
 
/**
* Get the name of the file where data for a given channel is stored.
* @param string channel name
540,6 → 500,9
strtolower($channel)) . '.reg';
}
 
// }}}
// {{{ getChannelAliasFileName()
 
/**
* @param string
* @return string
550,6 → 513,9
DIRECTORY_SEPARATOR . str_replace('/', '_', strtolower($alias)) . '.txt';
}
 
// }}}
// {{{ _getChannelFromAlias()
 
/**
* Get the name of a channel from its alias
*/
559,31 → 525,25
if ($channel == 'pear.php.net') {
return 'pear.php.net';
}
 
if ($channel == 'pecl.php.net') {
return 'pecl.php.net';
}
 
if ($channel == 'doc.php.net') {
return 'doc.php.net';
}
 
if ($channel == '__uri') {
return '__uri';
}
 
return false;
}
 
$channel = strtolower($channel);
if (file_exists($this->_getChannelAliasFileName($channel))) {
// translate an alias to an actual channel
return implode('', file($this->_getChannelAliasFileName($channel)));
} else {
return $channel;
}
}
// }}}
// {{{ _getChannelFromAlias()
 
return $channel;
}
 
/**
* Get the alias of a channel from its alias or its name
*/
593,25 → 553,19
if ($channel == 'pear.php.net') {
return 'pear';
}
 
if ($channel == 'pecl.php.net') {
return 'pecl';
}
 
if ($channel == 'doc.php.net') {
return 'phpdocs';
}
 
return false;
}
 
$channel = $this->_getChannel($channel);
if (PEAR::isError($channel)) {
return $channel;
}
 
return $channel->getAlias();
}
}
// }}}
// {{{ _channelDirectoryName()
 
/**
* Get the name of the file where data for a given package is stored.
627,79 → 581,84
{
if (!$channel || $this->_getChannelFromAlias($channel) == 'pear.php.net') {
return $this->statedir;
} else {
$ch = $this->_getChannelFromAlias($channel);
if (!$ch) {
$ch = $channel;
}
return $this->statedir . DIRECTORY_SEPARATOR . strtolower('.channel.' .
str_replace('/', '_', $ch));
}
}
 
$ch = $this->_getChannelFromAlias($channel);
if (!$ch) {
$ch = $channel;
}
// }}}
// {{{ _openPackageFile()
 
return $this->statedir . DIRECTORY_SEPARATOR . strtolower('.channel.' .
str_replace('/', '_', $ch));
}
 
function _openPackageFile($package, $mode, $channel = false)
{
if (!$this->_assertStateDir($channel)) {
return null;
}
 
if (!in_array($mode, array('r', 'rb')) && !$this->hasWriteAccess()) {
return null;
}
 
$file = $this->_packageFileName($package, $channel);
if (!file_exists($file) && $mode == 'r' || $mode == 'rb') {
return null;
}
 
$fp = @fopen($file, $mode);
if (!$fp) {
return null;
}
 
return $fp;
}
 
// }}}
// {{{ _closePackageFile()
 
function _closePackageFile($fp)
{
fclose($fp);
}
 
// }}}
// {{{ _openChannelFile()
 
function _openChannelFile($channel, $mode)
{
if (!$this->_assertChannelDir()) {
return null;
}
 
if (!in_array($mode, array('r', 'rb')) && !$this->hasWriteAccess()) {
return null;
}
 
$file = $this->_channelFileName($channel);
if (!file_exists($file) && $mode == 'r' || $mode == 'rb') {
return null;
}
 
$fp = @fopen($file, $mode);
if (!$fp) {
return null;
}
 
return $fp;
}
 
// }}}
// {{{ _closePackageFile()
 
function _closeChannelFile($fp)
{
fclose($fp);
}
 
// }}}
// {{{ _rebuildFileMap()
 
function _rebuildFileMap()
{
if (!class_exists('PEAR_Installer_Role')) {
require_once 'PEAR/Installer/Role.php';
}
 
$channels = $this->_listAllPackages();
$files = array();
foreach ($channels as $channel => $packages) {
709,43 → 668,37
if (!is_array($filelist)) {
continue;
}
 
foreach ($filelist as $name => $attrs) {
if (isset($attrs['attribs'])) {
$attrs = $attrs['attribs'];
}
 
// it is possible for conflicting packages in different channels to
// conflict with data files/doc files
if ($name == 'dirtree') {
continue;
}
 
if (isset($attrs['role']) && !in_array($attrs['role'],
PEAR_Installer_Role::getInstallableRoles())) {
// these are not installed
continue;
}
 
if (isset($attrs['role']) && !in_array($attrs['role'],
PEAR_Installer_Role::getBaseinstallRoles())) {
$attrs['baseinstalldir'] = $package;
}
 
if (isset($attrs['baseinstalldir'])) {
$file = $attrs['baseinstalldir'].DIRECTORY_SEPARATOR.$name;
} else {
$file = $name;
}
 
$file = preg_replace(',^/+,', '', $file);
if ($channel != 'pear.php.net') {
if (!isset($files[$attrs['role']])) {
$files[$attrs['role']] = array();
}
$files[$attrs['role']][$file] = array(strtolower($channel),
strtolower($package));
} else {
if (!is_array($files)) {
$file = array();
}
if (!isset($files[$attrs['role']])) {
$files[$attrs['role']] = array();
}
754,18 → 707,14
}
}
}
 
 
$this->_assertStateDir();
if (!$this->hasWriteAccess()) {
return false;
}
 
$fp = @fopen($this->filemap, 'wb');
if (!$fp) {
return false;
}
 
$this->filemap_cache = $files;
fwrite($fp, serialize($files));
fclose($fp);
772,30 → 721,36
return true;
}
 
// }}}
// {{{ _readFileMap()
 
function _readFileMap()
{
if (!file_exists($this->filemap)) {
return array();
}
 
$fp = @fopen($this->filemap, 'r');
if (!$fp) {
return $this->raiseError('PEAR_Registry: could not open filemap "' . $this->filemap . '"', PEAR_REGISTRY_ERROR_FILE, null, null, $php_errormsg);
}
 
clearstatcache();
$rt = get_magic_quotes_runtime();
set_magic_quotes_runtime(0);
$fsize = filesize($this->filemap);
fclose($fp);
$data = file_get_contents($this->filemap);
set_magic_quotes_runtime($rt);
$tmp = unserialize($data);
if (!$tmp && $fsize > 7) {
return $this->raiseError('PEAR_Registry: invalid filemap data', PEAR_REGISTRY_ERROR_FORMAT, null, null, $data);
}
 
$this->filemap_cache = $tmp;
return true;
}
 
// }}}
// {{{ _lock()
 
/**
* Lock the registry.
*
810,60 → 765,52
*/
function _lock($mode = LOCK_EX)
{
if (stristr(php_uname(), 'Windows 9')) {
return true;
}
 
if ($mode != LOCK_UN && is_resource($this->lock_fp)) {
// XXX does not check type of lock (LOCK_SH/LOCK_EX)
return true;
}
 
if (!$this->_assertStateDir()) {
if ($mode == LOCK_EX) {
return $this->raiseError('Registry directory is not writeable by the current user');
if (!eregi('Windows 9', php_uname())) {
if ($mode != LOCK_UN && is_resource($this->lock_fp)) {
// XXX does not check type of lock (LOCK_SH/LOCK_EX)
return true;
}
if (!$this->_assertStateDir()) {
if ($mode == LOCK_EX) {
return $this->raiseError('Registry directory is not writeable by the current user');
} else {
return true;
}
}
$open_mode = 'w';
// XXX People reported problems with LOCK_SH and 'w'
if ($mode === LOCK_SH || $mode === LOCK_UN) {
if (!file_exists($this->lockfile)) {
touch($this->lockfile);
}
$open_mode = 'r';
}
 
return true;
}
 
$open_mode = 'w';
// XXX People reported problems with LOCK_SH and 'w'
if ($mode === LOCK_SH || $mode === LOCK_UN) {
if (!file_exists($this->lockfile)) {
touch($this->lockfile);
if (!is_resource($this->lock_fp)) {
$this->lock_fp = @fopen($this->lockfile, $open_mode);
}
$open_mode = 'r';
}
 
if (!is_resource($this->lock_fp)) {
$this->lock_fp = @fopen($this->lockfile, $open_mode);
}
 
if (!is_resource($this->lock_fp)) {
$this->lock_fp = null;
return $this->raiseError("could not create lock file" .
(isset($php_errormsg) ? ": " . $php_errormsg : ""));
}
 
if (!(int)flock($this->lock_fp, $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;
if (!is_resource($this->lock_fp)) {
return $this->raiseError("could not create lock file" .
(isset($php_errormsg) ? ": " . $php_errormsg : ""));
}
 
//is resource at this point, close it on error.
fclose($this->lock_fp);
$this->lock_fp = null;
return $this->raiseError("could not acquire $str lock ($this->lockfile)",
PEAR_REGISTRY_ERROR_LOCK);
if (!(int)flock($this->lock_fp, $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 $this->raiseError("could not acquire $str lock ($this->lockfile)",
PEAR_REGISTRY_ERROR_LOCK);
}
}
 
return true;
}
 
// }}}
// {{{ _unlock()
 
function _unlock()
{
$ret = $this->_lock(LOCK_UN);
870,19 → 817,23
if (is_resource($this->lock_fp)) {
fclose($this->lock_fp);
}
 
$this->lock_fp = null;
return $ret;
}
 
// }}}
// {{{ _packageExists()
 
function _packageExists($package, $channel = false)
{
return file_exists($this->_packageFileName($package, $channel));
}
 
// }}}
// {{{ _channelExists()
 
/**
* Determine whether a channel exists in the registry
*
* @param string Channel name
* @param bool if true, then aliases will be ignored
* @return boolean
893,42 → 844,15
if (!$a && $channel == 'pear.php.net') {
return true;
}
 
if (!$a && $channel == 'pecl.php.net') {
return true;
}
 
if (!$a && $channel == 'doc.php.net') {
return true;
}
 
return $a;
}
 
/**
* Determine whether a mirror exists within the deafult channel in the registry
*
* @param string Channel name
* @param string Mirror name
*
* @return boolean
*/
function _mirrorExists($channel, $mirror)
{
$data = $this->_channelInfo($channel);
if (!isset($data['servers']['mirror'])) {
return false;
}
// }}}
// {{{ _addChannel()
 
foreach ($data['servers']['mirror'] as $m) {
if ($m['attribs']['host'] == $mirror) {
return true;
}
}
 
return false;
}
 
/**
* @param PEAR_ChannelFile Channel object
* @param donotuse
940,21 → 864,17
if (!is_a($channel, 'PEAR_ChannelFile')) {
return false;
}
 
if (!$channel->validate()) {
return false;
}
 
if (file_exists($this->_channelFileName($channel->getName()))) {
if (!$update) {
return false;
}
 
$checker = $this->_getChannel($channel->getName());
if (PEAR::isError($checker)) {
return $checker;
}
 
if ($channel->getAlias() != $checker->getAlias()) {
if (file_exists($this->_getChannelAliasFileName($checker->getAlias()))) {
@unlink($this->_getChannelAliasFileName($checker->getAlias()));
961,49 → 881,40
}
}
} else {
if ($update && !in_array($channel->getName(), array('pear.php.net', 'pecl.php.net', 'doc.php.net'))) {
if ($update && !in_array($channel->getName(), array('pear.php.net', 'pecl.php.net'))) {
return false;
}
}
 
$ret = $this->_assertChannelDir();
if (PEAR::isError($ret)) {
return $ret;
}
 
$ret = $this->_assertChannelStateDir($channel->getName());
if (PEAR::isError($ret)) {
return $ret;
}
 
if ($channel->getAlias() != $channel->getName()) {
if (file_exists($this->_getChannelAliasFileName($channel->getAlias())) &&
$this->_getChannelFromAlias($channel->getAlias()) != $channel->getName()) {
$channel->setAlias($channel->getName());
}
 
if (!$this->hasWriteAccess()) {
return false;
}
 
$fp = @fopen($this->_getChannelAliasFileName($channel->getAlias()), 'w');
if (!$fp) {
return false;
}
 
fwrite($fp, $channel->getName());
fclose($fp);
}
 
if (!$this->hasWriteAccess()) {
return false;
}
 
$fp = @fopen($this->_channelFileName($channel->getName()), 'wb');
if (!$fp) {
return false;
}
 
$info = $channel->toArray();
if ($lastmodified) {
$info['_lastmodified'] = $lastmodified;
1010,12 → 921,14
} else {
$info['_lastmodified'] = date('r');
}
 
fwrite($fp, serialize($info));
fclose($fp);
return true;
}
 
// }}}
// {{{ _deleteChannel()
 
/**
* Deletion fails if there are any packages installed from the channel
* @param string|PEAR_ChannelFile channel name
1024,51 → 937,39
function _deleteChannel($channel)
{
if (!is_string($channel)) {
if (!is_a($channel, 'PEAR_ChannelFile')) {
if (is_a($channel, 'PEAR_ChannelFile')) {
if (!$channel->validate()) {
return false;
}
$channel = $channel->getName();
} else {
return false;
}
 
if (!$channel->validate()) {
return false;
}
$channel = $channel->getName();
}
 
if ($this->_getChannelFromAlias($channel) == '__uri') {
return false;
}
 
if ($this->_getChannelFromAlias($channel) == 'pecl.php.net') {
return false;
}
 
if ($this->_getChannelFromAlias($channel) == 'doc.php.net') {
return false;
}
 
if (!$this->_channelExists($channel)) {
return false;
}
 
if (!$channel || $this->_getChannelFromAlias($channel) == 'pear.php.net') {
return false;
}
 
$channel = $this->_getChannelFromAlias($channel);
if ($channel == 'pear.php.net') {
return false;
}
 
$test = $this->_listChannelPackages($channel);
if (count($test)) {
return false;
}
 
$test = @rmdir($this->_channelDirectoryName($channel));
if (!$test) {
return false;
}
 
$file = $this->_getChannelAliasFileName($this->_getAlias($channel));
if (file_exists($file)) {
$test = @unlink($file);
1076,16 → 977,17
return false;
}
}
 
$file = $this->_channelFileName($channel);
$ret = true;
if (file_exists($file)) {
$ret = @unlink($file);
}
 
return $ret;
}
 
// }}}
// {{{ _isChannelAlias()
 
/**
* Determine whether a channel exists in the registry
* @param string Channel Alias
1096,6 → 998,9
return file_exists($this->_getChannelAliasFileName($alias));
}
 
// }}}
// {{{ _packageInfo()
 
/**
* @param string|null
* @param string|null
1117,10 → 1022,8
$ret[$channel][] = $this->_packageInfo($package, null, $channel);
}
}
 
return $ret;
}
 
$ps = $this->_listPackages($channel);
if (!count($ps)) {
return array();
1129,32 → 1032,33
$ps, array_fill(0, count($ps), null),
array_fill(0, count($ps), $channel));
}
 
$fp = $this->_openPackageFile($package, 'r', $channel);
if ($fp === null) {
return null;
}
 
$rt = get_magic_quotes_runtime();
set_magic_quotes_runtime(0);
clearstatcache();
$this->_closePackageFile($fp);
$data = file_get_contents($this->_packageFileName($package, $channel));
set_magic_quotes_runtime($rt);
$data = unserialize($data);
if ($key === null) {
return $data;
}
 
// compatibility for package.xml version 2.0
if (isset($data['old'][$key])) {
return $data['old'][$key];
}
 
if (isset($data[$key])) {
return $data[$key];
}
 
return null;
}
 
// }}}
// {{{ _channelInfo()
 
/**
* @param string Channel name
* @param bool whether to strictly retrieve info of channels, not just aliases
1165,83 → 1069,73
if (!$this->_channelExists($channel, $noaliases)) {
return null;
}
 
$fp = $this->_openChannelFile($channel, 'r');
if ($fp === null) {
return null;
}
 
$rt = get_magic_quotes_runtime();
set_magic_quotes_runtime(0);
clearstatcache();
$this->_closeChannelFile($fp);
$data = file_get_contents($this->_channelFileName($channel));
set_magic_quotes_runtime($rt);
$data = unserialize($data);
return $data;
}
 
// }}}
// {{{ _listChannels()
 
function _listChannels()
{
$channellist = array();
if (!file_exists($this->channelsdir) || !is_dir($this->channelsdir)) {
return array('pear.php.net', 'pecl.php.net', 'doc.php.net', '__uri');
return array('pear.php.net', 'pecl.php.net', '__uri');
}
 
$dp = opendir($this->channelsdir);
while ($ent = readdir($dp)) {
if ($ent{0} == '.' || substr($ent, -4) != '.reg') {
continue;
}
 
if ($ent == '__uri.reg') {
$channellist[] = '__uri';
continue;
}
 
$channellist[] = str_replace('_', '/', substr($ent, 0, -4));
}
 
closedir($dp);
if (!in_array('pear.php.net', $channellist)) {
$channellist[] = 'pear.php.net';
}
 
if (!in_array('pecl.php.net', $channellist)) {
$channellist[] = 'pecl.php.net';
}
 
if (!in_array('doc.php.net', $channellist)) {
$channellist[] = 'doc.php.net';
}
 
 
if (!in_array('__uri', $channellist)) {
$channellist[] = '__uri';
}
 
natsort($channellist);
return $channellist;
}
 
// }}}
// {{{ _listPackages()
 
function _listPackages($channel = false)
{
if ($channel && $this->_getChannelFromAlias($channel) != 'pear.php.net') {
return $this->_listChannelPackages($channel);
}
 
if (!file_exists($this->statedir) || !is_dir($this->statedir)) {
return array();
}
 
$pkglist = array();
$dp = opendir($this->statedir);
if (!$dp) {
return $pkglist;
}
 
while ($ent = readdir($dp)) {
if ($ent{0} == '.' || substr($ent, -4) != '.reg') {
continue;
}
 
$pkglist[] = substr($ent, 0, -4);
}
closedir($dp);
1248,6 → 1142,9
return $pkglist;
}
 
// }}}
// {{{ _listChannelPackages()
 
function _listChannelPackages($channel)
{
$pkglist = array();
1255,12 → 1152,10
!is_dir($this->_channelDirectoryName($channel))) {
return array();
}
 
$dp = opendir($this->_channelDirectoryName($channel));
if (!$dp) {
return $pkglist;
}
 
while ($ent = readdir($dp)) {
if ($ent{0} == '.' || substr($ent, -4) != '.reg') {
continue;
1267,11 → 1162,12
}
$pkglist[] = substr($ent, 0, -4);
}
 
closedir($dp);
return $pkglist;
}
 
// }}}
function _listAllPackages()
{
$ret = array();
1278,7 → 1174,6
foreach ($this->_listChannels() as $channel) {
$ret[$channel] = $this->_listPackages($channel);
}
 
return $ret;
}
 
1294,12 → 1189,10
if ($this->_packageExists($package)) {
return false;
}
 
$fp = $this->_openPackageFile($package, 'wb');
if ($fp === null) {
return false;
}
 
$info['_lastmodified'] = time();
fwrite($fp, serialize($info));
$this->_closePackageFile($fp);
1306,7 → 1199,6
if (isset($info['filelist'])) {
$this->_rebuildFileMap();
}
 
return true;
}
 
1317,10 → 1209,6
*/
function _addPackage2($info)
{
if (!is_a($info, 'PEAR_PackageFile_v1') && !is_a($info, 'PEAR_PackageFile_v2')) {
return false;
}
 
if (!$info->validate()) {
if (class_exists('PEAR_Common')) {
$ui = PEAR_Frontend::singleton();
1332,7 → 1220,6
}
return false;
}
 
$channel = $info->getChannel();
$package = $info->getPackage();
$save = $info;
1339,21 → 1226,17
if ($this->_packageExists($package, $channel)) {
return false;
}
 
if (!$this->_channelExists($channel, true)) {
return false;
}
 
$info = $info->toArray(true);
if (!$info) {
return false;
}
 
$fp = $this->_openPackageFile($package, 'wb', $channel);
if ($fp === null) {
return false;
}
 
$info['_lastmodified'] = time();
fwrite($fp, serialize($info));
$this->_closePackageFile($fp);
1373,17 → 1256,14
if (empty($oldinfo)) {
return false;
}
 
$fp = $this->_openPackageFile($package, 'w');
if ($fp === null) {
return false;
}
 
if (is_object($info)) {
$info = $info->toArray();
}
$info['_lastmodified'] = time();
 
$newinfo = $info;
if ($merge) {
$info = array_merge($oldinfo, $info);
1390,13 → 1270,11
} else {
$diff = $info;
}
 
fwrite($fp, serialize($info));
$this->_closePackageFile($fp);
if (isset($newinfo['filelist'])) {
$this->_rebuildFileMap();
}
 
return true;
}
 
1410,12 → 1288,10
if (!$this->_packageExists($info->getPackage(), $info->getChannel())) {
return false;
}
 
$fp = $this->_openPackageFile($info->getPackage(), 'w', $info->getChannel());
if ($fp === null) {
return false;
}
 
$save = $info;
$info = $save->getArray(true);
$info['_lastmodified'] = time();
1437,18 → 1313,15
if ($info === null) {
return $info;
}
 
$a = $this->_config;
if (!$a) {
$this->_config = new PEAR_Config;
$this->_config = &new PEAR_Config;
$this->_config->set('php_dir', $this->statedir);
}
 
if (!class_exists('PEAR_PackageFile')) {
require_once 'PEAR/PackageFile.php';
}
 
$pkg = new PEAR_PackageFile($this->_config);
$pkg = &new PEAR_PackageFile($this->_config);
$pf = &$pkg->fromArray($info);
return $pf;
}
1468,41 → 1341,33
if (!class_exists('PEAR_ChannelFile')) {
require_once 'PEAR/ChannelFile.php';
}
 
$ch = &PEAR_ChannelFile::fromArrayWithErrors($chinfo);
}
}
 
if ($ch) {
if ($ch->validate()) {
return $ch;
}
 
foreach ($ch->getErrors(true) as $err) {
$message = $err['message'] . "\n";
}
 
$ch = PEAR::raiseError($message);
return $ch;
}
 
if ($this->_getChannelFromAlias($channel) == 'pear.php.net') {
// the registry is not properly set up, so use defaults
if (!class_exists('PEAR_ChannelFile')) {
require_once 'PEAR/ChannelFile.php';
}
 
$pear_channel = new PEAR_ChannelFile;
$pear_channel->setServer('pear.php.net');
$pear_channel->setName('pear.php.net');
$pear_channel->setAlias('pear');
$pear_channel->setSummary('PHP Extension and Application Repository');
$pear_channel->setDefaultPEARProtocols();
$pear_channel->setBaseURL('REST1.0', 'http://pear.php.net/rest/');
$pear_channel->setBaseURL('REST1.1', 'http://pear.php.net/rest/');
$pear_channel->setBaseURL('REST1.3', 'http://pear.php.net/rest/');
return $pear_channel;
}
 
if ($this->_getChannelFromAlias($channel) == 'pecl.php.net') {
// the registry is not properly set up, so use defaults
if (!class_exists('PEAR_ChannelFile')) {
1509,7 → 1374,7
require_once 'PEAR/ChannelFile.php';
}
$pear_channel = new PEAR_ChannelFile;
$pear_channel->setServer('pecl.php.net');
$pear_channel->setName('pecl.php.net');
$pear_channel->setAlias('pecl');
$pear_channel->setSummary('PHP Extension Community Library');
$pear_channel->setDefaultPEARProtocols();
1518,42 → 1383,22
$pear_channel->setValidationPackage('PEAR_Validator_PECL', '1.0');
return $pear_channel;
}
 
if ($this->_getChannelFromAlias($channel) == 'doc.php.net') {
// the registry is not properly set up, so use defaults
if (!class_exists('PEAR_ChannelFile')) {
require_once 'PEAR/ChannelFile.php';
}
 
$doc_channel = new PEAR_ChannelFile;
$doc_channel->setServer('doc.php.net');
$doc_channel->setAlias('phpdocs');
$doc_channel->setSummary('PHP Documentation Team');
$doc_channel->setDefaultPEARProtocols();
$doc_channel->setBaseURL('REST1.0', 'http://doc.php.net/rest/');
$doc_channel->setBaseURL('REST1.1', 'http://doc.php.net/rest/');
$doc_channel->setBaseURL('REST1.3', 'http://doc.php.net/rest/');
return $doc_channel;
}
 
 
if ($this->_getChannelFromAlias($channel) == '__uri') {
// the registry is not properly set up, so use defaults
if (!class_exists('PEAR_ChannelFile')) {
require_once 'PEAR/ChannelFile.php';
}
 
$private = new PEAR_ChannelFile;
$private->setName('__uri');
$private->setDefaultPEARProtocols();
$private->setBaseURL('REST1.0', '****');
$private->addFunction('xmlrpc', '1.0', '****');
$private->setSummary('Pseudo-channel for static packages');
return $private;
}
 
return $ch;
}
 
// {{{ packageExists()
 
/**
* @param string Package name
* @param string Channel name
1590,23 → 1435,6
 
// }}}
 
/**
* @param string channel name mirror is in
* @param string mirror name
*
* @return bool
*/
function mirrorExists($channel, $mirror)
{
if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
return $e;
}
 
$ret = $this->_mirrorExists($channel, $mirror);
$this->_unlock();
return $ret;
}
 
// {{{ isAlias()
 
/**
1811,13 → 1639,11
if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
return $e;
}
 
$ret = $this->_deleteChannel($channel);
$this->_unlock();
if ($ret && is_a($this->_config, 'PEAR_Config')) {
$this->_config->setChannels($this->listChannels());
}
 
return $ret;
}
 
1831,20 → 1657,20
*/
function addChannel($channel, $lastmodified = false, $update = false)
{
if (!is_a($channel, 'PEAR_ChannelFile') || !$channel->validate()) {
if (!is_a($channel, 'PEAR_ChannelFile')) {
return false;
}
 
if (!$channel->validate()) {
return false;
}
if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
return $e;
}
 
$ret = $this->_addChannel($channel, $update, $lastmodified);
$this->_unlock();
if (!$update && $ret && is_a($this->_config, 'PEAR_Config')) {
$this->_config->setChannels($this->listChannels());
}
 
return $ret;
}
 
1856,9 → 1682,12
if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
return $e;
}
 
$file = $this->_packageFileName($package, $channel);
$ret = file_exists($file) ? @unlink($file) : false;
if (file_exists($file)) {
$ret = @unlink($file);
} else {
$ret = false;
}
$this->_rebuildFileMap();
$this->_unlock();
$p = array('channel' => $channel, 'package' => $package);
1897,19 → 1726,15
 
function updatePackage2($info)
{
 
if (!is_object($info)) {
return $this->updatePackage($info['package'], $info, $merge);
}
 
if (!$info->validate(PEAR_VALIDATE_DOWNLOADING)) {
return false;
}
 
if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
return $e;
}
 
$ret = $this->_updatePackage2($info);
$this->_unlock();
if ($ret) {
1916,7 → 1741,6
$this->_dependencyDB->uninstallPackage($info);
$this->_dependencyDB->installPackage($info);
}
 
return $ret;
}
 
1927,16 → 1751,16
* @param bool whether to strictly return raw channels (no aliases)
* @return PEAR_ChannelFile|PEAR_Error
*/
function getChannel($channel, $noaliases = false)
function &getChannel($channel, $noaliases = false)
{
if (PEAR::isError($e = $this->_lock(LOCK_SH))) {
return $e;
}
$ret = $this->_getChannel($channel, $noaliases);
$this->_unlock();
$ret = &$this->_getChannel($channel, $noaliases);
if (!$ret) {
return PEAR::raiseError('Unknown channel: ' . $channel);
}
$this->_unlock();
return $ret;
}
 
2325,7 → 2149,7
return PEAR::raiseError('parsePackageName(): "' . $param['version'] .
'" is neither a valid version nor a valid state in "' .
$saveparam . '"', 'version/state', null, null, $param);
}
}
}
}
return $param;
2386,3 → 2210,5
return $ret;
}
}
 
?>
/trunk/bibliotheque/pear/PEAR/REST.php
4,11 → 4,18
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: REST.php,v 1.21 2006/03/27 04:33:11 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
25,9 → 32,9
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
35,10 → 42,9
{
var $config;
var $_options;
 
function __construct(&$config, $options = array())
function PEAR_REST(&$config, $options = array())
{
$this->config = &$config;
$this->config = &$config;
$this->_options = $options;
}
 
53,16 → 59,14
* parsed using PEAR_XMLParser
* @return string|array
*/
function retrieveCacheFirst($url, $accept = false, $forcestring = false, $channel = false)
function retrieveCacheFirst($url, $accept = false, $forcestring = 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);
return $this->retrieveData($url, $accept, $forcestring);
}
 
/**
73,74 → 77,52
* parsed using PEAR_XMLParser
* @return string|array
*/
function retrieveData($url, $accept = false, $forcestring = false, $channel = false)
function retrieveData($url, $accept = false, $forcestring = 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);
$file = $this->downloadHttp($url, $cacheId ? $cacheId['lastChange'] : false, $accept);
} else {
$trieddownload = false;
$file = false;
}
 
if (PEAR::isError($file)) {
if ($file->getCode() !== -9276) {
if ($file->getCode() == -9276) {
$trieddownload = false;
$file = false; // use local copy if available on socket connect error
} else {
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());
}
$this->saveCache($url, $ret, null, true, $cacheId);
}
 
return $ret;
}
 
if (is_array($file)) {
$headers = $file[2];
$headers = $file[2];
$lastmodified = $file[1];
$content = $file[0];
$content = $file[0];
} else {
$headers = array();
$content = $file;
$lastmodified = false;
$content = $file;
$headers = array();
}
 
if ($forcestring) {
$result = $this->saveCache($url, $content, $lastmodified, false, $cacheId);
if (PEAR::isError($result)) {
return PEAR::raiseError($result->getMessage());
}
 
$this->saveCache($url, $content, $lastmodified, false, $cacheId);
return $content;
}
 
if (isset($headers['content-type'])) {
$content_type = explode(";", $headers['content-type']);
$content_type = $content_type[0];
switch ($content_type) {
switch ($headers['content-type']) {
case 'text/xml' :
case 'application/xml' :
case 'text/plain' :
if ($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);
160,12 → 142,7
$parser->parse($content);
$content = $parser->getData();
}
 
$result = $this->saveCache($url, $content, $lastmodified, false, $cacheId);
if (PEAR::isError($result)) {
return PEAR::raiseError($result->getMessage());
}
 
$this->saveCache($url, $content, $lastmodified, false, $cacheId);
return $content;
}
 
174,19 → 151,17
if ($cacheid === null) {
$cacheidfile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR .
md5($url) . 'rest.cacheid';
if (!file_exists($cacheidfile)) {
if (file_exists($cacheidfile)) {
$cacheid = unserialize(implode('', file($cacheidfile)));
} else {
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;
}
 
194,13 → 169,12
{
$cacheidfile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR .
md5($url) . 'rest.cacheid';
 
if (!file_exists($cacheidfile)) {
if (file_exists($cacheidfile)) {
$ret = unserialize(implode('', file($cacheidfile)));
return $ret;
} else {
return false;
}
 
$ret = unserialize(implode('', file($cacheidfile)));
return $ret;
}
 
function getCache($url)
207,12 → 181,11
{
$cachefile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR .
md5($url) . 'rest.cachefile';
 
if (!file_exists($cachefile)) {
if (file_exists($cachefile)) {
return unserialize(implode('', file($cachefile)));
} else {
return PEAR::raiseError('No cached content available for "' . $url . '"');
}
 
return unserialize(implode('', file($cachefile)));
}
 
/**
224,96 → 197,54
*/
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 (!is_writeable($cache_dir)) {
// If writing to the cache dir is not going to work, silently do nothing.
// An ugly hack, but retains compat with PEAR 1.9.1 where many commands
// work fine as non-root user (w/out write access to default cache dir).
return true;
}
 
$cacheidfile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR .
md5($url) . 'rest.cacheid';
$cachefile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR .
md5($url) . 'rest.cachefile';
if ($cacheid === null && $nochange) {
$cacheid = unserialize(implode('', file($cacheidfile)));
}
 
$idData = serialize(array(
'age' => time(),
'lastChange' => ($nochange ? $cacheid['lastChange'] : $lastmodified),
));
$fp = @fopen($cacheidfile, 'wb');
if (!$fp) {
$cache_dir = $this->config->get('cache_dir');
if (!is_dir($cache_dir)) {
System::mkdir(array('-p', $cache_dir));
$fp = @fopen($cacheidfile, 'wb');
if (!$fp) {
return false;
}
} else {
return false;
}
}
 
$result = $this->saveCacheFile($cacheidfile, $idData);
if (PEAR::isError($result)) {
return $result;
} elseif ($nochange) {
if ($nochange) {
fwrite($fp, serialize(array(
'age' => time(),
'lastChange' => $cacheid['lastChange'],
)));
fclose($fp);
return true;
} else {
fwrite($fp, serialize(array(
'age' => time(),
'lastChange' => $lastmodified,
)));
}
 
$result = $this->saveCacheFile($cachefile, serialize($contents));
if (PEAR::isError($result)) {
fclose($fp);
$fp = @fopen($cachefile, 'wb');
if (!$fp) {
if (file_exists($cacheidfile)) {
@unlink($cacheidfile);
@unlink($cacheidfile);
}
 
return $result;
return false;
}
 
fwrite($fp, serialize($contents));
fclose($fp);
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_fp = @fopen($file, 'r+b'); // do not truncate file
if (!$cachefile_fp) {
return PEAR::raiseError("Could not open $file for writing.");
}
 
if (OS_WINDOWS) {
$not_symlink = !is_link($file); // see bug #18834
} else {
$cachefile_lstat = lstat($file);
$cachefile_fstat = fstat($cachefile_fp);
$not_symlink = $cachefile_lstat['mode'] == $cachefile_fstat['mode']
&& $cachefile_lstat['ino'] == $cachefile_fstat['ino']
&& $cachefile_lstat['dev'] == $cachefile_fstat['dev']
&& $cachefile_fstat['nlink'] === 1;
}
 
if ($not_symlink) {
ftruncate($cachefile_fp, 0); // NOW truncate
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
335,59 → 266,54
*
* @access public
*/
function downloadHttp($url, $lastmodified = null, $accept = false, $channel = false)
function downloadHttp($url, $lastmodified = null, $accept = 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 . '"');
} else {
$host = $info['host'];
if (!array_key_exists('port', $info)) {
$info['port'] = null;
}
if (!array_key_exists('path', $info)) {
$info['path'] = null;
}
$port = $info['port'];
$path = $info['path'];
}
 
$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'))
) {
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') {
if (isset($proxy['scheme']) && $proxy['scheme'] == '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';
$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;
}
 
if (empty($port)) {
$port = (isset($info['scheme']) && $info['scheme'] == 'https') ? 443 : 80;
if (isset($info['scheme']) && $info['scheme'] == 'https') {
$port = 443;
} else {
$port = 80;
}
}
 
if (isset($proxy['host'])) {
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";
}
394,92 → 320,66
} else {
$ifmodifiedsince = ($lastmodified ? "If-Modified-Since: $lastmodified\r\n" : '');
}
 
$request .= $ifmodifiedsince .
"User-Agent: PEAR/1.10.1/PHP/" . PHP_VERSION . "\r\n";
 
$username = $this->config->get('username', null, $channel);
$password = $this->config->get('password', null, $channel);
 
$request .= "Host: $host:$port\r\n" . $ifmodifiedsince .
"User-Agent: PEAR/1.5.1/PHP/" . PHP_VERSION . "\r\n";
$username = $this->config->get('username');
$password = $this->config->get('password');
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);
return PEAR::raiseError("Connection to `$proxy_host:$proxy_port' failed: $errstr",
-9276);
}
} else {
if ($schema === 'https') {
if (isset($info['scheme']) && $info['scheme'] == '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)) {
while (trim($line = fgets($fp, 1024))) {
if (preg_match('/^([^:]+):\s+(.*)\s*$/', $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))) {
if ($matches[1] == 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 ($matches[1] != 200) {
return PEAR::raiseError("File http://$host:$port$path not valid (received: $line)", (int) $matches[1]);
}
}
}
 
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);
if (isset($headers['content-length'])) {
$length = $headers['content-length'];
} else {
$length = -1;
}
 
$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'];
487,10 → 387,9
$lastmodified = $headers['last-modified'];
}
}
 
return array($data, $lastmodified, $headers);
}
 
return $data;
}
}
?>
/trunk/bibliotheque/pear/PEAR/Command.php
4,12 → 4,19
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Command.php,v 1.38 2006/10/31 02:54:40 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
91,9 → 98,9
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
108,8 → 115,11
* @param object $config Instance of PEAR_Config object
*
* @return object the command object or a PEAR error
*
* @access public
* @static
*/
public static function &factory($command, &$config)
function &factory($command, &$config)
{
if (empty($GLOBALS['_PEAR_Command_commandlist'])) {
PEAR_Command::registerCommands();
130,13 → 140,13
return $a;
}
$ui =& PEAR_Command::getFrontendObject();
$obj = new $class($ui, $config);
$obj = &new $class($ui, $config);
return $obj;
}
 
// }}}
// {{{ & getObject()
public static function &getObject($command)
function &getObject($command)
{
$class = $GLOBALS['_PEAR_Command_commandlist'][$command];
if (!class_exists($class)) {
147,7 → 157,7
}
$ui =& PEAR_Command::getFrontendObject();
$config = &PEAR_Config::singleton();
$obj = new $class($ui, $config);
$obj = &new $class($ui, $config);
return $obj;
}
 
158,8 → 168,9
* Get instance of frontend object.
*
* @return object|PEAR_Error
* @static
*/
public static function &getFrontendObject()
function &getFrontendObject()
{
$a = &PEAR_Frontend::singleton();
return $a;
174,8 → 185,9
* @param string $uiclass Name of class implementing the frontend
*
* @return object the frontend object, or a PEAR error
* @static
*/
public static function &setFrontendClass($uiclass)
function &setFrontendClass($uiclass)
{
$a = &PEAR_Frontend::setFrontendClass($uiclass);
return $a;
190,8 → 202,9
* @param string $uitype Name of the frontend type (for example "CLI")
*
* @return object the frontend object, or a PEAR error
* @static
*/
public static function setFrontendType($uitype)
function setFrontendType($uitype)
{
$uiclass = 'PEAR_Frontend_' . $uitype;
return PEAR_Command::setFrontendClass($uiclass);
214,8 → 227,11
* included.
*
* @return bool TRUE on success, a PEAR error on failure
*
* @access public
* @static
*/
public static function registerCommands($merge = false, $dir = null)
function registerCommands($merge = false, $dir = null)
{
$parser = new PEAR_XMLParser;
if ($dir === null) {
231,31 → 247,27
if (!$merge) {
$GLOBALS['_PEAR_Command_commandlist'] = array();
}
 
while ($file = readdir($dp)) {
if ($file{0} == '.' || substr($file, -4) != '.xml') {
while ($entry = readdir($dp)) {
if ($entry{0} == '.' || substr($entry, -4) != '.xml') {
continue;
}
 
$f = substr($file, 0, -4);
$class = "PEAR_Command_" . $f;
$class = "PEAR_Command_".substr($entry, 0, -4);
$file = "$dir/$entry";
$parser->parse(file_get_contents($file));
$implements = $parser->getData();
// List of commands
if (empty($GLOBALS['_PEAR_Command_objects'][$class])) {
$GLOBALS['_PEAR_Command_objects'][$class] = "$dir/" . $f . '.php';
$GLOBALS['_PEAR_Command_objects'][$class] = "$dir/" . substr($entry, 0, -4) .
'.php';
}
 
$parser->parse(file_get_contents("$dir/$file"));
$implements = $parser->getData();
foreach ($implements as $command => $desc) {
if ($command == 'attribs') {
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'])) {
267,7 → 279,6
}
$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) {
280,7 → 291,6
}
}
}
 
ksort($GLOBALS['_PEAR_Command_shortcuts']);
ksort($GLOBALS['_PEAR_Command_commandlist']);
@closedir($dp);
295,8 → 305,11
* classes implement them.
*
* @return array command => implementing class
*
* @access public
* @static
*/
public static function getCommands()
function getCommands()
{
if (empty($GLOBALS['_PEAR_Command_commandlist'])) {
PEAR_Command::registerCommands();
311,8 → 324,11
* Get the list of command shortcuts.
*
* @return array shortcut => command
*
* @access public
* @static
*/
public static function getShortcuts()
function getShortcuts()
{
if (empty($GLOBALS['_PEAR_Command_shortcuts'])) {
PEAR_Command::registerCommands();
331,8 → 347,11
* @param array $long_args (reference) long getopt format
*
* @return void
*
* @access public
* @static
*/
public static function getGetoptArgs($command, &$short_args, &$long_args)
function getGetoptArgs($command, &$short_args, &$long_args)
{
if (empty($GLOBALS['_PEAR_Command_commandlist'])) {
PEAR_Command::registerCommands();
356,8 → 375,11
* @param string $command Name of the command
*
* @return string command description
*
* @access public
* @static
*/
public static function getDescription($command)
function getDescription($command)
{
if (!isset($GLOBALS['_PEAR_Command_commanddesc'][$command])) {
return null;
372,8 → 394,11
* Get help for command.
*
* @param string $command Name of the command to return help for
*
* @access public
* @static
*/
public static function getHelp($command)
function getHelp($command)
{
$cmds = PEAR_Command::getCommands();
if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) {
386,4 → 411,6
return false;
}
// }}}
}
}
 
?>
/trunk/bibliotheque/pear/PEAR/Frontend.php
4,21 → 4,23
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Frontend.php,v 1.9 2006/03/03 13:13:07 pajoye Exp $
* @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
*/
33,12 → 35,14
/**
* Singleton-based frontend for PEAR user input/output
*
* Note that frontend classes must implement userConfirm(), and shoul implement
* displayFatalError() and outputData()
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
47,8 → 51,9
/**
* Retrieve the frontend object
* @return PEAR_Frontend_CLI|PEAR_Frontend_Web|PEAR_Frontend_Gtk
* @static
*/
public static function &singleton($type = null)
function &singleton($type = null)
{
if ($type === null) {
if (!isset($GLOBALS['_PEAR_FRONTEND_SINGLETON'])) {
56,10 → 61,10
return $a;
}
return $GLOBALS['_PEAR_FRONTEND_SINGLETON'];
} else {
$a = PEAR_Frontend::setFrontendClass($type);
return $a;
}
 
$a = PEAR_Frontend::setFrontendClass($type);
return $a;
}
 
/**
69,14 → 74,14
* _ => DIRECTORY_SEPARATOR (PEAR_Frontend_CLI is in PEAR/Frontend/CLI.php)
* @param string $uiclass full class name
* @return PEAR_Frontend
* @static
*/
public static function &setFrontendClass($uiclass)
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)) {
83,21 → 88,19
include_once $file;
}
}
 
if (class_exists($uiclass)) {
$obj = new $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')) {
if (method_exists($obj, 'userConfirm')) {
$GLOBALS['_PEAR_FRONTEND_SINGLETON'] = &$obj;
$GLOBALS['_PEAR_FRONTEND_CLASS'] = $uiclass;
return $obj;
} else {
$err = PEAR::raiseError("not a frontend class: $uiclass");
return $err;
}
 
$err = PEAR::raiseError("not a frontend class: $uiclass");
return $err;
}
 
$err = PEAR::raiseError("no such class: $uiclass");
return $err;
}
108,41 → 111,52
* Frontends are expected to be a descendant of PEAR_Frontend
* @param PEAR_Frontend
* @return PEAR_Frontend
* @static
*/
public static function &setFrontendObject($uiobject)
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;
// quick test to see if this class implements a few of the most
// important frontend methods
if (method_exists($uiobject, 'userConfirm')) {
$GLOBALS['_PEAR_FRONTEND_SINGLETON'] = &$uiobject;
$GLOBALS['_PEAR_FRONTEND_CLASS'] = get_class($uiobject);
return $uiobject;
} else {
$err = PEAR::raiseError("not a value frontend class: (" . get_class($uiobject)
. ')');
return $err;
}
}
 
/**
* @param string $path relative or absolute include path
* @return boolean
* @static
*/
public static function isIncludeable($path)
function isIncludeable($path)
{
if (file_exists($path) && is_readable($path)) {
return true;
}
 
$fp = @fopen($path, 'r', true);
if ($fp) {
fclose($fp);
return true;
$ipath = explode(PATH_SEPARATOR, ini_get('include_path'));
foreach ($ipath as $include) {
$test = realpath($include . DIRECTORY_SEPARATOR . $path);
if (!$test) { // support wrappers like phar (realpath just don't work with them)
$test = $include . DIRECTORY_SEPARATOR . $path;
}
if (file_exists($test) && is_readable($test)) {
return true;
}
}
 
return false;
}
 
165,59 → 179,8
$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())
{
}
}
}
?>
/trunk/bibliotheque/pear/PEAR/PackageFileManager.php
New file
0,0 → 1,1595
<?php
//
// +------------------------------------------------------------------------+
// | PEAR :: Package File Manager |
// +------------------------------------------------------------------------+
// | Copyright (c) 2003-2004 Gregory Beaver |
// | Email cellog@phpdoc.org |
// +------------------------------------------------------------------------+
// | This source file is subject to version 3.00 of the PHP License, |
// | that is available at 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. |
// +------------------------------------------------------------------------+
// | Portions of this code based on phpDocumentor |
// | Web http://www.phpdoc.org |
// | Mirror http://phpdocu.sourceforge.net/ |
// +------------------------------------------------------------------------+
// $Id: PackageFileManager.php,v 1.42 2005/04/06 22:21:20 cellog Exp $
//
 
/**
* @package PEAR_PackageFileManager
*/
/**
* PEAR installer
*/
require_once 'PEAR/Common.php';
/**#@+
* Error Codes
*/
define('PEAR_PACKAGEFILEMANAGER_NOSTATE', 1);
define('PEAR_PACKAGEFILEMANAGER_NOVERSION', 2);
define('PEAR_PACKAGEFILEMANAGER_NOPKGDIR', 3);
define('PEAR_PACKAGEFILEMANAGER_NOBASEDIR', 4);
define('PEAR_PACKAGEFILEMANAGER_GENERATOR_NOTFOUND', 5);
define('PEAR_PACKAGEFILEMANAGER_GENERATOR_NOTFOUND_ANYWHERE', 6);
define('PEAR_PACKAGEFILEMANAGER_CANTWRITE_PKGFILE', 7);
define('PEAR_PACKAGEFILEMANAGER_DEST_UNWRITABLE', 8);
define('PEAR_PACKAGEFILEMANAGER_CANTCOPY_PKGFILE', 9);
define('PEAR_PACKAGEFILEMANAGER_CANTOPEN_TMPPKGFILE', 10);
define('PEAR_PACKAGEFILEMANAGER_PATH_DOESNT_EXIST', 11);
define('PEAR_PACKAGEFILEMANAGER_NOCVSENTRIES', 12);
define('PEAR_PACKAGEFILEMANAGER_DIR_DOESNT_EXIST', 13);
define('PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS', 14);
define('PEAR_PACKAGEFILEMANAGER_NOPACKAGE', 15);
define('PEAR_PACKAGEFILEMANAGER_WRONG_MROLE', 16);
define('PEAR_PACKAGEFILEMANAGER_NOSUMMARY', 17);
define('PEAR_PACKAGEFILEMANAGER_NODESC', 18);
define('PEAR_PACKAGEFILEMANAGER_ADD_MAINTAINERS', 19);
define('PEAR_PACKAGEFILEMANAGER_NO_FILES', 20);
define('PEAR_PACKAGEFILEMANAGER_IGNORED_EVERYTHING', 21);
define('PEAR_PACKAGEFILEMANAGER_INVALID_PACKAGE', 22);
define('PEAR_PACKAGEFILEMANAGER_INVALID_REPLACETYPE', 23);
define('PEAR_PACKAGEFILEMANAGER_INVALID_ROLE', 24);
define('PEAR_PACKAGEFILEMANAGER_PHP_NOT_PACKAGE', 25);
define('PEAR_PACKAGEFILEMANAGER_CVS_PACKAGED', 26);
define('PEAR_PACKAGEFILEMANAGER_NO_PHPCOMPATINFO', 27);
/**#@-*/
/**
* Error messages
* @global array $GLOBALS['_PEAR_PACKAGEFILEMANAGER_ERRORS']
*/
$GLOBALS['_PEAR_PACKAGEFILEMANAGER_ERRORS'] =
array(
'en' =>
array(
PEAR_PACKAGEFILEMANAGER_NOSTATE =>
'Release State (option \'state\') must by specified in PEAR_PackageFileManager setOptions (alpha|beta|stable)',
PEAR_PACKAGEFILEMANAGER_NOVERSION =>
'Release Version (option \'version\') must be specified in PEAR_PackageFileManager setOptions',
PEAR_PACKAGEFILEMANAGER_NOPKGDIR =>
'Package source base directory (option \'packagedirectory\') must be ' .
'specified in PEAR_PackageFileManager setOptions',
PEAR_PACKAGEFILEMANAGER_NOBASEDIR =>
'Package install base directory (option \'baseinstalldir\') must be ' .
'specified in PEAR_PackageFileManager setOptions',
PEAR_PACKAGEFILEMANAGER_GENERATOR_NOTFOUND =>
'Base class "%s" can\'t be located',
PEAR_PACKAGEFILEMANAGER_GENERATOR_NOTFOUND_ANYWHERE =>
'Base class "%s" can\'t be located in default or user-specified directories',
PEAR_PACKAGEFILEMANAGER_CANTWRITE_PKGFILE =>
'Failed to write package.xml file to destination directory',
PEAR_PACKAGEFILEMANAGER_DEST_UNWRITABLE =>
'Destination directory "%s" is unwritable',
PEAR_PACKAGEFILEMANAGER_CANTCOPY_PKGFILE =>
'Failed to copy package.xml.tmp file to package.xml',
PEAR_PACKAGEFILEMANAGER_CANTOPEN_TMPPKGFILE =>
'Failed to open temporary file "%s" for writing',
PEAR_PACKAGEFILEMANAGER_PATH_DOESNT_EXIST =>
'package.xml file path "%s" doesn\'t exist or isn\'t a directory',
PEAR_PACKAGEFILEMANAGER_NOCVSENTRIES =>
'Directory "%s" is not a CVS directory (it must have the CVS/Entries file)',
PEAR_PACKAGEFILEMANAGER_DIR_DOESNT_EXIST =>
'Package source base directory "%s" doesn\'t exist or isn\'t a directory',
PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS =>
'Run $managerclass->setOptions() before any other methods',
PEAR_PACKAGEFILEMANAGER_NOPACKAGE =>
'Package Name (option \'package\') must by specified in PEAR_PackageFileManager '.
'setOptions to create a new package.xml',
PEAR_PACKAGEFILEMANAGER_NOSUMMARY =>
'Package Summary (option \'summary\') must by specified in PEAR_PackageFileManager' .
' setOptions to create a new package.xml',
PEAR_PACKAGEFILEMANAGER_NODESC =>
'Detailed Package Description (option \'description\') must be' .
' specified in PEAR_PackageFileManager setOptions to create a new package.xml',
PEAR_PACKAGEFILEMANAGER_WRONG_MROLE =>
'Maintainer role must be one of "%s", was "%s"',
PEAR_PACKAGEFILEMANAGER_ADD_MAINTAINERS =>
'Add maintainers to a package before generating the package.xml',
PEAR_PACKAGEFILEMANAGER_NO_FILES =>
'No files found, check the path "%s"',
PEAR_PACKAGEFILEMANAGER_IGNORED_EVERYTHING =>
'No files left, check the path "%s" and ignore option "%s"',
PEAR_PACKAGEFILEMANAGER_INVALID_PACKAGE =>
'Package validation failed:%s%s',
PEAR_PACKAGEFILEMANAGER_INVALID_REPLACETYPE =>
'Replacement Type must be one of "%s", was passed "%s"',
PEAR_PACKAGEFILEMANAGER_INVALID_ROLE =>
'Invalid file role passed to addRole, must be one of "%s", was passed "%s"',
PEAR_PACKAGEFILEMANAGER_PHP_NOT_PACKAGE =>
'addDependency had PHP as a package, use type="php"',
PEAR_PACKAGEFILEMANAGER_CVS_PACKAGED =>
'path "%path%" contains CVS directory',
PEAR_PACKAGEFILEMANAGER_NO_PHPCOMPATINFO =>
'PHP_Compat is not installed, cannot detect dependencies',
),
// other language translations go here
);
/**
* PEAR :: PackageFileManager updates the <filelist></filelist> section
* of a PEAR package.xml file to reflect the current files in
* preparation for a release.
*
* The PEAR_PackageFileManager class uses a plugin system to generate the
* list of files in a package. This allows both standard recursive
* directory parsing (plugin type file) and more intelligent options
* such as the CVS browser {@link PEAR_PackageFileManager_Cvs}, which
* grabs all files in a local CVS checkout to create the list, ignoring
* any other local files.
*
* Other options include specifying roles for file extensions (all .php
* files are role="php", for example), roles for directories (all directories
* named "tests" are given role="tests" by default), and exceptions.
* Exceptions are specific pathnames with * and ? wildcards that match
* a default role, but should have another. For example, perhaps
* a debug.tpl template would normally be data, but should be included
* in the docs role. Along these lines, to exclude files entirely,
* use the ignore option.
*
* Required options for a release include version, baseinstalldir, state,
* and packagedirectory (the full path to the local location of the
* package to create a package.xml file for)
*
* Example usage:
* <code>
* <?php
* require_once('PEAR/PackageFileManager.php');
* $packagexml = new PEAR_PackageFileManager;
* $e = $packagexml->setOptions(
* array('baseinstalldir' => 'PhpDocumentor',
* 'version' => '1.2.1',
* 'packagedirectory' => 'C:/Web Pages/chiara/phpdoc2/',
* 'state' => 'stable',
* 'filelistgenerator' => 'cvs', // generate from cvs, use file for directory
* 'notes' => 'We\'ve implemented many new and exciting features',
* 'ignore' => array('TODO', 'tests/'), // ignore TODO, all files in tests/
* 'installexceptions' => array('phpdoc' => '/*'), // baseinstalldir ="/" for phpdoc
* 'dir_roles' => array('tutorials' => 'doc'),
* 'exceptions' => array('README' => 'doc', // README would be data, now is doc
* 'PHPLICENSE.txt' => 'doc'))); // same for the license
* if (PEAR::isError($e)) {
* echo $e->getMessage();
* die();
* }
* $e = $test->addPlatformException('pear-phpdoc.bat', 'windows');
* if (PEAR::isError($e)) {
* echo $e->getMessage();
* exit;
* }
* $packagexml->addRole('pkg', 'doc'); // add a new role mapping
* if (PEAR::isError($e)) {
* echo $e->getMessage();
* exit;
* }
* // replace @PHP-BIN@ in this file with the path to php executable! pretty neat
* $e = $test->addReplacement('pear-phpdoc', 'pear-config', '@PHP-BIN@', 'php_bin');
* if (PEAR::isError($e)) {
* echo $e->getMessage();
* exit;
* }
* $e = $test->addReplacement('pear-phpdoc.bat', 'pear-config', '@PHP-BIN@', 'php_bin');
* if (PEAR::isError($e)) {
* echo $e->getMessage();
* exit;
* }
* // note use of {@link debugPackageFile()} - this is VERY important
* if (isset($_GET['make']) || (isset($_SERVER['argv'][2]) &&
* $_SERVER['argv'][2] == 'make')) {
* $e = $packagexml->writePackageFile();
* } else {
* $e = $packagexml->debugPackageFile();
* }
* if (PEAR::isError($e)) {
* echo $e->getMessage();
* die();
* }
* ?>
* </code>
*
* In addition, a package.xml file can now be generated from
* scratch, with the usage of new options package, summary, description, and
* the use of the {@link addMaintainer()} method
* @package PEAR_PackageFileManager
*/
class PEAR_PackageFileManager
{
/**
* Format: array(array(regexp-ready string to search for whole path,
* regexp-ready string to search for basename of ignore strings),...)
* @var false|array
* @access private
*/
var $_ignore = false;
/**
* Contents of the package.xml file
* @var string
* @access private
*/
var $_packageXml = false;
/**
* Contents of the original package.xml file, if any
* @var string
* @access private
*/
var $_oldPackageXml = false;
/**
* @access private
* @var PEAR_Common
*/
var $_pear;
/**
* @access private
* @var array
*/
var $_warningStack = array();
 
/**
* flag used to determine whether to use PHP_CompatInfo to detect deps
* @var boolean
* @access private
*/
var $_detectDependencies = false;
/**
* @access private
* @var string
*/
var $_options = array(
'packagefile' => 'package.xml',
'doctype' => 'http://pear.php.net/dtd/package-1.0',
'filelistgenerator' => 'file',
'license' => 'PHP License',
'changelogoldtonew' => true,
'roles' =>
array(
'php' => 'php',
'html' => 'doc',
'*' => 'data',
),
'dir_roles' =>
array(
'docs' => 'doc',
'examples' => 'doc',
'tests' => 'test',
),
'exceptions' => array(),
'installexceptions' => array(),
'installas' => array(),
'platformexceptions' => array(),
'scriptphaseexceptions' => array(),
'ignore' => array(),
'include' => false,
'deps' => false,
'maintainers' => false,
'notes' => '',
'changelognotes' => false,
'outputdirectory' => false,
'pathtopackagefile' => false,
'lang' => 'en',
'configure_options' => array(),
'replacements' => array(),
'pearcommonclass' => false,
'simpleoutput' => false,
'addhiddenfiles' => false,
'cleardependencies' => false,
);
/**
* Does nothing, use setOptions
*
* The constructor is not used in order to be able to
* return a PEAR_Error from setOptions
* @see setOptions()
*/
function PEAR_PackageFileManager()
{
}
/**
* Set package.xml generation options
*
* The options array is indexed as follows:
* <code>
* $options = array('option_name' => <optionvalue>);
* </code>
*
* The documentation below simplifies this description through
* the use of option_name without quotes
*
* Configuration options:
* - lang: lang controls the language in which error messages are
* displayed. There are currently only English error messages,
* but any contributed will be added over time.<br>
* Possible values: en (default)
* - packagefile: the name of the packagefile, defaults to package.xml
* - pathtopackagefile: the path to an existing package file to read in,
* if different from the packagedirectory
* - packagedirectory: the path to the base directory of the package. For
* package PEAR_PackageFileManager, this path is
* /path/to/pearcvs/pear/PEAR_PackageFileManager where
* /path/to/pearcvs is a local path on your hard drive
* - outputdirectory: the path in which to place the generated package.xml
* by default, this is ignored, and the package.xml is
* created in the packagedirectory
* - filelistgenerator: the <filelist> section plugin which will be used.
* In this release, there are two generator plugins,
* file and cvs. For details, see the docs for these
* plugins
* - usergeneratordir: For advanced users. If you write your own filelist
* generator plugin, use this option to tell
* PEAR_PackageFileManager where to find the file that
* contains it. If the plugin is named foo, the class
* must be named PEAR_PackageFileManager_Foo
* no matter where it is located. By default, the Foo
* plugin is located in PEAR/PackageFileManager/Foo.php.
* If you pass /path/to/foo in this option, setOptions
* will look for PEAR_PackageFileManager_Foo in
* /path/to/foo/Foo.php
* - doctype: Specifies the DTD of the package.xml file. Default is
* http://pear.php.net/dtd/package-1.0
* - pearcommonclass: Specifies the name of the class to instantiate, default
* is PEAR_Common, but users can override this with a custom
* class that implements PEAR_Common's method interface
* - changelogoldtonew: True if the ChangeLog should list from oldest entry to
* newest. Set to false if you would like new entries first
* - simpleoutput: True if the package.xml should not contain md5sum or <provides />
* for readability
* - addhiddenfiles: True if you wish to add hidden files/directories that begin with .
* like .bashrc. This is only used by the File generator. The CVS
* generator will use all files in CVS regardless of format
*
* package.xml simple options:
* - baseinstalldir: The base directory to install this package in. For
* package PEAR_PackageFileManager, this is "PEAR", for
* package PEAR, this is "/"
* - license: The license this release is released under. Default is
* PHP License if left unspecified
* - notes: Release notes, any text describing what makes this release unique
* - changelognotes: notes for the changelog, this should be more detailed than
* the release notes. By default, PEAR_PackageFileManager uses
* the notes option for the changelog as well
* - version: The version number for this release. Remember the convention for
* numbering: initial alpha is between 0 and 1, add b<beta number> for
* beta as in 1.0b1, the integer portion of the version should specify
* backwards compatibility, as in 1.1 is backwards compatible with 1.0,
* but 2.0 is not backwards compatible with 1.10. Also note that 1.10
* is a greater release version than 1.1 (think of it as "one point ten"
* and "one point one"). Bugfix releases should be a third decimal as in
* 1.0.1, 1.0.2
* - package: [optional] Package name. Use this to create a new package.xml, or
* overwrite an existing one from another package used as a template
* - summary: [optional] Summary of package purpose
* - description: [optional] Description of package purpose. Note that the above
* three options are not optional when creating a new package.xml
* from scratch
*
* <b>WARNING</b>: all complex options that require a file path are case-sensitive
*
* package.xml complex options:
* - cleardependencies: since version 1.3.0, this option will erase any existing
* dependencies in the package.xml if set to true
* - ignore: an array of filenames, directory names, or wildcard expressions specifying
* files to exclude entirely from the package.xml. Wildcards are operating system
* wildcards * and ?. file*foo.php will exclude filefoo.php, fileabrfoo.php and
* filewho_is_thisfoo.php. file?foo.php will exclude fileafoo.php and will not
* exclude fileaafoo.php. test/ will exclude all directories and subdirectories of
* ANY directory named test encountered in directory parsing. *test* will exclude
* all files and directories that contain test in their name
* - include: an array of filenames, directory names, or wildcard expressions specifying
* files to include in the listing. All other files will be ignored.
* Wildcards are in the same format as ignore
* - roles: this is an array mapping file extension to install role. This
* specifies default behavior that can be overridden by the exceptions
* option and dir_roles option. use {@link addRole()} to add a new
* role to the pre-existing array
* - dir_roles: this is an array mapping directory name to install role. All
* files in a directory whose name matches the directory will be
* given the install role specified. Single files can be excluded
* from this using the exceptions option. The directory should be
* a relative path from the baseinstalldir, or "/" for the baseinstalldir
* - exceptions: specify file role for specific files. This array maps all files
* matching the exact name of a file to a role as in "file.ext" => "role"
* - deps: dependency array. Pass in an empty array to clear all dependencies, and use
* {@link addDependency()} to add new ones/replace existing ones
* - maintainers: maintainers array. Pass in an empty array to clear all maintainers, and
* use {@link addMaintainer()} to add a new maintainer/replace existing maintainer
* - installexceptions: array mapping of specific filenames to baseinstalldir values. Use
* this to force the installation of a file into another directory,
* such as forcing a script to be in the root scripts directory so that
* it will be in the path. The filename must be a relative path to the
* packagedirectory
* - platformexceptions: array mapping of specific filenames to the platform they should be
* installed on. Use this to specify unix-only files or windows-only
* files. The format of the platform string must be
* OS-version-cpu-extra if any more specific information is needed,
* and the OS must be in lower case as in "windows." The match is
* performed using a regular expression, but uses * and ? wildcards
* instead of .* and .?. Note that hpux/aix/irix/linux are all
* exclusive. To select non-windows, use (*ix|*ux)
* - scriptphaseexceptions: array mapping of scripts to their install phase. This can be
* one of: pre-install, post-install, pre-uninstall, post-uninstall,
* pre-build, post-build, pre-setup, or post-setup
* - installas: array mapping of specific filenames to the filename they should be installed as.
* Use this to specify new filenames for files that should be installed. This will
* often be used in conjunction with platformexceptions if there are two files for
* different OSes that must have the same name when installed.
* - replacements: array mapping of specific filenames to complex text search-and-replace that
* should be performed upon install. The format is:
* <pre>
* filename => array('type' => php-const|pear-config|package-info
* 'from' => text in file
* 'to' => name of variable)
* </pre>
* if type is php-const, then 'to' must be the name of a PHP Constant.
* If type is pear-config, then 'to' must be the name of a PEAR config
* variable accessible through a PEAR_Config class->get() method. If
* type is package-info, then 'to' must be the name of a section from
* the package.xml file used to install this file.
* - globalreplacements: a list of replacements that should be performed on every single file.
* The format is the same as replacements (since 1.4.0)
* - configure_options: array specifies build options for PECL packages (you should probably
* use PECL_Gen instead, but it's here for completeness)
* @see PEAR_PackageFileManager_File
* @see PEAR_PackageFileManager_CVS
* @return void|PEAR_Error
* @throws PEAR_PACKAGEFILEMANAGER_NOSTATE
* @throws PEAR_PACKAGEFILEMANAGER_NOVERSION
* @throws PEAR_PACKAGEFILEMANAGER_NOPKGDIR
* @throws PEAR_PACKAGEFILEMANAGER_NOBASEDIR
* @throws PEAR_PACKAGEFILEMANAGER_GENERATOR_NOTFOUND_ANYWHERE
* @throws PEAR_PACKAGEFILEMANAGER_GENERATOR_NOTFOUND
* @param array
*/
function setOptions($options = array(), $internal = false)
{
if (!$internal) {
if (!isset($options['state'])) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_NOSTATE);
}
if (!isset($options['version'])) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_NOVERSION);
}
}
if (!isset($options['packagedirectory']) && !$internal) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_NOPKGDIR);
} elseif (isset($options['packagedirectory'])) {
$options['packagedirectory'] = str_replace(DIRECTORY_SEPARATOR,
'/',
realpath($options['packagedirectory']));
if ($options['packagedirectory']{strlen($options['packagedirectory']) - 1} != '/') {
$options['packagedirectory'] .= '/';
}
}
if (isset($options['pathtopackagefile'])) {
$options['pathtopackagefile'] = str_replace(DIRECTORY_SEPARATOR,
'/',
realpath($options['pathtopackagefile']));
if ($options['pathtopackagefile']{strlen($options['pathtopackagefile']) - 1} != '/') {
$options['pathtopackagefile'] .= '/';
}
}
if (!isset($options['baseinstalldir']) && !$internal) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_NOBASEDIR);
}
$this->_options = array_merge($this->_options, $options);
if (!class_exists($this->_options['pearcommonclass'])) {
if ($this->_options['simpleoutput']) {
if ($this->isIncludeable('PEAR/PackageFile/Generator/v1.php')) {
include_once 'PEAR/PackageFileManager/SimpleGenerator.php';
$this->_options['pearcommonclass'] = 'PEAR_PackageFileManager_SimpleGenerator';
} else {
include_once 'PEAR/PackageFileManager/XMLOutput.php';
$this->_options['pearcommonclass'] = 'PEAR_PackageFileManager_XMLOutput';
}
} else {
$this->_options['pearcommonclass'] = 'PEAR_Common';
}
}
$path = ($this->_options['pathtopackagefile'] ?
$this->_options['pathtopackagefile'] : $this->_options['packagedirectory']);
$this->_options['filelistgenerator'] =
ucfirst(strtolower($this->_options['filelistgenerator']));
if (!$internal) {
if (PEAR::isError($res =
$this->_getExistingPackageXML($path, $this->_options['packagefile']))) {
return $res;
}
}
if (!class_exists('PEAR_PackageFileManager_' . $this->_options['filelistgenerator'])) {
// attempt to load the interface from the standard PEAR location
if ($this->isIncludeable('PEAR/PackageFileManager/' .
$this->_options['filelistgenerator'] . '.php')) {
include_once('PEAR/PackageFileManager/' .
$this->_options['filelistgenerator'] . '.php');
} elseif (isset($this->_options['usergeneratordir'])) {
// attempt to load from a user-specified directory
if (is_dir(realpath($this->_options['usergeneratordir']))) {
$this->_options['usergeneratordir'] =
str_replace(DIRECTORY_SEPARATOR,
'/',
realpath($this->_options['usergeneratordir']));
if ($this->_options['usergeneratordir']{strlen($this->_options['usergeneratordir'])
- 1} != '/') {
$this->_options['usergeneratordir'] .= '/';
}
} else {
$this->_options['usergeneratordir'] = '////';
}
if (file_exists($this->_options['usergeneratordir'] .
$this->_options['filelistgenerator'] . '.php') &&
is_readable($this->_options['usergeneratordir'] .
$this->_options['filelistgenerator'] . '.php')) {
include_once($this->_options['usergeneratordir'] .
$this->_options['filelistgenerator'] . '.php');
}
if (!class_exists('PEAR_PackageFileManager_' . $this->_options['filelistgenerator'])) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_GENERATOR_NOTFOUND_ANYWHERE,
'PEAR_PackageFileManager_' . $this->_options['filelistgenerator']);
}
} else {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_GENERATOR_NOTFOUND,
'PEAR_PackageFileManager_' . $this->_options['filelistgenerator']);
}
}
}
 
/**
* Import options from an existing package.xml
*
* @return true|PEAR_Error
*/
function importOptions($packagefile, $options = array())
{
$options['cleardependencies'] = $options['deps'] = $options['maintainers'] = false;
$this->setOptions($options, true);
if (PEAR::isError($res = $this->_getExistingPackageXML(dirname($packagefile) .
DIRECTORY_SEPARATOR, basename($packagefile)))) {
return $res;
}
$this->_options['package'] = $this->_oldPackageXml['package'];
$this->_options['summary'] = $this->_oldPackageXml['summary'];
$this->_options['description'] = $this->_oldPackageXml['description'];
$this->_options['date'] = $this->_oldPackageXml['release_date'];
$this->_options['version'] = $this->_oldPackageXml['version'];
$this->_options['license'] = $this->_oldPackageXml['release_license'];
$this->_options['state'] = $this->_oldPackageXml['release_state'];
$this->_options['notes'] = $this->_oldPackageXml['release_notes'];
if (isset($this->_oldPackagexml['release_deps'])) {
$this->_options['deps'] = $this->_oldPackageXml['release_deps'];
}
$this->_options['maintainers'] = $this->_oldPackageXml['maintainers'];
return true;
}
 
/**
* Get the existing options
* @return array
*/
function getOptions()
{
return $this->_options;
}
 
/**
* Add an extension/role mapping to the role mapping option
*
* Roles influence both where a file is installed and how it is installed.
* Files with role="data" are in a completely different directory hierarchy
* from the program files of role="php"
*
* In PEAR 1.3b2, these roles are
* - php (most common)
* - data
* - doc
* - test
* - script (gives the file an executable attribute)
* - src
* @param string file extension
* @param string role
* @throws PEAR_PACKAGEFILEMANAGER_INVALID_ROLE
*/
function addRole($extension, $role)
{
$roles = call_user_func(array($this->_options['pearcommonclass'], 'getfileroles'));
if (!in_array($role, $roles)) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_INVALID_ROLE, implode($roles, ', '), $role);
}
$this->_options['roles'][$extension] = $role;
}
/**
* Add an install-time platform conditional install for a file
*
* The format of the platform string must be
* OS-version-cpu-extra if any more specific information is needed,
* and the OS must be in lower case as in "windows." The match is
* performed using a regular expression, but uses * and ? wildcards
* instead of .* and .?. Note that hpux/aix/irix/linux are all
* exclusive. To select non-windows, use (*ix|*ux)
*
* This information is based on eyeing the source for OS/Guess.php, so
* if you are unsure of what to do, read that file.
* @param string relative path of file (relative to packagedirectory option)
* @param string platform descriptor string
*/
function addPlatformException($path, $platform)
{
if (!isset($this->_options['platformexceptions'])) {
$this->_options['platformexceptions'] = array();
}
$this->_options['platformexceptions'][$path] = $platform;
}
 
/**
* Add a replacement option for all files
*
* This sets an install-time complex search-and-replace function
* allowing the setting of platform-specific variables in all
* installed files.
*
* if $type is php-const, then $to must be the name of a PHP Constant.
* If $type is pear-config, then $to must be the name of a PEAR config
* variable accessible through a {@link PEAR_Config::get()} method. If
* type is package-info, then $to must be the name of a section from
* the package.xml file used to install this file.
* @param string relative path of file (relative to packagedirectory option)
* @param string variable type, either php-const, pear-config or package-info
* @param string text to replace in the source file
* @param string variable name to use for replacement
* @throws PEAR_PACKAGEFILEMANAGER_INVALID_REPLACETYPE
*/
function addGlobalReplacement($type, $from, $to)
{
if (!isset($this->_options['globalreplacements'])) {
$this->_options['globalreplacements'] = array();
}
$types = call_user_func(array($this->_options['pearcommonclass'], 'getreplacementtypes'));
if (!in_array($type, $types)) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_INVALID_REPLACETYPE,
implode($types, ', '), $type);
}
$this->_options['globalreplacements'][] =
array('type' => $type, 'from' => $from, 'to' => $to);
}
 
/**
* Add a replacement option for a file
*
* This sets an install-time complex search-and-replace function
* allowing the setting of platform-specific variables in an
* installed file.
*
* if $type is php-const, then $to must be the name of a PHP Constant.
* If $type is pear-config, then $to must be the name of a PEAR config
* variable accessible through a {@link PEAR_Config::get()} method. If
* type is package-info, then $to must be the name of a section from
* the package.xml file used to install this file.
* @param string relative path of file (relative to packagedirectory option)
* @param string variable type, either php-const, pear-config or package-info
* @param string text to replace in the source file
* @param string variable name to use for replacement
* @throws PEAR_PACKAGEFILEMANAGER_INVALID_REPLACETYPE
*/
function addReplacement($path, $type, $from, $to)
{
if (!isset($this->_options['replacements'])) {
$this->_options['replacements'] = array();
}
$types = call_user_func(array($this->_options['pearcommonclass'], 'getreplacementtypes'));
if (!in_array($type, $types)) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_INVALID_REPLACETYPE,
implode($types, ', '), $type);
}
$this->_options['replacements'][$path][] = array('type' => $type, 'from' => $from, 'to' => $to);
}
/**
* Add a maintainer to the list of maintainers.
*
* Every maintainer must have a valid account at pear.php.net. The
* first parameter is the account name (for instance, cellog is the
* handle for Greg Beaver at pear.php.net). Every maintainer has
* one of four possible roles:
* - lead: the primary maintainer
* - developer: an important developer on the project
* - contributor: self-explanatory
* - helper: ditto
*
* Finally, specify the name and email of the maintainer
* @param string username on pear.php.net of maintainer
* @param lead|developer|contributor|helper role of maintainer
* @param string full name of maintainer
* @param string email address of maintainer
*/
function addMaintainer($handle, $role, $name, $email)
{
if (!$this->_packageXml) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS);
}
if (!in_array($role, $GLOBALS['_PEAR_Common_maintainer_roles'])) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_WRONG_MROLE,
implode(', ', call_user_func(array($this->_options['pearcommonclass'],
'getUserRoles'))),
$role);
}
if (!isset($this->_packageXml['maintainers'])) {
$this->_packageXml['maintainers'] = array();
}
$found = false;
foreach($this->_packageXml['maintainers'] as $index => $maintainer) {
if ($maintainer['handle'] == $handle) {
$found = $index;
break;
}
}
$maintainer =
array('handle' => $handle, 'role' => $role, 'name' => $name, 'email' => $email);
if ($found !== false) {
$this->_packageXml['maintainers'][$found] = $maintainer;
} else {
$this->_packageXml['maintainers'][] = $maintainer;
}
}
/**
* Add an install-time configuration option for building of source
*
* This option is only useful to PECL projects that are built upon
* installation
* @param string name of the option
* @param string prompt to display to the user
* @param string default value
* @throws PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS
* @return void|PEAR_Error
*/
function addConfigureOption($name, $prompt, $default = null)
{
if (!$this->_packageXml) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS);
}
if (!isset($this->_packageXml['configure_options'])) {
$this->_packageXml['configure_options'] = array();
}
$found = false;
foreach($this->_packageXml['configure_options'] as $index => $option) {
if ($option['name'] == $name) {
$found = $index;
break;
}
}
$option = array('name' => $name, 'prompt' => $prompt);
if (isset($default)) {
$option['default'] = $default;
}
if ($found !== false) {
$this->_packageXml['configure_options'][$found] = $option;
} else {
$this->_packageXml['configure_options'][] = $option;
}
}
 
/**
* @return void|PEAR_Error
* @throws PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS
*/
function detectDependencies()
{
if (!$this->_packageXml) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS);
}
if (!$this->isIncludeable('PHP/CompatInfo.php')) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_PHP_COMPAT_NOT_INSTALLED);
} else {
if (include_once('PHP/CompatInfo.php')) {
$this->_detectDependencies = true;
} else {
$this->raiseError(PEAR_PACKAGEFILEMANAGER_NO_PHPCOMPATINFO);
}
}
}
 
function isIncludeable($file)
{
if (!defined('PATH_SEPARATOR')) {
define('PATH_SEPARATOR', strtolower(substr(PHP_OS, 0, 3)) == 'win' ? ';' : ':');
}
foreach (explode(PATH_SEPARATOR, ini_get('include_path')) as $path) {
if (file_exists($path . DIRECTORY_SEPARATOR . $file) &&
is_readable($path . DIRECTORY_SEPARATOR . $file)) {
return true;
}
}
return false;
}
 
/**
* Add a dependency on another package, or an extension/php
*
* This will overwrite an existing dependency if it is found. In
* other words, if a dependency on PHP 4.1.0 exists, and
* addDependency('php', '4.3.0', 'ge', 'php') is called, the existing
* dependency on PHP 4.1.0 will be overwritten with the new one on PHP 4.3.0
* @param string Dependency element name
* @param string Dependency version
* @param string A specific operator for the version, this can be one of:
* 'has', 'not', 'lt', 'le', 'eq', 'ne', 'ge', or 'gt'
* @param string Dependency type. This can be one of:
* 'pkg', 'ext', 'php', 'prog', 'os', 'sapi', or 'zend'
* @param boolean true if dependency is optional
* @throws PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS
* @throws PEAR_PACKAGEFILEMANAGER_PHP_NOT_PACKAGE
* @return void|PEAR_Error
*/
function addDependency($name, $version = false, $operator = 'ge', $type = 'pkg', $optional = false)
{
if (!$this->_packageXml) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS);
}
if ((strtolower($name) == 'php') && (strtolower($type) == 'pkg')) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_PHP_NOT_PACKAGE);
}
if (!isset($this->_packageXml['release_deps']) || !is_array($this->_packageXml['release_deps'])) {
$this->_packageXml['release_deps'] = array();
}
$found = false;
foreach($this->_packageXml['release_deps'] as $index => $dep) {
if ($type == 'php') {
if ($dep['type'] == 'php') {
$found = $index;
break;
}
} else {
if (isset($dep['name']) && $dep['name'] == $name && $dep['type'] == $type) {
$found = $index;
break;
}
}
}
$dep =
array(
'name' => $name,
'type' => $type);
if ($type == 'php') {
unset($dep['name']);
}
if ($operator) {
$dep['rel'] = $operator;
if ($dep['rel'] != 'has' && $version) {
$dep['version'] = $version;
}
}
if ($optional) {
$dep['optional'] = 'yes';
} else {
$dep['optional'] = 'no';
}
 
if ($found !== false) {
$this->_packageXml['release_deps'][$found] = $dep; // overwrite existing dependency
} else {
$this->_packageXml['release_deps'][] = $dep; // add new dependency
}
}
 
/**
* Writes the package.xml file out with the newly created <release></release> tag
*
* ALWAYS use {@link debugPackageFile} to verify that output is correct before
* overwriting your package.xml
* @param boolean null if no debugging, true if web interface, false if command-line
* @throws PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS
* @throws PEAR_PACKAGEFILEMANAGER_ADD_MAINTAINERS
* @throws PEAR_PACKAGEFILEMANAGER_CANTWRITE_PKGFILE
* @throws PEAR_PACKAGEFILEMANAGER_CANTCOPY_PKGFILE
* @throws PEAR_PACKAGEFILEMANAGER_CANTOPEN_TMPPKGFILE
* @throws PEAR_PACKAGEFILEMANAGER_DEST_UNWRITABLE
* @return void|PEAR_Error
*/
function writePackageFile($debuginterface = null)
{
if (!$this->_packageXml) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS);
}
if (!isset($this->_packageXml['maintainers']) || empty($this->_packageXml['maintainers'])) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_ADD_MAINTAINERS);
}
extract($this->_options);
$date = date('Y-m-d');
if (isset($package)) {
$this->_packageXml['package'] = $package;
}
if (isset($summary)) {
$this->_packageXml['summary'] = $summary;
}
if (isset($description)) {
$this->_packageXml['description'] = $description;
}
$this->_packageXml['release_date'] = $date;
$this->_packageXml['version'] = $version;
$this->_packageXml['release_license'] = $license;
$this->_packageXml['release_state'] = $state;
$this->_packageXml['release_notes'] = $notes;
$PEAR_Common = $this->_options['pearcommonclass'];
$this->_pear = new $PEAR_Common;
if (method_exists($this->_pear, 'setPackageFileManager')) {
$this->_pear->setPackageFileManager($this);
}
$this->_packageXml['filelist'] = $this->_getFileList();
$warnings = $this->getWarnings();
if (count($warnings)) {
$nl = (isset($debuginterface) && $debuginterface ? '<br />' : "\n");
foreach($warnings as $errmsg) {
echo 'WARNING: ' . $errmsg['message'] . $nl;
}
}
if (PEAR::isError($this->_packageXml['filelist'])) {
return $this->_packageXml['filelist'];
}
if (isset($this->_pear->pkginfo['provides'])) {
$this->_packageXml['provides'] = $this->_pear->pkginfo['provides'];
}
if ($this->_options['simpleoutput']) {
unset($this->_packageXml['provides']);
}
$this->_packageXml['release_deps'] = $this->_getDependencies();
$this->_updateChangeLog();
$common = &$this->_pear;
$warnings = $errors = array();
if (method_exists($common, 'setPackageFileManagerOptions')) {
$common->setPackageFileManagerOptions($this->_options);
}
$packagexml = $common->xmlFromInfo($this->_packageXml);
$common->validatePackageInfo($packagexml, $warnings, $errors,
$this->_options['packagedirectory']);
if (count($errors)) {
$ret = '';
$nl = (isset($debuginterface) && $debuginterface ? '<br />' : "\n");
foreach($errors as $errmsg) {
$ret .= $errmsg . $nl;
}
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_INVALID_PACKAGE, $nl, $ret);
}
if (count($warnings)) {
$nl = (isset($debuginterface) && $debuginterface ? '<br />' : "\n");
foreach($warnings as $errmsg) {
echo $errmsg . $nl;
}
}
if (!strpos($packagexml, '<!DOCTYPE')) {
// hack to fix pear
$packagexml = str_replace('<package version="1.0">',
'<!DOCTYPE package SYSTEM "' . $this->_options['doctype'] .
"\">\n<package version=\"1.0\">",
$packagexml);
}
if (isset($debuginterface)) {
if ($debuginterface) {
echo '<pre>' . htmlentities($packagexml) . '</pre>';
} else {
echo $packagexml;
}
return true;
}
$outputdir = ($this->_options['outputdirectory'] ?
$this->_options['outputdirectory'] : $this->_options['packagedirectory']);
if ((file_exists($outputdir . $this->_options['packagefile']) &&
is_writable($outputdir . $this->_options['packagefile']))
||
@touch($outputdir . $this->_options['packagefile'])) {
if ($fp = @fopen($outputdir . $this->_options['packagefile'] . '.tmp', "w")) {
$written = @fwrite($fp, $packagexml);
@fclose($fp);
if ($written === false) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_CANTWRITE_PKGFILE);
}
if (!@copy($outputdir . $this->_options['packagefile'] . '.tmp',
$outputdir . $this->_options['packagefile'])) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_CANTCOPY_PKGFILE);
} else {
@unlink($outputdir . $this->_options['packagefile'] . '.tmp');
return true;
}
} else {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_CANTOPEN_TMPPKGFILE,
$outputdir . $this->_options['packagefile'] . '.tmp');
}
} else {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_DEST_UNWRITABLE, $outputdir);
}
}
/**
* ALWAYS use this to test output before overwriting your package.xml!!
*
* This method instructs writePackageFile() to simply print the package.xml
* to output, either command-line or web-friendly (this is automatic
* based on the value of php_sapi_name())
* @uses writePackageFile() calls with the debug parameter set based on
* whether it is called from the command-line or web interface
*/
function debugPackageFile()
{
$webinterface = php_sapi_name() != 'cli';
return $this->writePackageFile($webinterface);
}
/**
* Store a warning on the warning stack
*/
function pushWarning($code, $info)
{
$this->_warningStack[] = array('code' => $code,
'message' => $this->_getMessage($code, $info));
}
/**
* Retrieve the list of warnings
* @return array
*/
function getWarnings()
{
$a = $this->_warningStack;
$this->_warningStack = array();
return $a;
}
/**
* Retrieve an error message from a code
* @access private
* @return string Error message
*/
function _getMessage($code, $info)
{
$msg = $GLOBALS['_PEAR_PACKAGEFILEMANAGER_ERRORS'][$this->_options['lang']][$code];
foreach ($info as $name => $value) {
$msg = str_replace('%' . $name . '%', $value, $msg);
}
return $msg;
}
/**
* Utility function to shorten error generation code
*
* {@source}
* @return PEAR_Error
* @static
*/
function raiseError($code, $i1 = '', $i2 = '')
{
return PEAR::raiseError('PEAR_PackageFileManager Error: ' .
sprintf($GLOBALS['_PEAR_PACKAGEFILEMANAGER_ERRORS'][$this->_options['lang']][$code],
$i1, $i2), $code);
}
/**
* Uses {@link PEAR_Common::analyzeSourceCode()} and {@link PEAR_Common::buildProvidesArray()}
* to create the <provides></provides> section of the package.xml
* @param PEAR_Common
* @param string path to source file
* @access private
*/
function _addProvides(&$pear, $file)
{
if (!($a = $pear->analyzeSourceCode($file))) {
return;
} else {
$pear->buildProvidesArray($a);
}
}
/**
* @uses getDirTag() generate the xml from the array
* @return string
* @access private
*/
function _getFileList()
{
$generatorclass = 'PEAR_PackageFileManager_' . $this->_options['filelistgenerator'];
$generator = new $generatorclass($this, $this->_options);
if ($this->_options['simpleoutput'] && is_a($this->_pear, 'PEAR_Common')) {
return $this->_getSimpleDirTag($this->_struc = $generator->getFileList());
}
return $this->_getDirTag($this->_struc = $generator->getFileList());
}
/**
* Recursively generate the <filelist> section's <dir> and <file> tags, but with
* simple human-readable output
* @param array|PEAR_Error the sorted directory structure, or an error
* from filelist generation
* @param false|string whether the parent directory has a role this should
* inherit
* @param integer indentation level
* @return array|PEAR_Error
* @access private
*/
function _getSimpleDirTag($struc, $role = false, $_curdir = '')
{
if (PEAR::isError($struc)) {
return $struc;
}
extract($this->_options);
$ret = array();
foreach($struc as $dir => $files) {
if (false && $dir === '/') {
// global directory role? overrides all exceptions except file exceptions
if (isset($dir_roles['/'])) {
$role = $dir_roles['/'];
}
return array(
'baseinstalldir' => $this->_options['baseinstalldir'],
'##files' => $this->_getSimpleDirTag($struc[$dir], $role, ''),
'name' => '/');
} else {
if (!isset($files['file'])) {
if (isset($dir_roles[$_curdir . $dir])) {
$myrole = $dir_roles[$_curdir . $dir];
} else {
$myrole = $role;
}
$ret[$dir] = array();
if ($dir == '/') {
$ret[$dir]['baseinstalldir'] = $this->_options['baseinstalldir'];
}
$ret[$dir]['name'] = $dir;
$recurdir = ($_curdir == '') ? $dir . '/' : $_curdir . $dir . '/';
if ($recurdir == '//') {
$recurdir = '';
}
$ret[$dir]['##files'] = $this->_getSimpleDirTag($files, $myrole, $recurdir);
} else {
$myrole = '';
if (!$role)
{
$myrole = false;
if (isset($exceptions[$files['path']])) {
$myrole = $exceptions[$files['path']];
} elseif (isset($roles[$files['ext']])) {
$myrole = $roles[$files['ext']];
} else {
$myrole = $roles['*'];
}
} else {
$myrole = $role;
if (isset($exceptions[$files['path']])) {
$myrole = $exceptions[$files['path']];
}
}
$test = explode('/', $files['path']);
foreach ($test as $subpath) {
if ($subpath == 'CVS') {
$this->pushWarning(PEAR_PACKAGEFILEMANAGER_CVS_PACKAGED,
array('path' => $files['path']));
}
}
$ret[$files['file']] = array('role' => $myrole);
if (isset($installexceptions[$files['path']])) {
$ret[$files['file']]['baseinstalldir'] =
$installexceptions[$files['path']];
}
if (isset($platformexceptions[$files['path']])) {
$ret[$files['file']]['platform'] = $platformexceptions[$files['path']];
}
if (isset($installas[$files['path']])) {
$ret[$files['file']]['install-as'] = $installas[$files['path']];
}
if (isset($replacements[$files['path']])) {
$ret[$files['file']]['replacements'] = $replacements[$files['path']];
}
if (isset($globalreplacements)) {
if (!isset($ret[$files['file']]['replacements'])) {
$ret[$files['file']]['replacements'] = array();
}
$ret[$files['file']]['replacements'] = array_merge(
$ret[$files['file']]['replacements'], $globalreplacements);
}
}
}
}
return $ret;
}
/**
* Recursively generate the <filelist> section's <dir> and <file> tags
* @param array|PEAR_Error the sorted directory structure, or an error
* from filelist generation
* @param false|string whether the parent directory has a role this should
* inherit
* @param integer indentation level
* @return array|PEAR_Error
* @access private
*/
function _getDirTag($struc, $role=false, $_curdir = '')
{
if (PEAR::isError($struc)) {
return $struc;
}
extract($this->_options);
$ret = array();
foreach($struc as $dir => $files) {
if ($dir === '/') {
// global directory role? overrides all exceptions except file exceptions
if (isset($dir_roles['/'])) {
$role = $dir_roles['/'];
}
return $this->_getDirTag($struc[$dir], $role, '');
} else {
if (!isset($files['file'])) {
$myrole = '';
if (isset($dir_roles[$_curdir . $dir])) {
$myrole = $dir_roles[$_curdir . $dir];
} elseif ($role) {
$myrole = $role;
}
$ret = array_merge($ret, $this->_getDirTag($files, $myrole, $_curdir . $dir . '/'));
} else {
$myrole = '';
if (!$role)
{
$myrole = false;
if (isset($exceptions[$files['path']])) {
$myrole = $exceptions[$files['path']];
} elseif (isset($roles[$files['ext']])) {
$myrole = $roles[$files['ext']];
} else {
$myrole = $roles['*'];
}
} else {
$myrole = $role;
if (isset($exceptions[$files['path']])) {
$myrole = $exceptions[$files['path']];
}
}
if (isset($installexceptions[$files['path']])) {
$bi = $installexceptions[$files['path']];
} else {
$bi = $this->_options['baseinstalldir'];
}
$test = explode('/', $files['path']);
foreach ($test as $subpath) {
if ($subpath == 'CVS') {
$this->pushWarning(PEAR_PACKAGEFILEMANAGER_CVS_PACKAGED, array('path' => $files['path']));
}
}
$ret[$files['path']] =
array('role' => $myrole,
'baseinstalldir' => $bi,
);
if (!isset($this->_options['simpleoutput'])) {
$md5sum = @md5_file($this->_options['packagedirectory'] . $files['path']);
if (!empty($md5sum)) {
$ret[$files['path']]['md5sum'] = $md5sum;
}
} elseif (isset($ret[$files['path']]['md5sum'])) {
unset($ret[$files['path']]['md5sum']);
}
if (isset($platformexceptions[$files['path']])) {
$ret[$files['path']]['platform'] = $platformexceptions[$files['path']];
}
if (isset($installas[$files['path']])) {
$ret[$files['path']]['install-as'] = $installas[$files['path']];
}
if (isset($replacements[$files['path']])) {
$ret[$files['path']]['replacements'] = $replacements[$files['path']];
}
if (isset($globalreplacements)) {
if (!isset($ret[$files['path']]['replacements'])) {
$ret[$files['path']]['replacements'] = array();
}
$ret[$files['path']]['replacements'] = array_merge(
$ret[$files['path']]['replacements'], $globalreplacements);
}
if ($myrole == 'php' && !$this->_options['simpleoutput']) {
$this->_addProvides($this->_pear, $files['fullpath']);
}
}
}
}
return $ret;
}
 
/**
* @param array
* @access private
*/
function _traverseFileArray($files, &$ret) {
foreach ($files as $file) {
if (!isset($file['fullpath'])) {
$this->_traverseFileArray($file, $ret);
} else {
$ret[] = $file['fullpath'];
}
}
}
 
/**
* Retrieve the 'deps' option passed to the constructor
* @access private
* @return array
*/
function _getDependencies()
{
if ($this->_detectDependencies) {
$this->_traverseFileArray($this->_struc, $ret);
$compatinfo = new PHP_CompatInfo();
$info = $compatinfo->parseArray($ret);
$ret = $this->addDependency('php',$info['version'],'ge','php',false);
if (is_a($ret, 'PEAR_Error')) {
return $ret;
}
foreach ($info['extensions'] as $ext) {
$this->addDependency($ext, '', 'has', 'ext', false);
}
}
if (isset($this->_packageXml['release_deps']) &&
is_array($this->_packageXml['release_deps'])) {
return $this->_packageXml['release_deps'];
} else {
return array();
}
}
 
/**
* Creates a changelog entry with the current release
* notes and dates, or overwrites a previous creation
* @access private
*/
function _updateChangeLog()
{
$curlog = $oldchangelog = false;
if (!isset($this->_packageXml['changelog'])) {
$changelog = array();
if (isset($this->_oldPackageXml['release_notes'])) {
$changelog['release_notes'] = $this->_oldPackageXml['release_notes'];
}
if (isset($this->_oldPackageXml['version'])) {
$changelog['version'] = $this->_oldPackageXml['version'];
}
if (isset($this->_oldPackageXml['release_date'])) {
$changelog['release_date'] = $this->_oldPackageXml['release_date'];
}
if (isset($this->_oldPackageXml['release_license'])) {
$changelog['release_license'] = $this->_oldPackageXml['release_license'];
}
if (isset($this->_oldPackageXml['release_state'])) {
$changelog['release_state'] = $this->_oldPackageXml['release_state'];
}
if (count($changelog)) {
$this->_packageXml['changelog'] = array($changelog);
} else {
$this->_packageXml['changelog'] = array();
}
} else {
if (isset($this->_oldPackageXml['release_notes'])) {
$oldchangelog['release_notes'] = $this->_oldPackageXml['release_notes'];
}
if (isset($this->_oldPackageXml['version'])) {
$oldchangelog['version'] = $this->_oldPackageXml['version'];
}
if (isset($this->_oldPackageXml['release_date'])) {
$oldchangelog['release_date'] = $this->_oldPackageXml['release_date'];
}
if (isset($this->_oldPackageXml['release_license'])) {
$oldchangelog['release_license'] = $this->_oldPackageXml['release_license'];
}
if (isset($this->_oldPackageXml['release_state'])) {
$oldchangelog['release_state'] = $this->_oldPackageXml['release_state'];
}
}
$hasoldversion = false;
foreach($this->_packageXml['changelog'] as $index => $changelog) {
if ($oldchangelog && isset($oldchangelog['version'])
&& strnatcasecmp($oldchangelog['version'], $changelog['version']) == 0) {
$hasoldversion = true;
}
if (isset($changelog['version']) && strnatcasecmp($changelog['version'], $this->_options['version']) == 0) {
$curlog = $index;
}
if (isset($this->_packageXml['changelog'][$index]['release_notes'])) {
$this->_packageXml['changelog'][$index]['release_notes'] = trim($changelog['release_notes']);
}
// the parsing of the release notes adds a \n for some reason
}
if (!$hasoldversion && $oldchangelog && count($oldchangelog)
&& $oldchangelog['version'] != $this->_options['version']) {
$this->_packageXml['changelog'][] = $oldchangelog;
}
$notes = ($this->_options['changelognotes'] ?
$this->_options['changelognotes'] : $this->_options['notes']);
$changelog = array('version' => $this->_options['version'],
'release_date' => date('Y-m-d'),
'release_license' => $this->_options['license'],
'release_state' => $this->_options['state'],
'release_notes' => $notes,
);
if ($curlog !== false) {
$this->_packageXml['changelog'][$curlog] = $changelog;
} else {
$this->_packageXml['changelog'][] = $changelog;
}
usort($this->_packageXml['changelog'], array($this, '_changelogsort'));
}
/**
* @static
* @access private
*/
function _changelogsort($a, $b)
{
if ($this->_options['changelogoldtonew']) {
$c = strtotime($a['release_date']);
$d = strtotime($b['release_date']);
$v1 = $a['version'];
$v2 = $b['version'];
} else {
$d = strtotime($a['release_date']);
$c = strtotime($b['release_date']);
$v2 = $a['version'];
$v1 = $b['version'];
}
if ($c - $d > 0) {
return 1;
} elseif ($c - $d < 0) {
return -1;
}
return version_compare($v1, $v2);
}
 
/**
* @return true|PEAR_Error
* @uses _generateNewPackageXML() if no package.xml is found, it
* calls this to create a new one
* @param string full path to package file
* @param string name of package file
* @throws PEAR_PACKAGEFILEMANAGER_PATH_DOESNT_EXIST
* @access private
*/
function _getExistingPackageXML($path, $packagefile = 'package.xml')
{
if (is_string($path) && is_dir($path)) {
$contents = false;
if (file_exists($path . $packagefile)) {
$contents = file_get_contents($path . $packagefile);
}
if (!$contents) {
return $this->_generateNewPackageXML();
} else {
$PEAR_Common = $this->_options['pearcommonclass'];
if (!class_exists($PEAR_Common)) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS);
}
$common = new $PEAR_Common;
if (is_a($common, 'PEAR_Common')) {
$this->_oldPackageXml =
$this->_packageXml = $common->infoFromString($contents);
} else { // new way
require_once 'PEAR/PackageFile.php';
$z = &PEAR_Config::singleton();
$pkg = &new PEAR_PackageFile($z);
$pf = &$pkg->fromXmlString($contents, PEAR_VALIDATE_DOWNLOADING, $path . $packagefile);
if (PEAR::isError($pf)) {
return $pf;
}
if ($pf->getPackagexmlVersion() != '1.0') {
return PEAR::raiseError('PEAR_PackageFileManager can only manage ' .
'package.xml version 1.0, use PEAR_PackageFileManager_v2 for newer' .
' package files');
}
$this->_oldPackageXml =
$this->_packageXml = $pf->toArray();
}
if (PEAR::isError($this->_packageXml)) {
return $this->_packageXml;
}
if ($this->_options['cleardependencies']) {
$this->_packageXml['release_deps'] = $this->_options['deps'];
}
if ($this->_options['deps'] !== false) {
$this->_packageXml['release_deps'] = $this->_options['deps'];
} else {
if (isset($this->_packageXml['release_deps'])) {
$this->_options['deps'] = $this->_packageXml['release_deps'];
}
}
if ($this->_options['maintainers'] !== false) {
$this->_packageXml['maintainers'] = $this->_options['maintainers'];
} else {
$this->_options['maintainers'] = $this->_packageXml['maintainers'];
}
unset($this->_packageXml['filelist']);
unset($this->_packageXml['provides']);
}
return true;
} else {
if (!is_string($path)) {
$path = gettype($path);
}
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_PATH_DOESNT_EXIST,
$path);
}
}
/**
* Create the structure for a new package.xml
*
* @uses $_packageXml emulates reading in a package.xml
* by using the package, summary and description
* options
* @return true|PEAR_Error
* @access private
*/
function _generateNewPackageXML()
{
$this->_oldPackageXml = false;
if (!isset($this->_options['package'])) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_NOPACKAGE);
}
if (!isset($this->_options['summary'])) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_NOSUMMARY);
}
if (!isset($this->_options['description'])) {
return $this->raiseError(PEAR_PACKAGEFILEMANAGER_NODESC);
}
$this->_packageXml = array();
$this->_packageXml['package'] = $this->_options['package'];
$this->_packageXml['summary'] = $this->_options['summary'];
$this->_packageXml['description'] = $this->_options['description'];
$this->_packageXml['changelog'] = array();
if ($this->_options['deps'] !== false) {
$this->_packageXml['release_deps'] = $this->_options['deps'];
} else {
$this->_packageXml['release_deps'] = $this->_options['deps'] = array();
}
if ($this->_options['maintainers'] !== false) {
$this->_packageXml['maintainers'] = $this->_options['maintainers'];
} else {
$this->_packageXml['maintainers'] = $this->_options['maintainers'] = array();
}
return true;
}
}
 
if (!function_exists('file_get_contents')) {
/**
* @ignore
*/
function file_get_contents($path, $use_include_path = null, $context = null)
{
$a = @file($path, $use_include_path, $context);
if (is_array($a)) {
return implode('', $a);
} else {
return false;
}
}
}
?>
/trunk/bibliotheque/pear/PEAR/Builder.php
4,15 → 4,22
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Builder.php,v 1.31 2007/01/10 05:32:51 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*
*
* TODO: log output parameters in PECL command line
* TODO: msdev path in configuration
*/
22,8 → 29,6
*/
require_once 'PEAR/Common.php';
require_once 'PEAR/PackageFile.php';
require_once 'System.php';
 
/**
* Class to handle building (compiling) extensions.
*
31,9 → 36,9
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @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
40,6 → 45,8
*/
class PEAR_Builder extends PEAR_Common
{
// {{{ properties
 
var $php_api_version = 0;
var $zend_module_api_no = 0;
var $zend_extension_api_no = 0;
55,6 → 62,8
// used for msdev builds
var $_lastline = null;
var $_firstline = null;
// }}}
// {{{ constructor
 
/**
* PEAR_Builder constructor.
63,12 → 72,16
*
* @access public
*/
function __construct(&$ui)
function PEAR_Builder(&$ui)
{
parent::__construct();
parent::PEAR_Common();
$this->setFrontendObject($ui);
}
 
// }}}
 
// {{{ _build_win32()
 
/**
* Build an extension from source on windows.
* requires msdev
79,7 → 92,7
$pkg = $descfile;
$descfile = $pkg->getPackageFile();
} else {
$pf = new PEAR_PackageFile($this->config, $this->debug);
$pf = &new PEAR_PackageFile($this->config, $this->debug);
$pkg = &$pf->fromPackageFile($descfile, PEAR_VALIDATE_NORMAL);
if (PEAR::isError($pkg)) {
return $pkg;
91,15 → 104,14
if (!file_exists($dir) || !is_dir($dir) || !chdir($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)) {
if (chdir($vdir)) {
$dir = getcwd();
} else {
return $this->raiseError("could not chdir to " . realpath($vdir));
}
 
$dir = getcwd();
}
 
$this->log(2, "building in $dir");
124,7 → 136,7
$buildtype = $matches[2];
}
 
if (preg_match('/(.*)?\s-\s(\d+).*?(\d+)/', $this->_lastline, $matches)) {
if (preg_match('/(.*)?\s-\s(\d+).*?(\d+)/',$this->_lastline,$matches)) {
if ($matches[2]) {
// there were errors in the build
return $this->raiseError("There were errors during compilation.");
146,7 → 158,7
$buildtype.'").*?'.
'\/out:"(.*?)"/is';
 
if ($dsptext && preg_match($regex, $dsptext, $matches)) {
if ($dsptext && preg_match($regex,$dsptext,$matches)) {
// what we get back is a relative path to the output file itself.
$outfile = realpath($matches[2]);
} else {
176,7 → 188,9
$this->_lastline = $data;
call_user_func($this->current_callback, $what, $data);
}
// }}}
 
// {{{ _harventInstDir
/**
* @param string
* @param string
217,10 → 231,14
return $ret;
}
 
// }}}
 
// {{{ build()
 
/**
* Build an extension from source. Runs "phpize" in the source
* directory, but compiles in a temporary directory
* (TMPDIR/pear-build-USER/PACKAGE-VERSION).
* (/var/tmp/pear-build-USER/PACKAGE-VERSION).
*
* @param string|PEAR_PackageFile_v* $descfile path to XML package description file, or
* a PEAR_PackageFile object
242,80 → 260,39
*/
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") {
return $this->_build_win32($descfile, $callback);
return $this->_build_win32($descfile,$callback);
}
 
if (PEAR_OS != 'Unix') {
return $this->raiseError("building extensions not supported on this platform");
}
 
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);
$pf = &new PEAR_PackageFile($this->config);
$pkg = &$pf->fromPackageFile($descfile, PEAR_VALIDATE_NORMAL);
if (PEAR::isError($pkg)) {
return $pkg;
}
$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;
}
}
 
$dir = dirname($descfile);
$old_cwd = getcwd();
if (!file_exists($dir) || !is_dir($dir) || !chdir($dir)) {
return $this->raiseError("could not chdir to $dir");
}
 
$vdir = $pkg->getPackage() . '-' . $pkg->getVersion();
if (is_dir($vdir)) {
chdir($vdir);
}
 
$dir = getcwd();
$this->log(2, "building in $dir");
putenv('PATH=' . $this->config->get('bin_dir') . ':' . getenv('PATH'));
$err = $this->_runCommand($this->config->get('php_prefix')
. "phpize" .
$this->config->get('php_suffix'),
array(&$this, 'phpizeCallback'));
$err = $this->_runCommand("phpize", array(&$this, 'phpizeCallback'));
if (PEAR::isError($err)) {
return $err;
}
 
if (!$err) {
return $this->raiseError("`phpize' failed");
}
322,16 → 299,6
 
// {{{ start of interactive part
$configure_command = "$dir/configure";
 
$phpConfigName = $this->config->get('php_prefix')
. 'php-config'
. $this->config->get('php_suffix');
$phpConfigPath = System::which($phpConfigName);
if ($phpConfigPath !== false) {
$configure_command .= ' --with-php-config='
. $phpConfigPath;
}
 
$configure_options = $pkg->getConfigureOptions();
if ($configure_options) {
foreach ($configure_options as $o) {
351,12 → 318,10
// }}} end of interactive part
 
// FIXME make configurable
if (!$user=getenv('USER')) {
if(!$user=getenv('USER')){
$user='defaultuser';
}
 
$tmpdir = $this->config->get('temp_dir');
$build_basedir = System::mktemp(' -t "' . $tmpdir . '" -d "pear-build-' . $user . '"');
$build_basedir = "/var/tmp/pear-build-$user";
$build_dir = "$build_basedir/$vdir";
$inst_dir = "$build_basedir/install-$vdir";
$this->log(1, "building in $build_dir");
363,11 → 328,9
if (is_dir($build_dir)) {
System::rm(array('-rf', $build_dir));
}
 
if (!System::mkDir(array('-p', $build_dir))) {
return $this->raiseError("could not create build dir: $build_dir");
}
 
$this->addTempFile($build_dir);
if (!System::mkDir(array('-p', $inst_dir))) {
return $this->raiseError("could not create temporary install dir: $inst_dir");
374,18 → 337,21
}
$this->addTempFile($inst_dir);
 
$make_command = getenv('MAKE') ? getenv('MAKE') : 'make';
 
if (getenv('MAKE')) {
$make_command = getenv('MAKE');
} else {
$make_command = 'make';
}
$to_run = array(
$configure_command,
$make_command,
"$make_command INSTALL_ROOT=\"$inst_dir\" install",
"find \"$inst_dir\" | xargs ls -dils"
"find \"$inst_dir\" -ls"
);
if (!file_exists($build_dir) || !is_dir($build_dir) || !chdir($build_dir)) {
return $this->raiseError("could not chdir to $build_dir");
}
putenv('PHP_PEAR_VERSION=1.10.1');
putenv('PHP_PEAR_VERSION=1.5.1');
foreach ($to_run as $cmd) {
$err = $this->_runCommand($cmd, $callback);
if (PEAR::isError($err)) {
402,14 → 368,15
return $this->raiseError("no `modules' directory found");
}
$built_files = array();
$prefix = exec($this->config->get('php_prefix')
. "php-config" .
$this->config->get('php_suffix') . " --prefix");
$prefix = exec("php-config --prefix");
$this->_harvestInstDir($prefix, $inst_dir . DIRECTORY_SEPARATOR . $prefix, $built_files);
chdir($old_cwd);
return $built_files;
}
 
// }}}
// {{{ phpizeCallback()
 
/**
* Message callback function used when running the "phpize"
* program. Extracts the API numbers used. Ignores other message
443,6 → 410,9
}
}
 
// }}}
// {{{ _runCommand()
 
/**
* Run an external command, using a message callback to report
* output. The command will be run through popen and output is
481,12 → 451,18
if ($callback && isset($olddbg)) {
$callback[0]->debug = $olddbg;
}
 
$exitcode = is_resource($pp) ? pclose($pp) : -1;
if (is_resource($pp)) {
$exitcode = pclose($pp);
} else {
$exitcode = -1;
}
return ($exitcode == 0);
}
 
function log($level, $msg, $append_crlf = true)
// }}}
// {{{ log()
 
function log($level, $msg)
{
if ($this->current_callback) {
if ($this->debug >= $level) {
494,6 → 470,10
}
return;
}
return parent::log($level, $msg, $append_crlf);
return PEAR_Common::log($level, $msg);
}
 
// }}}
}
 
?>
/trunk/bibliotheque/pear/PEAR/REST/13.php
File deleted
\ No newline at end of file
/trunk/bibliotheque/pear/PEAR/REST/10.php
4,11 → 4,18
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: 10.php,v 1.43 2006/11/01 05:09:05 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a12
*/
24,9 → 31,9
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a12
*/
36,9 → 43,9
* @var PEAR_REST
*/
var $_rest;
function __construct($config, $options = array())
function PEAR_REST_10($config, $options = array())
{
$this->_rest = new PEAR_REST($config, $options);
$this->_rest = &new PEAR_REST($config, $options);
}
 
/**
58,40 → 65,39
* @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)
function getDownloadURL($base, $packageinfo, $prefstate, $installed)
{
$channel = $packageinfo['channel'];
$package = $packageinfo['package'];
$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);
$state = $version = null;
if (isset($packageinfo['state'])) {
$state = $packageinfo['state'];
}
if (isset($packageinfo['version'])) {
$version = $packageinfo['version'];
}
$info = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . '/allreleases.xml');
if (PEAR::isError($info)) {
return PEAR::raiseError('No releases available for package "' .
$channel . '/' . $package . '"');
}
 
if (!isset($info['r'])) {
return false;
}
 
$release = $found = false;
$found = false;
$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 (isset($state)) {
// try our preferred state first
if ($release['s'] == $state) {
116,37 → 122,38
}
}
}
 
return $this->_returnDownloadURL($base, $package, $release, $info, $found, false, $channel);
return $this->_returnDownloadURL($base, $package, $release, $info, $found);
}
 
function getDepDownloadURL($base, $xsdversion, $dependency, $deppackage,
$prefstate = 'stable', $installed = false, $channel = false)
$prefstate = 'stable', $installed = false)
{
$channel = $dependency['channel'];
$package = $dependency['name'];
$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);
$state = $version = null;
if (isset($packageinfo['state'])) {
$state = $packageinfo['state'];
}
if (isset($packageinfo['version'])) {
$version = $packageinfo['version'];
}
$info = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . '/allreleases.xml');
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'];
170,6 → 177,7
break;
}
} else {
$pinfo['package'] = $dependency['name'];
$min = isset($dependency['min']) ? $dependency['min'] : false;
$max = isset($dependency['max']) ? $dependency['max'] : false;
$recommended = isset($dependency['recommended']) ?
180,7 → 188,8
}
}
}
$release = $found = false;
$found = false;
$release = false;
if (!is_array($info['r']) || !isset($info['r'][0])) {
$info['r'] = array($info['r']);
}
221,7 → 230,7
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);
return $this->_returnDownloadURL($base, $package, $release, $info, true);
}
}
}
239,7 → 248,7
break;
}
}
return $this->_returnDownloadURL($base, $package, $release, $info, $found, false, $channel);
return $this->_returnDownloadURL($base, $package, $release, $info, $found);
}
 
/**
250,244 → 259,123
* @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
* @param bool $found determines whether the release was found or this is the next
* best alternative
* @return array|PEAR_Error
* @access private
*/
function _returnDownloadURL($base, $package, $release, $info, $found, $phpversion = false, $channel = false)
function _returnDownloadURL($base, $package, $release, $info, $found)
{
if (!$found) {
$release = $info['r'][0];
}
 
$packageLower = strtolower($package);
$pinfo = $this->_rest->retrieveCacheFirst($base . 'p/' . $packageLower . '/' .
'info.xml', false, false, $channel);
$pinfo = $this->_rest->retrieveCacheFirst($base . 'p/' . strtolower($package) . '/' .
'info.xml');
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);
$releaseinfo = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/' .
$release['v'] . '.xml');
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);
$packagexml = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/' .
'deps.' . $release['v'] . '.txt', false, true);
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;
}
 
$allinfo = $this->_rest->retrieveData($base . 'r/' . strtolower($package) .
'/allreleases.xml');
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['name'] = $entry['p'];
$comp['channel'] = $entry['c'];
$comp['min'] = $entry['min'];
$comp['max'] = $entry['max'];
$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']));
}
$deprecated = array('channel' => (string) $pinfo['dc'],
'package' => trim($pinfo['dp']['_content']));
} else {
$deprecated = false;
}
 
$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
array('version' => $releaseinfo['v'],
'info' => $packagexml,
'package' => $releaseinfo['p']['_content'],
'stability' => $releaseinfo['st'],
'url' => $releaseinfo['g'],
'compatible' => $compatible,
'deprecated' => $deprecated,
);
} else {
return
array('version' => $releaseinfo['v'],
'package' => $releaseinfo['p']['_content'],
'stability' => $releaseinfo['st'],
'info' => $packagexml,
'compatible' => $compatible,
'deprecated' => $deprecated,
);
}
 
$return['php'] = $phpversion;
return $return;
}
 
function listPackages($base, $channel = false)
function listPackages($base)
{
$packagelist = $this->_rest->retrieveData($base . 'p/packages.xml', false, false, $channel);
$packagelist = $this->_rest->retrieveData($base . 'p/packages.xml');
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)
function listAll($base, $dostable, $basic = true, $searchpackage = false, $searchsummary = 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);
$packagelist = $this->_rest->retrieveData($base . 'p/packages.xml');
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);
$ui->log('Retrieving data...0%', false);
}
$ret = array();
if (!is_array($packagelist) || !isset($packagelist['p'])) {
496,17 → 384,6
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) {
520,14 → 397,13
$next += .1;
}
}
 
if ($basic) { // remote-list command
if ($dostable) {
$latest = $this->_rest->retrieveData($base . 'r/' . strtolower($package) .
'/stable.txt', false, false, $channel);
'/stable.txt');
} else {
$latest = $this->_rest->retrieveData($base . 'r/' . strtolower($package) .
'/latest.txt', false, false, $channel);
'/latest.txt');
}
if (PEAR::isError($latest)) {
$latest = false;
534,7 → 410,7
}
$info = array('stable' => $latest);
} else { // list-all command
$inf = $this->_rest->retrieveData($base . 'p/' . strtolower($package) . '/info.xml', false, false, $channel);
$inf = $this->_rest->retrieveData($base . 'p/' . strtolower($package) . '/info.xml');
if (PEAR::isError($inf)) {
PEAR::popErrorHandling();
return $inf;
549,7 → 425,7
};
}
$releases = $this->_rest->retrieveData($base . 'r/' . strtolower($package) .
'/allreleases.xml', false, false, $channel);
'/allreleases.xml');
if (PEAR::isError($releases)) {
continue;
}
603,7 → 479,7
}
if ($latest) {
$d = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/deps.' .
$latest . '.txt', false, false, $channel);
$latest . '.txt');
if (!PEAR::isError($d)) {
$d = unserialize($d);
if ($d) {
647,139 → 523,109
return $ret;
}
 
function listLatestUpgrades($base, $pref_state, $installed, $channel, &$reg)
function listLatestUpgrades($base, $state, $installed, $channel, &$reg)
{
$packagelist = $this->_rest->retrieveData($base . 'p/packages.xml', false, false, $channel);
$packagelist = $this->_rest->retrieveData($base . 'p/packages.xml');
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']);
}
 
if ($state) {
$states = $this->betterStates($state, true);
}
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);
'/allreleases.xml');
PEAR::popErrorHandling();
if (PEAR::isError($info)) {
continue; // no remote releases
}
 
if (!isset($info['r'])) {
continue;
}
 
$release = $found = false;
$found = false;
$release = 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;
continue;
}
 
// 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))) {
if ($state) {
if (in_array($release['s'], $states)) {
$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;
}
}
} else {
$found = true;
break;
}
}
 
if (!$found) {
continue;
}
 
$relinfo = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/' .
$release['v'] . '.xml', false, false, $channel);
$relinfo = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/' .
$release['v'] . '.xml');
if (PEAR::isError($relinfo)) {
return $relinfo;
}
 
$ret[$package] = array(
'version' => $release['v'],
'state' => $release['s'],
'filesize' => $relinfo['f'],
);
'version' => $release['v'],
'state' => $release['s'],
'filesize' => $relinfo['f'],
);
}
 
return $ret;
}
 
function packageInfo($base, $package, $channel = false)
function packageInfo($base, $package)
{
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$pinfo = $this->_rest->retrieveData($base . 'p/' . strtolower($package) . '/info.xml', false, false, $channel);
$pinfo = $this->_rest->retrieveData($base . 'p/' . strtolower($package) . '/info.xml');
if (PEAR::isError($pinfo)) {
PEAR::popErrorHandling();
return PEAR::raiseError('Unknown package: "' . $package . '" in channel "' . $channel . '"' . "\n". 'Debug: ' .
$pinfo->getMessage());
return PEAR::raiseError('Unknown package: "' . $package . '" (Debug: ' .
$pinfo->getMessage() . ')');
}
 
$releases = array();
$allreleases = $this->_rest->retrieveData($base . 'r/' . strtolower($package) .
'/allreleases.xml', false, false, $channel);
'/allreleases.xml');
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);
$release['v'] . '.txt');
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);
 
. '/' . $release['v'] . '.xml');
if (PEAR::isError($info)) {
continue;
}
 
$releases[$release['v']] = array(
'doneby' => $info['m'],
'license' => $info['l'],
794,24 → 640,13
} 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']));
}
$deprecated = array('channel' => (string) $pinfo['dc'],
'package' => trim($pinfo['dp']['_content']));
} else {
$deprecated = false;
}
 
if (!isset($latest)) {
$latest = '';
}
 
return array(
'name' => $pinfo['n'],
'channel' => $pinfo['c'],
840,31 → 675,10
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;
}
}
}
?>
/trunk/bibliotheque/pear/PEAR/REST/11.php
4,11 → 4,18
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: 11.php,v 1.8 2007/01/27 16:10:23 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.3
*/
24,9 → 31,9
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.3
*/
37,29 → 44,27
*/
var $_rest;
 
function __construct($config, $options = array())
function PEAR_REST_11($config, $options = array())
{
$this->_rest = new PEAR_REST($config, $options);
$this->_rest = &new PEAR_REST($config, $options);
}
 
function listAll($base, $dostable, $basic = true, $searchpackage = false, $searchsummary = false, $channel = false)
function listAll($base, $dostable, $basic = true)
{
$categorylist = $this->_rest->retrieveData($base . 'c/categories.xml', false, false, $channel);
$categorylist = $this->_rest->retrieveData($base . 'c/categories.xml');
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);
'c/' . urlencode($category) . '/packagesinfo.xml');
 
if (PEAR::isError($packagesinfo)) {
continue;
74,12 → 79,8
}
 
foreach ($packagesinfo['pi'] as $packageinfo) {
if (empty($packageinfo)) {
continue;
}
 
$info = $packageinfo['p'];
$package = $info['n'];
$info = $packageinfo['p'];
$package = $info['n'];
$releases = isset($packageinfo['a']) ? $packageinfo['a'] : false;
unset($latest);
unset($unstable);
90,7 → 91,6
if (!isset($releases['r'][0])) {
$releases['r'] = array($releases['r']);
}
 
foreach ($releases['r'] as $release) {
if (!isset($latest)) {
if ($dostable && $release['s'] == 'stable') {
102,7 → 102,6
$state = $release['s'];
}
}
 
if (!isset($stable) && $release['s'] == 'stable') {
$stable = $release['v'];
if (!isset($unstable)) {
109,16 → 108,13
$unstable = $stable;
}
}
 
if (!isset($unstable) && $release['s'] != 'stable') {
$unstable = $release['v'];
$latest = $unstable = $release['v'];
$state = $release['s'];
}
 
if (isset($latest) && !isset($state)) {
$state = $release['s'];
}
 
if (isset($latest) && isset($stable) && isset($unstable)) {
break;
}
129,7 → 125,6
if (!isset($latest)) {
$latest = false;
}
 
if ($dostable) {
// $state is not set if there are no releases
if (isset($state) && $state == 'stable') {
140,11 → 135,11
} else {
$ret[$package] = array('stable' => $latest);
}
 
continue;
}
 
// list-all command
$deps = array();
if (!isset($unstable)) {
$unstable = false;
$state = 'stable';
159,14 → 154,13
$latest = false;
}
 
$deps = array();
if ($latest && isset($packageinfo['deps'])) {
if (!is_array($packageinfo['deps']) ||
!isset($packageinfo['deps'][0])
) {
$packageinfo['deps'] = array($packageinfo['deps']);
if ($latest && $packageinfo['deps'] !== null) {
if (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) {
173,150 → 167,40
$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
);
$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
*
337,4 → 221,4
return array_slice($states, $i + 1);
}
}
?>
?>
/trunk/bibliotheque/pear/PEAR/Command/Auth.xml
1,14 → 1,11
<commands version="1.0">
<login>
<summary>Connects and authenticates to remote server [Deprecated in favor of channel-login]</summary>
<summary>Connects and authenticates to remote server</summary>
<shortcut>li</shortcut>
<function>doLogin</function>
<shortcut>li</shortcut>
<options />
<doc>&lt;channel name&gt;
WARNING: This function is deprecated in favor of using channel-login
 
Log in to a remote channel server. If &lt;channel name&gt; is not supplied,
the default channel is used. To use remote functions in the installer
<doc>
Log in to the remote server. 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
16,13 → 13,11
operations on the remote server.</doc>
</login>
<logout>
<summary>Logs out from the remote server [Deprecated in favor of channel-logout]</summary>
<summary>Logs out from the remote server</summary>
<shortcut>lo</shortcut>
<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>
/trunk/bibliotheque/pear/PEAR/Command/Mirror.php
4,11 → 4,18
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Mirror.php,v 1.18 2006/03/02 18:14:13 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.2.0
*/
24,14 → 31,16
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.2.0
*/
class PEAR_Command_Mirror extends PEAR_Command_Common
{
// {{{ properties
 
var $commands = array(
'download-all' => array(
'summary' => 'Downloads each available package from the default channel',
52,6 → 61,10
),
);
 
// }}}
 
// {{{ constructor
 
/**
* PEAR_Command_Mirror constructor.
*
59,11 → 72,13
* @param object PEAR_Frontend a reference to an frontend
* @param object PEAR_Config a reference to the configuration data
*/
function __construct(&$ui, &$config)
function PEAR_Command_Mirror(&$ui, &$config)
{
parent::__construct($ui, $config);
parent::PEAR_Command_Common($ui, $config);
}
 
// }}}
 
/**
* For unit-testing
*/
73,6 → 88,7
return $a;
}
 
// {{{ doDownloadAll()
/**
* retrieves a list of avaible Packages from master server
* and downloads them
81,8 → 97,8
* @param string $command the command
* @param array $options the command options before the command
* @param array $params the stuff after the command name
* @return bool true if successful
* @throw PEAR_Error
* @return bool true if succesful
* @throw PEAR_Error
*/
function doDownloadAll($command, $options, $params)
{
95,34 → 111,32
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));
$remoteInfo = array_flip($rest->listPackages($base));
} else {
$remote = &$this->config->getRemote();
$stable = ($this->config->get('preferred_state') == 'stable');
$remoteInfo = $remote->call("package.listAll", true, $stable, false);
}
 
if (PEAR::isError($remoteInfo)) {
return $remoteInfo;
}
 
$cmd = &$this->factory("download");
if (PEAR::isError($cmd)) {
return $cmd;
}
 
$this->ui->outputData('Using Preferred State of ' .
$this->config->get('preferred_state'));
$this->ui->outputData('Gathering release information, please wait...');
 
/**
* Error handling not necessary, because already done by
* Error handling not necessary, because already done by
* the download command
*/
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
132,7 → 146,8
if (PEAR::isError($err)) {
$this->ui->outputData($err->getMessage());
}
 
return true;
}
 
// }}}
}
/trunk/bibliotheque/pear/PEAR/Command/Test.php
4,13 → 4,20
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Test.php,v 1.15 2007/02/17 17:51:25 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
28,9 → 35,9
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
37,6 → 44,8
 
class PEAR_Command_Test extends PEAR_Command_Common
{
// {{{ properties
 
var $commands = array(
'run-tests' => array(
'summary' => 'Run Regression Tests',
70,8 → 79,7
),
'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.',
'doc' => 'Search parameters for AllTests.php, and use that to run phpunit-based tests',
),
'tapoutput' => array(
'shortopt' => 't',
82,14 → 90,6
'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+)',
),
'showdiff' => array(
'shortopt' => 'd',
'doc' => 'Output diff on test failure',
),
),
'doc' => '[testfile|dir ...]
Run regression tests with PHP\'s regression testing script (run-tests.php).',
98,33 → 98,42
 
var $output;
 
// }}}
// {{{ constructor
 
/**
* PEAR_Command_Test constructor.
*
* @access public
*/
function __construct(&$ui, &$config)
function PEAR_Command_Test(&$ui, &$config)
{
parent::__construct($ui, $config);
parent::PEAR_Command_Common($ui, $config);
}
 
// }}}
// {{{ doRunTests()
 
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 'PEAR/RunTest.php';
require_once 'System.php';
$log = new PEAR_Common;
$log->ui = &$this->ui; // slightly hacky, but it will work
$run = new PEAR_RunTest($log, $options);
$tests = array();
$depth = isset($options['recur']) ? 14 : 1;
 
if (isset($options['recur'])) {
$depth = 4;
} else {
$depth = 1;
}
if (!count($params)) {
$params[] = '.';
}
 
if (isset($options['package'])) {
$oldparams = $params;
$params = array();
134,30 → 143,29
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;
if (isset($options['phpunit'])) {
if (!preg_match('/AllTests\.php$/i', $name)) {
continue;
}
} else {
if (!preg_match('/\.phpt$/', $name)) {
continue;
}
}
$params[] = $atts['installed_as'];
}
}
}
 
foreach ($params as $p) {
if (is_dir($p)) {
if (isset($options['phpunit'])) {
164,115 → 172,75
$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;
} else {
$dir = System::find(array($p, '-type', 'f',
'-maxdepth', $depth,
'-name', '*.phpt'));
}
 
$args = array($p, '-type', 'f', '-name', '*.phpt');
$tests = array_merge($tests, $dir);
} 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);
if (!preg_match('/AllTests\.php$/i', $p)) {
continue;
}
$tests[] = $p;
} else {
if (!file_exists($p)) {
if (!preg_match('/\.phpt$/', $p)) {
$p .= '.phpt';
}
$dir = System::find(array(dirname($p), '-type', 'f',
'-maxdepth', $depth,
'-name', $p));
$tests = array_merge($tests, $dir);
} else {
$tests[] = $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);
$this->ui->outputData('Running ' . count($tests) . ' tests', $command);
$start = time();
if (isset($options['realtimelog']) && file_exists('run-tests.log')) {
unlink('run-tests.log');
if (isset($options['realtimelog'])) {
if (file_exists('run-tests.log')) {
unlink('run-tests.log');
}
}
 
if (isset($options['tapoutput'])) {
$tap = '1..' . $tests_count . "\n";
$tap = '1..' . count($tests) . "\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;
$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...");
fwrite($fp, "Running test $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);
}
$result = $run->run($t, $ini_settings);
PEAR::staticPopErrorHandling();
if (PEAR::isError($result)) {
$this->ui->log($result->getMessage());
continue;
}
 
if (isset($options['tapoutput'])) {
$tap .= $result[0] . ' ' . $i . $result[1] . "\n";
$i++;
continue;
}
 
if (isset($options['realtimelog'])) {
$fp = @fopen('run-tests.log', 'a');
if ($fp) {
280,20 → 248,16
fclose($fp);
}
}
 
if ($result == 'FAILED') {
$failed[] = $t;
$failed[] = $t;
}
if ($result == 'PASSED') {
$passed[] = $t;
$passed[] = $t;
}
if ($result == 'SKIPPED') {
$skipped[] = $t;
$skipped[] = $t;
}
 
$j++;
}
 
$total = date('i:s', time() - $start);
if (isset($options['tapoutput'])) {
$fp = @fopen('run-tests.log', 'w');
308,14 → 272,15
$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";
$output .= count($failed) . " FAILED TESTS:\n";
foreach ($failed as $failure) {
$output .= $failure . "\n";
}
if (isset($options['realtimelog'])) {
$fp = @fopen('run-tests.log', 'a');
} else {
$fp = @fopen('run-tests.log', 'w');
}
 
$mode = isset($options['realtimelog']) ? 'a' : 'w';
$fp = @fopen('run-tests.log', $mode);
 
if ($fp) {
fwrite($fp, $output, strlen($output));
fclose($fp);
329,15 → 294,15
$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);
}
$this->ui->outputData(count($failed) . ' FAILED TESTS:', $command);
foreach ($failed as $failure) {
$this->ui->outputData($failure, $command);
}
}
 
if (count($failed) == 0) {
return true;
}
return $this->raiseError('Some tests failed');
return true;
}
// }}}
}
 
?>
/trunk/bibliotheque/pear/PEAR/Command/Install.xml
26,7 → 26,7
</soft>
<nobuild>
<shortopt>B</shortopt>
<doc>don&#039;t build C extensions</doc>
<doc>don&apos;t build C extensions</doc>
</nobuild>
<nocompress>
<shortopt>Z</shortopt>
34,16 → 34,10
</nocompress>
<installroot>
<shortopt>R</shortopt>
<doc>root directory used when installing files (ala PHP&#039;s INSTALL_ROOT), use packagingroot for RPM</doc>
<arg>DIR</arg>
<doc>root directory used when installing files (ala PHP&apos;s INSTALL_ROOT)</doc>
</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>
76,7 → 70,7
package.xml. Useful for testing, or for wrapping a PEAR package in
another package manager such as RPM.
 
&quot;Package[-version/state][.tar]&quot; : queries your default channel&#039;s server
&quot;Package[-version/state][.tar]&quot; : queries your default channel&apos;s server
({config master_server}) and downloads the newest package with
the preferred quality/state ({config preferred_state}).
 
96,11 → 90,6
<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>
119,7 → 108,7
</register-only>
<nobuild>
<shortopt>B</shortopt>
<doc>don&#039;t build C extensions</doc>
<doc>don&apos;t build C extensions</doc>
</nobuild>
<nocompress>
<shortopt>Z</shortopt>
127,11 → 116,10
</nocompress>
<installroot>
<shortopt>R</shortopt>
<doc>root directory used when installing files (ala PHP&#039;s INSTALL_ROOT)</doc>
<arg>DIR</arg>
<doc>root directory used when installing files (ala PHP&apos;s INSTALL_ROOT)</doc>
</installroot>
<ignore-errors>
<shortopt></shortopt>
<doc>force install even if there were errors</doc>
</ignore-errors>
<alldeps>
163,15 → 151,10
</doc>
</upgrade>
<upgrade-all>
<summary>Upgrade All Packages [Deprecated in favor of calling upgrade with no parameters]</summary>
<function>doUpgradeAll</function>
<summary>Upgrade All Packages</summary>
<function>doInstall</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>
182,7 → 165,7
</register-only>
<nobuild>
<shortopt>B</shortopt>
<doc>don&#039;t build C extensions</doc>
<doc>don&apos;t build C extensions</doc>
</nobuild>
<nocompress>
<shortopt>Z</shortopt>
190,21 → 173,17
</nocompress>
<installroot>
<shortopt>R</shortopt>
<doc>root directory used when installing files (ala PHP&#039;s INSTALL_ROOT), use packagingroot for RPM</doc>
<arg>DIR</arg>
<doc>root directory used when installing files (ala PHP&apos;s INSTALL_ROOT)</doc>
</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
&quot;preferred_state&quot; (currently {config preferred_state}), or a state considered
226,11 → 205,10
</register-only>
<installroot>
<shortopt>R</shortopt>
<doc>root directory used when installing files (ala PHP&#039;s INSTALL_ROOT)</doc>
<arg>DIR</arg>
<doc>root directory used when installing files (ala PHP&apos;s INSTALL_ROOT)</doc>
</installroot>
<ignore-errors>
<shortopt></shortopt>
<doc>force install even if there were errors</doc>
</ignore-errors>
<offline>
251,8 → 229,8
<options>
<destination>
<shortopt>d</shortopt>
<arg>DIR</arg>
<doc>Optional destination directory for unpacking (defaults to current path or &quot;ext&quot; if exists)</doc>
<arg>DIR</arg>
</destination>
<force>
<shortopt>f</shortopt>
/trunk/bibliotheque/pear/PEAR/Command/Pickle.xml
13,15 → 13,20
<doc>Print the name of the packaged file.</doc>
</showname>
</options>
<doc>[descfile]
Creates a PECL package from its package2.xml file.
<doc>[descfile] [descfile2]
Creates a PECL 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 &quot;package.xml&quot; in the archive,
and the other as &quot;package2.xml&quot; in the archive&quot;
 
An automatic conversion will be made to a package.xml 1.0 and written out to
disk in the current directory as &quot;package.xml&quot;. Note that
If no second file is passed in, and [descfile] is a package.xml 2.0,
an automatic conversion will be made to a package.xml 1.0. 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
- more than one extsrcrelease/zendextsrcrelease
- zendextbinrelease, extbinrelease, phprelease, or bundle release type
- dependency groups
- ignore tags in release filelist
30,7 → 35,6
 
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>
generate both package.xml.</doc>
</pickle>
</commands>
/trunk/bibliotheque/pear/PEAR/Command/Registry.xml
13,10 → 13,6
<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>&lt;package&gt;
If invoked without parameters, this command lists the PEAR packages
/trunk/bibliotheque/pear/PEAR/Command/Common.php
4,12 → 4,19
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Common.php,v 1.35 2006/06/08 22:25:18 pajoye Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
26,14 → 33,16
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
class PEAR_Command_Common extends PEAR
{
// {{{ properties
 
/**
* PEAR_Config object used to pass user system and configuration
* on when executing commands
75,18 → 84,25
'sapi' => 'SAPI backend'
);
 
// }}}
// {{{ constructor
 
/**
* PEAR_Command_Common constructor.
*
* @access public
*/
function __construct(&$ui, &$config)
function PEAR_Command_Common(&$ui, &$config)
{
parent::__construct();
parent::PEAR();
$this->config = &$config;
$this->ui = &$ui;
}
 
// }}}
 
// {{{ getCommands()
 
/**
* Return a list of all the commands defined by this class.
* @return array list of commands
98,10 → 114,12
foreach (array_keys($this->commands) as $command) {
$ret[$command] = $this->commands[$command]['summary'];
}
 
return $ret;
}
 
// }}}
// {{{ getShortcuts()
 
/**
* Return a list of all the command shortcuts defined by this class.
* @return array shortcut => command
115,10 → 133,12
$ret[$this->commands[$command]['shortcut']] = $command;
}
}
 
return $ret;
}
 
// }}}
// {{{ getOptions()
 
function getOptions($command)
{
$shortcuts = $this->getShortcuts();
125,23 → 145,24
if (isset($shortcuts[$command])) {
$command = $shortcuts[$command];
}
 
if (isset($this->commands[$command]) &&
isset($this->commands[$command]['options'])) {
return $this->commands[$command]['options'];
} else {
return null;
}
 
return null;
}
 
// }}}
// {{{ getGetoptArgs()
 
function getGetoptArgs($command, &$short_args, &$long_args)
{
$short_args = '';
$short_args = "";
$long_args = array();
if (empty($this->commands[$command]) || empty($this->commands[$command]['options'])) {
return;
}
 
reset($this->commands[$command]['options']);
while (list($option, $info) = each($this->commands[$command]['options'])) {
$larg = $sarg = '';
156,15 → 177,15
$arg = $info['arg'];
}
}
 
if (isset($info['shortopt'])) {
$short_args .= $info['shortopt'] . $sarg;
}
 
$long_args[] = $option . $larg;
}
}
 
// }}}
// {{{ getHelp()
/**
* Returns the help message for the given command
*
179,12 → 200,10
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)) {
// XXX (cox) Fallback to summary if there is no doc (show both?)
if (!isset($this->commands[$command]['summary'])) {
192,22 → 211,22
}
$help = $this->commands[$command]['summary'];
}
 
if (preg_match_all('/{config\s+([^\}]+)}/e', $help, $matches)) {
foreach($matches[0] as $k => $v) {
$help = preg_replace("/$v/", $config->get($matches[1][$k]), $help);
}
}
 
return array($help, $this->getHelpArgs($command));
}
 
// }}}
// {{{ getHelpArgs()
/**
* Returns the help for the accepted arguments of a command
*
* @param string $command
* @return string The help string
*/
* Returns the help for the accepted arguments of a command
*
* @param string $command
* @return string The help string
*/
function getHelpArgs($command)
{
if (isset($this->commands[$command]['options']) &&
227,7 → 246,6
} else {
$sapp = $lapp = "";
}
 
if (isset($v['shortopt'])) {
$s = $v['shortopt'];
$help .= " -$s$sapp, --$k$lapp\n";
234,18 → 252,18
} else {
$help .= " --$k$lapp\n";
}
 
$p = " ";
$doc = rtrim(str_replace("\n", "\n$p", $v['doc']));
$help .= " $doc\n";
}
 
return $help;
}
 
return null;
}
 
// }}}
// {{{ run()
 
function run($command, $options, $params)
{
if (empty($this->commands[$command]['function'])) {
258,8 → 276,6
$func = $this->commands[$cmd]['function'];
}
$command = $cmd;
 
//$command = $this->commands[$cmd]['function'];
break;
}
}
266,7 → 282,10
} else {
$func = $this->commands[$command]['function'];
}
 
return $this->$func($command, $options, $params);
}
 
// }}}
}
 
?>
/trunk/bibliotheque/pear/PEAR/Command/Test.xml
31,8 → 31,7
</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>
<doc>Search parameters for AllTests.php, and use that to run phpunit-based tests</doc>
</phpunit>
<tapoutput>
<shortopt>t</shortopt>
43,12 → 42,8
<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&#039;s regression testing script (run-tests.php).</doc>
Run regression tests with PHP&apos;s regression testing script (run-tests.php).</doc>
</run-tests>
</commands>
/trunk/bibliotheque/pear/PEAR/Command/Package.php
5,13 → 5,20
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Package.php,v 1.122 2006/06/07 23:38:14 pajoye Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
29,9 → 36,9
* @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: @package_version@
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
38,6 → 45,8
 
class PEAR_Command_Package extends PEAR_Command_Common
{
// {{{ properties
 
var $commands = array(
'package' => array(
'summary' => 'Build Package',
133,39 → 142,6
of a specific release.
',
),
'svntag' => array(
'summary' => 'Set SVN Release Tag',
'function' => 'doSvnTag',
'shortcut' => 'sv',
'options' => array(
'quiet' => array(
'shortopt' => 'q',
'doc' => 'Be quiet',
),
'slide' => array(
'shortopt' => 'F',
'doc' => 'Move (slide) tag if it exists',
),
'delete' => array(
'shortopt' => 'd',
'doc' => 'Remove tag',
),
'dry-run' => array(
'shortopt' => 'n',
'doc' => 'Don\'t do anything, just pretend',
),
),
'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.
',
),
'cvstag' => array(
'summary' => 'Set CVS Release Tag',
'function' => 'doCvsTag',
208,20 → 184,14
'function' => 'doPackageDependencies',
'shortcut' => 'pd',
'options' => array(),
'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' => '
List all dependencies the package has.'
),
'sign' => array(
'summary' => 'Sign a package distribution file',
'function' => 'doSign',
'shortcut' => 'si',
'options' => array(
'verbose' => array(
'shortopt' => 'v',
'doc' => 'Display GnuPG output',
),
),
'options' => array(),
'doc' => '<package-file>
Signs a package distribution (.tar or .tgz) file with GnuPG.',
),
277,16 → 247,23
 
var $output;
 
// }}}
// {{{ constructor
 
/**
* PEAR_Command_Package constructor.
*
* @access public
*/
function __construct(&$ui, &$config)
function PEAR_Command_Package(&$ui, &$config)
{
parent::__construct($ui, $config);
parent::PEAR_Command_Common($ui, $config);
}
 
// }}}
 
// {{{ _displayValidationResults()
 
function _displayValidationResults($err, $warn, $strict = false)
{
foreach ($err as $e) {
297,7 → 274,7
}
$this->output .= sprintf('Validation: %d error(s), %d warning(s)'."\n",
sizeof($err), sizeof($warn));
if ($strict && count($err) > 0) {
if ($strict && sizeof($err) > 0) {
$this->output .= "Fix these errors and try again.";
return false;
}
304,29 → 281,31
return true;
}
 
// }}}
function &getPackager()
{
if (!class_exists('PEAR_Packager')) {
require_once 'PEAR/Packager.php';
}
$a = new PEAR_Packager;
$a = &new PEAR_Packager;
return $a;
}
 
function &getPackageFile($config, $debug = false)
function &getPackageFile($config, $debug = false, $tmpdir = null)
{
if (!class_exists('PEAR_Common')) {
require_once 'PEAR/Common.php';
}
if (!class_exists('PEAR_PackageFile')) {
if (!class_exists('PEAR/PackageFile.php')) {
require_once 'PEAR/PackageFile.php';
}
$a = new PEAR_PackageFile($config, $debug);
$a = &new PEAR_PackageFile($config, $debug, $tmpdir);
$common = new PEAR_Common;
$common->ui = $this->ui;
$a->setLogger($common);
return $a;
}
// {{{ doPackage()
 
function doPackage($command, $options, $params)
{
333,36 → 312,36
$this->output = '';
$pkginfofile = isset($params[0]) ? $params[0] : 'package.xml';
$pkg2 = isset($params[1]) ? $params[1] : null;
if (!$pkg2 && !isset($params[0]) && file_exists('package2.xml')) {
$pkg2 = 'package2.xml';
if (!$pkg2 && !isset($params[0])) {
if (file_exists('package2.xml')) {
$pkg2 = 'package2.xml';
}
}
 
$packager = &$this->getPackager();
$compress = empty($options['nocompress']) ? true : false;
$result = $packager->package($pkginfofile, $compress, $pkg2);
$result = $packager->package($pkginfofile, $compress, $pkg2);
if (PEAR::isError($result)) {
return $this->raiseError($result);
}
 
// Don't want output, only the package file name just created
if (isset($options['showname'])) {
$this->output = $result;
}
 
if ($this->output) {
$this->ui->outputData($this->output, $command);
}
 
return true;
}
 
// }}}
// {{{ doPackageValidate()
 
function doPackageValidate($command, $options, $params)
{
$this->output = '';
if (count($params) < 1) {
$params[0] = 'package.xml';
if (sizeof($params) < 1) {
$params[0] = "package.xml";
}
 
$obj = &$this->getPackageFile($this->config, $this->_debug);
$obj->rawReturn();
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
371,18 → 350,16
$info = $obj->fromPackageFile($params[0], PEAR_VALIDATE_NORMAL);
} else {
$archive = $info->getArchiveFile();
$tar = new Archive_Tar($archive);
$tar = &new Archive_Tar($archive);
$tar->extract(dirname($info->getPackageFile()));
$info->setPackageFile(dirname($info->getPackageFile()) . DIRECTORY_SEPARATOR .
$info->getPackage() . '-' . $info->getVersion() . DIRECTORY_SEPARATOR .
basename($info->getPackageFile()));
}
 
PEAR::staticPopErrorHandling();
if (PEAR::isError($info)) {
return $this->raiseError($info);
}
 
$valid = false;
if ($info->getPackagexmlVersion() == '2.0') {
if ($valid = $info->validate(PEAR_VALIDATE_NORMAL)) {
392,10 → 369,10
} else {
$valid = $info->validate(PEAR_VALIDATE_PACKAGING);
}
 
$err = $warn = array();
if ($errors = $info->getValidationWarnings()) {
foreach ($errors as $error) {
$err = array();
$warn = array();
if (!$valid) {
foreach ($info->getValidationWarnings() as $error) {
if ($error['level'] == 'warning') {
$warn[] = $error['message'];
} else {
403,243 → 380,27
}
}
}
 
$this->_displayValidationResults($err, $warn);
$this->ui->outputData($this->output, $command);
return true;
}
 
function doSvnTag($command, $options, $params)
{
$this->output = '';
$_cmd = $command;
if (count($params) < 1) {
$help = $this->getHelp($command);
return $this->raiseError("$command: missing parameter: $help[0]");
}
// }}}
// {{{ doCvsTag()
 
$packageFile = realpath($params[0]);
$dir = dirname($packageFile);
$dir = substr($dir, strrpos($dir, DIRECTORY_SEPARATOR) + 1);
$obj = &$this->getPackageFile($this->config, $this->_debug);
$info = $obj->fromAnyFile($packageFile, PEAR_VALIDATE_NORMAL);
if (PEAR::isError($info)) {
return $this->raiseError($info);
}
 
$err = $warn = array();
if (!$info->validate()) {
foreach ($info->getValidationWarnings() as $error) {
if ($error['level'] == 'warning') {
$warn[] = $error['message'];
} else {
$err[] = $error['message'];
}
}
}
 
if (!$this->_displayValidationResults($err, $warn, true)) {
$this->ui->outputData($this->output, $command);
return $this->raiseError('SVN tag failed');
}
 
$version = $info->getVersion();
$package = $info->getName();
$svntag = "$package-$version";
 
if (isset($options['delete'])) {
return $this->_svnRemoveTag($version, $package, $svntag, $packageFile, $options);
}
 
$path = $this->_svnFindPath($packageFile);
 
// Check if there are any modified files
$fp = popen('svn st --xml ' . dirname($packageFile), "r");
$out = '';
while ($line = fgets($fp, 1024)) {
$out .= rtrim($line)."\n";
}
pclose($fp);
 
if (!isset($options['quiet']) && strpos($out, 'item="modified"')) {
$params = array(array(
'name' => 'modified',
'type' => 'yesno',
'default' => 'no',
'prompt' => 'You have files in your SVN checkout (' . $path['from'] . ') that have been modified but not committed, do you still want to tag ' . $version . '?',
));
$answers = $this->ui->confirmDialog($params);
 
if (!in_array($answers['modified'], array('y', 'yes', 'on', '1'))) {
return true;
}
}
 
if (isset($options['slide'])) {
$this->_svnRemoveTag($version, $package, $svntag, $packageFile, $options);
}
 
// Check if tag already exists
$releaseTag = $path['local']['base'] . 'tags' . DIRECTORY_SEPARATOR . $svntag;
$existsCommand = 'svn ls ' . $path['base'] . 'tags/';
 
$fp = popen($existsCommand, "r");
$out = '';
while ($line = fgets($fp, 1024)) {
$out .= rtrim($line)."\n";
}
pclose($fp);
 
if (in_array($svntag . DIRECTORY_SEPARATOR, explode("\n", $out))) {
$this->ui->outputData($this->output, $command);
return $this->raiseError('SVN tag ' . $svntag . ' for ' . $package . ' already exists.');
} elseif (file_exists($path['local']['base'] . 'tags') === false) {
return $this->raiseError('Can not locate the tags directory at ' . $path['local']['base'] . 'tags');
} elseif (is_writeable($path['local']['base'] . 'tags') === false) {
return $this->raiseError('Can not write to the tag directory at ' . $path['local']['base'] . 'tags');
} else {
$makeCommand = 'svn mkdir ' . $releaseTag;
$this->output .= "+ $makeCommand\n";
if (empty($options['dry-run'])) {
// We need to create the tag dir.
$fp = popen($makeCommand, "r");
$out = '';
while ($line = fgets($fp, 1024)) {
$out .= rtrim($line)."\n";
}
pclose($fp);
$this->output .= "$out\n";
}
}
 
$command = 'svn';
if (isset($options['quiet'])) {
$command .= ' -q';
}
 
$command .= ' copy --parents ';
 
$dir = dirname($packageFile);
$dir = substr($dir, strrpos($dir, DIRECTORY_SEPARATOR) + 1);
$files = array_keys($info->getFilelist());
if (!in_array(basename($packageFile), $files)) {
$files[] = basename($packageFile);
}
 
array_shift($params);
if (count($params)) {
// add in additional files to be tagged (package files and such)
$files = array_merge($files, $params);
}
 
$commands = array();
foreach ($files as $file) {
if (!file_exists($file)) {
$file = $dir . DIRECTORY_SEPARATOR . $file;
}
$commands[] = $command . ' ' . escapeshellarg($file) . ' ' .
escapeshellarg($releaseTag . DIRECTORY_SEPARATOR . $file);
}
 
$this->output .= implode("\n", $commands) . "\n";
if (empty($options['dry-run'])) {
foreach ($commands as $command) {
$fp = popen($command, "r");
while ($line = fgets($fp, 1024)) {
$this->output .= rtrim($line)."\n";
}
pclose($fp);
}
}
 
$command = 'svn ci -m "Tagging the ' . $version . ' release" ' . $releaseTag . "\n";
$this->output .= "+ $command\n";
if (empty($options['dry-run'])) {
$fp = popen($command, "r");
while ($line = fgets($fp, 1024)) {
$this->output .= rtrim($line)."\n";
}
pclose($fp);
}
 
$this->ui->outputData($this->output, $_cmd);
return true;
}
 
function _svnFindPath($file)
{
$xml = '';
$command = "svn info --xml $file";
$fp = popen($command, "r");
while ($line = fgets($fp, 1024)) {
$xml .= rtrim($line)."\n";
}
pclose($fp);
$url_tag = strpos($xml, '<url>');
$url = substr($xml, $url_tag + 5, strpos($xml, '</url>', $url_tag + 5) - ($url_tag + 5));
 
$path = array();
$path['from'] = substr($url, 0, strrpos($url, '/'));
$path['base'] = substr($path['from'], 0, strrpos($path['from'], '/') + 1);
 
// Figure out the local paths - see http://pear.php.net/bugs/17463
$pos = strpos($file, DIRECTORY_SEPARATOR . 'trunk' . DIRECTORY_SEPARATOR);
if ($pos === false) {
$pos = strpos($file, DIRECTORY_SEPARATOR . 'branches' . DIRECTORY_SEPARATOR);
}
$path['local']['base'] = substr($file, 0, $pos + 1);
 
return $path;
}
 
function _svnRemoveTag($version, $package, $tag, $packageFile, $options)
{
$command = 'svn';
 
if (isset($options['quiet'])) {
$command .= ' -q';
}
 
$command .= ' remove';
$command .= ' -m "Removing tag for the ' . $version . ' release."';
 
$path = $this->_svnFindPath($packageFile);
$command .= ' ' . $path['base'] . 'tags/' . $tag;
 
 
if ($this->config->get('verbose') > 1) {
$this->output .= "+ $command\n";
}
 
$this->output .= "+ $command\n";
if (empty($options['dry-run'])) {
$fp = popen($command, "r");
while ($line = fgets($fp, 1024)) {
$this->output .= rtrim($line)."\n";
}
pclose($fp);
}
 
$this->ui->outputData($this->output, $command);
return true;
}
 
function doCvsTag($command, $options, $params)
{
$this->output = '';
$_cmd = $command;
if (count($params) < 1) {
if (sizeof($params) < 1) {
$help = $this->getHelp($command);
return $this->raiseError("$command: missing parameter: $help[0]");
}
 
$packageFile = realpath($params[0]);
$obj = &$this->getPackageFile($this->config, $this->_debug);
$info = $obj->fromAnyFile($packageFile, PEAR_VALIDATE_NORMAL);
$obj = &$this->getPackageFile($this->config, $this->_debug);
$info = $obj->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL);
if (PEAR::isError($info)) {
return $this->raiseError($info);
}
 
$err = $warn = array();
if (!$info->validate()) {
foreach ($info->getValidationWarnings() as $error) {
650,34 → 411,28
}
}
}
 
if (!$this->_displayValidationResults($err, $warn, true)) {
$this->ui->outputData($this->output, $command);
return $this->raiseError('CVS tag failed');
}
 
$version = $info->getVersion();
$version = $info->getVersion();
$cvsversion = preg_replace('/[^a-z0-9]/i', '_', $version);
$cvstag = "RELEASE_$cvsversion";
$files = array_keys($info->getFilelist());
$command = 'cvs';
$cvstag = "RELEASE_$cvsversion";
$files = array_keys($info->getFilelist());
$command = "cvs";
if (isset($options['quiet'])) {
$command .= ' -q';
}
 
if (isset($options['reallyquiet'])) {
$command .= ' -Q';
}
 
$command .= ' tag';
if (isset($options['slide'])) {
$command .= ' -F';
}
 
if (isset($options['delete'])) {
$command .= ' -d';
}
 
$command .= ' ' . $cvstag . ' ' . escapeshellarg($params[0]);
array_shift($params);
if (count($params)) {
684,20 → 439,12
// add in additional files to be tagged
$files = array_merge($files, $params);
}
 
$dir = dirname($packageFile);
$dir = substr($dir, strrpos($dir, '/') + 1);
foreach ($files as $file) {
if (!file_exists($file)) {
$file = $dir . DIRECTORY_SEPARATOR . $file;
}
$command .= ' ' . escapeshellarg($file);
}
 
if ($this->config->get('verbose') > 1) {
$this->output .= "+ $command\n";
}
 
$this->output .= "+ $command\n";
if (empty($options['dry-run'])) {
$fp = popen($command, "r");
706,11 → 453,13
}
pclose($fp);
}
 
$this->ui->outputData($this->output, $_cmd);
return true;
}
 
// }}}
// {{{ doCvsDiff()
 
function doCvsDiff($command, $options, $params)
{
$this->output = '';
718,14 → 467,11
$help = $this->getHelp($command);
return $this->raiseError("$command: missing parameter: $help[0]");
}
 
$file = realpath($params[0]);
$obj = &$this->getPackageFile($this->config, $this->_debug);
$info = $obj->fromAnyFile($file, PEAR_VALIDATE_NORMAL);
$obj = &$this->getPackageFile($this->config, $this->_debug);
$info = $obj->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL);
if (PEAR::isError($info)) {
return $this->raiseError($info);
}
 
$err = $warn = array();
if (!$info->validate()) {
foreach ($info->getValidationWarnings() as $error) {
736,12 → 482,10
}
}
}
 
if (!$this->_displayValidationResults($err, $warn, true)) {
$this->ui->outputData($this->output, $command);
return $this->raiseError('CVS diff failed');
}
 
$info1 = $info->getFilelist();
$files = $info1;
$cmd = "cvs";
749,12 → 493,10
$cmd .= ' -q';
unset($options['quiet']);
}
 
if (isset($options['reallyquiet'])) {
$cmd .= ' -Q';
unset($options['reallyquiet']);
}
 
if (isset($options['release'])) {
$cvsversion = preg_replace('/[^a-z0-9]/i', '_', $options['release']);
$cvstag = "RELEASE_$cvsversion";
761,13 → 503,11
$options['revision'] = $cvstag;
unset($options['release']);
}
 
$execute = true;
if (isset($options['dry-run'])) {
$execute = false;
unset($options['dry-run']);
}
 
$cmd .= ' diff';
// the rest of the options are passed right on to "cvs diff"
foreach ($options as $option => $optarg) {
781,15 → 521,12
$cmd .= ($short ? '' : '=') . escapeshellarg($optarg);
}
}
 
foreach ($files as $file) {
$cmd .= ' ' . escapeshellarg($file['name']);
}
 
if ($this->config->get('verbose') > 1) {
$this->output .= "+ $cmd\n";
}
 
if ($execute) {
$fp = popen($cmd, "r");
while ($line = fgets($fp, 1024)) {
797,30 → 534,24
}
pclose($fp);
}
 
$this->ui->outputData($this->output, $command);
return true;
}
 
// }}}
// {{{ doPackageDependencies()
 
function doPackageDependencies($command, $options, $params)
{
// $params[0] -> the PEAR package to list its information
if (count($params) !== 1) {
if (sizeof($params) != 1) {
return $this->raiseError("bad parameter(s), try \"help $command\"");
}
 
$obj = &$this->getPackageFile($this->config, $this->_debug);
if (is_file($params[0]) || strpos($params[0], '.xml') > 0) {
$info = $obj->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL);
} else {
$reg = $this->config->getRegistry();
$info = $obj->fromArray($reg->packageInfo($params[0]));
}
 
$info = $obj->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL);
if (PEAR::isError($info)) {
return $this->raiseError($info);
}
 
$deps = $info->getDeps();
if (is_array($deps)) {
if ($info->getPackagexmlVersion() == '1.0') {
840,7 → 571,6
} else {
$req = 'Yes';
}
 
if (isset($this->_deps_rel_trans[$d['rel']])) {
$rel = $this->_deps_rel_trans[$d['rel']];
} else {
880,30 → 610,25
);
foreach ($deps as $type => $subd) {
$req = ($type == 'required') ? 'Yes' : 'No';
if ($type == 'group' && isset($subd['attribs']['name'])) {
if ($type == 'group') {
$group = $subd['attribs']['name'];
} else {
$group = '';
}
 
if (!isset($subd[0])) {
$subd = array($subd);
}
 
foreach ($subd as $groupa) {
foreach ($groupa as $deptype => $depinfo) {
if ($deptype == 'attribs') {
continue;
}
 
if ($deptype == 'pearinstaller') {
$deptype = 'pear Installer';
}
 
if (!isset($depinfo[0])) {
$depinfo = array($depinfo);
}
 
foreach ($depinfo as $inf) {
$name = '';
if (isset($inf['channel'])) {
912,7 → 637,6
$alias = '(channel?) ' .$inf['channel'];
}
$name = $alias . '/';
 
}
if (isset($inf['name'])) {
$name .= $inf['name'];
921,17 → 645,14
} else {
$name .= '';
}
 
if (isset($inf['uri'])) {
$name .= ' [' . $inf['uri'] . ']';
}
 
if (isset($inf['conflicts'])) {
$ver = 'conflicts';
} else {
$ver = $d->_getExtraString($inf);
}
 
$data['data'][] = array($req, ucfirst($deptype), $name,
$ver, $group);
}
949,79 → 670,60
$this->ui->outputData("This package does not have any dependencies.", $command);
}
 
// }}}
// {{{ doSign()
 
function doSign($command, $options, $params)
{
require_once 'System.php';
require_once 'Archive/Tar.php';
// should move most of this code into PEAR_Packager
// so it'll be easy to implement "pear package --sign"
if (count($params) !== 1) {
if (sizeof($params) != 1) {
return $this->raiseError("bad parameter(s), try \"help $command\"");
}
 
require_once 'System.php';
require_once 'Archive/Tar.php';
 
if (!file_exists($params[0])) {
return $this->raiseError("file does not exist: $params[0]");
}
 
$obj = $this->getPackageFile($this->config, $this->_debug);
$info = $obj->fromTgzFile($params[0], PEAR_VALIDATE_NORMAL);
if (PEAR::isError($info)) {
return $this->raiseError($info);
}
 
$tar = new Archive_Tar($params[0]);
 
$tmpdir = $this->config->get('temp_dir');
$tmpdir = System::mktemp(' -t "' . $tmpdir . '" -d pearsign');
if (!$tar->extractList('package2.xml package.xml package.sig', $tmpdir)) {
return $this->raiseError("failed to extract tar file");
$tmpdir = System::mktemp('-d pearsign');
if (!$tar->extractList('package2.xml package.sig', $tmpdir)) {
if (!$tar->extractList('package.xml package.sig', $tmpdir)) {
return $this->raiseError("failed to extract tar file");
}
}
 
if (file_exists("$tmpdir/package.sig")) {
return $this->raiseError("package already signed");
}
 
$packagexml = 'package.xml';
if (file_exists("$tmpdir/package2.xml")) {
$packagexml = 'package2.xml';
}
 
if (file_exists("$tmpdir/package.sig")) {
unlink("$tmpdir/package.sig");
}
 
if (!file_exists("$tmpdir/$packagexml")) {
return $this->raiseError("Extracted file $tmpdir/$packagexml not found.");
}
 
$input = $this->ui->userDialog($command,
array('GnuPG Passphrase'),
array('password'));
if (!isset($input[0])) {
//use empty passphrase
$input[0] = '';
}
 
$devnull = (isset($options['verbose'])) ? '' : ' 2>/dev/null';
$gpg = popen("gpg --batch --passphrase-fd 0 --armor --detach-sign --output $tmpdir/package.sig $tmpdir/$packagexml" . $devnull, "w");
$gpg = popen("gpg --batch --passphrase-fd 0 --armor --detach-sign --output $tmpdir/package.sig $tmpdir/$packagexml 2>/dev/null", "w");
if (!$gpg) {
return $this->raiseError("gpg command failed");
}
 
fwrite($gpg, "$input[0]\n");
if (pclose($gpg) || !file_exists("$tmpdir/package.sig")) {
return $this->raiseError("gpg sign failed");
}
 
if (!$tar->addModify("$tmpdir/package.sig", '', $tmpdir)) {
return $this->raiseError('failed adding signature to file');
}
 
$this->ui->outputData("Package signed.", $command);
$tar->addModify("$tmpdir/package.sig", '', $tmpdir);
return true;
}
 
// }}}
 
/**
* For unit testing purposes
*/
1030,10 → 732,10
if (!class_exists('PEAR_Installer')) {
require_once 'PEAR/Installer.php';
}
$a = new PEAR_Installer($ui);
$a = &new PEAR_Installer($ui);
return $a;
}
 
/**
* For unit testing purposes
*/
1045,16 → 747,17
include_once 'PEAR/Command/Packaging.php';
}
}
 
if (class_exists('PEAR_Command_Packaging')) {
$a = new PEAR_Command_Packaging($ui, $config);
$a = &new PEAR_Command_Packaging($ui, $config);
} else {
$a = null;
}
 
return $a;
}
 
// {{{ doMakeRPM()
 
function doMakeRPM($command, $options, $params)
{
 
1067,17 → 770,17
$this->ui->outputData('PEAR_Command_Packaging is installed; using '.
'newer "make-rpm-spec" command instead');
return $packaging_cmd->run('make-rpm-spec', $options, $params);
} else {
$this->ui->outputData('WARNING: "pear makerpm" is no longer available; an '.
'improved version is available via "pear make-rpm-spec", which '.
'is available by installing PEAR_Command_Packaging');
}
 
$this->ui->outputData('WARNING: "pear makerpm" is no longer available; an '.
'improved version is available via "pear make-rpm-spec", which '.
'is available by installing PEAR_Command_Packaging');
return true;
}
 
function doConvert($command, $options, $params)
{
$packagexml = isset($params[0]) ? $params[0] : 'package.xml';
$packagexml = isset($params[0]) ? $params[0] : 'package.xml';
$newpackagexml = isset($params[1]) ? $params[1] : dirname($packagexml) .
DIRECTORY_SEPARATOR . 'package2.xml';
$pkg = &$this->getPackageFile($this->config, $this->_debug);
1084,7 → 787,32
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$pf = $pkg->fromPackageFile($packagexml, PEAR_VALIDATE_NORMAL);
PEAR::staticPopErrorHandling();
if (PEAR::isError($pf)) {
if (!PEAR::isError($pf)) {
if (is_a($pf, 'PEAR_PackageFile_v2')) {
$this->ui->outputData($packagexml . ' is already a package.xml version 2.0');
return true;
}
$gen = &$pf->getDefaultGenerator();
$newpf = &$gen->toV2();
$newpf->setPackagefile($newpackagexml);
$gen = &$newpf->getDefaultGenerator();
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$state = (isset($options['flat']) ? PEAR_VALIDATE_PACKAGING : PEAR_VALIDATE_NORMAL);
$saved = $gen->toPackageFile(dirname($newpackagexml), $state,
basename($newpackagexml));
PEAR::staticPopErrorHandling();
if (PEAR::isError($saved)) {
if (is_array($saved->getUserInfo())) {
foreach ($saved->getUserInfo() as $warning) {
$this->ui->outputData($warning['message']);
}
}
$this->ui->outputData($saved->getMessage());
return true;
}
$this->ui->outputData('Wrote new version 2.0 package.xml to "' . $saved . '"');
return true;
} else {
if (is_array($pf->getUserInfo())) {
foreach ($pf->getUserInfo() as $warning) {
$this->ui->outputData($warning['message']);
1092,32 → 820,9
}
return $this->raiseError($pf);
}
}
 
if (is_a($pf, 'PEAR_PackageFile_v2')) {
$this->ui->outputData($packagexml . ' is already a package.xml version 2.0');
return true;
}
// }}}
}
 
$gen = &$pf->getDefaultGenerator();
$newpf = &$gen->toV2();
$newpf->setPackagefile($newpackagexml);
$gen = &$newpf->getDefaultGenerator();
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$state = (isset($options['flat']) ? PEAR_VALIDATE_PACKAGING : PEAR_VALIDATE_NORMAL);
$saved = $gen->toPackageFile(dirname($newpackagexml), $state, basename($newpackagexml));
PEAR::staticPopErrorHandling();
if (PEAR::isError($saved)) {
if (is_array($saved->getUserInfo())) {
foreach ($saved->getUserInfo() as $warning) {
$this->ui->outputData($warning['message']);
}
}
 
$this->ui->outputData($saved->getMessage());
return true;
}
 
$this->ui->outputData('Wrote new version 2.0 package.xml to "' . $saved . '"');
return true;
}
}
?>
/trunk/bibliotheque/pear/PEAR/Command/Channels.php
6,12 → 6,19
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Channels.php,v 1.46 2006/07/17 18:19:25 pajoye Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
21,8 → 28,6
*/
require_once 'PEAR/Command/Common.php';
 
define('PEAR_COMMAND_CHANNELS_CHANNEL_EXISTS', -500);
 
/**
* PEAR commands for managing channels.
*
29,14 → 34,16
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_Command_Channels extends PEAR_Command_Common
{
// {{{ properties
 
var $commands = array(
'list-channels' => array(
'summary' => 'List Available Channels',
126,51 → 133,28
'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.
Initialize a Channel from its server and creates the local channel.xml.
'
),
'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.',
),
);
 
// }}}
// {{{ constructor
 
/**
* PEAR_Command_Registry constructor.
*
* @access public
*/
function __construct(&$ui, &$config)
function PEAR_Command_Channels(&$ui, &$config)
{
parent::__construct($ui, $config);
parent::PEAR_Command_Common($ui, $config);
}
 
// }}}
 
// {{{ doList()
function _sortChannels($a, $b)
{
return strnatcasecmp($a->getName(), $b->getName());
185,51 → 169,160
$data = array(
'caption' => 'Registered Channels:',
'border' => true,
'headline' => array('Channel', 'Alias', 'Summary')
'headline' => array('Channel', 'Summary')
);
foreach ($registered as $channel) {
$data['data'][] = array($channel->getName(),
$channel->getAlias(),
$channel->getSummary());
$channel->getSummary());
}
 
if (count($registered) === 0) {
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;
$savechannel = $this->config->get('default_channel');
if (isset($options['channel'])) {
if (!$reg->channelExists($options['channel'])) {
return $this->raiseError('Unknown channel "' . $options['channel'] . '"');
}
$this->config->set('default_channel', $options['channel']);
} else {
$this->config->set('default_channel', 'pear.php.net');
}
$remote = &$this->config->getRemote();
$channels = $remote->call('channel.listAll');
if (PEAR::isError($channels)) {
$this->config->set('default_channel', $savechannel);
return $channels;
}
if (!is_array($channels) || isset($channels['faultCode'])) {
$this->config->set('default_channel', $savechannel);
return $this->raiseError("Incorrect channel listing returned from channel '$chan'");
}
if (!count($channels)) {
$data = 'no updates available';
}
$dl = &$this->getDownloader();
if (!class_exists('System')) {
require_once 'System.php';
}
$tmpdir = System::mktemp(array('-d'));
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;
$channel = $channel[0];
$save = $channel;
if ($reg->channelExists($channel, true)) {
$this->ui->outputData("Updating channel \"$channel\"", $command);
$test = $reg->getChannel($channel, true);
if (PEAR::isError($test)) {
$this->ui->outputData("Channel '$channel' is corrupt in registry!", $command);
$lastmodified = false;
} else {
$success &= $err;
$lastmodified = $test->lastModified();
}
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$contents = $dl->downloadHttp('http://' . $test->getName() . '/channel.xml',
$this->ui, $tmpdir, null, $lastmodified);
PEAR::staticPopErrorHandling();
if (PEAR::isError($contents)) {
$this->ui->outputData('ERROR: Cannot retrieve channel.xml for channel "' .
$test->getName() . '"', $command);
continue;
}
if (!$contents) {
$this->ui->outputData("Channel \"$channel\" is up-to-date", $command);
continue;
}
list($contents, $lastmodified) = $contents;
$info = implode('', file($contents));
if (!$info) {
$this->ui->outputData("Channel \"$channel\" is up-to-date", $command);
continue;
}
if (!class_exists('PEAR_ChannelFile')) {
require_once 'PEAR/ChannelFile.php';
}
$channelinfo = new PEAR_ChannelFile;
$channelinfo->fromXmlString($info);
if ($channelinfo->getErrors()) {
$this->ui->outputData("Downloaded channel data from channel \"$channel\" " .
'is corrupt, skipping', $command);
continue;
}
$channel = $channelinfo;
if ($channel->getName() != $save) {
$this->ui->outputData('ERROR: Security risk - downloaded channel ' .
'definition file for channel "'
. $channel->getName() . ' from channel "' . $save .
'". To use anyway, use channel-update', $command);
continue;
}
$reg->updateChannel($channel, $lastmodified);
} else {
if ($reg->isAlias($channel)) {
$temp = &$reg->getChannel($channel);
if (PEAR::isError($temp)) {
return $this->raiseError($temp);
}
$temp->setAlias($temp->getName(), true); // set the alias to the channel name
if ($reg->channelExists($temp->getName())) {
$this->ui->outputData('ERROR: existing channel "' . $temp->getName() .
'" is aliased to "' . $channel . '" already and cannot be ' .
're-aliased to "' . $temp->getName() . '" because a channel with ' .
'that name or alias already exists! Please re-alias and try ' .
'again.', $command);
continue;
}
}
$this->ui->outputData("Adding new channel \"$channel\"", $command);
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$contents = $dl->downloadHttp('http://' . $channel . '/channel.xml',
$this->ui, $tmpdir, null, false);
PEAR::staticPopErrorHandling();
if (PEAR::isError($contents)) {
$this->ui->outputData('ERROR: Cannot retrieve channel.xml for channel "' .
$channel . '"', $command);
continue;
}
list($contents, $lastmodified) = $contents;
$info = implode('', file($contents));
if (!class_exists('PEAR_ChannelFile')) {
require_once 'PEAR/ChannelFile.php';
}
$channelinfo = new PEAR_Channelfile;
$channelinfo->fromXmlString($info);
if ($channelinfo->getErrors()) {
$this->ui->outputData("Downloaded channel data from channel \"$channel\"" .
' is corrupt, skipping', $command);
continue;
}
$channel = $channelinfo;
if ($channel->getName() != $save) {
$this->ui->outputData('ERROR: Security risk - downloaded channel ' .
'definition file for channel "'
. $channel->getName() . '" from channel "' . $save .
'". To use anyway, use channel-update', $command);
continue;
}
$reg->addChannel($channel, $lastmodified);
}
}
return $success;
$this->config->set('default_channel', $savechannel);
$this->ui->outputData('update-channels complete', $command);
return true;
}
 
function doInfo($command, $options, $params)
{
if (count($params) !== 1) {
if (sizeof($params) != 1) {
return $this->raiseError("No channel specified");
}
 
$reg = &$this->config->getRegistry();
$reg = &$this->config->getRegistry();
$channel = strtolower($params[0]);
if ($reg->channelExists($channel)) {
$chan = $reg->getChannel($channel);
239,26 → 332,27
} else {
if (strpos($channel, '://')) {
$downloader = &$this->getDownloader();
$tmpdir = $this->config->get('temp_dir');
if (!class_exists('System')) {
require_once 'System.php';
}
$tmpdir = System::mktemp(array('-d'));
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() . ')');
return $this->raiseError('Cannot open "' . $channel . '"');
} else {
$contents = implode('', file($loc));
}
} else {
if (!file_exists($params[0])) {
if (file_exists($params[0])) {
$fp = fopen($params[0], 'r');
if (!$fp) {
return $this->raiseError('Cannot open "' . $params[0] . '"');
}
} else {
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);
265,11 → 359,9
}
fclose($fp);
}
 
if (!class_exists('PEAR_ChannelFile')) {
require_once 'PEAR/ChannelFile.php';
}
 
$chan = new PEAR_ChannelFile;
$chan->fromXmlString($contents);
$chan->validate();
280,123 → 372,147
return $this->raiseError('Channel file "' . $params[0] . '" is not valid');
}
}
if ($chan) {
$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;
 
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);
$data['data'] = array();
$data['caption'] = 'Server Capabilities';
$data['headline'] = array('Type', 'Version/REST type', 'Function Name/REST base');
$capabilities = $chan->getFunctions('xmlrpc');
$soaps = $chan->getFunctions('soap');
if ($capabilities || $soaps || $chan->supportsREST()) {
if ($capabilities) {
if (!isset($capabilities[0])) {
$capabilities = array($capabilities);
}
foreach ($capabilities as $protocol) {
$data['data'][] = array('xmlrpc', $protocol['attribs']['version'],
$protocol['_content']);
}
}
foreach ($funcs as $protocol) {
$data['data'][] = array('rest', $protocol['attribs']['type'],
$protocol['_content']);
if ($soaps) {
if (!isset($soaps[0])) {
$soaps = array($soaps);
}
foreach ($soaps as $protocol) {
$data['data'][] = array('soap', $protocol['attribs']['version'],
$protocol['_content']);
}
}
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');
}
} 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);
$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 $mirror) {
$data['data'] = array();
$data['caption'] = 'Mirror ' . $mirror['attribs']['host'] . ' Capabilities';
$data['headline'] = array('Type', 'Version/REST type', 'Function Name/REST base');
$capabilities = $chan->getFunctions('xmlrpc', $mirror['attribs']['host']);
$soaps = $chan->getFunctions('soap', $mirror['attribs']['host']);
if ($capabilities || $soaps || $chan->supportsREST($mirror['attribs']['host'])) {
if ($capabilities) {
if (!isset($capabilities[0])) {
$capabilities = array($capabilities);
}
foreach ($capabilities as $protocol) {
$data['data'][] = array('xmlrpc', $protocol['attribs']['version'],
$protocol['_content']);
}
}
 
foreach ($funcs as $protocol) {
$data['data'][] = array('rest', $protocol['attribs']['type'],
$protocol['_content']);
if ($soaps) {
if (!isset($soaps[0])) {
$soaps = array($soaps);
}
foreach ($soaps as $protocol) {
$data['data'][] = array('soap', $protocol['attribs']['version'],
$protocol['_content']);
}
}
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');
}
} else {
$data['data'][] = array('No supported protocols');
$d['mirrorprotocols'] = $data;
}
$d['mirrorprotocols' . $i] = $data;
}
$this->ui->outputData($d, 'channel-info');
} else {
return $this->raiseError('Serious error: Channel "' . $params[0] .
'" has a corrupted registry entry');
}
$this->ui->outputData($d, 'channel-info');
}
 
// }}}
 
function doDelete($command, $options, $params)
{
if (count($params) !== 1) {
if (sizeof($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 {
407,51 → 523,32
 
function doAdd($command, $options, $params)
{
if (count($params) !== 1) {
if (sizeof($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)) {
if (!class_exists('System')) {
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"');
}
 
$tmpdir = System::mktemp(array('-d'));
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() . ')');
return $this->raiseError('channel-add: Cannot open "' . $params[0] . '"');
} else {
list($loc, $lastmodified) = $loc;
$contents = implode('', file($loc));
}
 
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);
458,11 → 555,9
}
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);
481,23 → 576,19
}
}
}
 
$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);
'" exists, use channel-update to update entry');
}
 
$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);
505,30 → 596,14
 
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)) {
if (!class_exists('System')) {
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"');
$tmpdir = System::mktemp(array('-d'));
$reg = &$this->config->getRegistry();
if (sizeof($params) != 1) {
return $this->raiseError("No channel file specified");
}
 
$reg = &$this->config->getRegistry();
$lastmodified = false;
if ((!file_exists($params[0]) || is_dir($params[0]))
&& $reg->channelExists(strtolower($params[0]))) {
536,8 → 611,7
if (PEAR::isError($c)) {
return $this->raiseError($c);
}
 
$this->ui->outputData("Updating channel \"$params[0]\"", $command);
$this->ui->outputData('Retrieving channel.xml from remote server');
$dl = &$this->getDownloader(array());
// if force is specified, use a timestamp of "1" to force retrieval
$lastmodified = isset($options['force']) ? false : $c->lastModified();
546,44 → 620,32
$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() . ')');
}
return $this->raiseError('Cannot retrieve channel.xml for channel "' .
$c->getName() . '"');
}
 
list($contents, $lastmodified) = $contents;
if (!$contents) {
$this->ui->outputData("Channel \"$params[0]\" is up to date");
$this->ui->outputData("Channel $params[0] channel.xml 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'])) {
if (isset($options['force'])) {
$this->ui->log(0, 'WARNING: downloaded channel definition file' .
' for channel "' . $channel->getName() . '" from channel "' .
strtolower($c->getName()) . '"');
} else {
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 {
594,22 → 656,19
$this->ui, $tmpdir, null, $lastmodified);
PEAR::staticPopErrorHandling();
if (PEAR::isError($loc)) {
return $this->raiseError("Cannot open " . $params[0] .
' (' . $loc->getMessage() . ')');
return $this->raiseError("Cannot open " . $params[0]);
} else {
list($loc, $lastmodified) = $loc;
$contents = implode('', file($loc));
}
 
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);
616,15 → 675,12
}
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) {
637,22 → 693,18
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');
669,214 → 721,65
 
function doAlias($command, $options, $params)
{
if (count($params) === 1) {
$reg = &$this->config->getRegistry();
if (sizeof($params) == 1) {
return $this->raiseError('No channel alias specified');
}
 
if (count($params) !== 2 || (!empty($params[1]) && $params[1]{0} == '-')) {
if (sizeof($params) != 2) {
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]) . '")';
} else {
$extra = '';
}
 
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]);
$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) {
$reg = &$this->config->getRegistry();
if (sizeof($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);
if ($reg->channelExists($params[0])) {
if ($reg->isAlias($params[0])) {
return $this->raiseError("A channel alias named \"$params[0]\" " .
'already exists, aliasing channel "' . $reg->channelName($params[0])
. '"');
} else {
return $this->raiseError("Channel \"$params[0]\" is already initialized");
}
 
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'));
$err = $this->doAdd($command, $options, array('http://' . $params[0] . '/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() . ')');
}
return $this->raiseError("Discovery of channel \"$params[0]\" 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);
$this->ui->outputData("Discovery of channel \"$params[0]\" 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;
}
}
?>
/trunk/bibliotheque/pear/PEAR/Command/Remote.php
5,12 → 5,19
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Remote.php,v 1.96 2006/09/24 03:08:57 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
28,14 → 35,16
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
class PEAR_Command_Remote extends PEAR_Command_Common
{
// {{{ command definitions
 
var $commands = array(
'remote-info' => array(
'summary' => 'Information About Remote Packages',
49,12 → 58,7
'summary' => 'List Available Upgrades',
'function' => 'doListUpgrades',
'shortcut' => 'lu',
'options' => array(
'channelinfo' => array(
'shortopt' => 'i',
'doc' => 'output fully channel-aware data, even on failure',
),
),
'options' => array(),
'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.)
86,15 → 90,7
'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
112,11 → 108,7
'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' => '
Lists the packages available on the configured server along with the
143,22 → 135,27
'shortcut' => 'cc',
'options' => array(),
'doc' => '
Clear the REST cache. See also the cache_ttl configuration
Clear the XML-RPC/REST cache. See also the cache_ttl configuration
parameter.
',
),
);
 
// }}}
// {{{ constructor
 
/**
* PEAR_Command_Remote constructor.
*
* @access public
*/
function __construct(&$ui, &$config)
function PEAR_Command_Remote(&$ui, &$config)
{
parent::__construct($ui, $config);
parent::PEAR_Command_Common($ui, $config);
}
 
// }}}
 
function _checkChannelForStatus($channel, $chan)
{
if (PEAR::isError($chan)) {
170,18 → 167,18
}
$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 .
'updated its protocols, use "channel-update ' . $channel .
'" to update');
}
}
 
// {{{ doRemoteInfo()
 
function doRemoteInfo($command, $options, $params)
{
if (sizeof($params) != 1) {
194,7 → 191,7
if (PEAR::isError($parsed)) {
return $this->raiseError('Invalid package name "' . $package . '"');
}
 
$channel = $parsed['channel'];
$this->config->set('default_channel', $channel);
$chan = $reg->getChannel($channel);
201,22 → 198,18
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)) {
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());
$info = $rest->packageInfo($base, $parsed['package'], $channel);
$info = $rest->packageInfo($base, $parsed['package']);
} else {
$r = &$this->config->getRemote();
$info = $r->call('package.info', $parsed['package']);
}
 
if (!isset($info)) {
return $this->raiseError('No supported protocol was found');
}
 
if (PEAR::isError($info)) {
$this->config->set('default_channel', $savechannel);
return $this->raiseError($info);
}
 
if (!isset($info['name'])) {
return $this->raiseError('No remote package "' . $package . '" was found');
}
233,6 → 226,9
return true;
}
 
// }}}
// {{{ doRemoteList()
 
function doRemoteList($command, $options, $params)
{
$savechannel = $channel = $this->config->get('default_channel');
239,55 → 235,54
$reg = &$this->config->getRegistry();
if (isset($options['channel'])) {
$channel = $options['channel'];
if (!$reg->channelExists($channel)) {
if ($reg->channelExists($channel)) {
$this->config->set('default_channel', $channel);
} else {
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;
if ($this->config->get('preferred_state') == 'stable') {
$list_options = true;
}
 
$available = array();
if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
$base = $chan->getBaseURL('REST1.1', $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());
$available = $rest->listAll($base, $list_options);
} 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());
$available = $rest->listAll($base, $list_options);
} else {
$r = &$this->config->getRemote();
if ($channel == 'pear.php.net') {
// hack because of poor pearweb design
$available = $r->call('package.listAll', true, $list_options, false);
} else {
$available = $r->call('package.listAll', true, $list_options);
}
}
 
if (PEAR::isError($available)) {
$this->config->set('default_channel', $savechannel);
return $this->raiseError($available);
}
 
$i = $j = 0;
$data = array(
'caption' => 'Channel ' . $channel . ' Available packages:',
'border' => true,
'headline' => array('Package', 'Version'),
'channel' => $channel
);
 
if (count($available) == 0) {
if (count($available)==0) {
$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);
$data['data'][] = array($name, (isset($info['stable']) && $info['stable'])
? $info['stable'] : '-n/a-');
}
}
$this->ui->outputData($data, $command);
295,6 → 290,9
return true;
}
 
// }}}
// {{{ doListAll()
 
function doListAll($command, $options, $params)
{
$savechannel = $channel = $this->config->get('default_channel');
301,52 → 299,47
$reg = &$this->config->getRegistry();
if (isset($options['channel'])) {
$channel = $options['channel'];
if (!$reg->channelExists($channel)) {
if ($reg->channelExists($channel)) {
$this->config->set('default_channel', $channel);
} else {
return $this->raiseError("Channel \"$channel\" does not exist");
}
 
$this->config->set('default_channel', $channel);
}
 
$list_options = false;
if ($this->config->get('preferred_state') == 'stable') {
$list_options = true;
}
 
$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());
$available = $rest->listAll($base, $list_options, false);
} 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());
$available = $rest->listAll($base, $list_options, false);
} else {
$r = &$this->config->getRemote();
if ($channel == 'pear.php.net') {
// hack because of poor pearweb design
$available = $r->call('package.listAll', true, $list_options, false);
} else {
$available = $r->call('package.listAll', true, $list_options);
}
}
 
if (PEAR::isError($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() . '")');
}
 
$data = array(
'caption' => 'All packages [Channel ' . $channel . ']:',
'caption' => 'All packages:',
'border' => true,
'headline' => array('Package', 'Latest', 'Local'),
'channel' => $channel,
);
 
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) {
380,39 → 373,13
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,
$latest,
$local,
isset($desc) ? $desc : null,
isset($info['deps']) ? $info['deps'] : null,
$data['data'][$info['category']][] = 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,
);
} 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;
}
 
if (isset($options['mode']) && in_array($options['mode'], array('notinstalled', 'upgrades'))) {
420,7 → 387,6
$this->ui->outputData($data, $command);
return true;
}
 
foreach ($local_pkgs as $name) {
$info = &$reg->getPackage($name, $channel);
$data['data']['Local'][] = array(
437,6 → 403,9
return true;
}
 
// }}}
// {{{ doSearch()
 
function doSearch($command, $options, $params)
{
if ((!isset($params[0]) || empty($params[0]))
443,94 → 412,47
&& (!isset($params[1]) || empty($params[1])))
{
return $this->raiseError('no valid search string supplied');
}
};
 
$channelinfo = isset($options['channelinfo']);
$savechannel = $channel = $this->config->get('default_channel');
$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]);
$package = $params[0];
$summary = isset($params[1]) ? $params[1] : false;
if (isset($options['channel'])) {
$reg = &$this->config->getRegistry();
$channel = $options['channel'];
if (!$reg->channelExists($channel)) {
if ($reg->channelExists($channel)) {
$this->config->set('default_channel', $channel);
} else {
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());
$available = $rest->listAll($base, false, false, $package, $summary);
} else {
$r = &$this->config->getRemote();
$available = $r->call('package.search', $package, $summary, true,
$this->config->get('preferred_state') == 'stable', true);
}
 
if (PEAR::isError($available)) {
$this->config->set('default_channel', $savechannel);
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 (!$available) {
return $this->raiseError('no packages found that match pattern "' . $package . '"');
}
$data = array(
'caption' => 'Matched packages, channel ' . $channel . ':',
'border' => true,
'headline' => array('Package', 'Stable/(Latest)', 'Local'),
);
 
if ($channelinfo) {
$data = array(
'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,
'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) {
$installed = $reg->packageInfo($name, null, $channel);
$desc = $info['summary'];
537,50 → 459,37
if (isset($params[$name]))
$desc .= "\n\n".$info['description'];
 
$unstable = '';
if ($info['unstable']) {
$unstable = '/(' . $info['unstable'] . ' ' . $info['state'] . ')';
}
if (!isset($info['stable']) || !$info['stable']) {
$version_remote = 'none';
} else {
if ($info['unstable']) {
$version_remote = $info['unstable'];
} else {
$version_remote = $info['stable'];
}
$version_remote .= ' ('.$info['state'].')';
$info['stable'] = 'none';
}
$version = is_array($installed['version']) ? $installed['version']['release'] :
$installed['version'];
if ($channelinfo) {
$packageinfo = array(
$channel,
$name,
$version_remote,
$version,
$desc,
$data['data'][$info['category']][] = array(
$name,
$info['stable'] . $unstable,
$version,
$desc,
);
} else {
$packageinfo = array(
$name,
$version_remote,
$version,
$desc,
);
}
$data['data'][$info['category']][] = $packageinfo;
}
 
$this->ui->outputData($data, $command);
$this->config->set('default_channel', $channel);
return true;
}
 
// }}}
function &getDownloader($options)
{
if (!class_exists('PEAR_Downloader')) {
require_once 'PEAR/Downloader.php';
}
$a = new PEAR_Downloader($this->ui, $options, $this->config);
$a = &new PEAR_Downloader($this->ui, $options, $this->config);
return $a;
}
// {{{ doDownload()
 
function doDownload($command, $options, $params)
{
594,13 → 503,7
// 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');
}
 
$downloader->setDownloadDir(getcwd());
$errors = array();
$downloaded = array();
$err = $downloader->download($params);
607,23 → 510,17
if (PEAR::isError($err)) {
return $err;
}
 
$errors = $downloader->getErrorMsgs();
if (count($errors)) {
foreach ($errors as $error) {
if ($error !== null) {
$this->ui->outputData($error);
}
$this->ui->outputData($error);
}
 
return $this->raiseError("$command failed");
}
 
$downloaded = $downloader->getDownloadedPackages();
foreach ($downloaded as $pkg) {
$this->ui->outputData("File $pkg[file] downloaded", $command);
}
 
return true;
}
 
634,6 → 531,9
}
}
 
// }}}
// {{{ doListUpgrades()
 
function doListUpgrades($command, $options, $params)
{
require_once 'PEAR/Common.php';
640,7 → 540,6
if (isset($params[0]) && !is_array(PEAR_Common::betterStates($params[0]))) {
return $this->raiseError($params[0] . ' is not a valid state (stable/beta/alpha/devel/etc.) try "pear help list-upgrades"');
}
 
$savechannel = $channel = $this->config->get('default_channel');
$reg = &$this->config->getRegistry();
foreach ($reg->listChannels() as $channel) {
648,66 → 547,56
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];
 
if (empty($params[0])) {
$state = $this->config->get('preferred_state');
} else {
$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.3', $preferred_mirror))
|| ($base = $chan->getBaseURL('REST1.0', $preferred_mirror))
)
 
) {
if ($base2) {
$rest = &$this->config->getREST('1.3', array());
$base = $base2;
} else {
$rest = &$this->config->getREST('1.0', array());
}
 
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());
if (empty($state) || $state == 'any') {
$state = false;
} else {
$caption .= ' (' . implode(', ', PEAR_Common::betterStates($state, true)) . ')';
}
 
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$latest = $rest->listLatestUpgrades($base, $state, $inst, $channel, $reg);
PEAR::staticPopErrorHandling();
} else {
$remote = &$this->config->getRemote();
$remote->pushErrorHandling(PEAR_ERROR_RETURN);
if (empty($state) || $state == 'any') {
$latest = $remote->call("package.listLatestReleases");
} else {
$latest = $remote->call("package.listLatestReleases", $state);
$caption .= ' (' . implode(', ', PEAR_Common::betterStates($state, true)) . ')';
}
$remote->popErrorHandling();
}
 
if (PEAR::isError($latest)) {
$this->ui->outputData($latest->getMessage());
continue;
}
 
$caption .= ':';
if (PEAR::isError($latest)) {
$this->config->set('default_channel', $savechannel);
return $latest;
}
 
$data = array(
'caption' => $caption,
'border' => 1,
'headline' => array('Channel', 'Package', 'Local', 'Remote', 'Size'),
'channel' => $channel
);
 
foreach ((array)$latest as $pkg => $info) {
$package = strtolower($pkg);
if (!isset($inst[$package])) {
714,7 → 603,6
// skip packages we don't have installed
continue;
}
 
extract($info);
$inst_version = $reg->packageInfo($package, 'version', $channel);
$inst_state = $reg->packageInfo($package, 'release_state', $channel);
722,7 → 610,6
// installed version is up-to-date
continue;
}
 
if ($filesize >= 20480) {
$filesize += 1024 - ($filesize % 1024);
$fs = sprintf("%dkB", $filesize / 1024);
732,53 → 619,39
} else {
$fs = " -"; // XXX center instead
}
 
$data['data'][] = array($channel, $pkg, "$inst_version ($inst_state)", "$version ($state)", $fs);
}
 
if (isset($options['channelinfo'])) {
if (empty($data['data'])) {
unset($data['headline']);
if (count($inst) == 0) {
$data['data'] = '(no packages installed)';
} else {
$data['data'] = '(no upgrades available)';
}
}
if (empty($data['data'])) {
$this->ui->outputData('Channel ' . $channel . ': No upgrades available');
} else {
$this->ui->outputData($data, $command);
} else {
if (empty($data['data'])) {
$this->ui->outputData('Channel ' . $channel . ': No upgrades available');
} else {
$this->ui->outputData($data, $command);
}
}
}
 
$this->config->set('default_channel', $savechannel);
return true;
}
 
// }}}
// {{{ doClearCache()
 
function doClearCache($command, $options, $params)
{
$cache_dir = $this->config->get('cache_dir');
$verbose = $this->config->get('verbose');
$verbose = $this->config->get('verbose');
$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))) {
return $this->raiseError("opendir($cache_dir) failed: $php_errormsg");
}
 
if ($verbose >= 1) {
$output .= "reading directory $cache_dir\n";
}
 
$num = 0;
while ($ent = readdir($dp)) {
if (preg_match('/rest.cache(file|id)\\z/', $ent)) {
if (preg_match('/^xmlrpc_cache_[a-z0-9]{32}$/', $ent) ||
preg_match('/rest.cache(file|id)$/', $ent)) {
$path = $cache_dir . DIRECTORY_SEPARATOR . $ent;
if (file_exists($path)) {
$ok = @unlink($path);
786,7 → 659,6
$ok = false;
$php_errormsg = '';
}
 
if ($ok) {
if ($verbose >= 2) {
$output .= "deleted $path\n";
797,13 → 669,15
}
}
}
 
closedir($dp);
if ($verbose >= 1) {
$output .= "$num cache entries cleared\n";
}
 
$this->ui->outputData(rtrim($output), $command);
return $num;
}
 
// }}}
}
 
?>
/trunk/bibliotheque/pear/PEAR/Command/Build.php
4,13 → 4,20
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Build.php,v 1.13 2006/01/06 04:47:36 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
28,14 → 35,16
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
class PEAR_Command_Build extends PEAR_Command_Common
{
// {{{ properties
 
var $commands = array(
'build' => array(
'summary' => 'Build an Extension From C Source',
47,16 → 56,24
),
);
 
// }}}
 
// {{{ constructor
 
/**
* PEAR_Command_Build constructor.
*
* @access public
*/
function __construct(&$ui, &$config)
function PEAR_Command_Build(&$ui, &$config)
{
parent::__construct($ui, $config);
parent::PEAR_Command_Common($ui, $config);
}
 
// }}}
 
// {{{ doBuild()
 
function doBuild($command, $options, $params)
{
require_once 'PEAR/Builder.php';
63,17 → 80,18
if (sizeof($params) < 1) {
$params[0] = 'package.xml';
}
 
$builder = new PEAR_Builder($this->ui);
$builder = &new PEAR_Builder($this->ui);
$this->debug = $this->config->get('verbose');
$err = $builder->build($params[0], array(&$this, 'buildCallback'));
if (PEAR::isError($err)) {
return $err;
}
 
return true;
}
 
// }}}
// {{{ buildCallback()
 
function buildCallback($what, $data)
{
if (($what == 'cmdoutput' && $this->debug > 1) ||
81,4 → 99,6
$this->ui->outputData(rtrim($data), 'build');
}
}
 
// }}}
}
/trunk/bibliotheque/pear/PEAR/Command/Auth.php
4,21 → 4,28
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Auth.php,v 1.24 2006/03/05 21:23:21 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
* @deprecated since 1.8.0alpha1
*/
 
/**
* base class
*/
require_once 'PEAR/Command/Channels.php';
require_once 'PEAR/Command/Common.php';
require_once 'PEAR/Config.php';
 
/**
* PEAR commands for login/logout
27,26 → 34,24
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @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
class PEAR_Command_Auth extends PEAR_Command_Common
{
// {{{ properties
 
var $commands = array(
'login' => array(
'summary' => 'Connects and authenticates to remote server [Deprecated in favor of channel-login]',
'summary' => 'Connects and authenticates to remote server',
'shortcut' => 'li',
'function' => 'doLogin',
'options' => array(),
'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
'doc' => '
Log in to the remote server. 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
54,13 → 59,11
operations on the remote server.',
),
'logout' => array(
'summary' => 'Logs out from the remote server [Deprecated in favor of channel-logout]',
'summary' => 'Logs out from the remote server',
'shortcut' => 'lo',
'function' => 'doLogout',
'options' => array(),
'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.',
68,13 → 71,116
 
);
 
// }}}
 
// {{{ constructor
 
/**
* PEAR_Command_Auth constructor.
*
* @access public
*/
function __construct(&$ui, &$config)
function PEAR_Command_Auth(&$ui, &$config)
{
parent::__construct($ui, $config);
parent::PEAR_Command_Common($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 or
* a PEAR error on failure
*
* @access public
*/
function doLogin($command, $options, $params)
{
$reg = &$this->config->getRegistry();
$channel = $this->config->get('default_channel');
$chan = $reg->getChannel($channel);
if (PEAR::isError($chan)) {
return $this->raiseError($chan);
}
$server = $this->config->get('preferred_mirror');
$remote = &$this->config->getRemote();
$username = $this->config->get('username');
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);
$this->config->set('username', $username);
$this->config->set('password', $password);
 
if ($chan->supportsREST()) {
$ok = true;
} else {
$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!");
}
return true;
}
 
// }}}
// {{{ 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 or
* a PEAR error on failure
*
* @access public
*/
function doLogout($command, $options, $params)
{
$reg = &$this->config->getRegistry();
$channel = $this->config->get('default_channel');
$chan = $reg->getChannel($channel);
if (PEAR::isError($chan)) {
return $this->raiseError($chan);
}
$server = $this->config->get('preferred_mirror');
$this->ui->outputData("Logging out from $server.", $command);
$this->config->remove('username');
$this->config->remove('password');
$this->config->store();
return true;
}
 
// }}}
}
 
?>
/trunk/bibliotheque/pear/PEAR/Command/Remote.xml
11,12 → 11,7
<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>
<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.)
47,14 → 42,6
<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
72,10 → 59,6
<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
/trunk/bibliotheque/pear/PEAR/Command/Channels.xml
50,8 → 50,8
</force>
<channel>
<shortopt>c</shortopt>
<arg>CHANNEL</arg>
<doc>will force download of new channel.xml if an existing channel name is used</doc>
<arg>CHANNEL</arg>
</channel>
</options>
<doc>[&lt;channel.xml&gt;|&lt;channel name&gt;]
87,37 → 87,7
<shortcut>di</shortcut>
<options />
<doc>[&lt;channel.xml&gt;|&lt;channel name&gt;]
Initialize a channel from its server and create a local channel.xml.
If &lt;channel name&gt; is in the format &quot;&lt;username&gt;:&lt;password&gt;@&lt;channel&gt;&quot; then
&lt;username&gt; and &lt;password&gt; will be set as the login username/password for
&lt;channel&gt;. 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&#039;s process list.
Initialize a Channel from its server and create the local channel.xml.
</doc>
</channel-discover>
<channel-login>
<summary>Connects and authenticates to remote channel server</summary>
<function>doLogin</function>
<shortcut>cli</shortcut>
<options />
<doc>&lt;channel name&gt;
Log in to a remote channel server. If &lt;channel name&gt; 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>&lt;channel name&gt;
Logs out from a remote channel server. If &lt;channel name&gt; 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>
</commands>
/trunk/bibliotheque/pear/PEAR/Command/Package.xml
79,12 → 79,11
<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&#039;t do anything, just pretend</doc>
<doc>Don&apos;t do anything, just pretend</doc>
</dry-run>
</options>
<doc>&lt;package.xml&gt;
94,39 → 93,6
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&#039;t do anything, just pretend</doc>
</dry-run>
</options>
<doc>&lt;package.xml&gt; [files...]
Sets a SVN tag on all files in a package. Use this command after you have
packaged a distribution tarball with the &quot;package&quot; 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 &quot;slide&quot; 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>
150,18 → 116,15
</delete>
<dry-run>
<shortopt>n</shortopt>
<doc>Don&#039;t do anything, just pretend</doc>
<doc>Don&apos;t do anything, just pretend</doc>
</dry-run>
</options>
<doc>&lt;package.xml&gt; [files...]
<doc>&lt;package.xml&gt;
Sets a CVS tag on all files in a package. Use this command after you have
packaged a distribution tarball with the &quot;package&quot; 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 &quot;slide&quot; 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>
169,20 → 132,14
<function>doPackageDependencies</function>
<shortcut>pd</shortcut>
<options />
<doc>&lt;package-file&gt; or &lt;package.xml&gt; or &lt;install-package-name&gt;
List all dependencies the package has.
Can take a tgz / tar file, package.xml or a package name of an installed package.</doc>
<doc>
List all dependencies the package has.</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>
<options />
<doc>&lt;package-file&gt;
Signs a package distribution (.tar or .tgz) file with GnuPG.</doc>
</sign>
193,14 → 150,14
<options>
<spec-template>
<shortopt>t</shortopt>
<arg>FILE</arg>
<doc>Use FILE as RPM spec file template</doc>
<arg>FILE</arg>
</spec-template>
<rpm-pkgname>
<shortopt>p</shortopt>
<arg>FORMAT</arg>
<doc>Use FORMAT as format string for RPM package name, %s is replaced
by the PEAR package name, defaults to &quot;PEAR::%s&quot;.</doc>
<arg>FORMAT</arg>
</rpm-pkgname>
</options>
<doc>&lt;package-file&gt;
234,4 → 191,4
used for automated conversion or learning the format.
</doc>
</convert>
</commands>
</commands>
/trunk/bibliotheque/pear/PEAR/Command/Config.php
4,12 → 4,19
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Config.php,v 1.52 2006/03/05 21:32:47 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
26,14 → 33,16
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
class PEAR_Command_Config extends PEAR_Command_Common
{
// {{{ properties
 
var $commands = array(
'config-show' => array(
'summary' => 'Show All Settings',
127,21 → 136,29
),
);
 
// }}}
// {{{ constructor
 
/**
* PEAR_Command_Config constructor.
*
* @access public
*/
function __construct(&$ui, &$config)
function PEAR_Command_Config(&$ui, &$config)
{
parent::__construct($ui, $config);
parent::PEAR_Command_Common($ui, $config);
}
 
// }}}
 
// {{{ doConfigShow()
 
function doConfigShow($command, $options, $params)
{
$layer = null;
if (is_array($params)) {
$layer = isset($params[0]) ? $params[0] : null;
$layer = isset($params[0]) ? $params[0] : NULL;
} else {
$layer = NULL;
}
 
// $params[0] -> the layer
148,7 → 165,6
if ($error = $this->_checkLayer($layer)) {
return $this->raiseError("config-show:$error");
}
 
$keys = $this->config->getKeys();
sort($keys);
$channel = isset($options['channel']) ? $options['channel'] :
157,8 → 173,6
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) {
$type = $this->config->getType($key);
166,16 → 180,13
if ($type == 'password' && $value) {
$value = '********';
}
 
if ($value === false) {
$value = 'false';
} elseif ($value === true) {
$value = 'true';
}
 
$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));
}
184,13 → 195,21
return true;
}
 
// }}}
// {{{ doConfigGet()
 
function doConfigGet($command, $options, $params)
{
$args_cnt = is_array($params) ? count($params) : 0;
if (!is_array($params)) {
$args_cnt = 0;
} else {
$args_cnt = count($params);
}
 
switch ($args_cnt) {
case 1:
$config_key = $params[0];
$layer = null;
$layer = NULL;
break;
case 2:
$config_key = $params[0];
204,17 → 223,21
return $this->raiseError("config-get expects 1 or 2 parameters");
}
 
$channel = isset($options['channel']) ? $options['channel'] : $this->config->get('default_channel');
$reg = &$this->config->getRegistry();
$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;
}
 
// }}}
// {{{ doConfigSet()
 
function doConfigSet($command, $options, $params)
{
// $param[0] -> a parameter to set
221,41 → 244,25
// $param[1] -> the value for the parameter
// $param[2] -> the layer
$failmsg = '';
if (count($params) < 2 || count($params) > 3) {
if (sizeof($params) < 2 || sizeof($params) > 3) {
$failmsg .= "config-set expects 2 or 3 parameters";
return PEAR::raiseError($failmsg);
}
 
if (isset($params[2]) && ($error = $this->_checkLayer($params[2]))) {
$failmsg .= $error;
return PEAR::raiseError("config-set:$failmsg");
}
 
$channel = isset($options['channel']) ? $options['channel'] : $this->config->get('default_channel');
$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);
if ($params[0] == 'default_channel' && !$reg->channelExists($params[1])) {
return $this->raiseError('Channel "' . $params[1] . '" does not exist');
if ($params[0] == 'default_channel') {
if (!$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';
262,29 → 269,29
} else {
$layer = $params[2];
}
 
array_push($params, $channel);
if (!call_user_func_array(array(&$this->config, 'set'), $params)) {
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) {
return $this->raiseError($failmsg);
}
 
$this->ui->outputData('config-set succeeded', $command);
return true;
}
 
// }}}
// {{{ doConfigHelp()
 
function doConfigHelp($command, $options, $params)
{
if (empty($params)) {
$params = $this->config->getKeys();
}
 
$data['caption'] = "Config help" . ((count($params) == 1) ? " for $params[0]" : '');
$data['headline'] = array('Name', 'Type', 'Description');
$data['border'] = true;
295,13 → 302,14
$docs = rtrim($docs) . "\nValid set: " .
implode(' ', $this->config->getSetValues($name));
}
 
$data['data'][] = array($name, $type, $docs);
}
 
$this->ui->outputData($data, $command);
}
 
// }}}
// {{{ doConfigCreate()
 
function doConfigCreate($command, $options, $params)
{
if (count($params) != 2) {
308,7 → 316,6
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;
316,45 → 323,38
array('/', '/', '/'),
$root);
if ($root{0} != '/') {
if (!isset($options['windows'])) {
if (isset($options['windows'])) {
if (!preg_match('/^[A-Za-z]:/', $root)) {
return PEAR::raiseError('Root directory must be an absolute path beginning ' .
'with "\\" or "C:\\", was: "' . $root . '"');
}
} else {
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] . '"');
if (!file_exists($params[1])) {
if (!@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);
$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->set('man_dir', $windows ? "$root\\pear\\man" : "$root/pear/man");
$config->writeConfigFile();
$this->_showConfig($config);
$this->ui->outputData('Successfully created default configuration file "' . $params[1] . '"',
361,6 → 361,8
$command);
}
 
// }}}
 
function _showConfig(&$config)
{
$params = array('user');
374,7 → 376,6
if ($type == 'password' && $value) {
$value = '********';
}
 
if ($value === false) {
$value = 'false';
} elseif ($value === true) {
383,7 → 384,6
$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' ,
393,6 → 393,7
$this->ui->outputData($data, 'config-show');
return true;
}
// {{{ _checkLayer()
 
/**
* Checks if a layer is defined or not
408,7 → 409,10
return " only the layers: \"" . implode('" or "', $layers) . "\" are supported";
}
}
 
return false;
}
 
// }}}
}
 
?>
/trunk/bibliotheque/pear/PEAR/Command/Install.php
4,12 → 4,19
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Install.php,v 1.122 2007/02/13 04:30:05 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
27,9 → 34,9
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
133,11 → 140,6
'function' => 'doInstall',
'shortcut' => 'up',
'options' => array(
'channel' => array(
'shortopt' => 'c',
'doc' => 'upgrade packages from a specific channel',
'arg' => 'CHAN',
),
'force' => array(
'shortopt' => 'f',
'doc' => 'overwrite newer installed packages',
165,8 → 167,13
'installroot' => array(
'shortopt' => 'R',
'arg' => 'DIR',
'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT)',
'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT), use packagingroot for RPM',
),
'packagingroot' => array(
'shortopt' => 'P',
'arg' => 'DIR',
'doc' => 'root directory used when packaging files, like RPM packaging',
),
'ignore-errors' => array(
'doc' => 'force install even if there were errors',
),
198,15 → 205,10
More than one package may be specified at once.
'),
'upgrade-all' => array(
'summary' => 'Upgrade All Packages [Deprecated in favor of calling upgrade with no parameters]',
'function' => 'doUpgradeAll',
'summary' => 'Upgrade All Packages',
'function' => 'doInstall',
'shortcut' => 'ua',
'options' => array(
'channel' => array(
'shortopt' => 'c',
'doc' => 'upgrade packages from a specific channel',
'arg' => 'CHAN',
),
'nodeps' => array(
'shortopt' => 'n',
'doc' => 'ignore dependencies, upgrade anyway',
236,8 → 238,6
),
),
'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
312,9 → 312,9
*
* @access public
*/
function __construct(&$ui, &$config)
function PEAR_Command_Install(&$ui, &$config)
{
parent::__construct($ui, $config);
parent::PEAR_Command_Common($ui, $config);
}
 
// }}}
327,7 → 327,7
if (!class_exists('PEAR_Downloader')) {
require_once 'PEAR/Downloader.php';
}
$a = new PEAR_Downloader($ui, $options, $config);
$a = &new PEAR_Downloader($ui, $options, $config);
return $a;
}
 
339,7 → 339,7
if (!class_exists('PEAR_Installer')) {
require_once 'PEAR/Installer.php';
}
$a = new PEAR_Installer($ui);
$a = &new PEAR_Installer($ui);
return $a;
}
 
352,6 → 352,10
if (PEAR::isError($ini)) {
return $ini;
}
$fp = @fopen($phpini, 'wb');
if (!$fp) {
return PEAR::raiseError('cannot open php.ini "' . $phpini . '" for writing');
}
$line = 0;
if ($type == 'extsrc' || $type == 'extbin') {
$search = 'extensions';
363,7 → 367,7
$info = ob_get_contents();
ob_end_clean();
$debug = function_exists('leak') ? '_debug' : '';
$ts = preg_match('/Thread Safety.+enabled/', $info) ? '_ts' : '';
$ts = preg_match('Thread Safety.+enabled', $info) ? '_ts' : '';
$enable = 'zend_extension' . $debug . $ts;
}
foreach ($ini[$search] as $line => $extension) {
385,10 → 389,6
$newini[] = $enable . '="' . $binary . '"' . (OS_UNIX ? "\n" : "\r\n");
}
$newini = array_merge($newini, array_slice($ini['all'], $line));
$fp = @fopen($phpini, 'wb');
if (!$fp) {
return PEAR::raiseError('cannot open php.ini "' . $phpini . '" for writing');
}
foreach ($newini as $line) {
fwrite($fp, $line);
}
416,7 → 416,7
$info = ob_get_contents();
ob_end_clean();
$debug = function_exists('leak') ? '_debug' : '';
$ts = preg_match('/Thread Safety.+enabled/', $info) ? '_ts' : '';
$ts = preg_match('Thread Safety.+enabled', $info) ? '_ts' : '';
$enable = 'zend_extension' . $debug . $ts;
}
$found = false;
451,71 → 451,70
 
function _parseIni($filename)
{
if (!file_exists($filename)) {
return PEAR::raiseError('php.ini "' . $filename . '" does not exist');
}
 
if (filesize($filename) > 300000) {
return PEAR::raiseError('php.ini "' . $filename . '" is too large, aborting');
}
 
ob_start();
phpinfo(INFO_GENERAL);
$info = ob_get_contents();
ob_end_clean();
$debug = function_exists('leak') ? '_debug' : '';
$ts = preg_match('/Thread Safety.+enabled/', $info) ? '_ts' : '';
$zend_extension_line = 'zend_extension' . $debug . $ts;
$all = @file($filename);
if ($all === false) {
return PEAR::raiseError('php.ini "' . $filename .'" could not be read');
}
$zend_extensions = $extensions = array();
// assume this is right, but pull from the php.ini if it is found
$extension_dir = ini_get('extension_dir');
foreach ($all as $linenum => $line) {
$line = trim($line);
if (!$line) {
continue;
if (file_exists($filename)) {
if (filesize($filename) > 300000) {
return PEAR::raiseError('php.ini "' . $filename . '" is too large, aborting');
}
if ($line[0] == ';') {
continue;
ob_start();
phpinfo(INFO_GENERAL);
$info = ob_get_contents();
ob_end_clean();
$debug = function_exists('leak') ? '_debug' : '';
$ts = preg_match('/Thread Safety.+enabled/', $info) ? '_ts' : '';
$zend_extension_line = 'zend_extension' . $debug . $ts;
$all = @file($filename);
if (!$all) {
return PEAR::raiseError('php.ini "' . $filename .'" could not be read');
}
if (strtolower(substr($line, 0, 13)) == 'extension_dir') {
$line = trim(substr($line, 13));
if ($line[0] == '=') {
$x = trim(substr($line, 1));
$x = explode(';', $x);
$extension_dir = str_replace('"', '', array_shift($x));
$zend_extensions = $extensions = array();
// assume this is right, but pull from the php.ini if it is found
$extension_dir = ini_get('extension_dir');
foreach ($all as $linenum => $line) {
$line = trim($line);
if (!$line) {
continue;
}
}
if (strtolower(substr($line, 0, 9)) == 'extension') {
$line = trim(substr($line, 9));
if ($line[0] == '=') {
$x = trim(substr($line, 1));
$x = explode(';', $x);
$extensions[$linenum] = str_replace('"', '', array_shift($x));
if ($line[0] == ';') {
continue;
}
}
if (strtolower(substr($line, 0, strlen($zend_extension_line))) ==
$zend_extension_line) {
$line = trim(substr($line, strlen($zend_extension_line)));
if ($line[0] == '=') {
$x = trim(substr($line, 1));
$x = explode(';', $x);
$zend_extensions[$linenum] = str_replace('"', '', array_shift($x));
continue;
if (strtolower(substr($line, 0, 13)) == 'extension_dir') {
$line = trim(substr($line, 13));
if ($line[0] == '=') {
$x = trim(substr($line, 1));
$x = explode(';', $x);
$extension_dir = str_replace('"', '', array_shift($x));
continue;
}
}
if (strtolower(substr($line, 0, 9)) == 'extension') {
$line = trim(substr($line, 9));
if ($line[0] == '=') {
$x = trim(substr($line, 1));
$x = explode(';', $x);
$extensions[$linenum] = str_replace('"', '', array_shift($x));
continue;
}
}
if (strtolower(substr($line, 0, strlen($zend_extension_line))) ==
$zend_extension_line) {
$line = trim(substr($line, strlen($zend_extension_line)));
if ($line[0] == '=') {
$x = trim(substr($line, 1));
$x = explode(';', $x);
$zend_extensions[$linenum] = str_replace('"', '', array_shift($x));
continue;
}
}
}
return array(
'extensions' => $extensions,
'zend_extensions' => $zend_extensions,
'extension_dir' => $extension_dir,
'all' => $all,
);
} else {
return PEAR::raiseError('php.ini "' . $filename . '" does not exist');
}
return array(
'extensions' => $extensions,
'zend_extensions' => $zend_extensions,
'extension_dir' => $extension_dir,
'all' => $all,
);
}
 
// {{{ doInstall()
522,176 → 521,98
 
function doInstall($command, $options, $params)
{
if (!class_exists('PEAR_PackageFile')) {
require_once 'PEAR/PackageFile.php';
if (empty($this->installer)) {
$this->installer = &$this->getInstaller($this->ui);
}
 
if ($command == 'upgrade') {
$options['upgrade'] = true;
}
if (isset($options['installroot']) && isset($options['packagingroot'])) {
return $this->raiseError('ERROR: cannot use both --installroot and --packagingroot');
}
 
if (isset($options['packagingroot']) && $this->config->get('verbose') > 2) {
$this->ui->outputData('using package root: ' . $options['packagingroot']);
}
$reg = &$this->config->getRegistry();
$channel = isset($options['channel']) ? $options['channel'] : $this->config->get('default_channel');
if (!$reg->channelExists($channel)) {
return $this->raiseError('Channel "' . $channel . '" does not exist');
}
 
if (empty($this->installer)) {
$this->installer = &$this->getInstaller($this->ui);
}
 
if ($command == 'upgrade' || $command == 'upgrade-all') {
// If people run the upgrade command but pass nothing, emulate a upgrade-all
if ($command == 'upgrade' && empty($params)) {
return $this->doUpgradeAll($command, $options, $params);
}
if ($command == 'upgrade-all') {
$options['upgrade'] = true;
} else {
$packages = $params;
}
 
$instreg = &$reg; // instreg used to check if package is installed
if (isset($options['packagingroot']) && !isset($options['upgrade'])) {
$packrootphp_dir = $this->installer->_prependPath(
$this->config->get('php_dir', null, 'pear.php.net'),
$options['packagingroot']);
$metadata_dir = $this->config->get('metadata_dir', null, 'pear.php.net');
if ($metadata_dir) {
$metadata_dir = $this->installer->_prependPath(
$metadata_dir,
$options['packagingroot']);
}
$instreg = new PEAR_Registry($packrootphp_dir, false, false, $metadata_dir); // other instreg!
 
if ($this->config->get('verbose') > 2) {
$this->ui->outputData('using package root: ' . $options['packagingroot']);
}
}
 
$abstractpackages = $otherpackages = array();
// parse params
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
 
foreach ($params as $param) {
if (strpos($param, 'http://') === 0) {
$otherpackages[] = $param;
continue;
}
 
if (strpos($param, 'channel://') === false && @file_exists($param)) {
if (isset($options['force'])) {
$otherpackages[] = $param;
$reg = &$this->config->getRegistry();
$savechannel = $this->config->get('default_channel');
$params = array();
foreach ($reg->listChannels() as $channel) {
if ($channel == '__uri') {
continue;
}
 
$pkg = new PEAR_PackageFile($this->config);
$pf = $pkg->fromAnyFile($param, PEAR_VALIDATE_DOWNLOADING);
if (PEAR::isError($pf)) {
$otherpackages[] = $param;
continue;
$this->config->set('default_channel', $channel);
$chan = &$reg->getChannel($channel);
if (PEAR::isError($chan)) {
return $this->raiseError($chan);
}
 
$exists = $reg->packageExists($pf->getPackage(), $pf->getChannel());
$pversion = $reg->packageInfo($pf->getPackage(), 'version', $pf->getChannel());
$version_compare = version_compare($pf->getVersion(), $pversion, '<=');
if ($exists && $version_compare) {
if ($this->config->get('verbose')) {
$this->ui->outputData('Ignoring installed package ' .
$reg->parsedPackageNameToString(
array('package' => $pf->getPackage(),
'channel' => $pf->getChannel()), true));
if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
$base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
$dorest = true;
unset($remote);
} else {
$dorest = false;
$remote = &$this->config->getRemote($this->config);
}
$state = $this->config->get('preferred_state');
$installed = array_flip($reg->listPackages($channel));
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
if ($dorest) {
$rest = &$this->config->getREST('1.0', array());
$latest = $rest->listLatestUpgrades($base, $state, $installed, $channel, $reg);
} else {
if (empty($state) || $state == 'any') {
$latest = $remote->call("package.listLatestReleases");
} else {
$latest = $remote->call("package.listLatestReleases", $state);
}
}
PEAR::staticPopErrorHandling();
if (PEAR::isError($latest) || !is_array($latest)) {
continue;
}
$otherpackages[] = $param;
continue;
}
 
$e = $reg->parsePackageName($param, $channel);
if (PEAR::isError($e)) {
$otherpackages[] = $param;
} else {
$abstractpackages[] = $e;
}
}
PEAR::staticPopErrorHandling();
 
// if there are any local package .tgz or remote static url, we can't
// filter. The filter only works for abstract packages
if (count($abstractpackages) && !isset($options['force'])) {
// when not being forced, only do necessary upgrades/installs
if (isset($options['upgrade'])) {
$abstractpackages = $this->_filterUptodatePackages($abstractpackages, $command);
} else {
$count = count($abstractpackages);
foreach ($abstractpackages as $i => $package) {
if (isset($package['group'])) {
// do not filter out install groups
foreach ($latest as $package => $info) {
$package = strtolower($package);
if (!isset($installed[$package])) {
// skip packages we don't have installed
continue;
}
 
if ($instreg->packageExists($package['package'], $package['channel'])) {
if ($count > 1) {
if ($this->config->get('verbose')) {
$this->ui->outputData('Ignoring installed package ' .
$reg->parsedPackageNameToString($package, true));
}
unset($abstractpackages[$i]);
} elseif ($count === 1) {
// Lets try to upgrade it since it's already installed
$options['upgrade'] = true;
}
$inst_version = $reg->packageInfo($package, 'version', $channel);
if (version_compare("$info[version]", "$inst_version", "le")) {
// installed version is up-to-date
continue;
}
$params[] = $a = $reg->parsedPackageNameToString(array('package' => $package,
'channel' => $channel));
$this->ui->outputData(array('data' => "Will upgrade $a"), $command);
}
}
$abstractpackages =
array_map(array($reg, 'parsedPackageNameToString'), $abstractpackages);
} elseif (count($abstractpackages)) {
$abstractpackages =
array_map(array($reg, 'parsedPackageNameToString'), $abstractpackages);
$this->config->set('default_channel', $savechannel);
}
 
$packages = array_merge($abstractpackages, $otherpackages);
if (!count($packages)) {
$c = '';
if (isset($options['channel'])){
$c .= ' in channel "' . $options['channel'] . '"';
}
$this->ui->outputData('Nothing to ' . $command . $c);
return true;
}
 
$this->downloader = &$this->getDownloader($this->ui, $options, $this->config);
$errors = $downloaded = $binaries = array();
$downloaded = &$this->downloader->download($packages);
$errors = array();
$downloaded = array();
$downloaded = &$this->downloader->download($params);
if (PEAR::isError($downloaded)) {
return $this->raiseError($downloaded);
}
 
$errors = $this->downloader->getErrorMsgs();
if (count($errors)) {
$err = array();
$err['data'] = array();
foreach ($errors as $error) {
if ($error !== null) {
$err['data'][] = array($error);
}
$err['data'][] = array($error);
}
 
if (!empty($err['data'])) {
$err['headline'] = 'Install Errors';
$this->ui->outputData($err);
}
 
$err['headline'] = 'Install Errors';
$this->ui->outputData($err);
if (!count($downloaded)) {
return $this->raiseError("$command failed");
}
}
 
$data = array(
'headline' => 'Packages that would be Installed'
);
 
if (isset($options['pretend'])) {
foreach ($downloaded as $package) {
$data['data'][] = array($reg->parsedPackageNameToString($package->getParsedPackage()));
699,7 → 620,6
$this->ui->outputData($data, 'pretend');
return true;
}
 
$this->installer->setOptions($options);
$this->installer->sortPackagesForInstall($downloaded);
if (PEAR::isError($err = $this->installer->setDownloadedPackages($downloaded))) {
706,8 → 626,15
$this->raiseError($err->getMessage());
return true;
}
 
$binaries = $extrainfo = array();
$extrainfo = array();
if (isset($options['packagingroot'])) {
$packrootphp_dir = $this->installer->_prependPath(
$this->config->get('php_dir', null, 'pear.php.net'),
$options['packagingroot']);
$instreg = new PEAR_Registry($packrootphp_dir);
} else {
$instreg = $reg;
}
foreach ($downloaded as $param) {
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$info = $this->installer->install($param, $options);
720,50 → 647,39
$this->ui->outputData('ERROR: ' .$oldinfo->getMessage());
continue;
}
 
// we just installed a different package than requested,
// let's change the param and info so that the rest of this works
$param = $info[0];
$info = $info[1];
$info = $info[1];
}
}
 
if (!is_array($info)) {
return $this->raiseError("$command failed");
}
 
if ($param->getPackageType() == 'extsrc' ||
$param->getPackageType() == 'extbin' ||
$param->getPackageType() == 'zendextsrc' ||
$param->getPackageType() == 'zendextbin'
) {
$pkg = &$param->getPackageFile();
if ($instbin = $pkg->getInstalledBinary()) {
$instpkg = &$instreg->getPackage($instbin, $pkg->getChannel());
} else {
$instpkg = &$instreg->getPackage($pkg->getPackage(), $pkg->getChannel());
}
 
foreach ($instpkg->getFilelist() as $name => $atts) {
$pinfo = pathinfo($atts['installed_as']);
if (!isset($pinfo['extension']) ||
in_array($pinfo['extension'], array('c', 'h'))
) {
continue; // make sure we don't match php_blah.h
if (is_array($info)) {
if ($param->getPackageType() == 'extsrc' ||
$param->getPackageType() == 'extbin' ||
$param->getPackageType() == 'zendextsrc' ||
$param->getPackageType() == 'zendextbin') {
$pkg = &$param->getPackageFile();
if ($instbin = $pkg->getInstalledBinary()) {
$instpkg = &$instreg->getPackage($instbin, $pkg->getChannel());
} else {
$instpkg = &$instreg->getPackage($pkg->getPackage(), $pkg->getChannel());
}
 
if ((strpos($pinfo['basename'], 'php_') === 0 &&
$pinfo['extension'] == 'dll') ||
// most unices
$pinfo['extension'] == 'so' ||
// hp-ux
$pinfo['extension'] == 'sl') {
$binaries[] = array($atts['installed_as'], $pinfo);
break;
foreach ($instpkg->getFilelist() as $name => $atts) {
$pinfo = pathinfo($atts['installed_as']);
if (!isset($pinfo['extension']) ||
in_array($pinfo['extension'], array('c', 'h'))) {
continue; // make sure we don't match php_blah.h
}
if ((strpos($pinfo['basename'], 'php_') === 0 &&
$pinfo['extension'] == 'dll') ||
// most unices
$pinfo['extension'] == 'so' ||
// hp-ux
$pinfo['extension'] == 'sl') {
$binaries[] = array($atts['installed_as'], $pinfo);
break;
}
}
}
 
if (count($binaries)) {
foreach ($binaries as $pinfo) {
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$ret = $this->enableExtension(array($pinfo[0]), $param->getPackageType());
773,13 → 689,17
if ($param->getPackageType() == 'extsrc' ||
$param->getPackageType() == 'extbin') {
$exttype = 'extension';
$extpath = $pinfo[1]['basename'];
} else {
$exttype = 'zend_extension';
$extpath = $atts['installed_as'];
ob_start();
phpinfo(INFO_GENERAL);
$info = ob_get_contents();
ob_end_clean();
$debug = function_exists('leak') ? '_debug' : '';
$ts = preg_match('Thread Safety.+enabled', $info) ? '_ts' : '';
$exttype = 'zend_extension' . $debug . $ts;
}
$extrainfo[] = 'You should add "' . $exttype . '=' .
$extpath . '" to php.ini';
$pinfo[1]['basename'] . '" to php.ini';
} else {
$extrainfo[] = 'Extension ' . $instpkg->getProvidesExtension() .
' enabled in php.ini';
786,139 → 706,100
}
}
}
}
 
if ($this->config->get('verbose') > 0) {
$chan = $param->getChannel();
$label = $reg->parsedPackageNameToString(
array(
'channel' => $chan,
'package' => $param->getPackage(),
'version' => $param->getVersion(),
));
$out = array('data' => "$command ok: $label");
if (isset($info['release_warnings'])) {
$out['release_warnings'] = $info['release_warnings'];
}
$this->ui->outputData($out, $command);
 
if (!isset($options['register-only']) && !isset($options['offline'])) {
if ($this->config->isDefinedLayer('ftp')) {
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$info = $this->installer->ftpInstall($param);
PEAR::staticPopErrorHandling();
if (PEAR::isError($info)) {
$this->ui->outputData($info->getMessage());
$this->ui->outputData("remote install failed: $label");
} else {
$this->ui->outputData("remote install ok: $label");
if ($this->config->get('verbose') > 0) {
$channel = $param->getChannel();
$label = $reg->parsedPackageNameToString(
array(
'channel' => $channel,
'package' => $param->getPackage(),
'version' => $param->getVersion(),
));
$out = array('data' => "$command ok: $label");
if (isset($info['release_warnings'])) {
$out['release_warnings'] = $info['release_warnings'];
}
$this->ui->outputData($out, $command);
if (!isset($options['register-only']) && !isset($options['offline'])) {
if ($this->config->isDefinedLayer('ftp')) {
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$info = $this->installer->ftpInstall($param);
PEAR::staticPopErrorHandling();
if (PEAR::isError($info)) {
$this->ui->outputData($info->getMessage());
$this->ui->outputData("remote install failed: $label");
} else {
$this->ui->outputData("remote install ok: $label");
}
}
}
}
}
 
$deps = $param->getDeps();
if ($deps) {
if (isset($deps['group'])) {
$groups = $deps['group'];
if (!isset($groups[0])) {
$groups = array($groups);
}
 
foreach ($groups as $group) {
if ($group['attribs']['name'] == 'default') {
// default group is always installed, unless the user
// explicitly chooses to install another group
continue;
$deps = $param->getDeps();
if ($deps) {
if (isset($deps['group'])) {
$groups = $deps['group'];
if (!isset($groups[0])) {
$groups = array($groups);
}
$extrainfo[] = $param->getPackage() . ': Optional feature ' .
$group['attribs']['name'] . ' available (' .
$group['attribs']['hint'] . ')';
foreach ($groups as $group) {
if ($group['attribs']['name'] == 'default') {
// default group is always installed, unless the user
// explicitly chooses to install another group
continue;
}
$this->ui->outputData($param->getPackage() . ': Optional feature ' .
$group['attribs']['name'] . ' available (' .
$group['attribs']['hint'] . ')');
}
$extrainfo[] = 'To install use "pear install ' .
$reg->parsedPackageNameToString(
array('package' => $param->getPackage(),
'channel' => $param->getChannel()), true) .
'#featurename"';
}
 
$extrainfo[] = $param->getPackage() .
': To install optional features use "pear install ' .
$reg->parsedPackageNameToString(
array('package' => $param->getPackage(),
'channel' => $param->getChannel()), true) .
'#featurename"';
}
}
 
$pkg = &$instreg->getPackage($param->getPackage(), $param->getChannel());
// $pkg may be NULL if install is a 'fake' install via --packagingroot
if (is_object($pkg)) {
$pkg->setConfig($this->config);
if ($list = $pkg->listPostinstallScripts()) {
$pn = $reg->parsedPackageNameToString(array('channel' =>
$param->getChannel(), 'package' => $param->getPackage()), true);
$extrainfo[] = $pn . ' has post-install scripts:';
foreach ($list as $file) {
$extrainfo[] = $file;
if (isset($options['installroot'])) {
$reg = &$this->config->getRegistry();
}
if (isset($options['packagingroot'])) {
$instreg = new PEAR_Registry($packrootphp_dir);
} else {
$instreg = $reg;
}
$pkg = &$instreg->getPackage($param->getPackage(), $param->getChannel());
// $pkg may be NULL if install is a 'fake' install via --packagingroot
if (is_object($pkg)) {
$pkg->setConfig($this->config);
if ($list = $pkg->listPostinstallScripts()) {
$pn = $reg->parsedPackageNameToString(array('channel' =>
$param->getChannel(), 'package' => $param->getPackage()), true);
$extrainfo[] = $pn . ' has post-install scripts:';
foreach ($list as $file) {
$extrainfo[] = $file;
}
$extrainfo[] = 'Use "pear run-scripts ' . $pn . '" to run';
$extrainfo[] = 'DO NOT RUN SCRIPTS FROM UNTRUSTED SOURCES';
}
$extrainfo[] = $param->getPackage() .
': Use "pear run-scripts ' . $pn . '" to finish setup.';
$extrainfo[] = 'DO NOT RUN SCRIPTS FROM UNTRUSTED SOURCES';
}
} else {
return $this->raiseError("$command failed");
}
}
 
if (count($extrainfo)) {
foreach ($extrainfo as $info) {
$this->ui->outputData($info);
}
}
 
return true;
}
 
// }}}
// {{{ doUpgradeAll()
 
function doUpgradeAll($command, $options, $params)
{
$reg = &$this->config->getRegistry();
$upgrade = array();
 
if (isset($options['channel'])) {
$channels = array($options['channel']);
} else {
$channels = $reg->listChannels();
}
 
foreach ($channels as $channel) {
if ($channel == '__uri') {
continue;
}
 
// parse name with channel
foreach ($reg->listPackages($channel) as $name) {
$upgrade[] = $reg->parsedPackageNameToString(array(
'channel' => $channel,
'package' => $name
));
}
}
 
$err = $this->doInstall($command, $options, $upgrade);
if (PEAR::isError($err)) {
$this->ui->outputData($err->getMessage(), $command);
}
}
 
// }}}
// {{{ doUninstall()
 
function doUninstall($command, $options, $params)
{
if (count($params) < 1) {
return $this->raiseError("Please supply the package(s) you want to uninstall");
}
 
if (empty($this->installer)) {
$this->installer = &$this->getInstaller($this->ui);
}
 
if (isset($options['remoteconfig'])) {
$e = $this->config->readFTPConfigFile($options['remoteconfig']);
if (!PEAR::isError($e)) {
925,10 → 806,11
$this->installer->setConfig($this->config);
}
}
 
if (sizeof($params) < 1) {
return $this->raiseError("Please supply the package(s) you want to uninstall");
}
$reg = &$this->config->getRegistry();
$newparams = array();
$binaries = array();
$badparams = array();
foreach ($params as $pkg) {
$channel = $this->config->get('default_channel');
967,7 → 849,7
if (isset($parsed['group'])) {
$group = $info->getDependencyGroup($parsed['group']);
if ($group) {
$installed = $reg->getInstalledGroup($group);
$installed = &$reg->getInstalledGroup($group);
if ($installed) {
foreach ($installed as $i => $p) {
$newparams[] = &$installed[$i];
987,7 → 869,6
// for circular dependencies like subpackages
$this->installer->setUninstallPackages($newparams);
$params = array_merge($params, $badparams);
$binaries = array();
foreach ($params as $pkg) {
$this->installer->pushErrorHandling(PEAR_ERROR_RETURN);
if ($err = $this->installer->uninstall($pkg, $options)) {
1003,7 → 884,6
if ($instbin = $pkg->getInstalledBinary()) {
continue; // this will be uninstalled later
}
 
foreach ($pkg->getFilelist() as $name => $atts) {
$pinfo = pathinfo($atts['installed_as']);
if (!isset($pinfo['extension']) ||
1020,31 → 900,29
break;
}
}
if (count($binaries)) {
foreach ($binaries as $pinfo) {
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$ret = $this->disableExtension(array($pinfo[0]), $pkg->getPackageType());
PEAR::staticPopErrorHandling();
if (PEAR::isError($ret)) {
$extrainfo[] = $ret->getMessage();
if ($pkg->getPackageType() == 'extsrc' ||
$pkg->getPackageType() == 'extbin') {
$exttype = 'extension';
} else {
ob_start();
phpinfo(INFO_GENERAL);
$info = ob_get_contents();
ob_end_clean();
$debug = function_exists('leak') ? '_debug' : '';
$ts = preg_match('/Thread Safety.+enabled/', $info) ? '_ts' : '';
$exttype = 'zend_extension' . $debug . $ts;
}
$this->ui->outputData('Unable to remove "' . $exttype . '=' .
$pinfo[1]['basename'] . '" from php.ini', $command);
foreach ($binaries as $pinfo) {
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$ret = $this->disableExtension(array($pinfo[0]), $pkg->getPackageType());
PEAR::staticPopErrorHandling();
if (PEAR::isError($ret)) {
$extrainfo[] = $ret->getMessage();
if ($pkg->getPackageType() == 'extsrc' ||
$pkg->getPackageType() == 'extbin') {
$exttype = 'extension';
} else {
$this->ui->outputData('Extension ' . $pkg->getProvidesExtension() .
' disabled in php.ini', $command);
ob_start();
phpinfo(INFO_GENERAL);
$info = ob_get_contents();
ob_end_clean();
$debug = function_exists('leak') ? '_debug' : '';
$ts = preg_match('Thread Safety.+enabled', $info) ? '_ts' : '';
$exttype = 'zend_extension' . $debug . $ts;
}
$this->ui->outputData('Unable to remove "' . $exttype . '=' .
$pinfo[1]['basename'] . '" from php.ini', $command);
} else {
$this->ui->outputData('Extension ' . $pkg->getProvidesExtension() .
' disabled in php.ini', $command);
}
}
}
1071,13 → 949,12
}
} else {
$this->installer->popErrorHandling();
if (!is_object($pkg)) {
return $this->raiseError("uninstall failed: $pkg");
if (is_object($pkg)) {
$pkg = $reg->parsedPackageNameToString($pkg);
}
$pkg = $reg->parsedPackageNameToString($pkg);
return $this->raiseError("uninstall failed: $pkg");
}
}
 
return true;
}
 
1093,15 → 970,10
 
function doBundle($command, $options, $params)
{
$opts = array(
'force' => true,
'nodeps' => true,
'soft' => true,
'downloadonly' => true
);
$downloader = &$this->getDownloader($this->ui, $opts, $this->config);
$downloader = &$this->getDownloader($this->ui, array('force' => true, 'nodeps' => true,
'soft' => true, 'downloadonly' => true), $this->config);
$reg = &$this->config->getRegistry();
if (count($params) < 1) {
if (sizeof($params) < 1) {
return $this->raiseError("Please supply the package you want to bundle");
}
 
1111,24 → 983,18
}
$dest = realpath($options['destination']);
} else {
$pwd = getcwd();
$dir = $pwd . DIRECTORY_SEPARATOR . 'ext';
$dest = is_dir($dir) ? $dir : $pwd;
$pwd = getcwd();
if (is_dir($pwd . DIRECTORY_SEPARATOR . 'ext')) {
$dest = $pwd . DIRECTORY_SEPARATOR . 'ext';
} else {
$dest = $pwd;
}
}
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$err = $downloader->setDownloadDir($dest);
PEAR::staticPopErrorHandling();
if (PEAR::isError($err)) {
return PEAR::raiseError('download directory "' . $dest .
'" is not writeable.');
}
$downloader->setDownloadDir($dest);
$result = &$downloader->download(array($params[0]));
if (PEAR::isError($result)) {
return $result;
}
if (!isset($result[0])) {
return $this->raiseError('unable to unpack ' . $params[0]);
}
$pkgfile = &$result[0]->getPackageFile();
$pkgname = $pkgfile->getName();
$pkgversion = $pkgfile->getVersion();
1137,7 → 1003,7
$dest .= DIRECTORY_SEPARATOR . $pkgname;
$orig = $pkgname . '-' . $pkgversion;
 
$tar = new Archive_Tar($pkgfile->getArchiveFile());
$tar = &new Archive_Tar($pkgfile->getArchiveFile());
if (!$tar->extractModify($dest, $orig)) {
return $this->raiseError('unable to unpack ' . $pkgfile->getArchiveFile());
}
1152,7 → 1018,6
if (!isset($params[0])) {
return $this->raiseError('run-scripts expects 1 parameter: a package name');
}
 
$reg = &$this->config->getRegistry();
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$parsed = $reg->parsePackageName($params[0], $this->config->get('default_channel'));
1160,110 → 1025,15
if (PEAR::isError($parsed)) {
return $this->raiseError($parsed);
}
 
$package = &$reg->getPackage($parsed['package'], $parsed['channel']);
if (!is_object($package)) {
if (is_object($package)) {
$package->setConfig($this->config);
$package->runPostinstallScripts();
} else {
return $this->raiseError('Could not retrieve package "' . $params[0] . '" from registry');
}
 
$package->setConfig($this->config);
$package->runPostinstallScripts();
$this->ui->outputData('Install scripts complete', $command);
return true;
}
 
/**
* Given a list of packages, filter out those ones that are already up to date
*
* @param $packages: packages, in parsed array format !
* @return list of packages that can be upgraded
*/
function _filterUptodatePackages($packages, $command)
{
$reg = &$this->config->getRegistry();
$latestReleases = array();
 
$ret = array();
foreach ($packages as $package) {
if (isset($package['group'])) {
$ret[] = $package;
continue;
}
 
$channel = $package['channel'];
$name = $package['package'];
if (!$reg->packageExists($name, $channel)) {
$ret[] = $package;
continue;
}
 
if (!isset($latestReleases[$channel])) {
// fill in cache for this channel
$chan = $reg->getChannel($channel);
if (PEAR::isError($chan)) {
return $this->raiseError($chan);
}
 
$base2 = false;
$preferred_mirror = $this->config->get('preferred_mirror', null, $channel);
if ($chan->supportsREST($preferred_mirror) &&
(
//($base2 = $chan->getBaseURL('REST1.4', $preferred_mirror)) ||
($base = $chan->getBaseURL('REST1.0', $preferred_mirror))
)
) {
$dorest = true;
}
 
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
if (!isset($package['state'])) {
$state = $this->config->get('preferred_state', null, $channel);
} else {
$state = $package['state'];
}
 
if ($dorest) {
if ($base2) {
$rest = &$this->config->getREST('1.4', array());
$base = $base2;
} else {
$rest = &$this->config->getREST('1.0', array());
}
 
$installed = array_flip($reg->listPackages($channel));
$latest = $rest->listLatestUpgrades($base, $state, $installed, $channel, $reg);
}
 
PEAR::staticPopErrorHandling();
if (PEAR::isError($latest)) {
$this->ui->outputData('Error getting channel info from ' . $channel .
': ' . $latest->getMessage());
continue;
}
 
$latestReleases[$channel] = array_change_key_case($latest);
}
 
// check package for latest release
$name_lower = strtolower($name);
if (isset($latestReleases[$channel][$name_lower])) {
// if not set, up to date
$inst_version = $reg->packageInfo($name, 'version', $channel);
$channel_version = $latestReleases[$channel][$name_lower]['version'];
if (version_compare($channel_version, $inst_version, 'le')) {
// installed version is up-to-date
continue;
}
 
// maintain BC
if ($command == 'upgrade-all') {
$this->ui->outputData(array('data' => 'Will upgrade ' .
$reg->parsedPackageNameToString($package)), $command);
}
$ret[] = $package;
}
}
 
return $ret;
}
}
?>
/trunk/bibliotheque/pear/PEAR/Command/Pickle.php
4,11 → 4,18
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 2005-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Pickle.php,v 1.6 2006/05/12 02:38:58 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.1
*/
24,9 → 31,9
* @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.10.1
* @copyright 2005-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.1
*/
75,11 → 82,12
*
* @access public
*/
function __construct(&$ui, &$config)
function PEAR_Command_Pickle(&$ui, &$config)
{
parent::__construct($ui, $config);
parent::PEAR_Command_Common($ui, $config);
}
 
 
/**
* For unit-testing ease
*
90,8 → 98,7
if (!class_exists('PEAR_Packager')) {
require_once 'PEAR/Packager.php';
}
 
$a = new PEAR_Packager;
$a = &new PEAR_Packager;
return $a;
}
 
103,17 → 110,15
* @param string|null $tmpdir
* @return PEAR_PackageFile
*/
function &getPackageFile($config, $debug = false)
function &getPackageFile($config, $debug = false, $tmpdir = null)
{
if (!class_exists('PEAR_Common')) {
require_once 'PEAR/Common.php';
}
 
if (!class_exists('PEAR_PackageFile')) {
if (!class_exists('PEAR/PackageFile.php')) {
require_once 'PEAR/PackageFile.php';
}
 
$a = new PEAR_PackageFile($config, $debug);
$a = &new PEAR_PackageFile($config, $debug, $tmpdir);
$common = new PEAR_Common;
$common->ui = $this->ui;
$a->setLogger($common);
128,18 → 133,15
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;
}
 
151,7 → 153,6
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);
160,19 → 161,16
'", 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 .
179,7 → 177,6
'", 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 .
186,19 → 183,16
'", 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());
206,7 → 200,6
$pf->addMaintainer($maintainer['role'], $maintainer['handle'],
$maintainer['name'], $maintainer['email']);
}
 
$pf->setVersion($pf2->getVersion());
$pf->setDate($pf2->getDate());
$pf->setLicense($pf2->getLicense());
216,12 → 209,10
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 . '"' .
228,40 → 219,31
' 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') {
if ($dep['channel'] != 'pear.php.net' && $dep['channel'] != 'pecl.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 . '"' .
268,26 → 250,21
' 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 . '"' .
294,90 → 271,72
' 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') {
if ($dep['channel'] != 'pear.php.net' && $dep['channel'] != 'pecl.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();
$release = $pf2->getReleases();
if (isset($releases[0])) {
return $this->raiseError('Cannot safely process "' . $packagexml . '" contains '
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);
$pf->addConfigureOption($option['name'], $option['prompt'],
isset($option['default']) ? $option['default'] : false);
}
}
 
if (isset($release['filelist']['ignore'])) {
return $this->raiseError('Cannot safely process "' . $packagexml . '" contains '
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)) {
390,13 → 349,11
$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']) {
404,17 → 361,16
}
}
}
 
$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('.');
}
}
 
?>
/trunk/bibliotheque/pear/PEAR/Command/Registry.php
4,12 → 4,19
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Registry.php,v 1.75 2006/11/19 23:50:09 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
26,14 → 33,16
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
class PEAR_Command_Registry extends PEAR_Command_Common
{
// {{{ properties
 
var $commands = array(
'list' => array(
'summary' => 'List Installed Packages In The Default Channel',
49,10 → 58,6
'shortopt' => 'a',
'doc' => 'list installed packages from all channels',
),
'channelinfo' => array(
'shortopt' => 'i',
'doc' => 'output fully channel-aware data, even on failure',
),
),
'doc' => '<package>
If invoked without parameters, this command lists the PEAR packages
92,16 → 97,23
)
);
 
// }}}
// {{{ constructor
 
/**
* PEAR_Command_Registry constructor.
*
* @access public
*/
function __construct(&$ui, &$config)
function PEAR_Command_Registry(&$ui, &$config)
{
parent::__construct($ui, $config);
parent::PEAR_Command_Common($ui, $config);
}
 
// }}}
 
// {{{ doList()
 
function _sortinfo($a, $b)
{
$apackage = isset($a['package']) ? $a['package'] : $a['name'];
111,131 → 123,67
 
function doList($command, $options, $params)
{
$reg = &$this->config->getRegistry();
$channelinfo = isset($options['channelinfo']);
if (isset($options['allchannels']) && !$channelinfo) {
if (isset($options['allchannels'])) {
return $this->doListAll($command, array(), $params);
}
 
if (isset($options['allchannels']) && $channelinfo) {
// allchannels with $channelinfo
unset($options['allchannels']);
$channels = $reg->getChannels();
$errors = array();
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
foreach ($channels as $channel) {
$options['channel'] = $channel->getName();
$ret = $this->doList($command, $options, $params);
 
if (PEAR::isError($ret)) {
$errors[] = $ret;
}
}
 
PEAR::staticPopErrorHandling();
if (count($errors)) {
// for now, only give first error
return PEAR::raiseError($errors[0]);
}
 
return true;
}
 
if (count($params) === 1) {
$reg = &$this->config->getRegistry();
if (count($params) == 1) {
return $this->doFileList($command, $options, $params);
}
 
if (isset($options['channel'])) {
if (!$reg->channelExists($options['channel'])) {
if ($reg->channelExists($options['channel'])) {
$channel = $reg->channelName($options['channel']);
} else {
return $this->raiseError('Channel "' . $options['channel'] .'" does not exist');
}
 
$channel = $reg->channelName($options['channel']);
} else {
$channel = $this->config->get('default_channel');
}
 
$installed = $reg->packageInfo(null, null, $channel);
usort($installed, array(&$this, '_sortinfo'));
 
$i = $j = 0;
$data = array(
'caption' => 'Installed packages, channel ' .
$channel . ':',
'border' => true,
'headline' => array('Package', 'Version', 'State'),
'channel' => $channel,
'headline' => array('Package', 'Version', 'State')
);
if ($channelinfo) {
$data['headline'] = array('Channel', 'Package', 'Version', 'State');
}
 
if (count($installed) && !isset($data['data'])) {
$data['data'] = array();
}
 
foreach ($installed as $package) {
$pobj = $reg->getPackage(isset($package['package']) ?
$package['package'] : $package['name'], $channel);
if ($channelinfo) {
$packageinfo = array($pobj->getChannel(), $pobj->getPackage(), $pobj->getVersion(),
$data['data'][] = array($pobj->getPackage(), $pobj->getVersion(),
$pobj->getState() ? $pobj->getState() : null);
} else {
$packageinfo = array($pobj->getPackage(), $pobj->getVersion(),
$pobj->getState() ? $pobj->getState() : null);
}
$data['data'][] = $packageinfo;
}
 
if (count($installed) === 0) {
if (!$channelinfo) {
$data = '(no packages installed from channel ' . $channel . ')';
} else {
$data = array(
'caption' => 'Installed packages, channel ' .
$channel . ':',
'border' => true,
'channel' => $channel,
'data' => array(array('(no packages installed)')),
);
}
if (count($installed)==0) {
$data = '(no packages installed from channel ' . $channel . ')';
}
 
$this->ui->outputData($data, $command);
return true;
}
 
function doListAll($command, $options, $params)
{
// This duplicate code is deprecated over
// list --channelinfo, which gives identical
// output for list and list --allchannels.
$reg = &$this->config->getRegistry();
$installed = $reg->packageInfo(null, null, null);
foreach ($installed as $channel => $packages) {
usort($packages, array($this, '_sortinfo'));
$i = $j = 0;
$data = array(
'caption' => 'Installed packages, channel ' . $channel . ':',
'border' => true,
'headline' => array('Package', 'Version', 'State'),
'channel' => $channel
);
 
'caption' => 'Installed packages, channel ' . $channel . ':',
'border' => true,
'headline' => array('Package', 'Version', 'State')
);
foreach ($packages as $package) {
$p = isset($package['package']) ? $package['package'] : $package['name'];
$pobj = $reg->getPackage($p, $channel);
$pobj = $reg->getPackage(isset($package['package']) ?
$package['package'] : $package['name'], $channel);
$data['data'][] = array($pobj->getPackage(), $pobj->getVersion(),
$pobj->getState() ? $pobj->getState() : null);
}
 
// Adds a blank line after each section
$data['data'][] = array();
 
if (count($packages) === 0) {
if (count($packages)==0) {
$data = array(
'caption' => 'Installed packages, channel ' . $channel . ':',
'border' => true,
'data' => array(array('(no packages installed)'), array()),
'channel' => $channel
'data' => array(array('(no packages installed)')),
);
}
$this->ui->outputData($data, $command);
242,25 → 190,23
}
return true;
}
 
function doFileList($command, $options, $params)
{
if (count($params) !== 1) {
if (count($params) != 1) {
return $this->raiseError('list-files expects 1 parameter');
}
 
$reg = &$this->config->getRegistry();
$fp = false;
if (!is_dir($params[0]) && (file_exists($params[0]) || $fp = @fopen($params[0], 'r'))) {
if (!is_dir($params[0]) && (file_exists($params[0]) || $fp = @fopen($params[0],
'r'))) {
if ($fp) {
fclose($fp);
}
 
if (!class_exists('PEAR_PackageFile')) {
require_once 'PEAR/PackageFile.php';
}
 
$pkg = new PEAR_PackageFile($this->config, $this->_debug);
$pkg = &new PEAR_PackageFile($this->config, $this->_debug);
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$info = &$pkg->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL);
PEAR::staticPopErrorHandling();
273,20 → 219,16
if (PEAR::isError($parsed)) {
return $this->raiseError($parsed);
}
 
$info = &$reg->getPackage($parsed['package'], $parsed['channel']);
$headings = array('Type', 'Install Path');
$installed = true;
}
 
if (PEAR::isError($info)) {
return $this->raiseError($info);
}
 
if ($info === null) {
return $this->raiseError("`$params[0]' not installed");
}
 
$list = ($info->getPackagexmlVersion() == '1.0' || $installed) ?
$info->getFilelist() : $info->getContents();
if ($installed) {
294,7 → 236,6
} else {
$caption = 'Contents of ' . basename($params[0]);
}
 
$data = array(
'caption' => $caption,
'border' => true,
344,7 → 285,6
if (!isset($list['dir']['file'][0])) {
$list['dir']['file'] = array($list['dir']['file']);
}
 
foreach ($list['dir']['file'] as $att) {
$att = $att['attribs'];
$file = $att['name'];
363,17 → 303,18
$data['data'][] = array($file, $dest);
}
}
 
$this->ui->outputData($data, $command);
return true;
}
 
// }}}
// {{{ doShellTest()
 
function doShellTest($command, $options, $params)
{
if (count($params) < 1) {
return PEAR::raiseError('ERROR, usage: pear shell-test packagename [[relation] version]');
}
 
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$reg = &$this->config->getRegistry();
$info = $reg->parsePackageName($params[0], $this->config->get('default_channel'));
380,7 → 321,6
if (PEAR::isError($info)) {
exit(1); // invalid package name
}
 
$package = $info['package'];
$channel = $info['channel'];
// "pear shell-test Foo"
391,19 → 331,18
}
}
}
 
if (count($params) === 1) {
if (sizeof($params) == 1) {
if (!$reg->packageExists($package, $channel)) {
exit(1);
}
// "pear shell-test Foo 1.0"
} elseif (count($params) === 2) {
} elseif (sizeof($params) == 2) {
$v = $reg->packageInfo($package, 'version', $channel);
if (!$v || !version_compare("$v", "{$params[1]}", "ge")) {
exit(1);
}
// "pear shell-test Foo ge 1.0"
} elseif (count($params) === 3) {
} elseif (sizeof($params) == 3) {
$v = $reg->packageInfo($package, 'version', $channel);
if (!$v || !version_compare("$v", "{$params[2]}", $params[1])) {
exit(1);
415,26 → 354,24
}
}
 
// }}}
// {{{ doInfo
 
function doInfo($command, $options, $params)
{
if (count($params) !== 1) {
if (count($params) != 1) {
return $this->raiseError('pear info expects 1 parameter');
}
 
$info = $fp = false;
$reg = &$this->config->getRegistry();
if (is_file($params[0]) && !is_dir($params[0]) &&
(file_exists($params[0]) || $fp = @fopen($params[0], 'r'))
) {
if ((file_exists($params[0]) && is_file($params[0]) && !is_dir($params[0])) || $fp = @fopen($params[0], 'r')) {
if ($fp) {
fclose($fp);
}
 
if (!class_exists('PEAR_PackageFile')) {
require_once 'PEAR/PackageFile.php';
}
 
$pkg = new PEAR_PackageFile($this->config, $this->_debug);
$pkg = &new PEAR_PackageFile($this->config, $this->_debug);
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$obj = &$pkg->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL);
PEAR::staticPopErrorHandling();
448,21 → 385,18
$this->ui->outputData($message);
}
}
 
return $this->raiseError($obj);
}
 
if ($obj->getPackagexmlVersion() != '1.0') {
if ($obj->getPackagexmlVersion() == '1.0') {
$info = $obj->toArray();
} else {
return $this->_doInfo2($command, $options, $params, $obj, false);
}
 
$info = $obj->toArray();
} else {
$parsed = $reg->parsePackageName($params[0], $this->config->get('default_channel'));
if (PEAR::isError($parsed)) {
return $this->raiseError($parsed);
}
 
$package = $parsed['package'];
$channel = $parsed['channel'];
$info = $reg->packageInfo($package, null, $channel);
471,16 → 405,13
return $this->_doInfo2($command, $options, $params, $obj, true);
}
}
 
if (PEAR::isError($info)) {
return $info;
}
 
if (empty($info)) {
$this->raiseError("No information found for `$params[0]'");
return;
}
 
unset($info['filelist']);
unset($info['dirtree']);
unset($info['changelog']);
488,12 → 419,10
$info['package.xml version'] = $info['xsdversion'];
unset($info['xsdversion']);
}
 
if (isset($info['packagerversion'])) {
$info['packaged with PEAR version'] = $info['packagerversion'];
unset($info['packagerversion']);
}
 
$keys = array_keys($info);
$longtext = array('description', 'summary');
foreach ($keys as $key) {
598,7 → 527,6
}
}
}
 
if ($key == '_lastmodified') {
$hdate = date('Y-m-d', $info[$key]);
unset($info[$key]);
613,7 → 541,6
}
}
}
 
$caption = 'About ' . $info['package'] . '-' . $info['version'];
$data = array(
'caption' => $caption,
627,6 → 554,8
$this->ui->outputData($data, 'package-info');
}
 
// }}}
 
/**
* @access private
*/
664,7 → 593,6
if ($src = $obj->getSourcePackage()) {
$extends .= ' (source package ' . $src['channel'] . '/' . $src['package'] . ')';
}
 
$info = array(
'Release Type' => $release,
'Name' => $extends,
678,27 → 606,21
if (!$leads) {
continue;
}
 
if (isset($leads['active'])) {
$leads = array($leads);
}
 
foreach ($leads as $lead) {
if (!empty($info['Maintainers'])) {
$info['Maintainers'] .= "\n";
}
 
$active = $lead['active'] == 'no' ? ', inactive' : '';
$info['Maintainers'] .= $lead['name'] . ' <';
$info['Maintainers'] .= $lead['email'] . "> ($role$active)";
$info['Maintainers'] .= $lead['email'] . "> ($role)";
}
}
 
$info['Release Date'] = $obj->getDate();
if ($time = $obj->getTime()) {
$info['Release Date'] .= ' ' . $time;
}
 
$info['Release Version'] = $obj->getVersion() . ' (' . $obj->getState() . ')';
$info['API Version'] = $obj->getVersion('api') . ' (' . $obj->getState('api') . ')';
$info['License'] = $obj->getLicense();
713,22 → 635,16
}
}
}
 
$info['Release Notes'] = $obj->getNotes();
if ($compat = $obj->getCompatible()) {
if (!isset($compat[0])) {
$compat = array($compat);
}
 
$info['Compatible with'] = '';
foreach ($compat as $package) {
$info['Compatible with'] .= $package['channel'] . '/' . $package['name'] .
$info['Compatible with'] .= $package['channel'] . '/' . $package['package'] .
"\nVersions >= " . $package['min'] . ', <= ' . $package['max'];
if (isset($package['exclude'])) {
if (is_array($package['exclude'])) {
$package['exclude'] = implode(', ', $package['exclude']);
}
 
if (!isset($info['Not Compatible with'])) {
$info['Not Compatible with'] = '';
} else {
735,17 → 651,15
$info['Not Compatible with'] .= "\n";
}
$info['Not Compatible with'] .= $package['channel'] . '/' .
$package['name'] . "\nVersions " . $package['exclude'];
$package['package'] . "\nVersions " . $package['exclude'];
}
}
}
 
$usesrole = $obj->getUsesrole();
if ($usesrole) {
if (!isset($usesrole[0])) {
$usesrole = array($usesrole);
}
 
foreach ($usesrole as $roledata) {
if (isset($info['Uses Custom Roles'])) {
$info['Uses Custom Roles'] .= "\n";
752,7 → 666,6
} else {
$info['Uses Custom Roles'] = '';
}
 
if (isset($roledata['package'])) {
$rolepackage = $reg->parsedPackageNameToString($roledata, true);
} else {
761,13 → 674,11
$info['Uses Custom Roles'] .= $roledata['role'] . ' (' . $rolepackage . ')';
}
}
 
$usestask = $obj->getUsestask();
if ($usestask) {
if (!isset($usestask[0])) {
$usestask = array($usestask);
}
 
foreach ($usestask as $taskdata) {
if (isset($info['Uses Custom Tasks'])) {
$info['Uses Custom Tasks'] .= "\n";
774,7 → 685,6
} else {
$info['Uses Custom Tasks'] = '';
}
 
if (isset($taskdata['package'])) {
$taskpackage = $reg->parsedPackageNameToString($taskdata, true);
} else {
783,7 → 693,6
$info['Uses Custom Tasks'] .= $taskdata['task'] . ' (' . $taskpackage . ')';
}
}
 
$deps = $obj->getDependencies();
$info['Required Dependencies'] = 'PHP version ' . $deps['required']['php']['min'];
if (isset($deps['required']['php']['max'])) {
791,7 → 700,6
} else {
$info['Required Dependencies'] .= "\n";
}
 
if (isset($deps['required']['php']['exclude'])) {
if (!isset($info['Not Compatible with'])) {
$info['Not Compatible with'] = '';
798,7 → 706,6
} else {
$info['Not Compatible with'] .= "\n";
}
 
if (is_array($deps['required']['php']['exclude'])) {
$deps['required']['php']['exclude'] =
implode(', ', $deps['required']['php']['exclude']);
806,7 → 713,6
$info['Not Compatible with'] .= "PHP versions\n " .
$deps['required']['php']['exclude'];
}
 
$info['Required Dependencies'] .= 'PEAR installer version';
if (isset($deps['required']['pearinstaller']['max'])) {
$info['Required Dependencies'] .= 's ' .
816,7 → 722,6
$info['Required Dependencies'] .= ' ' .
$deps['required']['pearinstaller']['min'] . ' or newer';
}
 
if (isset($deps['required']['pearinstaller']['exclude'])) {
if (!isset($info['Not Compatible with'])) {
$info['Not Compatible with'] = '';
823,7 → 728,6
} else {
$info['Not Compatible with'] .= "\n";
}
 
if (is_array($deps['required']['pearinstaller']['exclude'])) {
$deps['required']['pearinstaller']['exclude'] =
implode(', ', $deps['required']['pearinstaller']['exclude']);
831,7 → 735,6
$info['Not Compatible with'] .= "PEAR installer\n Versions " .
$deps['required']['pearinstaller']['exclude'];
}
 
foreach (array('Package', 'Extension') as $type) {
$index = strtolower($type);
if (isset($deps['required'][$index])) {
838,7 → 741,6
if (isset($deps['required'][$index]['name'])) {
$deps['required'][$index] = array($deps['required'][$index]);
}
 
foreach ($deps['required'][$index] as $package) {
if (isset($package['conflicts'])) {
$infoindex = 'Not Compatible with';
851,7 → 753,6
$infoindex = 'Required Dependencies';
$info[$infoindex] .= "\n";
}
 
if ($index == 'extension') {
$name = $package['name'];
} else {
861,13 → 762,11
$name = '__uri/' . $package['name'] . ' (static URI)';
}
}
 
$info[$infoindex] .= "$type $name";
if (isset($package['uri'])) {
$info[$infoindex] .= "\n Download URI: $package[uri]";
continue;
}
 
if (isset($package['max']) && isset($package['min'])) {
$info[$infoindex] .= " \n Versions " .
$package['min'] . '-' . $package['max'];
878,11 → 777,9
$info[$infoindex] .= " \n Version " .
$package['max'] . ' or older';
}
 
if (isset($package['recommended'])) {
$info[$infoindex] .= "\n Recommended version: $package[recommended]";
}
 
if (isset($package['exclude'])) {
if (!isset($info['Not Compatible with'])) {
$info['Not Compatible with'] = '';
889,11 → 786,9
} else {
$info['Not Compatible with'] .= "\n";
}
 
if (is_array($package['exclude'])) {
$package['exclude'] = implode(', ', $package['exclude']);
}
 
$package['package'] = $package['name']; // for parsedPackageNameToString
if (isset($package['conflicts'])) {
$info['Not Compatible with'] .= '=> except ';
905,12 → 800,10
}
}
}
 
if (isset($deps['required']['os'])) {
if (isset($deps['required']['os']['name'])) {
$dep['required']['os']['name'] = array($dep['required']['os']['name']);
}
 
foreach ($dep['required']['os'] as $os) {
if (isset($os['conflicts']) && $os['conflicts'] == 'yes') {
if (!isset($info['Not Compatible with'])) {
925,12 → 818,10
}
}
}
 
if (isset($deps['required']['arch'])) {
if (isset($deps['required']['arch']['pattern'])) {
$dep['required']['arch']['pattern'] = array($dep['required']['os']['pattern']);
}
 
foreach ($dep['required']['arch'] as $os) {
if (isset($os['conflicts']) && $os['conflicts'] == 'yes') {
if (!isset($info['Not Compatible with'])) {
945,7 → 836,6
}
}
}
 
if (isset($deps['optional'])) {
foreach (array('Package', 'Extension') as $type) {
$index = strtolower($type);
953,7 → 843,6
if (isset($deps['optional'][$index]['name'])) {
$deps['optional'][$index] = array($deps['optional'][$index]);
}
 
foreach ($deps['optional'][$index] as $package) {
if (isset($package['conflicts']) && $package['conflicts'] == 'yes') {
$infoindex = 'Not Compatible with';
970,7 → 859,6
$info['Optional Dependencies'] .= "\n";
}
}
 
if ($index == 'extension') {
$name = $package['name'];
} else {
980,18 → 868,15
$name = '__uri/' . $package['name'] . ' (static URI)';
}
}
 
$info[$infoindex] .= "$type $name";
if (isset($package['uri'])) {
$info[$infoindex] .= "\n Download URI: $package[uri]";
continue;
}
 
if ($infoindex == 'Not Compatible with') {
// conflicts is only used to say that all versions conflict
continue;
}
 
if (isset($package['max']) && isset($package['min'])) {
$info[$infoindex] .= " \n Versions " .
$package['min'] . '-' . $package['max'];
1002,11 → 887,9
$info[$infoindex] .= " \n Version " .
$package['min'] . ' or older';
}
 
if (isset($package['recommended'])) {
$info[$infoindex] .= "\n Recommended version: $package[recommended]";
}
 
if (isset($package['exclude'])) {
if (!isset($info['Not Compatible with'])) {
$info['Not Compatible with'] = '';
1013,11 → 896,9
} else {
$info['Not Compatible with'] .= "\n";
}
 
if (is_array($package['exclude'])) {
$package['exclude'] = implode(', ', $package['exclude']);
}
 
$info['Not Compatible with'] .= "Package $package\n Versions " .
$package['exclude'];
}
1025,12 → 906,10
}
}
}
 
if (isset($deps['group'])) {
if (!isset($deps['group'][0])) {
$deps['group'] = array($deps['group']);
}
 
foreach ($deps['group'] as $group) {
$info['Dependency Group ' . $group['attribs']['name']] = $group['attribs']['hint'];
$groupindex = $group['attribs']['name'] . ' Contents';
1041,12 → 920,10
if (isset($group[$index]['name'])) {
$group[$index] = array($group[$index]);
}
 
foreach ($group[$index] as $package) {
if (!empty($info[$groupindex])) {
$info[$groupindex] .= "\n";
}
 
if ($index == 'extension') {
$name = $package['name'];
} else {
1056,7 → 933,6
$name = '__uri/' . $package['name'] . ' (static URI)';
}
}
 
if (isset($package['uri'])) {
if (isset($package['conflicts']) && $package['conflicts'] == 'yes') {
$info[$groupindex] .= "Not Compatible with $type $name";
1063,16 → 939,13
} else {
$info[$groupindex] .= "$type $name";
}
 
$info[$groupindex] .= "\n Download URI: $package[uri]";
continue;
}
 
if (isset($package['conflicts']) && $package['conflicts'] == 'yes') {
$info[$groupindex] .= "Not Compatible with $type $name";
continue;
}
 
$info[$groupindex] .= "$type $name";
if (isset($package['max']) && isset($package['min'])) {
$info[$groupindex] .= " \n Versions " .
1084,11 → 957,9
$info[$groupindex] .= " \n Version " .
$package['min'] . ' or older';
}
 
if (isset($package['recommended'])) {
$info[$groupindex] .= "\n Recommended version: $package[recommended]";
}
 
if (isset($package['exclude'])) {
if (!isset($info['Not Compatible with'])) {
$info['Not Compatible with'] = '';
1095,7 → 966,6
} else {
$info[$groupindex] .= "Not Compatible with\n";
}
 
if (is_array($package['exclude'])) {
$package['exclude'] = implode(', ', $package['exclude']);
}
1107,7 → 977,6
}
}
}
 
if ($obj->getPackageType() == 'bundle') {
$info['Bundled Packages'] = '';
foreach ($obj->getBundledPackages() as $package) {
1114,7 → 983,6
if (!empty($info['Bundled Packages'])) {
$info['Bundled Packages'] .= "\n";
}
 
if (isset($package['uri'])) {
$info['Bundled Packages'] .= '__uri/' . $package['name'];
$info['Bundled Packages'] .= "\n (URI: $package[uri]";
1123,22 → 991,21
}
}
}
 
$info['package.xml version'] = '2.0';
if ($installed) {
if ($obj->getLastModified()) {
$info['Last Modified'] = date('Y-m-d H:i', $obj->getLastModified());
}
 
$v = $obj->getLastInstalledVersion();
$info['Previous Installed Version'] = $v ? $v : '- None -';
}
 
foreach ($info as $key => $value) {
$data['data'][] = array($key, $value);
}
$data['raw'] = $obj->getArray(); // no validation needed
 
$data['raw'] = $obj->getArray(); // no validation needed
$this->ui->outputData($data, 'package-info');
}
}
 
?>
/trunk/bibliotheque/pear/PEAR/Frontend/CLI.php
4,12 → 4,19
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: CLI.php,v 1.66 2006/11/19 23:56:32 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
24,14 → 31,16
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @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.
* @var string
42,23 → 51,28
 
var $params = array();
var $term = array(
'bold' => '',
'bold' => '',
'normal' => '',
);
);
 
function __construct()
// }}}
 
// {{{ constructor
 
function PEAR_Frontend_CLI()
{
parent::__construct();
parent::PEAR();
$term = getenv('TERM'); //(cox) $_ENV is empty for me in 4.1.1
if (function_exists('posix_isatty') && !posix_isatty(1)) {
// output is being redirected to a file or through a pipe
} elseif ($term) {
// XXX can use ncurses extension here, if available
if (preg_match('/^(xterm|vt220|linux)/', $term)) {
$this->term['bold'] = sprintf("%c%c%c%c", 27, 91, 49, 109);
$this->term['normal'] = sprintf("%c%c%c", 27, 91, 109);
$this->term['bold'] = sprintf("%c%c%c%c", 27, 91, 49, 109);
$this->term['normal']=sprintf("%c%c%c", 27, 91, 109);
} elseif (preg_match('/^vt100/', $term)) {
$this->term['bold'] = sprintf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0);
$this->term['normal'] = sprintf("%c%c%c%c%c", 27, 91, 109, 0, 0);
$this->term['bold'] = sprintf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0);
$this->term['normal']=sprintf("%c%c%c%c%c", 27, 91, 109, 0, 0);
}
} elseif (OS_WINDOWS) {
// XXX add ANSI codes here
65,14 → 79,47
}
}
 
// }}}
 
// {{{ 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
*/
function displayError($e)
function displayError($eobj)
{
return $this->_displayLine($e->getMessage());
return $this->_displayLine($eobj->getMessage());
}
 
// }}}
// {{{ displayFatalError(eobj)
 
/**
* @param object PEAR_Error object
*/
84,34 → 131,54
if ($config->get('verbose') > 5) {
if (function_exists('debug_print_backtrace')) {
debug_print_backtrace();
exit(1);
}
 
$raised = false;
foreach (debug_backtrace() as $i => $frame) {
if (!$raised) {
if (isset($frame['class'])
&& strtolower($frame['class']) == 'pear'
&& strtolower($frame['function']) == 'raiseerror'
) {
$raised = true;
} else {
continue;
} elseif (function_exists('debug_backtrace')) {
$trace = debug_backtrace();
$raised = false;
foreach ($trace as $i => $frame) {
if (!$raised) {
if (isset($frame['class']) && strtolower($frame['class']) ==
'pear' && strtolower($frame['function']) == 'raiseerror') {
$raised = true;
} else {
continue;
}
}
if (!isset($frame['class'])) {
$frame['class'] = '';
}
if (!isset($frame['type'])) {
$frame['type'] = '';
}
if (!isset($frame['function'])) {
$frame['function'] = '';
}
if (!isset($frame['line'])) {
$frame['line'] = '';
}
$this->_displayLine("#$i: $frame[class]$frame[type]$frame[function] $frame[line]");
}
 
$frame['class'] = !isset($frame['class']) ? '' : $frame['class'];
$frame['type'] = !isset($frame['type']) ? '' : $frame['type'];
$frame['function'] = !isset($frame['function']) ? '' : $frame['function'];
$frame['line'] = !isset($frame['line']) ? '' : $frame['line'];
$this->_displayLine("#$i: $frame[class]$frame[type]$frame[function] $frame[line]");
}
}
}
 
exit(1);
}
 
// }}}
// {{{ displayHeading(title)
 
function displayHeading($title)
{
trigger_error("PEAR_Frontend_CLI::displayHeading deprecated", E_USER_ERROR);
}
 
function _displayHeading($title)
{
print $this->lp.$this->bold($title)."\n";
print $this->lp.str_repeat("=", strlen($title))."\n";
}
 
// }}}
 
/**
* Instruct the runInstallScript method to skip a paramgroup that matches the
* id value passed in.
143,105 → 210,94
$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;
} else {
$completedPhases = array();
if (!isset($xml['paramgroup'][0])) {
$xml['paramgroup'] = array($xml['paramgroup']);
}
 
if (isset($group['name'])) {
$paramname = explode('::', $group['name']);
if ($lastgroup['id'] != $paramname[0]) {
foreach ($xml['paramgroup'] as $group) {
if (isset($this->_skipSections[$group['id']])) {
// the post-install script chose to skip this section dynamically
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;
if (isset($group['name'])) {
$paramname = explode('::', $group['name']);
if ($lastgroup['id'] != $paramname[0]) {
continue;
}
$group['name'] = $paramname[1];
if (isset($answers)) {
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;
}
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 :
}
} else {
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'];
$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']);
}
 
$answers = $this->confirmDialog($prompts);
}
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 {
$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;
}
}
}
254,13 → 310,17
*/
function confirmDialog($params)
{
$answers = $prompts = $types = array();
$answers = array();
$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'] : '';
$types[$param['name']] = $param['type'];
if (isset($param['default'])) {
$answers[$param['name']] = $param['default'];
} else {
$answers[$param['name']] = '';
}
}
 
$tried = false;
do {
if ($tried) {
272,27 → 332,30
$i++;
}
}
 
$answers = $this->userDialog('', $prompts, $types, $answers);
$tried = true;
$tried = true;
} while (is_array($answers) && count(array_filter($answers)) != count($prompts));
 
return $answers;
}
// {{{ userDialog(prompt, [type], [default])
 
function userDialog($command, $prompts, $types = array(), $defaults = array(), $screensize = 20)
function userDialog($command, $prompts, $types = array(), $defaults = array(),
$screensize = 20)
{
if (!is_array($prompts)) {
return array();
}
 
$testprompts = array_keys($prompts);
$result = $defaults;
 
$result = $defaults;
if (!defined('STDIN')) {
$fp = fopen('php://stdin', 'r');
} else {
$fp = STDIN;
}
reset($prompts);
if (count($prompts) === 1) {
if (count($prompts) == 1 && $types[key($prompts)] == 'yesno') {
foreach ($prompts as $key => $prompt) {
$type = $types[$key];
$type = $types[$key];
$default = @$defaults[$key];
print "$prompt ";
if ($default) {
299,62 → 362,70
print "[$default] ";
}
print ": ";
 
$line = fgets(STDIN, 2048);
$result[$key] = ($default && trim($line) == '') ? $default : trim($line);
if (version_compare(phpversion(), '5.0.0', '<')) {
$line = fgets($fp, 2048);
} else {
if (!defined('STDIN')) {
define('STDIN', fopen('php://stdin', 'r'));
}
$line = fgets(STDIN, 2048);
}
if ($default && trim($line) == "") {
$result[$key] = $default;
} else {
$result[$key] = trim($line);
}
}
 
return $result;
}
 
$first_run = true;
while (true) {
$descLength = max(array_map('strlen', $prompts));
$descFormat = "%-{$descLength}s";
$last = count($prompts);
$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);
printf("%2d. $descFormat : %s\n", ++$i, $prompts[$n], isset($result[$n]) ?
$result[$n] : null);
}
 
print "\n1-$last, 'all', 'abort', or Enter to continue: ";
 
$tmp = trim(fgets(STDIN, 1024));
$tmp = trim(fgets($fp, 1024));
if (empty($tmp)) {
break;
}
 
if ($tmp == 'abort') {
return false;
}
 
if (isset($testprompts[(int)$tmp - 1])) {
$var = $testprompts[(int)$tmp - 1];
$desc = $prompts[$var];
$var = $testprompts[(int)$tmp - 1];
$desc = $prompts[$var];
$current = @$result[$var];
print "$desc [$current] : ";
$tmp = trim(fgets(STDIN, 1024));
if ($tmp !== '') {
$result[$var] = $tmp;
$tmp = trim(fgets($fp, 1024));
if (trim($tmp) !== '') {
$result[$var] = trim($tmp);
}
} elseif ($tmp == 'all') {
foreach ($prompts as $var => $desc) {
$current = $result[$var];
print "$desc [$current] : ";
$tmp = trim(fgets(STDIN, 1024));
$tmp = trim(fgets($fp, 1024));
if (trim($tmp) !== '') {
$result[$var] = trim($tmp);
}
}
}
 
$first_run = false;
}
 
if (!defined('STDIN')) {
fclose($fp);
}
return $result;
}
 
// }}}
// {{{ userConfirm(prompt, [default])
 
function userConfirm($prompt, $default = 'yes')
{
trigger_error("PEAR_Frontend_CLI::userConfirm not yet converted", E_USER_ERROR);
380,219 → 451,48
return false;
}
 
function outputData($data, $command = '_default')
{
switch ($command) {
case 'channel-info':
foreach ($data as $type => $section) {
if ($type == 'main') {
$section['data'] = array_values($section['data']);
}
// }}}
// {{{ startTable([params])
 
$this->outputData($section);
}
break;
case 'install':
case 'upgrade':
case 'upgrade-all':
if (is_array($data) && isset($data['release_warnings'])) {
$this->_displayLine('');
$this->_startTable(array(
'border' => false,
'caption' => 'Release Warnings'
));
$this->_tableRow(array($data['release_warnings']), null, array(1 => array('wrap' => 55)));
$this->_endTable();
$this->_displayLine('');
}
 
$this->_displayLine(is_array($data) ? $data['data'] : $data);
break;
case 'search':
$this->_startTable($data);
if (isset($data['headline']) && is_array($data['headline'])) {
$this->_tableRow($data['headline'], array('bold' => true), array(1 => array('wrap' => 55)));
}
 
$packages = array();
foreach($data['data'] as $category) {
foreach($category as $name => $pkg) {
$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();
break;
case 'list-all':
if (!isset($data['data'])) {
$this->_displayLine('No packages in channel');
break;
}
 
$this->_startTable($data);
if (isset($data['headline']) && is_array($data['headline'])) {
$this->_tableRow($data['headline'], array('bold' => true), array(1 => array('wrap' => 55)));
}
 
$packages = array();
foreach($data['data'] as $category) {
foreach($category as $name => $pkg) {
$packages[$pkg[0]] = $pkg;
}
}
 
$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->_endTable();
break;
case 'config-show':
$data['border'] = false;
$opts = array(
0 => array('wrap' => 30),
1 => array('wrap' => 20),
2 => array('wrap' => 35)
);
 
$this->_startTable($data);
if (isset($data['headline']) && is_array($data['headline'])) {
$this->_tableRow($data['headline'], array('bold' => true), $opts);
}
 
foreach ($data['data'] as $group) {
foreach ($group as $value) {
if ($value[2] == '') {
$value[2] = "<not set>";
}
 
$this->_tableRow($value, null, $opts);
}
}
 
$this->_endTable();
break;
case 'remote-info':
$d = $data;
$data = array(
'caption' => 'Package details:',
'border' => false,
'data' => array(
array("Latest", $data['stable']),
array("Installed", $data['installed']),
array("Package", $data['name']),
array("License", $data['license']),
array("Category", $data['category']),
array("Summary", $data['summary']),
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: {
if (is_array($data)) {
$this->_startTable($data);
$count = count($data['data'][0]);
if ($count == 2) {
$opts = array(0 => array('wrap' => 25),
1 => array('wrap' => 48)
);
} elseif ($count == 3) {
$opts = array(0 => array('wrap' => 30),
1 => array('wrap' => 20),
2 => array('wrap' => 35)
);
} else {
$opts = null;
}
if (isset($data['headline']) && is_array($data['headline'])) {
$this->_tableRow($data['headline'],
array('bold' => true),
$opts);
}
 
if (is_array($data['data'])) {
foreach($data['data'] as $row) {
$this->_tableRow($row, null, $opts);
}
} else {
$this->_tableRow(array($data['data']), null, $opts);
}
$this->_endTable();
} else {
$this->_displayLine($data);
}
}
}
}
 
function log($text, $append_crlf = true)
function startTable($params = array())
{
if ($append_crlf) {
return $this->_displayLine($text);
}
 
return $this->_display($text);
trigger_error("PEAR_Frontend_CLI::startTable deprecated", E_USER_ERROR);
}
 
function bold($text)
function _startTable($params = array())
{
if (empty($this->term['bold'])) {
return strtoupper($text);
}
 
return $this->term['bold'] . $text . $this->term['normal'];
$params['table_data'] = array();
$params['widest'] = array(); // indexed by column
$params['highest'] = array(); // indexed by row
$params['ncols'] = 0;
$this->params = $params;
}
 
function _displayHeading($title)
{
print $this->lp.$this->bold($title)."\n";
print $this->lp.str_repeat("=", strlen($title))."\n";
}
// }}}
// {{{ tableRow(columns, [rowparams], [colparams])
 
function _startTable($params = array())
function tableRow($columns, $rowparams = array(), $colparams = array())
{
$params['table_data'] = array();
$params['widest'] = array(); // indexed by column
$params['highest'] = array(); // indexed by row
$params['ncols'] = 0;
$this->params = $params;
trigger_error("PEAR_Frontend_CLI::tableRow deprecated", E_USER_ERROR);
}
 
function _tableRow($columns, $rowparams = array(), $colparams = array())
{
$highest = 1;
for ($i = 0; $i < count($columns); $i++) {
for ($i = 0; $i < sizeof($columns); $i++) {
$col = &$columns[$i];
if (isset($colparams[$i]) && !empty($colparams[$i]['wrap'])) {
$col = wordwrap($col, $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) {
$len = strlen($line);
if ($len > $w) {
$w = $len;
if (strlen($line) > $w) {
$w = strlen($line);
}
}
$lines = count($multiline);
$lines = sizeof($multiline);
} else {
$w = strlen($col);
}
604,7 → 504,6
} 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;
612,20 → 511,26
$highest = $lines;
}
}
 
if (count($columns) > $this->params['ncols']) {
$this->params['ncols'] = count($columns);
if (sizeof($columns) > $this->params['ncols']) {
$this->params['ncols'] = sizeof($columns);
}
 
$new_row = array(
'data' => $columns,
'height' => $highest,
'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);
632,11 → 537,9
if (!empty($caption)) {
$this->_displayHeading($caption);
}
 
if (count($table_data) === 0) {
if (count($table_data) == 0) {
return;
}
 
if (!isset($width)) {
$width = $widest;
} else {
646,19 → 549,18
}
}
}
 
$border = false;
if (empty($border)) {
$cellstart = '';
$cellend = ' ';
$rowend = '';
$padrowend = false;
$cellstart = '';
$cellend = ' ';
$rowend = '';
$padrowend = false;
$borderline = '';
} else {
$cellstart = '| ';
$cellend = ' ';
$rowend = '|';
$padrowend = true;
$cellstart = '| ';
$cellend = ' ';
$rowend = '|';
$padrowend = true;
$borderline = '+';
foreach ($width as $w) {
$borderline .= str_repeat('-', $w + strlen($cellstart) + strlen($cellend) - 1);
665,44 → 567,38
$borderline .= '+';
}
}
 
if ($borderline) {
$this->_displayLine($borderline);
}
 
for ($i = 0; $i < count($table_data); $i++) {
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 < count($data); $c++) {
for ($c = 0; $c < sizeof($data); $c++) {
$rowlines[$c] = preg_split('/(\r?\n|\r)/', $data[$c]);
if (count($rowlines[$c]) < $height) {
if (sizeof($rowlines[$c]) < $height) {
$rowlines[$c] = array_pad($rowlines[$c], $height, '');
}
}
} else {
for ($c = 0; $c < count($data); $c++) {
for ($c = 0; $c < sizeof($data); $c++) {
$rowlines[$c] = array($data[$c]);
}
}
 
for ($r = 0; $r < $height; $r++) {
$rowtext = '';
for ($c = 0; $c < count($data); $c++) {
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];
710,11 → 606,9
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
723,28 → 617,174
 
$rowtext .= $cellstart . $cell . $cellend;
}
 
if (!$border) {
$rowtext = rtrim($rowtext);
}
 
$rowtext .= $rowend;
$this->_displayLine($rowtext);
}
}
 
if ($borderline) {
$this->_displayLine($borderline);
}
}
 
function _displayLine($text)
// }}}
// {{{ outputData()
 
function outputData($data, $command = '_default')
{
print "$this->lp$text\n";
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 'upgrade':
case 'upgrade-all':
if (isset($data['release_warnings'])) {
$this->_displayLine('');
$this->_startTable(array(
'border' => false,
'caption' => 'Release Warnings'
));
$this->_tableRow(array($data['release_warnings']), null, array(1 => array('wrap' => 55)));
$this->_endTable();
$this->_displayLine('');
}
$this->_displayLine($data['data']);
break;
case 'search':
$this->_startTable($data);
if (isset($data['headline']) && is_array($data['headline'])) {
$this->_tableRow($data['headline'], array('bold' => true), array(1 => array('wrap' => 55)));
}
 
foreach($data['data'] as $category) {
foreach($category as $pkg) {
$this->_tableRow($pkg, null, array(1 => array('wrap' => 55)));
}
};
$this->_endTable();
break;
case 'list-all':
$this->_startTable($data);
if (isset($data['headline']) && is_array($data['headline'])) {
$this->_tableRow($data['headline'], array('bold' => true), array(1 => array('wrap' => 55)));
}
 
foreach($data['data'] as $category) {
foreach($category as $pkg) {
unset($pkg[4]);
unset($pkg[5]);
$this->_tableRow($pkg, null, array(1 => array('wrap' => 55)));
}
};
$this->_endTable();
break;
case 'config-show':
$data['border'] = false;
$opts = array(0 => array('wrap' => 30),
1 => array('wrap' => 20),
2 => array('wrap' => 35));
$this->_startTable($data);
if (isset($data['headline']) && is_array($data['headline'])) {
$this->_tableRow($data['headline'],
array('bold' => true),
$opts);
}
foreach($data['data'] as $group) {
foreach($group as $value) {
if ($value[2] == '') {
$value[2] = "<not set>";
}
$this->_tableRow($value, null, $opts);
}
}
$this->_endTable();
break;
case 'remote-info':
$d = $data;
$data = array(
'caption' => 'Package details:',
'border' => false,
'data' => array(
array("Latest", $data['stable']),
array("Installed", $data['installed']),
array("Package", $data['name']),
array("License", $data['license']),
array("Category", $data['category']),
array("Summary", $data['summary']),
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: {
if (is_array($data)) {
$this->_startTable($data);
$count = count($data['data'][0]);
if ($count == 2) {
$opts = array(0 => array('wrap' => 25),
1 => array('wrap' => 48)
);
} elseif ($count == 3) {
$opts = array(0 => array('wrap' => 30),
1 => array('wrap' => 20),
2 => array('wrap' => 35)
);
} else {
$opts = null;
}
if (isset($data['headline']) && is_array($data['headline'])) {
$this->_tableRow($data['headline'],
array('bold' => true),
$opts);
}
foreach($data['data'] as $row) {
$this->_tableRow($row, null, $opts);
}
$this->_endTable();
} else {
$this->_displayLine($data);
}
}
}
}
 
function _display($text)
// }}}
// {{{ log(text)
 
 
function log($text, $append_crlf = true)
{
print $text;
if ($append_crlf) {
return $this->_displayLine($text);
}
return $this->_display($text);
}
 
 
// }}}
// {{{ bold($text)
 
function bold($text)
{
if (empty($this->term['bold'])) {
return strtoupper($text);
}
return $this->term['bold'] . $text . $this->term['normal'];
}
 
// }}}
}
 
?>
/trunk/bibliotheque/pear/PEAR/Validate.php
4,11 → 4,18
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Validate.php,v 1.50 2006/09/25 05:12:21 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
29,9 → 36,9
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
61,7 → 68,7
*/
function _validPackageName($name)
{
return (bool) preg_match('/^' . $this->packageregex . '\\z/', $name);
return (bool) preg_match('/^' . $this->packageregex . '$/', $name);
}
 
/**
73,7 → 80,7
{
if ($validatepackagename) {
if (strtolower($name) == strtolower($validatepackagename)) {
return (bool) preg_match('/^[a-zA-Z0-9_]+(?:\.[a-zA-Z0-9_]+)*\\z/', $name);
return (bool) preg_match('/^[a-zA-Z0-9_]+(?:\.[a-zA-Z0-9_]+)*$/', $name);
}
}
return $this->_validPackageName($name);
84,10 → 91,11
* to the PEAR naming convention, so the method is final and static.
* @param string
* @final
* @static
*/
public static function validGroupName($name)
function validGroupName($name)
{
return (bool) preg_match('/^' . _PEAR_COMMON_PACKAGE_NAME_PREG . '\\z/', $name);
return (bool) preg_match('/^' . _PEAR_COMMON_PACKAGE_NAME_PREG . '$/', $name);
}
 
/**
94,9 → 102,10
* Determine whether $state represents a valid stability level
* @param string
* @return bool
* @static
* @final
*/
public static function validState($state)
function validState($state)
{
return in_array($state, array('snapshot', 'devel', 'alpha', 'beta', 'stable'));
}
104,9 → 113,10
/**
* Get a list of valid stability levels
* @return array
* @static
* @final
*/
public static function getValidStates()
function getValidStates()
{
return array('snapshot', 'devel', 'alpha', 'beta', 'stable');
}
116,9 → 126,10
* by version_compare
* @param string
* @return bool
* @static
* @final
*/
public static function validVersion($ver)
function validVersion($ver)
{
return (bool) preg_match(PEAR_COMMON_PACKAGE_VERSION_PREG, $ver);
}
202,8 → 213,7
$this->_packagexml->getExtends()) {
$version = $this->_packagexml->getVersion() . '';
$name = $this->_packagexml->getPackage();
$a = explode('.', $version);
$test = array_shift($a);
$test = array_shift($a = explode('.', $version));
if ($test == '0') {
return true;
}
448,6 → 458,7
return false;
}
 
 
if ($this->_state == PEAR_VALIDATE_PACKAGING &&
$this->_packagexml->getDate() != date('Y-m-d')) {
$this->_addWarning('date', 'Release Date "' .
466,8 → 477,8
// default of no time value set
return true;
}
 
// packager automatically sets time, so only validate if pear validate is called
// 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())) {
475,15 → 486,12
$this->_packagexml->getTime() . '"');
return false;
}
 
$result = preg_match('|\d{2}\:\d{2}\:\d{2}|', $this->_packagexml->getTime(), $matches);
if ($result === false || empty($matches)) {
if (strtotime($this->_packagexml->getTime()) == -1) {
$this->_addFailure('time', 'invalid release time "' .
$this->_packagexml->getTime() . '"');
return false;
}
}
 
return true;
}
 
622,4 → 630,5
{
return true;
}
}
}
?>
/trunk/bibliotheque/pear/PEAR/Info.php
New file
0,0 → 1,420
<?php
/* vim: set expandtab tabstop=4 softtabstop=4 shiftwidth=4: */
// +----------------------------------------------------------------------+
// | PHP version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.0 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.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. |
// +----------------------------------------------------------------------+
// | Authors: Davey Shafik <davey@pixelated-dreams.com> |
// +----------------------------------------------------------------------+
//
// $Id: Info.php,v 1.19 2005/01/03 17:33:43 davey Exp $
 
require_once 'PEAR/Remote.php';
require_once 'PEAR/Registry.php';
 
/**
* PEAR_Info generate phpinfo() style PEAR information
*/
 
class PEAR_Info
{
 
/**
* PEAR_Info Constructor
* @param pear_dir string[optional]
* @return bool
* @access public
*/
 
function PEAR_Info($pear_dir = FALSE, $pear_user_config = FALSE)
{
if($pear_user_config === FALSE) {
$this->config = new PEAR_Config();
} else {
$this->config = new PEAR_Config($pear_user_config);
}
if ($pear_dir != FALSE) {
$this->config->set('php_dir',$pear_dir);
}
if (defined('PEAR_INFO_PROXY')) {
$this->config->set('http_proxy',PEAR_INFO_PROXY);
}
$this->r = new PEAR_Remote($this->config);
$this->reg = new PEAR_Registry($this->config->get('php_dir'));
// get PEARs packageInfo to show version number at the top of the HTML
$pear = $this->reg->packageInfo("PEAR");
$this->list_options = false;
if ($this->config->get('preferred_state') == 'stable') {
$this->list_options = true;
}
ob_start();
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>PEAR :: PEAR_Info()</title>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<style type="text/css">
body {background-color: #ffffff; color: #000000; white-space: normal;}
body, td, th, h1, h2 {font-family: sans-serif;}
a:link {color: #006600; text-decoration: none;}
a:visited { color: #003300; text-decoration: none;}
a:hover {text-decoration: underline;}
table {border-collapse: collapse; width: 600px; max-width: 600px; margin-left: auto; margin-right: auto; border: 0px; padding: 0px;}
td, th { border: 1px solid #000000; font-size: 75%; vertical-align: baseline;}
h1 {font-size: 150%; text-align: center;}
h2 {font-size: 125%; text-align: center;}
.p {text-align: left;}
.e {background-color: #006600; font-weight: bold; color: #FFFFFF; width: 100px;}
.e a:link { color: #FFFFFF; }
.e a:visited { color: #FFFFFF; }
.h {background-color: #339900; font-weight: bold;}
.v {background-color: #D9D9D9;}
img {float: right; border: 0px;}
</style>
</head>
<body>
<table>
<tr class="h">
<td>
<a href="http://pear.php.net/"><img src="<?php echo $_SERVER['PHP_SELF'];?>?pear_image=true" alt="PEAR Logo" /></a><h1 class="p">PEAR <?php echo $pear['version']; ?></h1>
</td>
</tr>
</table>
<?php
if (!isset($_GET['credits'])) {
echo '<h1><a href="' .$_SERVER['PHP_SELF']. '?credits=true">PEAR Credits</a></h1>';
// Get packageInfo and Show the HTML for the Packages
$this->getConfig();
echo '<br />';
$this->getPackages();
 
} else {
$this->getCredits();
}
?>
</body>
</html>
<?php
$this->info = ob_get_contents();
ob_end_clean();
/* With later versions of this where we properly implement the CLI such and stuff
this will return the actual status of whether or not creating the PEAR_Info object worked */
return true;
}
 
/**
* Set PEAR http_proxy for remote calls
* @param proxy string
* @return bool
* @access public
*/
 
function setProxy($proxy)
{
define('PEAR_INFO_PROXY',$proxy);
return true;
}
 
/**
* Retrieve and format PEAR Packages info
* @return void
* @access private
*/
 
function getPackages()
{
$latest = @$this->r->call('package.listLatestReleases');
$available = $this->reg->listPackages();
if (PEAR::isError($available)) {
echo '<h1 style="font-size: 12px;">An Error occured fetching the package list. Please try again.</h1>';
return FALSE;
}
if (!is_array($available)) {
echo '<h1 style="font-size: 12px;">The package list could not be fetched from the remote server. Please try again.</h1>';
return FALSE;
}
natcasesort($available);
if ((PEAR::isError($latest)) || (!is_array($latest))) {
$latest = FALSE;
}
$packages = '';
foreach ($available as $name) {
$installed = $this->reg->packageInfo($name);
if (strlen($installed['package']) > 1) {
if (!isset($old_index)) {
$old_index = '';
}
$current_index = $name{0};
if (strtolower($current_index) != strtolower($old_index)) {
$packages .= '<a name="' .$current_index. '"></a>';
$old_index = $current_index;
$this->index[] = $current_index;
}
$packages .= '
<h2><a name="pkg_' .trim($installed['package']). '">' .trim($installed['package']). '</a></h2>
<table>
<tr class="v">
<td class="e">
Summary
</td>
<td>
' .nl2br(htmlentities(trim($installed['summary']))). '
</td>
</tr>
<tr class="v">
<td class="e">
Version
</td>
<td>
' .trim($installed['version']). '
</td>
</tr>
<tr class="v">
<td class="e">
Description
</td>
<td>
' .nl2br(htmlentities(trim($installed['description']))). '
</td>
</tr>
<tr class="v">
<td class="e">
State
</td>
<td>
' .trim($installed['release_state']). '
</td>
</tr>
<tr class="v">
<td class="e">
Information
</td>
</tr>';
if ($latest != FALSE) {
if (isset($latest[$installed['package']])) {
if (version_compare($latest[$installed['package']]['version'],$installed['version'],'>')) {
$packages .= '<tr class="v">
<td class="e">
Latest Version
</td>
<td>
<a href="http://pear.php.net/get/' .trim($installed['package']). '">' .$latest[$installed['package']]['version'] . '</a>
('. $latest[$installed['package']]['state']. ')
</td>
</tr>';
}
}
}
$packages .= ' <tr>
<td colspan="2" class="v"><a href="#top">Top</a></td>
</tr>
</table>';
}
}
?>
<h2><a name="top">PEAR Packages</a></h2>
<table style="padding: 3px;">
<tr>
<td class="e">
Index
</td>
</tr>
<tr>
<td class ="v" style="text-align: center">
<?php
foreach ($this->index as $i) {
?>
| <a href="#<?php echo $i; ?>"><?php echo strtoupper($i); ?></a>
<?php
}
?>|
</td>
</tr>
</table>
<br />
<?php
echo $packages;
}
 
/**
* Retrieves and formats the PEAR Config data
* @return void
* @access private
*/
 
function getConfig()
{
$keys = $this->config->getKeys();
sort($keys);
?>
<h2>PEAR Config</h2>
<table>
<?php
foreach ($keys as $key) {
if (($key != 'password') && ($key != 'username') && ($key != 'sig_keyid') && ($key != 'http_proxy')) {
?>
<tr class="v">
<td class="e"><?php echo $key; ?></td>
<td><?php echo $this->config->get($key); ?></td>
</tr>
<?php
}
}
?>
</table>
<?php
}
 
/**
* Retrieves and formats the PEAR Credits
* @return void
* @access private
*/
 
function getCredits()
{
?>
<h1>PEAR Credits</h1>
<table>
<tr class="h">
<td>
PEAR Website Team
</td>
</tr>
<tr class="v">
<td>
<a href="http://pear.php.net/account-info.php?handle=ssb">Stig Bakken</a>,
<a href="http://pear.php.net/account-info.php?handle=cox">Thomas V.V.Cox</a>,
<a href="http://pear.php.net/account-info.php?handle=mj">Martin Jansen</a>,
<a href="http://pear.php.net/account-info.php?handle=cmv">Colin Viebrock</a>,
<a href="http://pear.php.net/account-info.php?handle=richard">Richard Heyes</a>
</td>
</tr>
</table>
<br />
<table>
<tr class="h">
<td>
PEAR documentation team
</td>
</tr>
<tr class="v">
<td>
<a href="http://pear.php.net/account-info.php?handle=cox">Thomas V.V.Cox</a>,
<a href="http://pear.php.net/account-info.php?handle=mj">Martin Jansen</a>,
<a href="http://pear.php.net/account-info.php?handle=alexmerz">Alexander Merz</a>
</td>
</tr>
</table>
<?php
$available = $this->reg->listPackages();
 
if (PEAR::isError($available)) {
echo '<h1 style="font-size: 12px;">An Error occured fetching the credits from the remote server. Please try again.</h1>';
return FALSE;
}
if (!is_array($available)) {
echo '<h1 style="font-size: 12px;">The credits could not be fetched from the remote server. Please try again.</h1>';
return FALSE;
}
echo '<br /><table border="0" cellpadding="3" width="600">';
echo '<tr class="h"><td>Package</td><td>Maintainers</td></tr>';
foreach ($available as $name) {
$installed = $this->reg->packageInfo($name);
if (strlen($installed['package']) > 1) {
?>
<tr>
<td class="e">
<a href="http://pear.php.net/<?php echo trim(strtolower($installed['package'])); ?>"><?php echo trim($installed['package']); ?></a>
 
</td>
<td class="v">
<?php
$maintainers = array();
foreach ($installed['maintainers'] as $i) {
$maintainers[] = '<a href="http://pear.php.net/account-info.php?handle=' .$i['handle']. '">' .htmlentities($i['name']). '</a>' .' (' .$i['role']. ')';
}
echo implode(', ',$maintainers);
?>
</td>
</tr>
<?php
}
}
echo '</table>';
}
 
/**
* outputs the PEAR logo
* @return void
* @access public
*/
 
function pearImage()
{
$pear_image = 'R0lGODlhaAAyAMT/AMDAwP3+/TWaAvD47Pj89vz++zebBDmcBj6fDEekFluvKmu3PvX68ujz4XvBS8LgrNXqxeHw1ZnPaa/dgvv9+cLqj8LmltD2msnuls';
$pear_image .= '3xmszwmf7+/f///wAAAAAAAAAAACH5BAEAAAAALAAAAABoADIAQAX/ICCOZGmeaKqubOtWWjwJphLLgH1XUu//C1Jisfj9YLEKQnSY3GaixWQqQTkYHM4';
$pear_image .= 'AMulNLJFC9pEwIW/odKU8cqTfsWoTTtcomU4ZjbR4ZP+AgYKCG0EiZ1AuiossEhwEXRMEg5SVWQ6MmZqKWD0QlqCUEHubpaYlExwRPRZioZZVp7KzKQoS';
$pear_image .= 'DxANDLsNXA5simd2FcQYb4YAc2jEU80TmAAIztPCMcjKdg4OEsZJmwIWWQPQI4ikIwtoVQnddgrv8PFlCWgYCwkI+fp5dkvJ/IlUKMCy6tYrDhNIIKLFE';
$pear_image .= 'AWCTxse+ABD4SClWA0zovAjcUJFi6EwahxZwoGqHhFA/4IqoICkyxQSKkbo0gDkuBXV4FRAJkRCnTgi2P28IcEfk5xpWppykFJVuScmEvDTEETAVJ6bEp';
$pear_image .= 'ypcADPkz3pvKVAICHChkC7siQ08zVqu4Q6hgIFEFZuEn/KMgRUkaBmAQs+cEHgIiHVH5EAFpIgW4+NT6LnaqhDwe/Ov7YOmWZp4MkiAWBIl0kAVsJWuzc';
$pear_image .= 'YpdiNgddc0E8cKBAu/FElBwagMb88ZZKDRAkWJtkWhHh3wwUbKHQJN3wQAaXGR2LpArv5oFHRR34C7Mf6oLXZNfqBgNI7oOLhj1f8PaGpygHQ0xtP8MDV';
$pear_image .= 'KwYTSKcgxr9/hS6/pCCAAg5M4B9/sWh1YP9/XSgQWRML/idBfKUc4IBET9lFjggKhDYZAELZJYEBI2BDB3ouNBEABwE8gAwiCcSYgAKqPdEVAG7scM8BP';
$pear_image .= 'PZ4AIlM+OgjAgpMhRE24OVoBwsIFEGFA7ZkQQBWienWxmRa7XDjKZXhBdAeSmKQwgLuUVLICa6VEKIGcK2mQWoVZHCBXJblJUFkY06yAXlGsPIHBEYdYi';
$pear_image .= 'WHb+WQBgaIJqqoHFNpgMGB7dT5ZQuG/WbBAIAUEEFNfwxAWpokTIXJAWdgoJ9kRFG2g5eDRpXSBpEIF0oEQFaZhDbaSFANRgqcJoEDRARLREtxOQpsPO9';
$pear_image .= '06ZUeJgjQB6dZUPBAdwcF8KLXXRVQaKFcsRRLJ6vMiiCNKxRE8ECZKgUA3Va4arOAAqdGRWO7uMZH5AL05gvsjQbg6y4NCjQ1kw8TVGcbdoKGKx8j3bGH';
$pear_image .= '7nARBArqwi0gkFJBrZiXBQRbHoIgnhSjcEBKfD7c3HMhz+JIQSY3t8GGKW+SUhfUajxGzKd0IoHBNkNQK86ZYEqdzYA8AHQpqXRUm80oHs1CAgMoBxzRq';
$pear_image .= 'vzs9CIKECC1JBp7enUpfXHApwVYNAfo16c4IrYPLVdSAJVob7IAtCBFQGHcs/RRdiUDPHA33oADEAIAOw==';
header('content-type: image/gif');
echo base64_decode($pear_image);
}
 
/**
* Shows PEAR_Info output
* @return void
* @access public
*/
 
function show()
{
echo $this->info;
}
/**
* Check if a package is installed
*/
function packageInstalled($package_name, $version = null, $pear_user_config = null)
{
if(is_null($pear_user_config)) {
$config = new PEAR_Config();
} else {
$config = new PEAR_Config($pear_user_config);
}
$reg = new PEAR_Registry($config->get('php_dir'));
if (is_null($version)) {
return $reg->packageExists($package_name);
} else {
$installed = $reg->packageInfo($package_name);
return version_compare($version, $installed['version'], '<=');
}
}
}
 
if (isset($_GET['pear_image'])) {
PEAR_Info::pearImage();
exit;
}
?>
/trunk/bibliotheque/pear/PEAR/PackageFile.php
4,11 → 4,18
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: PackageFile.php,v 1.40 2006/09/25 05:12:21 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
32,9 → 39,9
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
45,7 → 52,11
*/
var $_config;
var $_debug;
 
/**
* Temp directory for uncompressing tgz files.
* @var string|false
*/
var $_tmpdir;
var $_logger = false;
/**
* @var boolean
53,13 → 64,6
var $_rawReturn = false;
 
/**
* helper for extracting Archive_Tar errors
* @var array
* @access private
*/
var $_extractErrors = array();
 
/**
*
* @param PEAR_Config $config
* @param ? $debug
66,10 → 70,11
* @param string @tmpdir Optional temporary directory for uncompressing
* files
*/
function __construct(&$config, $debug = false)
function PEAR_PackageFile(&$config, $debug = false, $tmpdir = false)
{
$this->_config = $config;
$this->_debug = $debug;
$this->_tmpdir = $tmpdir;
}
 
/**
98,7 → 103,6
$a = false;
return $a;
}
 
include_once 'PEAR/PackageFile/Parser/v' . $version{0} . '.php';
$version = $version{0};
$class = "PEAR_PackageFile_Parser_v$version";
126,7 → 130,6
$a = false;
return $a;
}
 
include_once 'PEAR/PackageFile/v' . $version{0} . '.php';
$version = $version{0};
$class = $this->getClassPrefix() . $version;
150,25 → 153,22
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 (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;
}
 
if ($this->_logger) {
$obj->setLogger($this->_logger);
}
 
$obj->setConfig($this->_config);
$obj->fromArray($arr);
return $obj;
}
 
/**
185,53 → 185,50
*/
function &fromXmlString($data, $state, $file, $archive = false)
{
if (preg_match('/<package[^>]+version=[\'"]([0-9]+\.[0-9]+)[\'"]/', $data, $packageversion)) {
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']);
if ($pf->validate($state)) {
if ($this->_logger) {
if ($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;
} else {
if ($this->_config->get('verbose') > 0) {
if ($this->_logger) {
if ($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)) {
} elseif (preg_match('/<package[^>]+version="([^"]+)"/', $data, $packageversion)) {
$a = PEAR::raiseError('package.xml file "' . $file .
'" has unsupported package.xml <package> version "' . $packageversion[1] . '"');
return $a;
239,7 → 236,6
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 .
250,28 → 246,26
if (PEAR::isError($pf)) {
return $pf;
}
 
if ($this->_rawReturn) {
return $pf;
}
 
if (!$pf->validate($state)) {
if ($pf->validate($state)) {
if ($this->_logger) {
if ($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;
} else {
$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;
}
}
 
303,17 → 297,14
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))) {
320,19 → 311,17
$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;
} else {
if (!count($content) && !@is_file($file)) {
$ret = PEAR::raiseError("could not open file \"$file\"");
return $ret;
}
}
 
if (!count($content) && !@is_file($file)) {
$ret = PEAR::raiseError("could not open file \"$file\"");
return $ret;
}
 
$xml = null;
$xml = null;
$origfile = $file;
foreach ($content as $file) {
$name = $file['filename'];
340,39 → 329,32
$xml = $name;
break;
}
 
if ($name == 'package.xml') {
$xml = $name;
break;
} elseif (preg_match('/package.xml$/', $name, $match)) {
} elseif (ereg('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;
if ($this->_tmpdir) {
$tmpdir = $this->_tmpdir;
} else {
$tmpdir = System::mkTemp(array('-d', 'pear'));
PEAR_PackageFile::addTempFile($tmpdir);
}
 
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;
379,6 → 361,13
}
 
/**
* helper for extracting Archive_Tar errors
* @var array
* @access private
*/
var $_extractErrors = array();
 
/**
* helper callback for extracting Archive_Tar errors
*
* @param PEAR_Error|null $err
410,13 → 399,9
*/
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'))
)
) {
(!file_exists($descfile) || !is_file($descfile) || !is_readable($descfile) ||
(!$fp = @fopen($descfile, 'r')))) {
$a = PEAR::raiseError("Unable to open $descfile");
return $a;
}
429,6 → 414,7
return $ret;
}
 
 
/**
* Create a PEAR_PackageFile_v* from a .tgz archive or package.xml file.
*
453,19 → 439,15
} 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')))
) {
 
(file_exists($info) || ($fp = @fopen($info, 'r')))) {
if ($fp) {
fclose($fp);
}
 
$tmp = substr($info, -4);
if ($tmp == '.xml') {
$info = &PEAR_PackageFile::fromPackageFile($info, $state);
472,20 → 454,21
} elseif ($tmp == '.tar' || $tmp == '.tgz') {
$info = &PEAR_PackageFile::fromTgzFile($info, $state);
} else {
$fp = fopen($info, 'r');
$fp = fopen($info, "r");
$test = fread($fp, 5);
fclose($fp);
if ($test == '<?xml') {
if ($test == "<?xml") {
$info = &PEAR_PackageFile::fromPackageFile($info, $state);
} else {
$info = &PEAR_PackageFile::fromTgzFile($info, $state);
}
}
 
} else {
$info = PEAR::raiseError("Cannot open '$info' for parsing");
return $info;
}
 
$info = PEAR::raiseError("Cannot open '$info' for parsing");
return $info;
}
}
 
?>
/trunk/bibliotheque/pear/PEAR/Installer.php
4,6 → 4,12
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
10,8 → 16,9
* @author Tomas V.V. Cox <cox@idecnet.com>
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Installer.php,v 1.243 2007/02/16 04:00:37 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
33,9 → 40,9
* @author Tomas V.V. Cox <cox@idecnet.com>
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
115,9 → 122,9
*
* @access public
*/
function __construct(&$ui)
function PEAR_Installer(&$ui)
{
parent::__construct($ui, array(), null);
parent::PEAR_Common();
$this->setFrontendObject($ui);
$this->debug = $this->config->get('verbose');
}
129,7 → 136,7
 
function setConfig(&$config)
{
$this->config = &$config;
$this->config = &$config;
$this->_registry = &$config->getRegistry();
}
 
158,11 → 165,9
if (!$channel) {
$channel = 'pear.php.net';
}
 
if (!strlen($package)) {
return $this->raiseError("No package to uninstall given");
}
 
if (strtolower($package) == 'pear' && $channel == 'pear.php.net') {
// to avoid race conditions, include all possible needed files
require_once 'PEAR/Task/Common.php';
174,31 → 179,25
require_once 'PEAR/PackageFile/Generator/v1.php';
require_once 'PEAR/PackageFile/Generator/v2.php';
}
 
$filelist = $this->_registry->packageInfo($package, 'filelist', $channel);
if ($filelist == null) {
return $this->raiseError("$channel/$package not installed");
}
 
$ret = array();
foreach ($filelist as $file => $props) {
if (empty($props['installed_as'])) {
continue;
}
 
$path = $props['installed_as'];
if ($backup) {
$this->addFileOperation('backup', array($path));
$ret[] = $path;
}
 
$this->addFileOperation('delete', array($path));
}
 
if ($backup) {
return $ret;
}
 
return true;
}
 
219,20 → 218,17
if (!isset($this->_registry)) {
$this->_registry = &$this->config->getRegistry();
}
 
if (isset($atts['platform'])) {
if (empty($os)) {
$os = new OS_Guess();
}
 
if (strlen($atts['platform']) && $atts['platform']{0} == '!') {
$negate = true;
$negate = true;
$platform = substr($atts['platform'], 1);
} else {
$negate = false;
$negate = false;
$platform = $atts['platform'];
}
 
if ((bool) $os->matchSignature($platform) === $negate) {
$this->log(3, "skipped $file (meant for $atts[platform], we are ".$os->getSignature().")");
return PEAR_INSTALLER_SKIPPED;
243,10 → 239,6
$channel = $this->pkginfo->getChannel();
// {{{ assemble the destination paths
switch ($atts['role']) {
case 'src':
case 'extsrc':
$this->source_files++;
return;
case 'doc':
case 'data':
case 'test':
261,19 → 253,20
case 'script':
$dest_dir = $this->config->get('bin_dir', null, $channel);
break;
case 'src':
case 'extsrc':
$this->source_files++;
return;
default:
return $this->raiseError("Invalid role `$atts[role]' for file $file");
}
 
$save_destdir = $dest_dir;
if (!empty($atts['baseinstalldir'])) {
$dest_dir .= DIRECTORY_SEPARATOR . $atts['baseinstalldir'];
}
 
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 {
290,19 → 283,16
array($dest_file, $orig_file));
$final_dest_file = $installed_as = $dest_file;
if (isset($this->_options['packagingroot'])) {
$installedas_dest_dir = dirname($final_dest_file);
$installedas_dest_dir = dirname($final_dest_file);
$installedas_dest_file = $dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file);
$final_dest_file = $this->_prependPath($final_dest_file, $this->_options['packagingroot']);
$final_dest_file = $this->_prependPath($final_dest_file,
$this->_options['packagingroot']);
} else {
$installedas_dest_dir = dirname($final_dest_file);
$installedas_dest_dir = dirname($final_dest_file);
$installedas_dest_file = $installedas_dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file);
}
 
$dest_dir = dirname($final_dest_file);
$dest_dir = dirname($final_dest_file);
$dest_file = $dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file);
if (preg_match('~/\.\.(/|\\z)|^\.\./~', str_replace('\\', '/', $dest_file))) {
return $this->raiseError("SECURITY ERROR: file $file (installed to $dest_file) contains parent directory reference ..", PEAR_INSTALLER_FAILED);
}
// }}}
 
if (empty($this->_options['register-only']) &&
313,7 → 303,6
}
$this->log(3, "+ mkdir $dest_dir");
}
 
// pretty much nothing happens if we are only registering the install
if (empty($this->_options['register-only'])) {
if (empty($atts['replacements'])) {
321,12 → 310,10
return $this->raiseError("file $orig_file does not exist",
PEAR_INSTALLER_FAILED);
}
 
if (!@copy($orig_file, $dest_file)) {
return $this->raiseError("failed to write $dest_file: $php_errormsg",
PEAR_INSTALLER_FAILED);
}
 
$this->log(3, "+ cp $orig_file $dest_file");
if (isset($atts['md5sum'])) {
$md5sum = md5_file($dest_file);
337,21 → 324,18
return $this->raiseError("file does not exist",
PEAR_INSTALLER_FAILED);
}
 
$contents = file_get_contents($orig_file);
if ($contents === false) {
$contents = '';
}
 
if (isset($atts['md5sum'])) {
$md5sum = md5($contents);
}
 
$subst_from = $subst_to = array();
foreach ($atts['replacements'] as $a) {
$to = '';
if ($a['type'] == 'php-const') {
if (preg_match('/^[a-z0-9_]+\\z/i', $a['to'])) {
if (preg_match('/^[a-z0-9_]+$/i', $a['to'])) {
eval("\$to = $a[to];");
} else {
if (!isset($options['soft'])) {
391,30 → 375,25
$subst_to[] = $to;
}
}
 
$this->log(3, "doing ".sizeof($subst_from)." substitution(s) for $final_dest_file");
if (sizeof($subst_from)) {
$contents = str_replace($subst_from, $subst_to, $contents);
}
 
$wp = @fopen($dest_file, "wb");
if (!is_resource($wp)) {
return $this->raiseError("failed to create $dest_file: $php_errormsg",
PEAR_INSTALLER_FAILED);
}
 
if (@fwrite($wp, $contents) === false) {
return $this->raiseError("failed writing to $dest_file: $php_errormsg",
PEAR_INSTALLER_FAILED);
}
 
fclose($wp);
// }}}
}
 
// {{{ check the md5
if (isset($md5sum)) {
if (strtolower($md5sum) === strtolower($atts['md5sum'])) {
if (strtolower($md5sum) == strtolower($atts['md5sum'])) {
$this->log(2, "md5sum ok: $final_dest_file");
} else {
if (empty($options['force'])) {
422,15 → 401,14
if (file_exists($dest_file)) {
unlink($dest_file);
}
 
if (!isset($options['ignore-errors'])) {
return $this->raiseError("bad md5sum for file $final_dest_file",
PEAR_INSTALLER_FAILED);
} else {
if (!isset($options['soft'])) {
$this->log(0, "warning : bad md5sum for file $final_dest_file");
}
}
 
if (!isset($options['soft'])) {
$this->log(0, "warning : bad md5sum for file $final_dest_file");
}
} else {
if (!isset($options['soft'])) {
$this->log(0, "warning : bad md5sum for file $final_dest_file");
447,40 → 425,21
} else {
$mode = 0666 & ~(int)octdec($this->config->get('umask'));
}
 
if ($atts['role'] != 'src') {
$this->addFileOperation("chmod", array($mode, $dest_file));
if (!@chmod($dest_file, $mode)) {
if (!isset($options['soft'])) {
$this->log(0, "failed to change mode of $dest_file: $php_errormsg");
}
$this->addFileOperation("chmod", array($mode, $dest_file));
if (!@chmod($dest_file, $mode)) {
if (!isset($options['soft'])) {
$this->log(0, "failed to change mode of $dest_file: $php_errormsg");
}
}
}
// }}}
 
if ($atts['role'] == 'src') {
rename($dest_file, $final_dest_file);
$this->log(2, "renamed source file $dest_file to $final_dest_file");
} else {
$this->addFileOperation("rename", array($dest_file, $final_dest_file,
$atts['role'] == 'ext'));
}
$this->addFileOperation("rename", array($dest_file, $final_dest_file,
$atts['role'] == 'ext'));
}
 
// Store the full path where the file was installed for easy unistall
if ($atts['role'] != 'script') {
$loc = $this->config->get($atts['role'] . '_dir');
} else {
$loc = $this->config->get('bin_dir');
}
$this->addFileOperation("installed_as", array($file, $installed_as,
$save_destdir, dirname(substr($installedas_dest_file, strlen($save_destdir)))));
 
if ($atts['role'] != 'src') {
$this->addFileOperation("installed_as", array($file, $installed_as,
$loc,
dirname(substr($installedas_dest_file, strlen($loc)))));
}
 
//$this->log(2, "installed: $dest_file");
return PEAR_INSTALLER_OK;
}
496,9 → 455,8
* @param array options from command-line
* @access private
*/
function _installFile2(&$pkg, $file, &$real_atts, $tmp_path, $options)
function _installFile2(&$pkg, $file, $atts, $tmp_path, $options)
{
$atts = $real_atts;
if (!isset($this->_registry)) {
$this->_registry = &$this->config->getRegistry();
}
510,34 → 468,26
return $this->raiseError('Invalid role `' . $atts['attribs']['role'] .
"' for file $file");
}
 
$role = &PEAR_Installer_Role::factory($pkg, $atts['attribs']['role'], $this->config);
$err = $role->setup($this, $pkg, $atts['attribs'], $file);
$err = $role->setup($this, $pkg, $atts['attribs'], $file);
if (PEAR::isError($err)) {
return $err;
}
 
if (!$role->isInstallable()) {
return;
}
 
$info = $role->processInstallation($pkg, $atts['attribs'], $file, $tmp_path);
if (PEAR::isError($info)) {
return $info;
} else {
list($save_destdir, $dest_dir, $dest_file, $orig_file) = $info;
}
 
list($save_destdir, $dest_dir, $dest_file, $orig_file) = $info;
if (preg_match('~/\.\.(/|\\z)|^\.\./~', str_replace('\\', '/', $dest_file))) {
return $this->raiseError("SECURITY ERROR: file $file (installed to $dest_file) contains parent directory reference ..", PEAR_INSTALLER_FAILED);
}
 
$final_dest_file = $installed_as = $dest_file;
if (isset($this->_options['packagingroot'])) {
$final_dest_file = $this->_prependPath($final_dest_file,
$this->_options['packagingroot']);
}
 
$dest_dir = dirname($final_dest_file);
$dest_dir = dirname($final_dest_file);
$dest_file = $dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file);
// }}}
 
550,7 → 500,6
$this->log(3, "+ mkdir $dest_dir");
}
}
 
$attribs = $atts['attribs'];
unset($atts['attribs']);
// pretty much nothing happens if we are only registering the install
560,12 → 509,10
return $this->raiseError("file $orig_file does not exist",
PEAR_INSTALLER_FAILED);
}
 
if (!@copy($orig_file, $dest_file)) {
return $this->raiseError("failed to write $dest_file: $php_errormsg",
PEAR_INSTALLER_FAILED);
}
 
$this->log(3, "+ cp $orig_file $dest_file");
if (isset($attribs['md5sum'])) {
$md5sum = md5_file($dest_file);
575,20 → 522,18
return $this->raiseError("file $orig_file does not exist",
PEAR_INSTALLER_FAILED);
}
 
$contents = file_get_contents($orig_file);
if ($contents === false) {
$contents = '';
}
 
if (isset($attribs['md5sum'])) {
$md5sum = md5($contents);
}
 
foreach ($atts as $tag => $raw) {
$tag = str_replace(array($pkg->getTasksNs() . ':', '-'), array('', '_'), $tag);
$tag = str_replace(array($pkg->getTasksNs() . ':', '-'),
array('', '_'), $tag);
$task = "PEAR_Task_$tag";
$task = new $task($this->config, $this, PEAR_TASK_INSTALL);
$task = &new $task($this->config, $this, PEAR_TASK_INSTALL);
if (!$task->isScript()) { // scripts are only handled after installation
$task->init($raw, $attribs, $pkg->getLastInstalledVersion());
$res = $task->startSession($pkg, $contents, $final_dest_file);
595,39 → 540,27
if ($res === false) {
continue; // skip this file
}
 
if (PEAR::isError($res)) {
return $res;
}
 
$contents = $res; // save changes
}
 
$wp = @fopen($dest_file, "wb");
if (!is_resource($wp)) {
return $this->raiseError("failed to create $dest_file: $php_errormsg",
PEAR_INSTALLER_FAILED);
}
 
if (fwrite($wp, $contents) === false) {
return $this->raiseError("failed writing to $dest_file: $php_errormsg",
PEAR_INSTALLER_FAILED);
}
 
fclose($wp);
}
}
 
// {{{ check the md5
if (isset($md5sum)) {
// Make sure the original md5 sum matches with expected
if (strtolower($md5sum) === strtolower($attribs['md5sum'])) {
if (strtolower($md5sum) == strtolower($attribs['md5sum'])) {
$this->log(2, "md5sum ok: $final_dest_file");
 
if (isset($contents)) {
// set md5 sum based on $content in case any tasks were run.
$real_atts['attribs']['md5sum'] = md5($contents);
}
} else {
if (empty($options['force'])) {
// delete the file
634,15 → 567,14
if (file_exists($dest_file)) {
unlink($dest_file);
}
 
if (!isset($options['ignore-errors'])) {
return $this->raiseError("bad md5sum for file $final_dest_file",
PEAR_INSTALLER_FAILED);
} else {
if (!isset($options['soft'])) {
$this->log(0, "warning : bad md5sum for file $final_dest_file");
}
}
 
if (!isset($options['soft'])) {
$this->log(0, "warning : bad md5sum for file $final_dest_file");
}
} else {
if (!isset($options['soft'])) {
$this->log(0, "warning : bad md5sum for file $final_dest_file");
649,10 → 581,7
}
}
}
} else {
$real_atts['attribs']['md5sum'] = md5_file($dest_file);
}
 
// }}}
// {{{ set file permissions
if (!OS_WINDOWS) {
662,33 → 591,19
} else {
$mode = 0666 & ~(int)octdec($this->config->get('umask'));
}
 
if ($attribs['role'] != 'src') {
$this->addFileOperation("chmod", array($mode, $dest_file));
if (!@chmod($dest_file, $mode)) {
if (!isset($options['soft'])) {
$this->log(0, "failed to change mode of $dest_file: $php_errormsg");
}
$this->addFileOperation("chmod", array($mode, $dest_file));
if (!@chmod($dest_file, $mode)) {
if (!isset($options['soft'])) {
$this->log(0, "failed to change mode of $dest_file: $php_errormsg");
}
}
}
// }}}
 
if ($attribs['role'] == 'src') {
rename($dest_file, $final_dest_file);
$this->log(2, "renamed source file $dest_file to $final_dest_file");
} else {
$this->addFileOperation("rename", array($dest_file, $final_dest_file, $role->isExtension()));
}
$this->addFileOperation("rename", array($dest_file, $final_dest_file, $role->isExtension()));
}
 
// Store the full path where the file was installed for easy uninstall
if ($attribs['role'] != 'src') {
$loc = $this->config->get($role->getLocationConfig(), null, $channel);
$this->addFileOperation('installed_as', array($file, $installed_as,
$loc,
dirname(substr($installed_as, strlen($loc)))));
}
$this->addFileOperation("installed_as", array($file, $installed_as,
$save_destdir, dirname(substr($dest_file, strlen($save_destdir)))));
 
//$this->log(2, "installed: $dest_file");
return PEAR_INSTALLER_OK;
727,7 → 642,6
return $this->raiseError('Internal Error: $data in addFileOperation'
. ' must be an array, was ' . gettype($data));
}
 
if ($type == 'chmod') {
$octmode = decoct($data[0]);
$this->log(3, "adding to transaction: $type $octmode $data[1]");
753,9 → 667,11
 
function commitFileTransaction()
{
$n = count($this->file_operations);
$this->log(2, "about to commit $n file operations");
// {{{ first, check permissions and such manually
$errors = array();
foreach ($this->file_operations as $key => $tr) {
foreach ($this->file_operations as $tr) {
list($type, $data) = $tr;
switch ($type) {
case 'rename':
762,7 → 678,6
if (!file_exists($data[0])) {
$errors[] = "cannot rename file $data[0], doesn't exist";
}
 
// check that dest dir. is writable
if (!is_writable(dirname($data[1]))) {
$errors[] = "permission denied ($type): $data[1]";
792,27 → 707,6
fclose($fp);
}
}
 
/* Verify we are not deleting a file owned by another package
* This can happen when a file moves from package A to B in
* an upgrade ala http://pear.php.net/17986
*/
$info = array(
'package' => strtolower($this->pkginfo->getName()),
'channel' => strtolower($this->pkginfo->getChannel()),
);
$result = $this->_registry->checkFileMap($data[0], $info, '1.1');
if (is_array($result)) {
$res = array_diff($result, $info);
if (!empty($res)) {
$new = $this->_registry->getPackage($result[1], $result[0]);
$this->file_operations[$key] = false;
$pkginfoName = $this->pkginfo->getName();
$newChannel = $new->getChannel();
$newPackage = $new->getName();
$this->log(3, "file $data[0] was scheduled for removal from $pkginfoName but is owned by $newChannel/$newPackage, removal has been cancelled.");
}
}
}
break;
}
819,11 → 713,7
 
}
// }}}
 
$n = count($this->file_operations);
$this->log(2, "about to commit $n file operations for " . $this->pkginfo->getName());
 
$m = count($errors);
$m = sizeof($errors);
if ($m > 0) {
foreach ($errors as $error) {
if (!isset($this->_options['soft'])) {
830,12 → 720,10
$this->log(1, $error);
}
}
 
if (!isset($this->_options['ignore-errors'])) {
return false;
}
}
 
$this->_dirtree = array();
// {{{ really commit the transaction
foreach ($this->file_operations as $i => $tr) {
843,7 → 731,6
// support removal of non-existing backups
continue;
}
 
list($type, $data) = $tr;
switch ($type) {
case 'backup':
851,7 → 738,6
$this->file_operations[$i] = false;
break;
}
 
if (!@copy($data[0], $data[0] . '.bak')) {
$this->log(1, 'Could not copy ' . $data[0] . ' to ' . $data[0] .
'.bak ' . $php_errormsg);
866,7 → 752,11
}
break;
case 'rename':
$test = file_exists($data[1]) ? @unlink($data[1]) : null;
if (file_exists($data[1])) {
$test = @unlink($data[1]);
} else {
$test = null;
}
if (!$test && file_exists($data[1])) {
if ($data[2]) {
$extra = ', this extension must be installed manually. Rename to "' .
874,17 → 764,14
} else {
$extra = '';
}
 
if (!isset($this->_options['soft'])) {
$this->log(1, 'Could not delete ' . $data[1] . ', cannot rename ' .
$data[0] . $extra);
}
 
if (!isset($this->_options['ignore-errors'])) {
return false;
}
}
 
// permissions issues with rename - copy() is far superior
$perms = @fileperms($data[0]);
if (!@copy($data[0], $data[1])) {
892,7 → 779,6
' ' . $php_errormsg);
return false;
}
 
// copy over permissions, otherwise they are lost
@chmod($data[1], $perms);
@unlink($data[0]);
904,7 → 790,6
decoct($data[0]) . ' ' . $php_errormsg);
return false;
}
 
$octmode = decoct($data[0]);
$this->log(3, "+ chmod $octmode $data[1]");
break;
930,7 → 815,6
break 2; // this directory is not empty and can't be
// deleted
}
 
closedir($testme);
if (!@rmdir($data[0])) {
$this->log(1, 'Could not rmdir ' . $data[0] . ' ' .
947,8 → 831,8
$this->_dirtree[dirname($data[1])] = true;
$this->pkginfo->setDirtree(dirname($data[1]));
 
while(!empty($data[3]) && dirname($data[3]) != $data[3] &&
$data[3] != '/' && $data[3] != '\\') {
while(!empty($data[3]) && $data[3] != '/' && $data[3] != '\\'
&& $data[3] != '.') {
$this->pkginfo->setDirtree($pp =
$this->_prependPath($data[3], $data[2]));
$this->_dirtree[$pp] = true;
1020,12 → 904,62
}
 
// }}}
// {{{ download()
 
/**
* Download any files and their dependencies, if necessary
*
* @param array a mixed list of package names, local files, or package.xml
* @param PEAR_Config
* @param array options from the command line
* @param array this is the array that will be populated with packages to
* install. Format of each entry:
*
* <code>
* array('pkg' => 'package_name', 'file' => '/path/to/local/file',
* 'info' => array() // parsed package.xml
* );
* </code>
* @param array this will be populated with any error messages
* @param false private recursion variable
* @param false private recursion variable
* @param false private recursion variable
* @deprecated in favor of PEAR_Downloader
*/
function download($packages, $options, &$config, &$installpackages,
&$errors, $installed = false, $willinstall = false, $state = false)
{
// trickiness: initialize here
parent::PEAR_Downloader($this->ui, $options, $config);
$ret = parent::download($packages);
$errors = $this->getErrorMsgs();
$installpackages = $this->getDownloadedPackages();
trigger_error("PEAR Warning: PEAR_Installer::download() is deprecated " .
"in favor of PEAR_Downloader class", E_USER_WARNING);
return $ret;
}
 
// }}}
// {{{ _parsePackageXml()
 
function _parsePackageXml(&$descfile)
function _parsePackageXml(&$descfile, &$tmpdir)
{
if (substr($descfile, -4) == '.xml') {
$tmpdir = false;
} else {
// {{{ Decompress pack in tmp dir -------------------------------------
 
// To allow relative package file names
$descfile = realpath($descfile);
 
if (PEAR::isError($tmpdir = System::mktemp('-d'))) {
return $tmpdir;
}
$this->log(3, '+ tmp dir created at ' . $tmpdir);
// }}}
}
// Parse xml file -----------------------------------------------
$pkg = new PEAR_PackageFile($this->config, $this->debug);
$pkg = new PEAR_PackageFile($this->config, $this->debug, $tmpdir);
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$p = &$pkg->fromAnyFile($descfile, PEAR_VALIDATE_INSTALLING);
PEAR::staticPopErrorHandling();
1039,9 → 973,9
}
}
return $this->raiseError('Installation failed: invalid package file');
} else {
$descfile = $p->getPackageFile();
}
 
$descfile = $p->getPackageFile();
return $p;
}
 
1097,29 → 1031,26
*
* @return array|PEAR_Error package info if successful
*/
 
function install($pkgfile, $options = array())
{
$this->_options = $options;
$this->_registry = &$this->config->getRegistry();
if (is_object($pkgfile)) {
$dlpkg = &$pkgfile;
$pkg = $pkgfile->getPackageFile();
$pkgfile = $pkg->getArchiveFile();
$dlpkg = &$pkgfile;
$pkg = $pkgfile->getPackageFile();
$pkgfile = $pkg->getArchiveFile();
$descfile = $pkg->getPackageFile();
$tmpdir = dirname($descfile);
} else {
$descfile = $pkgfile;
$pkg = $this->_parsePackageXml($descfile);
if (PEAR::isError($pkg)) {
$tmpdir = '';
if (PEAR::isError($pkg = &$this->_parsePackageXml($descfile, $tmpdir))) {
return $pkg;
}
}
 
$tmpdir = dirname($descfile);
if (realpath($descfile) != realpath($pkgfile)) {
// Use the temp_dir since $descfile can contain the download dir path
$tmpdir = $this->config->get('temp_dir', null, 'pear.php.net');
$tmpdir = System::mktemp('-d -t "' . $tmpdir . '"');
 
$tar = new Archive_Tar($pkgfile);
if (!$tar->extract($tmpdir)) {
return $this->raiseError("unable to unpack $pkgfile");
1128,6 → 1059,14
 
$pkgname = $pkg->getName();
$channel = $pkg->getChannel();
if (isset($this->_options['packagingroot'])) {
$regdir = $this->_prependPath(
$this->config->get('php_dir', null, 'pear.php.net'),
$this->_options['packagingroot']);
$packrootphp_dir = $this->_prependPath(
$this->config->get('php_dir', null, $channel),
$this->_options['packagingroot']);
}
 
if (isset($options['installroot'])) {
$this->config->setInstallRoot($options['installroot']);
1139,21 → 1078,7
$this->config->setInstallRoot(false);
$this->_registry = &$this->config->getRegistry();
if (isset($this->_options['packagingroot'])) {
$regdir = $this->_prependPath(
$this->config->get('php_dir', null, 'pear.php.net'),
$this->_options['packagingroot']);
 
$metadata_dir = $this->config->get('metadata_dir', null, 'pear.php.net');
if ($metadata_dir) {
$metadata_dir = $this->_prependPath(
$metadata_dir,
$this->_options['packagingroot']);
}
$packrootphp_dir = $this->_prependPath(
$this->config->get('php_dir', null, $channel),
$this->_options['packagingroot']);
 
$installregistry = new PEAR_Registry($regdir, false, false, $metadata_dir);
$installregistry = &new PEAR_Registry($regdir);
if (!$installregistry->channelExists($channel, true)) {
// we need to fake a channel-discover of this channel
$chanobj = $this->_registry->getChannel($channel, true);
1176,7 → 1101,6
if (PEAR::isError($instfilelist)) {
return $instfilelist;
}
 
// ensure we have the most accurate registry
$installregistry->flushFileMap();
$test = $installregistry->checkFileMap($instfilelist, $testp, '1.1');
1183,7 → 1107,6
if (PEAR::isError($test)) {
return $test;
}
 
if (sizeof($test)) {
$pkgs = $this->getInstallPackages();
$found = false;
1193,7 → 1116,6
break;
}
}
 
if ($found) {
// subpackages can conflict with earlier versions of parent packages
$parentreg = $installregistry->packageInfo($param->getPackage(), null, $param->getChannel());
1201,52 → 1123,24
foreach ($tmp as $file => $info) {
if (is_array($info)) {
if (strtolower($info[1]) == strtolower($param->getPackage()) &&
strtolower($info[0]) == strtolower($param->getChannel())
) {
if (isset($parentreg['filelist'][$file])) {
unset($parentreg['filelist'][$file]);
} else{
$pos = strpos($file, '/');
$basedir = substr($file, 0, $pos);
$file2 = substr($file, $pos + 1);
if (isset($parentreg['filelist'][$file2]['baseinstalldir'])
&& $parentreg['filelist'][$file2]['baseinstalldir'] === $basedir
) {
unset($parentreg['filelist'][$file2]);
}
}
 
strtolower($info[0]) == strtolower($param->getChannel())) {
unset($test[$file]);
unset($parentreg['filelist'][$file]);
}
} else {
if (strtolower($param->getChannel()) != 'pear.php.net') {
continue;
}
 
if (strtolower($info) == strtolower($param->getPackage())) {
if (isset($parentreg['filelist'][$file])) {
unset($parentreg['filelist'][$file]);
} else{
$pos = strpos($file, '/');
$basedir = substr($file, 0, $pos);
$file2 = substr($file, $pos + 1);
if (isset($parentreg['filelist'][$file2]['baseinstalldir'])
&& $parentreg['filelist'][$file2]['baseinstalldir'] === $basedir
) {
unset($parentreg['filelist'][$file2]);
}
}
 
unset($test[$file]);
unset($parentreg['filelist'][$file]);
}
}
}
 
$pfk = new PEAR_PackageFile($this->config);
$pfk = &new PEAR_PackageFile($this->config);
$parentpkg = &$pfk->fromArray($parentreg);
$installregistry->updatePackage2($parentpkg);
}
 
if ($param->getChannel() == 'pecl.php.net' && isset($options['upgrade'])) {
$tmp = $test;
foreach ($tmp as $file => $info) {
1259,8 → 1153,7
}
}
}
 
if (count($test)) {
if (sizeof($test)) {
$msg = "$channel/$pkgname: conflicting files found:\n";
$longest = max(array_map("strlen", array_keys($test)));
$fmt = "%${longest}s (%s)\n";
1271,14 → 1164,13
$info = $info[0] . '/' . $info[1];
$msg .= sprintf($fmt, $file, $info);
}
 
if (!isset($options['ignore-errors'])) {
return $this->raiseError($msg);
} else {
if (!isset($options['soft'])) {
$this->log(0, "WARNING: $msg");
}
}
 
if (!isset($options['soft'])) {
$this->log(0, "WARNING: $msg");
}
}
}
}
1286,24 → 1178,30
 
$this->startFileTransaction();
 
$usechannel = $channel;
if ($channel == 'pecl.php.net') {
$test = $installregistry->packageExists($pkgname, $channel);
if (!$test) {
$test = $installregistry->packageExists($pkgname, 'pear.php.net');
$usechannel = 'pear.php.net';
}
} else {
$test = $installregistry->packageExists($pkgname, $channel);
}
 
if (empty($options['upgrade']) && empty($options['soft'])) {
// checks to do only when installing new packages
if ($channel == 'pecl.php.net') {
$test = $installregistry->packageExists($pkgname, $channel);
if (!$test) {
$test = $installregistry->packageExists($pkgname, 'pear.php.net');
}
} else {
$test = $installregistry->packageExists($pkgname, $channel);
}
if (empty($options['force']) && $test) {
return $this->raiseError("$channel/$pkgname is already installed");
}
} else {
// Upgrade
$usechannel = $channel;
if ($channel == 'pecl.php.net') {
$test = $installregistry->packageExists($pkgname, $channel);
if (!$test) {
$test = $installregistry->packageExists($pkgname, 'pear.php.net');
$usechannel = 'pear.php.net';
}
} else {
$test = $installregistry->packageExists($pkgname, $channel);
}
if ($test) {
$v1 = $installregistry->packageInfo($pkgname, 'version', $usechannel);
$v2 = $pkg->getVersion();
1311,23 → 1209,21
if (empty($options['force']) && !version_compare("$v2", "$v1", 'gt')) {
return $this->raiseError("upgrade to a newer version ($v2 is not newer than $v1)");
}
}
}
 
// Do cleanups for upgrade and install, remove old release's files first
if ($test && empty($options['register-only'])) {
// when upgrading, remove old release's files first:
if (PEAR::isError($err = $this->_deletePackageFiles($pkgname, $usechannel,
true))) {
if (!isset($options['ignore-errors'])) {
return $this->raiseError($err);
if (empty($options['register-only'])) {
// when upgrading, remove old release's files first:
if (PEAR::isError($err = $this->_deletePackageFiles($pkgname, $usechannel,
true))) {
if (!isset($options['ignore-errors'])) {
return $this->raiseError($err);
} else {
if (!isset($options['soft'])) {
$this->log(0, 'WARNING: ' . $err->getMessage());
}
}
} else {
$backedup = $err;
}
}
 
if (!isset($options['soft'])) {
$this->log(0, 'WARNING: ' . $err->getMessage());
}
} else {
$backedup = $err;
}
}
 
1345,8 → 1241,9
}
}
 
$tmp_path = dirname($descfile);
if (substr($pkgfile, -4) != '.xml') {
$tmpdir .= DIRECTORY_SEPARATOR . $pkgname . '-' . $pkg->getVersion();
$tmp_path .= DIRECTORY_SEPARATOR . $pkgname . '-' . $pkg->getVersion();
}
 
$this->configSet('default_channel', $channel);
1358,26 → 1255,22
} else {
$filelist = $pkg->getFileList();
}
 
if (PEAR::isError($filelist)) {
return $filelist;
}
 
$p = &$installregistry->getPackage($pkgname, $channel);
$dirtree = (empty($options['register-only']) && $p) ? $p->getDirTree() : false;
 
$pkg->resetFilelist();
$pkg->setLastInstalledVersion($installregistry->packageInfo($pkg->getPackage(),
'version', $pkg->getChannel()));
foreach ($filelist as $file => $atts) {
$this->expectError(PEAR_INSTALLER_FAILED);
if ($pkg->getPackagexmlVersion() == '1.0') {
$res = $this->_installFile($file, $atts, $tmpdir, $options);
$this->expectError(PEAR_INSTALLER_FAILED);
$res = $this->_installFile($file, $atts, $tmp_path, $options);
$this->popExpect();
} else {
$res = $this->_installFile2($pkg, $file, $atts, $tmpdir, $options);
$this->expectError(PEAR_INSTALLER_FAILED);
$res = $this->_installFile2($pkg, $file, $atts, $tmp_path, $options);
$this->popExpect();
}
$this->popExpect();
 
if (PEAR::isError($res)) {
if (empty($options['ignore-errors'])) {
$this->rollbackFileTransaction();
1384,17 → 1277,14
if ($res->getMessage() == "file does not exist") {
$this->raiseError("file $file in package.xml does not exist");
}
 
return $this->raiseError($res);
} else {
if (!isset($options['soft'])) {
$this->log(0, "Warning: " . $res->getMessage());
}
}
 
if (!isset($options['soft'])) {
$this->log(0, "Warning: " . $res->getMessage());
}
}
 
$real = isset($atts['attribs']) ? $atts['attribs'] : $atts;
if ($res == PEAR_INSTALLER_OK && $real['role'] != 'src') {
if ($res == PEAR_INSTALLER_OK) {
// Register files that were installed
$pkg->installedFile($file, $atts);
}
1413,7 → 1303,6
if (isset($backedup)) {
$this->_removeBackups($backedup);
}
 
if (!$this->commitFileTransaction()) {
$this->rollbackFileTransaction();
$this->configSet('default_channel', $savechannel);
1421,9 → 1310,9
}
// }}}
 
$ret = false;
$ret = false;
$installphase = 'install';
$oldversion = false;
$oldversion = false;
// {{{ Register that the package is installed -----------------------
if (empty($options['upgrade'])) {
// if 'force' is used, replace the info in registry
1437,7 → 1326,6
} else {
$test = $installregistry->packageExists($pkgname, $channel);
}
 
if (!empty($options['force']) && $test) {
$oldversion = $installregistry->packageInfo($pkgname, 'version', $usechannel);
$installregistry->deletePackage($pkgname, $usechannel);
1444,16 → 1332,6
}
$ret = $installregistry->addPackage2($pkg);
} else {
if ($dirtree) {
$this->startFileTransaction();
// attempt to delete empty directories
uksort($dirtree, array($this, '_sortDirs'));
foreach($dirtree as $dir => $notused) {
$this->addFileOperation('rmdir', array($dir));
}
$this->commitFileTransaction();
}
 
$usechannel = $channel;
if ($channel == 'pecl.php.net') {
$test = $installregistry->packageExists($pkgname, $channel);
1464,7 → 1342,6
} else {
$test = $installregistry->packageExists($pkgname, $channel);
}
 
// new: upgrade installs a package if it isn't installed
if (!$test) {
$ret = $installregistry->addPackage2($pkg);
1478,13 → 1355,11
$installphase = 'upgrade';
}
}
 
if (!$ret) {
$this->configSet('default_channel', $savechannel);
return $this->raiseError("Adding package $channel/$pkgname to registry failed");
}
// }}}
 
$this->configSet('default_channel', $savechannel);
if (class_exists('PEAR_Task_Common')) { // this is auto-included if any tasks exist
if (PEAR_Task_Common::hasPostinstallTasks()) {
1491,7 → 1366,6
PEAR_Task_Common::runPostinstallTasks($installphase);
}
}
 
return $pkg->toArray(true);
}
 
1506,7 → 1380,7
{
require_once 'PEAR/Builder.php';
$this->log(1, "$this->source_files source files, building");
$bob = new PEAR_Builder($this->ui);
$bob = &new PEAR_Builder($this->ui);
$bob->debug = $this->debug;
$built = $bob->build($filelist, array(&$this, '_buildCallback'));
if (PEAR::isError($built)) {
1514,7 → 1388,6
$this->configSet('default_channel', $savechannel);
return $built;
}
 
$this->log(1, "\nBuild process completed successfully");
foreach ($built as $ext) {
$bn = basename($ext['file']);
1529,17 → 1402,17
} else {
$role = 'src';
}
 
$dest = $ext['dest'];
$packagingroot = '';
if (isset($this->_options['packagingroot'])) {
$packagingroot = $this->_options['packagingroot'];
}
 
$copyto = $this->_prependPath($dest, $packagingroot);
$extra = $copyto != $dest ? " as '$copyto'" : '';
$this->log(1, "Installing '$dest'$extra");
 
if ($copyto != $dest) {
$this->log(1, "Installing '$dest' as '$copyto'");
} else {
$this->log(1, "Installing '$dest'");
}
$copydir = dirname($copyto);
// pretty much nothing happens if we are only registering the install
if (empty($this->_options['register-only'])) {
1548,14 → 1421,11
return $this->raiseError("failed to mkdir $copydir",
PEAR_INSTALLER_FAILED);
}
 
$this->log(3, "+ mkdir $copydir");
}
 
if (!@copy($ext['file'], $copyto)) {
return $this->raiseError("failed to write $copyto ($php_errormsg)", PEAR_INSTALLER_FAILED);
}
 
$this->log(3, "+ cp $ext[file] $copyto");
$this->addFileOperation('rename', array($ext['file'], $copyto));
if (!OS_WINDOWS) {
1567,20 → 1437,24
}
}
 
 
$data = array(
'role' => $role,
'name' => $bn,
'installed_as' => $dest,
'php_api' => $ext['php_api'],
'zend_mod_api' => $ext['zend_mod_api'],
'zend_ext_api' => $ext['zend_ext_api'],
);
 
if ($filelist->getPackageXmlVersion() == '1.0') {
$filelist->installedFile($bn, $data);
$filelist->installedFile($bn, array(
'role' => $role,
'name' => $bn,
'installed_as' => $dest,
'php_api' => $ext['php_api'],
'zend_mod_api' => $ext['zend_mod_api'],
'zend_ext_api' => $ext['zend_ext_api'],
));
} else {
$filelist->installedFile($bn, array('attribs' => $data));
$filelist->installedFile($bn, array('attribs' => array(
'role' => $role,
'name' => $bn,
'installed_as' => $dest,
'php_api' => $ext['php_api'],
'zend_mod_api' => $ext['zend_mod_api'],
'zend_ext_api' => $ext['zend_ext_api'],
)));
}
}
}
1607,14 → 1481,17
*/
function uninstall($package, $options = array())
{
$installRoot = isset($options['installroot']) ? $options['installroot'] : '';
$this->config->setInstallRoot($installRoot);
 
$this->installroot = '';
if (isset($options['installroot'])) {
$this->config->setInstallRoot($options['installroot']);
$this->installroot = '';
} else {
$this->config->setInstallRoot('');
$this->installroot = '';
}
$this->_registry = &$this->config->getRegistry();
if (is_object($package)) {
$channel = $package->getChannel();
$pkg = $package;
$pkg = $package;
$package = $pkg->getPackage();
} else {
$pkg = false;
1623,13 → 1500,11
$channel = $info['channel'];
$package = $info['package'];
}
 
$savechannel = $this->config->get('default_channel');
$this->configSet('default_channel', $channel);
if (!is_object($pkg)) {
$pkg = $this->_registry->getPackage($package, $channel);
}
 
if (!$pkg) {
$this->configSet('default_channel', $savechannel);
return $this->raiseError($this->_registry->parsedPackageNameToString(
1638,19 → 1513,16
'package' => $package
), true) . ' not installed');
}
 
if ($pkg->getInstalledBinary()) {
// this is just an alias for a binary package
return $this->_registry->deletePackage($package, $channel);
}
 
$filelist = $pkg->getFilelist();
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
if (!class_exists('PEAR_Dependency2')) {
require_once 'PEAR/Dependency2.php';
}
 
$depchecker = new PEAR_Dependency2($this->config, $options,
$depchecker = &new PEAR_Dependency2($this->config, $options,
array('channel' => $channel, 'package' => $package),
PEAR_VALIDATE_UNINSTALLING);
$e = $depchecker->validatePackageUninstall($this);
1658,17 → 1530,16
if (PEAR::isError($e)) {
if (!isset($options['ignore-errors'])) {
return $this->raiseError($e);
} else {
if (!isset($options['soft'])) {
$this->log(0, 'WARNING: ' . $e->getMessage());
}
}
 
if (!isset($options['soft'])) {
$this->log(0, 'WARNING: ' . $e->getMessage());
}
} elseif (is_array($e)) {
if (!isset($options['soft'])) {
$this->log(0, $e[0]);
}
}
 
$this->pkginfo = &$pkg;
// pretty much nothing happens if we are only registering the uninstall
if (empty($options['register-only'])) {
1681,45 → 1552,38
$this->configSet('default_channel', $savechannel);
if (!isset($options['ignore-errors'])) {
return $this->raiseError($err);
} else {
if (!isset($options['soft'])) {
$this->log(0, 'WARNING: ' . $err->getMessage());
}
}
 
if (!isset($options['soft'])) {
$this->log(0, 'WARNING: ' . $err->getMessage());
}
} else {
PEAR::popErrorHandling();
}
 
if (!$this->commitFileTransaction()) {
$this->rollbackFileTransaction();
if (!isset($options['ignore-errors'])) {
return $this->raiseError("uninstall failed");
}
 
if (!isset($options['soft'])) {
} elseif (!isset($options['soft'])) {
$this->log(0, 'WARNING: uninstall failed');
}
} else {
$this->startFileTransaction();
$dirtree = $pkg->getDirTree();
if ($dirtree === false) {
if ($dirtree = $pkg->getDirTree()) {
// attempt to delete empty directories
uksort($dirtree, array($this, '_sortDirs'));
foreach($dirtree as $dir => $notused) {
$this->addFileOperation('rmdir', array($dir));
}
} else {
$this->configSet('default_channel', $savechannel);
return $this->_registry->deletePackage($package, $channel);
}
 
// attempt to delete empty directories
uksort($dirtree, array($this, '_sortDirs'));
foreach($dirtree as $dir => $notused) {
$this->addFileOperation('rmdir', array($dir));
}
 
if (!$this->commitFileTransaction()) {
$this->rollbackFileTransaction();
if (!isset($options['ignore-errors'])) {
return $this->raiseError("uninstall failed");
}
 
if (!isset($options['soft'])) {
} elseif (!isset($options['soft'])) {
$this->log(0, 'WARNING: uninstall failed');
}
}
1792,3 → 1656,17
 
// }}}
}
 
// {{{ md5_file() utility function
if (!function_exists("md5_file")) {
function md5_file($filename) {
if (!$fd = @fopen($file, 'r')) {
return false;
}
fclose($fd);
return md5(file_get_contents($filename));
}
}
// }}}
 
?>
/trunk/bibliotheque/pear/PEAR/Downloader.php
4,6 → 4,12
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
10,8 → 16,9
* @author Stig Bakken <ssb@php.net>
* @author Tomas V. V. Cox <cox@idecnet.com>
* @author Martin Jansen <mj@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Downloader.php,v 1.123 2007/02/20 00:16:12 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.3.0
*/
36,9 → 43,9
* @author Stig Bakken <ssb@php.net>
* @author Tomas V. V. Cox <cox@idecnet.com>
* @author Martin Jansen <mj@php.net>
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.3.0
*/
51,6 → 58,12
var $_registry;
 
/**
* @var PEAR_Remote
* @access private
*/
var $_remote;
 
/**
* Preferred Installation State (snapshot, devel, alpha, beta, stable)
* @var string|null
* @access private
119,7 → 132,7
* @access private
*/
var $_errorStack = array();
 
/**
* @var boolean
* @access private
138,33 → 151,19
* @var string
*/
var $_downloadDir;
// {{{ PEAR_Downloader()
 
/**
* List of methods that can be called both statically and non-statically.
* @var array
*/
protected static $bivalentMethods = array(
'setErrorHandling' => true,
'raiseError' => true,
'throwError' => true,
'pushErrorHandling' => true,
'popErrorHandling' => true,
'downloadHttp' => true,
);
 
/**
* @param PEAR_Frontend_*
* @param array
* @param PEAR_Config
*/
function __construct($ui = null, $options = array(), $config = null)
function PEAR_Downloader(&$ui, $options, &$config)
{
parent::__construct();
parent::PEAR_Common();
$this->_options = $options;
if ($config !== null) {
$this->config = &$config;
$this->_preferredState = $this->config->get('preferred_state');
}
$this->config = &$config;
$this->_preferredState = $this->config->get('preferred_state');
$this->ui = &$ui;
if (!$this->_preferredState) {
// don't inadvertantly use a non-set preferred_state
171,12 → 170,11
$this->_preferredState = null;
}
 
if ($config !== null) {
if (isset($this->_options['installroot'])) {
$this->config->setInstallRoot($this->_options['installroot']);
}
$this->_registry = &$config->getRegistry();
if (isset($this->_options['installroot'])) {
$this->config->setInstallRoot($this->_options['installroot']);
}
$this->_registry = &$config->getRegistry();
$this->_remote = &$config->getRemote();
 
if (isset($this->_options['alldeps']) || isset($this->_options['onlyreqdeps'])) {
$this->_installed = $this->_registry->listAllPackages();
204,27 → 202,16
if (!class_exists('System')) {
require_once 'System.php';
}
 
$tmpdir = $this->config->get('temp_dir');
$tmp = System::mktemp('-d -t "' . $tmpdir . '"');
$a = $this->downloadHttp('http://' . $channel . '/channel.xml', $this->ui, $tmp, $callback, false);
$a = $this->downloadHttp('http://' . $channel . '/channel.xml', $this->ui,
System::mktemp(array('-d')), $callback, false);
PEAR::popErrorHandling();
if (PEAR::isError($a)) {
// Attempt to fallback to https automatically.
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$this->log(1, 'Attempting fallback to https instead of http on channel "' . $channel . '"...');
$a = $this->downloadHttp('https://' . $channel . '/channel.xml', $this->ui, $tmp, $callback, false);
PEAR::popErrorHandling();
if (PEAR::isError($a)) {
return false;
}
return false;
}
 
list($a, $lastmodified) = $a;
if (!class_exists('PEAR_ChannelFile')) {
if (!class_exists('PEAR/ChannelFile.php')) {
require_once 'PEAR/ChannelFile.php';
}
 
$b = new PEAR_ChannelFile;
if ($b->fromXmlFile($a)) {
unlink($a);
234,14 → 221,11
if ($b->getName() == $this->_registry->channelName($b->getAlias())) {
$alias = $b->getAlias();
}
 
$this->log(1, 'Auto-discovered channel "' . $channel .
'", alias "' . $alias . '", adding to registry');
}
 
return true;
}
 
unlink($a);
return false;
}
251,12 → 235,12
* @param PEAR_Downloader
* @return PEAR_Downloader_Package
*/
function newDownloaderPackage(&$t)
function &newDownloaderPackage(&$t)
{
if (!class_exists('PEAR_Downloader_Package')) {
require_once 'PEAR/Downloader/Package.php';
}
$a = new PEAR_Downloader_Package($t);
$a = &new PEAR_Downloader_Package($t);
return $a;
}
 
269,10 → 253,10
*/
function &getDependency2Object(&$c, $i, $p, $s)
{
if (!class_exists('PEAR_Dependency2')) {
if (!class_exists('PEAR/Dependency2.php')) {
require_once 'PEAR/Dependency2.php';
}
$z = new PEAR_Dependency2($c, $i, $p, $s);
$z = &new PEAR_Dependency2($c, $i, $p, $s);
return $z;
}
 
282,15 → 266,16
$a = array();
return $a;
}
 
if (!isset($this->_registry)) {
$this->_registry = &$this->config->getRegistry();
}
 
if (!isset($this->_remote)) {
$this->_remote = &$this->config->getRemote();
}
$channelschecked = array();
// convert all parameters into PEAR_Downloader_Package objects
foreach ($params as $i => $param) {
$params[$i] = $this->newDownloaderPackage($this);
$params[$i] = &$this->newDownloaderPackage($this);
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$err = $params[$i]->initialize($param);
PEAR::staticPopErrorHandling();
298,75 → 283,51
// skip parameters that were missed by preferred_state
continue;
}
 
if (PEAR::isError($err)) {
if (!isset($this->_options['soft']) && $err->getMessage() !== '') {
if (!isset($this->_options['soft'])) {
$this->log(0, $err->getMessage());
}
 
$params[$i] = false;
if (is_object($param)) {
$param = $param->getChannel() . '/' . $param->getPackage();
}
 
if (!isset($this->_options['soft'])) {
$this->log(2, 'Package "' . $param . '" is not valid');
}
 
// Message logged above in a specific verbose mode, passing null to not show up on CLI
$this->pushError(null, PEAR_INSTALLER_SKIPPED);
$this->pushError('Package "' . $param . '" is not valid',
PEAR_INSTALLER_SKIPPED);
} else {
do {
if ($params[$i] && $params[$i]->getType() == 'local') {
// bug #7090 skip channel.xml check for local packages
// bug #7090
// skip channel.xml check for local packages
break;
}
 
if ($params[$i] && !isset($channelschecked[$params[$i]->getChannel()]) &&
!isset($this->_options['offline'])
) {
!isset($this->_options['offline'])) {
$channelschecked[$params[$i]->getChannel()] = true;
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
if (!class_exists('System')) {
require_once 'System.php';
}
 
$curchannel = $this->_registry->getChannel($params[$i]->getChannel());
$curchannel = &$this->_registry->getChannel($params[$i]->getChannel());
if (PEAR::isError($curchannel)) {
PEAR::staticPopErrorHandling();
return $this->raiseError($curchannel);
}
 
if (PEAR::isError($dir = $this->getDownloadDir())) {
PEAR::staticPopErrorHandling();
break;
}
$a = $this->downloadHttp('http://' . $params[$i]->getChannel() .
'/channel.xml', $this->ui, $dir, null, $curchannel->lastModified());
 
$mirror = $this->config->get('preferred_mirror', null, $params[$i]->getChannel());
$url = 'http://' . $mirror . '/channel.xml';
$a = $this->downloadHttp($url, $this->ui, $dir, null, $curchannel->lastModified());
 
PEAR::staticPopErrorHandling();
if ($a === false) {
//channel.xml not modified
if (PEAR::isError($a) || !$a) {
break;
} else if (PEAR::isError($a)) {
// Attempt fallback to https automatically
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$a = $this->downloadHttp('https://' . $mirror .
'/channel.xml', $this->ui, $dir, null, $curchannel->lastModified());
 
PEAR::staticPopErrorHandling();
if (PEAR::isError($a) || !$a) {
break;
}
}
$this->log(0, 'WARNING: channel "' . $params[$i]->getChannel() . '" has ' .
'updated its protocols, use "' . PEAR_RUNTYPE . ' channel-update ' . $params[$i]->getChannel() .
'updated its protocols, use "channel-update ' . $params[$i]->getChannel() .
'" to update');
}
} while (false);
 
if ($params[$i] && !isset($this->_options['downloadonly'])) {
if (isset($this->_options['packagingroot'])) {
$checkdir = $this->_prependPath(
376,15 → 337,12
$checkdir = $this->config->get('php_dir',
null, $params[$i]->getChannel());
}
 
while ($checkdir && $checkdir != '/' && !file_exists($checkdir)) {
$checkdir = dirname($checkdir);
}
 
if ($checkdir == '.') {
$checkdir = '/';
}
 
if (!is_writeable($checkdir)) {
return PEAR::raiseError('Cannot install, php_dir for channel "' .
$params[$i]->getChannel() . '" is not writeable by the current user');
392,7 → 350,6
}
}
}
 
unset($channelschecked);
PEAR_Downloader_Package::removeDuplicates($params);
if (!count($params)) {
399,15 → 356,11
$a = array();
return $a;
}
 
if (!isset($this->_options['nodeps']) && !isset($this->_options['offline'])) {
$reverify = true;
while ($reverify) {
$reverify = false;
foreach ($params as $i => $param) {
//PHP Bug 40768 / PEAR Bug #10944
//Nested foreaches fail in PHP 5.2.1
key($params);
$ret = $params[$i]->detectDependencies($params);
if (PEAR::isError($ret)) {
$reverify = true;
421,30 → 374,15
}
}
}
 
if (isset($this->_options['offline'])) {
$this->log(3, 'Skipping dependency download check, --offline specified');
}
 
if (!count($params)) {
$a = array();
return $a;
}
 
while (PEAR_Downloader_Package::mergeDependencies($params));
PEAR_Downloader_Package::removeDuplicates($params, true);
$errorparams = array();
if (PEAR_Downloader_Package::detectStupidDuplicates($params, $errorparams)) {
if (count($errorparams)) {
foreach ($errorparams as $param) {
$name = $this->_registry->parsedPackageNameToString($param->getParsedPackage());
$this->pushError('Duplicate package ' . $name . ' found', PEAR_INSTALLER_FAILED);
}
$a = array();
return $a;
}
}
 
PEAR_Downloader_Package::removeInstalled($params);
if (!count($params)) {
$this->pushError('No valid packages found', PEAR_INSTALLER_FAILED);
451,7 → 389,6
$a = array();
return $a;
}
 
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$err = $this->analyzeDependencies($params);
PEAR::popErrorHandling();
460,14 → 397,11
$a = array();
return $a;
}
 
$ret = array();
$newparams = array();
if (isset($this->_options['pretend'])) {
return $params;
}
 
$somefailed = false;
foreach ($params as $i => $package) {
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$pf = &$params[$i]->download();
480,30 → 414,13
true) .
'"');
}
$somefailed = true;
continue;
}
 
$newparams[] = &$params[$i];
$ret[] = array(
'file' => $pf->getArchiveFile(),
'info' => &$pf,
'pkg' => $pf->getPackage()
);
$ret[] = array('file' => $pf->getArchiveFile(),
'info' => &$pf,
'pkg' => $pf->getPackage());
}
 
if ($somefailed) {
// remove params that did not download successfully
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$err = $this->analyzeDependencies($newparams, true);
PEAR::popErrorHandling();
if (!count($newparams)) {
$this->pushError('Download failed', PEAR_INSTALLER_FAILED);
$a = array();
return $a;
}
}
 
$this->_downloadedPackages = $ret;
return $newparams;
}
511,15 → 428,15
/**
* @param array all packages to be installed
*/
function analyzeDependencies(&$params, $force = false)
function analyzeDependencies(&$params)
{
$hasfailed = $failed = false;
if (isset($this->_options['downloadonly'])) {
return;
}
 
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$redo = true;
$reset = $hasfailed = $failed = false;
$redo = true;
$reset = false;
while ($redo) {
$redo = false;
foreach ($params as $i => $param) {
527,52 → 444,52
if (!$deps) {
$depchecker = &$this->getDependency2Object($this->config, $this->getOptions(),
$param->getParsedPackage(), PEAR_VALIDATE_DOWNLOADING);
$send = $param->getPackageFile();
 
if ($param->getType() == 'xmlrpc') {
$send = $param->getDownloadURL();
} else {
$send = $param->getPackageFile();
}
$installcheck = $depchecker->validatePackage($send, $this, $params);
if (PEAR::isError($installcheck)) {
if (!isset($this->_options['soft'])) {
$this->log(0, $installcheck->getMessage());
}
$hasfailed = true;
$hasfailed = true;
$params[$i] = false;
$reset = true;
$redo = true;
$failed = false;
$reset = true;
$redo = true;
$failed = false;
PEAR_Downloader_Package::removeDuplicates($params);
continue 2;
}
continue;
}
 
if (!$reset && $param->alreadyValidated() && !$force) {
if (!$reset && $param->alreadyValidated()) {
continue;
}
 
if (count($deps)) {
$depchecker = &$this->getDependency2Object($this->config, $this->getOptions(),
$param->getParsedPackage(), PEAR_VALIDATE_DOWNLOADING);
$send = $param->getPackageFile();
if ($send === null) {
if ($param->getType() == 'xmlrpc') {
$send = $param->getDownloadURL();
} else {
$send = $param->getPackageFile();
}
 
$installcheck = $depchecker->validatePackage($send, $this, $params);
if (PEAR::isError($installcheck)) {
if (!isset($this->_options['soft'])) {
$this->log(0, $installcheck->getMessage());
}
$hasfailed = true;
$hasfailed = true;
$params[$i] = false;
$reset = true;
$redo = true;
$failed = false;
$reset = true;
$redo = true;
$failed = false;
PEAR_Downloader_Package::removeDuplicates($params);
continue 2;
}
 
$failed = false;
if (isset($deps['required']) && is_array($deps['required'])) {
if (isset($deps['required'])) {
foreach ($deps['required'] as $type => $dep) {
// note: Dependency2 will never return a PEAR_Error if ignore-errors
// is specified, so soft is needed to turn off logging
605,8 → 522,7
}
}
}
 
if (isset($deps['optional']) && is_array($deps['optional'])) {
if (isset($deps['optional'])) {
foreach ($deps['optional'] as $type => $dep) {
if (!isset($dep[0])) {
if (PEAR::isError($e =
639,13 → 555,11
}
}
}
 
$groupname = $param->getGroup();
if (isset($deps['group']) && $groupname) {
if (!isset($deps['group'][0])) {
$deps['group'] = array($deps['group']);
}
 
$found = false;
foreach ($deps['group'] as $group) {
if ($group['attribs']['name'] == $groupname) {
653,7 → 567,6
break;
}
}
 
if ($found) {
unset($group['attribs']);
foreach ($group as $type => $dep) {
705,19 → 618,17
}
$params[$i]->setValidated();
}
 
if ($failed) {
$hasfailed = true;
$hasfailed = true;
$params[$i] = false;
$reset = true;
$redo = true;
$failed = false;
$reset = true;
$redo = true;
$failed = false;
PEAR_Downloader_Package::removeDuplicates($params);
continue 2;
}
}
}
 
PEAR::staticPopErrorHandling();
if ($hasfailed && (isset($this->_options['ignore-errors']) ||
isset($this->_options['nodeps']))) {
738,49 → 649,33
if (isset($this->_downloadDir)) {
return $this->_downloadDir;
}
 
$downloaddir = $this->config->get('download_dir');
if (empty($downloaddir) || (is_dir($downloaddir) && !is_writable($downloaddir))) {
if (is_dir($downloaddir) && !is_writable($downloaddir)) {
$this->log(0, 'WARNING: configuration download directory "' . $downloaddir .
'" is not writeable. Change download_dir config variable to ' .
'a writeable dir to avoid this warning');
}
 
if (empty($downloaddir)) {
if (!class_exists('System')) {
require_once 'System.php';
}
 
if (PEAR::isError($downloaddir = System::mktemp('-d'))) {
return $downloaddir;
}
$this->log(3, '+ tmp dir created at ' . $downloaddir);
}
 
if (!is_writable($downloaddir)) {
if (PEAR::isError(System::mkdir(array('-p', $downloaddir))) ||
!is_writable($downloaddir)) {
if (PEAR::isError(System::mkdir(array('-p', $downloaddir)))) {
return PEAR::raiseError('download directory "' . $downloaddir .
'" is not writeable. Change download_dir config variable to ' .
'a writeable dir');
}
}
 
return $this->_downloadDir = $downloaddir;
}
 
function setDownloadDir($dir)
{
if (!@is_writable($dir)) {
if (PEAR::isError(System::mkdir(array('-p', $dir)))) {
return PEAR::raiseError('download directory "' . $dir .
'" is not writeable. Change download_dir config variable to ' .
'a writeable dir');
}
}
$this->_downloadDir = $dir;
}
 
// }}}
// {{{ configSet()
function configSet($key, $value, $layer = 'user', $channel = false)
{
$this->config->set($key, $value, $layer, $channel);
791,18 → 686,40
}
}
 
// }}}
// {{{ setOptions()
function setOptions($options)
{
$this->_options = $options;
}
 
// }}}
// {{{ setOptions()
function getOptions()
{
return $this->_options;
}
 
// }}}
 
/**
* For simpler unit-testing
* @param PEAR_Config
* @param int
* @param string
*/
function &getPackagefileObject(&$c, $d, $t = false)
{
if (!class_exists('PEAR_PackageFile')) {
require_once 'PEAR/PackageFile.php';
}
$a = &new PEAR_PackageFile($c, $d, $t);
return $a;
}
 
// {{{ _getPackageDownloadUrl()
 
/**
* @param array output of {@link parsePackageName()}
* @access private
*/
816,127 → 733,149
$state = isset($parr['state']) ? $parr['state'] : $this->config->get('preferred_state');
if (!$this->_registry->channelExists($parr['channel'])) {
do {
if ($this->config->get('auto_discover') && $this->discover($parr['channel'])) {
break;
if ($this->config->get('auto_discover')) {
if ($this->discover($parr['channel'])) {
break;
}
}
 
$this->configSet('default_channel', $curchannel);
return PEAR::raiseError('Unknown remote channel: ' . $parr['channel']);
return PEAR::raiseError('Unknown remote channel: ' . $remotechannel);
} while (false);
}
 
$chan = $this->_registry->getChannel($parr['channel']);
$chan = &$this->_registry->getChannel($parr['channel']);
if (PEAR::isError($chan)) {
return $chan;
}
 
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$version = $this->_registry->packageInfo($parr['package'], 'version', $parr['channel']);
$stability = $this->_registry->packageInfo($parr['package'], 'stability', $parr['channel']);
// package is installed - use the installed release stability level
if (!isset($parr['state']) && $stability !== null) {
$state = $stability['release'];
}
PEAR::staticPopErrorHandling();
$base2 = false;
 
$preferred_mirror = $this->config->get('preferred_mirror');
if (!$chan->supportsREST($preferred_mirror) ||
(
!($base2 = $chan->getBaseURL('REST1.3', $preferred_mirror))
&&
!($base = $chan->getBaseURL('REST1.0', $preferred_mirror))
)
) {
return $this->raiseError($parr['channel'] . ' is using a unsupported protocol - This should never happen.');
}
 
if ($base2) {
$rest = &$this->config->getREST('1.3', $this->_options);
$base = $base2;
$version = $this->_registry->packageInfo($parr['package'], 'version',
$parr['channel']);
if ($chan->supportsREST($this->config->get('preferred_mirror')) &&
$base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
$rest = &$this->config->getREST('1.0', $this->_options);
if (!isset($parr['version']) && !isset($parr['state']) && $version
&& !isset($this->_options['downloadonly'])) {
$url = $rest->getDownloadURL($base, $parr, $state, $version);
} else {
$url = $rest->getDownloadURL($base, $parr, $state, false);
}
if (PEAR::isError($url)) {
$this->configSet('default_channel', $curchannel);
return $url;
}
if ($parr['channel'] != $curchannel) {
$this->configSet('default_channel', $curchannel);
}
if (!is_array($url)) {
return $url;
}
$url['raw'] = false; // no checking is necessary for REST
if (!is_array($url['info'])) {
return PEAR::raiseError('Invalid remote dependencies retrieved from REST - ' .
'this should never happen');
}
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$testversion = $this->_registry->packageInfo($url['package'], 'version',
$parr['channel']);
PEAR::staticPopErrorHandling();
if (!isset($this->_options['force']) &&
!isset($this->_options['downloadonly']) &&
!PEAR::isError($testversion) &&
!isset($parr['group'])) {
if (version_compare($testversion, $url['version'], '>=')) {
return PEAR::raiseError($this->_registry->parsedPackageNameToString(
$parr, true) . ' is already installed and is newer than detected ' .
'release version ' . $url['version'], -976);
}
}
if (isset($url['info']['required']) || $url['compatible']) {
require_once 'PEAR/PackageFile/v2.php';
$pf = new PEAR_PackageFile_v2;
$pf->setRawChannel($parr['channel']);
if ($url['compatible']) {
$pf->setRawCompatible($url['compatible']);
}
} else {
require_once 'PEAR/PackageFile/v1.php';
$pf = new PEAR_PackageFile_v1;
}
$pf->setRawPackage($url['package']);
$pf->setDeps($url['info']);
if ($url['compatible']) {
$pf->setCompatible($url['compatible']);
}
$pf->setRawState($url['stability']);
$url['info'] = &$pf;
if (!extension_loaded("zlib") || isset($this->_options['nocompress'])) {
$ext = '.tar';
} else {
$ext = '.tgz';
}
if (is_array($url)) {
if (isset($url['url'])) {
$url['url'] .= $ext;
}
}
return $url;
} elseif ($chan->supports('xmlrpc', 'package.getDownloadURL', false, '1.1')) {
// don't install with the old version information unless we're doing a plain
// vanilla simple installation. If the user says to install a particular
// version or state, ignore the current installed version
if (!isset($parr['version']) && !isset($parr['state']) && $version
&& !isset($this->_options['downloadonly'])) {
$url = $this->_remote->call('package.getDownloadURL', $parr, $state, $version);
} else {
$url = $this->_remote->call('package.getDownloadURL', $parr, $state);
}
} else {
$rest = &$this->config->getREST('1.0', $this->_options);
$url = $this->_remote->call('package.getDownloadURL', $parr, $state);
}
 
$downloadVersion = false;
if (!isset($parr['version']) && !isset($parr['state']) && $version
&& !PEAR::isError($version)
&& !isset($this->_options['downloadonly'])
) {
$downloadVersion = $version;
}
 
$url = $rest->getDownloadURL($base, $parr, $state, $downloadVersion, $chan->getName());
if (PEAR::isError($url)) {
$this->configSet('default_channel', $curchannel);
return $url;
}
 
if ($parr['channel'] != $curchannel) {
$this->configSet('default_channel', $curchannel);
}
 
if (isset($url['__PEAR_ERROR_CLASS__'])) {
return PEAR::raiseError($url['message']);
}
if (!is_array($url)) {
return $url;
}
 
$url['raw'] = false; // no checking is necessary for REST
if (!is_array($url['info'])) {
return PEAR::raiseError('Invalid remote dependencies retrieved from REST - ' .
'this should never happen');
}
 
if (!isset($this->_options['force']) &&
!isset($this->_options['downloadonly']) &&
$version &&
!PEAR::isError($version) &&
!isset($parr['group'])
) {
if (version_compare($version, $url['version'], '=')) {
return PEAR::raiseError($this->_registry->parsedPackageNameToString(
$parr, true) . ' is already installed and is the same as the ' .
'released version ' . $url['version'], -976);
$url['raw'] = $url['info'];
if (isset($this->_options['downloadonly'])) {
$pkg = &$this->getPackagefileObject($this->config, $this->debug);
} else {
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
if (PEAR::isError($dir = $this->getDownloadDir())) {
PEAR::staticPopErrorHandling();
return $dir;
}
 
if (version_compare($version, $url['version'], '>')) {
return PEAR::raiseError($this->_registry->parsedPackageNameToString(
$parr, true) . ' is already installed and is newer than detected ' .
'released version ' . $url['version'], -976);
}
PEAR::staticPopErrorHandling();
$pkg = &$this->getPackagefileObject($this->config, $this->debug, $dir);
}
 
if (isset($url['info']['required']) || $url['compatible']) {
require_once 'PEAR/PackageFile/v2.php';
$pf = new PEAR_PackageFile_v2;
$pf->setRawChannel($parr['channel']);
if ($url['compatible']) {
$pf->setRawCompatible($url['compatible']);
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$pinfo = &$pkg->fromXmlString($url['info'], PEAR_VALIDATE_DOWNLOADING, 'remote');
PEAR::staticPopErrorHandling();
if (PEAR::isError($pinfo)) {
if (!isset($this->_options['soft'])) {
$this->log(0, $pinfo->getMessage());
}
} else {
require_once 'PEAR/PackageFile/v1.php';
$pf = new PEAR_PackageFile_v1;
return PEAR::raiseError('Remote package.xml is not valid - this should never happen');
}
 
$pf->setRawPackage($url['package']);
$pf->setDeps($url['info']);
if ($url['compatible']) {
$pf->setCompatible($url['compatible']);
}
 
$pf->setRawState($url['stability']);
$url['info'] = &$pf;
$url['info'] = &$pinfo;
if (!extension_loaded("zlib") || isset($this->_options['nocompress'])) {
$ext = '.tar';
} else {
$ext = '.tgz';
}
 
if (is_array($url) && isset($url['url'])) {
$url['url'] .= $ext;
if (is_array($url)) {
if (isset($url['url'])) {
$url['url'] .= $ext;
}
}
 
return $url;
}
// }}}
// {{{ getDepPackageDownloadUrl()
 
/**
* @param array dependency array
948,11 → 887,10
$curchannel = $this->config->get('default_channel');
if (isset($dep['uri'])) {
$xsdversion = '2.0';
$chan = $this->_registry->getChannel('__uri');
$chan = &$this->_registry->getChannel('__uri');
if (PEAR::isError($chan)) {
return $chan;
}
 
$version = $this->_registry->packageInfo($dep['name'], 'version', '__uri');
$this->configSet('default_channel', '__uri');
} else {
961,7 → 899,6
} else {
$remotechannel = 'pear.php.net';
}
 
if (!$this->_registry->channelExists($remotechannel)) {
do {
if ($this->config->get('auto_discover')) {
972,23 → 909,20
return PEAR::raiseError('Unknown remote channel: ' . $remotechannel);
} while (false);
}
 
$chan = $this->_registry->getChannel($remotechannel);
$chan = &$this->_registry->getChannel($remotechannel);
if (PEAR::isError($chan)) {
return $chan;
}
 
$version = $this->_registry->packageInfo($dep['name'], 'version', $remotechannel);
$version = $this->_registry->packageInfo($dep['name'], 'version',
$remotechannel);
$this->configSet('default_channel', $remotechannel);
}
 
$state = isset($parr['state']) ? $parr['state'] : $this->config->get('preferred_state');
if (isset($parr['state']) && isset($parr['version'])) {
unset($parr['state']);
}
 
if (isset($dep['uri'])) {
$info = $this->newDownloaderPackage($this);
$info = &$this->newDownloaderPackage($this);
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$err = $info->initialize($dep);
PEAR::staticPopErrorHandling();
996,12 → 930,10
// skip parameters that were missed by preferred_state
return PEAR::raiseError('Cannot initialize dependency');
}
 
if (PEAR::isError($err)) {
if (!isset($this->_options['soft'])) {
$this->log(0, $err->getMessage());
}
 
if (is_object($info)) {
$param = $info->getChannel() . '/' . $info->getPackage();
}
1008,41 → 940,25
return PEAR::raiseError('Package "' . $param . '" is not valid');
}
return $info;
} elseif ($chan->supportsREST($this->config->get('preferred_mirror'))
&&
(
($base2 = $chan->getBaseURL('REST1.3', $this->config->get('preferred_mirror')))
||
($base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror')))
)
) {
if ($base2) {
$base = $base2;
$rest = &$this->config->getREST('1.3', $this->_options);
} else {
$rest = &$this->config->getREST('1.0', $this->_options);
}
 
} elseif ($chan->supportsREST($this->config->get('preferred_mirror')) &&
$base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) {
$rest = &$this->config->getREST('1.0', $this->_options);
$url = $rest->getDepDownloadURL($base, $xsdversion, $dep, $parr,
$state, $version, $chan->getName());
$state, $version);
if (PEAR::isError($url)) {
return $url;
}
 
if ($parr['channel'] != $curchannel) {
$this->configSet('default_channel', $curchannel);
}
 
if (!is_array($url)) {
return $url;
}
 
$url['raw'] = false; // no checking is necessary for REST
if (!is_array($url['info'])) {
return PEAR::raiseError('Invalid remote dependencies retrieved from REST - ' .
'this should never happen');
}
 
if (isset($url['info']['required'])) {
if (!class_exists('PEAR_PackageFile_v2')) {
require_once 'PEAR/PackageFile/v2.php';
1054,7 → 970,6
require_once 'PEAR/PackageFile/v1.php';
}
$pf = new PEAR_PackageFile_v1;
 
}
$pf->setRawPackage($url['package']);
$pf->setDeps($url['info']);
1061,7 → 976,6
if ($url['compatible']) {
$pf->setCompatible($url['compatible']);
}
 
$pf->setRawState($url['stability']);
$url['info'] = &$pf;
if (!extension_loaded("zlib") || isset($this->_options['nocompress'])) {
1069,16 → 983,58
} else {
$ext = '.tgz';
}
 
if (is_array($url) && isset($url['url'])) {
$url['url'] .= $ext;
if (is_array($url)) {
if (isset($url['url'])) {
$url['url'] .= $ext;
}
}
 
return $url;
} elseif ($chan->supports('xmlrpc', 'package.getDepDownloadURL', false, '1.1')) {
if ($version) {
$url = $this->_remote->call('package.getDepDownloadURL', $xsdversion, $dep, $parr,
$state, $version);
} else {
$url = $this->_remote->call('package.getDepDownloadURL', $xsdversion, $dep, $parr,
$state);
}
} else {
$url = $this->_remote->call('package.getDepDownloadURL', $xsdversion, $dep, $parr, $state);
}
 
return $this->raiseError($parr['channel'] . ' is using a unsupported protocol - This should never happen.');
if ($this->config->get('default_channel') != $curchannel) {
$this->configSet('default_channel', $curchannel);
}
if (!is_array($url)) {
return $url;
}
if (isset($url['__PEAR_ERROR_CLASS__'])) {
return PEAR::raiseError($url['message']);
}
$url['raw'] = $url['info'];
$pkg = &$this->getPackagefileObject($this->config, $this->debug);
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$pinfo = &$pkg->fromXmlString($url['info'], PEAR_VALIDATE_DOWNLOADING, 'remote');
PEAR::staticPopErrorHandling();
if (PEAR::isError($pinfo)) {
if (!isset($this->_options['soft'])) {
$this->log(0, $pinfo->getMessage());
}
return PEAR::raiseError('Remote package.xml is not valid - this should never happen');
}
$url['info'] = &$pinfo;
if (is_array($url)) {
if (!extension_loaded("zlib") || isset($this->_options['nocompress'])) {
$ext = '.tar';
} else {
$ext = '.tgz';
}
if (isset($url['url'])) {
$url['url'] .= $ext;
}
}
return $url;
}
// }}}
// {{{ getPackageDownloadUrl()
 
/**
* @deprecated in favor of _getPackageDownloadUrl
1103,6 → 1059,9
return $package;
}
 
// }}}
// {{{ getDownloadedPackages()
 
/**
* Retrieve a list of downloaded packages after a call to {@link download()}.
*
1117,6 → 1076,9
return $ret;
}
 
// }}}
// {{{ _downloadCallback()
 
function _downloadCallback($msg, $params = null)
{
switch ($msg) {
1149,6 → 1111,9
$this->ui->_downloadCallback($msg, $params);
}
 
// }}}
// {{{ _prependPath($path, $prepend)
 
function _prependPath($path, $prepend)
{
if (strlen($prepend) > 0) {
1165,6 → 1130,8
}
return $path;
}
// }}}
// {{{ pushError($errmsg, $code)
 
/**
* @param string
1175,6 → 1142,9
array_push($this->_errorStack, array($errmsg, $code));
}
 
// }}}
// {{{ getErrorMsgs()
 
function getErrorMsgs()
{
$msgs = array();
1186,14 → 1156,14
return $msgs;
}
 
// }}}
 
/**
* for BC
*
* @deprecated
*/
function sortPkgDeps(&$packages, $uninstall = false)
{
$uninstall ?
$uninstall ?
$this->sortPackagesForUninstall($packages) :
$this->sortPackagesForInstall($packages);
}
1224,7 → 1194,6
$nodes[$pname]->setData($packages[$i]);
$depgraph->addNode($nodes[$pname]);
}
 
$deplinks = array();
foreach ($nodes as $package => $node) {
$pf = &$node->getData();
1232,7 → 1201,6
if (!$pdeps) {
continue;
}
 
if ($pf->getPackagexmlVersion() == '1.0') {
foreach ($pdeps as $dep) {
if ($dep['type'] != 'pkg' ||
1239,34 → 1207,30
(isset($dep['optional']) && $dep['optional'] == 'yes')) {
continue;
}
 
$dname = $reg->parsedPackageNameToString(
array(
'channel' => 'pear.php.net',
'package' => strtolower($dep['name']),
));
 
if (isset($nodes[$dname])) {
if (isset($nodes[$dname]))
{
if (!isset($deplinks[$dname])) {
$deplinks[$dname] = array();
}
 
$deplinks[$dname][$package] = 1;
// dependency is in installed packages
continue;
}
 
$dname = $reg->parsedPackageNameToString(
array(
'channel' => 'pecl.php.net',
'package' => strtolower($dep['name']),
));
 
if (isset($nodes[$dname])) {
if (isset($nodes[$dname]))
{
if (!isset($deplinks[$dname])) {
$deplinks[$dname] = array();
}
 
$deplinks[$dname][$package] = 1;
// dependency is in installed packages
continue;
1281,15 → 1245,12
if (!isset($t[0])) {
$t = array($t);
}
 
$this->_setupGraph($t, $reg, $deplinks, $nodes, $package);
}
 
if (isset($pdeps['group'])) {
if (!isset($pdeps['group'][0])) {
$pdeps['group'] = array($pdeps['group']);
}
 
foreach ($pdeps['group'] as $group) {
if (isset($group['subpackage'])) {
$t = $group['subpackage'];
1296,35 → 1257,28
if (!isset($t[0])) {
$t = array($t);
}
 
$this->_setupGraph($t, $reg, $deplinks, $nodes, $package);
}
}
}
 
if (isset($pdeps['optional']['subpackage'])) {
$t = $pdeps['optional']['subpackage'];
if (!isset($t[0])) {
$t = array($t);
}
 
$this->_setupGraph($t, $reg, $deplinks, $nodes, $package);
}
 
if (isset($pdeps['required']['package'])) {
$t = $pdeps['required']['package'];
if (!isset($t[0])) {
$t = array($t);
}
 
$this->_setupGraph($t, $reg, $deplinks, $nodes, $package);
}
 
if (isset($pdeps['group'])) {
if (!isset($pdeps['group'][0])) {
$pdeps['group'] = array($pdeps['group']);
}
 
foreach ($pdeps['group'] as $group) {
if (isset($group['package'])) {
$t = $group['package'];
1331,7 → 1285,6
if (!isset($t[0])) {
$t = array($t);
}
 
$this->_setupGraph($t, $reg, $deplinks, $nodes, $package);
}
}
1338,7 → 1291,6
}
}
}
 
$this->_detectDepCycle($deplinks);
foreach ($deplinks as $dependent => $parents) {
foreach ($parents as $parent => $unused) {
1345,10 → 1297,9
$nodes[$dependent]->connectTo($nodes[$parent]);
}
}
 
$installOrder = Structures_Graph_Manipulator_TopologicalSorter::sort($depgraph);
$ret = array();
for ($i = 0, $count = count($installOrder); $i < $count; $i++) {
for ($i = 0; $i < count($installOrder); $i++) {
foreach ($installOrder[$i] as $index => $sortedpackage) {
$data = &$installOrder[$i][$index]->getData();
$ret[] = &$nodes[$reg->parsedPackageNameToString(
1358,7 → 1309,6
))]->getData();
}
}
 
$packages = $ret;
return;
}
1383,7 → 1333,6
if (count($deplinks[$dep]) == 0) {
unset($deplinks[$dep]);
}
 
continue 3;
}
}
1398,23 → 1347,19
$visited = array();
return;
}
 
// this happens when a parent has a dep cycle on another dependency
// but the child is not part of the cycle
if (isset($visited[$dep])) {
return false;
}
 
$visited[$dep] = 1;
if ($test == $dep) {
return true;
}
 
if (isset($deplinks[$dep])) {
if (in_array($test, array_keys($deplinks[$dep]), true)) {
return true;
}
 
foreach ($deplinks[$dep] as $parent => $unused) {
if ($this->_testCycle($test, $deplinks, $parent)) {
return true;
1421,7 → 1366,6
}
}
}
 
return false;
}
 
1438,14 → 1382,15
function _setupGraph($t, $reg, &$deplinks, &$nodes, $package)
{
foreach ($t as $dep) {
$depchannel = !isset($dep['channel']) ? '__uri': $dep['channel'];
$depchannel = !isset($dep['channel']) ?
'__uri': $dep['channel'];
$dname = $reg->parsedPackageNameToString(
array(
'channel' => $depchannel,
'package' => strtolower($dep['name']),
));
 
if (isset($nodes[$dname])) {
if (isset($nodes[$dname]))
{
if (!isset($deplinks[$dname])) {
$deplinks[$dname] = array();
}
1456,7 → 1401,8
 
function _dependsOn($a, $b)
{
return $this->_checkDepTree(strtolower($a->getChannel()), strtolower($a->getPackage()), $b);
return $this->_checkDepTree(strtolower($a->getChannel()), strtolower($a->getPackage()),
$b);
}
 
function _checkDepTree($channel, $package, $b, $checked = array())
1465,12 → 1411,10
if (!isset($this->_depTree[$channel][$package])) {
return false;
}
 
if (isset($this->_depTree[$channel][$package][strtolower($b->getChannel())]
[strtolower($b->getPackage())])) {
return true;
}
 
foreach ($this->_depTree[$channel][$package] as $ch => $packages) {
foreach ($packages as $pa => $true) {
if ($this->_checkDepTree($ch, $pa, $b, $checked)) {
1478,7 → 1422,6
}
}
}
 
return false;
}
 
1541,51 → 1484,43
* @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
* @param false|string $channel Channel to use for retrieving authentication
* @return mixed Returns the full path 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.
* If $lastmodified was given and the there are no changes,
* boolean false is returned.
* @return string|array Returns the full path 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
*/
public static function _downloadHttp(
$object, $url, &$ui, $save_dir = '.', $callback = null, $lastmodified = null,
$accept = false, $channel = false
) {
function downloadHttp($url, &$ui, $save_dir = '.', $callback = null, $lastmodified = null,
$accept = false)
{
static $redirect = 0;
// always reset , so we are clean case of error
// allways reset , so we are clean case of error
$wasredirect = $redirect;
$redirect = 0;
if ($callback) {
call_user_func($callback, 'setup', array(&$ui));
}
 
$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 . '"');
} else {
$host = isset($info['host']) ? $info['host'] : null;
$port = isset($info['port']) ? $info['port'] : null;
$path = isset($info['path']) ? $info['path'] : null;
}
 
$host = isset($info['host']) ? $info['host'] : null;
$port = isset($info['port']) ? $info['port'] : null;
$path = isset($info['path']) ? $info['path'] : null;
 
if ($object !== null) {
$config = $object->config;
if (isset($this)) {
$config = &$this->config;
} else {
$config = &PEAR_Config::singleton();
}
 
$proxy_host = $proxy_port = $proxy_user = $proxy_pass = '';
if ($config->get('http_proxy') &&
if ($config->get('http_proxy') &&
$proxy = parse_url($config->get('http_proxy'))) {
$proxy_host = isset($proxy['host']) ? $proxy['host'] : null;
if (isset($proxy['scheme']) && $proxy['scheme'] == 'https') {
1599,13 → 1534,13
call_user_func($callback, 'message', "Using HTTP proxy $host:$port");
}
}
 
if (empty($port)) {
$port = (isset($info['scheme']) && $info['scheme'] == 'https') ? 443 : 80;
if (isset($info['scheme']) && $info['scheme'] == 'https') {
$port = 443;
} else {
$port = 80;
}
}
 
$scheme = (isset($info['scheme']) && $info['scheme'] == 'https') ? 'https' : 'http';
 
if ($proxy_host != '') {
$fp = @fsockopen($proxy_host, $proxy_port, $errno, $errstr);
if (!$fp) {
1615,21 → 1550,16
}
return PEAR::raiseError("Connection to `$proxy_host:$proxy_port' failed: $errstr", $errno);
}
 
if ($lastmodified === false || $lastmodified) {
$request = "GET $url HTTP/1.1\r\n";
$request .= "Host: $host\r\n";
$request = "GET $url HTTP/1.1\r\n";
} else {
$request = "GET $url HTTP/1.0\r\n";
$request .= "Host: $host\r\n";
$request = "GET $url HTTP/1.0\r\n";
}
} else {
$network_host = $host;
if (isset($info['scheme']) && $info['scheme'] == 'https') {
$network_host = 'ssl://' . $host;
$host = 'ssl://' . $host;
}
 
$fp = @fsockopen($network_host, $port, $errno, $errstr);
$fp = @fsockopen($host, $port, $errno, $errstr);
if (!$fp) {
if ($callback) {
call_user_func($callback, 'connfailed', array($host, $port,
1637,22 → 1567,19
}
return PEAR::raiseError("Connection to `$host:$port' failed: $errstr", $errno);
}
 
if ($lastmodified === false || $lastmodified) {
$request = "GET $path HTTP/1.1\r\n";
$request .= "Host: $host\r\n";
$request .= "Host: $host:$port\r\n";
} else {
$request = "GET $path HTTP/1.0\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";
}
1659,28 → 1586,23
} else {
$ifmodifiedsince = ($lastmodified ? "If-Modified-Since: $lastmodified\r\n" : '');
}
 
$request .= $ifmodifiedsince .
"User-Agent: PEAR/1.10.1/PHP/" . PHP_VERSION . "\r\n";
 
if ($object !== null) { // only pass in authentication for non-static calls
$username = $config->get('username', null, $channel);
$password = $config->get('password', null, $channel);
$request .= $ifmodifiedsince . "User-Agent: PEAR/1.5.1/PHP/" .
PHP_VERSION . "\r\n";
if (isset($this)) { // only pass in authentication for non-static calls
$username = $config->get('username');
$password = $config->get('password');
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 .= "Connection: close\r\n";
$request .= "\r\n";
fwrite($fp, $request);
1687,41 → 1609,37
$headers = array();
$reply = 0;
while (trim($line = fgets($fp, 1024))) {
if (preg_match('/^([^:]+):\s+(.*)\s*\\z/', $line, $matches)) {
if (preg_match('/^([^:]+):\s+(.*)\s*$/', $line, $matches)) {
$headers[strtolower($matches[1])] = trim($matches[2]);
} elseif (preg_match('|^HTTP/1.[01] ([0-9]{3}) |', $line, $matches)) {
$reply = (int)$matches[1];
$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 $scheme://$host:$port$path not valid (received: $line)");
if (! in_array($reply, array(200, 301, 302, 303, 305, 307))) {
return PEAR::raiseError("File http://$host:$port$path not valid (received: $line)");
}
}
}
 
if ($reply != 200) {
if (!isset($headers['location'])) {
return PEAR::raiseError("File $scheme://$host:$port$path not valid (redirected but no location)");
if (isset($headers['location'])) {
if ($wasredirect < 5) {
$redirect = $wasredirect + 1;
return $this->downloadHttp($headers['location'],
$ui, $save_dir, $callback, $lastmodified, $accept);
} else {
return PEAR::raiseError("File http://$host:$port$path not valid (redirection looped more than 5 times)");
}
} else {
return PEAR::raiseError("File http://$host:$port$path not valid (redirected but no location)");
}
 
if ($wasredirect > 4) {
return PEAR::raiseError("File $scheme://$host:$port$path not valid (redirection looped more than 5 times)");
}
 
$redirect = $wasredirect + 1;
return static::_downloadHttp($object, $headers['location'],
$ui, $save_dir, $callback, $lastmodified, $accept);
}
 
if (isset($headers['content-disposition']) &&
preg_match('/\sfilename=\"([^;]*\S)\"\s*(;|\\z)/', $headers['content-disposition'], $matches)) {
preg_match('/\sfilename=\"([^;]*\S)\"\s*(;|$)/', $headers['content-disposition'], $matches)) {
$save_as = basename($matches[1]);
} else {
$save_as = basename($url);
}
 
if ($callback) {
$tmp = call_user_func($callback, 'saveas', $save_as);
if ($tmp) {
1728,12 → 1646,7
$save_as = $tmp;
}
}
 
$dest_file = $save_dir . DIRECTORY_SEPARATOR . $save_as;
if (is_link($dest_file)) {
return PEAR::raiseError('SECURITY ERROR: Will not write to ' . $dest_file . ' as it is symlinked to ' . readlink($dest_file) . ' - Possible symlink attack');
}
 
if (!$wp = @fopen($dest_file, 'wb')) {
fclose($fp);
if ($callback) {
1741,14 → 1654,15
}
return PEAR::raiseError("could not open $dest_file for writing");
}
 
$length = isset($headers['content-length']) ? $headers['content-length'] : -1;
 
if (isset($headers['content-length'])) {
$length = $headers['content-length'];
} else {
$length = -1;
}
$bytes = 0;
if ($callback) {
call_user_func($callback, 'start', array(basename($dest_file), $length));
}
 
while ($data = fread($fp, 1024)) {
$bytes += strlen($data);
if ($callback) {
1762,18 → 1676,15
return PEAR::raiseError("$dest_file: write failed ($php_errormsg)");
}
}
 
fclose($fp);
fclose($wp);
if ($callback) {
call_user_func($callback, 'done', $bytes);
}
 
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'];
1786,3 → 1697,6
return $dest_file;
}
}
// }}}
 
?>
/trunk/bibliotheque/pear/PEAR/Autoloader.php
3,13 → 3,19
* Class auto-loader
*
* PHP versions 4
 
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Autoloader.php,v 1.13 2006/01/06 04:47:36 cellog Exp $
* @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
42,9 → 48,9
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @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
143,7 → 149,7
$include_file = preg_replace('/[^a-z0-9]/i', '_', $classname);
include_once $include_file;
}
$obj = new $classname;
$obj =& new $classname;
$methods = get_class_methods($classname);
foreach ($methods as $method) {
// don't import priviate methods and constructors
/trunk/bibliotheque/pear/PEAR/Dependency2.php
4,11 → 4,18
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Dependency2.php,v 1.54 2007/02/13 04:16:25 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
28,9 → 35,9
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
42,39 → 49,32
* @var integer
*/
var $_state;
 
/**
* Command-line options to install/upgrade/uninstall commands
* @param array
*/
var $_options;
 
/**
* @var OS_Guess
*/
var $_os;
 
/**
* @var PEAR_Registry
*/
var $_registry;
 
/**
* @var PEAR_Config
*/
var $_config;
 
/**
* @var PEAR_DependencyDB
*/
var $_dependencydb;
 
/**
* Output of PEAR_Registry::parsedPackageName()
* @var array
*/
var $_currentPackage;
 
/**
* @param PEAR_Config
* @param array installation options
81,7 → 81,7
* @param array format of PEAR_Registry::parsedPackageName()
* @param int installation state (one of PEAR_VALIDATE_*)
*/
function __construct(&$config, $installoptions, $package,
function PEAR_Dependency2(&$config, $installoptions, $package,
$state = PEAR_VALIDATE_INSTALLING)
{
$this->_config = &$config;
88,24 → 88,20
if (!class_exists('PEAR_DependencyDB')) {
require_once 'PEAR/DependencyDB.php';
}
 
if (isset($installoptions['packagingroot'])) {
// make sure depdb is in the right location
$config->setInstallRoot($installoptions['packagingroot']);
}
 
$this->_registry = &$config->getRegistry();
$this->_dependencydb = &PEAR_DependencyDB::singleton($config);
if (isset($installoptions['packagingroot'])) {
$config->setInstallRoot(false);
}
 
$this->_options = $installoptions;
$this->_state = $state;
if (!class_exists('OS_Guess')) {
require_once 'OS/Guess.php';
}
 
$this->_os = new OS_Guess;
$this->_currentPackage = $package;
}
116,7 → 112,6
if (isset($dep['uri'])) {
return '';
}
 
if (isset($dep['recommended'])) {
$extra .= 'recommended version ' . $dep['recommended'];
} else {
123,7 → 118,6
if (isset($dep['min'])) {
$extra .= 'version >= ' . $dep['min'];
}
 
if (isset($dep['max'])) {
if ($extra != ' (') {
$extra .= ', ';
130,16 → 124,13
}
$extra .= 'version <= ' . $dep['max'];
}
 
if (isset($dep['exclude'])) {
if (!is_array($dep['exclude'])) {
$dep['exclude'] = array($dep['exclude']);
}
 
if ($extra != ' (') {
$extra .= ', ';
}
 
$extra .= 'excluded versions: ';
foreach ($dep['exclude'] as $i => $exclude) {
if ($i) {
149,12 → 140,10
}
}
}
 
$extra .= ')';
if ($extra == ' ()') {
$extra = '';
}
 
return $extra;
}
 
182,32 → 171,37
*/
function validateOsDependency($dep)
{
if ($this->_state != PEAR_VALIDATE_INSTALLING && $this->_state != PEAR_VALIDATE_DOWNLOADING) {
if ($this->_state != PEAR_VALIDATE_INSTALLING &&
$this->_state != PEAR_VALIDATE_DOWNLOADING) {
return true;
}
 
if (isset($dep['conflicts'])) {
$not = true;
} else {
$not = false;
}
if ($dep['name'] == '*') {
return true;
}
 
$not = isset($dep['conflicts']) ? true : false;
switch (strtolower($dep['name'])) {
case 'windows' :
if ($not) {
if (strtolower(substr($this->getPHP_OS(), 0, 3)) == 'win') {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
if (!isset($this->_options['nodeps']) &&
!isset($this->_options['force'])) {
return $this->raiseError("Cannot install %s on Windows");
} else {
return $this->warning("warning: Cannot install %s on Windows");
}
 
return $this->warning("warning: Cannot install %s on Windows");
}
} else {
if (strtolower(substr($this->getPHP_OS(), 0, 3)) != 'win') {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
if (!isset($this->_options['nodeps']) &&
!isset($this->_options['force'])) {
return $this->raiseError("Can only install %s on Windows");
} else {
return $this->warning("warning: Can only install %s on Windows");
}
 
return $this->warning("warning: Can only install %s on Windows");
}
}
break;
215,19 → 209,23
$unices = array('linux', 'freebsd', 'darwin', 'sunos', 'irix', 'hpux', 'aix');
if ($not) {
if (in_array($this->getSysname(), $unices)) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
if (!isset($this->_options['nodeps']) &&
!isset($this->_options['force'])) {
return $this->raiseError("Cannot install %s on any Unix system");
} else {
return $this->warning(
"warning: Cannot install %s on any Unix system");
}
 
return $this->warning( "warning: Cannot install %s on any Unix system");
}
} else {
if (!in_array($this->getSysname(), $unices)) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
if (!isset($this->_options['nodeps']) &&
!isset($this->_options['force'])) {
return $this->raiseError("Can only install %s on a Unix system");
} else {
return $this->warning(
"warning: Can only install %s on a Unix system");
}
 
return $this->warning("warning: Can only install %s on a Unix system");
}
}
break;
238,22 → 236,23
!isset($this->_options['force'])) {
return $this->raiseError('Cannot install %s on ' . $dep['name'] .
' operating system');
} else {
return $this->warning('warning: Cannot install %s on ' .
$dep['name'] . ' operating system');
}
 
return $this->warning('warning: Cannot install %s on ' .
$dep['name'] . ' operating system');
}
} else {
if (strtolower($dep['name']) != strtolower($this->getSysname())) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
if (!isset($this->_options['nodeps']) &&
!isset($this->_options['force'])) {
return $this->raiseError('Cannot install %s on ' .
$this->getSysname() .
' operating system, can only install on ' . $dep['name']);
} else {
return $this->warning('warning: Cannot install %s on ' .
$this->getSysname() .
' operating system, can only install on ' . $dep['name']);
}
 
return $this->warning('warning: Cannot install %s on ' .
$this->getSysname() .
' operating system, can only install on ' . $dep['name']);
}
}
}
280,33 → 279,34
if ($this->_state != PEAR_VALIDATE_INSTALLING) {
return true;
}
 
$not = isset($dep['conflicts']) ? true : false;
if (isset($dep['conflicts'])) {
$not = true;
} else {
$not = false;
}
if (!$this->matchSignature($dep['pattern'])) {
if (!$not) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s Architecture dependency failed, does not ' .
'match "' . $dep['pattern'] . '"');
} else {
return $this->warning('warning: %s Architecture dependency failed, does ' .
'not match "' . $dep['pattern'] . '"');
}
 
return $this->warning('warning: %s Architecture dependency failed, does ' .
'not match "' . $dep['pattern'] . '"');
}
 
return true;
}
 
if ($not) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s Architecture dependency failed, required "' .
$dep['pattern'] . '"');
} else {
if ($not) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s Architecture dependency failed, required "' .
$dep['pattern'] . '"');
} else {
return $this->warning('warning: %s Architecture dependency failed, ' .
'required "' . $dep['pattern'] . '"');
}
}
 
return $this->warning('warning: %s Architecture dependency failed, ' .
'required "' . $dep['pattern'] . '"');
return true;
}
 
return true;
}
 
/**
324,9 → 324,9
{
if ($name !== null) {
return phpversion($name);
} else {
return phpversion();
}
 
return phpversion();
}
 
function validateExtensionDependency($dep, $required = true)
335,101 → 335,92
$this->_state != PEAR_VALIDATE_DOWNLOADING) {
return true;
}
 
$loaded = $this->extension_loaded($dep['name']);
$extra = $this->_getExtraString($dep);
$extra = $this->_getExtraString($dep);
if (isset($dep['exclude'])) {
if (!is_array($dep['exclude'])) {
$dep['exclude'] = array($dep['exclude']);
}
}
 
if (!isset($dep['min']) && !isset($dep['max']) &&
!isset($dep['recommended']) && !isset($dep['exclude'])
) {
!isset($dep['recommended']) && !isset($dep['exclude'])) {
if ($loaded) {
if (isset($dep['conflicts'])) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s conflicts with PHP extension "' .
$dep['name'] . '"' . $extra);
} else {
return $this->warning('warning: %s conflicts with PHP extension "' .
$dep['name'] . '"' . $extra);
}
 
return $this->warning('warning: %s conflicts with PHP extension "' .
$dep['name'] . '"' . $extra);
}
 
return true;
}
 
if (isset($dep['conflicts'])) {
return true;
}
 
if ($required) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s requires PHP extension "' .
} else {
if (isset($dep['conflicts'])) {
return true;
}
if ($required) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s requires PHP extension "' .
$dep['name'] . '"' . $extra);
} else {
return $this->warning('warning: %s requires PHP extension "' .
$dep['name'] . '"' . $extra);
}
} else {
return $this->warning('%s can optionally use PHP extension "' .
$dep['name'] . '"' . $extra);
}
 
return $this->warning('warning: %s requires PHP extension "' .
$dep['name'] . '"' . $extra);
}
 
return $this->warning('%s can optionally use PHP extension "' .
$dep['name'] . '"' . $extra);
}
 
if (!$loaded) {
if (isset($dep['conflicts'])) {
return true;
}
 
if (!$required) {
return $this->warning('%s can optionally use PHP extension "' .
$dep['name'] . '"' . $extra);
} else {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s requires PHP extension "' . $dep['name'] .
'"' . $extra);
}
return $this->warning('warning: %s requires PHP extension "' . $dep['name'] .
'"' . $extra);
}
 
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s requires PHP extension "' . $dep['name'] .
'"' . $extra);
}
 
return $this->warning('warning: %s requires PHP extension "' . $dep['name'] .
'"' . $extra);
}
 
$version = (string) $this->phpversion($dep['name']);
if (empty($version)) {
$version = '0';
}
 
$fail = false;
if (isset($dep['min']) && !version_compare($version, $dep['min'], '>=')) {
$fail = true;
if (isset($dep['min'])) {
if (!version_compare($version, $dep['min'], '>=')) {
$fail = true;
}
}
 
if (isset($dep['max']) && !version_compare($version, $dep['max'], '<=')) {
$fail = true;
if (isset($dep['max'])) {
if (!version_compare($version, $dep['max'], '<=')) {
$fail = true;
}
}
 
if ($fail && !isset($dep['conflicts'])) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s requires PHP extension "' . $dep['name'] .
'"' . $extra . ', installed version is ' . $version);
} else {
return $this->warning('warning: %s requires PHP extension "' . $dep['name'] .
'"' . $extra . ', installed version is ' . $version);
}
 
return $this->warning('warning: %s requires PHP extension "' . $dep['name'] .
'"' . $extra . ', installed version is ' . $version);
} elseif ((isset($dep['min']) || isset($dep['max'])) && !$fail && isset($dep['conflicts'])) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s conflicts with PHP extension "' .
$dep['name'] . '"' . $extra . ', installed version is ' . $version);
} else {
return $this->warning('warning: %s conflicts with PHP extension "' .
$dep['name'] . '"' . $extra . ', installed version is ' . $version);
}
 
return $this->warning('warning: %s conflicts with PHP extension "' .
$dep['name'] . '"' . $extra . ', installed version is ' . $version);
}
 
if (isset($dep['exclude'])) {
foreach ($dep['exclude'] as $exclude) {
if (version_compare($version, $exclude, '==')) {
436,45 → 427,43
if (isset($dep['conflicts'])) {
continue;
}
 
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
if (!isset($this->_options['nodeps']) &&
!isset($this->_options['force'])) {
return $this->raiseError('%s is not compatible with PHP extension "' .
$dep['name'] . '" version ' .
$exclude);
} else {
return $this->warning('warning: %s is not compatible with PHP extension "' .
$dep['name'] . '" version ' .
$exclude);
}
 
return $this->warning('warning: %s is not compatible with PHP extension "' .
$dep['name'] . '" version ' .
$exclude);
} elseif (version_compare($version, $exclude, '!=') && isset($dep['conflicts'])) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s conflicts with PHP extension "' .
$dep['name'] . '"' . $extra . ', installed version is ' . $version);
} else {
return $this->warning('warning: %s conflicts with PHP extension "' .
$dep['name'] . '"' . $extra . ', installed version is ' . $version);
}
 
return $this->warning('warning: %s conflicts with PHP extension "' .
$dep['name'] . '"' . $extra . ', installed version is ' . $version);
}
}
}
 
if (isset($dep['recommended'])) {
if (version_compare($version, $dep['recommended'], '==')) {
return true;
} else {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s dependency: PHP extension ' . $dep['name'] .
' version "' . $version . '"' .
' is not the recommended version "' . $dep['recommended'] .
'", but may be compatible, use --force to install');
} else {
return $this->warning('warning: %s dependency: PHP extension ' .
$dep['name'] . ' version "' . $version . '"' .
' is not the recommended version "' . $dep['recommended'].'"');
}
}
 
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s dependency: PHP extension ' . $dep['name'] .
' version "' . $version . '"' .
' is not the recommended version "' . $dep['recommended'] .
'", but may be compatible, use --force to install');
}
 
return $this->warning('warning: %s dependency: PHP extension ' .
$dep['name'] . ' version "' . $version . '"' .
' is not the recommended version "' . $dep['recommended'].'"');
}
 
return true;
}
 
484,54 → 473,50
$this->_state != PEAR_VALIDATE_DOWNLOADING) {
return true;
}
 
$version = $this->phpversion();
$extra = $this->_getExtraString($dep);
$extra = $this->_getExtraString($dep);
if (isset($dep['exclude'])) {
if (!is_array($dep['exclude'])) {
$dep['exclude'] = array($dep['exclude']);
}
}
 
if (isset($dep['min'])) {
if (!version_compare($version, $dep['min'], '>=')) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s requires PHP' .
$extra . ', installed version is ' . $version);
} else {
return $this->warning('warning: %s requires PHP' .
$extra . ', installed version is ' . $version);
}
 
return $this->warning('warning: %s requires PHP' .
$extra . ', installed version is ' . $version);
}
}
 
if (isset($dep['max'])) {
if (!version_compare($version, $dep['max'], '<=')) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s requires PHP' .
$extra . ', installed version is ' . $version);
} else {
return $this->warning('warning: %s requires PHP' .
$extra . ', installed version is ' . $version);
}
 
return $this->warning('warning: %s requires PHP' .
$extra . ', installed version is ' . $version);
}
}
 
if (isset($dep['exclude'])) {
foreach ($dep['exclude'] as $exclude) {
if (version_compare($version, $exclude, '==')) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
if (!isset($this->_options['nodeps']) &&
!isset($this->_options['force'])) {
return $this->raiseError('%s is not compatible with PHP version ' .
$exclude);
} else {
return $this->warning(
'warning: %s is not compatible with PHP version ' .
$exclude);
}
 
return $this->warning(
'warning: %s is not compatible with PHP version ' .
$exclude);
}
}
}
 
return true;
}
 
540,7 → 525,7
*/
function getPEARVersion()
{
return '1.10.1';
return '1.5.1';
}
 
function validatePearinstallerDependency($dep)
552,47 → 537,42
$dep['exclude'] = array($dep['exclude']);
}
}
 
if (version_compare($pearversion, $dep['min'], '<')) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s requires PEAR Installer' . $extra .
', installed version is ' . $pearversion);
} else {
return $this->warning('warning: %s requires PEAR Installer' . $extra .
', installed version is ' . $pearversion);
}
 
return $this->warning('warning: %s requires PEAR Installer' . $extra .
', installed version is ' . $pearversion);
}
 
if (isset($dep['max'])) {
if (version_compare($pearversion, $dep['max'], '>')) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s requires PEAR Installer' . $extra .
', installed version is ' . $pearversion);
} else {
return $this->warning('warning: %s requires PEAR Installer' . $extra .
', installed version is ' . $pearversion);
}
 
return $this->warning('warning: %s requires PEAR Installer' . $extra .
', installed version is ' . $pearversion);
}
}
 
if (isset($dep['exclude'])) {
if (!isset($dep['exclude'][0])) {
$dep['exclude'] = array($dep['exclude']);
}
 
foreach ($dep['exclude'] as $exclude) {
if (version_compare($exclude, $pearversion, '==')) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s is not compatible with PEAR Installer ' .
'version ' . $exclude);
} else {
return $this->warning('warning: %s is not compatible with PEAR ' .
'Installer version ' . $exclude);
}
 
return $this->warning('warning: %s is not compatible with PEAR ' .
'Installer version ' . $exclude);
}
}
}
 
return true;
}
 
606,7 → 586,7
* @param boolean whether this is a required dependency
* @param array a list of downloaded packages to be installed, if any
* @param boolean if true, then deps on pear.php.net that fail will also check
* against pecl.php.net packages to accommodate extensions that have
* against pecl.php.net packages to accomodate extensions that have
* moved to pecl.php.net from pear.php.net
*/
function validatePackageDependency($dep, $required, $params, $depv1 = false)
615,7 → 595,6
$this->_state != PEAR_VALIDATE_DOWNLOADING) {
return true;
}
 
if (isset($dep['providesextension'])) {
if ($this->extension_loaded($dep['providesextension'])) {
$save = $dep;
629,11 → 608,9
}
}
}
 
if ($this->_state == PEAR_VALIDATE_INSTALLING) {
return $this->_validatePackageInstall($dep, $required, $depv1);
}
 
if ($this->_state == PEAR_VALIDATE_DOWNLOADING) {
return $this->_validatePackageDownload($dep, $required, $params, $depv1);
}
645,7 → 622,6
if (isset($dep['uri'])) {
$dep['channel'] = '__uri';
}
 
$depname = $this->_registry->parsedPackageNameToString($dep, true);
$found = false;
foreach ($params as $param) {
655,7 → 631,6
$found = true;
break;
}
 
if ($depv1 && $dep['channel'] == 'pear.php.net') {
if ($param->isEqual(
array('package' => $dep['name'],
665,7 → 640,6
}
}
}
 
if (!$found && isset($dep['providesextension'])) {
foreach ($params as $param) {
if ($param->isExtension($dep['providesextension'])) {
674,7 → 648,6
}
}
}
 
if ($found) {
$version = $param->getVersion();
$installed = false;
699,73 → 672,77
}
}
}
 
$extra = $this->_getExtraString($dep);
if (isset($dep['exclude']) && !is_array($dep['exclude'])) {
$dep['exclude'] = array($dep['exclude']);
if (isset($dep['exclude'])) {
if (!is_array($dep['exclude'])) {
$dep['exclude'] = array($dep['exclude']);
}
}
 
if (!isset($dep['min']) && !isset($dep['max']) &&
!isset($dep['recommended']) && !isset($dep['exclude'])
) {
!isset($dep['recommended']) && !isset($dep['exclude'])) {
if ($installed || $downloaded) {
$installed = $installed ? 'installed' : 'downloaded';
if (isset($dep['conflicts'])) {
$rest = '';
if ($version) {
$rest = ", $installed version is " . $version;
} else {
$rest = '';
}
 
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s conflicts with package "' . $depname . '"' . $extra . $rest);
return $this->raiseError('%s conflicts with package "' . $depname . '"' .
$extra . $rest);
} else {
return $this->warning('warning: %s conflicts with package "' . $depname . '"' .
$extra . $rest);
}
 
return $this->warning('warning: %s conflicts with package "' . $depname . '"' . $extra . $rest);
}
 
return true;
}
 
if (isset($dep['conflicts'])) {
return true;
}
 
if ($required) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s requires package "' . $depname . '"' . $extra);
} else {
if (isset($dep['conflicts'])) {
return true;
}
 
return $this->warning('warning: %s requires package "' . $depname . '"' . $extra);
if ($required) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s requires package "' . $depname . '"' .
$extra);
} else {
return $this->warning('warning: %s requires package "' . $depname . '"' .
$extra);
}
} else {
return $this->warning('%s can optionally use package "' . $depname . '"' .
$extra);
}
}
 
return $this->warning('%s can optionally use package "' . $depname . '"' . $extra);
}
 
if (!$installed && !$downloaded) {
if (isset($dep['conflicts'])) {
return true;
}
 
if ($required) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s requires package "' . $depname . '"' . $extra);
return $this->raiseError('%s requires package "' . $depname . '"' .
$extra);
} else {
return $this->warning('warning: %s requires package "' . $depname . '"' .
$extra);
}
 
return $this->warning('warning: %s requires package "' . $depname . '"' . $extra);
} else {
return $this->warning('%s can optionally use package "' . $depname . '"' .
$extra);
}
 
return $this->warning('%s can optionally use package "' . $depname . '"' . $extra);
}
 
$fail = false;
if (isset($dep['min']) && version_compare($version, $dep['min'], '<')) {
$fail = true;
if (isset($dep['min'])) {
if (version_compare($version, $dep['min'], '<')) {
$fail = true;
}
}
 
if (isset($dep['max']) && version_compare($version, $dep['max'], '>')) {
$fail = true;
if (isset($dep['max'])) {
if (version_compare($version, $dep['max'], '>')) {
$fail = true;
}
}
 
if ($fail && !isset($dep['conflicts'])) {
$installed = $installed ? 'installed' : 'downloaded';
$dep['package'] = $dep['name'];
773,10 → 750,10
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s requires package "' . $depname . '"' .
$extra . ", $installed version is " . $version);
} else {
return $this->warning('warning: %s requires package "' . $depname . '"' .
$extra . ", $installed version is " . $version);
}
 
return $this->warning('warning: %s requires package "' . $depname . '"' .
$extra . ", $installed version is " . $version);
} elseif ((isset($dep['min']) || isset($dep['max'])) && !$fail &&
isset($dep['conflicts']) && !isset($dep['exclude'])) {
$installed = $installed ? 'installed' : 'downloaded';
783,88 → 760,82
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s conflicts with package "' . $depname . '"' . $extra .
", $installed version is " . $version);
} else {
return $this->warning('warning: %s conflicts with package "' . $depname . '"' .
$extra . ", $installed version is " . $version);
}
 
return $this->warning('warning: %s conflicts with package "' . $depname . '"' .
$extra . ", $installed version is " . $version);
}
 
if (isset($dep['exclude'])) {
$installed = $installed ? 'installed' : 'downloaded';
foreach ($dep['exclude'] as $exclude) {
if (version_compare($version, $exclude, '==') && !isset($dep['conflicts'])) {
if (!isset($this->_options['nodeps']) &&
!isset($this->_options['force'])
) {
!isset($this->_options['force'])) {
return $this->raiseError('%s is not compatible with ' .
$installed . ' package "' .
$depname . '" version ' .
$exclude);
} else {
return $this->warning('warning: %s is not compatible with ' .
$installed . ' package "' .
$depname . '" version ' .
$exclude);
}
 
return $this->warning('warning: %s is not compatible with ' .
$installed . ' package "' .
$depname . '" version ' .
$exclude);
} elseif (version_compare($version, $exclude, '!=') && isset($dep['conflicts'])) {
$installed = $installed ? 'installed' : 'downloaded';
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('%s conflicts with package "' . $depname . '"' .
$extra . ", $installed version is " . $version);
} else {
return $this->warning('warning: %s conflicts with package "' . $depname . '"' .
$extra . ", $installed version is " . $version);
}
 
return $this->warning('warning: %s conflicts with package "' . $depname . '"' .
$extra . ", $installed version is " . $version);
}
}
}
 
if (isset($dep['recommended'])) {
$installed = $installed ? 'installed' : 'downloaded';
if (version_compare($version, $dep['recommended'], '==')) {
return true;
}
 
if (!$found && $installed) {
$param = $this->_registry->getPackage($dep['name'], $dep['channel']);
}
 
if ($param) {
$found = false;
foreach ($params as $parent) {
if ($parent->isEqual($this->_currentPackage)) {
$found = true;
break;
}
} else {
if (!$found && $installed) {
$param = $this->_registry->getPackage($dep['name'], $dep['channel']);
}
 
if ($found) {
if ($param->isCompatible($parent)) {
return true;
if ($param) {
$found = false;
foreach ($params as $parent) {
if ($parent->isEqual($this->_currentPackage)) {
$found = true;
break;
}
}
} else { // this is for validPackage() calls
$parent = $this->_registry->getPackage($this->_currentPackage['package'],
$this->_currentPackage['channel']);
if ($parent !== null && $param->isCompatible($parent)) {
return true;
if ($found) {
if ($param->isCompatible($parent)) {
return true;
}
} else { // this is for validPackage() calls
$parent = $this->_registry->getPackage($this->_currentPackage['package'],
$this->_currentPackage['channel']);
if ($parent !== null) {
if ($param->isCompatible($parent)) {
return true;
}
}
}
}
if (!isset($this->_options['nodeps']) && !isset($this->_options['force']) &&
!isset($this->_options['loose'])) {
return $this->raiseError('%s dependency package "' . $depname .
'" ' . $installed . ' version ' . $version .
' is not the recommended version ' . $dep['recommended'] .
', but may be compatible, use --force to install');
} else {
return $this->warning('warning: %s dependency package "' . $depname .
'" ' . $installed . ' version ' . $version .
' is not the recommended version ' . $dep['recommended']);
}
}
 
if (!isset($this->_options['nodeps']) && !isset($this->_options['force']) &&
!isset($this->_options['loose'])
) {
return $this->raiseError('%s dependency package "' . $depname .
'" ' . $installed . ' version ' . $version .
' is not the recommended version ' . $dep['recommended'] .
', but may be compatible, use --force to install');
}
 
return $this->warning('warning: %s dependency package "' . $depname .
'" ' . $installed . ' version ' . $version .
' is not the recommended version ' . $dep['recommended']);
}
 
return true;
}
 
884,7 → 855,6
if (PEAR::isError($this->_dependencydb)) {
return $this->_dependencydb;
}
 
$params = array();
// construct an array of "downloaded" packages to fool the package dependency checker
// into using these to validate uninstalls of circular dependencies
893,11 → 863,10
if (!class_exists('PEAR_Downloader_Package')) {
require_once 'PEAR/Downloader/Package.php';
}
$dp = new PEAR_Downloader_Package($dl);
$dp = &new PEAR_Downloader_Package($dl);
$dp->setPackageFile($downloaded[$i]);
$params[$i] = $dp;
$params[$i] = &$dp;
}
 
// check cache
$memyselfandI = strtolower($this->_currentPackage['channel']) . '/' .
strtolower($this->_currentPackage['package']);
908,38 → 877,27
$dl->log(0, $warning[0]);
}
}
 
if (isset($badpackages[$memyselfandI]['errors'])) {
foreach ($badpackages[$memyselfandI]['errors'] as $error) {
if (is_array($error)) {
$dl->log(0, $error[0]);
} else {
$dl->log(0, $error->getMessage());
}
$dl->log(0, $error->getMessage());
}
 
if (isset($this->_options['nodeps']) || isset($this->_options['force'])) {
return $this->warning(
'warning: %s should not be uninstalled, other installed packages depend ' .
'on this package');
} else {
return $this->raiseError(
'%s cannot be uninstalled, other installed packages depend on this package');
}
 
return $this->raiseError(
'%s cannot be uninstalled, other installed packages depend on this package');
}
 
return true;
}
 
// first, list the immediate parents of each package to be uninstalled
$perpackagelist = array();
$allparents = array();
foreach ($params as $i => $param) {
$a = array(
'channel' => strtolower($param->getChannel()),
'package' => strtolower($param->getPackage())
);
 
$a = array('channel' => strtolower($param->getChannel()),
'package' => strtolower($param->getPackage()));
$deps = $this->_dependencydb->getDependentPackages($a);
if ($deps) {
foreach ($deps as $d) {
966,7 → 924,6
}
}
}
 
// next, remove any packages from the parents list that are not installed
$remove = array();
foreach ($allparents as $parent => $d1) {
977,7 → 934,6
$remove[$parent] = true;
}
}
 
// next remove any packages from the parents list that are not passed in for
// uninstallation
foreach ($allparents as $parent => $d1) {
992,7 → 948,6
$remove[$parent] = true;
}
}
 
// remove all packages whose dependencies fail
// save which ones failed for error reporting
$badchildren = array();
1002,7 → 957,6
if (!isset($allparents[$package])) {
continue;
}
 
foreach ($allparents[$package] as $kid => $d1) {
foreach ($d1 as $depinfo) {
if ($depinfo[1]['type'] != 'optional') {
1022,7 → 976,6
}
}
} while ($fail);
 
// next, construct the list of packages that can't be uninstalled
$badpackages = array();
$save = $this->_currentPackage;
1031,7 → 984,6
if (!isset($remove[$parent[0]])) {
continue;
}
 
$packagename = $this->_registry->parsePackageName($parent[0]);
$packagename['channel'] = $this->_registry->channelAlias($packagename['channel']);
$pa = $this->_registry->getPackage($packagename['package'], $packagename['channel']);
1057,8 → 1009,7
}
}
}
 
$this->_currentPackage = $save;
$this->_currentPackage = $save;
$dl->___uninstall_package_cache = $badpackages;
if (isset($badpackages[$memyselfandI])) {
if (isset($badpackages[$memyselfandI]['warnings'])) {
1066,27 → 1017,20
$dl->log(0, $warning[0]);
}
}
 
if (isset($badpackages[$memyselfandI]['errors'])) {
foreach ($badpackages[$memyselfandI]['errors'] as $error) {
if (is_array($error)) {
$dl->log(0, $error[0]);
} else {
$dl->log(0, $error->getMessage());
}
$dl->log(0, $error->getMessage());
}
 
if (isset($this->_options['nodeps']) || isset($this->_options['force'])) {
return $this->warning(
'warning: %s should not be uninstalled, other installed packages depend ' .
'on this package');
} else {
return $this->raiseError(
'%s cannot be uninstalled, other installed packages depend on this package');
}
 
return $this->raiseError(
'%s cannot be uninstalled, other installed packages depend on this package');
}
}
 
return true;
}
 
1093,63 → 1037,65
function _validatePackageUninstall($dep, $required, $dl)
{
$depname = $this->_registry->parsedPackageNameToString($dep, true);
$version = $this->_registry->packageinfo($dep['package'], 'version', $dep['channel']);
$version = $this->_registry->packageinfo($dep['package'], 'version',
$dep['channel']);
if (!$version) {
return true;
}
 
$extra = $this->_getExtraString($dep);
if (isset($dep['exclude']) && !is_array($dep['exclude'])) {
$dep['exclude'] = array($dep['exclude']);
if (isset($dep['exclude'])) {
if (!is_array($dep['exclude'])) {
$dep['exclude'] = array($dep['exclude']);
}
}
 
if (isset($dep['conflicts'])) {
return true; // uninstall OK - these packages conflict (probably installed with --force)
}
 
if (!isset($dep['min']) && !isset($dep['max'])) {
if (!$required) {
if ($required) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('"' . $depname . '" is required by ' .
'installed package %s' . $extra);
} else {
return $this->warning('warning: "' . $depname . '" is required by ' .
'installed package %s' . $extra);
}
} else {
return $this->warning('"' . $depname . '" can be optionally used by ' .
'installed package %s' . $extra);
}
 
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError('"' . $depname . '" is required by ' .
'installed package %s' . $extra);
}
 
return $this->warning('warning: "' . $depname . '" is required by ' .
'installed package %s' . $extra);
}
 
$fail = false;
if (isset($dep['min']) && version_compare($version, $dep['min'], '>=')) {
$fail = true;
if (isset($dep['min'])) {
if (version_compare($version, $dep['min'], '>=')) {
$fail = true;
}
}
 
if (isset($dep['max']) && version_compare($version, $dep['max'], '<=')) {
$fail = true;
if (isset($dep['max'])) {
if (version_compare($version, $dep['max'], '<=')) {
$fail = true;
}
}
 
// we re-use this variable, preserve the original value
$saverequired = $required;
if (!$required) {
if ($required) {
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError($depname . $extra . ' is required by installed package' .
' "%s"');
} else {
return $this->raiseError('warning: ' . $depname . $extra .
' is required by installed package "%s"');
}
} else {
return $this->warning($depname . $extra . ' can be optionally used by installed package' .
' "%s"');
}
 
if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) {
return $this->raiseError($depname . $extra . ' is required by installed package' .
' "%s"');
}
 
return $this->raiseError('warning: ' . $depname . $extra .
' is required by installed package "%s"');
return true;
}
 
/**
* validate a downloaded package against installed packages
*
*
* As of PEAR 1.4.3, this will only validate
*
* @param array|PEAR_Downloader_Package|PEAR_PackageFile_v1|PEAR_PackageFile_v2
1167,20 → 1113,17
} else {
$deps = $this->_dependencydb->getDependentPackageDependencies($pkg);
}
 
$fail = false;
if ($deps) {
if (!class_exists('PEAR_Downloader_Package')) {
require_once 'PEAR/Downloader/Package.php';
}
 
$dp = new PEAR_Downloader_Package($dl);
$dp = &new PEAR_Downloader_Package($dl);
if (is_object($pkg)) {
$dp->setPackageFile($pkg);
} else {
$dp->setDownloadURL($pkg);
}
 
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
foreach ($deps as $channel => $info) {
foreach ($info as $package => $ds) {
1196,9 → 1139,8
continue 2; // jump to next package
}
}
 
foreach ($ds as $d) {
$checker = new PEAR_Dependency2($this->_config, $this->_options,
$checker = &new PEAR_Dependency2($this->_config, $this->_options,
array('channel' => $channel, 'package' => $package), $this->_state);
$dep = $d['dep'];
$required = $d['type'] == 'required';
1214,12 → 1156,10
}
PEAR::popErrorHandling();
}
 
if ($fail) {
return $this->raiseError(
'%s cannot be installed, conflicts with installed packages');
}
 
return true;
}
 
1231,12 → 1171,10
if (!isset($dep['optional'])) {
$dep['optional'] = 'no';
}
 
list($newdep, $type) = $this->normalizeDep($dep);
if (!$newdep) {
return $this->raiseError("Invalid Dependency");
}
 
if (method_exists($this, "validate{$type}Dependency")) {
return $this->{"validate{$type}Dependency"}($newdep, $dep['optional'] == 'no',
$params, true);
1254,13 → 1192,11
'os' => 'Os',
'php' => 'Php'
);
 
if (!isset($types[$dep['type']])) {
if (isset($types[$dep['type']])) {
$type = $types[$dep['type']];
} else {
return array(false, false);
}
 
$type = $types[$dep['type']];
 
$newdep = array();
switch ($type) {
case 'Package' :
1270,7 → 1206,6
$newdep['name'] = $dep['name'];
break;
}
 
$dep['rel'] = PEAR_Dependency2::signOperator($dep['rel']);
switch ($dep['rel']) {
case 'has' :
1306,9 → 1241,8
}
if ($type == 'Php') {
if (!isset($newdep['min'])) {
$newdep['min'] = '4.4.0';
$newdep['min'] = '4.2.0';
}
 
if (!isset($newdep['max'])) {
$newdep['max'] = '6.0.0';
}
1344,7 → 1278,6
if (isset($this->_options['ignore-errors'])) {
return $this->warning($msg);
}
 
return PEAR::raiseError(sprintf($msg, $this->_registry->parsedPackageNameToString(
$this->_currentPackage, true)));
}
1355,3 → 1288,4
$this->_currentPackage, true)));
}
}
?>
/trunk/bibliotheque/pear/PEAR/RunTest.php
4,12 → 4,19
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: RunTest.php,v 1.34 2007/02/17 19:57:56 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.3.3
*/
35,37 → 42,28
* @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 Release: 1.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.3.3
*/
class PEAR_RunTest
{
var $_headers = array();
var $_logger;
var $_options;
var $_php;
var $tests_count;
var $xdebug_loaded;
/**
* Saved value of php executable, used to reset $_php when we
* have a test that uses cgi
*
* @var unknown_type
*/
var $_savephp;
var $ini_overwrites = array(
'output_handler=',
'open_basedir=',
'safe_mode=0',
'disable_functions=',
'output_buffering=Off',
'error_reporting=E_ALL',
'display_errors=1',
'log_errors=0',
'html_errors=0',
'track_errors=1',
'report_memleaks=0',
'report_memleaks=1',
'report_zend_debug=0',
'docref_root=',
'docref_ext=.html',
73,32 → 71,22
'error_append_string=',
'auto_prepend_file=',
'auto_append_file=',
'xdebug.default_enable=0',
'allow_url_fopen=1',
'magic_quotes_runtime=0',
);
 
 
/**
* An object that supports the PEAR_Common->log() signature, or null
* @param PEAR_Common|null
*/
function __construct($logger = null, $options = array())
function PEAR_RunTest($logger = null, $options = array())
{
if (!defined('E_DEPRECATED')) {
define('E_DEPRECATED', 0);
}
if (!defined('E_STRICT')) {
define('E_STRICT', 0);
}
$this->ini_overwrites[] = 'error_reporting=' . (E_ALL & ~(E_DEPRECATED | E_STRICT));
if (is_null($logger)) {
require_once 'PEAR/Common.php';
$logger = new PEAR_Common;
}
$this->_logger = $logger;
$this->_logger = $logger;
$this->_options = $options;
 
$conf = &PEAR_Config::singleton();
$this->_php = $conf->get('php_bin');
}
 
/**
112,27 → 100,37
function system_with_timeout($commandline, $env = null, $stdin = null)
{
$data = '';
$proc = proc_open($commandline, array(
0 => array('pipe', 'r'),
1 => array('pipe', 'w'),
2 => array('pipe', 'w')
), $pipes, null, $env, array('suppress_errors' => true));
 
if (version_compare(phpversion(), '5.0.0', '<')) {
$proc = proc_open($commandline, array(
0 => array('pipe', 'r'),
1 => array('pipe', 'w'),
2 => array('pipe', 'w')
), $pipes);
} else {
$proc = proc_open($commandline, array(
0 => array('pipe', 'r'),
1 => array('pipe', 'w'),
2 => array('pipe', 'w')
), $pipes, null, $env, array("suppress_errors" => true));
}
if (!$proc) {
return false;
}
 
if (is_string($stdin)) {
fwrite($pipes[0], $stdin);
}
fclose($pipes[0]);
 
while (true) {
/* hide errors from interrupted syscalls */
$r = $pipes;
$e = $w = null;
$w = null;
$e = null;
$n = @stream_select($r, $w, $e, 60);
 
if ($n === 0) {
/* timed out */
$data .= "\n ** ERROR: process timed out **\n";
160,40 → 158,12
return array($code, $data);
}
 
/**
* Turns a PHP INI string into an array
*
* Turns -d "include_path=/foo/bar" into this:
* array(
* 'include_path' => array(
* 'operator' => '-d',
* 'value' => '/foo/bar',
* )
* )
* Works both with quotes and without
*
* @param string an PHP INI string, -d "include_path=/foo/bar"
* @return array
*/
function iniString2array($ini_string)
{
if (!$ini_string) {
return array();
}
$split = preg_split('/[\s]|=/', $ini_string, -1, PREG_SPLIT_NO_EMPTY);
$key = $split[1][0] == '"' ? substr($split[1], 1) : $split[1];
$value = $split[2][strlen($split[2]) - 1] == '"' ? substr($split[2], 0, -1) : $split[2];
// FIXME review if this is really the struct to go with
$array = array($key => array('operator' => $split[0], 'value' => $value));
return $array;
}
 
function settings2array($settings, $ini_settings)
{
foreach ($settings as $setting) {
if (strpos($setting, '=') !== false) {
$setting = explode('=', $setting, 2);
$name = trim(strtolower($setting[0]));
if (strpos($setting, '=')!==false) {
$setting = explode("=", $setting, 2);
$name = trim(strtolower($setting[0]));
$value = trim($setting[1]);
$ini_settings[$name] = $value;
}
200,122 → 170,107
}
return $ini_settings;
}
 
function settings2params($ini_settings)
{
$settings = '';
foreach ($ini_settings as $name => $value) {
if (is_array($value)) {
$operator = $value['operator'];
$value = $value['value'];
} else {
$operator = '-d';
}
$value = addslashes($value);
$settings .= " $operator \"$name=$value\"";
$settings .= " -d \"$name=$value\"";
}
return $settings;
}
 
function _preparePhpBin($php, $file, $ini_settings)
{
$file = escapeshellarg($file);
$cmd = $php . $ini_settings . ' -f ' . $file;
//
// Run an individual test case.
//
 
return $cmd;
}
 
function runPHPUnit($file, $ini_settings = '')
function run($file, $ini_settings = '')
{
if (!file_exists($file) && file_exists(getcwd() . DIRECTORY_SEPARATOR . $file)) {
$file = realpath(getcwd() . DIRECTORY_SEPARATOR . $file);
} elseif (file_exists($file)) {
$file = realpath($file);
$cwd = getcwd();
$conf = &PEAR_Config::singleton();
$php = $conf->get('php_bin');
if (isset($this->_options['phpunit'])) {
$cmd = "$php$ini_settings -f $file";
if (isset($this->_logger)) {
$this->_logger->log(2, 'Running command "' . $cmd . '"');
}
$savedir = getcwd(); // in case the test moves us around
chdir(dirname($file));
echo `$cmd`;
chdir($savedir);
return 'PASSED'; // we have no way of knowing this information so assume passing
}
 
$cmd = $this->_preparePhpBin($this->_php, $file, $ini_settings);
if (isset($this->_logger)) {
$this->_logger->log(2, 'Running command "' . $cmd . '"');
$pass_options = '';
if (!empty($this->_options['ini'])) {
$pass_options = $this->_options['ini'];
}
 
$savedir = getcwd(); // in case the test moves us around
chdir(dirname($file));
echo `$cmd`;
chdir($savedir);
return 'PASSED'; // we have no way of knowing this information so assume passing
}
$info_params = '';
$log_format = 'LEOD';
 
/**
* Runs an individual test case.
*
* @param string The filename of the test
* @param array|string INI settings to be applied to the test run
* @param integer Number what the current running test is of the
* whole test suite being runned.
*
* @return string|object Returns PASSED, WARNED, FAILED depending on how the
* test came out.
* PEAR Error when the tester it self fails
*/
function run($file, $ini_settings = array(), $test_number = 1)
{
$this->_restorePHPBinary();
// Load the sections of the test file.
$section_text = array(
'TEST' => '(unnamed test)',
'SKIPIF' => '',
'GET' => '',
'COOKIE' => '',
'POST' => '',
'ARGS' => '',
'INI' => '',
'CLEAN' => '',
);
 
if (empty($this->_options['cgi'])) {
// try to see if php-cgi is in the path
$res = $this->system_with_timeout('php-cgi -v');
if (false !== $res && !(is_array($res) && in_array($res[0], array(-1, 127)))) {
$this->_options['cgi'] = 'php-cgi';
}
}
if (1 < $len = strlen($this->tests_count)) {
$test_number = str_pad($test_number, $len, ' ', STR_PAD_LEFT);
$test_nr = "[$test_number/$this->tests_count] ";
} else {
$test_nr = '';
}
 
$file = realpath($file);
$section_text = $this->_readFile($file);
if (PEAR::isError($section_text)) {
return $section_text;
if (!is_file($file) || !$fp = fopen($file, "r")) {
return PEAR::raiseError("Cannot open test file: $file");
}
 
if (isset($section_text['POST_RAW']) && isset($section_text['UPLOAD'])) {
return PEAR::raiseError("Cannot contain both POST_RAW and UPLOAD in test file: $file");
}
$section = '';
while (!feof($fp)) {
$line = fgets($fp);
 
$cwd = getcwd();
// Match the beginning of a section.
if (preg_match('/^--([_A-Z]+)--/', $line, $r)) {
$section = $r[1];
$section_text[$section] = '';
continue;
} elseif (empty($section)) {
fclose($fp);
return PEAR::raiseError("Invalid sections formats in test file: $file");
}
 
$pass_options = '';
if (!empty($this->_options['ini'])) {
$pass_options = $this->_options['ini'];
// Add to the section text.
$section_text[$section] .= $line;
}
fclose($fp);
 
if (is_string($ini_settings)) {
$ini_settings = $this->iniString2array($ini_settings);
if (isset($section_text['POST_RAW']) && isset($section_text['UPLOAD'])) {
return PEAR::raiseError("Cannot contain both POST_RAW and UPLOAD in test file: $file");
}
 
$ini_settings = array();
$ini_settings = $this->settings2array($this->ini_overwrites, $ini_settings);
if ($section_text['INI']) {
if (strpos($section_text['INI'], '{PWD}') !== false) {
$section_text['INI'] = str_replace('{PWD}', dirname($file), $section_text['INI']);
}
$ini = preg_split( "/[\n\r]+/", $section_text['INI']);
$ini_settings = $this->settings2array($ini, $ini_settings);
$ini_settings = $this->settings2array(preg_split( "/[\n\r]+/",
$section_text['INI']), $ini_settings);
}
$ini_settings = $this->settings2params($ini_settings);
$shortname = str_replace($cwd . DIRECTORY_SEPARATOR, '', $file);
 
$tested = trim($section_text['TEST']);
$tested.= !isset($this->_options['simple']) ? "[$shortname]" : ' ';
 
if (!empty($section_text['POST']) || !empty($section_text['POST_RAW']) ||
!empty($section_text['UPLOAD']) || !empty($section_text['GET']) ||
!empty($section_text['COOKIE']) || !empty($section_text['EXPECTHEADERS'])) {
if (!isset($this->_options['simple'])) {
$tested = trim($section_text['TEST']) . "[$shortname]";
} else {
$tested = trim($section_text['TEST']) . ' ';
}
if (!empty($section_text['GET']) || !empty($section_text['POST']) ||
!empty($section_text['POST_RAW']) || !empty($section_text['COOKIE']) ||
!empty($section_text['UPLOAD'])) {
if (empty($this->_options['cgi'])) {
if (!isset($this->_options['quiet'])) {
$this->_logger->log(0, "SKIP $test_nr$tested (reason: --cgi option needed for this test, type 'pear help run-tests')");
$this->_logger->log(0, "SKIP $tested (reason: --cgi option needed for this test, type 'pear help run-tests')");
}
if (isset($this->_options['tapoutput'])) {
return array('ok', ' # skip --cgi option needed for this test, "pear help run-tests" for info');
322,107 → 277,169
}
return 'SKIPPED';
}
$this->_savePHPBinary();
$this->_php = $this->_options['cgi'];
$php = $this->_options['cgi'];
}
 
$temp_dir = realpath(dirname($file));
$main_file_name = basename($file, 'phpt');
$diff_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'diff';
$log_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'log';
$exp_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'exp';
$output_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'out';
$memcheck_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'mem';
$temp_file = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'php';
$temp_skipif = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'skip.php';
$temp_clean = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'clean.php';
$tmp_post = $temp_dir . DIRECTORY_SEPARATOR . uniqid('phpt.');
$temp_dir = $test_dir = realpath(dirname($file));
$main_file_name = basename($file,'phpt');
$diff_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'diff';
$log_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'log';
$exp_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'exp';
$output_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'out';
$memcheck_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'mem';
$temp_file = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'php';
$test_file = $test_dir . DIRECTORY_SEPARATOR . $main_file_name.'php';
$temp_skipif = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'skip.php';
$test_skipif = $test_dir . DIRECTORY_SEPARATOR . $main_file_name.'skip.php';
$temp_clean = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'clean.php';
$test_clean = $test_dir . DIRECTORY_SEPARATOR . $main_file_name.'clean.php';
$tmp_post = $temp_dir . DIRECTORY_SEPARATOR . uniqid('phpt.');
 
// unlink old test results
$this->_cleanupOldFiles($file);
// unlink old test results
@unlink($diff_filename);
@unlink($log_filename);
@unlink($exp_filename);
@unlink($output_filename);
@unlink($memcheck_filename);
@unlink($temp_file);
@unlink($test_file);
@unlink($temp_skipif);
@unlink($test_skipif);
@unlink($tmp_post);
@unlink($temp_clean);
@unlink($test_clean);
 
// Check if test should be skipped.
$res = $this->_runSkipIf($section_text, $temp_skipif, $tested, $ini_settings);
if (count($res) != 2) {
return $res;
$info = '';
$warn = false;
if (array_key_exists('SKIPIF', $section_text)) {
if (trim($section_text['SKIPIF'])) {
$this->save_text($temp_skipif, $section_text['SKIPIF']);
$output = $this->system_with_timeout("$php $info_params -f $temp_skipif");
$output = $output[1];
unlink($temp_skipif);
if (!strncasecmp('skip', ltrim($output), 4)) {
$skipreason = "SKIP $tested";
if (preg_match('/^\s*skip\s*(.+)\s*/i', $output, $m)) {
$skipreason .= '(reason: ' . $m[1] . ')';
}
if (!isset($this->_options['quiet'])) {
$this->_logger->log(0, $skipreason);
}
if (isset($this->_options['tapoutput'])) {
return array('ok', ' # skip ' . $reason);
}
return 'SKIPPED';
}
if (!strncasecmp('info', ltrim($output), 4)) {
if (preg_match('/^\s*info\s*(.+)\s*/i', $output, $m)) {
$info = " (info: $m[1])";
}
}
if (!strncasecmp('warn', ltrim($output), 4)) {
if (preg_match('/^\s*warn\s*(.+)\s*/i', $output, $m)) {
$warn = true; /* only if there is a reason */
$info = " (warn: $m[1])";
}
}
}
}
$info = $res['info'];
$warn = $res['warn'];
 
// We've satisfied the preconditions - run the test!
if (isset($this->_options['coverage']) && $this->xdebug_loaded) {
$xdebug_file = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'xdebug';
$text = "\n" . 'function coverage_shutdown() {' .
"\n" . ' $xdebug = var_export(xdebug_get_code_coverage(), true);';
if (!function_exists('file_put_contents')) {
$text .= "\n" . ' $fh = fopen(\'' . $xdebug_file . '\', "wb");' .
"\n" . ' if ($fh !== false) {' .
"\n" . ' fwrite($fh, $xdebug);' .
"\n" . ' fclose($fh);' .
"\n" . ' }';
} else {
$text .= "\n" . ' file_put_contents(\'' . $xdebug_file . '\', $xdebug);';
}
$this->save_text($temp_file,$section_text['FILE']);
 
// Workaround for http://pear.php.net/bugs/bug.php?id=17292
$lines = explode("\n", $section_text['FILE']);
$numLines = count($lines);
$namespace = '';
$coverage_shutdown = 'coverage_shutdown';
$args = $section_text['ARGS'] ? ' -- '.$section_text['ARGS'] : '';
 
if (
substr($lines[0], 0, 2) == '<?' ||
substr($lines[0], 0, 5) == '<?php'
) {
unset($lines[0]);
}
$cmd = "$php$ini_settings -f $temp_file$args 2>&1";
if (isset($this->_logger)) {
$this->_logger->log(2, 'Running command "' . $cmd . '"');
}
 
 
for ($i = 0; $i < $numLines; $i++) {
if (isset($lines[$i]) && substr($lines[$i], 0, 9) == 'namespace') {
$namespace = substr($lines[$i], 10, -1);
$coverage_shutdown = $namespace . '\\coverage_shutdown';
$namespace = "namespace " . $namespace . ";\n";
 
unset($lines[$i]);
break;
$savedir = getcwd(); // in case the test moves us around
// Reset environment from any previous test.
$env = $_ENV;
$env['REDIRECT_STATUS']='';
$env['QUERY_STRING']='';
$env['PATH_TRANSLATED']='';
$env['SCRIPT_FILENAME']='';
$env['REQUEST_METHOD']='';
$env['CONTENT_TYPE']='';
$env['CONTENT_LENGTH']='';
if (!empty($section_text['ENV'])) {
foreach(explode("\n", trim($section_text['ENV'])) as $e) {
$e = explode('=',trim($e),2);
if (!empty($e[0]) && isset($e[1])) {
$env[$e[0]] = $e[1];
}
}
 
$text .= "\n xdebug_stop_code_coverage();" .
"\n" . '} // end coverage_shutdown()' .
"\n\n" . 'register_shutdown_function("' . $coverage_shutdown . '");';
$text .= "\n" . 'xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE);' . "\n";
 
$this->save_text($temp_file, "<?php\n" . $namespace . $text . "\n" . implode("\n", $lines));
}
if (array_key_exists('GET', $section_text)) {
$query_string = trim($section_text['GET']);
} else {
$this->save_text($temp_file, $section_text['FILE']);
$query_string = '';
}
 
$args = $section_text['ARGS'] ? ' -- '.$section_text['ARGS'] : '';
$cmd = $this->_preparePhpBin($this->_php, $temp_file, $ini_settings);
$cmd.= "$args 2>&1";
if (isset($this->_logger)) {
$this->_logger->log(2, 'Running command "' . $cmd . '"');
if (array_key_exists('COOKIE', $section_text)) {
$env['HTTP_COOKIE'] = trim($section_text['COOKIE']);
} else {
$env['HTTP_COOKIE'] = '';
}
$env['REDIRECT_STATUS'] = '1';
$env['QUERY_STRING'] = $query_string;
$env['PATH_TRANSLATED'] = $test_file;
$env['SCRIPT_FILENAME'] = $test_file;
if (array_key_exists('UPLOAD', $section_text) && !empty($section_text['UPLOAD'])) {
$upload_files = trim($section_text['UPLOAD']);
$upload_files = explode("\n", $upload_files);
 
// Reset environment from any previous test.
$env = $this->_resetEnv($section_text, $temp_file);
 
$section_text = $this->_processUpload($section_text, $file);
if (PEAR::isError($section_text)) {
return $section_text;
$request = "Content-Type: multipart/form-data; boundary=---------------------------20896060251896012921717172737\n" .
"-----------------------------20896060251896012921717172737\n";
foreach ($upload_files as $fileinfo) {
$fileinfo = explode('=', $fileinfo);
if (count($fileinfo) != 2) {
return PEAR::raiseError("Invalid UPLOAD section in test file: $file");
}
if (!realpath(dirname($file) . '/' . $fileinfo[1])) {
return PEAR::raiseError("File for upload does not exist: $fileinfo[1] " .
"in test file: $file");
}
$file_contents = file_get_contents(dirname($file) . '/' . $fileinfo[1]);
$fileinfo[1] = basename($fileinfo[1]);
$request .= "Content-Disposition: form-data; name=\"$fileinfo[0]\"; filename=\"$fileinfo[1]\"\n";
$request .= "Content-Type: text/plain\n\n";
$request .= $file_contents . "\n" .
"-----------------------------20896060251896012921717172737\n";
}
if (array_key_exists('POST', $section_text) && !empty($section_text['POST'])) {
// encode POST raw
$post = trim($section_text['POST']);
$post = explode('&', $post);
foreach ($post as $i => $post_info) {
$post_info = explode('=', $post_info);
if (count($post_info) != 2) {
return PEAR::raiseError("Invalid POST data in test file: $file");
}
$post_info[0] = rawurldecode($post_info[0]);
$post_info[1] = rawurldecode($post_info[1]);
$post[$i] = $post_info;
}
foreach ($post as $post_info) {
$request .= "Content-Disposition: form-data; name=\"$post_info[0]\"\n\n";
$request .= $post_info[1] . "\n" .
"-----------------------------20896060251896012921717172737\n";
}
unset($section_text['POST']);
}
$section_text['POST_RAW'] = $request;
}
 
if (array_key_exists('POST_RAW', $section_text) && !empty($section_text['POST_RAW'])) {
$post = trim($section_text['POST_RAW']);
$raw_lines = explode("\n", $post);
 
$request = '';
$started = false;
foreach ($raw_lines as $i => $line) {
if (empty($env['CONTENT_TYPE']) &&
preg_match('/^Content-Type:(.*)/i', $line, $res)) {
preg_match('/^Content-Type:(.*)/i', $line, $res)) {
$env['CONTENT_TYPE'] = trim(str_replace("\r", '', $res[1]));
continue;
}
432,28 → 449,32
$started = true;
$request .= $line;
}
 
$env['CONTENT_LENGTH'] = strlen($request);
$env['REQUEST_METHOD'] = 'POST';
 
$this->save_text($tmp_post, $request);
$cmd = "$this->_php$pass_options$ini_settings \"$temp_file\" 2>&1 < $tmp_post";
$cmd = "$php$pass_options$ini_settings -f \"$test_file\" 2>&1 < $tmp_post";
} elseif (array_key_exists('POST', $section_text) && !empty($section_text['POST'])) {
$post = trim($section_text['POST']);
$this->save_text($tmp_post, $post);
$content_length = strlen($post);
 
$env['REQUEST_METHOD'] = 'POST';
$env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
$env['CONTENT_LENGTH'] = $content_length;
 
$cmd = "$this->_php$pass_options$ini_settings \"$temp_file\" 2>&1 < $tmp_post";
$cmd = "$php$pass_options$ini_settings -f \"$test_file\" 2>&1 < $tmp_post";
} else {
$env['REQUEST_METHOD'] = 'GET';
$env['CONTENT_TYPE'] = '';
$env['CONTENT_LENGTH'] = '';
$cmd = "$php$pass_options$ini_settings -f \"$test_file\" $args 2>&1";
}
 
if (OS_WINDOWS && isset($section_text['RETURNS'])) {
ob_start();
system($cmd, $return_value);
463,43 → 484,43
$returnfail = ($return_value != $section_text['RETURNS']);
} else {
$returnfail = false;
$stdin = isset($section_text['STDIN']) ? $section_text['STDIN'] : null;
$out = $this->system_with_timeout($cmd, $env, $stdin);
$out = $this->system_with_timeout($cmd, $env,
isset($section_text['STDIN']) ? $section_text['STDIN'] : null);
$return_value = $out[0];
$out = $out[1];
}
if (isset($tmp_post) && realpath($tmp_post)) {
unlink(realpath($tmp_post));
}
chdir($savedir);
 
$output = preg_replace('/\r\n/', "\n", trim($out));
 
if (isset($tmp_post) && realpath($tmp_post) && file_exists($tmp_post)) {
@unlink(realpath($tmp_post));
if ($section_text['CLEAN']) {
// perform test cleanup
$this->save_text($temp_clean, $section_text['CLEAN']);
$this->system_with_timeout("$php $temp_clean");
if (file_exists($temp_clean)) {
unlink($temp_clean);
}
}
chdir($cwd); // in case the test moves us around
// Does the output match what is expected?
$output = trim($out);
$output = preg_replace('/\r\n/', "\n", $output);
 
/* when using CGI, strip the headers from the output */
$output = $this->_stripHeadersCGI($output);
 
if (isset($section_text['EXPECTHEADERS'])) {
$testheaders = $this->_processHeaders($section_text['EXPECTHEADERS']);
$missing = array_diff_assoc($testheaders, $this->_headers);
$changed = '';
foreach ($missing as $header => $value) {
if (isset($this->_headers[$header])) {
$changed .= "-$header: $value\n+$header: ";
$changed .= $this->_headers[$header];
} else {
$changed .= "-$header: $value\n";
$headers = "";
if (!empty($this->_options['cgi']) &&
preg_match("/^(.*?)\r?\n\r?\n(.*)/s", $out, $match)) {
$output = trim($match[2]);
$rh = preg_split("/[\n\r]+/",$match[1]);
$headers = array();
foreach ($rh as $line) {
if (strpos($line, ':')!==false) {
$line = explode(':', $line, 2);
$headers[trim($line[0])] = trim($line[1]);
}
}
if ($missing) {
// tack on failed headers to output:
$output .= "\n====EXPECTHEADERS FAILURE====:\n$changed";
}
}
 
$this->_testCleanup($section_text, $temp_clean);
 
// Does the output match what is expected?
do {
if (isset($section_text['EXPECTF']) || isset($section_text['EXPECTREGEX'])) {
if (isset($section_text['EXPECTF'])) {
507,7 → 528,7
} else {
$wanted = trim($section_text['EXPECTREGEX']);
}
$wanted_re = preg_replace('/\r\n/', "\n", $wanted);
$wanted_re = preg_replace('/\r\n/',"\n",$wanted);
if (isset($section_text['EXPECTF'])) {
$wanted_re = preg_quote($wanted_re, '/');
// Stick to basics
519,7 → 540,6
$wanted_re = str_replace("%c", ".", $wanted_re);
// %f allows two points "-.0.0" but that is the best *simple* expression
}
 
/* DEBUG YOUR REGEX HERE
var_dump($wanted_re);
print(str_repeat('=', 80) . "\n");
529,36 → 549,28
if (file_exists($temp_file)) {
unlink($temp_file);
}
 
if (array_key_exists('FAIL', $section_text)) {
break;
}
if (!isset($this->_options['quiet'])) {
$this->_logger->log(0, "PASS $test_nr$tested$info");
$this->_logger->log(0, "PASS $tested$info");
}
if (isset($old_php)) {
$php = $old_php;
}
if (isset($this->_options['tapoutput'])) {
return array('ok', ' - ' . $tested);
}
return 'PASSED';
}
 
} else {
if (isset($section_text['EXPECTFILE'])) {
$f = $temp_dir . '/' . trim($section_text['EXPECTFILE']);
if (!($fp = @fopen($f, 'rb'))) {
return PEAR::raiseError('--EXPECTFILE-- section file ' .
$f . ' not found');
}
fclose($fp);
$section_text['EXPECT'] = file_get_contents($f);
}
 
if (isset($section_text['EXPECT'])) {
$wanted = preg_replace('/\r\n/', "\n", trim($section_text['EXPECT']));
} else {
$wanted = '';
}
 
// compare and leave on success
if (!$returnfail && 0 == strcmp($output, $wanted)) {
$wanted = trim($section_text['EXPECT']);
$wanted = preg_replace('/\r\n/',"\n",$wanted);
// compare and leave on success
$ok = (0 == strcmp($output,$wanted));
if (!$returnfail && $ok) {
if (file_exists($temp_file)) {
unlink($temp_file);
}
566,8 → 578,11
break;
}
if (!isset($this->_options['quiet'])) {
$this->_logger->log(0, "PASS $test_nr$tested$info");
$this->_logger->log(0, "PASS $tested$info");
}
if (isset($old_php)) {
$php = $old_php;
}
if (isset($this->_options['tapoutput'])) {
return array('ok', ' - ' . $tested);
}
579,14 → 594,20
if (array_key_exists('FAIL', $section_text)) {
// we expect a particular failure
// this is only used for testing PEAR_RunTest
$expectf = isset($section_text['EXPECTF']) ? $wanted_re : null;
$faildiff = $this->generate_diff($wanted, $output, null, $expectf);
$faildiff = $this->generate_diff(
$wanted,
$output,
null,
isset($section_text['EXPECTF']) ? $wanted_re : null);
$wanted = preg_replace('/\r/', '', trim($section_text['FAIL']));
$faildiff = preg_replace('/\r/', '', $faildiff);
$wanted = preg_replace('/\r/', '', trim($section_text['FAIL']));
if ($faildiff == $wanted) {
if (!isset($this->_options['quiet'])) {
$this->_logger->log(0, "PASS $test_nr$tested$info");
$this->_logger->log(0, "PASS $tested$info");
}
if (isset($old_php)) {
$php = $old_php;
}
if (isset($this->_options['tapoutput'])) {
return array('ok', ' - ' . $tested);
}
601,57 → 622,94
}
 
// Test failed so we need to report details.
$txt = $warn ? 'WARN ' : 'FAIL ';
$this->_logger->log(0, $txt . $test_nr . $tested . $info);
if ($warn) {
$this->_logger->log(0, "WARN $tested$info");
} else {
$this->_logger->log(0, "FAIL $tested$info");
}
 
if (isset($section_text['RETURNS'])) {
$GLOBALS['__PHP_FAILED_TESTS__'][] = array(
'name' => $file,
'test_name' => $tested,
'output' => $log_filename,
'diff' => $diff_filename,
'info' => $info,
'return' => $return_value
);
} else {
$GLOBALS['__PHP_FAILED_TESTS__'][] = array(
'name' => $file,
'test_name' => $tested,
'output' => $output_filename,
'diff' => $diff_filename,
'info' => $info,
);
}
 
// write .exp
$res = $this->_writeLog($exp_filename, $wanted);
if (PEAR::isError($res)) {
return $res;
if (strpos($log_format,'E') !== FALSE) {
$logname = $exp_filename;
if (!$log = fopen($logname,'w')) {
return PEAR::raiseError("Cannot create test log - $logname");
}
fwrite($log,$wanted);
fclose($log);
}
 
// write .out
$res = $this->_writeLog($output_filename, $output);
if (PEAR::isError($res)) {
return $res;
if (strpos($log_format,'O') !== FALSE) {
$logname = $output_filename;
if (!$log = fopen($logname,'w')) {
return PEAR::raiseError("Cannot create test log - $logname");
}
fwrite($log,$output);
fclose($log);
}
 
// write .diff
$returns = isset($section_text['RETURNS']) ?
array(trim($section_text['RETURNS']), $return_value) : null;
$expectf = isset($section_text['EXPECTF']) ? $wanted_re : null;
$data = $this->generate_diff($wanted, $output, $returns, $expectf);
$res = $this->_writeLog($diff_filename, $data);
if (isset($this->_options['showdiff'])) {
$this->_logger->log(0, "========DIFF========");
$this->_logger->log(0, $data);
$this->_logger->log(0, "========DONE========");
if (strpos($log_format,'D') !== FALSE) {
$logname = $diff_filename;
if (!$log = fopen($logname,'w')) {
return PEAR::raiseError("Cannot create test log - $logname");
}
fwrite($log, $this->generate_diff(
$wanted,
$output,
isset($section_text['RETURNS']) ?
array(trim($section_text['RETURNS']), $return_value) : null,
isset($section_text['EXPECTF']) ? $wanted_re : null)
);
fclose($log);
}
if (PEAR::isError($res)) {
return $res;
}
 
// write .log
$data = "
if (strpos($log_format,'L') !== FALSE) {
$logname = $log_filename;
if (!$log = fopen($logname,'w')) {
return PEAR::raiseError("Cannot create test log - $logname");
}
fwrite($log,"
---- EXPECTED OUTPUT
$wanted
---- ACTUAL OUTPUT
$output
---- FAILED
";
 
if ($returnfail) {
$data .= "
");
if ($returnfail) {
fwrite($log,"
---- EXPECTED RETURN
$section_text[RETURNS]
---- ACTUAL RETURN
$return_value
";
");
}
fclose($log);
//error_report($file,$logname,$tested);
}
 
$res = $this->_writeLog($log_filename, $data);
if (PEAR::isError($res)) {
return $res;
if (isset($old_php)) {
$php = $old_php;
}
 
if (isset($this->_options['tapoutput'])) {
664,39 → 722,47
return $warn ? 'WARNED' : 'FAILED';
}
 
function generate_diff($wanted, $output, $rvalue, $wanted_re)
function generate_diff($wanted, $output, $return_value, $wanted_re)
{
$w = explode("\n", $wanted);
$o = explode("\n", $output);
$w = explode("\n", $wanted);
$o = explode("\n", $output);
$wr = explode("\n", $wanted_re);
$w1 = array_diff_assoc($w, $o);
$o1 = array_diff_assoc($o, $w);
$o2 = $w2 = array();
foreach ($w1 as $idx => $val) {
$w1 = array_diff_assoc($w,$o);
$o1 = array_diff_assoc($o,$w);
$w2 = array();
$o2 = array();
foreach($w1 as $idx => $val) {
if (!$wanted_re || !isset($wr[$idx]) || !isset($o1[$idx]) ||
!preg_match('/^' . $wr[$idx] . '\\z/', $o1[$idx])) {
!preg_match('/^' . $wr[$idx] . '$/', $o1[$idx])) {
$w2[sprintf("%03d<", $idx)] = sprintf("%03d- ", $idx + 1) . $val;
}
}
foreach ($o1 as $idx => $val) {
foreach($o1 as $idx => $val) {
if (!$wanted_re || !isset($wr[$idx]) ||
!preg_match('/^' . $wr[$idx] . '\\z/', $val)) {
!preg_match('/^' . $wr[$idx] . '$/', $val)) {
$o2[sprintf("%03d>", $idx)] = sprintf("%03d+ ", $idx + 1) . $val;
}
}
$diff = array_merge($w2, $o2);
ksort($diff);
$extra = $rvalue ? "##EXPECTED: $rvalue[0]\r\n##RETURNED: $rvalue[1]" : '';
if ($return_value) {
$extra = "##EXPECTED: $return_value[0]\r\n##RETURNED: $return_value[1]";
} else {
$extra = '';
}
return implode("\r\n", $diff) . $extra;
}
 
//
// Write the given text to a temporary file, and return the filename.
//
 
function save_text($filename, $text)
{
if (!$fp = fopen($filename, 'w')) {
return PEAR::raiseError("Cannot open file '" . $filename . "' (save_text)");
}
fwrite($fp, $text);
fwrite($fp,$text);
fclose($fp);
if (1 < DETAILED) echo "
FILE $filename {{{
705,268 → 771,5
";
}
 
function _cleanupOldFiles($file)
{
$temp_dir = realpath(dirname($file));
$mainFileName = basename($file, 'phpt');
$diff_filename = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'diff';
$log_filename = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'log';
$exp_filename = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'exp';
$output_filename = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'out';
$memcheck_filename = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'mem';
$temp_file = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'php';
$temp_skipif = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'skip.php';
$temp_clean = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'clean.php';
$tmp_post = $temp_dir . DIRECTORY_SEPARATOR . uniqid('phpt.');
 
// unlink old test results
@unlink($diff_filename);
@unlink($log_filename);
@unlink($exp_filename);
@unlink($output_filename);
@unlink($memcheck_filename);
@unlink($temp_file);
@unlink($temp_skipif);
@unlink($tmp_post);
@unlink($temp_clean);
}
 
function _runSkipIf($section_text, $temp_skipif, $tested, $ini_settings)
{
$info = '';
$warn = false;
if (array_key_exists('SKIPIF', $section_text) && trim($section_text['SKIPIF'])) {
$this->save_text($temp_skipif, $section_text['SKIPIF']);
$output = $this->system_with_timeout("$this->_php$ini_settings -f \"$temp_skipif\"");
$output = $output[1];
$loutput = ltrim($output);
unlink($temp_skipif);
if (!strncasecmp('skip', $loutput, 4)) {
$skipreason = "SKIP $tested";
if (preg_match('/^\s*skip\s*(.+)\s*/i', $output, $m)) {
$skipreason .= '(reason: ' . $m[1] . ')';
}
if (!isset($this->_options['quiet'])) {
$this->_logger->log(0, $skipreason);
}
if (isset($this->_options['tapoutput'])) {
return array('ok', ' # skip ' . $reason);
}
return 'SKIPPED';
}
 
if (!strncasecmp('info', $loutput, 4)
&& preg_match('/^\s*info\s*(.+)\s*/i', $output, $m)) {
$info = " (info: $m[1])";
}
 
if (!strncasecmp('warn', $loutput, 4)
&& preg_match('/^\s*warn\s*(.+)\s*/i', $output, $m)) {
$warn = true; /* only if there is a reason */
$info = " (warn: $m[1])";
}
}
 
return array('warn' => $warn, 'info' => $info);
}
 
function _stripHeadersCGI($output)
{
$this->headers = array();
if (!empty($this->_options['cgi']) &&
$this->_php == $this->_options['cgi'] &&
preg_match("/^(.*?)(?:\n\n(.*)|\\z)/s", $output, $match)) {
$output = isset($match[2]) ? trim($match[2]) : '';
$this->_headers = $this->_processHeaders($match[1]);
}
 
return $output;
}
 
/**
* Return an array that can be used with array_diff() to compare headers
*
* @param string $text
*/
function _processHeaders($text)
{
$headers = array();
$rh = preg_split("/[\n\r]+/", $text);
foreach ($rh as $line) {
if (strpos($line, ':')!== false) {
$line = explode(':', $line, 2);
$headers[trim($line[0])] = trim($line[1]);
}
}
return $headers;
}
 
function _readFile($file)
{
// Load the sections of the test file.
$section_text = array(
'TEST' => '(unnamed test)',
'SKIPIF' => '',
'GET' => '',
'COOKIE' => '',
'POST' => '',
'ARGS' => '',
'INI' => '',
'CLEAN' => '',
);
 
if (!is_file($file) || !$fp = fopen($file, "r")) {
return PEAR::raiseError("Cannot open test file: $file");
}
 
$section = '';
while (!feof($fp)) {
$line = fgets($fp);
 
// Match the beginning of a section.
if (preg_match('/^--([_A-Z]+)--/', $line, $r)) {
$section = $r[1];
$section_text[$section] = '';
continue;
} elseif (empty($section)) {
fclose($fp);
return PEAR::raiseError("Invalid sections formats in test file: $file");
}
 
// Add to the section text.
$section_text[$section] .= $line;
}
fclose($fp);
 
return $section_text;
}
 
function _writeLog($logname, $data)
{
if (!$log = fopen($logname, 'w')) {
return PEAR::raiseError("Cannot create test log - $logname");
}
fwrite($log, $data);
fclose($log);
}
 
function _resetEnv($section_text, $temp_file)
{
$env = $_ENV;
$env['REDIRECT_STATUS'] = '';
$env['QUERY_STRING'] = '';
$env['PATH_TRANSLATED'] = '';
$env['SCRIPT_FILENAME'] = '';
$env['REQUEST_METHOD'] = '';
$env['CONTENT_TYPE'] = '';
$env['CONTENT_LENGTH'] = '';
if (!empty($section_text['ENV'])) {
if (strpos($section_text['ENV'], '{PWD}') !== false) {
$section_text['ENV'] = str_replace('{PWD}', dirname($temp_file), $section_text['ENV']);
}
foreach (explode("\n", trim($section_text['ENV'])) as $e) {
$e = explode('=', trim($e), 2);
if (!empty($e[0]) && isset($e[1])) {
$env[$e[0]] = $e[1];
}
}
}
if (array_key_exists('GET', $section_text)) {
$env['QUERY_STRING'] = trim($section_text['GET']);
} else {
$env['QUERY_STRING'] = '';
}
if (array_key_exists('COOKIE', $section_text)) {
$env['HTTP_COOKIE'] = trim($section_text['COOKIE']);
} else {
$env['HTTP_COOKIE'] = '';
}
$env['REDIRECT_STATUS'] = '1';
$env['PATH_TRANSLATED'] = $temp_file;
$env['SCRIPT_FILENAME'] = $temp_file;
 
return $env;
}
 
function _processUpload($section_text, $file)
{
if (array_key_exists('UPLOAD', $section_text) && !empty($section_text['UPLOAD'])) {
$upload_files = trim($section_text['UPLOAD']);
$upload_files = explode("\n", $upload_files);
 
$request = "Content-Type: multipart/form-data; boundary=---------------------------20896060251896012921717172737\n" .
"-----------------------------20896060251896012921717172737\n";
foreach ($upload_files as $fileinfo) {
$fileinfo = explode('=', $fileinfo);
if (count($fileinfo) != 2) {
return PEAR::raiseError("Invalid UPLOAD section in test file: $file");
}
if (!realpath(dirname($file) . '/' . $fileinfo[1])) {
return PEAR::raiseError("File for upload does not exist: $fileinfo[1] " .
"in test file: $file");
}
$file_contents = file_get_contents(dirname($file) . '/' . $fileinfo[1]);
$fileinfo[1] = basename($fileinfo[1]);
$request .= "Content-Disposition: form-data; name=\"$fileinfo[0]\"; filename=\"$fileinfo[1]\"\n";
$request .= "Content-Type: text/plain\n\n";
$request .= $file_contents . "\n" .
"-----------------------------20896060251896012921717172737\n";
}
 
if (array_key_exists('POST', $section_text) && !empty($section_text['POST'])) {
// encode POST raw
$post = trim($section_text['POST']);
$post = explode('&', $post);
foreach ($post as $i => $post_info) {
$post_info = explode('=', $post_info);
if (count($post_info) != 2) {
return PEAR::raiseError("Invalid POST data in test file: $file");
}
$post_info[0] = rawurldecode($post_info[0]);
$post_info[1] = rawurldecode($post_info[1]);
$post[$i] = $post_info;
}
foreach ($post as $post_info) {
$request .= "Content-Disposition: form-data; name=\"$post_info[0]\"\n\n";
$request .= $post_info[1] . "\n" .
"-----------------------------20896060251896012921717172737\n";
}
unset($section_text['POST']);
}
$section_text['POST_RAW'] = $request;
}
 
return $section_text;
}
 
function _testCleanup($section_text, $temp_clean)
{
if ($section_text['CLEAN']) {
$this->_restorePHPBinary();
 
// perform test cleanup
$this->save_text($temp_clean, $section_text['CLEAN']);
$output = $this->system_with_timeout("$this->_php $temp_clean 2>&1");
if (strlen($output[1])) {
echo "BORKED --CLEAN-- section! output:\n", $output[1];
}
if (file_exists($temp_clean)) {
unlink($temp_clean);
}
}
}
 
function _savePHPBinary()
{
$this->_savephp = $this->_php;
}
 
function _restorePHPBinary()
{
if (isset($this->_savephp))
{
$this->_php = $this->_savephp;
unset($this->_savephp);
}
}
}
?>
/trunk/bibliotheque/pear/PEAR/PackageFile/Parser/v1.php
4,11 → 4,18
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: v1.php,v 1.22 2006/03/27 05:25:48 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
21,8 → 28,8
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: @PEAR-VER@
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
59,7 → 66,7
* @param string contents of package.xml file, version 1.0
* @return bool success of parsing
*/
function &parse($data, $file, $archive = false)
function parse($data, $file, $archive = false)
{
if (!extension_loaded('xml')) {
return PEAR::raiseError('Cannot create xml parser for parsing package.xml, no xml extension');
66,8 → 73,7
}
$xp = xml_parser_create();
if (!$xp) {
$a = &PEAR::raiseError('Cannot create xml parser for parsing package.xml');
return $a;
return PEAR::raiseError('Cannot create xml parser for parsing package.xml');
}
xml_set_object($xp, $this);
xml_set_element_handler($xp, '_element_start_1_0', '_element_end_1_0');
90,9 → 96,8
$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",
return PEAR::raiseError(sprintf("XML error: %s at line %d",
$str = xml_error_string($code), $line), 2);
return $a;
}
 
xml_parser_free($xp);
127,8 → 132,6
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;
164,7 → 167,7
if (array_key_exists('name', $attribs) && $attribs['name'] != '/') {
$attribs['name'] = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'),
$attribs['name']);
if (strrpos($attribs['name'], '/') === strlen($attribs['name']) - 1) {
if (strrpos($attribs['name'], '/') == strlen($attribs['name']) - 1) {
$attribs['name'] = substr($attribs['name'], 0,
strlen($attribs['name']) - 1);
}
330,6 → 333,7
$this->current_maintainer['role'] = $data;
break;
case 'version':
//$data = ereg_replace ('[^a-zA-Z0-9._\-]', '_', $data);
if ($this->in_changelog) {
$this->current_release['version'] = $data;
} else {
346,8 → 350,7
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));
$data = $this->_unIndent($this->cdata);
if ($this->in_changelog) {
$this->current_release['release_notes'] = $data;
} else {
/trunk/bibliotheque/pear/PEAR/PackageFile/Parser/v2.php
4,11 → 4,18
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: v2.php,v 1.19 2006/01/23 17:39:52 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
22,8 → 29,8
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: @PEAR-VER@
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
63,8 → 70,6
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;
92,21 → 97,19
* a subclass
* @return PEAR_PackageFile_v2
*/
function parse($data, $file = null, $archive = false, $class = 'PEAR_PackageFile_v2')
function &parse($data, $file, $archive = false, $class = 'PEAR_PackageFile_v2')
{
if (PEAR::isError($err = parent::parse($data))) {
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;
}
}
}
?>
/trunk/bibliotheque/pear/PEAR/PackageFile/v1.php
4,11 → 4,18
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: v1.php,v 1.72 2006/10/31 02:54:41 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
272,9 → 279,9
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
345,9 → 352,9
* @param bool determines whether to return a PEAR_Error object, or use the PEAR_ErrorStack
* @param string Name of Error Stack class to use.
*/
function __construct()
function PEAR_PackageFile_v1()
{
$this->_stack = new PEAR_ErrorStack('PEAR_PackageFile_v1');
$this->_stack = &new PEAR_ErrorStack('PEAR_PackageFile_v1');
$this->_stack->setErrorMessageTemplate($this->_getErrorMessage());
$this->_isValid = 0;
}
1193,25 → 1200,10
$this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE,
array('file' => $file, 'role' => $fa['role'], 'roles' => PEAR_Common::getFileRoles()));
}
if (preg_match('~/\.\.?(/|\\z)|^\.\.?/~', str_replace('\\', '/', $file))) {
// file contains .. parent directory or . cur directory references
if ($file{0} == '.' && $file{1} == '/') {
$this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME,
array('file' => $file));
}
if (isset($fa['install-as']) &&
preg_match('~/\.\.?(/|\\z)|^\.\.?/~',
str_replace('\\', '/', $fa['install-as']))) {
// install-as contains .. parent directory or . cur directory references
$this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME,
array('file' => $file . ' [installed as ' . $fa['install-as'] . ']'));
}
if (isset($fa['baseinstalldir']) &&
preg_match('~/\.\.?(/|\\z)|^\.\.?/~',
str_replace('\\', '/', $fa['baseinstalldir']))) {
// install-as contains .. parent directory or . cur directory references
$this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME,
array('file' => $file . ' [baseinstalldir ' . $fa['baseinstalldir'] . ']'));
}
}
}
if (isset($this->_registry) && $this->_isValid) {
1307,7 → 1299,7
if (!class_exists('PEAR_PackageFile_Generator_v1')) {
require_once 'PEAR/PackageFile/Generator/v1.php';
}
$a = new PEAR_PackageFile_Generator_v1($this);
$a = &new PEAR_PackageFile_Generator_v1($this);
return $a;
}
 
1330,7 → 1322,7
if (!class_exists('Archive_Tar')) {
require_once 'Archive/Tar.php';
}
$tar = new Archive_Tar($this->_archiveFile);
$tar = &new Archive_Tar($this->_archiveFile);
$tar->pushErrorHandling(PEAR_ERROR_RETURN);
if ($file != 'package.xml' && $file != 'package2.xml') {
$file = $this->getPackage() . '-' . $this->getVersion() . '/' . $file;
1465,6 → 1457,15
$look_for = $token;
continue 2;
case T_STRING:
if (version_compare(zend_version(), '2.0', '<')) {
if (in_array(strtolower($data),
array('public', 'private', 'protected', 'abstract',
'interface', 'implements', 'throw')
)) {
$this->_validateWarning(PEAR_PACKAGEFILE_ERROR_PHP5,
array($file));
}
}
if ($look_for == T_CLASS) {
$current_class = $data;
$current_class_level = $brace_level;
/trunk/bibliotheque/pear/PEAR/PackageFile/v2.php
4,11 → 4,18
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: v2.php,v 1.136 2007/02/20 00:16:12 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
20,9 → 27,9
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
114,7 → 121,7
*
* - package name
* - channel name
* - dependencies
* - dependencies
* @var boolean
* @access private
*/
128,7 → 135,7
/**
* The constructor merely sets up the private error stack
*/
function __construct()
function PEAR_PackageFile_v2()
{
$this->_stack = new PEAR_ErrorStack('PEAR_PackageFile_v2', false, null);
$this->_isValid = false;
135,15 → 142,6
}
 
/**
* PHP 4 style constructor for backwards compatibility.
* Used by PEAR_PackageFileManager2
*/
public function PEAR_PackageFile_v2()
{
$this->__construct();
}
 
/**
* To make unit-testing easier
* @param PEAR_Frontend_*
* @param array options
153,7 → 151,7
*/
function &getPEARDownloader(&$i, $o, &$c)
{
$z = new PEAR_Downloader($i, $o, $c);
$z = &new PEAR_Downloader($i, $o, $c);
return $z;
}
 
171,7 → 169,7
if (!class_exists('PEAR_Dependency2')) {
require_once 'PEAR/Dependency2.php';
}
$z = new PEAR_Dependency2($c, $o, $p, $s);
$z = &new PEAR_Dependency2($c, $o, $p, $s);
return $z;
}
 
475,9 → 473,6
*/
function setRawState($state)
{
if (!isset($this->_packageInfo['stability'])) {
$this->_packageInfo['stability'] = array();
}
$this->_packageInfo['stability']['release'] = $state;
}
 
572,7 → 567,7
$atts = $filelist[$name];
foreach ($tasks as $tag => $raw) {
$task = $this->getTask($tag);
$task = new $task($this->_config, $common, PEAR_TASK_INSTALL);
$task = &new $task($this->_config, $common, PEAR_TASK_INSTALL);
if ($task->isScript()) {
$ret[] = $filelist[$name]['installed_as'];
}
618,7 → 613,7
$atts = $filelist[$name];
foreach ($tasks as $tag => $raw) {
$taskname = $this->getTask($tag);
$task = new $taskname($this->_config, $common, PEAR_TASK_INSTALL);
$task = &new $taskname($this->_config, $common, PEAR_TASK_INSTALL);
if (!$task->isScript()) {
continue; // scripts are only handled after installation
}
807,10 → 802,6
{
unset($pinfo['old']);
unset($pinfo['xsdversion']);
// If the changelog isn't an array then it was passed in as an empty tag
if (isset($pinfo['changelog']) && !is_array($pinfo['changelog'])) {
unset($pinfo['changelog']);
}
$this->_incomplete = false;
$this->_packageInfo = $pinfo;
}
1178,16 → 1169,10
$this->flattenFilelist();
if ($contents = $this->getContents()) {
$ret = array();
if (!isset($contents['dir'])) {
return false;
}
if (!isset($contents['dir']['file'][0])) {
$contents['dir']['file'] = array($contents['dir']['file']);
}
foreach ($contents['dir']['file'] as $file) {
if (!isset($file['attribs']['name'])) {
continue;
}
$name = $file['attribs']['name'];
if (!$preserve) {
$file = $file['attribs'];
1212,24 → 1197,19
if ($this->getPackageType() != 'extsrc' && $this->getPackageType() != 'zendextsrc') {
return false;
}
 
$releases = $this->getReleases();
if (isset($releases[0])) {
$releases = $releases[0];
}
 
if (isset($releases['configureoption'])) {
if (!isset($releases['configureoption'][0])) {
$releases['configureoption'] = array($releases['configureoption']);
}
 
for ($i = 0; $i < count($releases['configureoption']); $i++) {
$releases['configureoption'][$i] = $releases['configureoption'][$i]['attribs'];
}
 
return $releases['configureoption'];
}
 
return false;
}
 
1583,7 → 1563,7
if (strtolower($dep['name']) == strtolower($package) &&
$depchannel == $channel) {
return true;
}
}
}
}
}
1601,7 → 1581,7
if (strtolower($dep['name']) == strtolower($package) &&
$depchannel == $channel) {
return true;
}
}
}
}
}
1661,8 → 1641,7
);
foreach (array('required', 'optional') as $type) {
$optional = ($type == 'optional') ? 'yes' : 'no';
if (!isset($this->_packageInfo['dependencies'][$type])
|| empty($this->_packageInfo['dependencies'][$type])) {
if (!isset($this->_packageInfo['dependencies'][$type])) {
continue;
}
foreach ($this->_packageInfo['dependencies'][$type] as $dtype => $deps) {
1865,7 → 1844,7
return implode('', file($file));
}
} else { // tgz
$tar = new Archive_Tar($this->_archiveFile);
$tar = &new Archive_Tar($this->_archiveFile);
$tar->pushErrorHandling(PEAR_ERROR_RETURN);
if ($file != 'package.xml' && $file != 'package2.xml') {
$file = $this->getPackage() . '-' . $this->getVersion() . '/' . $file;
1904,7 → 1883,7
if (!class_exists('PEAR_PackageFile_Generator_v2')) {
require_once 'PEAR/PackageFile/Generator/v2.php';
}
$a = new PEAR_PackageFile_Generator_v2($this);
$a = &new PEAR_PackageFile_Generator_v2($this);
return $a;
}
 
1968,17 → 1947,17
$this->getTasksNs();
// transform all '-' to '/' and 'tasks:' to '' so tasks:replace becomes replace
$task = str_replace(array($this->_tasksNs . ':', '-'), array('', ' '), $task);
$taskfile = str_replace(' ', '/', ucwords($task));
$task = str_replace(array(' ', '/'), '_', ucwords($task));
if (class_exists("PEAR_Task_$task")) {
return "PEAR_Task_$task";
$task = str_replace(' ', '/', ucwords($task));
$ps = (strtolower(substr(PHP_OS, 0, 3)) == 'win') ? ';' : ':';
foreach (explode($ps, ini_get('include_path')) as $path) {
if (file_exists($path . "/PEAR/Task/$task.php")) {
include_once "PEAR/Task/$task.php";
$task = str_replace('/', '_', $task);
if (class_exists("PEAR_Task_$task")) {
return "PEAR_Task_$task";
}
}
}
$fp = @fopen("PEAR/Task/$taskfile.php", 'r', true);
if ($fp) {
fclose($fp);
require_once "PEAR/Task/$taskfile.php";
return "PEAR_Task_$task";
}
return false;
}
 
/trunk/bibliotheque/pear/PEAR/PackageFile/Generator/v1.php
4,11 → 4,18
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: v1.php,v 1.72 2006/05/10 02:56:19 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
26,9 → 33,9
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
38,7 → 45,7
* @var PEAR_PackageFile_v1
*/
var $_packagefile;
function __construct(&$packagefile)
function PEAR_PackageFile_Generator_v1(&$packagefile)
{
$this->_packagefile = &$packagefile;
}
45,7 → 52,7
 
function getPackagerVersion()
{
return '1.10.1';
return '1.5.1';
}
 
/**
108,7 → 115,7
// }}}
$packagexml = $this->toPackageFile($where, PEAR_VALIDATE_PACKAGING, 'package.xml', true);
if ($packagexml) {
$tar = new Archive_Tar($dest_package, $compress);
$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);
167,6 → 174,9
*/
function _fixXmlEncoding($string)
{
if (version_compare(phpversion(), '5.0.0', 'lt')) {
$string = utf8_encode($string);
}
return strtr($string, array(
'&' => '&amp;',
'>' => '&gt;',
196,7 → 206,7
);
$ret = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
$ret .= "<!DOCTYPE package SYSTEM \"http://pear.php.net/dtd/package-1.0\">\n";
$ret .= "<package version=\"1.0\" packagerversion=\"1.10.1\">\n" .
$ret .= "<package version=\"1.0\" packagerversion=\"1.5.1\">\n" .
" <name>$pkginfo[package]</name>";
if (isset($pkginfo['extends'])) {
$ret .= "\n<extends>$pkginfo[extends]</extends>";
511,7 → 521,6
return $a;
}
}
 
$arr = array(
'attribs' => array(
'version' => '2.0',
541,7 → 550,6
);
$arr['lead'][] = $new;
}
 
if (!isset($arr['lead'])) { // some people... you know?
$arr['lead'] = array(
'name' => 'unknown',
550,11 → 558,9
'active' => 'no',
);
}
 
if (count($arr['lead']) == 1) {
$arr['lead'] = $arr['lead'][0];
}
 
foreach ($maintainers as $maintainer) {
if ($maintainer['role'] == 'lead') {
continue;
567,19 → 573,15
);
$arr[$maintainer['role']][] = $new;
}
 
if (isset($arr['developer']) && count($arr['developer']) == 1) {
$arr['developer'] = $arr['developer'][0];
}
 
if (isset($arr['contributor']) && count($arr['contributor']) == 1) {
$arr['contributor'] = $arr['contributor'][0];
}
 
if (isset($arr['helper']) && count($arr['helper']) == 1) {
$arr['helper'] = $arr['helper'][0];
}
 
$arr['date'] = $this->_packagefile->getDate();
$arr['version'] =
array(
603,7 → 605,6
'gpl' => 'http://www.gnu.org/copyleft/gpl.html',
'apache' => 'http://www.opensource.org/licenses/apache2.0.php'
);
 
if (isset($licensemap[strtolower($this->_packagefile->getLicense())])) {
$arr['license'] = array(
'attribs' => array('uri' =>
614,7 → 615,6
// don't use bogus uri
$arr['license'] = $this->_packagefile->getLicense();
}
 
$arr['notes'] = $this->_packagefile->getNotes();
$temp = array();
$arr['contents'] = $this->_convertFilelist2_0($temp);
625,7 → 625,6
$arr['channel'] = 'pecl.php.net';
$arr['providesextension'] = $arr['name']; // assumption
}
 
$arr[$release] = array();
if ($this->_packagefile->getConfigureOptions()) {
$arr[$release]['configureoption'] = $this->_packagefile->getConfigureOptions();
636,13 → 635,11
$arr[$release]['configureoption'] = $arr[$release]['configureoption'][0];
}
}
 
$this->_convertRelease2_0($arr[$release], $temp);
if ($release == 'extsrcrelease' && count($arr[$release]) > 1) {
// multiple extsrcrelease tags added in PEAR 1.4.1
$arr['dependencies']['required']['pearinstaller']['min'] = '1.4.1';
}
 
if ($cl = $this->_packagefile->getChangelog()) {
foreach ($cl as $release) {
$rel = array();
654,7 → 651,6
if (!isset($release['release_state'])) {
$release['release_state'] = 'stable';
}
 
$rel['stability'] =
array(
'release' => $release['release_state'],
665,7 → 661,6
} else {
$rel['date'] = date('Y-m-d');
}
 
if (isset($release['release_license'])) {
if (isset($licensemap[strtolower($release['release_license'])])) {
$uri = $licensemap[strtolower($release['release_license'])];
679,22 → 674,18
} else {
$rel['license'] = $arr['license'];
}
 
if (!isset($release['release_notes'])) {
$release['release_notes'] = 'no release notes';
}
 
$rel['notes'] = $release['release_notes'];
$arr['changelog']['release'][] = $rel;
}
}
 
$ret = new $class;
$ret->setConfig($this->_packagefile->_config);
if (isset($this->_packagefile->_logger) && is_object($this->_packagefile->_logger)) {
$ret->setLogger($this->_packagefile->_logger);
}
 
$ret->fromArray($arr);
return $ret;
}
709,7 → 700,7
$peardep = array('pearinstaller' =>
array('min' => '1.4.0b1')); // this is a lot safer
$required = $optional = array();
$release['dependencies'] = array('required' => array());
$release['dependencies'] = array();
if ($this->_packagefile->hasDeps()) {
foreach ($this->_packagefile->getDeps() as $dep) {
if (!isset($dep['optional']) || $dep['optional'] == 'no') {
840,9 → 831,9
/**
* Post-process special files with install-as/platform attributes and
* make the release tag.
*
*
* This complex method follows this work-flow to create the release tags:
*
*
* <pre>
* - if any install-as/platform exist, create a generic release and fill it with
* o <install as=..> tags for <file name=... install-as=...>
858,10 → 849,10
* o <ignore> tags for <file name=... platform=other platform install-as=..>
* o <ignore> tags for <file name=... platform=!this platform install-as=..>
* </pre>
*
*
* It does this by accessing the $package parameter, which contains an array with
* indices:
*
*
* - platform: mapping of file => OS the file should be installed on
* - install-as: mapping of file => installed name
* - osmap: mapping of OS => list of files that should be installed
875,7 → 866,7
*/
function _convertRelease2_0(&$release, $package)
{
//- if any install-as/platform exist, create a generic release and fill it with
//- if any install-as/platform exist, create a generic release and fill it with
if (count($package['platform']) || count($package['install-as'])) {
$generic = array();
$genericIgnore = array();
1174,15 → 1165,13
}
if (count($min)) {
// get the highest minimum
$a = array_flip($min);
$min = array_pop($a);
$min = array_pop($a = array_flip($min));
} else {
$min = false;
}
if (count($max)) {
// get the lowest maximum
$a = array_flip($max);
$max = array_shift($a);
$max = array_shift($a = array_flip($max));
} else {
$max = false;
}
1213,15 → 1202,16
*/
function _processMultipleDepsName($deps)
{
$ret = $tests = array();
$tests = array();
foreach ($deps as $name => $dep) {
foreach ($dep as $d) {
$tests[$name][] = $this->_processDep($d);
}
}
 
foreach ($tests as $name => $test) {
$max = $min = $php = array();
$php = array();
$min = array();
$max = array();
$php['name'] = $name;
foreach ($test as $dep) {
if (!$dep) {
1248,15 → 1238,13
}
if (count($min)) {
// get the highest minimum
$a = array_flip($min);
$min = array_pop($a);
$min = array_pop($a = array_flip($min));
} else {
$min = false;
}
if (count($max)) {
// get the lowest maximum
$a = array_flip($max);
$max = array_shift($a);
$max = array_shift($a = array_flip($max));
} else {
$max = false;
}
1281,4 → 1269,4
return $ret;
}
}
?>
?>
/trunk/bibliotheque/pear/PEAR/PackageFile/Generator/v2.php
4,12 → 4,19
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: v2.php,v 1.35 2006/03/25 21:09:08 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
17,8 → 24,6
* 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.
*
28,9 → 33,9
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
42,37 → 47,37
* @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
'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 PEAR_PackageFile_Generator_v2_PEAR_PackageFile_Generator_v2_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 conjunction with attributesArray
'beautifyFilelist' => false,
'encoding' => 'UTF-8',
);
), // 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
99,12 → 104,9
/**
* @param PEAR_PackageFile_v2
*/
function __construct(&$packagefile)
function PEAR_PackageFile_Generator_v2(&$packagefile)
{
$this->_packagefile = &$packagefile;
if (isset($this->_packagefile->encoding)) {
$this->_defaultOptions['encoding'] = $this->_packagefile->encoding;
}
}
 
/**
112,7 → 114,7
*/
function getPackagerVersion()
{
return '1.10.1';
return '1.5.1';
}
 
/**
142,7 → 144,6
'" 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');
151,34 → 152,29
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)) {
if (file_exists($where . DIRECTORY_SEPARATOR . 'package.xml') &&
!is_file($where . DIRECTORY_SEPARATOR . 'package.xml')) {
return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: unable to save package.xml as' .
' "' . $file .'"');
' "' . $where . DIRECTORY_SEPARATOR . 'package.xml"');
}
 
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)) {
if (file_exists(getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext) &&
!is_file(getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext)) {
return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: cannot create tgz file "' .
$dest_package . '"');
getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext . '"');
}
 
$pkgfile = $this->_packagefile->getPackageFile();
if (!$pkgfile) {
if ($pkgfile = $this->_packagefile->getPackageFile()) {
$pkgdir = dirname(realpath($pkgfile));
$pkgfile = basename($pkgfile);
} else {
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;
189,7 → 185,6
if (!isset($contents[0])) {
$contents = array($contents);
}
 
$packageDir = $where;
foreach ($contents as $i => $package) {
$fname = $package;
197,7 → 192,6
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);
209,7 → 203,7
if (!isset($contents[0])) {
$contents = array($contents);
}
 
$packageDir = $where;
foreach ($contents as $i => $file) {
$fname = $file['attribs']['name'];
218,57 → 212,52
$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
} else {
$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($this->_packagefile->getTasksNs() . ':', '', $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 (PEAR::isError($res)) {
return $res;
}
 
$contents = $res; // save changes
}
if (!file_exists($tfile)) {
System::mkdir(array('-p', dirname($tfile)));
$wp = fopen($tfile, "wb");
fwrite($wp, $contents);
fclose($wp);
copy($file, $tfile);
}
$filelist[$i++] = $tfile;
$this->_packagefile->setFileAttribute($fname, 'md5sum', md5_file($tfile), $i - 1);
$packager->log(2, "Adding file $fname");
}
 
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';
if ($pf1 !== null) {
$name = 'package2.xml';
} else {
$name = 'package.xml';
}
$packagexml = $this->toPackageFile($where, PEAR_VALIDATE_PACKAGING, $name);
if ($packagexml) {
$tar = new Archive_Tar($dest_package, $compress);
$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);
278,23 → 267,21
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);
$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;
}
}
305,7 → 292,6
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');
314,7 → 300,6
return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: "' . $where . '" could' .
' not be created');
}
 
$newpkgfile = $where . DIRECTORY_SEPARATOR . $name;
$np = @fopen($newpkgfile, 'wb');
if (!$np) {
344,47 → 329,18
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']);
396,12 → 352,10
}
$this->options['beautifyFilelist'] = true;
}
 
$arr['attribs']['packagerversion'] = '1.10.1';
$arr['attribs']['packagerversion'] = '1.5.1';
if ($this->serialize($arr, $options)) {
return $this->_serializedData . "\n";
}
 
return false;
}
 
523,7 → 477,7
{
$this->options[$name] = $value;
}
 
/**
* sets several options at once
*
555,22 → 509,29
} else {
$this->options = array_merge($this->options, $options);
}
} else {
}
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';
if (isset($this->options['rootName'])) {
$tagName = $this->options['rootName'];
} else {
$tagName = '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->_serializedData = PEAR_PackageFile_Generator_v2_XML_Util::getDoctypeDeclaration($tagName, $this->options['doctype'])
. $this->options['linebreak']
. $this->_serializedData;
}
578,17 → 539,21
// 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)
if (isset($this->options['encoding']) ) {
$encoding = $this->options['encoding'];
} else {
$encoding = null;
}
$this->_serializedData = PEAR_PackageFile_Generator_v2_XML_Util::getXMLDeclaration('1.0', $encoding)
. $this->options['linebreak']
. $this->_serializedData;
}
 
 
if ($optionsBak !== null) {
$this->options = $optionsBak;
}
 
if ($optionsBak !== null) {
$this->options = $optionsBak;
}
return true;
}
 
600,12 → 565,12
*/
function getSerializedData()
{
if ($this->_serializedData === null) {
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
*
633,7 → 598,7
}
return $xml;
}
 
/**
* serialize an array
*
642,12 → 607,12
* @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
* @uses PEAR_PackageFile_Generator_v2_XML_Util::isValidName() to check, whether key has to be substituted
*/
function _serializeArray(&$array, $tagName = null, $attributes = array())
{
$_content = null;
 
/**
* check for special attributes
*/
711,10 → 676,10
$this->_curdir = $savedir;
}
}
 
$string .= $this->options['linebreak'];
// do indentation
if ($this->options['indent'] !== null && $this->_tagDepth > 0) {
// do indentation
if ($this->options['indent']!==null && $this->_tagDepth>0) {
$string .= str_repeat($this->options['indent'], $this->_tagDepth);
}
}
721,16 → 686,16
return rtrim($string);
}
}
if ($this->options['scalarAsAttributes'] === true) {
foreach ($array as $key => $value) {
if (is_scalar($value) && (PEAR_PackageFile_Generator_v2_XML_Util::isValidName($key) === true)) {
unset($array[$key]);
$attributes[$this->options['prependAttributes'].$key] = $value;
}
}
}
 
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(
743,29 → 708,29
$this->_tagDepth++;
$tmp = $this->options['linebreak'];
foreach ($array as $key => $value) {
// do indentation
if ($this->options['indent'] !== null && $this->_tagDepth > 0) {
// 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'];
}
}
// copy key
$origKey = $key;
// key cannot be used as tagname => use default tag
$valid = PEAR_PackageFile_Generator_v2_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 ($key !== $origKey) {
$atts[$this->options['keyAttribute']] = (string)$origKey;
}
}
if ($this->options['beautifyFilelist'] && $key == 'dir') {
if (!isset($this->_curdir)) {
801,21 → 766,21
}
$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;
}
 
if (trim($tmp) === '') {
$tmp = null;
}
$tag = array(
'qname' => $tagName,
'content' => $tmp,
'attributes' => $attributes
);
'qname' => $tagName,
'content' => $tmp,
'attributes' => $attributes
);
}
if ($this->options['typeHints'] === true) {
if (!isset($tag['attributes'][$this->options['typeAttribute']])) {
826,7 → 791,7
$string = $this->_createXMLTag($tag, false);
return $string;
}
 
/**
* create a tag from an array
* this method awaits an array in the following format
843,7 → 808,7
* @param boolean $replaceEntities whether to replace XML entities in content or not
* @return string $string XML tag
*/
function _createXMLTag($tag, $replaceEntities = true)
function _createXMLTag( $tag, $replaceEntities = true )
{
if ($this->options['indentAttributes'] !== false) {
$multiline = true;
856,31 → 821,707
$indent .= $this->options['indentAttributes'];
}
} else {
$indent = $multiline = false;
$multiline = false;
$indent = false;
}
 
if (is_array($tag['content'])) {
if (empty($tag['content'])) {
$tag['content'] = '';
$tag['content'] = '';
}
} elseif(is_scalar($tag['content']) && (string)$tag['content'] == '') {
$tag['content'] = '';
$tag['content'] = '';
}
 
if (is_scalar($tag['content']) || is_null($tag['content'])) {
if ($replaceEntities === true) {
$replaceEntities = XML_UTIL_ENTITIES_XML;
if ($this->options['encoding'] == 'UTF-8' &&
version_compare(phpversion(), '5.0.0', 'lt')) {
$encoding = PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_UTF8_XML;
} else {
$encoding = PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML;
}
 
$tag = XML_Util::createTagFromArray($tag, $replaceEntities, $multiline, $indent, $this->options['linebreak']);
$tag = PEAR_PackageFile_Generator_v2_XML_Util::createTagFromArray($tag, $replaceEntities, $multiline, $indent, $this->options['linebreak'], $encoding);
} elseif (is_array($tag['content'])) {
$tag = $this->_serializeArray($tag['content'], $tag['qname'], $tag['attributes']);
$tag = $this->_serializeArray($tag['content'], $tag['qname'], $tag['attributes']);
} elseif (is_object($tag['content'])) {
$tag = $this->_serializeObject($tag['content'], $tag['qname'], $tag['attributes']);
$tag = $this->_serializeObject($tag['content'], $tag['qname'], $tag['attributes']);
} elseif (is_resource($tag['content'])) {
settype($tag['content'], 'string');
$tag = XML_Util::createTagFromArray($tag, $replaceEntities);
$tag = PEAR_PackageFile_Generator_v2_XML_Util::createTagFromArray($tag, $replaceEntities);
}
return $tag;
}
}
 
// well, it's one way to do things without extra deps ...
/* vim: set expandtab tabstop=4 shiftwidth=4: */
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.0 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.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. |
// +----------------------------------------------------------------------+
// | Authors: Stephan Schmidt <schst@php-tools.net> |
// +----------------------------------------------------------------------+
//
// $Id: v2.php,v 1.35 2006/03/25 21:09:08 cellog Exp $
 
/**
* error code for invalid chars in XML name
*/
define("PEAR_PackageFile_Generator_v2_XML_Util_ERROR_INVALID_CHARS", 51);
 
/**
* error code for invalid chars in XML name
*/
define("PEAR_PackageFile_Generator_v2_XML_Util_ERROR_INVALID_START", 52);
 
/**
* error code for non-scalar tag content
*/
define("PEAR_PackageFile_Generator_v2_XML_Util_ERROR_NON_SCALAR_CONTENT", 60);
/**
* error code for missing tag name
*/
define("PEAR_PackageFile_Generator_v2_XML_Util_ERROR_NO_TAG_NAME", 61);
/**
* replace XML entities
*/
define("PEAR_PackageFile_Generator_v2_XML_Util_REPLACE_ENTITIES", 1);
 
/**
* embedd content in a CData Section
*/
define("PEAR_PackageFile_Generator_v2_XML_Util_CDATA_SECTION", 2);
 
/**
* do not replace entitites
*/
define("PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_NONE", 0);
 
/**
* replace all XML entitites
* This setting will replace <, >, ", ' and &
*/
define("PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML", 1);
 
/**
* replace only required XML entitites
* This setting will replace <, " and &
*/
define("PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML_REQUIRED", 2);
 
/**
* replace HTML entitites
* @link http://www.php.net/htmlentities
*/
define("PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_HTML", 3);
 
/**
* replace all XML entitites, and encode from ISO-8859-1 to UTF-8
* This setting will replace <, >, ", ' and &
*/
define("PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_UTF8_XML", 4);
 
/**
* utility class for working with XML documents
*
* customized version of XML_Util 0.6.0
*
* @category XML
* @package PEAR
* @version 0.6.0
* @author Stephan Schmidt <schst@php.net>
* @author Gregory Beaver <cellog@php.net>
*/
class PEAR_PackageFile_Generator_v2_XML_Util {
 
/**
* return API version
*
* @access public
* @static
* @return string $version API version
*/
function apiVersion()
{
return "0.6";
}
 
/**
* replace XML entities
*
* With the optional second parameter, you may select, which
* entities should be replaced.
*
* <code>
* require_once 'XML/Util.php';
*
* // replace XML entites:
* $string = PEAR_PackageFile_Generator_v2_XML_Util::replaceEntities("This string contains < & >.");
* </code>
*
* @access public
* @static
* @param string string where XML special chars should be replaced
* @param integer setting for entities in attribute values (one of PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML, PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML_REQUIRED, PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_HTML)
* @return string string with replaced chars
*/
function replaceEntities($string, $replaceEntities = PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML)
{
switch ($replaceEntities) {
case PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_UTF8_XML:
return strtr(utf8_encode($string),array(
'&' => '&amp;',
'>' => '&gt;',
'<' => '&lt;',
'"' => '&quot;',
'\'' => '&apos;' ));
break;
case PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML:
return strtr($string,array(
'&' => '&amp;',
'>' => '&gt;',
'<' => '&lt;',
'"' => '&quot;',
'\'' => '&apos;' ));
break;
case PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML_REQUIRED:
return strtr($string,array(
'&' => '&amp;',
'<' => '&lt;',
'"' => '&quot;' ));
break;
case PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_HTML:
return htmlspecialchars($string);
break;
}
return $string;
}
 
/**
* build an xml declaration
*
* <code>
* require_once 'XML/Util.php';
*
* // get an XML declaration:
* $xmlDecl = PEAR_PackageFile_Generator_v2_XML_Util::getXMLDeclaration("1.0", "UTF-8", true);
* </code>
*
* @access public
* @static
* @param string $version xml version
* @param string $encoding character encoding
* @param boolean $standAlone document is standalone (or not)
* @return string $decl xml declaration
* @uses PEAR_PackageFile_Generator_v2_XML_Util::attributesToString() to serialize the attributes of the XML declaration
*/
function getXMLDeclaration($version = "1.0", $encoding = null, $standalone = null)
{
$attributes = array(
"version" => $version,
);
// add encoding
if ($encoding !== null) {
$attributes["encoding"] = $encoding;
}
// add standalone, if specified
if ($standalone !== null) {
$attributes["standalone"] = $standalone ? "yes" : "no";
}
return sprintf("<?xml%s?>", PEAR_PackageFile_Generator_v2_XML_Util::attributesToString($attributes, false));
}
 
/**
* build a document type declaration
*
* <code>
* require_once 'XML/Util.php';
*
* // get a doctype declaration:
* $xmlDecl = PEAR_PackageFile_Generator_v2_XML_Util::getDocTypeDeclaration("rootTag","myDocType.dtd");
* </code>
*
* @access public
* @static
* @param string $root name of the root tag
* @param string $uri uri of the doctype definition (or array with uri and public id)
* @param string $internalDtd internal dtd entries
* @return string $decl doctype declaration
* @since 0.2
*/
function getDocTypeDeclaration($root, $uri = null, $internalDtd = null)
{
if (is_array($uri)) {
$ref = sprintf( ' PUBLIC "%s" "%s"', $uri["id"], $uri["uri"] );
} elseif (!empty($uri)) {
$ref = sprintf( ' SYSTEM "%s"', $uri );
} else {
$ref = "";
}
 
if (empty($internalDtd)) {
return sprintf("<!DOCTYPE %s%s>", $root, $ref);
} else {
return sprintf("<!DOCTYPE %s%s [\n%s\n]>", $root, $ref, $internalDtd);
}
}
 
/**
* create string representation of an attribute list
*
* <code>
* require_once 'XML/Util.php';
*
* // build an attribute string
* $att = array(
* "foo" => "bar",
* "argh" => "tomato"
* );
*
* $attList = PEAR_PackageFile_Generator_v2_XML_Util::attributesToString($att);
* </code>
*
* @access public
* @static
* @param array $attributes attribute array
* @param boolean|array $sort sort attribute list alphabetically, may also be an assoc array containing the keys 'sort', 'multiline', 'indent', 'linebreak' and 'entities'
* @param boolean $multiline use linebreaks, if more than one attribute is given
* @param string $indent string used for indentation of multiline attributes
* @param string $linebreak string used for linebreaks of multiline attributes
* @param integer $entities setting for entities in attribute values (one of PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_NONE, PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML, PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML_REQUIRED, PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_HTML)
* @return string string representation of the attributes
* @uses PEAR_PackageFile_Generator_v2_XML_Util::replaceEntities() to replace XML entities in attribute values
* @todo allow sort also to be an options array
*/
function attributesToString($attributes, $sort = true, $multiline = false, $indent = ' ', $linebreak = "\n", $entities = PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML)
{
/**
* second parameter may be an array
*/
if (is_array($sort)) {
if (isset($sort['multiline'])) {
$multiline = $sort['multiline'];
}
if (isset($sort['indent'])) {
$indent = $sort['indent'];
}
if (isset($sort['linebreak'])) {
$multiline = $sort['linebreak'];
}
if (isset($sort['entities'])) {
$entities = $sort['entities'];
}
if (isset($sort['sort'])) {
$sort = $sort['sort'];
} else {
$sort = true;
}
}
$string = '';
if (is_array($attributes) && !empty($attributes)) {
if ($sort) {
ksort($attributes);
}
if( !$multiline || count($attributes) == 1) {
foreach ($attributes as $key => $value) {
if ($entities != PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_NONE) {
$value = PEAR_PackageFile_Generator_v2_XML_Util::replaceEntities($value, $entities);
}
$string .= ' '.$key.'="'.$value.'"';
}
} else {
$first = true;
foreach ($attributes as $key => $value) {
if ($entities != PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_NONE) {
$value = PEAR_PackageFile_Generator_v2_XML_Util::replaceEntities($value, $entities);
}
if ($first) {
$string .= " ".$key.'="'.$value.'"';
$first = false;
} else {
$string .= $linebreak.$indent.$key.'="'.$value.'"';
}
}
}
}
return $string;
}
 
/**
* create a tag
*
* This method will call PEAR_PackageFile_Generator_v2_XML_Util::createTagFromArray(), which
* is more flexible.
*
* <code>
* require_once 'XML/Util.php';
*
* // create an XML tag:
* $tag = PEAR_PackageFile_Generator_v2_XML_Util::createTag("myNs:myTag", array("foo" => "bar"), "This is inside the tag", "http://www.w3c.org/myNs#");
* </code>
*
* @access public
* @static
* @param string $qname qualified tagname (including namespace)
* @param array $attributes array containg attributes
* @param mixed $content
* @param string $namespaceUri URI of the namespace
* @param integer $replaceEntities whether to replace XML special chars in content, embedd it in a CData section or none of both
* @param boolean $multiline whether to create a multiline tag where each attribute gets written to a single line
* @param string $indent string used to indent attributes (_auto indents attributes so they start at the same column)
* @param string $linebreak string used for linebreaks
* @param string $encoding encoding that should be used to translate content
* @return string $string XML tag
* @see PEAR_PackageFile_Generator_v2_XML_Util::createTagFromArray()
* @uses PEAR_PackageFile_Generator_v2_XML_Util::createTagFromArray() to create the tag
*/
function createTag($qname, $attributes = array(), $content = null, $namespaceUri = null, $replaceEntities = PEAR_PackageFile_Generator_v2_XML_Util_REPLACE_ENTITIES, $multiline = false, $indent = "_auto", $linebreak = "\n", $encoding = PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML)
{
$tag = array(
"qname" => $qname,
"attributes" => $attributes
);
 
// add tag content
if ($content !== null) {
$tag["content"] = $content;
}
// add namespace Uri
if ($namespaceUri !== null) {
$tag["namespaceUri"] = $namespaceUri;
}
 
return PEAR_PackageFile_Generator_v2_XML_Util::createTagFromArray($tag, $replaceEntities, $multiline, $indent, $linebreak, $encoding);
}
 
/**
* create a tag from an array
* this method awaits an array in the following format
* <pre>
* array(
* "qname" => $qname // qualified name of the tag
* "namespace" => $namespace // namespace prefix (optional, if qname is specified or no namespace)
* "localpart" => $localpart, // local part of the tagname (optional, if qname is specified)
* "attributes" => array(), // array containing all attributes (optional)
* "content" => $content, // tag content (optional)
* "namespaceUri" => $namespaceUri // namespaceUri for the given namespace (optional)
* )
* </pre>
*
* <code>
* require_once 'XML/Util.php';
*
* $tag = array(
* "qname" => "foo:bar",
* "namespaceUri" => "http://foo.com",
* "attributes" => array( "key" => "value", "argh" => "fruit&vegetable" ),
* "content" => "I'm inside the tag",
* );
* // creating a tag with qualified name and namespaceUri
* $string = PEAR_PackageFile_Generator_v2_XML_Util::createTagFromArray($tag);
* </code>
*
* @access public
* @static
* @param array $tag tag definition
* @param integer $replaceEntities whether to replace XML special chars in content, embedd it in a CData section or none of both
* @param boolean $multiline whether to create a multiline tag where each attribute gets written to a single line
* @param string $indent string used to indent attributes (_auto indents attributes so they start at the same column)
* @param string $linebreak string used for linebreaks
* @return string $string XML tag
* @see PEAR_PackageFile_Generator_v2_XML_Util::createTag()
* @uses PEAR_PackageFile_Generator_v2_XML_Util::attributesToString() to serialize the attributes of the tag
* @uses PEAR_PackageFile_Generator_v2_XML_Util::splitQualifiedName() to get local part and namespace of a qualified name
*/
function createTagFromArray($tag, $replaceEntities = PEAR_PackageFile_Generator_v2_XML_Util_REPLACE_ENTITIES, $multiline = false, $indent = "_auto", $linebreak = "\n", $encoding = PEAR_PackageFile_Generator_v2_XML_Util_ENTITIES_XML)
{
if (isset($tag["content"]) && !is_scalar($tag["content"])) {
return PEAR_PackageFile_Generator_v2_XML_Util::raiseError( "Supplied non-scalar value as tag content", PEAR_PackageFile_Generator_v2_XML_Util_ERROR_NON_SCALAR_CONTENT );
}
 
if (!isset($tag['qname']) && !isset($tag['localPart'])) {
return PEAR_PackageFile_Generator_v2_XML_Util::raiseError( 'You must either supply a qualified name (qname) or local tag name (localPart).', PEAR_PackageFile_Generator_v2_XML_Util_ERROR_NO_TAG_NAME );
}
 
// if no attributes hav been set, use empty attributes
if (!isset($tag["attributes"]) || !is_array($tag["attributes"])) {
$tag["attributes"] = array();
}
// qualified name is not given
if (!isset($tag["qname"])) {
// check for namespace
if (isset($tag["namespace"]) && !empty($tag["namespace"])) {
$tag["qname"] = $tag["namespace"].":".$tag["localPart"];
} else {
$tag["qname"] = $tag["localPart"];
}
// namespace URI is set, but no namespace
} elseif (isset($tag["namespaceUri"]) && !isset($tag["namespace"])) {
$parts = PEAR_PackageFile_Generator_v2_XML_Util::splitQualifiedName($tag["qname"]);
$tag["localPart"] = $parts["localPart"];
if (isset($parts["namespace"])) {
$tag["namespace"] = $parts["namespace"];
}
}
 
if (isset($tag["namespaceUri"]) && !empty($tag["namespaceUri"])) {
// is a namespace given
if (isset($tag["namespace"]) && !empty($tag["namespace"])) {
$tag["attributes"]["xmlns:".$tag["namespace"]] = $tag["namespaceUri"];
} else {
// define this Uri as the default namespace
$tag["attributes"]["xmlns"] = $tag["namespaceUri"];
}
}
 
// check for multiline attributes
if ($multiline === true) {
if ($indent === "_auto") {
$indent = str_repeat(" ", (strlen($tag["qname"])+2));
}
}
// create attribute list
$attList = PEAR_PackageFile_Generator_v2_XML_Util::attributesToString($tag["attributes"], true, $multiline, $indent, $linebreak );
if (!isset($tag["content"]) || (string)$tag["content"] == '') {
$tag = sprintf("<%s%s />", $tag["qname"], $attList);
} else {
if ($replaceEntities == PEAR_PackageFile_Generator_v2_XML_Util_REPLACE_ENTITIES) {
$tag["content"] = PEAR_PackageFile_Generator_v2_XML_Util::replaceEntities($tag["content"], $encoding);
} elseif ($replaceEntities == PEAR_PackageFile_Generator_v2_XML_Util_CDATA_SECTION) {
$tag["content"] = PEAR_PackageFile_Generator_v2_XML_Util::createCDataSection($tag["content"]);
}
$tag = sprintf("<%s%s>%s</%s>", $tag["qname"], $attList, $tag["content"], $tag["qname"] );
}
return $tag;
}
 
/**
* create a start element
*
* <code>
* require_once 'XML/Util.php';
*
* // create an XML start element:
* $tag = PEAR_PackageFile_Generator_v2_XML_Util::createStartElement("myNs:myTag", array("foo" => "bar") ,"http://www.w3c.org/myNs#");
* </code>
*
* @access public
* @static
* @param string $qname qualified tagname (including namespace)
* @param array $attributes array containg attributes
* @param string $namespaceUri URI of the namespace
* @param boolean $multiline whether to create a multiline tag where each attribute gets written to a single line
* @param string $indent string used to indent attributes (_auto indents attributes so they start at the same column)
* @param string $linebreak string used for linebreaks
* @return string $string XML start element
* @see PEAR_PackageFile_Generator_v2_XML_Util::createEndElement(), PEAR_PackageFile_Generator_v2_XML_Util::createTag()
*/
function createStartElement($qname, $attributes = array(), $namespaceUri = null, $multiline = false, $indent = '_auto', $linebreak = "\n")
{
// if no attributes hav been set, use empty attributes
if (!isset($attributes) || !is_array($attributes)) {
$attributes = array();
}
if ($namespaceUri != null) {
$parts = PEAR_PackageFile_Generator_v2_XML_Util::splitQualifiedName($qname);
}
 
// check for multiline attributes
if ($multiline === true) {
if ($indent === "_auto") {
$indent = str_repeat(" ", (strlen($qname)+2));
}
}
 
if ($namespaceUri != null) {
// is a namespace given
if (isset($parts["namespace"]) && !empty($parts["namespace"])) {
$attributes["xmlns:".$parts["namespace"]] = $namespaceUri;
} else {
// define this Uri as the default namespace
$attributes["xmlns"] = $namespaceUri;
}
}
 
// create attribute list
$attList = PEAR_PackageFile_Generator_v2_XML_Util::attributesToString($attributes, true, $multiline, $indent, $linebreak);
$element = sprintf("<%s%s>", $qname, $attList);
return $element;
}
 
/**
* create an end element
*
* <code>
* require_once 'XML/Util.php';
*
* // create an XML start element:
* $tag = PEAR_PackageFile_Generator_v2_XML_Util::createEndElement("myNs:myTag");
* </code>
*
* @access public
* @static
* @param string $qname qualified tagname (including namespace)
* @return string $string XML end element
* @see PEAR_PackageFile_Generator_v2_XML_Util::createStartElement(), PEAR_PackageFile_Generator_v2_XML_Util::createTag()
*/
function createEndElement($qname)
{
$element = sprintf("</%s>", $qname);
return $element;
}
/**
* create an XML comment
*
* <code>
* require_once 'XML/Util.php';
*
* // create an XML start element:
* $tag = PEAR_PackageFile_Generator_v2_XML_Util::createComment("I am a comment");
* </code>
*
* @access public
* @static
* @param string $content content of the comment
* @return string $comment XML comment
*/
function createComment($content)
{
$comment = sprintf("<!-- %s -->", $content);
return $comment;
}
/**
* create a CData section
*
* <code>
* require_once 'XML/Util.php';
*
* // create a CData section
* $tag = PEAR_PackageFile_Generator_v2_XML_Util::createCDataSection("I am content.");
* </code>
*
* @access public
* @static
* @param string $data data of the CData section
* @return string $string CData section with content
*/
function createCDataSection($data)
{
return sprintf("<![CDATA[%s]]>", $data);
}
 
/**
* split qualified name and return namespace and local part
*
* <code>
* require_once 'XML/Util.php';
*
* // split qualified tag
* $parts = PEAR_PackageFile_Generator_v2_XML_Util::splitQualifiedName("xslt:stylesheet");
* </code>
* the returned array will contain two elements:
* <pre>
* array(
* "namespace" => "xslt",
* "localPart" => "stylesheet"
* );
* </pre>
*
* @access public
* @static
* @param string $qname qualified tag name
* @param string $defaultNs default namespace (optional)
* @return array $parts array containing namespace and local part
*/
function splitQualifiedName($qname, $defaultNs = null)
{
if (strstr($qname, ':')) {
$tmp = explode(":", $qname);
return array(
"namespace" => $tmp[0],
"localPart" => $tmp[1]
);
}
return array(
"namespace" => $defaultNs,
"localPart" => $qname
);
}
 
/**
* check, whether string is valid XML name
*
* <p>XML names are used for tagname, attribute names and various
* other, lesser known entities.</p>
* <p>An XML name may only consist of alphanumeric characters,
* dashes, undescores and periods, and has to start with a letter
* or an underscore.
* </p>
*
* <code>
* require_once 'XML/Util.php';
*
* // verify tag name
* $result = PEAR_PackageFile_Generator_v2_XML_Util::isValidName("invalidTag?");
* if (PEAR_PackageFile_Generator_v2_XML_Util::isError($result)) {
* print "Invalid XML name: " . $result->getMessage();
* }
* </code>
*
* @access public
* @static
* @param string $string string that should be checked
* @return mixed $valid true, if string is a valid XML name, PEAR error otherwise
* @todo support for other charsets
*/
function isValidName($string)
{
// check for invalid chars
if (!preg_match("/^[[:alnum:]_\-.]$/", $string{0})) {
return PEAR_PackageFile_Generator_v2_XML_Util::raiseError( "XML names may only start with letter or underscore", PEAR_PackageFile_Generator_v2_XML_Util_ERROR_INVALID_START );
}
// check for invalid chars
if (!preg_match("/^([a-zA-Z_]([a-zA-Z0-9_\-\.]*)?:)?[a-zA-Z_]([a-zA-Z0-9_\-\.]+)?$/", $string)) {
return PEAR_PackageFile_Generator_v2_XML_Util::raiseError( "XML names may only contain alphanumeric chars, period, hyphen, colon and underscores", PEAR_PackageFile_Generator_v2_XML_Util_ERROR_INVALID_CHARS );
}
// XML name is valid
return true;
}
 
/**
* replacement for PEAR_PackageFile_Generator_v2_XML_Util::raiseError
*
* Avoids the necessity to always require
* PEAR.php
*
* @access public
* @param string error message
* @param integer error code
* @return object PEAR_Error
*/
function raiseError($msg, $code)
{
require_once 'PEAR.php';
return PEAR::raiseError($msg, $code);
}
}
?>
/trunk/bibliotheque/pear/PEAR/PackageFile/v2/Validator.php
1,28 → 1,27
<?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: Greg Beaver <cellog@php.net> |
// | |
// +----------------------------------------------------------------------+
//
// $Id: Validator.php,v 1.97 2007/02/10 05:56:18 cellog Exp $
/**
* PEAR_PackageFile_v2, package.xml version 2.0, 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
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a8
*/
/**
* Private validation class used by PEAR_PackageFile_v2 - do not use directly, its
* sole purpose is to split up the PEAR/PackageFile/v2.php file to make it smaller
* @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.10.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a8
* @author Greg Beaver <cellog@php.net>
* @access private
*/
class PEAR_PackageFile_v2_Validator
72,8 → 71,7
}
if (!isset($this->_packageInfo['attribs']['version']) ||
($this->_packageInfo['attribs']['version'] != '2.0' &&
$this->_packageInfo['attribs']['version'] != '2.1')
) {
$this->_packageInfo['attribs']['version'] != '2.1')) {
$this->_noPackageVersion();
}
$structure =
111,10 → 109,8
isset($test['dependencies']['required']) &&
isset($test['dependencies']['required']['pearinstaller']) &&
isset($test['dependencies']['required']['pearinstaller']['min']) &&
'1.10.1' != '@package' . '_version@' &&
version_compare('1.10.1',
$test['dependencies']['required']['pearinstaller']['min'], '<')
) {
version_compare('1.5.1',
$test['dependencies']['required']['pearinstaller']['min'], '<')) {
$this->_pearVersionTooLow($test['dependencies']['required']['pearinstaller']['min']);
return false;
}
134,13 → 130,18
if (array_key_exists('_lastversion', $test)) {
unset($test['_lastversion']);
}
if (!$this->_stupidSchemaValidate($structure, $test, '<package>')) {
if (!$this->_stupidSchemaValidate($structure,
$test, '<package>')) {
return false;
}
if (empty($this->_packageInfo['name'])) {
$this->_tagCannotBeEmpty('name');
}
$test = isset($this->_packageInfo['uri']) ? 'uri' :'channel';
if (isset($this->_packageInfo['uri'])) {
$test = 'uri';
} else {
$test = 'channel';
}
if (empty($this->_packageInfo[$test])) {
$this->_tagCannotBeEmpty($test);
}
232,17 → 233,14
}
}
}
 
if ($fail) {
return false;
}
 
$list = $this->_packageInfo['contents'];
if (isset($list['dir']) && is_array($list['dir']) && isset($list['dir'][0])) {
$this->_multipleToplevelDirNotAllowed();
return $this->_isValid = 0;
}
 
$this->_validateFilelist();
$this->_validateRelease();
if (!$this->_stack->hasErrors()) {
256,10 → 254,11
$validator = $chan->getValidationObject($this->_pf->getPackage());
if (!$validator) {
$this->_stack->push(__FUNCTION__, 'error',
array('channel' => $chan->getName(),
'package' => $this->_pf->getPackage(),
'name' => $valpack['_content'],
'version' => $valpack['attribs']['version']),
array_merge(
array('channel' => $chan->getName(),
'package' => $this->_pf->getPackage()),
$valpack
),
'package "%channel%/%package%" cannot be properly validated without ' .
'validation package "%channel%/%name%-%version%"');
return $this->_isValid = 0;
277,7 → 276,6
}
}
}
 
$this->_pf->_isValid = $this->_isValid = !$this->_stack->hasErrors('error');
if ($this->_isValid && $state == PEAR_VALIDATE_PACKAGING && !$this->_filesValid) {
if ($this->_pf->getPackageType() == 'bundle') {
294,11 → 292,9
}
}
}
 
if ($this->_isValid) {
return $this->_pf->_isValid = $this->_isValid = $state;
}
 
return $this->_pf->_isValid = $this->_isValid = 0;
}
 
470,21 → 466,21
$a = $this->_stupidSchemaValidate($structure, $this->_packageInfo['version'], '<version>');
$a &= $this->_stupidSchemaValidate($structure, $this->_packageInfo['stability'], '<stability>');
if ($a) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/',
$this->_packageInfo['version']['release'])) {
$this->_invalidVersion('release', $this->_packageInfo['version']['release']);
}
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/',
$this->_packageInfo['version']['api'])) {
$this->_invalidVersion('api', $this->_packageInfo['version']['api']);
}
if (!in_array($this->_packageInfo['stability']['release'],
array('snapshot', 'devel', 'alpha', 'beta', 'stable'))) {
$this->_invalidState('release', $this->_packageInfo['stability']['release']);
$this->_invalidState('release', $this->_packageinfo['stability']['release']);
}
if (!in_array($this->_packageInfo['stability']['api'],
array('devel', 'alpha', 'beta', 'stable'))) {
$this->_invalidState('api', $this->_packageInfo['stability']['api']);
$this->_invalidState('api', $this->_packageinfo['stability']['api']);
}
}
}
523,13 → 519,13
$type = $installcondition ? '<installcondition><php>' : '<dependencies><required><php>';
$this->_stupidSchemaValidate($structure, $dep, $type);
if (isset($dep['min'])) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?(?:-[a-zA-Z0-9]+)?\\z/',
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?(?:-[a-zA-Z0-9]+)?$/',
$dep['min'])) {
$this->_invalidVersion($type . '<min>', $dep['min']);
}
}
if (isset($dep['max'])) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?(?:-[a-zA-Z0-9]+)?\\z/',
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?(?:-[a-zA-Z0-9]+)?$/',
$dep['max'])) {
$this->_invalidVersion($type . '<max>', $dep['max']);
}
540,7 → 536,7
}
foreach ($dep['exclude'] as $exclude) {
if (!preg_match(
'/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?(?:-[a-zA-Z0-9]+)?\\z/',
'/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?(?:-[a-zA-Z0-9]+)?$/',
$exclude)) {
$this->_invalidVersion($type . '<exclude>', $exclude);
}
558,7 → 554,7
);
$this->_stupidSchemaValidate($structure, $dep, '<dependencies><required><pearinstaller>');
if (isset($dep['min'])) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/',
$dep['min'])) {
$this->_invalidVersion('<dependencies><required><pearinstaller><min>',
$dep['min']);
565,7 → 561,7
}
}
if (isset($dep['max'])) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/',
$dep['max'])) {
$this->_invalidVersion('<dependencies><required><pearinstaller><max>',
$dep['max']);
572,7 → 568,7
}
}
if (isset($dep['recommended'])) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/',
$dep['recommended'])) {
$this->_invalidVersion('<dependencies><required><pearinstaller><recommended>',
$dep['recommended']);
583,7 → 579,7
$dep['exclude'] = array($dep['exclude']);
}
foreach ($dep['exclude'] as $exclude) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/',
$exclude)) {
$this->_invalidVersion('<dependencies><required><pearinstaller><exclude>',
$exclude);
645,19 → 641,19
$this->_DepchannelCannotBeUri('<dependencies>' . $group . $type);
}
if (isset($dep['min'])) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/',
$dep['min'])) {
$this->_invalidVersion('<dependencies>' . $group . $type . '<min>', $dep['min']);
}
}
if (isset($dep['max'])) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/',
$dep['max'])) {
$this->_invalidVersion('<dependencies>' . $group . $type . '<max>', $dep['max']);
}
}
if (isset($dep['recommended'])) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/',
$dep['recommended'])) {
$this->_invalidVersion('<dependencies>' . $group . $type . '<recommended>',
$dep['recommended']);
668,7 → 664,7
$dep['exclude'] = array($dep['exclude']);
}
foreach ($dep['exclude'] as $exclude) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/',
$exclude)) {
$this->_invalidVersion('<dependencies>' . $group . $type . '<exclude>',
$exclude);
717,19 → 713,19
}
$this->_stupidSchemaValidate($structure, $dep, $type);
if (isset($dep['min'])) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/',
$dep['min'])) {
$this->_invalidVersion(substr($type, 1) . '<min', $dep['min']);
}
}
if (isset($dep['max'])) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/',
$dep['max'])) {
$this->_invalidVersion(substr($type, 1) . '<max', $dep['max']);
}
}
if (isset($dep['recommended'])) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/',
$dep['recommended'])) {
$this->_invalidVersion(substr($type, 1) . '<recommended', $dep['recommended']);
}
739,7 → 735,7
$dep['exclude'] = array($dep['exclude']);
}
foreach ($dep['exclude'] as $exclude) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/',
$exclude)) {
$this->_invalidVersion(substr($type, 1) . '<exclude', $exclude);
}
936,13 → 932,13
}
$this->_stupidSchemaValidate($required, $package, $type);
if (is_array($package) && array_key_exists('min', $package)) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/',
$package['min'])) {
$this->_invalidVersion(substr($type, 1) . '<min', $package['min']);
}
}
if (is_array($package) && array_key_exists('max', $package)) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/',
$package['max'])) {
$this->_invalidVersion(substr($type, 1) . '<max', $package['max']);
}
952,7 → 948,7
$package['exclude'] = array($package['exclude']);
}
foreach ($package['exclude'] as $exclude) {
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/',
if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?$/',
$exclude)) {
$this->_invalidVersion(substr($type, 1) . '<exclude', $exclude);
}
1011,11 → 1007,6
$dirname = $iscontents ? '<contents>' : $unknown;
} else {
$dirname = '<dir name="' . $list['attribs']['name'] . '">';
if (preg_match('~/\.\.?(/|\\z)|^\.\.?/~',
str_replace('\\', '/', $list['attribs']['name']))) {
// file contains .. parent directory or . cur directory
$this->_invalidDirName($list['attribs']['name']);
}
}
$res = $this->_stupidSchemaValidate($struc, $list, $dirname);
if ($allowignore && $res) {
1045,12 → 1036,6
$ignored_or_installed[$file['attribs']['name']] = array();
}
$ignored_or_installed[$file['attribs']['name']][] = 1;
if (preg_match('~/\.\.?(/|\\z)|^\.\.?/~',
str_replace('\\', '/', $file['attribs']['as']))) {
// file contains .. parent directory or . cur directory references
$this->_invalidFileInstallAs($file['attribs']['name'],
$file['attribs']['as']);
}
}
}
if (isset($list['ignore'])) {
1069,10 → 1054,6
}
}
if (!$allowignore && isset($list['file'])) {
if (is_string($list['file'])) {
$this->_oldStyleFileNotAllowed();
return false;
}
if (!isset($list['file'][0])) {
// single file
$list['file'] = array($list['file']);
1079,17 → 1060,11
}
foreach ($list['file'] as $i => $file)
{
if (isset($file['attribs']) && isset($file['attribs']['name'])) {
if ($file['attribs']['name']{0} == '.' &&
$file['attribs']['name']{1} == '/') {
// name is something like "./doc/whatever.txt"
$this->_invalidFileName($file['attribs']['name'], $dirname);
}
if (preg_match('~/\.\.?(/|\\z)|^\.\.?/~',
str_replace('\\', '/', $file['attribs']['name']))) {
// file contains .. parent directory or . cur directory
$this->_invalidFileName($file['attribs']['name'], $dirname);
}
if (isset($file['attribs']) && isset($file['attribs']['name']) &&
$file['attribs']['name']{0} == '.' &&
$file['attribs']['name']{1} == '/') {
// name is something like "./doc/whatever.txt"
$this->_invalidFileName($file['attribs']['name']);
}
if (isset($file['attribs']) && isset($file['attribs']['role'])) {
if (!$this->_validateRole($file['attribs']['role'])) {
1329,7 → 1304,7
}
if (is_array($rel) && array_key_exists('filelist', $rel)) {
if ($rel['filelist']) {
 
$this->_validateFilelist($rel['filelist'], true);
}
}
1350,7 → 1325,7
$this->_stack->push(__FUNCTION__, 'error',
array('version' => $version),
'This package.xml requires PEAR version %version% to parse properly, we are ' .
'version 1.10.1');
'version 1.5.1');
}
 
function _invalidTagOrder($oktags, $actual, $root)
1374,13 → 1349,6
'<contents>, use <ignore> and <install> only');
}
 
function _oldStyleFileNotAllowed()
{
$this->_stack->push(__FUNCTION__, 'error', array(),
'Old-style <file>name</file> is not allowed. Use' .
'<file name="name" role="role"/>');
}
 
function _tagMissingAttribute($tag, $attr, $context)
{
$this->_stack->push(__FUNCTION__, 'error', array('tag' => $tag,
1413,23 → 1381,9
{
$this->_stack->push(__FUNCTION__, 'error', array(
'file' => $file),
'File "%file%" in directory "%dir%" cannot begin with "./" or contain ".."');
'File "%file%" cannot begin with "."');
}
 
function _invalidFileInstallAs($file, $as)
{
$this->_stack->push(__FUNCTION__, 'error', array(
'file' => $file, 'as' => $as),
'File "%file%" <install as="%as%"/> cannot contain "./" or contain ".."');
}
 
function _invalidDirName($dir)
{
$this->_stack->push(__FUNCTION__, 'error', array(
'dir' => $file),
'Directory "%dir%" cannot begin with "./" or contain ".."');
}
 
function _filelistCannotContainFile($filelist)
{
$this->_stack->push(__FUNCTION__, 'error', array('tag' => $filelist),
1671,13 → 1625,13
function _usesroletaskMustHaveChannelOrUri($role, $tag)
{
$this->_stack->push(__FUNCTION__, 'error', array('role' => $role, 'tag' => $tag),
'<%tag%> for role "%role%" must contain either <uri>, or <channel> and <package>');
'<%tag%> must contain either <uri>, or <channel> and <package>');
}
 
function _usesroletaskMustHavePackage($role, $tag)
{
$this->_stack->push(__FUNCTION__, 'error', array('role' => $role, 'tag' => $tag),
'<%tag%> for role "%role%" must contain <package>');
'<%tag%> must contain <package>');
}
 
function _usesroletaskMustHaveRoleTask($tag, $type)
1694,7 → 1648,7
 
function _invalidDepGroupName($name)
{
$this->_stack->push(__FUNCTION__, 'error', array('name' => $name),
$this->_stack->push(__FUNCTION__, 'error', array('group' => $name),
'Invalid dependency group name "%name%"');
}
 
1729,15 → 1683,14
return false;
}
$dir_prefix = dirname($this->_pf->_packageFile);
$common = new PEAR_Common;
$log = isset($this->_pf->_logger) ? array(&$this->_pf->_logger, 'log') :
array($common, 'log');
array('PEAR_Common', 'log');
$info = $this->_pf->getContents();
$info = $info['bundledpackage'];
if (!is_array($info)) {
$info = array($info);
}
$pkg = new PEAR_PackageFile($this->_pf->_config);
$pkg = &new PEAR_PackageFile($this->_pf->_config);
foreach ($info as $package) {
if (!file_exists($dir_prefix . DIRECTORY_SEPARATOR . $package)) {
$this->_fileNotFound($dir_prefix . DIRECTORY_SEPARATOR . $package);
1845,19 → 1798,15
'Parser error: token_get_all() function must exist to analyze source code, PHP may have been compiled with --disable-tokenizer');
return false;
}
 
if (!defined('T_DOC_COMMENT')) {
define('T_DOC_COMMENT', T_COMMENT);
}
 
if (!defined('T_INTERFACE')) {
define('T_INTERFACE', -1);
}
 
if (!defined('T_IMPLEMENTS')) {
define('T_IMPLEMENTS', -1);
}
 
if ($string) {
$contents = $file;
} else {
1867,18 → 1816,7
fclose($fp);
$contents = file_get_contents($file);
}
 
// Silence this function so we can catch PHP Warnings and show our own custom message
$tokens = @token_get_all($contents);
if (isset($php_errormsg)) {
if (isset($this->_stack)) {
$pn = $this->_pf->getPackage();
$this->_stack->push(__FUNCTION__, 'warning',
array('file' => $file, 'package' => $pn),
'in %file%: Could not process file for unknown reasons,' .
' possibly a PHP parse error in %file% from %package%');
}
}
$tokens = token_get_all($contents);
/*
for ($i = 0; $i < sizeof($tokens); $i++) {
@list($token, $data) = $tokens[$i];
1918,7 → 1856,6
$token = $tokens[$i];
$data = '';
}
 
if ($inquote) {
if ($token != '"' && $token != T_END_HEREDOC) {
continue;
1927,7 → 1864,6
continue;
}
}
 
switch ($token) {
case T_WHITESPACE :
continue;
1963,14 → 1899,8
$interface = true;
case T_CLASS:
if (($current_class_level != -1) || ($current_function_level != -1)) {
if (isset($this->_stack)) {
$this->_stack->push(__FUNCTION__, 'error', array('file' => $file),
'Parser error: invalid PHP found in file "%file%"');
} else {
PEAR::raiseError("Parser error: invalid PHP found in file \"$file\"",
PEAR_COMMON_ERROR_INVALIDPHP);
}
 
$this->_stack->push(__FUNCTION__, 'error', array('file' => $file),
'Parser error: invalid PHP found in file "%file%"');
return false;
}
case T_FUNCTION:
1980,6 → 1910,17
$look_for = $token;
continue 2;
case T_STRING:
if (version_compare(zend_version(), '2.0', '<')) {
if (in_array(strtolower($data),
array('public', 'private', 'protected', 'abstract',
'interface', 'implements', 'throw')
)) {
$this->_stack->push(__FUNCTION__, 'warning', array(
'file' => $file),
'Error, PHP5 token encountered in %file%,' .
' analysis should be in PHP5');
}
}
if ($look_for == T_CLASS) {
$current_class = $data;
$current_class_level = $brace_level;
2003,13 → 1944,11
$current_function = $data;
$declared_functions[] = $current_function;
}
 
$current_function_level = $brace_level;
$m = array();
} elseif ($look_for == T_NEW) {
$used_classes[$data] = true;
}
 
$look_for = 0;
continue 2;
case T_VARIABLE:
2025,28 → 1964,18
}
continue 2;
case T_DOUBLE_COLON:
$token = $tokens[$i - 1][0];
if (!($token == T_WHITESPACE || $token == T_STRING || $token == T_STATIC || $token == T_VARIABLE)) {
if (isset($this->_stack)) {
$this->_stack->push(__FUNCTION__, 'warning', array('file' => $file),
'Parser error: invalid PHP found in file "%file%"');
} else {
PEAR::raiseError("Parser error: invalid PHP found in file \"$file\"",
PEAR_COMMON_ERROR_INVALIDPHP);
}
 
if (!($tokens[$i - 1][0] == T_WHITESPACE || $tokens[$i - 1][0] == T_STRING)) {
$this->_stack->push(__FUNCTION__, 'warning', array('file' => $file),
'Parser error: invalid PHP found in file "%file%"');
return false;
}
 
$class = $tokens[$i - 1][1];
if (strtolower($class) != 'parent') {
$used_classes[$class] = true;
}
 
continue 2;
}
}
 
return array(
"source_file" => $file,
"declared_classes" => $declared_classes,
2056,7 → 1985,7
"used_classes" => array_diff(array_keys($used_classes), $nodeps),
"inheritance" => $extends,
"implements" => $implements,
);
);
}
 
/**
2083,17 → 2012,15
if (!$this->_isValid) {
return array();
}
 
$providesret = array();
$file = basename($srcinfo['source_file']);
$pn = isset($this->_pf) ? $this->_pf->getPackage() : '';
$pnl = strlen($pn);
$file = basename($srcinfo['source_file']);
$pn = $this->_pf->getPackage();
$pnl = strlen($pn);
foreach ($srcinfo['declared_classes'] as $class) {
$key = "class;$class";
if (isset($providesret[$key])) {
continue;
}
 
$providesret[$key] =
array('file'=> $file, 'type' => 'class', 'name' => $class);
if (isset($srcinfo['inheritance'][$class])) {
2101,7 → 2028,6
$srcinfo['inheritance'][$class];
}
}
 
foreach ($srcinfo['declared_methods'] as $class => $methods) {
foreach ($methods as $method) {
$function = "$class::$method";
2110,7 → 2036,6
isset($providesret[$key])) {
continue;
}
 
$providesret[$key] =
array('file'=> $file, 'type' => 'function', 'name' => $function);
}
2121,15 → 2046,13
if ($function{0} == '_' || isset($providesret[$key])) {
continue;
}
 
if (!strstr($function, '::') && strncasecmp($function, $pn, $pnl)) {
$warnings[] = "in1 " . $file . ": function \"$function\" not prefixed with package name \"$pn\"";
}
 
$providesret[$key] =
array('file'=> $file, 'type' => 'function', 'name' => $function);
}
 
return $providesret;
}
}
?>
/trunk/bibliotheque/pear/PEAR/PackageFile/v2/rw.php
4,11 → 4,18
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: rw.php,v 1.19 2006/10/30 04:12:02 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a8
*/
20,9 → 27,9
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a8
*/
101,7 → 108,7
$this->_isValid = 0;
if (!isset($this->_packageInfo['uri'])) {
// ensure that the uri tag is set up in the right location
$this->_packageInfo = $this->_insertBefore($this->_packageInfo,
$this->_packageInfo = $this->_insertBefore($this->_packageInfo,
array('extends', 'summary', 'description', 'lead',
'developer', 'contributor', 'helper', 'date', 'time', 'version',
'stability', 'license', 'notes', 'contents', 'compatible',
241,7 → 248,7
}
}
foreach ($info as $i => $maintainer) {
if (is_array($maintainer) && $maintainer['user'] == $handle) {
if ($maintainer['user'] == $handle) {
$found = $i;
break 2;
}
451,13 → 458,11
'bundle', 'changelog'), array(), 'contents');
}
if ($this->getPackageType() != 'bundle') {
$this->_packageInfo['contents'] =
$this->_packageInfo['contents'] =
array('dir' => array('attribs' => array('name' => '/')));
if ($baseinstall) {
$this->_packageInfo['contents']['dir']['attribs']['baseinstalldir'] = $baseinstall;
}
} else {
$this->_packageInfo['contents'] = array('bundledpackage' => array());
}
}
 
1220,26 → 1225,21
'zendextbin', 'bundle'))) {
return false;
}
 
if (in_array($type, array('zendextsrc', 'zendextbin'))) {
$this->_setPackageVersion2_1();
}
 
if ($type != 'bundle') {
$type .= 'release';
}
 
foreach (array('phprelease', 'extbinrelease', 'extsrcrelease',
'zendextsrcrelease', 'zendextbinrelease', 'bundle') as $test) {
unset($this->_packageInfo[$test]);
}
 
if (!isset($this->_packageInfo[$type])) {
// ensure that the release tag is set up
$this->_packageInfo = $this->_insertBefore($this->_packageInfo, array('changelog'),
array(), $type);
}
 
$this->_packageInfo[$type] = array();
return true;
}
1359,17 → 1359,14
if ($this->getPackageType() != 'extsrc' && $this->getPackageType() != 'zendextsrc') {
return false;
}
 
$r = &$this->_getCurrentRelease(false);
if ($r === null) {
return false;
}
 
$opt = array('attribs' => array('name' => $name, 'prompt' => $prompt));
if ($default !== null) {
$opt['attribs']['default'] = $default;
$opt['default'] = $default;
}
 
$this->_isValid = 0;
$r = $this->_mergeTag($r, $opt,
array(
1547,7 → 1544,7
function generateChangeLogEntry($notes = false)
{
return array(
'version' =>
'version' =>
array(
'release' => $this->getVersion('release'),
'api' => $this->getVersion('api'),
1600,4 → 1597,5
{
unset($this->_packageInfo['changelog']);
}
}
}
?>
/trunk/bibliotheque/pear/PEAR/Installer/Role/Www.xml
File deleted
\ No newline at end of file
/trunk/bibliotheque/pear/PEAR/Installer/Role/Cfg.php
File deleted
\ No newline at end of file
/trunk/bibliotheque/pear/PEAR/Installer/Role/Cfg.xml
File deleted
\ No newline at end of file
/trunk/bibliotheque/pear/PEAR/Installer/Role/Man.php
File deleted
/trunk/bibliotheque/pear/PEAR/Installer/Role/Man.xml
File deleted
/trunk/bibliotheque/pear/PEAR/Installer/Role/Www.php
File deleted
\ No newline at end of file
/trunk/bibliotheque/pear/PEAR/Installer/Role/Ext.php
4,11 → 4,18
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Ext.php,v 1.6 2006/01/06 04:47:37 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
17,9 → 24,9
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
/trunk/bibliotheque/pear/PEAR/Installer/Role/Src.xml
1,8 → 1,8
<role version="1.0">
<releasetypes>extsrc</releasetypes>
<releasetypes>zendextsrc</releasetypes>
<installable>1</installable>
<locationconfig>temp_dir</locationconfig>
<installable />
<locationconfig />
<honorsbaseinstall />
<unusualbaseinstall />
<phpfile />
/trunk/bibliotheque/pear/PEAR/Installer/Role/Script.php
4,11 → 4,18
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Script.php,v 1.6 2006/01/06 04:47:37 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
17,9 → 24,9
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
/trunk/bibliotheque/pear/PEAR/Installer/Role/Doc.php
4,11 → 4,18
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Doc.php,v 1.6 2006/01/06 04:47:37 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
17,9 → 24,9
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
/trunk/bibliotheque/pear/PEAR/Installer/Role/Php.php
4,11 → 4,18
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Php.php,v 1.7 2006/01/06 04:47:37 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
17,9 → 24,9
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
/trunk/bibliotheque/pear/PEAR/Installer/Role/Src.php
4,11 → 4,18
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Src.php,v 1.6 2006/01/06 04:47:37 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
17,9 → 24,9
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
/trunk/bibliotheque/pear/PEAR/Installer/Role/Common.php
4,11 → 4,18
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Common.php,v 1.12 2006/10/19 23:55:32 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
22,8 → 29,8
* @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.10.1
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
38,7 → 45,7
/**
* @param PEAR_Config
*/
function __construct(&$config)
function PEAR_Installer_Role_Common(&$config)
{
$this->config = $config;
}
170,4 → 177,4
return $roleInfo['phpextension'];
}
}
?>
?>
/trunk/bibliotheque/pear/PEAR/Installer/Role/Data.php
4,11 → 4,18
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Data.php,v 1.6 2006/01/06 04:47:37 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
17,9 → 24,9
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
/trunk/bibliotheque/pear/PEAR/Installer/Role/Test.php
4,11 → 4,18
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Test.php,v 1.6 2006/01/06 04:47:37 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
17,9 → 24,9
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
/trunk/bibliotheque/pear/PEAR/Installer/Role.php
4,11 → 4,18
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Role.php,v 1.16 2006/10/31 02:54:41 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
22,9 → 29,9
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
35,19 → 42,19
*
* Never call this directly, it is called by the PEAR_Config constructor
* @param PEAR_Config
* @access private
* @static
*/
public static function initializeConfig(&$config)
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']);
$config->_addConfigVars($info['config_vars']);
}
}
 
56,23 → 63,21
* @param string role name
* @param PEAR_Config
* @return PEAR_Installer_Role_Common
* @static
*/
public static function &factory($pkg, $role, &$config)
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;
}
84,22 → 89,20
* @param string
* @param bool clear cache
* @return array
* @static
*/
public static function getValidRoles($release, $clear = false)
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'])) {
106,7 → 109,6
$ret[$release][] = strtolower(str_replace('PEAR_Installer_Role_', '', $role));
}
}
 
return $ret[$release];
}
 
118,29 → 120,25
* roles are actually fully bundled releases of a package
* @param bool clear cache
* @return array
* @static
*/
public static function getInstallableRoles($clear = false)
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));
if (!isset($ret)) {
$ret = array();
foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) {
if ($okreleases['installable']) {
$ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role));
}
}
}
 
return $ret;
}
 
152,29 → 150,25
* so a tests file tests/file.phpt is installed into PackageName/tests/filepath.php
* @param bool clear cache
* @return array
* @static
*/
public static function getBaseinstallRoles($clear = false)
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));
if (!isset($ret)) {
$ret = array();
foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) {
if ($okreleases['honorsbaseinstall']) {
$ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role));
}
}
}
 
return $ret;
}
 
183,29 → 177,25
* like the "php" role.
* @param bool clear cache
* @return array
* @static
*/
public static function getPhpRoles($clear = false)
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));
if (!isset($ret)) {
$ret = array();
foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) {
if ($okreleases['phpfile']) {
$ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role));
}
}
}
 
return $ret;
}
 
218,8 → 208,10
* included.
*
* @return bool TRUE on success, a PEAR error on failure
* @access public
* @static
*/
public static function registerRoles($dir = null)
function registerRoles($dir = null)
{
$GLOBALS['_PEAR_INSTALLER_ROLES'] = array();
$parser = new PEAR_XMLParser;
226,21 → 218,17
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");
return PEAR::raiseError("registerRoles: opendir($dir) failed");
}
 
$dp = @opendir($dir);
if (empty($dp)) {
return PEAR::raiseError("registerRoles: opendir($dir) failed: $php_errmsg");
return PEAR::raiseError("registerRoles: opendir($dir) failed");
}
 
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])) {
250,11 → 238,9
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);
263,4 → 249,5
PEAR_Installer_Role::getValidRoles('****', true);
return true;
}
}
}
?>
/trunk/bibliotheque/pear/PEAR/ChannelFile.php
4,11 → 4,18
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: ChannelFile.php,v 1.78 2006/10/31 02:54:40 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
65,11 → 72,11
*/
define('PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY', 9);
/**
* Error code when channel server is missing for protocol
* Error code when channel server is missing for xmlrpc or soap protocol
*/
define('PEAR_CHANNELFILE_ERROR_NO_HOST', 10);
/**
* Error code when channel server is invalid for protocol
* Error code when channel server is invalid for xmlrpc or soap protocol
*/
define('PEAR_CHANNELFILE_ERROR_INVALID_HOST', 11);
/**
121,11 → 128,11
* Error code when <baseurl> contains no type attribute in a <rest> protocol definition
*/
define('PEAR_CHANNELFILE_ERROR_NOBASEURLTYPE', 35);
/**
/**
* Error code when a mirror is defined and the channel.xml represents the __uri pseudo-channel
*/
define('PEAR_CHANNELFILE_URI_CANT_MIRROR', 36);
/**
/**
* Error code when ssl attribute is present and is not "yes"
*/
define('PEAR_CHANNELFILE_ERROR_INVALID_SSL', 37);
143,14 → 150,13
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_ChannelFile
{
class PEAR_ChannelFile {
/**
* @access private
* @var PEAR_ErrorStack
157,7 → 163,7
* @access private
*/
var $_stack;
 
/**
* Supported channel.xml versions, for parsing
* @var array
185,7 → 191,7
* @access private
*/
var $_mirrorIndex;
 
/**
* Flag used to determine the validity of parsed content
* @var boolean
193,13 → 199,13
*/
var $_isValid = false;
 
function __construct()
function PEAR_ChannelFile()
{
$this->_stack = new PEAR_ErrorStack('PEAR_ChannelFile');
$this->_stack = &new PEAR_ErrorStack('PEAR_ChannelFile');
$this->_stack->setErrorMessageTemplate($this->_getErrorMessage());
$this->_isValid = false;
}
 
/**
* @return array
* @access protected
278,7 → 284,7
if ($result !== true) {
if ($result->getCode() == 1) {
$this->_stack->push(PEAR_CHANNELFILE_ERROR_NO_XML_EXT, 'error',
array('error' => $result->getMessage()));
array('error' => $error));
} else {
$this->_stack->push(PEAR_CHANNELFILE_ERROR_CANT_MAKE_PARSER, 'error');
}
291,7 → 297,7
return false;
}
}
 
/**
* @return array
*/
302,15 → 308,14
}
return $this->_channelInfo;
}
 
/**
* @param array
*
* @static
* @return PEAR_ChannelFile|false false if invalid
*/
public static function &fromArray(
$data, $compatibility = false, $stackClass = 'PEAR_ErrorStack'
) {
function &fromArray($data, $compatibility = false, $stackClass = 'PEAR_ErrorStack')
{
$a = new PEAR_ChannelFile($compatibility, $stackClass);
$a->_fromArray($data);
if (!$a->validate()) {
322,19 → 327,18
 
/**
* Unlike {@link fromArray()} this does not do any validation
*
* @param array
*
* @static
* @return PEAR_ChannelFile
*/
public static function &fromArrayWithErrors(
$data, $compatibility = false, $stackClass = 'PEAR_ErrorStack'
) {
function &fromArrayWithErrors($data, $compatibility = false,
$stackClass = 'PEAR_ErrorStack')
{
$a = new PEAR_ChannelFile($compatibility, $stackClass);
$a->_fromArray($data);
return $a;
}
 
/**
* @param array
* @access private
343,7 → 347,7
{
$this->_channelInfo = $data;
}
 
/**
* Wrapper to {@link PEAR_ErrorStack::getErrors()}
* @param boolean determines whether to purge the error stack after retrieving
480,9 → 484,15
$ret .= ' port="' . $channelInfo['servers']['primary']['attribs']['port'] . '"';
}
$ret .= ">\n";
if (isset($channelInfo['servers']['primary']['xmlrpc'])) {
$ret .= $this->_makeXmlrpcXml($channelInfo['servers']['primary']['xmlrpc'], ' ');
}
if (isset($channelInfo['servers']['primary']['rest'])) {
$ret .= $this->_makeRestXml($channelInfo['servers']['primary']['rest'], ' ');
}
if (isset($channelInfo['servers']['primary']['soap'])) {
$ret .= $this->_makeSoapXml($channelInfo['servers']['primary']['soap'], ' ');
}
$ret .= " </primary>\n";
if (isset($channelInfo['servers']['mirror'])) {
$ret .= $this->_makeMirrorsXml($channelInfo);
493,6 → 503,38
}
 
/**
* Generate the <xmlrpc> tag
* @access private
*/
function _makeXmlrpcXml($info, $indent)
{
$ret = $indent . "<xmlrpc";
if (isset($info['attribs']['path'])) {
$ret .= ' path="' . htmlspecialchars($info['attribs']['path']) . '"';
}
$ret .= ">\n";
$ret .= $this->_makeFunctionsXml($info['function'], "$indent ");
$ret .= $indent . "</xmlrpc>\n";
return $ret;
}
 
/**
* Generate the <soap> tag
* @access private
*/
function _makeSoapXml($info, $indent)
{
$ret = $indent . "<soap";
if (isset($info['attribs']['path'])) {
$ret .= ' path="' . htmlspecialchars($info['attribs']['path']) . '"';
}
$ret .= ">\n";
$ret .= $this->_makeFunctionsXml($info['function'], "$indent ");
$ret .= $indent . "</soap>\n";
return $ret;
}
 
/**
* Generate the <rest> tag
* @access private
*/
499,15 → 541,12
function _makeRestXml($info, $indent)
{
$ret = $indent . "<rest>\n";
if (isset($info['baseurl']) && !isset($info['baseurl'][0])) {
if (!isset($info['baseurl'][0])) {
$info['baseurl'] = array($info['baseurl']);
}
 
if (isset($info['baseurl'])) {
foreach ($info['baseurl'] as $url) {
$ret .= "$indent <baseurl type=\"" . $url['attribs']['type'] . "\"";
$ret .= ">" . $url['_content'] . "</baseurl>\n";
}
foreach ($info['baseurl'] as $url) {
$ret .= "$indent <baseurl type=\"" . $url['attribs']['type'] . "\"";
$ret .= ">" . $url['_content'] . "</baseurl>\n";
}
$ret .= $indent . "</rest>\n";
return $ret;
532,10 → 571,16
$ret .= ' ssl="' . $mirror['attribs']['ssl'] . '"';
}
$ret .= ">\n";
if (isset($mirror['rest'])) {
if (isset($mirror['xmlrpc']) || isset($mirror['soap'])) {
if (isset($mirror['xmlrpc'])) {
$ret .= $this->_makeXmlrpcXml($mirror['xmlrpc'], ' ');
}
if (isset($mirror['rest'])) {
$ret .= $this->_makeRestXml($mirror['rest'], ' ');
}
if (isset($mirror['soap'])) {
$ret .= $this->_makeSoapXml($mirror['soap'], ' ');
}
$ret .= " </mirror>\n";
} else {
$ret .= "/>\n";
635,14 → 680,12
array('package' => $content));
}
}
 
if (isset($info['servers']['primary']['attribs'], $info['servers']['primary']['attribs']['port']) &&
if (isset($info['servers']['primary']['attribs']['port']) &&
!is_numeric($info['servers']['primary']['attribs']['port'])) {
$this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_PORT,
array('port' => $info['servers']['primary']['attribs']['port']));
}
 
if (isset($info['servers']['primary']['attribs'], $info['servers']['primary']['attribs']['ssl']) &&
if (isset($info['servers']['primary']['attribs']['ssl']) &&
$info['servers']['primary']['attribs']['ssl'] != 'yes') {
$this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_SSL,
array('ssl' => $info['servers']['primary']['attribs']['ssl'],
649,6 → 692,14
'server' => $info['name']));
}
 
if (isset($info['servers']['primary']['xmlrpc']) &&
isset($info['servers']['primary']['xmlrpc']['function'])) {
$this->_validateFunctions('xmlrpc', $info['servers']['primary']['xmlrpc']['function']);
}
if (isset($info['servers']['primary']['soap']) &&
isset($info['servers']['primary']['soap']['function'])) {
$this->_validateFunctions('soap', $info['servers']['primary']['soap']['function']);
}
if (isset($info['servers']['primary']['rest']) &&
isset($info['servers']['primary']['rest']['baseurl'])) {
$this->_validateFunctions('rest', $info['servers']['primary']['rest']['baseurl']);
660,6 → 711,7
if (!isset($info['servers']['mirror'][0])) {
$info['servers']['mirror'] = array($info['servers']['mirror']);
}
$i = 0;
foreach ($info['servers']['mirror'] as $mirror) {
if (!isset($mirror['attribs']['host'])) {
$this->_validateError(PEAR_CHANNELFILE_ERROR_NO_HOST,
672,6 → 724,14
$this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_SSL,
array('ssl' => $info['ssl'], 'server' => $mirror['attribs']['host']));
}
if (isset($mirror['xmlrpc'])) {
$this->_validateFunctions('xmlrpc',
$mirror['xmlrpc']['function'], $mirror['attribs']['host']);
}
if (isset($mirror['soap'])) {
$this->_validateFunctions('soap', $mirror['soap']['function'],
$mirror['attribs']['host']);
}
if (isset($mirror['rest'])) {
$this->_validateFunctions('rest', $mirror['rest']['baseurl'],
$mirror['attribs']['host']);
682,7 → 742,7
}
 
/**
* @param string rest - protocol name this function applies to
* @param string xmlrpc or soap - protocol name this function applies to
* @param array the functions
* @param string the name of the parent element (mirror name, for instance)
*/
691,17 → 751,15
if (!isset($functions[0])) {
$functions = array($functions);
}
 
foreach ($functions as $function) {
if (!isset($function['_content']) || empty($function['_content'])) {
$this->_validateError(PEAR_CHANNELFILE_ERROR_NO_FUNCTIONNAME,
array('parent' => $parent, 'protocol' => $protocol));
}
 
if ($protocol == 'rest') {
if (!isset($function['attribs']['type']) ||
empty($function['attribs']['type'])) {
$this->_validateError(PEAR_CHANNELFILE_ERROR_NOBASEURLTYPE,
$this->_validateError(PEAR_CHANNELFILE_ERROR_NO_BASEURLTYPE,
array('parent' => $parent, 'protocol' => $protocol));
}
} else {
734,9 → 792,9
{
if (isset($this->_channelInfo['name'])) {
return $this->_channelInfo['name'];
} else {
return false;
}
 
return false;
}
 
/**
746,9 → 804,9
{
if (isset($this->_channelInfo['name'])) {
return $this->_channelInfo['name'];
} else {
return false;
}
 
return false;
}
 
/**
760,26 → 818,21
if ($mir = $this->getMirror($mirror)) {
if (isset($mir['attribs']['port'])) {
return $mir['attribs']['port'];
} else {
if ($this->getSSL($mirror)) {
return 443;
}
return 80;
}
 
if ($this->getSSL($mirror)) {
return 443;
}
 
return 80;
}
 
return false;
}
 
if (isset($this->_channelInfo['servers']['primary']['attribs']['port'])) {
return $this->_channelInfo['servers']['primary']['attribs']['port'];
}
 
if ($this->getSSL()) {
return 443;
}
 
return 80;
}
 
792,18 → 845,15
if ($mir = $this->getMirror($mirror)) {
if (isset($mir['attribs']['ssl'])) {
return true;
} else {
return false;
}
 
return false;
}
 
return false;
}
 
if (isset($this->_channelInfo['servers']['primary']['attribs']['ssl'])) {
return true;
}
 
return false;
}
 
814,13 → 864,37
{
if (isset($this->_channelInfo['summary'])) {
return $this->_channelInfo['summary'];
} else {
return false;
}
}
 
return false;
/**
* @param string xmlrpc or soap
* @param string|false mirror name or false for primary server
*/
function getPath($protocol, $mirror = false)
{
if (!in_array($protocol, array('xmlrpc', 'soap'))) {
return false;
}
if ($mirror) {
if (!($mir = $this->getMirror($mirror))) {
return false;
}
if (isset($mir[$protocol]['attribs']['path'])) {
return $mir[$protocol]['attribs']['path'];
} else {
return $protocol . '.php';
}
} elseif (isset($this->_channelInfo['servers']['primary'][$protocol]['attribs']['path'])) {
return $this->_channelInfo['servers']['primary'][$protocol]['attribs']['path'];
}
return $protocol . '.php';
}
 
/**
* @param string protocol type
* @param string protocol type (xmlrpc, soap)
* @param string Mirror name
* @return array|false
*/
829,8 → 903,11
if ($this->getName() == '__uri') {
return false;
}
 
$function = $protocol == 'rest' ? 'baseurl' : 'function';
if ($protocol == 'rest') {
$function = 'baseurl';
} else {
$function = 'function';
}
if ($mirror) {
if ($mir = $this->getMirror($mirror)) {
if (isset($mir[$protocol][$function])) {
837,15 → 914,13
return $mir[$protocol][$function];
}
}
 
return false;
}
 
if (isset($this->_channelInfo['servers']['primary'][$protocol][$function])) {
return $this->_channelInfo['servers']['primary'][$protocol][$function];
} else {
return false;
}
 
return false;
}
 
/**
861,19 → 936,15
if (!$protocols) {
return false;
}
 
foreach ($protocols as $protocol) {
if ($name === null) {
return $protocol;
}
 
if ($protocol['_content'] != $name) {
continue;
}
 
return $protocol;
}
 
return false;
}
 
890,23 → 961,18
if (!$protocols) {
return false;
}
 
foreach ($protocols as $protocol) {
if ($protocol['attribs']['version'] != $version) {
continue;
}
 
if ($name === null) {
return true;
}
 
if ($protocol['_content'] != $name) {
continue;
}
 
return true;
}
 
return false;
}
 
921,15 → 987,12
if ($mirror == $this->_channelInfo['name']) {
$mirror = false;
}
 
if ($mirror) {
if ($mir = $this->getMirror($mirror)) {
return isset($mir['rest']);
}
 
return false;
}
 
return isset($this->_channelInfo['servers']['primary']['rest']);
}
 
945,28 → 1008,25
if ($mirror == $this->_channelInfo['name']) {
$mirror = false;
}
 
if ($mirror) {
$mir = $this->getMirror($mirror);
if (!$mir) {
if ($mir = $this->getMirror($mirror)) {
$rest = $mir['rest'];
} else {
return false;
}
 
$rest = $mir['rest'];
$server = $mirror;
} else {
$rest = $this->_channelInfo['servers']['primary']['rest'];
$server = $this->getServer();
}
 
if (!isset($rest['baseurl'][0])) {
$rest['baseurl'] = array($rest['baseurl']);
}
 
foreach ($rest['baseurl'] as $baseurl) {
if (strtolower($baseurl['attribs']['type']) == strtolower($resourceType)) {
return $baseurl['_content'];
}
}
 
return false;
}
 
982,7 → 1042,7
 
/**
* Empty all protocol definitions
* @param string protocol type
* @param string protocol type (xmlrpc, soap)
* @param string|false mirror name, if any
*/
function resetFunctions($type, $mirror = false)
993,28 → 1053,24
if (!isset($mirrors[0])) {
$mirrors = array($mirrors);
}
 
foreach ($mirrors as $i => $mir) {
if ($mir['attribs']['host'] == $mirror) {
if (isset($this->_channelInfo['servers']['mirror'][$i][$type])) {
unset($this->_channelInfo['servers']['mirror'][$i][$type]);
}
 
return true;
}
}
 
return false;
} else {
return false;
}
 
return false;
} else {
if (isset($this->_channelInfo['servers']['primary'][$type])) {
unset($this->_channelInfo['servers']['primary'][$type]);
}
return true;
}
 
if (isset($this->_channelInfo['servers']['primary'][$type])) {
unset($this->_channelInfo['servers']['primary'][$type]);
}
 
return true;
}
 
/**
1024,15 → 1080,19
{
switch ($version) {
case '1.0' :
$this->resetFunctions('xmlrpc', $mirror);
$this->resetFunctions('soap', $mirror);
$this->resetREST($mirror);
 
if (!isset($this->_channelInfo['servers'])) {
$this->_channelInfo['servers'] = array('primary' =>
array('rest' => array()));
} elseif (!isset($this->_channelInfo['servers']['primary'])) {
$this->_channelInfo['servers']['primary'] = array('rest' => array());
}
 
$this->addFunction('xmlrpc', '1.0', 'logintest', $mirror);
$this->addFunction('xmlrpc', '1.0', 'package.listLatestReleases', $mirror);
$this->addFunction('xmlrpc', '1.0', 'package.listAll', $mirror);
$this->addFunction('xmlrpc', '1.0', 'package.info', $mirror);
$this->addFunction('xmlrpc', '1.0', 'package.getDownloadURL', $mirror);
$this->addFunction('xmlrpc', '1.1', 'package.getDownloadURL', $mirror);
$this->addFunction('xmlrpc', '1.0', 'package.getDepDownloadURL', $mirror);
$this->addFunction('xmlrpc', '1.1', 'package.getDepDownloadURL', $mirror);
$this->addFunction('xmlrpc', '1.0', 'package.search', $mirror);
$this->addFunction('xmlrpc', '1.0', 'channel.listAll', $mirror);
return true;
break;
default :
1040,7 → 1100,7
break;
}
}
 
/**
* @return array
*/
1051,11 → 1111,10
if (!isset($mirrors[0])) {
$mirrors = array($mirrors);
}
 
return $mirrors;
} else {
return array();
}
 
return array();
}
 
/**
1069,7 → 1128,6
return $mirror;
}
}
 
return false;
}
 
1097,7 → 1155,7
array('mirror' => $mirror));
return false;
}
 
$setmirror = false;
if (isset($this->_channelInfo['servers']['mirror'][0])) {
foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
if ($mirror == $mir['attribs']['host']) {
1105,7 → 1163,6
return true;
}
}
 
return false;
} elseif ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) {
$this->_channelInfo['servers']['mirror']['attribs']['port'] = $port;
1113,7 → 1170,6
return true;
}
}
 
$this->_channelInfo['servers']['primary']['attribs']['port'] = $port;
$this->_isValid = false;
return true;
1132,7 → 1188,7
array('mirror' => $mirror));
return false;
}
 
$setmirror = false;
if (isset($this->_channelInfo['servers']['mirror'][0])) {
foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
if ($mirror == $mir['attribs']['host']) {
1144,11 → 1200,9
} else {
$this->_channelInfo['servers']['mirror'][$i]['attribs']['ssl'] = 'yes';
}
 
return true;
}
}
 
return false;
} elseif ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) {
if (!$ssl) {
1158,12 → 1212,10
} else {
$this->_channelInfo['servers']['mirror']['attribs']['ssl'] = 'yes';
}
 
$this->_isValid = false;
return true;
}
}
 
if ($ssl) {
$this->_channelInfo['servers']['primary']['attribs']['ssl'] = 'yes';
} else {
1171,7 → 1223,45
unset($this->_channelInfo['servers']['primary']['attribs']['ssl']);
}
}
$this->_isValid = false;
return true;
}
 
/**
* Set the socket number (port) that is used to connect to this channel
* @param integer
* @param string|false name of the mirror server, or false for the primary
*/
function setPath($protocol, $path, $mirror = false)
{
if (!in_array($protocol, array('xmlrpc', 'soap'))) {
return false;
}
if ($mirror) {
if (!isset($this->_channelInfo['servers']['mirror'])) {
$this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
array('mirror' => $mirror));
return false;
}
$setmirror = false;
if (isset($this->_channelInfo['servers']['mirror'][0])) {
foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
if ($mirror == $mir['attribs']['host']) {
$this->_channelInfo['servers']['mirror'][$i][$protocol]['attribs']['path'] =
$path;
return true;
}
}
$this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
array('mirror' => $mirror));
return false;
} elseif ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) {
$this->_channelInfo['servers']['mirror'][$protocol]['attribs']['path'] = $path;
$this->_isValid = false;
return true;
}
}
$this->_channelInfo['servers']['primary'][$protocol]['attribs']['path'] = $path;
$this->_isValid = false;
return true;
}
1192,7 → 1282,6
array('tag' => 'name', 'name' => $server));
return false;
}
 
if ($mirror) {
$found = false;
foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
1201,17 → 1290,14
break;
}
}
 
if (!$found) {
$this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
array('mirror' => $mirror));
return false;
}
 
$this->_channelInfo['mirror'][$i]['attribs']['host'] = $server;
return true;
}
 
$this->_channelInfo['name'] = $server;
return true;
}
1231,7 → 1317,6
$this->_validateWarning(PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY,
array('summary' => $summary));
}
 
$this->_channelInfo['summary'] = $summary;
return true;
}
1248,13 → 1333,11
array('tag' => 'suggestedalias', 'name' => $alias));
return false;
}
 
if ($local) {
$this->_channelInfo['localalias'] = $alias;
} else {
$this->_channelInfo['suggestedalias'] = $alias;
}
 
return true;
}
 
1272,7 → 1355,6
if (isset($this->_channelInfo['name'])) {
return $this->_channelInfo['name'];
}
return '';
}
 
/**
1304,7 → 1386,6
if ($mirror) {
return $this->addMirrorFunction($mirror, $type, $version, $name);
}
 
$set = array('attribs' => array('version' => $version), '_content' => $name);
if (!isset($this->_channelInfo['servers']['primary'][$type]['function'])) {
if (!isset($this->_channelInfo['servers'])) {
1313,7 → 1394,6
} elseif (!isset($this->_channelInfo['servers']['primary'])) {
$this->_channelInfo['servers']['primary'] = array($type => array());
}
 
$this->_channelInfo['servers']['primary'][$type]['function'] = $set;
$this->_isValid = false;
return true;
1321,7 → 1401,6
$this->_channelInfo['servers']['primary'][$type]['function'] = array(
$this->_channelInfo['servers']['primary'][$type]['function']);
}
 
$this->_channelInfo['servers']['primary'][$type]['function'][] = $set;
return true;
}
1334,12 → 1413,12
*/
function addMirrorFunction($mirror, $type, $version, $name = '')
{
$found = false;
if (!isset($this->_channelInfo['servers']['mirror'])) {
$this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
array('mirror' => $mirror));
return false;
}
 
$setmirror = false;
if (isset($this->_channelInfo['servers']['mirror'][0])) {
foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
1353,13 → 1432,11
$setmirror = &$this->_channelInfo['servers']['mirror'];
}
}
 
if (!$setmirror) {
$this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
array('mirror' => $mirror));
return false;
}
 
$set = array('attribs' => array('version' => $version), '_content' => $name);
if (!isset($setmirror[$type]['function'])) {
$setmirror[$type]['function'] = $set;
1368,7 → 1445,6
} elseif (!isset($setmirror[$type]['function'][0])) {
$setmirror[$type]['function'] = array($setmirror[$type]['function']);
}
 
$setmirror[$type]['function'][] = $set;
$this->_isValid = false;
return true;
1382,12 → 1458,12
function setBaseURL($resourceType, $url, $mirror = false)
{
if ($mirror) {
$found = false;
if (!isset($this->_channelInfo['servers']['mirror'])) {
$this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND,
array('mirror' => $mirror));
return false;
}
 
$setmirror = false;
if (isset($this->_channelInfo['servers']['mirror'][0])) {
foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) {
1404,12 → 1480,10
} else {
$setmirror = &$this->_channelInfo['servers']['primary'];
}
 
$set = array('attribs' => array('type' => $resourceType), '_content' => $url);
if (!isset($setmirror['rest'])) {
$setmirror['rest'] = array();
}
 
if (!isset($setmirror['rest']['baseurl'])) {
$setmirror['rest']['baseurl'] = $set;
$this->_isValid = false;
1417,7 → 1491,6
} elseif (!isset($setmirror['rest']['baseurl'][0])) {
$setmirror['rest']['baseurl'] = array($setmirror['rest']['baseurl']);
}
 
foreach ($setmirror['rest']['baseurl'] as $i => $url) {
if ($url['attribs']['type'] == $resourceType) {
$this->_isValid = false;
1425,7 → 1498,6
return true;
}
}
 
$setmirror['rest']['baseurl'][] = $set;
$this->_isValid = false;
return true;
1441,22 → 1513,19
if ($this->_channelInfo['name'] == '__uri') {
return false; // the __uri channel cannot have mirrors by definition
}
 
$set = array('attribs' => array('host' => $server));
if (is_numeric($port)) {
$set['attribs']['port'] = $port;
}
 
if (!isset($this->_channelInfo['servers']['mirror'])) {
$this->_channelInfo['servers']['mirror'] = $set;
return true;
} else {
if (!isset($this->_channelInfo['servers']['mirror'][0])) {
$this->_channelInfo['servers']['mirror'] =
array($this->_channelInfo['servers']['mirror']);
}
}
 
if (!isset($this->_channelInfo['servers']['mirror'][0])) {
$this->_channelInfo['servers']['mirror'] =
array($this->_channelInfo['servers']['mirror']);
}
 
$this->_channelInfo['servers']['mirror'][] = $set;
return true;
}
1470,12 → 1539,10
if (!$this->_isValid && !$this->validate()) {
return false;
}
 
if (!isset($this->_channelInfo['validatepackage'])) {
return array('attribs' => array('version' => 'default'),
'_content' => 'PEAR_Validate');
}
 
return $this->_channelInfo['validatepackage'];
}
 
1491,7 → 1558,6
if (!class_exists('PEAR_Validate')) {
require_once 'PEAR/Validate.php';
}
 
if (!$this->_isValid) {
if (!$this->validate()) {
$a = false;
1498,14 → 1564,12
return $a;
}
}
 
if (isset($this->_channelInfo['validatepackage'])) {
if ($package == $this->_channelInfo['validatepackage']) {
// channel validation packages are always validated by PEAR_Validate
$val = new PEAR_Validate;
$val = &new PEAR_Validate;
return $val;
}
 
if (!class_exists(str_replace('.', '_',
$this->_channelInfo['validatepackage']['_content']))) {
if ($this->isIncludeable(str_replace('_', '/',
1514,7 → 1578,7
$this->_channelInfo['validatepackage']['_content']) . '.php';
$vclass = str_replace('.', '_',
$this->_channelInfo['validatepackage']['_content']);
$val = new $vclass;
$val = &new $vclass;
} else {
$a = false;
return $a;
1522,12 → 1586,11
} else {
$vclass = str_replace('.', '_',
$this->_channelInfo['validatepackage']['_content']);
$val = new $vclass;
$val = &new $vclass;
}
} else {
$val = new PEAR_Validate;
$val = &new PEAR_Validate;
}
 
return $val;
}
 
1540,7 → 1603,6
return true;
}
}
 
return false;
}
 
1554,7 → 1616,7
if (isset($this->_channelInfo['_lastmodified'])) {
return $this->_channelInfo['_lastmodified'];
}
 
return time();
}
}
?>
/trunk/bibliotheque/pear/PEAR/Downloader/Package.php
4,15 → 4,21
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Package.php,v 1.104 2007/01/14 21:11:54 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
 
/**
* Error code when parameter initialization fails because no releases
* exist within preferred_state, but releases do exist
19,12 → 25,6
*/
define('PEAR_DOWNLOADER_PACKAGE_STATE', -1003);
/**
* Error code when parameter initialization fails because no releases
* exist that will work with the existing PHP version
*/
define('PEAR_DOWNLOADER_PACKAGE_PHPVERSION', -1004);
 
/**
* Coordinates download parameters and manages their dependencies
* prior to downloading them.
*
47,9 → 47,9
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
110,7 → 110,7
*/
var $_explicitGroup = false;
/**
* Package type local|url
* Package type local|url|xmlrpc
* @var string
*/
var $_type;
129,7 → 129,7
/**
* @param PEAR_Downloader
*/
function __construct(&$downloader)
function PEAR_Downloader_Package(&$downloader)
{
$this->_downloader = &$downloader;
$this->_config = &$this->_downloader->config;
157,87 → 157,67
function initialize($param)
{
$origErr = $this->_fromFile($param);
if ($this->_valid) {
return true;
}
 
$options = $this->_downloader->getOptions();
if (isset($options['offline'])) {
if (PEAR::isError($origErr) && !isset($options['soft'])) {
foreach ($origErr->getUserInfo() as $userInfo) {
if (isset($userInfo['message'])) {
$this->_downloader->log(0, $userInfo['message']);
if (!$this->_valid) {
$options = $this->_downloader->getOptions();
if (isset($options['offline'])) {
if (PEAR::isError($origErr)) {
if (!isset($options['soft'])) {
$this->_downloader->log(0, $origErr->getMessage());
}
}
 
$this->_downloader->log(0, $origErr->getMessage());
return PEAR::raiseError('Cannot download non-local package "' . $param . '"');
}
 
return PEAR::raiseError('Cannot download non-local package "' . $param . '"');
}
 
$err = $this->_fromUrl($param);
if (PEAR::isError($err) || !$this->_valid) {
if ($this->_type == 'url') {
if (PEAR::isError($err) && !isset($options['soft'])) {
$this->_downloader->log(0, $err->getMessage());
}
 
return PEAR::raiseError("Invalid or missing remote package file");
}
 
$err = $this->_fromString($param);
$err = $this->_fromUrl($param);
if (PEAR::isError($err) || !$this->_valid) {
if (PEAR::isError($err) && $err->getCode() == PEAR_DOWNLOADER_PACKAGE_STATE) {
return false; // instruct the downloader to silently skip
if ($this->_type == 'url') {
if (PEAR::isError($err)) {
if (!isset($options['soft'])) {
$this->_downloader->log(0, $err->getMessage());
}
}
return PEAR::raiseError("Invalid or missing remote package file");
}
 
if (isset($this->_type) && $this->_type == 'local' && PEAR::isError($origErr)) {
if (is_array($origErr->getUserInfo())) {
foreach ($origErr->getUserInfo() as $err) {
if (is_array($err)) {
$err = $err['message'];
$err = $this->_fromString($param);
if (PEAR::isError($err) || !$this->_valid) {
if (PEAR::isError($err) &&
$err->getCode() == PEAR_DOWNLOADER_PACKAGE_STATE) {
return false; // instruct the downloader to silently skip
}
if (isset($this->_type) && $this->_type == 'local' &&
PEAR::isError($origErr)) {
if (is_array($origErr->getUserInfo())) {
foreach ($origErr->getUserInfo() as $err) {
if (is_array($err)) {
$err = $err['message'];
}
if (!isset($options['soft'])) {
$this->_downloader->log(0, $err);
}
}
 
if (!isset($options['soft'])) {
$this->_downloader->log(0, $err);
}
}
if (!isset($options['soft'])) {
$this->_downloader->log(0, $origErr->getMessage());
}
if (is_array($param)) {
$param = $this->_registry->parsedPackageNameToString($param,
true);
}
return PEAR::raiseError(
"Cannot initialize '$param', invalid or missing package file");
}
 
if (!isset($options['soft'])) {
$this->_downloader->log(0, $origErr->getMessage());
if (PEAR::isError($err)) {
if (!isset($options['soft'])) {
$this->_downloader->log(0, $err->getMessage());
}
}
 
if (is_array($param)) {
$param = $this->_registry->parsedPackageNameToString($param, true);
}
 
if (!isset($options['soft'])) {
$this->_downloader->log(2, "Cannot initialize '$param', invalid or missing package file");
}
 
// Passing no message back - already logged above
return PEAR::raiseError();
return PEAR::raiseError(
"Cannot initialize '$param', invalid or missing package file");
}
 
if (PEAR::isError($err) && !isset($options['soft'])) {
$this->_downloader->log(0, $err->getMessage());
}
 
if (is_array($param)) {
$param = $this->_registry->parsedPackageNameToString($param, true);
}
 
if (!isset($options['soft'])) {
$this->_downloader->log(2, "Cannot initialize '$param', invalid or missing package file");
}
 
// Passing no message back - already logged above
return PEAR::raiseError();
}
}
 
return true;
}
 
250,7 → 230,6
if (isset($this->_packagefile)) {
return $this->_packagefile;
}
 
if (isset($this->_downloadURL['url'])) {
$this->_isvalid = false;
$info = $this->getParsedPackage();
257,7 → 236,6
foreach ($info as $i => $p) {
$info[$i] = strtolower($p);
}
 
$err = $this->_fromUrl($this->_downloadURL['url'],
$this->_registry->parsedPackageNameToString($this->_parsedname, true));
$newinfo = $this->getParsedPackage();
264,24 → 242,15
foreach ($newinfo as $i => $p) {
$newinfo[$i] = strtolower($p);
}
 
if ($info != $newinfo) {
do {
if ($info['channel'] == 'pecl.php.net' && $newinfo['channel'] == 'pear.php.net') {
$info['channel'] = 'pear.php.net';
if ($info['package'] == 'pecl.php.net' && $newinfo['package'] == 'pear.php.net') {
$info['package'] = 'pear.php.net';
if ($info == $newinfo) {
// skip the channel check if a pecl package says it's a PEAR package
break;
}
}
if ($info['channel'] == 'pear.php.net' && $newinfo['channel'] == 'pecl.php.net') {
$info['channel'] = 'pecl.php.net';
if ($info == $newinfo) {
// skip the channel check if a pecl package says it's a PEAR package
break;
}
}
 
return PEAR::raiseError('CRITICAL ERROR: We are ' .
$this->_registry->parsedPackageNameToString($info) . ', but the file ' .
'downloaded claims to be ' .
288,12 → 257,10
$this->_registry->parsedPackageNameToString($this->getParsedPackage()));
} while (false);
}
 
if (PEAR::isError($err) || !$this->_valid) {
return $err;
}
}
 
$this->_type = 'local';
return $this->_packagefile;
}
308,7 → 275,7
return $this->_downloader;
}
 
function getType()
function getType()
{
return $this->_type;
}
326,7 → 293,6
} else {
$ext = '.tgz';
}
 
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$err = $this->_fromUrl($dep['uri'] . $ext);
PEAR::popErrorHandling();
334,7 → 300,6
if (!isset($options['soft'])) {
$this->_downloader->log(0, $err->getMessage());
}
 
return PEAR::raiseError('Invalid uri dependency "' . $dep['uri'] . $ext . '", ' .
'cannot download');
}
349,7 → 314,6
$this->_parsedname['group'] = 'default'; // download the default dependency group
$this->_explicitGroup = false;
}
 
$this->_rawpackagefile = $dep['raw'];
}
}
360,27 → 324,23
if (isset($options['downloadonly'])) {
return;
}
 
if (isset($options['offline'])) {
$this->_downloader->log(3, 'Skipping dependency download check, --offline specified');
return;
}
 
$pname = $this->getParsedPackage();
if (!$pname) {
return;
}
 
$deps = $this->getDeps();
if (!$deps) {
return;
}
 
if (isset($deps['required'])) { // package.xml 2.0
return $this->_detect2($deps, $pname, $options, $params);
} else {
return $this->_detect1($deps, $pname, $options, $params);
}
 
return $this->_detect1($deps, $pname, $options, $params);
}
 
function setValidated()
396,24 → 356,22
/**
* Remove packages to be downloaded that are already installed
* @param array of PEAR_Downloader_Package objects
* @static
*/
public static function removeInstalled(&$params)
function removeInstalled(&$params)
{
if (!isset($params[0])) {
return;
}
 
$options = $params[0]->_downloader->getOptions();
if (!isset($options['downloadonly'])) {
foreach ($params as $i => $param) {
$package = $param->getPackage();
$channel = $param->getChannel();
// remove self if already installed with this version
// this does not need any pecl magic - we only remove exact matches
if ($param->_installRegistry->packageExists($package, $channel)) {
$packageVersion = $param->_installRegistry->packageInfo($package, 'version', $channel);
if (version_compare($packageVersion, $param->getVersion(), '==')) {
if (!isset($options['force']) && !isset($options['packagingroot'])) {
if ($param->_installRegistry->packageExists($param->getPackage(), $param->getChannel())) {
if (version_compare($param->_installRegistry->packageInfo($param->getPackage(), 'version',
$param->getChannel()), $param->getVersion(), '==')) {
if (!isset($options['force'])) {
$info = $param->getParsedPackage();
unset($info['version']);
unset($info['state']);
420,22 → 378,25
if (!isset($options['soft'])) {
$param->_downloader->log(1, 'Skipping package "' .
$param->getShortName() .
'", already installed as version ' . $packageVersion);
'", already installed as version ' .
$param->_installRegistry->packageInfo($param->getPackage(),
'version', $param->getChannel()));
}
$params[$i] = false;
}
} elseif (!isset($options['force']) && !isset($options['upgrade']) &&
!isset($options['soft']) && !isset($options['packagingroot'])) {
!isset($options['soft'])) {
$info = $param->getParsedPackage();
$param->_downloader->log(1, 'Skipping package "' .
$param->getShortName() .
'", already installed as version ' . $packageVersion);
'", already installed as version ' .
$param->_installRegistry->packageInfo($param->getPackage(), 'version',
$param->getChannel()));
$params[$i] = false;
}
}
}
}
 
PEAR_Downloader_Package::removeDuplicates($params);
}
 
455,8 → 416,6
$ret = $this->_detect2Dep($dep, $pname, 'required', $params);
if (is_array($ret)) {
$this->_downloadDeps[] = $ret;
} elseif (PEAR::isError($ret) && !isset($options['soft'])) {
$this->_downloader->log(0, $ret->getMessage());
}
}
} else {
466,13 → 425,10
$ret = $this->_detect2Dep($dep, $pname, 'required', $params);
if (is_array($ret)) {
$this->_downloadDeps[] = $ret;
} elseif (PEAR::isError($ret) && !isset($options['soft'])) {
$this->_downloader->log(0, $ret->getMessage());
}
}
}
}
 
// get optional dependency group, if any
if (isset($deps['optional'][$packagetype])) {
$skipnames = array();
479,7 → 435,6
if (!isset($deps['optional'][$packagetype][0])) {
$deps['optional'][$packagetype] = array($deps['optional'][$packagetype]);
}
 
foreach ($deps['optional'][$packagetype] as $dep) {
$skip = false;
if (!isset($options['alldeps'])) {
496,13 → 451,7
$skip = true;
unset($dep['package']);
}
 
$ret = $this->_detect2Dep($dep, $pname, 'optional', $params);
if (PEAR::isError($ret) && !isset($options['soft'])) {
$this->_downloader->log(0, $ret->getMessage());
}
 
if (!$ret) {
if (!($ret = $this->_detect2Dep($dep, $pname, 'optional', $params))) {
$dep['package'] = $dep['name'];
$skip = count($skipnames) ?
$skipnames[count($skipnames) - 1] : '';
511,12 → 460,10
array_pop($skipnames);
}
}
 
if (!$skip && is_array($ret)) {
$this->_downloadDeps[] = $ret;
}
}
 
if (count($skipnames)) {
if (!isset($options['soft'])) {
$this->_downloader->log(1, 'Did not download optional dependencies: ' .
525,22 → 472,19
}
}
}
 
// get requested dependency group, if any
$groupname = $this->getGroup();
$explicit = $this->_explicitGroup;
$explicit = $this->_explicitGroup;
if (!$groupname) {
if (!$this->canDefault()) {
if ($this->canDefault()) {
$groupname = 'default'; // try the default dependency group
} else {
continue;
}
 
$groupname = 'default'; // try the default dependency group
}
 
if ($groupnotfound) {
continue;
}
 
if (isset($deps['group'])) {
if (isset($deps['group']['attribs'])) {
if (strtolower($deps['group']['attribs']['name']) == strtolower($groupname)) {
551,7 → 495,6
$this->_registry->parsedPackageNameToString($pname, true) .
'" has no dependency ' . 'group named "' . $groupname . '"');
}
 
$groupnotfound = true;
continue;
}
563,7 → 506,6
break;
}
}
 
if (!$found) {
if ($explicit) {
if (!isset($options['soft'])) {
572,33 → 514,29
'" has no dependency ' . 'group named "' . $groupname . '"');
}
}
 
$groupnotfound = true;
continue;
}
}
}
 
if (isset($group) && isset($group[$packagetype])) {
if (isset($group[$packagetype][0])) {
foreach ($group[$packagetype] as $dep) {
$ret = $this->_detect2Dep($dep, $pname, 'dependency group "' .
if (isset($group)) {
if (isset($group[$packagetype])) {
if (isset($group[$packagetype][0])) {
foreach ($group[$packagetype] as $dep) {
$ret = $this->_detect2Dep($dep, $pname, 'dependency group "' .
$group['attribs']['name'] . '"', $params);
if (is_array($ret)) {
$this->_downloadDeps[] = $ret;
}
}
} else {
$ret = $this->_detect2Dep($group[$packagetype], $pname,
'dependency group "' .
$group['attribs']['name'] . '"', $params);
if (is_array($ret)) {
$this->_downloadDeps[] = $ret;
} elseif (PEAR::isError($ret) && !isset($options['soft'])) {
$this->_downloader->log(0, $ret->getMessage());
}
}
} else {
$ret = $this->_detect2Dep($group[$packagetype], $pname,
'dependency group "' .
$group['attribs']['name'] . '"', $params);
if (is_array($ret)) {
$this->_downloadDeps[] = $ret;
} elseif (PEAR::isError($ret) && !isset($options['soft'])) {
$this->_downloader->log(0, $ret->getMessage());
}
}
}
}
609,12 → 547,10
if (isset($dep['conflicts'])) {
return true;
}
 
$options = $this->_downloader->getOptions();
if (isset($dep['uri'])) {
return array('uri' => $dep['uri'], 'dep' => $dep);;
}
 
$testdep = $dep;
$testdep['package'] = $dep['name'];
if (PEAR_Downloader_Package::willDownload($testdep, $params)) {
627,19 → 563,17
}
return false;
}
 
$options = $this->_downloader->getOptions();
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
if ($this->_explicitState) {
$pname['state'] = $this->_explicitState;
}
 
$url = $this->_downloader->_getDepPackageDownloadUrl($dep, $pname);
$url =
$this->_downloader->_getDepPackageDownloadUrl($dep, $pname);
if (PEAR::isError($url)) {
PEAR::popErrorHandling();
return $url;
}
 
$dep['package'] = $dep['name'];
$ret = $this->_analyzeDownloadURL($url, 'dependency', $dep, $params, $group == 'optional' &&
!isset($options['alldeps']), true);
648,38 → 582,34
if (!isset($options['soft'])) {
$this->_downloader->log(0, $ret->getMessage());
}
 
return false;
}
 
// check to see if a dep is already installed and is the same or newer
if (!isset($dep['min']) && !isset($dep['max']) && !isset($dep['recommended'])) {
$oper = 'has';
} else {
$oper = 'gt';
}
 
// do not try to move this before getDepPackageDownloadURL
// we can't determine whether upgrade is necessary until we know what
// version would be downloaded
if (!isset($options['force']) && $this->isInstalled($ret, $oper)) {
$version = $this->_installRegistry->packageInfo($dep['name'], 'version', $dep['channel']);
$dep['package'] = $dep['name'];
if (!isset($options['soft'])) {
$this->_downloader->log(3, $this->getShortName() . ': Skipping ' . $group .
' dependency "' .
$this->_registry->parsedPackageNameToString($dep, true) .
'" version ' . $url['version'] . ', already installed as version ' .
$version);
// check to see if a dep is already installed and is the same or newer
if (!isset($dep['min']) && !isset($dep['max']) && !isset($dep['recommended'])) {
$oper = 'has';
} else {
$oper = 'gt';
}
 
return false;
// do not try to move this before getDepPackageDownloadURL
// we can't determine whether upgrade is necessary until we know what
// version would be downloaded
if (!isset($options['force']) && $this->isInstalled($ret, $oper)) {
$version = $this->_installRegistry->packageInfo($dep['name'], 'version',
$dep['channel']);
$dep['package'] = $dep['name'];
if (!isset($options['soft'])) {
$this->_downloader->log(3, $this->getShortName() . ': Skipping ' . $group .
' dependency "' .
$this->_registry->parsedPackageNameToString($dep, true) .
'" version ' . $url['version'] . ', already installed as version ' .
$version);
}
return false;
}
}
 
if (isset($dep['nodefault'])) {
$ret['nodefault'] = true;
}
 
return $ret;
}
 
689,7 → 619,7
$skipnames = array();
foreach ($deps as $dep) {
$nodownload = false;
if (isset ($dep['type']) && $dep['type'] === 'pkg') {
if ($dep['type'] == 'pkg') {
$dep['channel'] = 'pear.php.net';
$dep['package'] = $dep['name'];
switch ($dep['rel']) {
721,13 → 651,12
continue 2;
}
}
 
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
if ($this->_explicitState) {
$pname['state'] = $this->_explicitState;
}
 
$url = $this->_downloader->_getDepPackageDownloadUrl($dep, $pname);
$url =
$this->_downloader->_getDepPackageDownloadUrl($dep, $pname);
$chan = 'pear.php.net';
if (PEAR::isError($url)) {
// check to see if this is a pecl package that has jumped
735,12 → 664,12
if (!class_exists('PEAR_Dependency2')) {
require_once 'PEAR/Dependency2.php';
}
 
$newdep = PEAR_Dependency2::normalizeDep($dep);
$newdep = $newdep[0];
$newdep['channel'] = 'pecl.php.net';
$chan = 'pecl.php.net';
$url = $this->_downloader->_getDepPackageDownloadUrl($newdep, $pname);
$url =
$this->_downloader->_getDepPackageDownloadUrl($newdep, $pname);
$obj = &$this->_installRegistry->getPackage($dep['name']);
if (PEAR::isError($url)) {
PEAR::popErrorHandling();
765,7 → 694,8
} else {
if (isset($dep['optional']) && $dep['optional'] == 'yes') {
$this->_downloader->log(2, $this->getShortName() .
': Skipping optional dependency "' .
': Skipping ' . $group
. ' dependency "' .
$this->_registry->parsedPackageNameToString($dep, true) .
'", no releases exist');
continue;
775,7 → 705,6
}
}
}
 
PEAR::popErrorHandling();
if (!isset($options['alldeps'])) {
if (isset($dep['optional']) && $dep['optional'] == 'yes') {
794,7 → 723,6
$nodownload = true;
}
}
 
if (!isset($options['alldeps']) && !isset($options['onlyreqdeps'])) {
if (!isset($dep['optional']) || $dep['optional'] == 'no') {
if (!isset($options['soft'])) {
812,7 → 740,6
$nodownload = true;
}
}
 
// check to see if a dep is already installed
// do not try to move this before getDepPackageDownloadURL
// we can't determine whether upgrade is necessary until we know what
824,11 → 751,11
'optional';
$dep['package'] = $dep['name'];
if (isset($newdep)) {
$version = $this->_installRegistry->packageInfo($newdep['name'], 'version', $newdep['channel']);
$version = $this->_installRegistry->packageInfo($newdep['name'], 'version',
$newdep['channel']);
} else {
$version = $this->_installRegistry->packageInfo($dep['name'], 'version');
}
 
$dep['version'] = $url['version'];
if (!isset($options['soft'])) {
$this->_downloader->log(3, $this->getShortName() . ': Skipping ' . $group .
836,7 → 763,6
$this->_registry->parsedPackageNameToString($dep, true) .
'", already installed as version ' . $version);
}
 
$skip = count($skipnames) ?
$skipnames[count($skipnames) - 1] : '';
if ($skip ==
843,19 → 769,15
$this->_registry->parsedPackageNameToString($dep, true)) {
array_pop($skipnames);
}
 
continue;
}
 
if ($nodownload) {
continue;
}
 
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
if (isset($newdep)) {
$dep = $newdep;
}
 
$dep['package'] = $dep['name'];
$ret = $this->_analyzeDownloadURL($url, 'dependency', $dep, $params,
isset($dep['optional']) && $dep['optional'] == 'yes' &&
867,11 → 789,9
}
continue;
}
 
$this->_downloadDeps[] = $ret;
}
}
 
if (count($skipnames)) {
if (!isset($options['soft'])) {
$this->_downloader->log(1, 'Did not download dependencies: ' .
903,13 → 823,12
}
 
function getParsedPackage()
{
{
if (isset($this->_packagefile) || isset($this->_parsedname)) {
return array('channel' => $this->getChannel(),
'package' => $this->getPackage(),
'version' => $this->getVersion());
}
 
return false;
}
 
920,10 → 839,11
 
function canDefault()
{
if (isset($this->_downloadURL) && isset($this->_downloadURL['nodefault'])) {
return false;
if (isset($this->_downloadURL)) {
if (isset($this->_downloadURL['nodefault'])) {
return false;
}
}
 
return true;
}
 
933,9 → 853,9
return $this->_packagefile->getPackage();
} elseif (isset($this->_downloadURL['info'])) {
return $this->_downloadURL['info']->getPackage();
} else {
return false;
}
 
return false;
}
 
/**
947,9 → 867,9
return $this->_packagefile->isSubpackage($pf);
} elseif (isset($this->_downloadURL['info'])) {
return $this->_downloadURL['info']->isSubpackage($pf);
} else {
return false;
}
 
return false;
}
 
function getPackageType()
958,9 → 878,9
return $this->_packagefile->getPackageType();
} elseif (isset($this->_downloadURL['info'])) {
return $this->_downloadURL['info']->getPackageType();
} else {
return false;
}
 
return false;
}
 
function isBundle()
967,9 → 887,9
{
if (isset($this->_packagefile)) {
return $this->_packagefile->getPackageType() == 'bundle';
} else {
return false;
}
 
return false;
}
 
function getPackageXmlVersion()
978,9 → 898,9
return $this->_packagefile->getPackagexmlVersion();
} elseif (isset($this->_downloadURL['info'])) {
return $this->_downloadURL['info']->getPackagexmlVersion();
} else {
return '1.0';
}
 
return '1.0';
}
 
function getChannel()
989,9 → 909,9
return $this->_packagefile->getChannel();
} elseif (isset($this->_downloadURL['info'])) {
return $this->_downloadURL['info']->getChannel();
} else {
return false;
}
 
return false;
}
 
function getURI()
1000,9 → 920,9
return $this->_packagefile->getURI();
} elseif (isset($this->_downloadURL['info'])) {
return $this->_downloadURL['info']->getURI();
} else {
return false;
}
 
return false;
}
 
function getVersion()
1011,9 → 931,9
return $this->_packagefile->getVersion();
} elseif (isset($this->_downloadURL['version'])) {
return $this->_downloadURL['version'];
} else {
return false;
}
 
return false;
}
 
function isCompatible($pf)
1022,9 → 942,9
return $this->_packagefile->isCompatible($pf);
} elseif (isset($this->_downloadURL['info'])) {
return $this->_downloadURL['info']->isCompatible($pf);
} else {
return true;
}
 
return true;
}
 
function setGroup($group)
1036,9 → 956,9
{
if (isset($this->_parsedname['group'])) {
return $this->_parsedname['group'];
} else {
return '';
}
 
return '';
}
 
function isExtension($name)
1046,14 → 966,14
if (isset($this->_packagefile)) {
return $this->_packagefile->isExtension($name);
} elseif (isset($this->_downloadURL['info'])) {
if ($this->_downloadURL['info']->getPackagexmlVersion() == '2.0') {
return $this->_downloadURL['info']->getProvidesExtension() == $name;
}
 
if ($this->_downloadURL['info']->getPackagexmlVersion() == '2.0') {
return $this->_downloadURL['info']->getProvidesExtension() == $name;
} else {
return false;
}
} else {
return false;
}
 
return false;
}
 
function getDeps()
1062,19 → 982,19
$ver = $this->_packagefile->getPackagexmlVersion();
if (version_compare($ver, '2.0', '>=')) {
return $this->_packagefile->getDeps(true);
} else {
return $this->_packagefile->getDeps();
}
 
return $this->_packagefile->getDeps();
} elseif (isset($this->_downloadURL['info'])) {
$ver = $this->_downloadURL['info']->getPackagexmlVersion();
if (version_compare($ver, '2.0', '>=')) {
return $this->_downloadURL['info']->getDeps(true);
} else {
return $this->_downloadURL['info']->getDeps();
}
 
return $this->_downloadURL['info']->getDeps();
} else {
return array();
}
 
return array();
}
 
/**
1107,14 → 1027,14
}
return $param['uri'] == $this->getURI();
}
 
$package = isset($param['package']) ? $param['package'] : $param['info']->getPackage();
$channel = isset($param['channel']) ? $param['channel'] : $param['info']->getChannel();
$package = isset($param['package']) ? $param['package'] :
$param['info']->getPackage();
$channel = isset($param['channel']) ? $param['channel'] :
$param['info']->getChannel();
if (isset($param['rel'])) {
if (!class_exists('PEAR_Dependency2')) {
require_once 'PEAR/Dependency2.php';
}
 
$newdep = PEAR_Dependency2::normalizeDep($param);
$newdep = $newdep[0];
} elseif (isset($param['min'])) {
1121,16 → 1041,13
$newdep = $param;
}
}
 
if (isset($newdep)) {
if (!isset($newdep['min'])) {
$newdep['min'] = '0';
}
 
if (!isset($newdep['max'])) {
$newdep['max'] = '100000000000000000000';
}
 
// use magic to support pecl packages suddenly jumping to the pecl channel
// we need to support both dependency possibilities
if ($channel == 'pear.php.net' && $this->getChannel() == 'pecl.php.net') {
1143,13 → 1060,11
$channel = 'pear.php.net';
}
}
 
return (strtolower($package) == strtolower($this->getPackage()) &&
$channel == $this->getChannel() &&
version_compare($newdep['min'], $this->getVersion(), '<=') &&
version_compare($newdep['max'], $this->getVersion(), '>='));
}
 
// use magic to support pecl packages suddenly jumping to the pecl channel
if ($channel == 'pecl.php.net' && $this->getChannel() == 'pear.php.net') {
if (strtolower($package) == strtolower($this->getPackage())) {
1156,15 → 1071,14
$channel = 'pear.php.net';
}
}
 
if (isset($param['version'])) {
return (strtolower($package) == strtolower($this->getPackage()) &&
$channel == $this->getChannel() &&
$param['version'] == $this->getVersion());
} else {
return strtolower($package) == strtolower($this->getPackage()) &&
$channel == $this->getChannel();
}
 
return strtolower($package) == strtolower($this->getPackage()) &&
$channel == $this->getChannel();
}
 
function isInstalled($dep, $oper = '==')
1172,11 → 1086,9
if (!$dep) {
return false;
}
 
if ($oper != 'ge' && $oper != 'gt' && $oper != 'has' && $oper != '==') {
return false;
}
 
if (is_object($dep)) {
$package = $dep->getPackage();
$channel = $dep->getChannel();
1199,15 → 1111,13
$package = $dep['info']->getPackage();
}
}
 
$options = $this->_downloader->getOptions();
$test = $this->_installRegistry->packageExists($package, $channel);
$test = $this->_installRegistry->packageExists($package, $channel);
if (!$test && $channel == 'pecl.php.net') {
// do magic to allow upgrading from old pecl packages to new ones
$test = $this->_installRegistry->packageExists($package, 'pear.php.net');
$channel = 'pear.php.net';
}
 
if ($test) {
if (isset($dep['uri'])) {
if ($this->_installRegistry->packageInfo($package, 'uri', '__uri') == $dep['uri']) {
1214,73 → 1124,35
return true;
}
}
 
if (isset($options['upgrade'])) {
$packageVersion = $this->_installRegistry->packageInfo($package, 'version', $channel);
if (version_compare($packageVersion, $dep['version'], '>=')) {
return true;
if ($oper == 'has') {
if (version_compare($this->_installRegistry->packageInfo(
$package, 'version', $channel),
$dep['version'], '>=')) {
return true;
} else {
return false;
}
} else {
if (version_compare($this->_installRegistry->packageInfo(
$package, 'version', $channel),
$dep['version'], '>=')) {
return true;
}
return false;
}
 
return false;
}
 
return true;
}
 
return false;
}
 
/**
* Detect duplicate package names with differing versions
*
* If a user requests to install Date 1.4.6 and Date 1.4.7,
* for instance, this is a logic error. This method
* detects this situation.
*
* @param array $params array of PEAR_Downloader_Package objects
* @param array $errorparams empty array
* @return array array of stupid duplicated packages in PEAR_Downloader_Package obejcts
*/
public static function detectStupidDuplicates($params, &$errorparams)
{
$existing = array();
foreach ($params as $i => $param) {
$package = $param->getPackage();
$channel = $param->getChannel();
$group = $param->getGroup();
if (!isset($existing[$channel . '/' . $package])) {
$existing[$channel . '/' . $package] = array();
}
 
if (!isset($existing[$channel . '/' . $package][$group])) {
$existing[$channel . '/' . $package][$group] = array();
}
 
$existing[$channel . '/' . $package][$group][] = $i;
}
 
$indices = array();
foreach ($existing as $package => $groups) {
foreach ($groups as $group => $dupes) {
if (count($dupes) > 1) {
$indices = $indices + $dupes;
}
}
}
 
$indices = array_unique($indices);
foreach ($indices as $index) {
$errorparams[] = $params[$index];
}
 
return count($errorparams);
}
 
/**
* @param array
* @param bool ignore install groups - for final removal of dupe packages
* @static
*/
public static function removeDuplicates(&$params, $ignoreGroups = false)
function removeDuplicates(&$params, $ignoreGroups = false)
{
$pnames = array();
foreach ($params as $i => $param) {
1287,44 → 1159,45
if (!$param) {
continue;
}
 
if ($param->getPackage()) {
$group = $ignoreGroups ? '' : $param->getGroup();
if ($ignoreGroups) {
$group = '';
} else {
$group = $param->getGroup();
}
$pnames[$i] = $param->getChannel() . '/' .
$param->getPackage() . '-' . $param->getVersion() . '#' . $group;
}
}
 
$pnames = array_unique($pnames);
$unset = array_diff(array_keys($params), array_keys($pnames));
$testp = array_flip($pnames);
$unset = array_diff(array_keys($params), array_keys($pnames));
$testp = array_flip($pnames);
foreach ($params as $i => $param) {
if (!$param) {
$unset[] = $i;
continue;
}
 
if (!is_a($param, 'PEAR_Downloader_Package')) {
$unset[] = $i;
continue;
}
 
$group = $ignoreGroups ? '' : $param->getGroup();
if ($ignoreGroups) {
$group = '';
} else {
$group = $param->getGroup();
}
if (!isset($testp[$param->getChannel() . '/' . $param->getPackage() . '-' .
$param->getVersion() . '#' . $group])) {
$unset[] = $i;
}
}
 
foreach ($unset as $i) {
unset($params[$i]);
}
 
$ret = array();
foreach ($params as $i => $param) {
$ret[] = &$params[$i];
}
 
$params = array();
foreach ($ret as $i => $param) {
$params[] = &$ret[$i];
1342,15 → 1215,16
}
 
/**
* @static
*/
public static function mergeDependencies(&$params)
function mergeDependencies(&$params)
{
$bundles = $newparams = array();
$newparams = array();
$bundles = array();
foreach ($params as $i => $param) {
if (!$param->isBundle()) {
continue;
}
 
$bundles[] = $i;
$pf = &$param->getPackageFile();
$newdeps = array();
1358,7 → 1232,6
if (!is_array($contents)) {
$contents = array($contents);
}
 
foreach ($contents as $file) {
$filecontents = $pf->getFileContents($file);
$dl = &$param->getDownloader();
1366,28 → 1239,22
if (PEAR::isError($dir = $dl->getDownloadDir())) {
return $dir;
}
 
$fp = @fopen($dir . DIRECTORY_SEPARATOR . $file, 'wb');
if (!$fp) {
continue;
}
 
// FIXME do symlink check
 
fwrite($fp, $filecontents, strlen($filecontents));
fclose($fp);
if ($s = $params[$i]->explicitState()) {
$obj->setExplicitState($s);
}
 
$obj = new PEAR_Downloader_Package($params[$i]->getDownloader());
$obj = &new PEAR_Downloader_Package($params[$i]->getDownloader());
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
if (PEAR::isError($dir = $dl->getDownloadDir())) {
PEAR::popErrorHandling();
return $dir;
}
$a = $dir . DIRECTORY_SEPARATOR . $file;
$e = $obj->_fromFile($a);
$e = $obj->_fromFile($a = $dir . DIRECTORY_SEPARATOR . $file);
PEAR::popErrorHandling();
if (PEAR::isError($e)) {
if (!isset($options['soft'])) {
1395,18 → 1262,16
}
continue;
}
 
if (!PEAR_Downloader_Package::willDownload($obj,
array_merge($params, $newparams)) && !$param->isInstalled($obj)) {
$newparams[] = $obj;
$j = &$obj;
if (!PEAR_Downloader_Package::willDownload($j,
array_merge($params, $newparams)) && !$param->isInstalled($j)) {
$newparams[] = &$j;
}
}
}
 
foreach ($bundles as $i) {
unset($params[$i]); // remove bundles - only their contents matter for installation
}
 
PEAR_Downloader_Package::removeDuplicates($params); // strip any unset indices
if (count($newparams)) { // add in bundled packages for install
foreach ($newparams as $i => $unused) {
1414,29 → 1279,24
}
$newparams = array();
}
 
foreach ($params as $i => $param) {
$newdeps = array();
foreach ($param->_downloadDeps as $dep) {
$merge = array_merge($params, $newparams);
if (!PEAR_Downloader_Package::willDownload($dep, $merge)
&& !$param->isInstalled($dep)
) {
if (!PEAR_Downloader_Package::willDownload($dep,
array_merge($params, $newparams)) && !$param->isInstalled($dep)) {
$newdeps[] = $dep;
} else {
//var_dump($dep);
// detect versioning conflicts here
}
}
 
// convert the dependencies into PEAR_Downloader_Package objects for the next time around
// convert the dependencies into PEAR_Downloader_Package objects for the next time
// around
$params[$i]->_downloadDeps = array();
foreach ($newdeps as $dep) {
$obj = new PEAR_Downloader_Package($params[$i]->getDownloader());
$obj = &new PEAR_Downloader_Package($params[$i]->getDownloader());
if ($s = $params[$i]->explicitState()) {
$obj->setExplicitState($s);
}
 
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$e = $obj->fromDepURL($dep);
PEAR::popErrorHandling();
1446,7 → 1306,6
}
continue;
}
 
$e = $obj->detectDependencies($params);
if (PEAR::isError($e)) {
if (!isset($options['soft'])) {
1453,36 → 1312,34
$obj->_downloader->log(0, $e->getMessage());
}
}
 
$newparams[] = $obj;
$j = &$obj;
$newparams[] = &$j;
}
}
 
if (count($newparams)) {
foreach ($newparams as $i => $unused) {
$params[] = &$newparams[$i];
}
return true;
} else {
return false;
}
 
return false;
}
 
 
/**
* @static
*/
public static function willDownload($param, $params)
function willDownload($param, $params)
{
if (!is_array($params)) {
return false;
}
 
foreach ($params as $obj) {
if ($obj->isEqual($param)) {
return true;
}
}
 
return false;
}
 
1492,12 → 1349,13
* @param int
* @param string
*/
function &getPackagefileObject(&$c, $d)
function &getPackagefileObject(&$c, $d, $t = false)
{
$a = new PEAR_PackageFile($c, $d);
$a = &new PEAR_PackageFile($c, $d, $t);
return $a;
}
 
 
/**
* This will retrieve from a local file if possible, and parse out
* a group name as well. The original parameter will be modified to reflect this.
1511,17 → 1369,25
if (!@file_exists($param)) {
$test = explode('#', $param);
$group = array_pop($test);
if (@file_exists(implode('#', $test))) {
if (file_exists(implode('#', $test))) {
$this->setGroup($group);
$param = implode('#', $test);
$this->_explicitGroup = true;
}
}
 
if (@is_file($param)) {
$this->_type = 'local';
$options = $this->_downloader->getOptions();
$pkg = &$this->getPackagefileObject($this->_config, $this->_downloader->_debug);
if (isset($options['downloadonly'])) {
$pkg = &$this->getPackagefileObject($this->_config,
$this->_downloader->_debug);
} else {
if (PEAR::isError($dir = $this->_downloader->getDownloadDir())) {
return $dir;
}
$pkg = &$this->getPackagefileObject($this->_config,
$this->_downloader->_debug, $dir);
}
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$pf = &$pkg->fromAnyFile($param, PEAR_VALIDATE_INSTALLING);
PEAR::popErrorHandling();
1543,7 → 1409,8
 
function _fromUrl($param, $saveparam = '')
{
if (!is_array($param) && (preg_match('#^(http|https|ftp)://#', $param))) {
if (!is_array($param) &&
(preg_match('#^(http|ftp)://#', $param))) {
$options = $this->_downloader->getOptions();
$this->_type = 'url';
$callback = $this->_downloader->ui ?
1553,10 → 1420,8
$this->_downloader->popErrorHandling();
return $dir;
}
 
$this->_downloader->log(3, 'Downloading "' . $param . '"');
$file = $this->_downloader->downloadHttp($param, $this->_downloader->ui,
$dir, $callback, null, false, $this->getChannel());
$dir, $callback);
$this->_downloader->popErrorHandling();
if (PEAR::isError($file)) {
if (!empty($saveparam)) {
1566,35 → 1431,39
'"' . $saveparam . ' (' . $file->getMessage() . ')');
return $err;
}
 
if ($this->_rawpackagefile) {
require_once 'Archive/Tar.php';
$tar = new Archive_Tar($file);
$tar = &new Archive_Tar($file);
$packagexml = $tar->extractInString('package2.xml');
if (!$packagexml) {
$packagexml = $tar->extractInString('package.xml');
}
 
if (str_replace(array("\n", "\r"), array('',''), $packagexml) !=
str_replace(array("\n", "\r"), array('',''), $this->_rawpackagefile)) {
if ($this->getChannel() != 'pear.php.net') {
if ($this->getChannel() == 'pear.php.net') {
// be more lax for the existing PEAR packages that have not-ok
// characters in their package.xml
$this->_downloader->log(0, 'CRITICAL WARNING: The "' .
$this->getPackage() . '" package has invalid characters in its ' .
'package.xml. The next version of PEAR may not be able to install ' .
'this package for security reasons. Please open a bug report at ' .
'http://pear.php.net/package/' . $this->getPackage() . '/bugs');
} else {
return PEAR::raiseError('CRITICAL ERROR: package.xml downloaded does ' .
'not match value returned from xml-rpc');
}
 
// be more lax for the existing PEAR packages that have not-ok
// characters in their package.xml
$this->_downloader->log(0, 'CRITICAL WARNING: The "' .
$this->getPackage() . '" package has invalid characters in its ' .
'package.xml. The next version of PEAR may not be able to install ' .
'this package for security reasons. Please open a bug report at ' .
'http://pear.php.net/package/' . $this->getPackage() . '/bugs');
}
}
 
// whew, download worked!
$pkg = &$this->getPackagefileObject($this->_config, $this->_downloader->debug);
 
if (isset($options['downloadonly'])) {
$pkg = &$this->getPackagefileObject($this->_config, $this->_downloader->debug);
} else {
if (PEAR::isError($dir = $this->_downloader->getDownloadDir())) {
return $dir;
}
$pkg = &$this->getPackagefileObject($this->_config, $this->_downloader->debug,
$dir);
}
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$pf = &$pkg->fromAnyFile($file, PEAR_VALIDATE_INSTALLING);
PEAR::popErrorHandling();
1604,30 → 1473,23
if (is_array($err)) {
$err = $err['message'];
}
 
if (!isset($options['soft'])) {
$this->_downloader->log(0, "Validation Error: $err");
}
}
}
 
if (!isset($options['soft'])) {
$this->_downloader->log(0, $pf->getMessage());
}
 
///FIXME need to pass back some error code that we can use to match with to cancel all further operations
/// At least stop all deps of this package from being installed
$out = $saveparam ? $saveparam : $param;
$err = PEAR::raiseError('Download of "' . $out . '" succeeded, but it is not a valid package archive');
$err = PEAR::raiseError('Download of "' . ($saveparam ? $saveparam :
$param) . '" succeeded, but it is not a valid package archive');
$this->_valid = false;
return $err;
}
 
$this->_packagefile = &$pf;
$this->setGroup('default'); // install the default dependency group
return $this->_valid = true;
}
 
return $this->_valid = false;
}
 
1644,9 → 1506,9
function _fromString($param)
{
$options = $this->_downloader->getOptions();
$channel = $this->_config->get('default_channel');
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$pname = $this->_registry->parsePackageName($param, $channel);
$pname = $this->_registry->parsePackageName($param,
$this->_config->get('default_channel'));
PEAR::popErrorHandling();
if (PEAR::isError($pname)) {
if ($pname->getCode() == 'invalid') {
1653,13 → 1515,13
$this->_valid = false;
return false;
}
 
if ($pname->getCode() == 'channel') {
$parsed = $pname->getUserInfo();
if ($this->_downloader->discover($parsed['channel'])) {
if ($this->_config->get('auto_discover')) {
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
$pname = $this->_registry->parsePackageName($param, $channel);
$pname = $this->_registry->parsePackageName($param,
$this->_config->get('default_channel'));
PEAR::popErrorHandling();
} else {
if (!isset($options['soft'])) {
1670,17 → 1532,15
}
}
}
 
if (PEAR::isError($pname)) {
if (!isset($options['soft'])) {
$this->_downloader->log(0, $pname->getMessage());
}
 
if (is_array($param)) {
$param = $this->_registry->parsedPackageNameToString($param);
}
 
$err = PEAR::raiseError('invalid package name/package file "' . $param . '"');
$err = PEAR::raiseError('invalid package name/package file "' .
$param . '"');
$this->_valid = false;
return $err;
}
1688,21 → 1548,26
if (!isset($options['soft'])) {
$this->_downloader->log(0, $pname->getMessage());
}
 
$err = PEAR::raiseError('invalid package name/package file "' . $param . '"');
$err = PEAR::raiseError('invalid package name/package file "' .
$param . '"');
$this->_valid = false;
return $err;
}
}
 
if (!isset($this->_type)) {
$this->_type = 'rest';
$this->_type = 'xmlrpc';
}
 
$this->_parsedname = $pname;
$this->_explicitState = isset($pname['state']) ? $pname['state'] : false;
$this->_explicitGroup = isset($pname['group']) ? true : false;
 
$this->_parsedname = $pname;
if (isset($pname['state'])) {
$this->_explicitState = $pname['state'];
} else {
$this->_explicitState = false;
}
if (isset($pname['group'])) {
$this->_explicitGroup = true;
} else {
$this->_explicitGroup = false;
}
$info = $this->_downloader->_getPackageDownloadUrl($pname);
if (PEAR::isError($info)) {
if ($info->getCode() != -976 && $pname['channel'] == 'pear.php.net') {
1721,16 → 1586,13
$pname['channel'] = 'pear.php.net';
}
}
 
return $info;
}
 
$this->_rawpackagefile = $info['raw'];
$ret = $this->_analyzeDownloadURL($info, $param, $pname);
if (PEAR::isError($ret)) {
return $ret;
}
 
if ($ret) {
$this->_downloadURL = $ret;
return $this->_valid = (bool) $ret;
1753,15 → 1615,16
if (!is_string($param) && PEAR_Downloader_Package::willDownload($param, $params)) {
return false;
}
 
if ($info === false) {
$saveparam = !is_string($param) ? ", cannot download \"$param\"" : '';
 
if (!$info) {
if (!is_string($param)) {
$saveparam = ", cannot download \"$param\"";
} else {
$saveparam = '';
}
// no releases exist
return PEAR::raiseError('No releases for package "' .
$this->_registry->parsedPackageNameToString($pname, true) . '" exist' . $saveparam);
}
 
if (strtolower($info['info']->getChannel()) != strtolower($pname['channel'])) {
$err = false;
if ($pname['channel'] == 'pecl.php.net') {
1775,7 → 1638,6
} else {
$err = true;
}
 
if ($err) {
return PEAR::raiseError('SECURITY ERROR: package in channel "' . $pname['channel'] .
'" retrieved another channel\'s name for download! ("' .
1782,13 → 1644,11
$info['info']->getChannel() . '")');
}
}
 
$preferred_state = $this->_config->get('preferred_state');
if (!isset($info['url'])) {
$package_version = $this->_registry->packageInfo($info['info']->getPackage(),
'version', $info['info']->getChannel());
if ($this->isInstalled($info)) {
if ($isdependency && version_compare($info['version'], $package_version, '<=')) {
if ($isdependency && version_compare($info['version'],
$this->_registry->packageInfo($info['info']->getPackage(),
'version', $info['info']->getChannel()), '<=')) {
// ignore bogus errors of "failed to download dependency"
// if it is already installed and the one that would be
// downloaded is older or the same version (Bug #7219)
1795,27 → 1655,6
return false;
}
}
 
if ($info['version'] === $package_version) {
if (!isset($options['soft'])) {
$this->_downloader->log(1, 'WARNING: failed to download ' . $pname['channel'] .
'/' . $pname['package'] . '-' . $package_version. ', additionally the suggested version' .
' (' . $package_version . ') is the same as the locally installed one.');
}
 
return false;
}
 
if (version_compare($info['version'], $package_version, '<=')) {
if (!isset($options['soft'])) {
$this->_downloader->log(1, 'WARNING: failed to download ' . $pname['channel'] .
'/' . $pname['package'] . '-' . $package_version . ', additionally the suggested version' .
' (' . $info['version'] . ') is a lower version than the locally installed one (' . $package_version . ').');
}
 
return false;
}
 
$instead = ', will instead download version ' . $info['version'] .
', stability "' . $info['info']->getState() . '"';
// releases exist, but we failed to get any
1828,9 → 1667,8
if (!class_exists('PEAR_Common')) {
require_once 'PEAR/Common.php';
}
 
if (!in_array($info['info']->getState(),
PEAR_Common::betterStates($preferred_state, true))) {
PEAR_Common::betterStates($this->_config->get('preferred_state'), true))) {
if ($optional) {
// don't spit out confusing error message
return $this->_downloader->_getPackageDownloadUrl(
1838,13 → 1676,12
'channel' => $pname['channel'],
'version' => $info['version']));
}
$vs = ' within preferred state "' . $preferred_state .
$vs = ' within preferred state "' . $this->_config->get('preferred_state') .
'"';
} else {
if (!class_exists('PEAR_Dependency2')) {
require_once 'PEAR/Dependency2.php';
}
 
if ($optional) {
// don't spit out confusing error message
return $this->_downloader->_getPackageDownloadUrl(
1856,14 → 1693,13
$instead = '';
}
} else {
$vs = ' within preferred state "' . $preferred_state . '"';
$vs = ' within preferred state "' . $this->_config->get(
'preferred_state') . '"';
}
 
if (!isset($options['soft'])) {
$this->_downloader->log(1, 'WARNING: failed to download ' . $pname['channel'] .
'/' . $pname['package'] . $vs . $instead);
}
 
// download the latest release
return $this->_downloader->_getPackageDownloadUrl(
array('package' => $pname['package'],
1870,22 → 1706,6
'channel' => $pname['channel'],
'version' => $info['version']));
} else {
if (isset($info['php']) && $info['php']) {
$err = PEAR::raiseError('Failed to download ' .
$this->_registry->parsedPackageNameToString(
array('channel' => $pname['channel'],
'package' => $pname['package']),
true) .
', latest release is version ' . $info['php']['v'] .
', but it requires PHP version "' .
$info['php']['m'] . '", use "' .
$this->_registry->parsedPackageNameToString(
array('channel' => $pname['channel'], 'package' => $pname['package'],
'version' => $info['php']['v'])) . '" to install',
PEAR_DOWNLOADER_PACKAGE_PHPVERSION);
return $err;
}
 
// construct helpful error message
if (isset($pname['version'])) {
$vs = ', version "' . $pname['version'] . '"';
1895,9 → 1715,8
if (!class_exists('PEAR_Common')) {
require_once 'PEAR/Common.php';
}
 
if (!in_array($info['info']->getState(),
PEAR_Common::betterStates($preferred_state, true))) {
PEAR_Common::betterStates($this->_config->get('preferred_state'), true))) {
if ($optional) {
// don't spit out confusing error message, and don't die on
// optional dep failure!
1906,12 → 1725,12
'channel' => $pname['channel'],
'version' => $info['version']));
}
$vs = ' within preferred state "' . $preferred_state . '"';
$vs = ' within preferred state "' . $this->_config->get('preferred_state') .
'"';
} else {
if (!class_exists('PEAR_Dependency2')) {
require_once 'PEAR/Dependency2.php';
}
 
if ($optional) {
// don't spit out confusing error message, and don't die on
// optional dep failure!
1923,9 → 1742,9
$vs = PEAR_Dependency2::_getExtraString($pname);
}
} else {
$vs = ' within preferred state "' . $this->_downloader->config->get('preferred_state') . '"';
$vs = ' within preferred state "' . $this->_downloader->config->get(
'preferred_state') . '"';
}
 
$options = $this->_downloader->getOptions();
// this is only set by the "download-all" command
if (isset($options['ignorepreferred_state'])) {
1942,32 → 1761,22
PEAR_DOWNLOADER_PACKAGE_STATE);
return $err;
}
 
// Checks if the user has a package installed already and checks the release against
// the state against the installed package, this allows upgrades for packages
// with lower stability than the preferred_state
$stability = $this->_registry->packageInfo($pname['package'], 'stability', $pname['channel']);
if (!$this->isInstalled($info)
|| !in_array($info['info']->getState(), PEAR_Common::betterStates($stability['release'], true))
) {
$err = PEAR::raiseError(
'Failed to download ' . $this->_registry->parsedPackageNameToString(
array('channel' => $pname['channel'], 'package' => $pname['package']),
true)
. $vs .
', latest release is version ' . $info['version'] .
', stability "' . $info['info']->getState() . '", use "' .
$this->_registry->parsedPackageNameToString(
array('channel' => $pname['channel'], 'package' => $pname['package'],
'version' => $info['version'])) . '" to install');
return $err;
}
$err = PEAR::raiseError(
'Failed to download ' . $this->_registry->parsedPackageNameToString(
array('channel' => $pname['channel'], 'package' => $pname['package']),
true)
. $vs .
', latest release is version ' . $info['version'] .
', stability "' . $info['info']->getState() . '", use "' .
$this->_registry->parsedPackageNameToString(
array('channel' => $pname['channel'], 'package' => $pname['package'],
'version' => $info['version'])) . '" to install');
return $err;
}
}
 
if (isset($info['deprecated']) && $info['deprecated']) {
$this->_downloader->log(0,
'WARNING: "' .
'WARNING: "' .
$this->_registry->parsedPackageNameToString(
array('channel' => $info['info']->getChannel(),
'package' => $info['info']->getPackage()), true) .
1975,7 → 1784,7
$this->_registry->parsedPackageNameToString($info['deprecated'], true) .
'"');
}
 
return $info;
}
}
?>
/trunk/bibliotheque/pear/PEAR/Task/Windowseol.php
4,13 → 4,20
*
* 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
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Windowseol.php,v 1.7 2006/01/06 04:47:37 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
/**
* Base class
18,35 → 25,33
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.10.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_Task_Windowseol extends PEAR_Task_Common
{
public $type = 'simple';
public $phase = PEAR_TASK_PACKAGE;
public $_replacements;
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
* @param PEAR_PackageFile_v2
* @param array raw, parsed xml
* @param PEAR_Config
* @static
*/
public static function validateXml($pkg, $xml, $config, $fileXml)
function validateXml($pkg, $xml, &$config, $fileXml)
{
if ($xml != '') {
return array(PEAR_TASK_ERROR_INVALID, 'no attributes allowed');
}
 
return true;
}
 
54,9 → 59,8
* Initialize a task instance with the parameters
* @param array raw, parsed xml
* @param unused
* @param unused
*/
public function init($xml, $attribs, $lastVersion = null)
function init($xml, $attribs)
{
}
 
64,17 → 68,16
* 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)
* @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
* (use $this->throwError), otherwise return the new contents
*/
public function startSession($pkg, $contents, $dest)
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);
}
}
?>
/trunk/bibliotheque/pear/PEAR/Task/Postinstallscript/rw.php
4,13 → 4,20
*
* 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
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a10
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: rw.php,v 1.11 2006/01/06 04:47:37 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a10
*/
/**
* Base class
21,9 → 28,9
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a10
*/
34,31 → 41,30
*
* @var PEAR_PackageFile_v2_rw
*/
public $_pkg;
var $_pkg;
/**
* Enter description here...
*
* @param PEAR_PackageFile_v2_rw $pkg Package
* @param PEAR_Config $config Config
* @param PEAR_Frontend $logger Logger
* @param array $fileXml XML
*
* @param PEAR_PackageFile_v2_rw $pkg
* @param PEAR_Config $config
* @param PEAR_Frontend $logger
* @param array $fileXml
* @return PEAR_Task_Postinstallscript_rw
*/
function __construct(&$pkg, &$config, &$logger, $fileXml)
function PEAR_Task_Postinstallscript_rw(&$pkg, &$config, &$logger, $fileXml)
{
parent::__construct($config, $logger, PEAR_TASK_PACKAGE);
parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE);
$this->_contents = $fileXml;
$this->_pkg = &$pkg;
$this->_params = array();
}
 
public function validate()
function validate()
{
return $this->validateXml($this->_pkg, $this->_params, $this->config, $this->_contents);
}
 
public function getName()
function getName()
{
return 'postinstallscript';
}
70,15 → 76,14
* 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 $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
*/
public function addParamGroup($id, $params = false, $instructions = false)
function addParamGroup($id, $params = false, $instructions = false)
{
if ($params && isset($params[0]) && !isset($params[1])) {
$params = $params[0];
85,19 → 90,19
}
$stuff =
array(
$this->_pkg->getTasksNs().':id' => $id,
$this->_pkg->getTasksNs() . ':id' => $id,
);
if ($instructions) {
$stuff[$this->_pkg->getTasksNs().':instructions'] = $instructions;
$stuff[$this->_pkg->getTasksNs() . ':instructions'] = $instructions;
}
if ($params) {
$stuff[$this->_pkg->getTasksNs().':param'] = $params;
$stuff[$this->_pkg->getTasksNs() . ':param'] = $params;
}
$this->_params[$this->_pkg->getTasksNs().':paramgroup'][] = $stuff;
$this->_params[$this->_pkg->getTasksNs() . ':paramgroup'][] = $stuff;
}
 
/**
* Add a complex <paramgroup> to the post-install script with conditions
* add a complex <paramgroup> to the post-install script with conditions
*
* This inserts a <paramgroup> with
*
105,46 → 110,42
* 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 $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
*/
public function addConditionTypeGroup($id,
$oldgroup,
$param,
$value,
$conditiontype = '=',
$params = false,
$instructions = false
) {
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,
);
$stuff =
array(
$this->_pkg->getTasksNs() . ':id' => $id,
);
if ($instructions) {
$stuff[$this->_pkg->getTasksNs().':instructions'] = $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;
$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;
$stuff[$this->_pkg->getTasksNs() . ':param'] = $params;
}
$this->_params[$this->_pkg->getTasksNs().':paramgroup'][] = $stuff;
$this->_params[$this->_pkg->getTasksNs() . ':paramgroup'][] = $stuff;
}
 
public function getXml()
function getXml()
{
return $this->_params;
}
151,32 → 152,25
 
/**
* Use to set up a param tag for use in creating a paramgroup
*
* @param mixed $name Name of parameter
* @param mixed $prompt Prompt
* @param string $type Type, defaults to 'string'
* @param mixed $default Default value
*
* @return array
* @static
*/
public static function getParam(
$name, $prompt, $type = 'string', $default = null
) {
function getParam($name, $prompt, $type = 'string', $default = null)
{
if ($default !== null) {
return
return
array(
$this->_pkg->getTasksNs().':name' => $name,
$this->_pkg->getTasksNs().':prompt' => $prompt,
$this->_pkg->getTasksNs().':type' => $type,
$this->_pkg->getTasksNs().':default' => $default,
$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,
$this->_pkg->getTasksNs() . ':name' => $name,
$this->_pkg->getTasksNs() . ':prompt' => $prompt,
$this->_pkg->getTasksNs() . ':type' => $type,
);
}
}
?>
/trunk/bibliotheque/pear/PEAR/Task/Replace.php
4,13 → 4,20
*
* 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
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Replace.php,v 1.15 2006/03/02 18:14:13 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
/**
* Base class
21,26 → 28,26
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_Task_Replace extends PEAR_Task_Common
{
public $type = 'simple';
public $phase = PEAR_TASK_PACKAGEANDINSTALL;
public $_replacements;
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
* @param PEAR_PackageFile_v2
* @param array raw, parsed xml
* @param PEAR_Config
* @static
*/
public static function validateXml($pkg, $xml, $config, $fileXml)
function validateXml($pkg, $xml, &$config, $fileXml)
{
if (!isset($xml['attribs'])) {
return array(PEAR_TASK_ERROR_NOATTRIBS);
57,7 → 64,7
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(), );
$config->getKeys());
}
} elseif ($xml['attribs']['type'] == 'php-const') {
if (defined($xml['attribs']['to'])) {
64,16 → 71,14
return true;
} else {
return array(PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE, 'to', $xml['attribs']['to'],
array('valid PHP constant'), );
array('valid PHP constant'));
}
} elseif ($xml['attribs']['type'] == 'package-info') {
if (in_array(
$xml['attribs']['to'],
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', )
)) {
'date', 'time'))) {
return true;
} else {
return array(PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE, 'to', $xml['attribs']['to'],
80,13 → 85,12
array('name', 'summary', 'channel', 'notes', 'extends', 'description',
'release_notes', 'license', 'release-license', 'license-uri',
'version', 'api-version', 'state', 'api-state', 'release_date',
'date', 'time', ), );
'date', 'time'));
}
} else {
return array(PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE, 'type', $xml['attribs']['type'],
array('pear-config', 'package-info', 'php-const'), );
array('pear-config', 'package-info', 'php-const'));
}
 
return true;
}
 
94,9 → 98,8
* Initialize a task instance with the parameters
* @param array raw, parsed xml
* @param unused
* @param unused
*/
public function init($xml, $attribs, $lastVersion = null)
function init($xml, $attribs)
{
$this->_replacements = isset($xml['attribs']) ? array($xml) : $xml;
}
105,14 → 108,13
* 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)
* @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
* (use $this->throwError), otherwise return the new contents
*/
public function startSession($pkg, $contents, $dest)
function startSession($pkg, $contents, $dest)
{
$subst_from = $subst_to = array();
foreach ($this->_replacements as $a) {
128,7 → 130,6
$to = $chan->getServer();
} else {
$this->logger->log(0, "$dest: invalid pear-config replacement: $a[to]");
 
return false;
}
} else {
145,7 → 146,6
}
if (is_null($to)) {
$this->logger->log(0, "$dest: invalid pear-config replacement: $a[to]");
 
return false;
}
} elseif ($a['type'] == 'php-const') {
156,7 → 156,6
$to = constant($a['to']);
} else {
$this->logger->log(0, "$dest: invalid php-const replacement: $a[to]");
 
return false;
}
} else {
164,7 → 163,6
$to = $t;
} else {
$this->logger->log(0, "$dest: invalid package-info replacement: $a[to]");
 
return false;
}
}
173,14 → 171,12
$subst_to[] = $to;
}
}
$this->logger->log(
3, "doing ".sizeof($subst_from).
" substitution(s) for $dest"
);
$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;
}
}
?>
/trunk/bibliotheque/pear/PEAR/Task/Unixeol/rw.php
4,13 → 4,20
*
* 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
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a10
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: rw.php,v 1.4 2006/01/06 04:47:37 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a10
*/
/**
* Base class
21,35 → 28,35
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @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 __construct(&$pkg, &$config, &$logger, $fileXml)
function PEAR_Task_Unixeol_rw(&$pkg, &$config, &$logger, $fileXml)
{
parent::__construct($config, $logger, PEAR_TASK_PACKAGE);
parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE);
$this->_contents = $fileXml;
$this->_pkg = &$pkg;
$this->_params = array();
}
 
public function validate()
function validate()
{
return true;
}
 
public function getName()
function getName()
{
return 'unixeol';
}
 
public function getXml()
function getXml()
{
return '';
}
}
?>
?>
/trunk/bibliotheque/pear/PEAR/Task/Postinstallscript.php
4,13 → 4,20
*
* 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
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Postinstallscript.php,v 1.18 2006/02/08 01:21:47 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
/**
* Base class
21,29 → 28,28
*
* 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.10.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_Task_Postinstallscript extends PEAR_Task_Common
{
public $type = 'script';
public $_class;
public $_params;
public $_obj;
var $type = 'script';
var $_class;
var $_params;
var $_obj;
/**
*
* @var PEAR_PackageFile_v2
*/
public $_pkg;
public $_contents;
public $phase = PEAR_TASK_INSTALL;
var $_pkg;
var $_contents;
var $phase = PEAR_TASK_INSTALL;
 
/**
* Validate the raw xml at parsing-time.
50,29 → 56,28
*
* 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
* @param PEAR_PackageFile_v2
* @param array The XML contents of the <postinstallscript> tag
* @param PEAR_Config
* @param array the entire parsed <file> tag
* @static
*/
public static function validateXml($pkg, $xml, $config, $fileXml)
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"', );
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(), );
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!', );
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) {
79,37 → 84,29
PEAR::popErrorHandling();
$warnings = '';
foreach ($pkg->getValidationWarnings() as $warn) {
$warnings .= $warn['message']."\n";
$warnings .= $warn['message'] . "\n";
}
 
return array(PEAR_TASK_ERROR_INVALID, 'Analysis of post-install script "'.
$fileXml['name'].'" failed: '.$warnings, );
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', );
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') {
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"', );
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()', );
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) {
119,137 → 116,129
}
if (count($methods)) {
PEAR::popErrorHandling();
 
return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "'.
$fileXml['name'].'" must declare methods init() and run()', );
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'])) {
$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 (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 . '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 . '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 (!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 (!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 . '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 . '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'])) {
if (!isset($param[$tasksNamespace . 'param'])) {
continue; // <param> is no longer required
}
$subparams = $param[$tasksNamespace.'param'];
$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 (!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 (!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 . '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', );
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'];
$definedparams[] = $param[$tasksNamespace . 'id'] . '::' .
$subparam[$tasksNamespace . 'name'];
}
}
}
 
return true;
}
 
/**
* Initialize a task instance with the parameters
* @param array $xml raw, parsed xml
* @param array $fileattribs attributes from the <file> tag containing
* this task
* @param string|null $lastversion last installed version of this package,
* if any (useful for upgrades)
* @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)
*/
public function init($xml, $fileattribs, $lastversion)
function init($xml, $fileattribs, $lastversion)
{
$this->_class = str_replace('/', '_', $fileattribs['name']);
$this->_filename = $fileattribs['name'];
$this->_class = str_replace('.php', '', $this->_class).'_postinstall';
$this->_class = str_replace ('.php', '', $this->_class) . '_postinstall';
$this->_params = $xml;
$this->_lastversion = $lastversion;
}
259,7 → 248,7
*
* @access private
*/
public function _stripNamespace($params = null)
function _stripNamespace($params = null)
{
if ($params === null) {
$params = array();
270,7 → 259,7
if (is_array($param)) {
$param = $this->_stripNamespace($param);
}
$params[str_replace($this->_pkg->getTasksNs().':', '', $i)] = $param;
$params[str_replace($this->_pkg->getTasksNs() . ':', '', $i)] = $param;
}
$this->_params = $params;
} else {
279,24 → 268,21
if (is_array($param)) {
$param = $this->_stripNamespace($param);
}
$newparams[str_replace($this->_pkg->getTasksNs().':', '', $i)] = $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 mixed $pkg PEAR_PackageFile_v1|PEAR_PackageFile_v2
* @param string $contents file name
*
* 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)
* (use $this->throwError)
*/
public function startSession($pkg, $contents)
function startSession($pkg, $contents)
{
if ($this->installphase != PEAR_TASK_INSTALL) {
return false;
304,21 → 290,17
// 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'
);
$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'
);
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()"');
$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();
325,25 → 307,23
if ($res) {
$this->logger->log(0, 'init succeeded');
} else {
return $this->throwError(
'init of post-install script "'.$this->_class.
'->init()" failed'
);
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
* @see PEAR_PackageFile_v2::runPostinstallScripts()
* @param array an array of tasks
* @param string install or upgrade
* @access protected
* @static
*/
public static function run()
function run()
{
}
}
?>
/trunk/bibliotheque/pear/PEAR/Task/Unixeol.php
4,13 → 4,20
*
* 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
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Unixeol.php,v 1.8 2006/01/06 04:47:37 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
/**
* Base class
21,31 → 28,30
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_Task_Unixeol extends PEAR_Task_Common
{
public $type = 'simple';
public $phase = PEAR_TASK_PACKAGE;
public $_replacements;
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
* @param PEAR_PackageFile_v2
* @param array raw, parsed xml
* @param PEAR_Config
* @static
*/
public static function validateXml($pkg, $xml, $config, $fileXml)
function validateXml($pkg, $xml, &$config, $fileXml)
{
if ($xml != '') {
return array(PEAR_TASK_ERROR_INVALID, 'no attributes allowed');
}
 
return true;
}
 
53,9 → 59,8
* Initialize a task instance with the parameters
* @param array raw, parsed xml
* @param unused
* @param unused
*/
public function init($xml, $attribs, $lastVersion = null)
function init($xml, $attribs)
{
}
 
63,17 → 68,16
* 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)
* @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
* (use $this->throwError), otherwise return the new contents
*/
public function startSession($pkg, $contents, $dest)
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);
}
}
?>
/trunk/bibliotheque/pear/PEAR/Task/Windowseol/rw.php
4,13 → 4,20
*
* 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
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a10
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: rw.php,v 1.4 2006/01/06 04:47:37 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a10
*/
/**
* Base class
18,39 → 25,38
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.10.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a10
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @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 __construct(&$pkg, &$config, &$logger, $fileXml)
function PEAR_Task_Windowseol_rw(&$pkg, &$config, &$logger, $fileXml)
{
parent::__construct($config, $logger, PEAR_TASK_PACKAGE);
parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE);
$this->_contents = $fileXml;
$this->_pkg = &$pkg;
$this->_params = array();
}
 
public function validate()
function validate()
{
return true;
}
 
public function getName()
function getName()
{
return 'windowseol';
}
 
public function getXml()
function getXml()
{
return '';
}
}
?>
?>
/trunk/bibliotheque/pear/PEAR/Task/Replace/rw.php
4,13 → 4,20
*
* 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
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a10
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: rw.php,v 1.3 2006/01/06 04:47:37 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a10
*/
/**
* Base class
21,39 → 28,40
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a10
*/
class PEAR_Task_Replace_rw extends PEAR_Task_Replace
{
public function __construct(&$pkg, &$config, &$logger, $fileXml)
function PEAR_Task_Replace_rw(&$pkg, &$config, &$logger, $fileXml)
{
parent::__construct($config, $logger, PEAR_TASK_PACKAGE);
parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE);
$this->_contents = $fileXml;
$this->_pkg = &$pkg;
$this->_params = array();
}
 
public function validate()
function validate()
{
return $this->validateXml($this->_pkg, $this->_params, $this->config, $this->_contents);
}
 
public function setInfo($from, $to, $type)
function setInfo($from, $to, $type)
{
$this->_params = array('attribs' => array('from' => $from, 'to' => $to, 'type' => $type));
}
 
public function getName()
function getName()
{
return 'replace';
}
 
public function getXml()
function getXml()
{
return $this->_params;
}
}
?>
/trunk/bibliotheque/pear/PEAR/Task/Common.php
4,13 → 4,20
*
* 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
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Common.php,v 1.16 2006/11/12 05:02:41 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
/**#@+
* Error codes for task validation routines
41,15 → 48,14
* 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.10.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
* @abstract
*/
class PEAR_Task_Common
62,35 → 68,34
* changes directly to disk
*
* Child task classes must override this property.
*
* @access protected
*/
protected $type = 'simple';
var $type = 'simple';
/**
* Determines which install phase this task is executed under
*/
public $phase = PEAR_TASK_INSTALL;
var $phase = PEAR_TASK_INSTALL;
/**
* @access protected
*/
protected $config;
var $config;
/**
* @access protected
*/
protected $registry;
var $registry;
/**
* @access protected
*/
public $logger;
var $logger;
/**
* @access protected
*/
protected $installphase;
var $installphase;
/**
* @param PEAR_Config
* @param PEAR_Common
*/
function __construct(&$config, &$logger, $phase)
function PEAR_Task_Common(&$config, &$logger, $phase)
{
$this->config = &$config;
$this->registry = &$config->getRegistry();
103,90 → 108,86
 
/**
* 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][, ...])
* 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
*
* 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
*/
public static function validateXml($pkg, $xml, $config, $fileXml)
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
* @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
*/
public function init($xml, $fileAttributes, $lastVersion)
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
* 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
* @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
*/
public function startSession($pkg, $contents, $dest)
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
* 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
*/
public static function run($tasks)
function run($tasks)
{
}
 
/**
* @static
* @final
*/
public static function hasPostinstallTasks()
function hasPostinstallTasks()
{
return isset($GLOBALS['_PEAR_TASK_POSTINSTANCES']);
}
 
/**
* @final
*/
public static 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']);
/**
* @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']);
}
 
/**
193,15 → 194,15
* Determines whether a role is a script
* @return bool
*/
public function isScript()
function isScript()
{
return $this->type == 'script';
return $this->type == 'script';
}
 
public function throwError($msg, $code = -1)
function throwError($msg, $code = -1)
{
include_once 'PEAR.php';
 
return PEAR::raiseError($msg, $code);
}
}
?>
/trunk/bibliotheque/pear/PEAR/XMLParser.php
1,15 → 1,22
<?php
/**
* PEAR_XMLParser
* PEAR_FTP
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: XMLParser.php,v 1.12 2006/03/27 04:39:03 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
16,15 → 23,15
 
/**
* 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.10.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
* @category pear
* @package PEAR
* @author Greg Beaver <cellog@php.net>
* @author Stephan Schmidt (original XML_Unserializer code)
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
class PEAR_XMLParser
{
44,13 → 51,13
* stack for all data that is found
* @var array $_dataStack
*/
var $_dataStack = array();
var $_dataStack = array();
 
/**
* stack for all values that are generated
* @var array $_valStack
*/
var $_valStack = array();
var $_valStack = array();
 
/**
* current tag depth
59,12 → 66,6
var $_depth = 0;
 
/**
* The XML encoding to use
* @var string $encoding
*/
var $encoding = 'ISO-8859-1';
 
/**
* @return array
*/
function getData()
82,19 → 83,22
include_once 'PEAR.php';
return PEAR::raiseError("XML Extension not found", 1);
}
$this->_dataStack = $this->_valStack = array();
$this->_valStack = array();
$this->_dataStack = 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')) {
if (strpos($data, 'encoding="UTF-8"')) {
$data = utf8_decode($data);
}
$xp = xml_parser_create('ISO-8859-1');
} else {
if (strpos($data, 'encoding="UTF-8"')) {
$xp = xml_parser_create('UTF-8');
} else {
$xp = xml_parser_create('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');
121,21 → 125,25
*/
function startHandler($parser, $element, $attribs)
{
$type = 'string';
 
$this->_depth++;
$this->_dataStack[$this->_depth] = null;
 
$val = array(
'name' => $element,
'value' => null,
'type' => 'string',
'childrenKeys' => array(),
'aggregKeys' => array()
);
'name' => $element,
'value' => null,
'type' => $type,
'childrenKeys' => array(),
'aggregKeys' => array()
);
 
if (count($attribs) > 0) {
$val['children'] = array();
$val['type'] = 'array';
 
$val['children']['attribs'] = $attribs;
 
}
 
array_push($this->_valStack, $val);
166,14 → 174,20
$data = $this->postProcess($this->_dataStack[$this->_depth], $element);
 
// adjust type of the value
switch (strtolower($value['type'])) {
// unserialize an array
switch(strtolower($value['type'])) {
 
/*
* unserialize an array
*/
case 'array':
if ($data !== '') {
$value['children']['_content'] = $data;
}
 
$value['value'] = isset($value['children']) ? $value['children'] : array();
if (isset($value['children'])) {
$value['value'] = $value['children'];
} else {
$value['value'] = array();
}
break;
 
/*
191,43 → 205,42
$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';
} else {
// 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();
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['aggregKeys'], $value['name']);
array_push($parent['children'][$value['name']], $value['value']);
} else {
$parent['children'][$value['name']] = &$value['value'];
array_push($parent['childrenKeys'], $value['name']);
}
array_push($parent['children'][$value['name']], $value['value']);
} else {
$parent['children'][$value['name']] = &$value['value'];
array_push($parent['childrenKeys'], $value['name']);
array_push($parent['children'],$value['value']);
}
} else {
array_push($parent['children'],$value['value']);
array_push($this->_valStack, $parent);
}
array_push($this->_valStack, $parent);
 
$this->_depth--;
}
244,4 → 257,5
{
$this->_dataStack[$this->_depth] .= $cdata;
}
}
}
?>
/trunk/bibliotheque/pear/PEAR/Packager.php
4,13 → 4,20
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Packager.php,v 1.70 2006/09/25 05:12:21 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
28,9 → 35,9
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
40,6 → 47,7
* @var PEAR_Registry
*/
var $_registry;
// {{{ package()
 
function package($pkgfile = null, $compress = true, $pkg2 = null)
{
47,10 → 55,9
if (empty($pkgfile)) {
$pkgfile = 'package.xml';
}
 
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$pkg = new PEAR_PackageFile($this->config, $this->debug);
$pf = &$pkg->fromPackageFile($pkgfile, PEAR_VALIDATE_NORMAL);
$pkg = &new PEAR_PackageFile($this->config, $this->debug);
$pf = &$pkg->fromPackageFile($pkgfile, PEAR_VALIDATE_NORMAL);
$main = &$pf;
PEAR::staticPopErrorHandling();
if (PEAR::isError($pf)) {
59,15 → 66,14
$this->log(0, 'Error: ' . $error['message']);
}
}
 
$this->log(0, $pf->getMessage());
return $this->raiseError("Cannot package, errors in package file");
} else {
foreach ($pf->getValidationWarnings() as $warning) {
$this->log(1, 'Warning: ' . $warning['message']);
}
}
 
foreach ($pf->getValidationWarnings() as $warning) {
$this->log(1, 'Warning: ' . $warning['message']);
}
 
// }}}
if ($pkg2) {
$this->log(0, 'Attempting to process the second package file');
82,34 → 88,29
}
$this->log(0, $pf2->getMessage());
return $this->raiseError("Cannot package, errors in second package file");
} else {
foreach ($pf2->getValidationWarnings() as $warning) {
$this->log(1, 'Warning: ' . $warning['message']);
}
}
 
foreach ($pf2->getValidationWarnings() as $warning) {
$this->log(1, 'Warning: ' . $warning['message']);
}
 
if ($pf2->getPackagexmlVersion() == '2.0' ||
$pf2->getPackagexmlVersion() == '2.1'
) {
$main = &$pf2;
$pf2->getPackagexmlVersion() == '2.1') {
$main = &$pf2;
$other = &$pf;
} else {
$main = &$pf;
$main = &$pf;
$other = &$pf2;
}
 
if ($main->getPackagexmlVersion() != '2.0' &&
$main->getPackagexmlVersion() != '2.1') {
return PEAR::raiseError('Error: cannot package two package.xml version 1.0, can ' .
'only package together a package.xml 1.0 and package.xml 2.0');
}
 
if ($other->getPackagexmlVersion() != '1.0') {
return PEAR::raiseError('Error: cannot package two package.xml version 2.0, can ' .
'only package together a package.xml 1.0 and package.xml 2.0');
}
}
 
$main->setLogger($this);
if (!$main->validate(PEAR_VALIDATE_PACKAGING)) {
foreach ($main->getValidationWarnings() as $warning) {
116,12 → 117,11
$this->log(0, 'Error: ' . $warning['message']);
}
return $this->raiseError("Cannot package, errors in package");
} else {
foreach ($main->getValidationWarnings() as $warning) {
$this->log(1, 'Warning: ' . $warning['message']);
}
}
 
foreach ($main->getValidationWarnings() as $warning) {
$this->log(1, 'Warning: ' . $warning['message']);
}
 
if ($pkg2) {
$other->setLogger($this);
$a = false;
129,31 → 129,26
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");
} else {
foreach ($other->getValidationWarnings() as $warning) {
$this->log(1, 'Warning: ' . $warning['message']);
}
}
 
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);
 
$pkgdir = dirname($pkgfile);
// TAR the Package -------------------------------------------
$this->log(1, "Package $dest_package done");
if (file_exists("$pkgdir/CVS/Root")) {
162,12 → 157,6
$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();
176,10 → 165,9
$this->log(0, $tgzfile->getMessage());
return $this->raiseError("Cannot package, errors in package");
}
 
$dest_package = basename($tgzfile);
$pkgdir = dirname($pkgfile);
 
$pkgdir = dirname($pkgfile);
// TAR the Package -------------------------------------------
$this->log(1, "Package $dest_package done");
if (file_exists("$pkgdir/CVS/Root")) {
187,14 → 175,25
$cvstag = "RELEASE_$cvsversion";
$this->log(1, "Tag the released code with `pear cvstag $pkgfile'");
$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;
}
}
 
// }}}
}
 
// {{{ md5_file() utility function
if (!function_exists('md5_file')) {
function md5_file($file) {
if (!$fd = @fopen($file, 'r')) {
return false;
}
fclose($fd);
$md5 = md5(file_get_contents($file));
return $md5;
}
}
// }}}
 
?>
/trunk/bibliotheque/pear/PEAR/Dependency.php
New file
0,0 → 1,495
<?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. |
// +----------------------------------------------------------------------+
// | Authors: Tomas V.V.Cox <cox@idecnet.com> |
// | Stig Bakken <ssb@php.net> |
// +----------------------------------------------------------------------+
//
// THIS FILE IS DEPRECATED IN FAVOR OF DEPENDENCY2.PHP, AND IS NOT USED IN THE INSTALLER
// $Id: Dependency.php,v 1.42 2006/03/26 23:25:56 cellog Exp $
 
require_once "PEAR.php";
require_once "OS/Guess.php";
 
define('PEAR_DEPENDENCY_MISSING', -1);
define('PEAR_DEPENDENCY_CONFLICT', -2);
define('PEAR_DEPENDENCY_UPGRADE_MINOR', -3);
define('PEAR_DEPENDENCY_UPGRADE_MAJOR', -4);
define('PEAR_DEPENDENCY_BAD_DEPENDENCY', -5);
define('PEAR_DEPENDENCY_MISSING_OPTIONAL', -6);
define('PEAR_DEPENDENCY_CONFLICT_OPTIONAL', -7);
define('PEAR_DEPENDENCY_UPGRADE_MINOR_OPTIONAL', -8);
define('PEAR_DEPENDENCY_UPGRADE_MAJOR_OPTIONAL', -9);
 
/**
* Dependency check for PEAR packages
*
* The class is based on the dependency RFC that can be found at
* http://cvs.php.net/cvs.php/pearweb/rfc. It requires PHP >= 4.1
*
* @author Tomas V.V.Vox <cox@idecnet.com>
* @author Stig Bakken <ssb@php.net>
*/
class PEAR_Dependency
{
// {{{ constructor
/**
* Constructor
*
* @access public
* @param object Registry object
* @return void
*/
function PEAR_Dependency(&$registry)
{
$this->registry = &$registry;
}
 
// }}}
// {{{ callCheckMethod()
 
/**
* This method maps the XML dependency definition to the
* corresponding one from PEAR_Dependency
*
* <pre>
* $opts => Array
* (
* [type] => pkg
* [rel] => ge
* [version] => 3.4
* [name] => HTML_Common
* [optional] => false
* )
* </pre>
*
* @param string Error message
* @param array Options
* @return boolean
*/
function callCheckMethod(&$errmsg, $opts)
{
$rel = isset($opts['rel']) ? $opts['rel'] : 'has';
$req = isset($opts['version']) ? $opts['version'] : null;
$name = isset($opts['name']) ? $opts['name'] : null;
$channel = isset($opts['channel']) ? $opts['channel'] : 'pear.php.net';
$opt = (isset($opts['optional']) && $opts['optional'] == 'yes') ?
$opts['optional'] : null;
$errmsg = '';
switch ($opts['type']) {
case 'pkg':
return $this->checkPackage($errmsg, $name, $req, $rel, $opt, $channel);
break;
case 'ext':
return $this->checkExtension($errmsg, $name, $req, $rel, $opt);
break;
case 'php':
return $this->checkPHP($errmsg, $req, $rel);
break;
case 'prog':
return $this->checkProgram($errmsg, $name);
break;
case 'os':
return $this->checkOS($errmsg, $name);
break;
case 'sapi':
return $this->checkSAPI($errmsg, $name);
break;
case 'zend':
return $this->checkZend($errmsg, $name);
break;
default:
return "'{$opts['type']}' dependency type not supported";
}
}
 
// }}}
// {{{ checkPackage()
 
/**
* Package dependencies check method
*
* @param string $errmsg Empty string, it will be populated with an error message, if any
* @param string $name Name of the package to test
* @param string $req The package version required
* @param string $relation How to compare versions with each other
* @param bool $opt Whether the relationship is optional
* @param string $channel Channel name
*
* @return mixed bool false if no error or the error string
*/
function checkPackage(&$errmsg, $name, $req = null, $relation = 'has',
$opt = false, $channel = 'pear.php.net')
{
if (is_string($req) && substr($req, 0, 2) == 'v.') {
$req = substr($req, 2);
}
switch ($relation) {
case 'has':
if (!$this->registry->packageExists($name, $channel)) {
if ($opt) {
$errmsg = "package `$channel/$name' is recommended to utilize some features.";
return PEAR_DEPENDENCY_MISSING_OPTIONAL;
}
$errmsg = "requires package `$channel/$name'";
return PEAR_DEPENDENCY_MISSING;
}
return false;
case 'not':
if ($this->registry->packageExists($name, $channel)) {
$errmsg = "conflicts with package `$channel/$name'";
return PEAR_DEPENDENCY_CONFLICT;
}
return false;
case 'lt':
case 'le':
case 'eq':
case 'ne':
case 'ge':
case 'gt':
$version = $this->registry->packageInfo($name, 'version', $channel);
if (!$this->registry->packageExists($name, $channel)
|| !version_compare("$version", "$req", $relation))
{
$code = $this->codeFromRelation($relation, $version, $req, $opt);
if ($opt) {
$errmsg = "package `$channel/$name' version " . $this->signOperator($relation) .
" $req is recommended to utilize some features.";
if ($version) {
$errmsg .= " Installed version is $version";
}
return $code;
}
$errmsg = "requires package `$channel/$name' " .
$this->signOperator($relation) . " $req";
return $code;
}
return false;
}
$errmsg = "relation '$relation' with requirement '$req' is not supported (name=$channel/$name)";
return PEAR_DEPENDENCY_BAD_DEPENDENCY;
}
 
// }}}
// {{{ checkPackageUninstall()
 
/**
* Check package dependencies on uninstall
*
* @param string $error The resultant error string
* @param string $warning The resultant warning string
* @param string $name Name of the package to test
* @param string $channel Channel name of the package
*
* @return bool true if there were errors
*/
function checkPackageUninstall(&$error, &$warning, $package, $channel = 'pear.php.net')
{
$channel = strtolower($channel);
$error = null;
$channels = $this->registry->listAllPackages();
foreach ($channels as $channelname => $packages) {
foreach ($packages as $pkg) {
if ($pkg == $package && $channel == $channelname) {
continue;
}
$deps = $this->registry->packageInfo($pkg, 'release_deps', $channel);
if (empty($deps)) {
continue;
}
foreach ($deps as $dep) {
$depchannel = isset($dep['channel']) ? $dep['channel'] : 'pear.php.net';
if ($dep['type'] == 'pkg' && (strcasecmp($dep['name'], $package) == 0) &&
($depchannel == $channel)) {
if ($dep['rel'] == 'ne') {
continue;
}
if (isset($dep['optional']) && $dep['optional'] == 'yes') {
$warning .= "\nWarning: Package '$depchannel/$pkg' optionally depends on '$channel:/package'";
} else {
$error .= "Package '$depchannel/$pkg' depends on '$channel/$package'\n";
}
}
}
}
}
return ($error) ? true : false;
}
 
// }}}
// {{{ checkExtension()
 
/**
* Extension dependencies check method
*
* @param string $name Name of the extension to test
* @param string $req_ext_ver Required extension version to compare with
* @param string $relation How to compare versions with eachother
* @param bool $opt Whether the relationship is optional
*
* @return mixed bool false if no error or the error string
*/
function checkExtension(&$errmsg, $name, $req = null, $relation = 'has',
$opt = false)
{
if ($relation == 'not') {
if (extension_loaded($name)) {
$errmsg = "conflicts with PHP extension '$name'";
return PEAR_DEPENDENCY_CONFLICT;
} else {
return false;
}
}
 
if (!extension_loaded($name)) {
if ($relation == 'ne') {
return false;
}
if ($opt) {
$errmsg = "'$name' PHP extension is recommended to utilize some features";
return PEAR_DEPENDENCY_MISSING_OPTIONAL;
}
$errmsg = "'$name' PHP extension is not installed";
return PEAR_DEPENDENCY_MISSING;
}
if ($relation == 'has') {
return false;
}
$code = false;
if (is_string($req) && substr($req, 0, 2) == 'v.') {
$req = substr($req, 2);
}
$ext_ver = phpversion($name);
$operator = $relation;
// Force params to be strings, otherwise the comparation will fail (ex. 0.9==0.90)
if (!version_compare("$ext_ver", "$req", $operator)) {
$errmsg = "'$name' PHP extension version " .
$this->signOperator($operator) . " $req is required";
$code = $this->codeFromRelation($relation, $ext_ver, $req, $opt);
if ($opt) {
$errmsg = "'$name' PHP extension version " . $this->signOperator($operator) .
" $req is recommended to utilize some features";
return $code;
}
}
return $code;
}
 
// }}}
// {{{ checkOS()
 
/**
* Operating system dependencies check method
*
* @param string $os Name of the operating system
*
* @return mixed bool false if no error or the error string
*/
function checkOS(&$errmsg, $os)
{
// XXX Fixme: Implement a more flexible way, like
// comma separated values or something similar to PEAR_OS
static $myos;
if (empty($myos)) {
$myos = new OS_Guess();
}
// only 'has' relation is currently supported
if ($myos->matchSignature($os)) {
return false;
}
$errmsg = "'$os' operating system not supported";
return PEAR_DEPENDENCY_CONFLICT;
}
 
// }}}
// {{{ checkPHP()
 
/**
* PHP version check method
*
* @param string $req which version to compare
* @param string $relation how to compare the version
*
* @return mixed bool false if no error or the error string
*/
function checkPHP(&$errmsg, $req, $relation = 'ge')
{
// this would be a bit stupid, but oh well :)
if ($relation == 'has') {
return false;
}
if ($relation == 'not') {
$errmsg = "Invalid dependency - 'not' is allowed when specifying PHP, you must run PHP in PHP";
return PEAR_DEPENDENCY_BAD_DEPENDENCY;
}
if (substr($req, 0, 2) == 'v.') {
$req = substr($req,2, strlen($req) - 2);
}
$php_ver = phpversion();
$operator = $relation;
if (!version_compare("$php_ver", "$req", $operator)) {
$errmsg = "PHP version " . $this->signOperator($operator) .
" $req is required";
return PEAR_DEPENDENCY_CONFLICT;
}
return false;
}
 
// }}}
// {{{ checkProgram()
 
/**
* External program check method. Looks for executable files in
* directories listed in the PATH environment variable.
*
* @param string $program which program to look for
*
* @return mixed bool false if no error or the error string
*/
function checkProgram(&$errmsg, $program)
{
// XXX FIXME honor safe mode
$exe_suffix = OS_WINDOWS ? '.exe' : '';
$path_elements = explode(PATH_SEPARATOR, getenv('PATH'));
foreach ($path_elements as $dir) {
$file = $dir . DIRECTORY_SEPARATOR . $program . $exe_suffix;
if (file_exists($file) && is_executable($file)) {
return false;
}
}
$errmsg = "'$program' program is not present in the PATH";
return PEAR_DEPENDENCY_MISSING;
}
 
// }}}
// {{{ checkSAPI()
 
/**
* SAPI backend check method. Version comparison is not yet
* available here.
*
* @param string $name name of SAPI backend
* @param string $req which version to compare
* @param string $relation how to compare versions (currently
* hardcoded to 'has')
* @return mixed bool false if no error or the error string
*/
function checkSAPI(&$errmsg, $name, $req = null, $relation = 'has')
{
// XXX Fixme: There is no way to know if the user has or
// not other SAPI backends installed than the installer one
 
$sapi_backend = php_sapi_name();
// Version comparisons not supported, sapi backends don't have
// version information yet.
if ($sapi_backend == $name) {
return false;
}
$errmsg = "'$sapi_backend' SAPI backend not supported";
return PEAR_DEPENDENCY_CONFLICT;
}
 
// }}}
// {{{ checkZend()
 
/**
* Zend version check method
*
* @param string $req which version to compare
* @param string $relation how to compare the version
*
* @return mixed bool false if no error or the error string
*/
function checkZend(&$errmsg, $req, $relation = 'ge')
{
if (substr($req, 0, 2) == 'v.') {
$req = substr($req,2, strlen($req) - 2);
}
$zend_ver = zend_version();
$operator = substr($relation,0,2);
if (!version_compare("$zend_ver", "$req", $operator)) {
$errmsg = "Zend version " . $this->signOperator($operator) .
" $req is required";
return PEAR_DEPENDENCY_CONFLICT;
}
return false;
}
 
// }}}
// {{{ signOperator()
 
/**
* Converts text comparing operators to them sign equivalents
*
* Example: 'ge' to '>='
*
* @access public
* @param string Operator
* @return string Sign equivalent
*/
function signOperator($operator)
{
switch($operator) {
case 'lt': return '<';
case 'le': return '<=';
case 'gt': return '>';
case 'ge': return '>=';
case 'eq': return '==';
case 'ne': return '!=';
default:
return $operator;
}
}
 
// }}}
// {{{ codeFromRelation()
 
/**
* Convert relation into corresponding code
*
* @access public
* @param string Relation
* @param string Version
* @param string Requirement
* @param bool Optional dependency indicator
* @return integer
*/
function codeFromRelation($relation, $version, $req, $opt = false)
{
$code = PEAR_DEPENDENCY_BAD_DEPENDENCY;
switch ($relation) {
case 'gt': case 'ge': case 'eq':
// upgrade
$have_major = preg_replace('/\D.*/', '', $version);
$need_major = preg_replace('/\D.*/', '', $req);
if ($need_major > $have_major) {
$code = $opt ? PEAR_DEPENDENCY_UPGRADE_MAJOR_OPTIONAL :
PEAR_DEPENDENCY_UPGRADE_MAJOR;
} else {
$code = $opt ? PEAR_DEPENDENCY_UPGRADE_MINOR_OPTIONAL :
PEAR_DEPENDENCY_UPGRADE_MINOR;
}
break;
case 'lt': case 'le': case 'ne':
$code = $opt ? PEAR_DEPENDENCY_CONFLICT_OPTIONAL :
PEAR_DEPENDENCY_CONFLICT;
break;
}
return $code;
}
 
// }}}
}
?>
/trunk/bibliotheque/pear/PEAR/ErrorStack.php
21,8 → 21,9
* @category Debugging
* @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
* @copyright 2004-2006 Greg Beaver
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: ErrorStack.php,v 1.26 2006/10/31 02:54:40 cellog Exp $
* @link http://pear.php.net/package/PEAR_ErrorStack
*/
 
131,11 → 132,12
* $local_stack = new PEAR_ErrorStack('MyPackage');
* </code>
* @author Greg Beaver <cellog@php.net>
* @version 1.10.1
* @version 1.5.1
* @package PEAR_ErrorStack
* @category Debugging
* @copyright 2004-2008 Greg Beaver
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @copyright 2004-2006 Greg Beaver
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: ErrorStack.php,v 1.26 2006/10/31 02:54:40 cellog Exp $
* @link http://pear.php.net/package/PEAR_ErrorStack
*/
class PEAR_ErrorStack {
192,12 → 194,12
* @access protected
*/
var $_contextCallback = false;
 
/**
* If set to a valid callback, this will be called every time an error
* is pushed onto the stack. The return value will be used to determine
* whether to allow an error to be pushed or logged.
*
*
* The return value must be one an PEAR_ERRORSTACK_* constant
* @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG
* @var false|string|array
204,7 → 206,7
* @access protected
*/
var $_errorCallback = array();
 
/**
* PEAR::Log object for logging errors
* @var false|Log
211,7 → 213,7
* @access protected
*/
var $_logger = false;
 
/**
* Error messages - designed to be overridden
* @var array
218,10 → 220,10
* @abstract
*/
var $_errorMsgs = array();
 
/**
* Set up a new error stack
*
*
* @param string $package name of the package this error stack represents
* @param callback $msgCallback callback used for error message generation
* @param callback $contextCallback callback used for context generation,
228,7 → 230,7
* defaults to {@link getFileLine()}
* @param boolean $throwPEAR_Error
*/
function __construct($package, $msgCallback = false, $contextCallback = false,
function PEAR_ErrorStack($package, $msgCallback = false, $contextCallback = false,
$throwPEAR_Error = false)
{
$this->_package = $package;
248,13 → 250,12
* defaults to {@link getFileLine()}
* @param boolean $throwPEAR_Error
* @param string $stackClass class to instantiate
*
* @static
* @return PEAR_ErrorStack
*/
public static function &singleton(
$package, $msgCallback = false, $contextCallback = false,
$throwPEAR_Error = false, $stackClass = 'PEAR_ErrorStack'
) {
function &singleton($package, $msgCallback = false, $contextCallback = false,
$throwPEAR_Error = false, $stackClass = 'PEAR_ErrorStack')
{
if (isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {
return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package];
}
296,14 → 297,15
/**
* Set up a PEAR::Log object for all error stacks that don't have one
* @param Log $log
* @static
*/
public static function setDefaultLogger(&$log)
function setDefaultLogger(&$log)
{
if (is_object($log) && method_exists($log, 'log') ) {
$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log;
} elseif (is_callable($log)) {
$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log;
}
}
}
/**
356,8 → 358,9
* messages for a singleton
* @param array|string Callback function/method
* @param string Package name, or false for all packages
* @static
*/
public static function setDefaultCallback($callback = false, $package = false)
function setDefaultCallback($callback = false, $package = false)
{
if (!is_callable($callback)) {
$callback = false;
429,8 → 432,9
* @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG
* @see staticPopCallback(), pushCallback()
* @param string|array $cb
* @static
*/
public static function staticPushCallback($cb)
function staticPushCallback($cb)
{
array_push($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'], $cb);
}
439,8 → 443,9
* Remove a temporary overriding error callback
* @see staticPushCallback()
* @return array|string|false
* @static
*/
public static function staticPopCallback()
function staticPopCallback()
{
$ret = array_pop($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK']);
if (!is_array($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'])) {
599,11 → 604,11
* to find error context
* @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also
* thrown. see docs for {@link push()}
* @static
*/
public static function staticPush(
$package, $code, $level = 'error', $params = array(),
$msg = false, $repackage = false, $backtrace = false
) {
function staticPush($package, $code, $level = 'error', $params = array(),
$msg = false, $repackage = false, $backtrace = false)
{
$s = &PEAR_ErrorStack::singleton($package);
if ($s->_contextCallback) {
if (!$backtrace) {
745,8 → 750,9
* @param string|false Package name to check for errors
* @param string Level name to check for a particular severity
* @return boolean
* @static
*/
public static function staticHasErrors($package = false, $level = false)
function staticHasErrors($package = false, $level = false)
{
if ($package) {
if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) {
770,13 → 776,12
* @param boolean $merge Set to return a flat array, not organized by package
* @param array $sortfunc Function used to sort a merged array - default
* sorts by time, and should be good for most cases
*
* @static
* @return array
*/
public static function staticGetErrors(
$purge = false, $level = false, $merge = false,
$sortfunc = array('PEAR_ErrorStack', '_sortErrors')
) {
function staticGetErrors($purge = false, $level = false, $merge = false,
$sortfunc = array('PEAR_ErrorStack', '_sortErrors'))
{
$ret = array();
if (!is_callable($sortfunc)) {
$sortfunc = array('PEAR_ErrorStack', '_sortErrors');
801,7 → 806,7
* Error sorting function, sorts by time
* @access private
*/
public static function _sortErrors($a, $b)
function _sortErrors($a, $b)
{
if ($a['time'] == $b['time']) {
return 0;
824,8 → 829,9
* @param unused
* @param integer backtrace frame.
* @param array Results of debug_backtrace()
* @static
*/
public static function getFileLine($code, $params, $backtrace = null)
function getFileLine($code, $params, $backtrace = null)
{
if ($backtrace === null) {
return false;
851,7 → 857,7
'line' => $filebacktrace['line']);
// rearrange for eval'd code or create function errors
if (strpos($filebacktrace['file'], '(') &&
preg_match(';^(.*?)\((\d+)\) : (.*?)\\z;', $filebacktrace['file'],
preg_match(';^(.*?)\((\d+)\) : (.*?)$;', $filebacktrace['file'],
$matches)) {
$ret['file'] = $matches[1];
$ret['line'] = $matches[2] + 0;
897,10 → 903,10
* @param PEAR_ErrorStack
* @param array
* @param string|false Pre-generated error message template
*
* @static
* @return string
*/
public static function getErrorMessage(&$stack, $err, $template = false)
function getErrorMessage(&$stack, $err, $template = false)
{
if ($template) {
$mainmsg = $template;
/trunk/bibliotheque/pear/PEAR/ChannelFile/Parser.php
4,11 → 4,18
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Parser.php,v 1.4 2006/01/06 04:47:36 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
23,9 → 30,9
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
51,13 → 58,11
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();
64,4 → 69,5
$ret->setPackagefile($file, $archive);
return $ret;
}
}
}
?>
/trunk/bibliotheque/pear/PEAR/DependencyDB.php
4,12 → 4,19
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @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
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: DependencyDB.php,v 1.35 2007/01/06 04:03:32 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 1.4.0a1
*/
27,9 → 34,9
* @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.10.1
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 1.4.0a1
*/
88,21 → 95,22
* @param PEAR_Config
* @param string|false full path to the dependency database, or false to use default
* @return PEAR_DependencyDB|PEAR_Error
* @static
*/
public static function &singleton(&$config, $depdb = false)
function &singleton(&$config, $depdb = false)
{
$phpdir = $config->get('php_dir', null, 'pear.php.net');
if (!isset($GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'][$phpdir])) {
if (!isset($GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE']
[$config->get('php_dir', null, 'pear.php.net')])) {
$a = new PEAR_DependencyDB;
$GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'][$phpdir] = &$a;
$GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE']
[$config->get('php_dir', null, 'pear.php.net')] = &$a;
$a->setConfig($config, $depdb);
$e = $a->assertDepsDB();
if (PEAR::isError($e)) {
if (PEAR::isError($e = $a->assertDepsDB())) {
return $e;
}
}
 
return $GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'][$phpdir];
return $GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE']
[$config->get('php_dir', null, 'pear.php.net')];
}
 
/**
117,18 → 125,13
} else {
$this->_config = &$config;
}
 
$this->_registry = &$this->_config->getRegistry();
if (!$depdb) {
$dir = $this->_config->get('metadata_dir', null, 'pear.php.net');
if (!$dir) {
$dir = $this->_config->get('php_dir', null, 'pear.php.net');
}
$this->_depdb = $dir . DIRECTORY_SEPARATOR . '.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';
}
// }}}
142,15 → 145,13
if ($dir != '.' && file_exists($dir)) {
if (is_writeable($dir)) {
return true;
} else {
return false;
}
 
return false;
}
}
 
return false;
}
 
return is_writeable($this->_depdb);
}
 
165,20 → 166,18
{
if (!is_file($this->_depdb)) {
$this->rebuildDB();
return;
} else {
$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');
}
}
 
$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');
}
}
 
/**
196,11 → 195,9
$channel = strtolower($pkg['channel']);
$package = strtolower($pkg['package']);
}
 
if (isset($data['packages'][$channel][$package])) {
return $data['packages'][$channel][$package];
}
 
return false;
}
 
220,25 → 217,19
$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 (strtolower($dep['dep']['channel']) == strtolower($channel) &&
strtolower($dep['dep']['name']) == strtolower($package)) {
if (!isset($dependencies[$info['channel']])) {
$dependencies[$info['channel']] = array();
}
 
if (!isset($dependencies[$info['channel']][$info['package']])) {
$dependencies[$info['channel']][$info['package']] = array();
}
246,7 → 237,6
}
}
}
 
return $dependencies;
}
 
264,12 → 254,10
$channel = strtolower($pkg['channel']);
$package = strtolower($pkg['package']);
}
 
$data = $this->_getDepDB();
if (isset($data['dependencies'][$channel][$package])) {
return $data['dependencies'][$channel][$package];
}
 
return false;
}
 
284,7 → 272,7
$this->_getDepDB();
return $this->_dependsOn($parent, $child, $c);
}
 
function _dependsOn($parent, $child, &$checked)
{
if (is_object($parent)) {
294,7 → 282,6
$channel = strtolower($parent['channel']);
$package = strtolower($parent['package']);
}
 
if (is_object($child)) {
$depchannel = strtolower($child->getChannel());
$deppackage = strtolower($child->getPackage());
302,16 → 289,13
$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)) {
325,13 → 309,11
}
return false;
}
 
if (strtolower($info['dep']['channel']) == $depchannel &&
strtolower($info['dep']['name']) == $deppackage) {
if (strtolower($info['dep']['channel']) == strtolower($depchannel) &&
strtolower($info['dep']['name']) == strtolower($deppackage)) {
return true;
}
}
 
foreach ($this->_cache['dependencies'][$channel][$package] as $info) {
if (isset($info['dep']['uri'])) {
if ($this->_dependsOn(array(
347,7 → 329,6
}
}
}
 
return false;
}
 
381,51 → 362,50
$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 = false;
if (isset($dep['dep']['uri'])) {
$depchannel = '__uri';
} else {
$depchannel = strtolower($dep['dep']['channel']);
}
if (isset($data['packages'][$depchannel][strtolower($dep['dep']['name'])])) {
foreach ($data['packages'][$depchannel][strtolower($dep['dep']['name'])] 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]);
unset($data['packages'][$depchannel][strtolower($dep['dep']['name'])][$i]);
if (!count($data['packages'][$depchannel][strtolower($dep['dep']['name'])])) {
unset($data['packages'][$depchannel][strtolower($dep['dep']['name'])]);
if (!count($data['packages'][$depchannel])) {
unset($data['packages'][$depchannel]);
}
} else {
$data['packages'][$depchannel][$depname] =
array_values($data['packages'][$depchannel][$depname]);
$data['packages'][$depchannel][strtolower($dep['dep']['name'])] =
array_values(
$data['packages'][$depchannel][strtolower($dep['dep']['name'])]);
}
}
}
 
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);
}
 
440,27 → 420,17
// 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;
}
473,47 → 443,40
*/
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');
if (!eregi('Windows 9', php_uname())) {
if ($mode != LOCK_UN && is_resource($this->_lockFp)) {
// XXX does not check type of lock (LOCK_SH/LOCK_EX)
return true;
}
$open_mode = 'r';
}
$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;
if (!is_resource($this->_lockFp)) {
$this->_lockFp = @fopen($this->_lockfile, $open_mode);
}
 
return PEAR::raiseError("could not acquire $str lock ($this->_lockfile)");
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;
}
 
541,19 → 504,19
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;
}
569,13 → 532,14
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;
598,89 → 562,70
} 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();
if (!isset($data['dependencies'][strtolower($pkg->getChannel())])) {
$data['dependencies'][strtolower($pkg->getChannel())] = array();
}
 
$data['dependencies'][$channel][$package] = array();
$data['dependencies'][strtolower($pkg->getChannel())][strtolower($pkg->getPackage())]
= 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']);
688,11 → 633,12
}
}
}
 
if ($data['dependencies'][$channel][$package] == array()) {
unset($data['dependencies'][$channel][$package]);
if (!count($data['dependencies'][$channel])) {
unset($data['dependencies'][$channel]);
if ($data['dependencies'][strtolower($pkg->getChannel())]
[strtolower($pkg->getPackage())] == array()) {
unset($data['dependencies'][strtolower($pkg->getChannel())]
[strtolower($pkg->getPackage())]);
if (!count($data['dependencies'][strtolower($pkg->getChannel())])) {
unset($data['dependencies'][strtolower($pkg->getChannel())]);
}
}
}
707,58 → 653,55
function _registerDep(&$data, &$pkg, $dep, $type, $group = false)
{
$info = array(
'dep' => $dep,
'type' => $type,
'group' => $group
);
'dep' => $dep,
'type' => $type,
'group' => $group);
 
$dep = array_map('strtolower', $dep);
$depchannel = isset($dep['channel']) ? $dep['channel'] : '__uri';
if (isset($dep['channel'])) {
$depchannel = $dep['channel'];
} else {
$depchannel = '__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'][strtolower($pkg->getChannel())])) {
$data['dependencies'][strtolower($pkg->getChannel())] = array();
}
 
if (!isset($data['dependencies'][$channel][$package])) {
$data['dependencies'][$channel][$package] = array();
if (!isset($data['dependencies'][strtolower($pkg->getChannel())][strtolower($pkg->getPackage())])) {
$data['dependencies'][strtolower($pkg->getChannel())][strtolower($pkg->getPackage())] = array();
}
 
$data['dependencies'][$channel][$package][] = $info;
if (isset($data['packages'][$depchannel][$dep['name']])) {
$data['dependencies'][strtolower($pkg->getChannel())][strtolower($pkg->getPackage())][]
= $info;
if (isset($data['packages'][strtolower($depchannel)][strtolower($dep['name'])])) {
$found = false;
foreach ($data['packages'][$depchannel][$dep['name']] as $i => $p) {
if ($p['channel'] == $channel && $p['package'] == $package) {
foreach ($data['packages'][strtolower($depchannel)][strtolower($dep['name'])]
as $i => $p) {
if ($p['channel'] == strtolower($pkg->getChannel()) &&
$p['package'] == strtolower($pkg->getPackage())) {
$found = true;
break;
}
}
if (!$found) {
$data['packages'][strtolower($depchannel)][strtolower($dep['name'])][]
= array('channel' => strtolower($pkg->getChannel()),
'package' => strtolower($pkg->getPackage()));
}
} else {
if (!isset($data['packages'])) {
$data['packages'] = array();
}
 
if (!isset($data['packages'][$depchannel])) {
$data['packages'][$depchannel] = array();
if (!isset($data['packages'][strtolower($depchannel)])) {
$data['packages'][strtolower($depchannel)] = array();
}
 
if (!isset($data['packages'][$depchannel][$dep['name']])) {
$data['packages'][$depchannel][$dep['name']] = array();
if (!isset($data['packages'][strtolower($depchannel)][strtolower($dep['name'])])) {
$data['packages'][strtolower($depchannel)][strtolower($dep['name'])] = array();
}
 
$found = false;
$data['packages'][strtolower($depchannel)][strtolower($dep['name'])][]
= array('channel' => strtolower($pkg->getChannel()),
'package' => strtolower($pkg->getPackage()));
}
 
if (!$found) {
$data['packages'][$depchannel][$dep['name']][] = array(
'channel' => $channel,
'package' => $package
);
}
}
}
?>
/trunk/bibliotheque/pear/DB.php
5,7 → 5,7
/**
* Database independent query interface
*
* PHP version 5
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
18,9 → 18,9
* @author Stig Bakken <ssb@php.net>
* @author Tomas V.V.Cox <cox@idecnet.com>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2007 The PHP Group
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id$
* @version CVS: $Id: DB.php,v 1.80 2005/02/16 02:16:00 danielc Exp $
* @link http://pear.php.net/package/DB
*/
 
424,14 → 424,14
* @author Stig Bakken <ssb@php.net>
* @author Tomas V.V.Cox <cox@idecnet.com>
* @author Daniel Convissor <danielc@php.net>
* @copyright 1997-2007 The PHP Group
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.9.2
* @version Release: 1.7.6
* @link http://pear.php.net/package/DB
*/
class DB
{
// {{{ factory()
// {{{ &factory()
 
/**
* Create a new DB object for the specified database type but don't
444,7 → 444,7
*
* @see DB_common::setOption()
*/
public static function factory($type, $options = false)
function &factory($type, $options = false)
{
if (!is_array($options)) {
$options = array('persistent' => $options);
467,7 → 467,7
return $tmp;
}
 
@$obj = new $classname;
@$obj =& new $classname;
 
foreach ($options as $option => $value) {
$test = $obj->setOption($option, $value);
480,7 → 480,7
}
 
// }}}
// {{{ connect()
// {{{ &connect()
 
/**
* Create a new DB object including a connection to the specified database
495,7 → 495,7
* 'portability' => DB_PORTABILITY_ALL,
* );
*
* $db = DB::connect($dsn, $options);
* $db =& DB::connect($dsn, $options);
* if (PEAR::isError($db)) {
* die($db->getMessage());
* }
515,7 → 515,7
*
* @uses DB::parseDSN(), DB_common::setOption(), PEAR::isError()
*/
public static function connect($dsn, $options = array())
function &connect($dsn, $options = array())
{
$dsninfo = DB::parseDSN($dsn);
$type = $dsninfo['phptype'];
539,13 → 539,12
if (!class_exists($classname)) {
$tmp = PEAR::raiseError(null, DB_ERROR_NOT_FOUND, null, null,
"Unable to include the DB/{$type}.php"
. " file for '"
. DB::getDSNString($dsn, true) . "'",
. " file for '$dsn'",
'DB_Error', true);
return $tmp;
}
 
@$obj = new $classname;
@$obj =& new $classname;
 
foreach ($options as $option => $value) {
$test = $obj->setOption($option, $value);
556,11 → 555,7
 
$err = $obj->connect($dsninfo, $obj->getOption('persistent'));
if (DB::isError($err)) {
if (is_array($dsn)) {
$err->addUserInfo(DB::getDSNString($dsn, true));
} else {
$err->addUserInfo($dsn);
}
$err->addUserInfo($dsn);
return $err;
}
 
577,7 → 572,7
*/
function apiVersion()
{
return '1.9.2';
return '1.7.6';
}
 
// }}}
590,9 → 585,9
*
* @return bool whether $value is DB_Error object
*/
public static function isError($value)
function isError($value)
{
return is_object($value) && is_a($value, 'DB_Error');
return is_a($value, 'DB_Error');
}
 
// }}}
605,7 → 600,7
*
* @return bool whether $value is a DB_<driver> object
*/
public static function isConnection($value)
function isConnection($value)
{
return (is_object($value) &&
is_subclass_of($value, 'db_common') &&
626,11 → 621,11
*
* @return boolean whether $query is a data manipulation query
*/
public static function isManip($query)
function isManip($query)
{
$manips = 'INSERT|UPDATE|DELETE|REPLACE|'
. 'CREATE|DROP|'
. 'LOAD DATA|SELECT .* INTO .* FROM|COPY|'
. 'LOAD DATA|SELECT .* INTO|COPY|'
. 'ALTER|GRANT|REVOKE|'
. 'LOCK|UNLOCK';
if (preg_match('/^\s*"?(' . $manips . ')\s+/i', $query)) {
650,7 → 645,7
* @return string the error message or false if the error code was
* not recognized
*/
public static function errorMessage($value)
function errorMessage($value)
{
static $errorMessages;
if (!isset($errorMessages)) {
731,7 → 726,7
* + username: User name for login
* + password: Password for login
*/
public static function parseDSN($dsn)
function parseDSN($dsn)
{
$parsed = array(
'phptype' => false,
813,11 → 808,13
// process the different protocol options
$parsed['protocol'] = (!empty($proto)) ? $proto : 'tcp';
$proto_opts = rawurldecode($proto_opts);
if (strpos($proto_opts, ':') !== false) {
list($proto_opts, $parsed['port']) = explode(':', $proto_opts);
}
if ($parsed['protocol'] == 'tcp') {
$parsed['hostspec'] = $proto_opts;
if (strpos($proto_opts, ':') !== false) {
list($parsed['hostspec'],
$parsed['port']) = explode(':', $proto_opts);
} else {
$parsed['hostspec'] = $proto_opts;
}
} elseif ($parsed['protocol'] == 'unix') {
$parsed['socket'] = $proto_opts;
}
851,82 → 848,6
}
 
// }}}
// {{{ getDSNString()
 
/**
* Returns the given DSN in a string format suitable for output.
*
* @param array|string the DSN to parse and format
* @param boolean true to hide the password, false to include it
* @return string
*/
public static function getDSNString($dsn, $hidePassword) {
/* Calling parseDSN will ensure that we have all the array elements
* defined, and means that we deal with strings and array in the same
* manner. */
$dsnArray = DB::parseDSN($dsn);
if ($hidePassword) {
$dsnArray['password'] = 'PASSWORD';
}
 
/* Protocol is special-cased, as using the default "tcp" along with an
* Oracle TNS connection string fails. */
if (is_string($dsn) && strpos($dsn, 'tcp') === false && $dsnArray['protocol'] == 'tcp') {
$dsnArray['protocol'] = false;
}
// Now we just have to construct the actual string. This is ugly.
$dsnString = $dsnArray['phptype'];
if ($dsnArray['dbsyntax']) {
$dsnString .= '('.$dsnArray['dbsyntax'].')';
}
$dsnString .= '://'
.$dsnArray['username']
.':'
.$dsnArray['password']
.'@'
.$dsnArray['protocol'];
if ($dsnArray['socket']) {
$dsnString .= '('.$dsnArray['socket'].')';
}
if ($dsnArray['protocol'] && $dsnArray['hostspec']) {
$dsnString .= '+';
}
$dsnString .= $dsnArray['hostspec'];
if ($dsnArray['port']) {
$dsnString .= ':'.$dsnArray['port'];
}
$dsnString .= '/'.$dsnArray['database'];
/* Option handling. Unfortunately, parseDSN simply places options into
* the top-level array, so we'll first get rid of the fields defined by
* DB and see what's left. */
unset($dsnArray['phptype'],
$dsnArray['dbsyntax'],
$dsnArray['username'],
$dsnArray['password'],
$dsnArray['protocol'],
$dsnArray['socket'],
$dsnArray['hostspec'],
$dsnArray['port'],
$dsnArray['database']
);
if (count($dsnArray) > 0) {
$dsnString .= '?';
$i = 0;
foreach ($dsnArray as $key => $value) {
if (++$i > 1) {
$dsnString .= '&';
}
$dsnString .= $key.'='.$value;
}
}
 
return $dsnString;
}
// }}}
}
 
// }}}
939,9 → 860,9
* @category Database
* @package DB
* @author Stig Bakken <ssb@php.net>
* @copyright 1997-2007 The PHP Group
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.9.2
* @version Release: 1.7.6
* @link http://pear.php.net/package/DB
*/
class DB_Error extends PEAR_Error
959,32 → 880,18
*
* @see PEAR_Error
*/
function __construct($code = DB_ERROR, $mode = PEAR_ERROR_RETURN,
function DB_Error($code = DB_ERROR, $mode = PEAR_ERROR_RETURN,
$level = E_USER_NOTICE, $debuginfo = null)
{
if (is_int($code)) {
parent::__construct('DB Error: ' . DB::errorMessage($code), $code,
$this->PEAR_Error('DB Error: ' . DB::errorMessage($code), $code,
$mode, $level, $debuginfo);
} else {
parent::__construct("DB Error: $code", DB_ERROR,
$this->PEAR_Error("DB Error: $code", DB_ERROR,
$mode, $level, $debuginfo);
}
}
 
/**
* Workaround to both avoid the "Redefining already defined constructor"
* PHP error and provide backward compatibility in case someone is calling
* DB_Error() dynamically
*/
public function __call($method, $arguments)
{
if ($method == 'DB_Error') {
return call_user_func_array(array($this, '__construct'), $arguments);
}
trigger_error(
'Call to undefined method DB_Error::' . $method . '()', E_USER_ERROR
);
}
// }}}
}
 
1000,9 → 907,9
* @category Database
* @package DB
* @author Stig Bakken <ssb@php.net>
* @copyright 1997-2007 The PHP Group
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.9.2
* @version Release: 1.7.6
* @link http://pear.php.net/package/DB
*/
class DB_result
1109,7 → 1016,7
*
* @return void
*/
function __construct(&$dbh, $result, $options = array())
function DB_result(&$dbh, $result, $options = array())
{
$this->autofree = $dbh->options['autofree'];
$this->dbh = &$dbh;
1182,7 → 1089,7
$fetchmode = DB_FETCHMODE_ASSOC;
$object_class = $this->fetchmode_object_class;
}
if (is_null($rownum) && $this->limit_from !== null) {
if ($this->limit_from !== null) {
if ($this->row_counter === null) {
$this->row_counter = $this->limit_from;
// Skip rows
1214,7 → 1121,7
if ($object_class == 'stdClass') {
$arr = (object) $arr;
} else {
$arr = new $object_class($arr);
$arr = &new $object_class($arr);
}
}
return $arr;
1264,7 → 1171,7
$fetchmode = DB_FETCHMODE_ASSOC;
$object_class = $this->fetchmode_object_class;
}
if (is_null($rownum) && $this->limit_from !== null) {
if ($this->limit_from !== null) {
if ($this->row_counter === null) {
$this->row_counter = $this->limit_from;
// Skip rows
1346,33 → 1253,10
while ($res->fetchInto($tmp, DB_FETCHMODE_ORDERED)) {
$i++;
}
$count = $i;
return $i;
} else {
$count = $this->dbh->numRows($this->result);
return $this->dbh->numRows($this->result);
}
 
/* fbsql is checked for here because limit queries are implemented
* using a TOP() function, which results in fbsql_num_rows still
* returning the total number of rows that would have been returned,
* rather than the real number. As a result, we'll just do the limit
* calculations for fbsql in the same way as a database with emulated
* limits. Unfortunately, we can't just do this in DB_fbsql::numRows()
* because that only gets the result resource, rather than the full
* DB_Result object. */
if (($this->dbh->features['limit'] === 'emulate'
&& $this->limit_from !== null)
|| $this->dbh->phptype == 'fbsql') {
$limit_count = is_null($this->limit_count) ? $count : $this->limit_count;
if ($count < $this->limit_from) {
$count = 0;
} elseif ($count < ($this->limit_from + $limit_count)) {
$count -= $this->limit_from;
} else {
$count = $limit_count;
}
}
 
return $count;
}
 
// }}}
1465,9 → 1349,9
* @category Database
* @package DB
* @author Stig Bakken <ssb@php.net>
* @copyright 1997-2007 The PHP Group
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.9.2
* @version Release: 1.7.6
* @link http://pear.php.net/package/DB
* @see DB_common::setFetchMode()
*/
1482,7 → 1366,7
*
* @return void
*/
function __construct(&$arr)
function DB_row(&$arr)
{
foreach ($arr as $key => $value) {
$this->$key = &$arr[$key];
/trunk/bibliotheque/pear/PEAR.php
6,6 → 6,12
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* 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 web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Sterling Hughes <sterling@php.net>
12,8 → 18,9
* @author Stig Bakken <ssb@php.net>
* @author Tomas V.V.Cox <cox@idecnet.com>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2010 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: PEAR.php,v 1.101 2006/04/25 02:41:03 cellog Exp $
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
32,6 → 39,8
*/
define('PEAR_ERROR_EXCEPTION', 32);
/**#@-*/
define('PEAR_ZE2', (function_exists('version_compare') &&
version_compare(zend_version(), "2-dev", "ge")));
 
if (substr(PHP_OS, 0, 3) == 'WIN') {
define('OS_WINDOWS', true);
43,6 → 52,15
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_options'] = E_USER_NOTICE;
$GLOBALS['_PEAR_destructor_object_list'] = array();
74,8 → 92,8
* @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.10.1
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @link http://pear.php.net/package/PEAR
* @see PEAR_Error
* @since Class available since PHP 4.0.2
83,6 → 101,8
*/
class PEAR
{
// {{{ properties
 
/**
* Whether to enable internal debug messages.
*
133,18 → 153,10
*/
var $_expected_errors = array();
 
/**
* List of methods that can be called both statically and non-statically.
* @var array
*/
protected static $bivalentMethods = array(
'setErrorHandling' => true,
'raiseError' => true,
'throwError' => true,
'pushErrorHandling' => true,
'popErrorHandling' => true,
);
// }}}
 
// {{{ constructor
 
/**
* Constructor. Registers this object in
* $_PEAR_destructor_object_list for destructor emulation if a
155,17 → 167,15
* @access public
* @return void
*/
function __construct($error_class = null)
function PEAR($error_class = null)
{
$classname = strtolower(get_class($this));
if ($this->_debug) {
print "PEAR constructor called, class=$classname\n";
}
 
if ($error_class !== null) {
$this->_error_class = $error_class;
}
 
while ($classname && strcasecmp($classname, "pear")) {
$destructor = "_$classname";
if (method_exists($this, $destructor)) {
182,17 → 192,8
}
}
 
/**
* Only here for backwards compatibility.
* E.g. Archive_Tar calls $this->PEAR() in its constructor.
*
* @param string $error_class Which class to use for error objects,
* defaults to PEAR_Error.
*/
public function PEAR($error_class = null)
{
self::__construct($error_class);
}
// }}}
// {{{ destructor
 
/**
* Destructor (the emulated type of...). Does nothing right now,
211,32 → 212,9
}
}
 
public function __call($method, $arguments)
{
if (!isset(self::$bivalentMethods[$method])) {
trigger_error(
'Call to undefined method PEAR::' . $method . '()', E_USER_ERROR
);
}
return call_user_func_array(
array(get_class(), '_' . $method),
array_merge(array($this), $arguments)
);
}
// }}}
// {{{ getStaticProperty()
 
public static function __callStatic($method, $arguments)
{
if (!isset(self::$bivalentMethods[$method])) {
trigger_error(
'Call to undefined method PEAR::' . $method . '()', E_USER_ERROR
);
}
return call_user_func_array(
array(get_class(), '_' . $method),
array_merge(array(null), $arguments)
);
}
 
/**
* 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)
243,35 → 221,37
* do this: $myVar = &PEAR::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.
*/
public static function &getStaticProperty($class, $var)
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];
}
 
// }}}
// {{{ registerShutdownFunc()
 
/**
* Use this function to register a shutdown method for static
* classes.
*
* @access public
* @param mixed $func The function name (or array of class/method) to call
* @param mixed $args The arguments to pass to the function
*
* @return void
*/
public static 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
282,6 → 262,9
$GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args);
}
 
// }}}
// {{{ isError()
 
/**
* Tell whether a value is a PEAR error.
*
290,24 → 273,26
* only if $code is a string and
* $obj->getMessage() == $code or
* $code is an integer and $obj->getCode() == $code
*
* @access public
* @return bool true if parameter is an error
*/
public static function isError($data, $code = null)
function isError($data, $code = null)
{
if (!is_a($data, 'PEAR_Error')) {
return false;
if (is_a($data, 'PEAR_Error')) {
if (is_null($code)) {
return true;
} elseif (is_string($code)) {
return $data->getMessage() == $code;
} else {
return $data->getCode() == $code;
}
}
return false;
}
 
if (is_null($code)) {
return true;
} elseif (is_string($code)) {
return $data->getMessage() == $code;
}
// }}}
// {{{ setErrorHandling()
 
return $data->getCode() == $code;
}
 
/**
* Sets how errors generated by this object should be handled.
* Can be invoked both in objects and statically. If called
315,9 → 300,6
* PEAR objects. If called in an object, setErrorHandling sets
* the default behaviour for that object.
*
* @param object $object
* Object the method was called on (non-static mode)
*
* @param int $mode
* One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT,
* PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE,
349,12 → 331,12
*
* @since PHP 4.0.5
*/
protected static function _setErrorHandling(
$object, $mode = null, $options = null
) {
if ($object !== null) {
$setmode = &$object->_default_error_mode;
$setoptions = &$object->_default_error_options;
 
function setErrorHandling($mode = null, $options = null)
{
if (isset($this) && is_a($this, 'PEAR')) {
$setmode = &$this->_default_error_mode;
$setoptions = &$this->_default_error_options;
} else {
$setmode = &$GLOBALS['_PEAR_default_error_mode'];
$setoptions = &$GLOBALS['_PEAR_default_error_options'];
387,6 → 369,9
}
}
 
// }}}
// {{{ expectError()
 
/**
* This method is used to tell which errors you expect to get.
* Expected errors are always returned with error mode
409,9 → 394,12
} else {
array_push($this->_expected_errors, array($code));
}
return count($this->_expected_errors);
return sizeof($this->_expected_errors);
}
 
// }}}
// {{{ popExpect()
 
/**
* This method pops one element off the expected error codes
* stack.
423,6 → 411,9
return array_pop($this->_expected_errors);
}
 
// }}}
// {{{ _checkDelExpect()
 
/**
* This method checks unsets an error code if available
*
434,7 → 425,8
function _checkDelExpect($error_code)
{
$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)) {
unset($this->_expected_errors[$key][array_search($error_code, $error_array)]);
$deleted = true;
445,10 → 437,12
unset($this->_expected_errors[$key]);
}
}
 
return $deleted;
}
 
// }}}
// {{{ delExpect()
 
/**
* This method deletes all occurences of the specified element from
* the expected error codes stack.
461,27 → 455,35
function delExpect($error_code)
{
$deleted = false;
 
if ((is_array($error_code) && (0 != count($error_code)))) {
// $error_code is a non-empty array here; we walk through it trying
// to unset all values
foreach ($error_code as $key => $error) {
$deleted = $this->_checkDelExpect($error) ? true : false;
// $error_code is a non-empty array here;
// we walk through it trying to unset all
// values
foreach($error_code as $key => $error) {
if ($this->_checkDelExpect($error)) {
$deleted = true;
} else {
$deleted = false;
}
}
 
return $deleted ? true : PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME
} elseif (!empty($error_code)) {
// $error_code comes alone, trying to unset it
if ($this->_checkDelExpect($error_code)) {
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
return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME
}
 
// $error_code is empty
return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME
}
 
// }}}
// {{{ raiseError()
 
/**
* This method is a wrapper that returns an instance of the
* configured error class with this object's default error
514,12 → 516,12
* @param bool $skipmsg If true, raiseError will only pass error codes,
* the error message parameter will be dropped.
*
* @access public
* @return object a PEAR error object
* @see PEAR::setErrorHandling
* @since PHP 4.0.5
*/
protected static function _raiseError($object,
$message = null,
function &raiseError($message = null,
$code = null,
$mode = null,
$options = null,
536,26 → 538,19
$message = $message->getMessage();
}
 
if (
$object !== null &&
isset($object->_expected_errors) &&
count($object->_expected_errors) > 0 &&
count($exp = end($object->_expected_errors))
) {
if (isset($this) && isset($this->_expected_errors) && sizeof($this->_expected_errors) > 0 && sizeof($exp = end($this->_expected_errors))) {
if ($exp[0] == "*" ||
(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;
}
}
 
// No mode given, try global ones
if ($mode === null) {
// Class error handler
if ($object !== null && isset($object->_default_error_mode)) {
$mode = $object->_default_error_mode;
$options = $object->_default_error_options;
if (isset($this) && isset($this->_default_error_mode)) {
$mode = $this->_default_error_mode;
$options = $this->_default_error_options;
// Global error handler
} elseif (isset($GLOBALS['_PEAR_default_error_mode'])) {
$mode = $GLOBALS['_PEAR_default_error_mode'];
565,50 → 560,47
 
if ($error_class !== null) {
$ec = $error_class;
} elseif ($object !== null && isset($object->_error_class)) {
$ec = $object->_error_class;
} elseif (isset($this) && isset($this->_error_class)) {
$ec = $this->_error_class;
} else {
$ec = 'PEAR_Error';
}
 
if ($skipmsg) {
$a = new $ec($code, $mode, $options, $userinfo);
$a = &new $ec($code, $mode, $options, $userinfo);
return $a;
} else {
$a = new $ec($message, $code, $mode, $options, $userinfo);
$a = &new $ec($message, $code, $mode, $options, $userinfo);
return $a;
}
 
return $a;
}
 
// }}}
// {{{ throwError()
 
/**
* Simpler form of raiseError with fewer options. In most cases
* message, code and userinfo are enough.
*
* @param mixed $message a text error message or a PEAR error object
* @param string $message
*
* @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.
*
* @return object a PEAR error object
* @see PEAR::raiseError
*/
protected static function _throwError($object, $message = null, $code = null, $userinfo = null)
function &throwError($message = null,
$code = null,
$userinfo = null)
{
if ($object !== null) {
$a = &$object->raiseError($message, $code, null, null, $userinfo);
if (isset($this) && is_a($this, 'PEAR')) {
$a = &$this->raiseError($message, $code, null, null, $userinfo);
return $a;
} else {
$a = &PEAR::raiseError($message, $code, null, null, $userinfo);
return $a;
}
 
$a = &PEAR::raiseError($message, $code, null, null, $userinfo);
return $a;
}
 
public static function staticPushErrorHandling($mode, $options = null)
// }}}
function staticPushErrorHandling($mode, $options = null)
{
$stack = &$GLOBALS['_PEAR_error_handler_stack'];
$stack = &$GLOBALS['_PEAR_error_handler_stack'];
$def_mode = &$GLOBALS['_PEAR_default_error_mode'];
$def_options = &$GLOBALS['_PEAR_default_error_options'];
$stack[] = array($def_mode, $def_options);
641,7 → 633,7
return true;
}
 
public static function staticPopErrorHandling()
function staticPopErrorHandling()
{
$stack = &$GLOBALS['_PEAR_error_handler_stack'];
$setmode = &$GLOBALS['_PEAR_default_error_mode'];
677,6 → 669,8
return true;
}
 
// {{{ pushErrorHandling()
 
/**
* 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
689,12 → 683,12
*
* @see PEAR::setErrorHandling
*/
protected static function _pushErrorHandling($object, $mode, $options = null)
function pushErrorHandling($mode, $options = null)
{
$stack = &$GLOBALS['_PEAR_error_handler_stack'];
if ($object !== null) {
$def_mode = &$object->_default_error_mode;
$def_options = &$object->_default_error_options;
if (isset($this) && is_a($this, 'PEAR')) {
$def_mode = &$this->_default_error_mode;
$def_options = &$this->_default_error_options;
} else {
$def_mode = &$GLOBALS['_PEAR_default_error_mode'];
$def_options = &$GLOBALS['_PEAR_default_error_options'];
701,8 → 695,8
}
$stack[] = array($def_mode, $def_options);
 
if ($object !== null) {
$object->setErrorHandling($mode, $options);
if (isset($this) && is_a($this, 'PEAR')) {
$this->setErrorHandling($mode, $options);
} else {
PEAR::setErrorHandling($mode, $options);
}
710,6 → 704,9
return true;
}
 
// }}}
// {{{ popErrorHandling()
 
/**
* Pop the last error handler used
*
717,14 → 714,14
*
* @see PEAR::pushErrorHandling
*/
protected static function _popErrorHandling($object)
function popErrorHandling()
{
$stack = &$GLOBALS['_PEAR_error_handler_stack'];
array_pop($stack);
list($mode, $options) = $stack[sizeof($stack) - 1];
array_pop($stack);
if ($object !== null) {
$object->setErrorHandling($mode, $options);
if (isset($this) && is_a($this, 'PEAR')) {
$this->setErrorHandling($mode, $options);
} else {
PEAR::setErrorHandling($mode, $options);
}
731,43 → 728,44
return true;
}
 
// }}}
// {{{ loadExtension()
 
/**
* OS independent 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.
*
* @param string $ext The extension name
* @return bool Success or not on the dl() call
*/
public static function loadExtension($ext)
function loadExtension($ext)
{
if (extension_loaded($ext)) {
return true;
if (!extension_loaded($ext)) {
// if either returns true dl() will produce a FATAL error, stop that
if ((ini_get('enable_dl') != 1) || (ini_get('safe_mode') == 1)) {
return false;
}
if (OS_WINDOWS) {
$suffix = '.dll';
} elseif (PHP_OS == 'HP-UX') {
$suffix = '.sl';
} elseif (PHP_OS == 'AIX') {
$suffix = '.a';
} elseif (PHP_OS == 'OSX') {
$suffix = '.bundle';
} else {
$suffix = '.so';
}
return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix);
}
return true;
}
 
// if either returns true dl() will produce a FATAL error, stop that
if (
function_exists('dl') === false ||
ini_get('enable_dl') != 1
) {
return false;
}
// }}}
}
 
if (OS_WINDOWS) {
$suffix = '.dll';
} elseif (PHP_OS == 'HP-UX') {
$suffix = '.sl';
} elseif (PHP_OS == 'AIX') {
$suffix = '.a';
} elseif (PHP_OS == 'OSX') {
$suffix = '.bundle';
} else {
$suffix = '.so';
}
// {{{ _PEAR_call_destructors()
 
return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix);
}
}
 
function _PEAR_call_destructors()
{
global $_PEAR_destructor_object_list;
775,13 → 773,9
sizeof($_PEAR_destructor_object_list))
{
reset($_PEAR_destructor_object_list);
 
$destructLifoExists = PEAR::getStaticProperty('PEAR', 'destructlifo');
 
if ($destructLifoExists) {
if (PEAR::getStaticProperty('PEAR', 'destructlifo')) {
$_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list);
}
 
while (list($k, $objref) = each($_PEAR_destructor_object_list)) {
$classname = get_class($objref);
while ($classname) {
800,11 → 794,7
}
 
// Now call the shutdown functions
if (
isset($GLOBALS['_PEAR_shutdown_funcs']) &&
is_array($GLOBALS['_PEAR_shutdown_funcs']) &&
!empty($GLOBALS['_PEAR_shutdown_funcs'])
) {
if (is_array($GLOBALS['_PEAR_shutdown_funcs']) AND !empty($GLOBALS['_PEAR_shutdown_funcs'])) {
foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) {
call_user_func_array($value[0], $value[1]);
}
811,6 → 801,7
}
}
 
// }}}
/**
* Standard PEAR error class for PHP 4
*
822,8 → 813,8
* @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.10.1
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @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
830,6 → 821,8
*/
class PEAR_Error
{
// {{{ properties
 
var $error_message_prefix = '';
var $mode = PEAR_ERROR_RETURN;
var $level = E_USER_NOTICE;
838,6 → 831,9
var $userinfo = '';
var $backtrace = null;
 
// }}}
// {{{ constructor
 
/**
* PEAR_Error constructor
*
858,7 → 854,7
* @access public
*
*/
function __construct($message = 'unknown error', $code = null,
function PEAR_Error($message = 'unknown error', $code = null,
$mode = null, $options = null, $userinfo = null)
{
if ($mode === null) {
868,16 → 864,12
$this->code = $code;
$this->mode = $mode;
$this->userinfo = $userinfo;
 
$skiptrace = PEAR::getStaticProperty('PEAR_Error', 'skiptrace');
 
if (!$skiptrace) {
if (!PEAR::getStaticProperty('PEAR_Error', 'skiptrace')) {
$this->backtrace = debug_backtrace();
if (isset($this->backtrace[0]) && isset($this->backtrace[0]['object'])) {
unset($this->backtrace[0]['object']);
}
}
 
if ($mode & PEAR_ERROR_CALLBACK) {
$this->level = E_USER_NOTICE;
$this->callback = $options;
885,11 → 877,9
if ($options === null) {
$options = E_USER_NOTICE;
}
 
$this->level = $options;
$this->callback = null;
}
 
if ($this->mode & PEAR_ERROR_PRINT) {
if (is_null($options) || is_int($options)) {
$format = "%s";
896,14 → 886,11
} else {
$format = $options;
}
 
printf($format, $this->getMessage());
}
 
if ($this->mode & PEAR_ERROR_TRIGGER) {
trigger_error($this->getMessage(), $this->level);
}
 
if ($this->mode & PEAR_ERROR_DIE) {
$msg = $this->getMessage();
if (is_null($options) || is_int($options)) {
916,11 → 903,11
}
die(sprintf($format, $msg));
}
 
if ($this->mode & PEAR_ERROR_CALLBACK && is_callable($this->callback)) {
call_user_func($this->callback, $this);
if ($this->mode & PEAR_ERROR_CALLBACK) {
if (is_callable($this->callback)) {
call_user_func($this->callback, $this);
}
}
 
if ($this->mode & PEAR_ERROR_EXCEPTION) {
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);');
927,23 → 914,8
}
}
 
/**
* Only here for backwards compatibility.
*
* Class "Cache_Error" still uses it, among others.
*
* @param string $message Message
* @param int $code Error code
* @param int $mode Error mode
* @param mixed $options See __construct()
* @param string $userinfo Additional user/debug info
*/
public function PEAR_Error(
$message = 'unknown error', $code = null, $mode = null,
$options = null, $userinfo = null
) {
self::__construct($message, $code, $mode, $options, $userinfo);
}
// }}}
// {{{ getMode()
 
/**
* Get the error mode from an error object.
951,11 → 923,13
* @return int error mode
* @access public
*/
function getMode()
{
function getMode() {
return $this->mode;
}
 
// }}}
// {{{ getCallback()
 
/**
* Get the callback function/method from an error object.
*
962,11 → 936,14
* @return mixed callback function or object/method array
* @access public
*/
function getCallback()
{
function getCallback() {
return $this->callback;
}
 
// }}}
// {{{ getMessage()
 
 
/**
* Get the error message from an error object.
*
978,6 → 955,10
return ($this->error_message_prefix . $this->message);
}
 
 
// }}}
// {{{ getCode()
 
/**
* Get error code from an error object
*
989,6 → 970,9
return $this->code;
}
 
// }}}
// {{{ getType()
 
/**
* Get the name of this error/exception.
*
1000,6 → 984,9
return get_class($this);
}
 
// }}}
// {{{ getUserInfo()
 
/**
* Get additional user-supplied information.
*
1011,6 → 998,9
return $this->userinfo;
}
 
// }}}
// {{{ getDebugInfo()
 
/**
* Get additional debug information supplied by the application.
*
1022,6 → 1012,9
return $this->getUserInfo();
}
 
// }}}
// {{{ getBacktrace()
 
/**
* Get the call backtrace from where the error was generated.
* Supported with PHP 4.3.0 or newer.
1041,6 → 1034,9
return $this->backtrace[$frame];
}
 
// }}}
// {{{ addUserInfo()
 
function addUserInfo($info)
{
if (empty($this->userinfo)) {
1050,10 → 1046,8
}
}
 
function __toString()
{
return $this->getMessage();
}
// }}}
// {{{ toString()
 
/**
* Make a string representation of this object.
1061,8 → 1055,7
* @return string a string with an object summary
* @access public
*/
function toString()
{
function toString() {
$modes = array();
$levels = array(E_USER_NOTICE => 'notice',
E_USER_WARNING => 'warning',
1101,6 → 1094,8
$this->error_message_prefix,
$this->userinfo);
}
 
// }}}
}
 
/*
1110,3 → 1105,4
* c-basic-offset: 4
* End:
*/
?>
/trunk/scripts/clonegtt.sh
67,7 → 67,7
// cree par clonegtt le $DATE
define('GTT_AUTH_SESSION_NOM', 'gtt_auth_$PREFIXE');
define('GTT_BDD_NOM', '$BDD_BASE');
define('GTT_BDD_DSN', 'mysqli://$BDD_LOGIN:$BDD_MDP@$BDD_HOTE/'.GTT_BDD_NOM);
define('GTT_BDD_DSN', 'mysql://$BDD_LOGIN:$BDD_MDP@$BDD_HOTE/'.GTT_BDD_NOM);
define('GTT_BDD_PREFIXE', '$PREFIXE');
define('GTT_DEBOGAGE', false);
define('GTT_DEBOGAGE_SQL', false);
/trunk/scripts/installgtt.sh
47,7 → 47,7
// cree par installgtt le $DATE
define('GTT_AUTH_SESSION_NOM', 'gtt_auth_$PREFIXE');
define('GTT_BDD_NOM', '$BDD_BASE');
define('GTT_BDD_DSN', 'mysqli://$BDD_LOGIN:$BDD_MDP@$BDD_HOTE/'.GTT_BDD_NOM);
define('GTT_BDD_DSN', 'mysql://$BDD_LOGIN:$BDD_MDP@$BDD_HOTE/'.GTT_BDD_NOM);
define('GTT_BDD_PREFIXE', '$PREFIXE');
define('GTT_DEBOGAGE', false);
define('GTT_DEBOGAGE_SQL', false);
/trunk/config.inc.defaut.php
3,7 → 3,7
define('GTT_AUTH_SESSION_NOM', 'gtt_auth_v4');
// Base de données
define('GTT_BDD_NOM', 'gtt_v4');
define('GTT_BDD_DSN', 'mysqli://utilsiateur:mot_de_passe@localhost/'.GTT_BDD_NOM);
define('GTT_BDD_DSN', 'mysql://utilsiateur:mot_de_passe@localhost/'.GTT_BDD_NOM);
define('GTT_BDD_PREFIXE', '');
// Débogage
/** Constante stockant si oui ou non on veut afficher le débogage.*/