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 }