[ Index ]
 

Code source de GeekLog 1.4.1

Accédez au Source d'autres logiciels libres

title

Body

[fermer]

/system/pear/PEAR/ -> DependencyDB.php (source)

   1  <?php
   2  /**
   3   * PEAR_DependencyDB, advanced installed packages dependency database
   4   *
   5   * PHP versions 4 and 5
   6   *
   7   * LICENSE: This source file is subject to version 3.0 of the PHP license
   8   * that is available through the world-wide-web at the following URI:
   9   * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
  10   * the PHP License and are unable to obtain it through the web, please
  11   * send a note to license@php.net so we can mail you a copy immediately.
  12   *
  13   * @category   pear
  14   * @package    PEAR
  15   * @author     Tomas V. V. Cox <cox@idecnet.com>
  16   * @author     Greg Beaver <cellog@php.net>
  17   * @copyright  1997-2006 The PHP Group
  18   * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  19   * @version    CVS: $Id: DependencyDB.php,v 1.30.2.1 2006/05/25 22:00:05 cellog Exp $
  20   * @link       http://pear.php.net/package/PEAR
  21   * @since      File available since Release 1.4.0a1
  22   */
  23  
  24  /**
  25   * Needed for error handling
  26   */
  27  require_once  'PEAR.php';
  28  require_once 'PEAR/Config.php';
  29  
  30  /**
  31   * Track dependency relationships between installed packages
  32   * @category   pear
  33   * @package    PEAR
  34   * @author     Greg Beaver <cellog@php.net>
  35   * @author     Tomas V.V.Cox <cox@idec.net.com>
  36   * @copyright  1997-2006 The PHP Group
  37   * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  38   * @version    Release: 1.4.11
  39   * @link       http://pear.php.net/package/PEAR
  40   * @since      Class available since Release 1.4.0a1
  41   */
  42  class PEAR_DependencyDB
  43  {
  44      // {{{ properties
  45  
  46      /**
  47       * This is initialized by {@link setConfig()}
  48       * @var PEAR_Config
  49       * @access private
  50       */
  51      var $_config;
  52      /**
  53       * This is initialized by {@link setConfig()}
  54       * @var PEAR_Registry
  55       * @access private
  56       */
  57      var $_registry;
  58      /**
  59       * Filename of the dependency DB (usually .depdb)
  60       * @var string
  61       * @access private
  62       */
  63      var $_depdb = false;
  64      /**
  65       * File name of the lockfile (usually .depdblock)
  66       * @var string
  67       * @access private
  68       */
  69      var $_lockfile = false;
  70      /**
  71       * Open file resource for locking the lockfile
  72       * @var resource|false
  73       * @access private
  74       */
  75      var $_lockFp = false;
  76      /**
  77       * API version of this class, used to validate a file on-disk
  78       * @var string
  79       * @access private
  80       */
  81      var $_version = '1.0';
  82      /**
  83       * Cached dependency database file
  84       * @var array|null
  85       * @access private
  86       */
  87      var $_cache;
  88  
  89      // }}}
  90      // {{{ & singleton()
  91  
  92      /**
  93       * Get a raw dependency database.  Calls setConfig() and assertDepsDB()
  94       * @param PEAR_Config
  95       * @param string|false full path to the dependency database, or false to use default
  96       * @return PEAR_DependencyDB|PEAR_Error
  97       * @static
  98       */
  99      function &singleton(&$config, $depdb = false)
 100      {
 101          if (!isset($GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE']
 102                [$config->get('php_dir', null, 'pear.php.net')])) {
 103              $a = new PEAR_DependencyDB;
 104              $GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE']
 105                [$config->get('php_dir', null, 'pear.php.net')] = &$a;
 106              $a->setConfig($config, $depdb);
 107              if (PEAR::isError($e = $a->assertDepsDB())) {
 108                  return $e;
 109              }
 110          }
 111          return $GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE']
 112                [$config->get('php_dir', null, 'pear.php.net')];
 113      }
 114  
 115      /**
 116       * Set up the registry/location of dependency DB
 117       * @param PEAR_Config|false
 118       * @param string|false full path to the dependency database, or false to use default
 119       */
 120      function setConfig(&$config, $depdb = false)
 121      {
 122          if (!$config) {
 123              $this->_config = &PEAR_Config::singleton();
 124          } else {
 125              $this->_config = &$config;
 126          }
 127          $this->_registry = &$this->_config->getRegistry();
 128          if (!$depdb) {
 129              $this->_depdb = $this->_config->get('php_dir', null, 'pear.php.net') .
 130                  DIRECTORY_SEPARATOR . '.depdb';
 131          } else {
 132              $this->_depdb = $depdb;
 133          }
 134          $this->_lockfile = dirname($this->_depdb) . DIRECTORY_SEPARATOR . '.depdblock';
 135      }
 136      // }}}
 137  
 138      function hasWriteAccess()
 139      {
 140          if (!@file_exists($this->_depdb)) {
 141              $dir = $this->_depdb;
 142              while ($dir && $dir != '.') {
 143                  $dir = dirname($dir); // cd ..
 144                  if ($dir != '.' && @file_exists($dir)) {
 145                      if (@is_writeable($dir)) {
 146                          return true;
 147                      } else {
 148                          return false;
 149                      }
 150                  }
 151              }
 152              return false;
 153          }
 154          return @is_writeable($this->_depdb);
 155      }
 156  
 157      // {{{ assertDepsDB()
 158  
 159      /**
 160       * Create the dependency database, if it doesn't exist.  Error if the database is
 161       * newer than the code reading it.
 162       * @return void|PEAR_Error
 163       */
 164      function assertDepsDB()
 165      {
 166          if (!is_file($this->_depdb)) {
 167              $this->rebuildDB();
 168          } else {
 169              $depdb = $this->_getDepDB();
 170              // Datatype format has been changed, rebuild the Deps DB
 171              if ($depdb['_version'] < $this->_version) {
 172                  $this->rebuildDB();
 173              }
 174              if ($depdb['_version']{0} > $this->_version{0}) {
 175                  return PEAR::raiseError('Dependency database is version ' .
 176                      $depdb['_version'] . ', and we are version ' .
 177                      $this->_version . ', cannot continue');
 178              }
 179          }
 180      }
 181  
 182      /**
 183       * Get a list of installed packages that depend on this package
 184       * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array
 185       * @return array|false
 186       */
 187      function getDependentPackages(&$pkg)
 188      {
 189          $data = $this->_getDepDB();
 190          if (is_object($pkg)) {
 191              $channel = strtolower($pkg->getChannel());
 192              $package = strtolower($pkg->getPackage());
 193          } else {
 194              $channel = strtolower($pkg['channel']);
 195              $package = strtolower($pkg['package']);
 196          }
 197          if (isset($data['packages'][$channel][$package])) {
 198              return $data['packages'][$channel][$package];
 199          }
 200          return false;
 201      }
 202  
 203      /**
 204       * Get a list of the actual dependencies of installed packages that depend on
 205       * a package.
 206       * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array
 207       * @return array|false
 208       */
 209      function getDependentPackageDependencies(&$pkg)
 210      {
 211          $data = $this->_getDepDB();
 212          if (is_object($pkg)) {
 213              $channel = strtolower($pkg->getChannel());
 214              $package = strtolower($pkg->getPackage());
 215          } else {
 216              $channel = strtolower($pkg['channel']);
 217              $package = strtolower($pkg['package']);
 218          }
 219          $depend = $this->getDependentPackages($pkg);
 220          if (!$depend) {
 221              return false;
 222          }
 223          $dependencies = array();
 224          foreach ($depend as $info) {
 225              $temp = $this->getDependencies($info);
 226              foreach ($temp as $dep) {
 227                  if (strtolower($dep['dep']['channel']) == strtolower($channel) &&
 228                        strtolower($dep['dep']['name']) == strtolower($package)) {
 229                      $dependencies[$info['channel']][$info['package']][] = $dep;
 230                  }
 231              }
 232          }
 233          return $dependencies;
 234      }
 235  
 236      /**
 237       * Get a list of dependencies of this installed package
 238       * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array
 239       * @return array|false
 240       */
 241      function getDependencies(&$pkg)
 242      {
 243          if (is_object($pkg)) {
 244              $channel = strtolower($pkg->getChannel());
 245              $package = strtolower($pkg->getPackage());
 246          } else {
 247              $channel = strtolower($pkg['channel']);
 248              $package = strtolower($pkg['package']);
 249          }
 250          $data = $this->_getDepDB();
 251          if (isset($data['dependencies'][$channel][$package])) {
 252              return $data['dependencies'][$channel][$package];
 253          }
 254          return false;
 255      }
 256  
 257      /**
 258       * Determine whether $parent depends on $child, near or deep
 259       * @param array|PEAR_PackageFile_v2|PEAR_PackageFile_v2
 260       * @param array|PEAR_PackageFile_v2|PEAR_PackageFile_v2
 261       */
 262      function dependsOn($parent, $child)
 263      {
 264          $c = array();
 265          $this->_getDepDB();
 266          return $this->_dependsOn($parent, $child, $c);
 267      }
 268      
 269      function _dependsOn($parent, $child, &$checked)
 270      {
 271          if (is_object($parent)) {
 272              $channel = strtolower($parent->getChannel());
 273              $package = strtolower($parent->getPackage());
 274          } else {
 275              $channel = strtolower($parent['channel']);
 276              $package = strtolower($parent['package']);
 277          }
 278          if (is_object($child)) {
 279              $depchannel = strtolower($child->getChannel());
 280              $deppackage = strtolower($child->getPackage());
 281          } else {
 282              $depchannel = strtolower($child['channel']);
 283              $deppackage = strtolower($child['package']);
 284          }
 285          if (isset($checked[$channel][$package][$depchannel][$deppackage])) {
 286              return false; // avoid endless recursion
 287          }
 288          $checked[$channel][$package][$depchannel][$deppackage] = true;
 289          if (!isset($this->_cache['dependencies'][$channel][$package])) {
 290              return false;
 291          }
 292          foreach ($this->_cache['dependencies'][$channel][$package] as $info) {
 293              if (isset($info['dep']['uri'])) {
 294                  if (is_object($child)) {
 295                      if ($info['dep']['uri'] == $child->getURI()) {
 296                          return true;
 297                      }
 298                  } elseif (isset($child['uri'])) {
 299                      if ($info['dep']['uri'] == $child['uri']) {
 300                          return true;
 301                      }
 302                  }
 303                  return false;
 304              }
 305              if (strtolower($info['dep']['channel']) == strtolower($depchannel) &&
 306                    strtolower($info['dep']['name']) == strtolower($deppackage)) {
 307                  return true;
 308              }
 309          }
 310          foreach ($this->_cache['dependencies'][$channel][$package] as $info) {
 311              if (isset($info['dep']['uri'])) {
 312                  if ($this->_dependsOn(array(
 313                          'uri' => $info['dep']['uri'],
 314                          'package' => $info['dep']['name']), $child, $checked)) {
 315                      return true;
 316                  }
 317              } else {
 318                  if ($this->_dependsOn(array(
 319                          'channel' => $info['dep']['channel'],
 320                          'package' => $info['dep']['name']), $child, $checked)) {
 321                      return true;
 322                  }
 323              }
 324          }
 325          return false;
 326      }
 327  
 328      /**
 329       * Register dependencies of a package that is being installed or upgraded
 330       * @param PEAR_PackageFile_v2|PEAR_PackageFile_v2
 331       */
 332      function installPackage(&$package)
 333      {
 334          $data = $this->_getDepDB();
 335          unset($this->_cache);
 336          $this->_setPackageDeps($data, $package);
 337          $this->_writeDepDB($data);
 338      }
 339  
 340      /**
 341       * Remove dependencies of a package that is being uninstalled, or upgraded.
 342       *
 343       * Upgraded packages first uninstall, then install
 344       * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array If an array, then it must have
 345       *        indices 'channel' and 'package'
 346       */
 347      function uninstallPackage(&$pkg)
 348      {
 349          $data = $this->_getDepDB();
 350          unset($this->_cache);
 351          if (is_object($pkg)) {
 352              $channel = strtolower($pkg->getChannel());
 353              $package = strtolower($pkg->getPackage());
 354          } else {
 355              $channel = strtolower($pkg['channel']);
 356              $package = strtolower($pkg['package']);
 357          }
 358          if (!isset($data['dependencies'][$channel][$package])) {
 359              return true;
 360          }
 361          foreach ($data['dependencies'][$channel][$package] as $dep) {
 362              $found = false;
 363              if (isset($dep['dep']['uri'])) {
 364                  $depchannel = '__uri';
 365              } else {
 366                  $depchannel = strtolower($dep['dep']['channel']);
 367              }
 368              if (isset($data['packages'][$depchannel][strtolower($dep['dep']['name'])])) {
 369                  foreach ($data['packages'][$depchannel][strtolower($dep['dep']['name'])] as
 370                        $i => $info) {
 371                      if ($info['channel'] == $channel &&
 372                            $info['package'] == $package) {
 373                          $found = true;
 374                          break;
 375                      }
 376                  }
 377              }
 378              if ($found) {
 379                  unset($data['packages'][$depchannel][strtolower($dep['dep']['name'])][$i]);
 380                  if (!count($data['packages'][$depchannel][strtolower($dep['dep']['name'])])) {
 381                      unset($data['packages'][$depchannel][strtolower($dep['dep']['name'])]);
 382                      if (!count($data['packages'][$depchannel])) {
 383                          unset($data['packages'][$depchannel]);
 384                      }
 385                  } else {
 386                      $data['packages'][$depchannel][strtolower($dep['dep']['name'])] =
 387                          array_values(
 388                              $data['packages'][$depchannel][strtolower($dep['dep']['name'])]);
 389                  }
 390              }
 391          }
 392          unset($data['dependencies'][$channel][$package]);
 393          if (!count($data['dependencies'][$channel])) {
 394              unset($data['dependencies'][$channel]);
 395          }
 396          if (!count($data['dependencies'])) {
 397              unset($data['dependencies']);
 398          }
 399          if (!count($data['packages'])) {
 400              unset($data['packages']);
 401          }
 402          $this->_writeDepDB($data);
 403      }
 404  
 405      /**
 406       * Rebuild the dependency DB by reading registry entries.
 407       * @return true|PEAR_Error
 408       */
 409      function rebuildDB()
 410      {
 411          $depdb = array('_version' => $this->_version);
 412          if (!$this->hasWriteAccess()) {
 413              // allow startup for read-only with older Registry
 414              return $depdb;
 415          }
 416          $packages = $this->_registry->listAllPackages();
 417          foreach ($packages as $channel => $ps) {
 418              foreach ($ps as $package) {
 419                  $package = $this->_registry->getPackage($package, $channel);
 420                  $this->_setPackageDeps($depdb, $package);
 421              }
 422          }
 423          $error = $this->_writeDepDB($depdb);
 424          if (PEAR::isError($error)) {
 425              return $error;
 426          }
 427          $this->_cache = $depdb;
 428          return true;
 429      }
 430  
 431      /**
 432       * Register usage of the dependency DB to prevent race conditions
 433       * @param int one of the LOCK_* constants
 434       * @return true|PEAR_Error
 435       * @access private
 436       */
 437      function _lock($mode = LOCK_EX)
 438      {
 439          if (!eregi('Windows 9', php_uname())) {
 440              if ($mode != LOCK_UN && is_resource($this->_lockFp)) {
 441                  // XXX does not check type of lock (LOCK_SH/LOCK_EX)
 442                  return true;
 443              }
 444              $open_mode = 'w';
 445              // XXX People reported problems with LOCK_SH and 'w'
 446              if ($mode === LOCK_SH) {
 447                  if (@!is_file($this->_lockfile)) {
 448                      touch($this->_lockfile);
 449                  }
 450                  $open_mode = 'r';
 451              }
 452  
 453              if (!is_resource($this->_lockFp)) {
 454                  $this->_lockFp = @fopen($this->_lockfile, $open_mode);
 455              }
 456              if (!is_resource($this->_lockFp)) {
 457                  return PEAR::raiseError("could not create Dependency lock file" .
 458                                           (isset($php_errormsg) ? ": " . $php_errormsg : ""));
 459              }
 460              if (!(int)flock($this->_lockFp, $mode)) {
 461                  switch ($mode) {
 462                      case LOCK_SH: $str = 'shared';    break;
 463                      case LOCK_EX: $str = 'exclusive'; break;
 464                      case LOCK_UN: $str = 'unlock';    break;
 465                      default:      $str = 'unknown';   break;
 466                  }
 467                  return PEAR::raiseError("could not acquire $str lock ($this->_lockfile)");
 468              }
 469          }
 470          return true;
 471      }
 472  
 473      /**
 474       * Release usage of dependency DB
 475       * @return true|PEAR_Error
 476       * @access private
 477       */
 478      function _unlock()
 479      {
 480          $ret = $this->_lock(LOCK_UN);
 481          if (is_resource($this->_lockFp)) {
 482              fclose($this->_lockFp);
 483          }
 484          $this->_lockFp = null;
 485          return $ret;
 486      }
 487  
 488      /**
 489       * Load the dependency database from disk, or return the cache
 490       * @return array|PEAR_Error
 491       */
 492      function _getDepDB()
 493      {
 494          if (!$this->hasWriteAccess()) {
 495              return array('_version' => $this->_version);
 496          }
 497          if (isset($this->_cache)) {
 498              return $this->_cache;
 499          }
 500          if (!$fp = fopen($this->_depdb, 'r')) {
 501              $err = PEAR::raiseError("Could not open dependencies file `".$this->_depdb."'");
 502              return $err;
 503          }
 504          $rt = get_magic_quotes_runtime();
 505          set_magic_quotes_runtime(0);
 506          clearstatcache();
 507          if (function_exists('file_get_contents')) {
 508              fclose($fp);
 509              $data = unserialize(file_get_contents($this->_depdb));
 510          } else {
 511              $data = unserialize(fread($fp, filesize($this->_depdb)));
 512              fclose($fp);
 513          }
 514          set_magic_quotes_runtime($rt);
 515          $this->_cache = $data;
 516          return $data;
 517      }
 518  
 519      /**
 520       * Write out the dependency database to disk
 521       * @param array the database
 522       * @return true|PEAR_Error
 523       * @access private
 524       */
 525      function _writeDepDB(&$deps)
 526      {
 527          if (PEAR::isError($e = $this->_lock(LOCK_EX))) {
 528              return $e;
 529          }
 530          if (!$fp = fopen($this->_depdb, 'wb')) {
 531              $this->_unlock();
 532              return PEAR::raiseError("Could not open dependencies file `".$this->_depdb."' for writing");
 533          }
 534          $rt = get_magic_quotes_runtime();
 535          set_magic_quotes_runtime(0);
 536          fwrite($fp, serialize($deps));
 537          set_magic_quotes_runtime($rt);
 538          fclose($fp);
 539          $this->_unlock();
 540          $this->_cache = $deps;
 541          return true;
 542      }
 543  
 544      /**
 545       * Register all dependencies from a package in the dependencies database, in essence
 546       * "installing" the package's dependency information
 547       * @param array the database
 548       * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
 549       * @access private
 550       */
 551      function _setPackageDeps(&$data, &$pkg)
 552      {
 553          $pkg->setConfig($this->_config);
 554          if ($pkg->getPackagexmlVersion() == '1.0') {
 555              $gen = &$pkg->getDefaultGenerator();
 556              $deps = $gen->dependenciesToV2();
 557          } else {
 558              $deps = $pkg->getDeps(true);
 559          }
 560          if (!$deps) {
 561              return;
 562          }
 563          $data['dependencies'][strtolower($pkg->getChannel())][strtolower($pkg->getPackage())]
 564              = array();
 565          if (isset($deps['required']['package'])) {
 566              if (!isset($deps['required']['package'][0])) {
 567                  $deps['required']['package'] = array($deps['required']['package']);
 568              }
 569              foreach ($deps['required']['package'] as $dep) {
 570                  $this->_registerDep($data, $pkg, $dep, 'required');
 571              }
 572          }
 573          if (isset($deps['optional']['package'])) {
 574              if (!isset($deps['optional']['package'][0])) {
 575                  $deps['optional']['package'] = array($deps['optional']['package']);
 576              }
 577              foreach ($deps['optional']['package'] as $dep) {
 578                  $this->_registerDep($data, $pkg, $dep, 'optional');
 579              }
 580          }
 581          if (isset($deps['required']['subpackage'])) {
 582              if (!isset($deps['required']['subpackage'][0])) {
 583                  $deps['required']['subpackage'] = array($deps['required']['subpackage']);
 584              }
 585              foreach ($deps['required']['subpackage'] as $dep) {
 586                  $this->_registerDep($data, $pkg, $dep, 'required');
 587              }
 588          }
 589          if (isset($deps['optional']['subpackage'])) {
 590              if (!isset($deps['optional']['subpackage'][0])) {
 591                  $deps['optional']['subpackage'] = array($deps['optional']['subpackage']);
 592              }
 593              foreach ($deps['optional']['subpackage'] as $dep) {
 594                  $this->_registerDep($data, $pkg, $dep, 'optional');
 595              }
 596          }
 597          if (isset($deps['group'])) {
 598              if (!isset($deps['group'][0])) {
 599                  $deps['group'] = array($deps['group']);
 600              }
 601              foreach ($deps['group'] as $group) {
 602                  if (isset($group['package'])) {
 603                      if (!isset($group['package'][0])) {
 604                          $group['package'] = array($group['package']);
 605                      }
 606                      foreach ($group['package'] as $dep) {
 607                          $this->_registerDep($data, $pkg, $dep, 'optional',
 608                              $group['attribs']['name']);
 609                      }
 610                  }
 611                  if (isset($group['subpackage'])) {
 612                      if (!isset($group['subpackage'][0])) {
 613                          $group['subpackage'] = array($group['subpackage']);
 614                      }
 615                      foreach ($group['subpackage'] as $dep) {
 616                          $this->_registerDep($data, $pkg, $dep, 'optional',
 617                              $group['attribs']['name']);
 618                      }
 619                  }
 620              }
 621          }
 622          if ($data['dependencies'][strtolower($pkg->getChannel())]
 623                [strtolower($pkg->getPackage())] == array()) {
 624              unset($data['dependencies'][strtolower($pkg->getChannel())]
 625                [strtolower($pkg->getPackage())]);
 626              if (!count($data['dependencies'][strtolower($pkg->getChannel())])) {
 627                  unset($data['dependencies'][strtolower($pkg->getChannel())]);
 628              }
 629          }
 630      }
 631  
 632      /**
 633       * @param array the database
 634       * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
 635       * @param array the specific dependency
 636       * @param required|optional whether this is a required or an optional dep
 637       * @param string|false dependency group this dependency is from, or false for ordinary dep
 638       */
 639      function _registerDep(&$data, &$pkg, $dep, $type, $group = false)
 640      {
 641          $info = array(
 642              'dep' => $dep,
 643              'type' => $type,
 644              'group' => $group);
 645  
 646          if (isset($dep['channel'])) {
 647              $depchannel = $dep['channel'];
 648          } else {
 649              $depchannel = '__uri';
 650          }
 651          $data['dependencies'][strtolower($pkg->getChannel())][strtolower($pkg->getPackage())][]
 652              = $info;
 653          if (isset($data['packages'][strtolower($depchannel)][strtolower($dep['name'])])) {
 654              $found = false;
 655              foreach ($data['packages'][strtolower($depchannel)][strtolower($dep['name'])]
 656                    as $i => $p) {
 657                  if ($p['channel'] == strtolower($pkg->getChannel()) &&
 658                        $p['package'] == strtolower($pkg->getPackage())) {
 659                      $found = true;
 660                      break;
 661                  }
 662              }
 663              if (!$found) {
 664                  $data['packages'][strtolower($depchannel)][strtolower($dep['name'])][]
 665                      = array('channel' => strtolower($pkg->getChannel()),
 666                              'package' => strtolower($pkg->getPackage()));
 667              }
 668          } else {
 669              $data['packages'][strtolower($depchannel)][strtolower($dep['name'])][]
 670                  = array('channel' => strtolower($pkg->getChannel()),
 671                          'package' => strtolower($pkg->getPackage()));
 672          }
 673      }
 674  }
 675  ?>


Généré le : Wed Nov 21 12:27:40 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics