PEAR_Frontend_Gtk2
[ class tree: PEAR_Frontend_Gtk2 ] [ index: PEAR_Frontend_Gtk2 ] [ all elements ]

Source for file Packages.php

Documentation is available at Packages.php

  1. <?php
  2. require_once 'PEAR/Frontend/Gtk2/Package.php';
  3. require_once 'PEAR/Config.php';
  4.  
  5. /**
  6. *   This class deals with packages: local package loading,
  7. *   remote package loading and so.
  8. *
  9. *   The callback is called after everything has been finished
  10. *   with parameters (true, true) to signal that it's done.
  11. *
  12. *   @author Christian Weiske <cweiske@php.net>
  13. */
  14. class PEAR_Frontend_Gtk2_Packages
  15. {
  16.     /**
  17.     *   The currently active channel name
  18.     *   @var string 
  19.     */
  20.     protected $strActiveChannel = null;
  21.  
  22.     /**
  23.     *   Array of channel => package arrays
  24.     *   @var array 
  25.     */
  26.     protected $arPackages = null;
  27.  
  28.     /**
  29.     *   Array of channel => category strings
  30.     *   @var array 
  31.     */
  32.     protected $arCategories = null;
  33.  
  34.     public static $EXCEPTION_NO_REST = 451;
  35.  
  36.  
  37.  
  38.     public function __construct($strActiveChannel = null)
  39.     {
  40.         $this->setActiveChannel($strActiveChannel);
  41.     }//public function __construct($strActiveChannel = null)
  42.  
  43.  
  44.  
  45.     public function setActiveChannel($strActiveChannel)
  46.     {
  47.         $this->strActiveChannel $strActiveChannel;
  48.     }//public function setActiveChannel($strActiveChannel)
  49.  
  50.  
  51.  
  52.     public function getActiveChannel()
  53.     {
  54.         return $this->strActiveChannel;
  55.     }//public function getActiveChannel()
  56.  
  57.  
  58.  
  59.     /**
  60.     *   Returns a list with all packages, or all packages in the given category.
  61.     *   Package list is cached, so that it's faster after the first call.
  62.     *
  63.     *   @param string   $strCategory    If given, the list is filtered by category name
  64.     *   @param callback $callback       The function to call before a package information is downloaded
  65.     *   @param booleab  $bWorkOffline   If the user wants to work offline (don't connect to the internet)
  66.     *
  67.     *   @return array   Array of PEAR_Frontend_Gtk2_Package's
  68.     */
  69.     public function getPackages($strCategory = null$callback = null$bWorkOffline = false)
  70.     {
  71.         if (!$this->packagesLoaded()) {
  72.             $this->arPackages[$this->strActiveChannel= PEAR_Frontend_Gtk2_Packages::getAllPackages($this->strActiveChannel$callback$bWorkOffline);
  73.         }
  74.         if ($strCategory === null{
  75.             return $this->arPackages[$this->strActiveChannel];
  76.         }
  77.  
  78.         $arSelectedPackages = array();
  79.         foreach ($this->arPackages[$this->strActiveChannelas $strName => $package{
  80.             if ($package->getCategory(== $strCategory{
  81.                 $arSelectedPackages[$strName$package;
  82.             }
  83.         }
  84.         return $arSelectedPackages;
  85.     }//public function getPackages($strCategory = null, $callback = null, $bWorkOffline = false)
  86.  
  87.  
  88.  
  89.     /**
  90.     *   Gets an array of packages for the active channel
  91.     *   (local and remote packages)
  92.     *
  93.     *   @param string   $strChannel     Channel to get packages for
  94.     *   @param callback $callback       The callback to call for each single remote package
  95.     *   @param boolean  $bWorkOffline   If the users wants to work offline
  96.     *
  97.     *   @return array   Array of Packages
  98.     */
  99.     public static function getAllPackages($strChannel$callback = null$bWorkOffline = false)
  100.     {
  101.         return PEAR_Frontend_Gtk2_Packages::getRemotePackages(
  102.                     $strChannel,
  103.                     true,
  104.                     $callback,
  105.                     PEAR_Frontend_Gtk2_Packages::getLocalPackages($strChannel),
  106.                     $bWorkOffline
  107.                 );
  108.     }//public static function getAllPackages($strChannel, $callback = null, $bWorkOffline = false)
  109.  
  110.  
  111.  
  112.     /**
  113.     *   Loads the locally installed packages of the given
  114.     *   channel
  115.     *
  116.     *   @param  string  $strChannel         The channel name
  117.     *   @param  array   $arLocalPackages    Array with already existing local packages. If set, package info will be incorporated.
  118.     *   @return array   Array of locally installed packages
  119.     *   @static
  120.     */
  121.     public static function getLocalPackages($strChannel$arLocalPackages = array())
  122.     {
  123.         $config        = PEAR_Config::singleton();
  124.         $arRawPackages $config->getRegistry()->packageInfo(nullnull$strChannel);
  125.         $arExisting    is_null($arLocalPackages? array(array_keys($arLocalPackages);
  126.         $arFound       = array();
  127.  
  128.         foreach ($arRawPackages as $strPackageId => $dontuseit{
  129.             if (isset($arRawPackages[$strPackageId]['name'])) {
  130.                 $strPackageName $arRawPackages[$strPackageId]['name'];
  131.             else {
  132.                 $strPackageName $arRawPackages[$strPackageId]['package'];
  133.             }
  134.             if (!isset($arLocalPackages[$strPackageName])) {
  135.                 $arLocalPackages[$strPackageName= new PEAR_Frontend_Gtk2_Package($strPackageName$strChannel);
  136.                 $arLocalPackages[$strPackageName]->setCategory(PEAR_Frontend_Gtk2_Package::guessCategory($strPackageName));
  137.             }
  138.             $arLocalPackages[$strPackageName]->incorporateLocalInfo($arRawPackages[$strPackageId]);
  139.             $arFound[$strPackageName= true;
  140.         }
  141.  
  142.         foreach ($arExisting as $strId => $strPackageName{
  143.             if (isset($arFound[$strPackageName])) {
  144.                 unset($arExisting[$strId]);
  145.             }
  146.         }
  147.  
  148.         //The ones still in here aren't installed locally any more
  149.         foreach ($arExisting as $strPackageName{
  150.             $arLocalPackages[$strPackageName]->setInstalledVersion(null);
  151.         }
  152.  
  153.         return $arLocalPackages;
  154.     }//public static function getLocalPackages($strChannel, $arLocalPackages = array())
  155.  
  156.  
  157.  
  158.     /**
  159.     *   Loads the remotely available packages for the given channel
  160.     *
  161.     *   @param string   $strChannel         The channel name
  162.     *   @param boolean  $bLoadPackageData   If all the package data shall be loaded, not only the names
  163.     *   @param callback $callback           The callback to call after a package info has been loaded
  164.     *   @param array    $arExistingPackages Array with local packages already loaded
  165.     *   @param boolean  $bWorkOffline       If we should use the local cache if possible
  166.     *
  167.     *   @return array   Array of remotely available packages (PEAR_Frontend_Gtk2_Package)
  168.     *   @throws Exception If the channel has no REST support or if the connection failed
  169.     *   @static
  170.     */
  171.     public static function getRemotePackages($strChannel$bLoadPackageData = true$callback = null$arExistingPackages = array()$bWorkOffline = false)
  172.     {
  173.         $config     = PEAR_Config::singleton();
  174.         $channel    $config->getRegistry()->getChannel($strChannel);
  175.         if ($channel === false{
  176.             throw new Exception('Channel "' $strChannel '" doesn\'t exist');
  177.         }
  178.         $strBaseUrl $channel->getBaseURL('REST1.0');
  179.         $strServer  $channel->getServer();
  180.         $rest       $config->getREST('1.0');
  181.  
  182.         if ($channel->supportsREST($strServer&& $strBaseUrl{
  183.             $arXmlPackages = PEAR_Frontend_Gtk2_Packages::listPackages($strChannel$bWorkOffline);
  184.             if (PEAR::isError($arXmlPackages)) {
  185.                 throw new Exception(
  186.                     'Error listing packages on channel ' $strChannel ":\r\n"
  187.                         . $arXmlPackages->getMessage(),
  188.                     $arXmlPackages->getCode()
  189.                 );
  190.             }
  191.         else {
  192.             throw new Exception($strChannel ' has no REST support'PEAR_Frontend_Gtk2_Packages::$EXCEPTION_NO_REST);
  193.         }
  194.  
  195.         if (count($arXmlPackages== 0
  196.             || (count($arXmlPackages== 1 && $arXmlPackages[0=== null)
  197.         {
  198.             //No packages...
  199.             return $arExistingPackages;
  200.         }
  201.  
  202.         foreach ($arXmlPackages as $id => $strName{
  203.             if (!isset($arExistingPackages[$strName])) {
  204.                 $arExistingPackages[$strName= new PEAR_Frontend_Gtk2_Package($strName$strChannel);
  205.             }
  206.         }
  207.  
  208.         if ($bLoadPackageData === false{
  209.             return $arExistingPackages;
  210.         else {
  211.             return PEAR_Frontend_Gtk2_Packages::loadRemotePackageData($arExistingPackages$strChannel$callback$bWorkOffline);
  212.         }
  213.     }//public static function getRemotePackages($strChannel, $bLoadPackageData = true, $callback = null, $arExistingPackages = array(), $bWorkOffline = false)
  214.  
  215.  
  216.  
  217.     /**
  218.     *   Copy of the PEAR_REST#listPackages function with the change
  219.     *   that this one is able to get the list from the local cache.
  220.     *
  221.     *   @param string   $strChannel     The channel which packages shall be listed
  222.     *   @param boolean  $bWorkOffline   If false, the local cache is used - if true, the online list is loaded
  223.     *
  224.     *   @return mixed   PEAR_Error or array (package list)
  225.     */
  226.     public static function listPackages($strChannel$bWorkOffline = false)
  227.     {
  228.         $config     = PEAR_Config::singleton();
  229.         $channel    $config->getRegistry()->getChannel($strChannel);
  230.         $strBaseUrl $channel->getBaseURL('REST1.0');
  231.         $strServer  $channel->getServer();
  232.         $rest       $config->getREST('1.0');
  233.  
  234.         if ($bWorkOffline{
  235.             //We can't use the retrieveCacheFirst function as it would
  236.             //try to connect if the local cache is empty
  237.             $url       $strBaseUrl 'p/packages.xml';
  238.             $cachefile $config->get('cache_dir'. DIRECTORY_SEPARATOR . md5($url'rest.cachefile';
  239.             if (@file_exists($cachefile)) {
  240.                 //local package list cache file
  241.                 $arCache unserialize(implode(''file($cachefile)));
  242.                 if (PEAR::isError($arCache)) {
  243.                     return $arCache;
  244.                 }
  245.                 if (!is_array($arCache|| !isset($arCache['p'])) {
  246.                     return array();
  247.                 }
  248.                 if (!is_array($arCache['p'])) {
  249.                     $arCache['p'= array($arCache['p']);
  250.                 }
  251.                 return $arCache['p'];
  252.  
  253.             else {
  254.                 //no local cache -> return empty package list
  255.                 return array();
  256.             }
  257.         else {
  258.             //online => list online packages
  259.             return $rest->listPackages($strBaseUrl);
  260.         }
  261.     }//public static function listPackages($strChannel, $bWorkOffline = false)
  262.  
  263.  
  264.  
  265.  
  266.     /**
  267.     *   Loads all available information for the given packages
  268.     *
  269.     *   @param array    $arRemotePackages   Array with PEAR_Frontend_Gtk2_Package-s
  270.     *   @param string   $strChannel         The channel name to retrieve packages from
  271.     *   @param callback $callback           The callback to call after a package info has been loaded
  272.     *   @param boolean  $bWorkOffline       If the local cache *only* shall be used, or (if no local cache is there)
  273.     *                                            an connection to the internet server shall be made
  274.     *   @param boolean  $bUseCache          If the cache shall be used. If not, the only chance to get package data is
  275.     *                                            reading them from the online server (if $bWorkOffline is false)
  276.     *
  277.     *   @return array   Array of packages (locally installed and remotely available) (PEAR_Frontend_Gtk2_Package)
  278.     *   @static
  279.     */
  280.     public static function loadRemotePackageData($arRemotePackages$strChannel$callback = null$bWorkOffline = false$bUseCache = true)
  281.     {
  282.         $config     = PEAR_Config::singleton();
  283.         $rest10     $config->getREST('1.0');
  284.         $rest       $rest10->_rest;//FIXME: could change in future pear versions
  285.         $channel    $config->getRegistry()->getChannel($strChannel);
  286.         $strBaseUrl $channel->getBaseURL('REST1.0');
  287.  
  288.         $nNumberPackages count($arRemotePackages);
  289.         $nCurrentPackageNumber = 0;
  290.  
  291.         foreach ($arRemotePackages as $strId => $dontuseit{
  292.             if ($callback !== null{
  293.                 call_user_func_array($callbackarray($nNumberPackages++$nCurrentPackageNumber));
  294.             }
  295.             $package $arRemotePackages[$strId];
  296.             $inf = PEAR_Frontend_Gtk2_Packages::retrieveCacheFirst(
  297.                         PEAR_Frontend_Gtk2_Packages::getInfoUrl($strBaseUrl$package->getName()),
  298.                         $config,
  299.                         $rest,
  300.                         $bWorkOffline,
  301.                         $bUseCache
  302.                     );
  303.             if (PEAR::isError($inf)) {
  304.                 if (strpos(strtolower($inf->message)'404 not found'!== false{
  305.                     //FIXME: That is a hack because the error hasn't an error code yet.
  306.                     //We continue because it's an 404 error, maybe the package isn't there yet.
  307.                     //Happens if you installed new packages which haven't been uploaded to the server yet.
  308.                     $package->setCategory($package->guessCategory($package->getName()));
  309.                     continue;
  310.                 }
  311.                 throw new Exception($inf->getMessage());
  312.             }
  313.             if ($inf['ca']['_content'!== null{
  314.                 $package->setCategory(   $inf['ca']['_content']);
  315.             }
  316.             $package->setSummary(    $inf['s']);
  317.             $package->setDescription($inf['d']);
  318.             $package->setLatestVersion(
  319.                 //FIXME: use preferred_state config option
  320.                 PEAR_Frontend_Gtk2_Packages::retrieveCacheFirst(
  321.                     PEAR_Frontend_Gtk2_Packages::getLatestVersionUrl($strBaseUrl$package->getName()),
  322.                     $config,
  323.                     $rest,
  324.                     $bWorkOffline,
  325.                     $bUseCache
  326.                 )
  327.             );
  328.         }
  329.  
  330.         if ($callback !== null{
  331.             call_user_func_array($callbackarray(truetrue));
  332.         }
  333.  
  334.         return $arRemotePackages;
  335.     }//public static function loadRemotePackageData($arRemotePackages, $strChannel, $callback = null, $bWorkOffline = false, $bUseCache = true)
  336.  
  337.  
  338.  
  339.     /**
  340.     *   Copy of the PEAR_REST#retrieveCacheFirst() function with the addition
  341.     *   that one can specify if the cache only shall be loaded, or if the cache
  342.     *   is not available, an connection shall be made.
  343.     *
  344.     *   If the user works offline, and no cache is there, NULL is returned.
  345.     *
  346.     *   @param string       $url            The URL to get the data from
  347.     *   @param PEAR_Config  $config         The PEAR configuration
  348.     *   @param PEAR_REST    $rest           The REST object which can be used to retrieve the data
  349.     *   @param boolean      $bWorkOffline   If the local cache *only* shall be used, or (if no local cache is there)
  350.     *                                            an connection to the internet server shall be made
  351.     *   @param boolean      $bUseCache      If the cache shall be used. If not, the only chance to get package data is
  352.     *                                            reading them from the online server (if $bWorkOffline is false)
  353.     */
  354.     public static function retrieveCacheFirst($url$config$rest$bWorkOffline = false$bUseCache = true)
  355.     {
  356.         if ($bUseCache{
  357.             $cachefile $config->get('cache_dir'. DIRECTORY_SEPARATOR . md5($url'rest.cachefile';
  358.             if (@file_exists($cachefile)) {
  359.                 return unserialize(implode(''file($cachefile)));
  360.             }
  361.         }
  362.         if ($bWorkOffline{
  363.             return null;
  364.         else {
  365.             return $rest->retrieveData($url);
  366.         }
  367.     }//public static function retrieveCacheFirst($url, $config, $rest, $bWorkOffline = false, $bUseCache = true)
  368.  
  369.  
  370.  
  371.  
  372.     /**
  373.     *   Path to info.xml for the specific package
  374.     */
  375.     public static function getInfoUrl($strBaseUrl$strPackageName)
  376.     {
  377.         return $strBaseUrl 'p/' strtolower($strPackageName'/info.xml';
  378.     }//public static function getInfoUrl($strBaseUrl, $strPackageName)
  379.  
  380.  
  381.  
  382.     /**
  383.     *   Path to latest.txt for the specific package
  384.     */
  385.     public static function getLatestVersionUrl($strBaseUrl$strPackageName)
  386.     {
  387.         return $strBaseUrl 'r/' strtolower($strPackageName'/latest.txt';
  388.     }//public static function getLatestVersionUrl($strBaseUrl, $strPackageName)
  389.  
  390.  
  391.  
  392.     /**
  393.     *   Creates an array of categories (strings) of the current
  394.     *   channel server
  395.     *
  396.     *   @param callback $callback       The callback to call when package information is loaded
  397.     *   @param boolean  $bWorkOffline   If the user wants to work offline (don't try to connect to the internet)
  398.     *
  399.     *   @return array   Array of category strings
  400.     */
  401.     public function getCategories($callback = null$bWorkOffline = false)
  402.     {
  403.         if (!isset($this->arCategories[$this->strActiveChannel])) {
  404.             $arPackages $this->getPackages(null$callback$bWorkOffline);
  405.  
  406.             $this->arCategories[$this->strActiveChannel= array();
  407.             if (count($arPackages> 0{
  408.                 foreach ($arPackages as $package{
  409.                     $strCategory $package->getCategory();
  410.                     $this->arCategories[$this->strActiveChannel][$strCategory$strCategory;
  411.                 }
  412.                 natcasesort($this->arCategories[$this->strActiveChannel]);
  413.             }
  414.         }
  415.  
  416.         return $this->arCategories[$this->strActiveChannel];
  417.     }//public function getCategories($callback = null)
  418.  
  419.  
  420.  
  421.     /**
  422.     *   Checks if the packages for the given channel have already been loaded
  423.     *
  424.     *   @param string $strChannel   The channel to check (active channel if null)
  425.     *   @return boolean     true if the packages already have been loaded, false if not
  426.     */
  427.     public function packagesLoaded($strChannel = null)
  428.     {
  429.         if ($strChannel === null{
  430.             $strChannel $this->strActiveChannel;
  431.         }
  432.         return (isset($this->arPackages[$strChannel]&& $this->arPackages[$strChannel!== null);
  433.     }//public function packagesLoaded($strChannel = null)
  434.  
  435.  
  436.  
  437.     /**
  438.     *   Refreshs the package list of the given channel by re-reading
  439.     *   the local package info
  440.     *
  441.     *   @param string   $strChannel     The channel to update. If NULL, the active one is used
  442.     *   @return array   Package list for the given channel
  443.     */
  444.     public function refreshLocalPackages($strChannel = null)
  445.     {
  446.         if ($strChannel === null{
  447.             $strChannel $this->strActiveChannel;
  448.         }
  449.         $this->arPackages[$strChannel= self::getLocalPackages($strChannel$this->arPackages[$strChannel]);
  450.         return $this->arPackages[$strChannel];
  451.     }//public function refreshLocalPackages($strChannel = null)
  452.  
  453.  
  454.  
  455.     /**
  456.     *   Refreshs the package list of the given channel by re-reading the remote
  457.     *   package information.
  458.     *
  459.     *   @param string   $strChannel     The channel to update. If NULL, the active one is used
  460.     *   @return array   Package list for the given channel
  461.     */
  462.     public function refreshRemotePackages($strChannel = null$callback = null)
  463.     {
  464.         if ($strChannel === null{
  465.             $strChannel $this->strActiveChannel;
  466.         }
  467.         $this->arPackages[$strChannel= self::loadRemotePackageData($this->arPackages[$strChannel]$strChannel$callbackfalsefalse);
  468.         return $this->arPackages[$strChannel];
  469.     }//public function refreshRemotePackages($strChannel = null, $callback = null)
  470.  
  471. }//class PEAR_Frontend_Gtk2_Packages
  472. ?>

Documentation generated on Mon, 11 Mar 2019 14:39:44 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.