/**
  * Downloads the latest update package to Joomla!'s temporary directory
  *
  * @return  string  The absolute path to the downloaded update package.
  */
 public function downloadUpdate()
 {
     // Get the update URL
     $updateInformation = $this->getUpdates();
     $url = $updateInformation['downloadURL'];
     if (empty($url)) {
         throw new RuntimeException("No download URL was provided in the update information");
     }
     $config = JFactory::getConfig();
     $tmp_dest = $config->get('tmp_path');
     if (!$tmp_dest) {
         throw new RuntimeException("You must set a non-empty Joomla! temp-directory in Global Configuration before continuing.");
     }
     if (!JFolder::exists($tmp_dest)) {
         throw new RuntimeException("Joomla!'s temp-directory does not exist. Please set the correct path in Global Configuration before continuing.");
     }
     // Get the target filename
     $filename = $this->component . '.zip';
     $filename = rtrim($tmp_dest, '\\/') . '/' . $filename;
     try {
         $downloader = new FOFDownload();
         $data = $downloader->getFromURL($url);
     } catch (Exception $e) {
         $code = $e->getCode();
         $message = $e->getMessage();
         throw new RuntimeException("An error occurred while trying to download the update package. Double check your Download ID and your server's network settings. The error message was: #{$code}: {$message}");
     }
     if (!JFile::write($filename, $data)) {
         if (!file_put_contents($filename, $data)) {
             throw new RuntimeException("Joomla!'s temp-directory is not writeable. Please check its permissions or set a different, writeable path in Global Configuration before continuing.");
         }
     }
     return $filename;
 }
 /**
  * Reads a "collection" XML update source and returns the complete tree of categories
  * and extensions applicable for platform version $jVersion
  *
  * @param   string  $url       The collection XML update source URL to read from
  * @param   string  $jVersion  Joomla! version to fetch updates for, or null to use JVERSION
  *
  * @return  array  A list of update sources applicable to $jVersion
  */
 public function getAllUpdates($url, $jVersion = null)
 {
     // Get the target platform
     if (is_null($jVersion)) {
         $jVersion = JVERSION;
     }
     // Initialise return value
     $updates = array('metadata' => array('name' => '', 'description' => ''), 'categories' => array(), 'extensions' => array());
     // Download and parse the XML file
     $donwloader = new FOFDownload();
     $xmlSource = $donwloader->getFromURL($url);
     try {
         $xml = new SimpleXMLElement($xmlSource, LIBXML_NONET);
     } catch (Exception $e) {
         return $updates;
     }
     // Sanity check
     if ($xml->getName() != 'extensionset') {
         unset($xml);
         return $updates;
     }
     // Initialise return value with the stream metadata (name, description)
     $rootAttributes = $xml->attributes();
     foreach ($rootAttributes as $k => $v) {
         $updates['metadata'][$k] = (string) $v;
     }
     // Initialise the raw list of updates
     $rawUpdates = array('categories' => array(), 'extensions' => array());
     // Segregate the raw list to a hierarchy of extension and category entries
     /** @var SimpleXMLElement $extension */
     foreach ($xml->children() as $extension) {
         switch ($extension->getName()) {
             case 'category':
                 // These are the parameters we expect in a category
                 $params = array('name' => '', 'description' => '', 'category' => '', 'ref' => '', 'targetplatformversion' => $jVersion);
                 // These are the attributes of the element
                 $attributes = $extension->attributes();
                 // Merge them all
                 foreach ($attributes as $k => $v) {
                     $params[$k] = (string) $v;
                 }
                 // We can't have a category with an empty category name
                 if (empty($params['category'])) {
                     continue;
                 }
                 // We can't have a category with an empty ref
                 if (empty($params['ref'])) {
                     continue;
                 }
                 if (empty($params['description'])) {
                     $params['description'] = $params['category'];
                 }
                 if (!array_key_exists($params['category'], $rawUpdates['categories'])) {
                     $rawUpdates['categories'][$params['category']] = array();
                 }
                 $rawUpdates['categories'][$params['category']][] = $params;
                 break;
             case 'extension':
                 // These are the parameters we expect in a category
                 $params = array('element' => '', 'type' => '', 'version' => '', 'name' => '', 'detailsurl' => '', 'targetplatformversion' => $jVersion);
                 // These are the attributes of the element
                 $attributes = $extension->attributes();
                 // Merge them all
                 foreach ($attributes as $k => $v) {
                     $params[$k] = (string) $v;
                 }
                 // We can't have an extension with an empty element
                 if (empty($params['element'])) {
                     continue;
                 }
                 // We can't have an extension with an empty type
                 if (empty($params['type'])) {
                     continue;
                 }
                 // We can't have an extension with an empty version
                 if (empty($params['version'])) {
                     continue;
                 }
                 if (empty($params['name'])) {
                     $params['name'] = $params['element'] . ' ' . $params['version'];
                 }
                 if (!array_key_exists($params['type'], $rawUpdates['extensions'])) {
                     $rawUpdates['extensions'][$params['type']] = array();
                 }
                 if (!array_key_exists($params['element'], $rawUpdates['extensions'][$params['type']])) {
                     $rawUpdates['extensions'][$params['type']][$params['element']] = array();
                 }
                 $rawUpdates['extensions'][$params['type']][$params['element']][] = $params;
                 break;
             default:
                 break;
         }
     }
     unset($xml);
     if (!empty($rawUpdates['categories'])) {
         foreach ($rawUpdates['categories'] as $category => $entries) {
             $update = $this->filterListByPlatform($entries, $jVersion);
             $updates['categories'][$category] = $update;
         }
     }
     if (!empty($rawUpdates['extensions'])) {
         foreach ($rawUpdates['extensions'] as $type => $extensions) {
             $updates['extensions'][$type] = array();
             if (!empty($extensions)) {
                 foreach ($extensions as $element => $entries) {
                     $update = $this->filterListByPlatform($entries, $jVersion);
                     $updates['extensions'][$type][$element] = $update;
                 }
             }
         }
     }
     return $updates;
 }
Example #3
0
 /**
  * Reads an "extension" XML update source and returns all listed update entries.
  *
  * If you have a "collection" XML update source you should do something like this:
  * $collection = new FOFUtilsUpdateCollection();
  * $extensionUpdateURL = $collection->getExtensionUpdateSource($url, 'component', 'com_foobar', JVERSION);
  * $extension = new FOFUtilsUpdateExtension();
  * $updates = $extension->getUpdatesFromExtension($extensionUpdateURL);
  *
  * @param   string  $url  The extension XML update source URL to read from
  *
  * @return  array  An array of update entries
  */
 public function getUpdatesFromExtension($url)
 {
     // Initialise
     $ret = array();
     // Get and parse the XML source
     $downloader = new FOFDownload();
     $xmlSource = $downloader->getFromURL($url);
     try {
         $xml = new SimpleXMLElement($xmlSource, LIBXML_NONET);
     } catch (Exception $e) {
         return $ret;
     }
     // Sanity check
     if ($xml->getName() != 'updates') {
         unset($xml);
         return $ret;
     }
     // Let's populate the list of updates
     /** @var SimpleXMLElement $update */
     foreach ($xml->children() as $update) {
         // Sanity check
         if ($update->getName() != 'update') {
             continue;
         }
         $entry = array('infourl' => array('title' => '', 'url' => ''), 'downloads' => array(), 'tags' => array(), 'targetplatform' => array());
         $properties = get_object_vars($update);
         foreach ($properties as $nodeName => $nodeContent) {
             switch ($nodeName) {
                 default:
                     $entry[$nodeName] = $nodeContent;
                     break;
                 case 'infourl':
                 case 'downloads':
                 case 'tags':
                 case 'targetplatform':
                     break;
             }
         }
         $infourlNode = $update->xpath('infourl');
         $entry['infourl']['title'] = (string) $infourlNode[0]['title'];
         $entry['infourl']['url'] = (string) $infourlNode[0];
         $downloadNodes = $update->xpath('downloads/downloadurl');
         foreach ($downloadNodes as $downloadNode) {
             $entry['downloads'][] = array('type' => (string) $downloadNode['type'], 'format' => (string) $downloadNode['format'], 'url' => (string) $downloadNode);
         }
         $tagNodes = $update->xpath('tags/tag');
         foreach ($tagNodes as $tagNode) {
             $entry['tags'][] = (string) $tagNode;
         }
         /** @var SimpleXMLElement $targetPlatformNode */
         $targetPlatformNode = $update->xpath('targetplatform');
         $entry['targetplatform']['name'] = (string) $targetPlatformNode[0]['name'];
         $entry['targetplatform']['version'] = (string) $targetPlatformNode[0]['version'];
         $client = $targetPlatformNode[0]->xpath('client');
         $entry['targetplatform']['client'] = is_array($client) && count($client) ? (string) $client[0] : '';
         $folder = $targetPlatformNode[0]->xpath('folder');
         $entry['targetplatform']['folder'] = is_array($folder) && count($folder) ? (string) $folder[0] : '';
         $ret[] = $entry;
     }
     unset($xml);
     return $ret;
 }