[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/src/Updater/ -> UpdateAdapter.php (source)

   1  <?php
   2  
   3  /**
   4   * Joomla! Content Management System
   5   *
   6   * @copyright  (C) 2008 Open Source Matters, Inc. <https://www.joomla.org>
   7   * @license    GNU General Public License version 2 or later; see LICENSE.txt
   8   */
   9  
  10  namespace Joomla\CMS\Updater;
  11  
  12  use Joomla\CMS\Adapter\AdapterInstance;
  13  use Joomla\CMS\Factory;
  14  use Joomla\CMS\Http\HttpFactory;
  15  use Joomla\CMS\Language\Text;
  16  use Joomla\CMS\Log\Log;
  17  use Joomla\CMS\Version;
  18  use Joomla\Database\ParameterType;
  19  use Joomla\Registry\Registry;
  20  
  21  // phpcs:disable PSR1.Files.SideEffects
  22  \defined('JPATH_PLATFORM') or die;
  23  // phpcs:enable PSR1.Files.SideEffects
  24  
  25  /**
  26   * UpdateAdapter class.
  27   *
  28   * @since  1.7.0
  29   */
  30  abstract class UpdateAdapter extends AdapterInstance
  31  {
  32      /**
  33       * Resource handle for the XML Parser
  34       *
  35       * @var    resource
  36       * @since  3.0.0
  37       */
  38      protected $xmlParser;
  39  
  40      /**
  41       * Element call stack
  42       *
  43       * @var    array
  44       * @since  3.0.0
  45       */
  46      protected $stack = array('base');
  47  
  48      /**
  49       * ID of update site
  50       *
  51       * @var    integer
  52       * @since  3.0.0
  53       */
  54      protected $updateSiteId = 0;
  55  
  56      /**
  57       * Columns in the extensions table to be updated
  58       *
  59       * @var    array
  60       * @since  3.0.0
  61       */
  62      protected $updatecols = array('NAME', 'ELEMENT', 'TYPE', 'FOLDER', 'CLIENT', 'VERSION', 'DESCRIPTION', 'INFOURL', 'CHANGELOGURL', 'EXTRA_QUERY');
  63  
  64      /**
  65       * Should we try appending a .xml extension to the update site's URL?
  66       *
  67       * @var   boolean
  68       */
  69      protected $appendExtension = false;
  70  
  71      /**
  72       * The name of the update site (used in logging)
  73       *
  74       * @var   string
  75       */
  76      protected $updateSiteName = '';
  77  
  78      /**
  79       * The update site URL from which we will get the update information
  80       *
  81       * @var   string
  82       */
  83      protected $_url = '';
  84  
  85      /**
  86       * The minimum stability required for updates to be taken into account. The possible values are:
  87       * 0    dev         Development snapshots, nightly builds, pre-release versions and so on
  88       * 1    alpha       Alpha versions (work in progress, things are likely to be broken)
  89       * 2    beta        Beta versions (major functionality in place, show-stopper bugs are likely to be present)
  90       * 3    rc          Release Candidate versions (almost stable, minor bugs might be present)
  91       * 4    stable      Stable versions (production quality code)
  92       *
  93       * @var    integer
  94       * @since  14.1
  95       *
  96       * @see    Updater
  97       */
  98      protected $minimum_stability = Updater::STABILITY_STABLE;
  99  
 100      /**
 101       * Gets the reference to the current direct parent
 102       *
 103       * @return  string
 104       *
 105       * @since   1.7.0
 106       */
 107      protected function _getStackLocation()
 108      {
 109          return implode('->', $this->stack);
 110      }
 111  
 112      /**
 113       * Gets the reference to the last tag
 114       *
 115       * @return  object
 116       *
 117       * @since   1.7.0
 118       */
 119      protected function _getLastTag()
 120      {
 121          return $this->stack[\count($this->stack) - 1];
 122      }
 123  
 124      /**
 125       * Finds an update
 126       *
 127       * @param   array  $options  Options to use: update_site_id: the unique ID of the update site to look at
 128       *
 129       * @return  array  Update_sites and updates discovered
 130       *
 131       * @since   1.7.0
 132       */
 133      abstract public function findUpdate($options);
 134  
 135      /**
 136       * Toggles the enabled status of an update site. Update sites are disabled before getting the update information
 137       * from their URL and enabled afterwards. If the URL fetch fails with a PHP fatal error (e.g. timeout) the faulty
 138       * update site will remain disabled the next time we attempt to load the update information.
 139       *
 140       * @param   int   $updateSiteId  The numeric ID of the update site to enable/disable
 141       * @param   bool  $enabled       Enable the site when true, disable it when false
 142       *
 143       * @return  void
 144       */
 145      protected function toggleUpdateSite($updateSiteId, $enabled = true)
 146      {
 147          $updateSiteId = (int) $updateSiteId;
 148          $enabled = (bool) $enabled ? 1 : 0;
 149  
 150          if (empty($updateSiteId)) {
 151              return;
 152          }
 153  
 154          $db = $this->parent->getDbo();
 155          $query = $db->getQuery(true)
 156              ->update($db->quoteName('#__update_sites'))
 157              ->set($db->quoteName('enabled') . ' = :enabled')
 158              ->where($db->quoteName('update_site_id') . ' = :id')
 159              ->bind(':enabled', $enabled, ParameterType::INTEGER)
 160              ->bind(':id', $updateSiteId, ParameterType::INTEGER);
 161          $db->setQuery($query);
 162  
 163          try {
 164              $db->execute();
 165          } catch (\RuntimeException $e) {
 166              // Do nothing
 167          }
 168      }
 169  
 170      /**
 171       * Get the name of an update site. This is used in logging.
 172       *
 173       * @param   int  $updateSiteId  The numeric ID of the update site
 174       *
 175       * @return  string  The name of the update site or an empty string if it's not found
 176       */
 177      protected function getUpdateSiteName($updateSiteId)
 178      {
 179          $updateSiteId = (int) $updateSiteId;
 180  
 181          if (empty($updateSiteId)) {
 182              return '';
 183          }
 184  
 185          $db = $this->parent->getDbo();
 186          $query = $db->getQuery(true)
 187              ->select($db->quoteName('name'))
 188              ->from($db->quoteName('#__update_sites'))
 189              ->where($db->quoteName('update_site_id') . ' = :id')
 190              ->bind(':id', $updateSiteId, ParameterType::INTEGER);
 191          $db->setQuery($query);
 192  
 193          $name = '';
 194  
 195          try {
 196              $name = $db->loadResult();
 197          } catch (\RuntimeException $e) {
 198              // Do nothing
 199          }
 200  
 201          return $name;
 202      }
 203  
 204      /**
 205       * Try to get the raw HTTP response from the update site, hopefully containing the update XML.
 206       *
 207       * @param   array  $options  The update options, see findUpdate() in children classes
 208       *
 209       * @return  \Joomla\CMS\Http\Response|bool  False if we can't connect to the site, HTTP Response object otherwise
 210       *
 211       * @throws  \Exception
 212       */
 213      protected function getUpdateSiteResponse($options = array())
 214      {
 215          $url = trim($options['location']);
 216          $this->_url = &$url;
 217          $this->updateSiteId = $options['update_site_id'];
 218  
 219          if (!isset($options['update_site_name'])) {
 220              $options['update_site_name'] = $this->getUpdateSiteName($this->updateSiteId);
 221          }
 222  
 223          $this->updateSiteName  = $options['update_site_name'];
 224          $this->appendExtension = false;
 225  
 226          if (\array_key_exists('append_extension', $options)) {
 227              $this->appendExtension = $options['append_extension'];
 228          }
 229  
 230          if ($this->appendExtension && (substr($url, -4) !== '.xml')) {
 231              if (substr($url, -1) !== '/') {
 232                  $url .= '/';
 233              }
 234  
 235              $url .= 'extension.xml';
 236          }
 237  
 238          // Disable the update site. If the get() below fails with a fatal error (e.g. timeout) the faulty update
 239          // site will remain disabled
 240          $this->toggleUpdateSite($this->updateSiteId, false);
 241  
 242          $startTime = microtime(true);
 243  
 244          $version    = new Version();
 245          $httpOption = new Registry();
 246          $httpOption->set('userAgent', $version->getUserAgent('Joomla', true, false));
 247  
 248          // JHttp transport throws an exception when there's no response.
 249          try {
 250              $http = HttpFactory::getHttp($httpOption);
 251              $response = $http->get($url, array(), 20);
 252          } catch (\RuntimeException $e) {
 253              $response = null;
 254          }
 255  
 256          // Enable the update site. Since the get() returned the update site should remain enabled
 257          $this->toggleUpdateSite($this->updateSiteId, true);
 258  
 259          // Log the time it took to load this update site's information
 260          $endTime    = microtime(true);
 261          $timeToLoad = sprintf('%0.2f', $endTime - $startTime);
 262          Log::add(
 263              "Loading information from update site #{$this->updateSiteId} with name " .
 264              "\"$this->updateSiteName\" and URL $url took $timeToLoad seconds",
 265              Log::INFO,
 266              'updater'
 267          );
 268  
 269          if ($response === null || $response->code !== 200) {
 270              // If the URL is missing the .xml extension, try appending it and retry loading the update
 271              if (!$this->appendExtension && (substr($url, -4) !== '.xml')) {
 272                  $options['append_extension'] = true;
 273  
 274                  return $this->getUpdateSiteResponse($options);
 275              }
 276  
 277              // Log the exact update site name and URL which could not be loaded
 278              Log::add('Error opening url: ' . $url . ' for update site: ' . $this->updateSiteName, Log::WARNING, 'updater');
 279              $app = Factory::getApplication();
 280              $app->enqueueMessage(Text::sprintf('JLIB_UPDATER_ERROR_OPEN_UPDATE_SITE', $this->updateSiteId, $this->updateSiteName, $url), 'warning');
 281  
 282              return false;
 283          }
 284  
 285          return $response;
 286      }
 287  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer