[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * Joomla! Content Management System 5 * 6 * @copyright (C) 2019 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\Changelog; 11 12 use Joomla\CMS\Http\HttpFactory; 13 use Joomla\CMS\Language\Text; 14 use Joomla\CMS\Log\Log; 15 use Joomla\CMS\Object\CMSObject; 16 use Joomla\CMS\Version; 17 use Joomla\Registry\Registry; 18 use RuntimeException; 19 20 // phpcs:disable PSR1.Files.SideEffects 21 \defined('JPATH_PLATFORM') or die; 22 // phpcs:enable PSR1.Files.SideEffects 23 24 /** 25 * Changelog class. 26 * 27 * @since 4.0.0 28 */ 29 class Changelog extends CMSObject 30 { 31 /** 32 * Update manifest `<element>` element 33 * 34 * @var string 35 * @since 4.0.0 36 */ 37 protected $element; 38 39 /** 40 * Update manifest `<type>` element 41 * 42 * @var string 43 * @since 4.0.0 44 */ 45 protected $type; 46 47 /** 48 * Update manifest `<version>` element 49 * 50 * @var string 51 * @since 4.0.0 52 */ 53 protected $version; 54 55 /** 56 * Update manifest `<security>` element 57 * 58 * @var array 59 * @since 4.0.0 60 */ 61 protected $security = array(); 62 63 /** 64 * Update manifest `<fix>` element 65 * 66 * @var array 67 * @since 4.0.0 68 */ 69 protected $fix = array(); 70 71 /** 72 * Update manifest `<language>` element 73 * 74 * @var array 75 * @since 4.0.0 76 */ 77 protected $language = array(); 78 79 /** 80 * Update manifest `<addition>` element 81 * 82 * @var array 83 * @since 4.0.0 84 */ 85 protected $addition = array(); 86 87 /** 88 * Update manifest `<change>` elements 89 * 90 * @var array 91 * @since 4.0.0 92 */ 93 protected $change = array(); 94 95 /** 96 * Update manifest `<remove>` element 97 * 98 * @var array 99 * @since 4.0.0 100 */ 101 protected $remove = array(); 102 103 /** 104 * Update manifest `<maintainer>` element 105 * 106 * @var array 107 * @since 4.0.0 108 */ 109 protected $note = array(); 110 111 /** 112 * List of node items 113 * 114 * @var array 115 * @since 4.0.0 116 */ 117 private $items = array(); 118 119 /** 120 * Resource handle for the XML Parser 121 * 122 * @var resource 123 * @since 4.0.0 124 */ 125 protected $xmlParser; 126 127 /** 128 * Element call stack 129 * 130 * @var array 131 * @since 4.0.0 132 */ 133 protected $stack = array('base'); 134 135 /** 136 * Object containing the current update data 137 * 138 * @var \stdClass 139 * @since 4.0.0 140 */ 141 protected $currentChangelog; 142 143 /** 144 * The version to match the changelog 145 * 146 * @var string 147 * @since 4.0.0 148 */ 149 private $matchVersion = ''; 150 151 /** 152 * Object containing the latest changelog data 153 * 154 * @var \stdClass 155 * @since 4.0.0 156 */ 157 protected $latest; 158 159 /** 160 * Gets the reference to the current direct parent 161 * 162 * @return string 163 * 164 * @since 4.0.0 165 */ 166 protected function getStackLocation() 167 { 168 return implode('->', $this->stack); 169 } 170 171 /** 172 * Get the last position in stack count 173 * 174 * @return string 175 * 176 * @since 4.0.0 177 */ 178 protected function getLastTag() 179 { 180 return $this->stack[\count($this->stack) - 1]; 181 } 182 183 /** 184 * Set the version to match. 185 * 186 * @param string $version The version to match 187 * 188 * @return void 189 * 190 * @since 4.0.0 191 */ 192 public function setVersion(string $version) 193 { 194 $this->matchVersion = $version; 195 } 196 197 /** 198 * XML Start Element callback 199 * 200 * @param object $parser Parser object 201 * @param string $name Name of the tag found 202 * @param array $attrs Attributes of the tag 203 * 204 * @return void 205 * 206 * @note This is public because it is called externally 207 * @since 1.7.0 208 */ 209 public function startElement($parser, $name, $attrs = array()) 210 { 211 $this->stack[] = $name; 212 $tag = $this->getStackLocation(); 213 214 // Reset the data 215 if (isset($this->$tag)) { 216 $this->$tag->data = ''; 217 } 218 219 $name = strtolower($name); 220 221 if (!isset($this->currentChangelog->$name)) { 222 $this->currentChangelog->$name = new \stdClass(); 223 } 224 225 $this->currentChangelog->$name->data = ''; 226 227 foreach ($attrs as $key => $data) { 228 $key = strtolower($key); 229 $this->currentChangelog->$name->$key = $data; 230 } 231 } 232 233 /** 234 * Callback for closing the element 235 * 236 * @param object $parser Parser object 237 * @param string $name Name of element that was closed 238 * 239 * @return void 240 * 241 * @note This is public because it is called externally 242 * @since 1.7.0 243 */ 244 public function endElement($parser, $name) 245 { 246 array_pop($this->stack); 247 248 switch ($name) { 249 case 'SECURITY': 250 case 'FIX': 251 case 'LANGUAGE': 252 case 'ADDITION': 253 case 'CHANGE': 254 case 'REMOVE': 255 case 'NOTE': 256 $name = strtolower($name); 257 $this->currentChangelog->$name->data = $this->items; 258 $this->items = array(); 259 break; 260 case 'CHANGELOG': 261 if (version_compare($this->currentChangelog->version->data, $this->matchVersion, '==') === true) { 262 $this->latest = $this->currentChangelog; 263 } 264 265 // No version match, empty it 266 $this->currentChangelog = new \stdClass(); 267 break; 268 case 'CHANGELOGS': 269 // If the latest item is set then we transfer it to where we want to 270 if (isset($this->latest)) { 271 foreach (get_object_vars($this->latest) as $key => $val) { 272 $this->$key = $val; 273 } 274 275 unset($this->latest); 276 unset($this->currentChangelog); 277 } elseif (isset($this->currentChangelog)) { 278 // The update might be for an older version of j! 279 unset($this->currentChangelog); 280 } 281 break; 282 } 283 } 284 285 /** 286 * Character Parser Function 287 * 288 * @param object $parser Parser object. 289 * @param object $data The data. 290 * 291 * @return void 292 * 293 * @note This is public because its called externally. 294 * @since 1.7.0 295 */ 296 public function characterData($parser, $data) 297 { 298 $tag = $this->getLastTag(); 299 300 switch ($tag) { 301 case 'ITEM': 302 $this->items[] = $data; 303 break; 304 case 'SECURITY': 305 case 'FIX': 306 case 'LANGUAGE': 307 case 'ADDITION': 308 case 'CHANGE': 309 case 'REMOVE': 310 case 'NOTE': 311 break; 312 default: 313 // Throw the data for this item together 314 $tag = strtolower($tag); 315 316 if (isset($this->currentChangelog->$tag)) { 317 $this->currentChangelog->$tag->data .= $data; 318 } 319 break; 320 } 321 } 322 323 /** 324 * Loads an XML file from a URL. 325 * 326 * @param string $url The URL. 327 * 328 * @return boolean True on success 329 * 330 * @since 4.0.0 331 */ 332 public function loadFromXml($url) 333 { 334 $version = new Version(); 335 $httpOption = new Registry(); 336 $httpOption->set('userAgent', $version->getUserAgent('Joomla', true, false)); 337 338 try { 339 $http = HttpFactory::getHttp($httpOption); 340 $response = $http->get($url); 341 } catch (RuntimeException $e) { 342 $response = null; 343 } 344 345 if ($response === null || $response->code !== 200) { 346 // @todo: Add a 'mark bad' setting here somehow 347 Log::add(Text::sprintf('JLIB_UPDATER_ERROR_EXTENSION_OPEN_URL', $url), Log::WARNING, 'jerror'); 348 349 return false; 350 } 351 352 $this->currentChangelog = new \stdClass(); 353 354 $this->xmlParser = xml_parser_create(''); 355 xml_set_object($this->xmlParser, $this); 356 xml_set_element_handler($this->xmlParser, 'startElement', 'endElement'); 357 xml_set_character_data_handler($this->xmlParser, 'characterData'); 358 359 if (!xml_parse($this->xmlParser, $response->body)) { 360 Log::add( 361 sprintf( 362 'XML error: %s at line %d', 363 xml_error_string(xml_get_error_code($this->xmlParser)), 364 xml_get_current_line_number($this->xmlParser) 365 ), 366 Log::WARNING, 367 'updater' 368 ); 369 370 return false; 371 } 372 373 xml_parser_free($this->xmlParser); 374 375 return true; 376 } 377 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |