1 <?php
  2 /**
  3  * @package     FrameworkOnFramework
  4  * @subpackage  utils
  5  * @copyright   Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
  6  * @license     GNU General Public License version 2 or later; see LICENSE.txt
  7  */
  8 
  9 // Protect from unauthorized access
 10 defined('FOF_INCLUDED') or die;
 11 
 12 /**
 13  * A helper class to read and parse "extension" update XML files over the web
 14  */
 15 class FOFUtilsUpdateExtension
 16 {
 17     /**
 18      * Reads an "extension" XML update source and returns all listed update entries.
 19      *
 20      * If you have a "collection" XML update source you should do something like this:
 21      * $collection = new FOFUtilsUpdateCollection();
 22      * $extensionUpdateURL = $collection->getExtensionUpdateSource($url, 'component', 'com_foobar', JVERSION);
 23      * $extension = new FOFUtilsUpdateExtension();
 24      * $updates = $extension->getUpdatesFromExtension($extensionUpdateURL);
 25      *
 26      * @param   string  $url  The extension XML update source URL to read from
 27      *
 28      * @return  array  An array of update entries
 29      */
 30     public function getUpdatesFromExtension($url)
 31     {
 32         // Initialise
 33         $ret = array();
 34 
 35         // Get and parse the XML source
 36         $downloader = new FOFDownload();
 37         $xmlSource = $downloader->getFromURL($url);
 38 
 39         try
 40         {
 41             $xml = new SimpleXMLElement($xmlSource, LIBXML_NONET);
 42         }
 43         catch(Exception $e)
 44         {
 45             return $ret;
 46         }
 47 
 48         // Sanity check
 49         if (($xml->getName() != 'updates'))
 50         {
 51             unset($xml);
 52 
 53             return $ret;
 54         }
 55 
 56         // Let's populate the list of updates
 57         /** @var SimpleXMLElement $update */
 58         foreach ($xml->children() as $update)
 59         {
 60             // Sanity check
 61             if ($update->getName() != 'update')
 62             {
 63                 continue;
 64             }
 65 
 66             $entry = array(
 67                 'infourl'           => array('title' => '', 'url' => ''),
 68                 'downloads'         => array(),
 69                 'tags'              => array(),
 70                 'targetplatform'    => array(),
 71             );
 72 
 73             $properties = get_object_vars($update);
 74 
 75             foreach ($properties as $nodeName => $nodeContent)
 76             {
 77                 switch ($nodeName)
 78                 {
 79                     default:
 80                         $entry[$nodeName] = $nodeContent;
 81                         break;
 82 
 83                     case 'infourl':
 84                     case 'downloads':
 85                     case 'tags':
 86                     case 'targetplatform':
 87                         break;
 88                 }
 89             }
 90 
 91             $infourlNode = $update->xpath('infourl');
 92             $entry['infourl']['title'] = (string)$infourlNode[0]['title'];
 93             $entry['infourl']['url'] = (string)$infourlNode[0];
 94 
 95             $downloadNodes = $update->xpath('downloads/downloadurl');
 96             foreach ($downloadNodes as $downloadNode)
 97             {
 98                 $entry['downloads'][] = array(
 99                     'type'      => (string)$downloadNode['type'],
100                     'format'    => (string)$downloadNode['format'],
101                     'url'       => (string)$downloadNode,
102                 );
103             }
104 
105             $tagNodes = $update->xpath('tags/tag');
106             foreach ($tagNodes as $tagNode)
107             {
108                 $entry['tags'][] = (string)$tagNode;
109             }
110 
111             /** @var SimpleXMLElement $targetPlatformNode */
112             $targetPlatformNode = $update->xpath('targetplatform');
113 
114             $entry['targetplatform']['name'] = (string)$targetPlatformNode[0]['name'];
115             $entry['targetplatform']['version'] = (string)$targetPlatformNode[0]['version'];
116             $client = $targetPlatformNode[0]->xpath('client');
117             $entry['targetplatform']['client'] = (is_array($client) && count($client)) ? (string)$client[0] : '';
118             $folder = $targetPlatformNode[0]->xpath('folder');
119             $entry['targetplatform']['folder'] = is_array($folder) && count($folder) ? (string)$folder[0] : '';
120 
121             $ret[] = $entry;
122         }
123 
124         unset($xml);
125 
126         return $ret;
127     }
128 }