Spade
Mini Shell
PK��[=��'�'collection.phpnu�[���<?php
/**
* @package FrameworkOnFramework
* @subpackage utils
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba
Ltd. All rights reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
* @note This file has been modified by the Joomla! Project and no
longer reflects the original work of its author.
*/
// Protect from unauthorized access
defined('FOF_INCLUDED') or die;
/**
* A helper class to read and parse "collection" update XML files
over the web
*/
class FOFUtilsUpdateCollection
{
/**
* 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']))
{
break;
}
// We can't have a category with an empty ref
if (empty($params['ref']))
{
break;
}
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']))
{
break;
}
// We can't have an extension with an empty type
if (empty($params['type']))
{
break;
}
// We can't have an extension with an empty version
if (empty($params['version']))
{
break;
}
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;
}
/**
* Filters a list of updates, returning only those available for the
* specified platform version $jVersion
*
* @param array $updates An array containing update definitions
(categories or extensions)
* @param string $jVersion Joomla! version to fetch updates for, or
null to use JVERSION
*
* @return array|null The update definition that is compatible, or null
if none is compatible
*/
private function filterListByPlatform($updates, $jVersion = null)
{
// Get the target platform
if (is_null($jVersion))
{
$jVersion = JVERSION;
}
$versionParts = explode('.', $jVersion, 4);
$platformVersionMajor = $versionParts[0];
$platformVersionMinor = (count($versionParts) > 1) ?
$platformVersionMajor . '.' . $versionParts[1] :
$platformVersionMajor;
$platformVersionNormal = (count($versionParts) > 2) ?
$platformVersionMinor . '.' . $versionParts[2] :
$platformVersionMinor;
$platformVersionFull = (count($versionParts) > 3) ?
$platformVersionNormal . '.' . $versionParts[3] :
$platformVersionNormal;
$pickedExtension = null;
$pickedSpecificity = -1;
foreach ($updates as $update)
{
// Test the target platform
$targetPlatform = (string)$update['targetplatformversion'];
if ($targetPlatform === $platformVersionFull)
{
$pickedExtension = $update;
$pickedSpecificity = 4;
}
elseif (($targetPlatform === $platformVersionNormal) &&
($pickedSpecificity <= 3))
{
$pickedExtension = $update;
$pickedSpecificity = 3;
}
elseif (($targetPlatform === $platformVersionMinor) &&
($pickedSpecificity <= 2))
{
$pickedExtension = $update;
$pickedSpecificity = 2;
}
elseif (($targetPlatform === $platformVersionMajor) &&
($pickedSpecificity <= 1))
{
$pickedExtension = $update;
$pickedSpecificity = 1;
}
}
return $pickedExtension;
}
/**
* Returns only the category definitions of a collection
*
* @param string $url The URL of the collection update source
* @param string $jVersion Joomla! version to fetch updates for, or
null to use JVERSION
*
* @return array An array of category update definitions
*/
public function getCategories($url, $jVersion = null)
{
$allUpdates = $this->getAllUpdates($url, $jVersion);
return $allUpdates['categories'];
}
/**
* Returns the update source for a specific category
*
* @param string $url The URL of the collection update source
* @param string $category The category name you want to get the
update source URL of
* @param string $jVersion Joomla! version to fetch updates for, or
null to use JVERSION
*
* @return string|null The update stream URL, or null if it's not
found
*/
public function getCategoryUpdateSource($url, $category, $jVersion = null)
{
$allUpdates = $this->getAllUpdates($url, $jVersion);
if (array_key_exists($category, $allUpdates['categories']))
{
return $allUpdates['categories'][$category]['ref'];
}
else
{
return null;
}
}
/**
* Get a list of updates for extensions only, optionally of a specific
type
*
* @param string $url The URL of the collection update source
* @param string $type The extension type you want to get the
update source URL of, empty to get all
* extension types
* @param string $jVersion Joomla! version to fetch updates for, or
null to use JVERSION
*
* @return array|null An array of extension update definitions or null
if none is found
*/
public function getExtensions($url, $type = null, $jVersion = null)
{
$allUpdates = $this->getAllUpdates($url, $jVersion);
if (empty($type))
{
return $allUpdates['extensions'];
}
elseif (array_key_exists($type, $allUpdates['extensions']))
{
return $allUpdates['extensions'][$type];
}
else
{
return null;
}
}
/**
* Get the update source URL for a specific extension, based on the type
and element, e.g.
* type=file and element=joomla is Joomla! itself.
*
* @param string $url The URL of the collection update source
* @param string $type The extension type you want to get the
update source URL of
* @param string $element The extension element you want to get the
update source URL of
* @param string $jVersion Joomla! version to fetch updates for, or
null to use JVERSION
*
* @return string|null The update source URL or null if the extension is
not found
*/
public function getExtensionUpdateSource($url, $type, $element, $jVersion
= null)
{
$allUpdates = $this->getExtensions($url, $type, $jVersion);
if (empty($allUpdates))
{
return null;
}
elseif (array_key_exists($element, $allUpdates))
{
return $allUpdates[$element]['detailsurl'];
}
else
{
return null;
}
}
}PK��[�
b/5
5
extension.phpnu�[���<?php
/**
* @package FrameworkOnFramework
* @subpackage utils
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba
Ltd. All rights reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
// Protect from unauthorized access
defined('FOF_INCLUDED') or die;
/**
* A helper class to read and parse "extension" update XML files
over the web
*/
class FOFUtilsUpdateExtension
{
/**
* 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;
}
}PK��[kyڰ@�@
joomla.phpnu�[���<?php
/**
* @package FrameworkOnFramework
* @subpackage utils
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba
Ltd. All rights reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
* @note This file has been modified by the Joomla! Project and no
longer reflects the original work of its author.
*/
// Protect from unauthorized access
defined('FOF_INCLUDED') or die;
/**
* A helper class which provides update information for the Joomla! CMS
itself. This is slightly different than the
* regular "extension" files as we need to know if a Joomla!
version is STS, LTS, testing, current and so on.
*/
class FOFUtilsUpdateJoomla extends FOFUtilsUpdateExtension
{
/**
* The source for LTS updates
*
* @var string
*/
protected static $lts_url =
'http://update.joomla.org/core/list.xml';
/**
* The source for STS updates
*
* @var string
*/
protected static $sts_url =
'http://update.joomla.org/core/sts/list_sts.xml';
/**
* The source for test release updates
*
* @var string
*/
protected static $test_url =
'http://update.joomla.org/core/test/list_test.xml';
/**
* 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 CmsupdateHelperCollection();
* $extensionUpdateURL = $collection->getExtensionUpdateSource($url,
'component', 'com_foobar', JVERSION);
* $extension = new CmsupdateHelperExtension();
* $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;
}
/**
* Reads a "collection" XML update source and picks the correct
source URL
* for the extension update source.
*
* @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 string The URL of the extension update source, or empty if no
updates are provided / fetching failed
*/
public function getUpdateSourceFromCollection($url, $jVersion = null)
{
$provider = new FOFUtilsUpdateCollection();
return $provider->getExtensionUpdateSource($url, 'file',
'joomla', $jVersion);
}
/**
* Determines the properties of a version: STS/LTS, normal or testing
*
* @param string $jVersion The version number to check
* @param string $currentVersion The current Joomla! version number
*
* @return array The properties analysis
*/
public function getVersionProperties($jVersion, $currentVersion = null)
{
// Initialise
$ret = array(
'lts' => true,
// Is this an LTS release? False means STS.
'current' => false,
// Is this a release in the $currentVersion branch?
'upgrade' => 'none',
// Upgrade relation of $jVersion to $currentVersion: 'none'
(can't upgrade), 'lts' (next or current LTS),
'sts' (next or current STS) or 'current' (same release,
no upgrade available)
'testing' => false,
// Is this a testing (alpha, beta, RC) release?
);
// Get the current version if none is defined
if (is_null($currentVersion))
{
$currentVersion = JVERSION;
}
// Sanitise version numbers
$sameVersion = $jVersion == $currentVersion;
$jVersion = $this->sanitiseVersion($jVersion);
$currentVersion = $this->sanitiseVersion($currentVersion);
$sameVersion = $sameVersion || ($jVersion == $currentVersion);
// Get the base version
$baseVersion = substr($jVersion, 0, 3);
// Get the minimum and maximum current version numbers
$current_minimum = substr($currentVersion, 0, 3);
$current_maximum = $current_minimum . '.9999';
// Initialise STS/LTS version numbers
$sts_minimum = false;
$sts_maximum = false;
$lts_minimum = false;
// Is it an LTS or STS release?
switch ($baseVersion)
{
case '1.5':
$ret['lts'] = true;
break;
case '1.6':
$ret['lts'] = false;
$sts_minimum = '1.7';
$sts_maximum = '1.7.999';
$lts_minimum = '2.5';
break;
case '1.7':
$ret['lts'] = false;
$sts_minimum = false;
$lts_minimum = '2.5';
break;
case '2.5':
$ret['lts'] = true;
$sts_minimum = false;
$lts_minimum = '2.5';
break;
default:
$majorVersion = (int) substr($jVersion, 0, 1);
//$minorVersion = (int) substr($jVersion, 2, 1);
$ret['lts'] = true;
$sts_minimum = false;
$lts_minimum = $majorVersion . '.0';
break;
}
// Is it a current release?
if (version_compare($jVersion, $current_minimum, 'ge')
&& version_compare($jVersion, $current_maximum, 'le'))
{
$ret['current'] = true;
}
// Is this a testing release?
$versionParts = explode('.', $jVersion);
$lastVersionPart = array_pop($versionParts);
if (in_array(substr($lastVersionPart, 0, 1), array('a',
'b')))
{
$ret['testing'] = true;
}
elseif (substr($lastVersionPart, 0, 2) == 'rc')
{
$ret['testing'] = true;
}
elseif (substr($lastVersionPart, 0, 3) == 'dev')
{
$ret['testing'] = true;
}
// Find the upgrade relation of $jVersion to $currentVersion
if (version_compare($jVersion, $currentVersion, 'eq'))
{
$ret['upgrade'] = 'current';
}
elseif (($sts_minimum !== false) && version_compare($jVersion,
$sts_minimum, 'ge') && version_compare($jVersion,
$sts_maximum, 'le'))
{
$ret['upgrade'] = 'sts';
}
elseif (($lts_minimum !== false) && version_compare($jVersion,
$lts_minimum, 'ge'))
{
$ret['upgrade'] = 'lts';
}
elseif ($baseVersion == $current_minimum)
{
$ret['upgrade'] = $ret['lts'] ? 'lts' :
'sts';
}
else
{
$ret['upgrade'] = 'none';
}
if ($sameVersion)
{
$ret['upgrade'] = 'none';
}
return $ret;
}
/**
* Filters a list of updates, making sure they apply to the specified CMS
* release.
*
* @param array $updates A list of update records returned by the
getUpdatesFromExtension method
* @param string $jVersion The current Joomla! version number
*
* @return array A filtered list of updates. Each update record also
includes version relevance information.
*/
public function filterApplicableUpdates($updates, $jVersion = null)
{
if (empty($jVersion))
{
$jVersion = JVERSION;
}
$versionParts = explode('.', $jVersion, 4);
$platformVersionMajor = $versionParts[0];
$platformVersionMinor = $platformVersionMajor . '.' .
$versionParts[1];
$platformVersionNormal = $platformVersionMinor . '.' .
$versionParts[2];
//$platformVersionFull = (count($versionParts) > 3) ?
$platformVersionNormal . '.' . $versionParts[3] :
$platformVersionNormal;
$ret = array();
foreach ($updates as $update)
{
// Check each update for platform match
if (strtolower($update['targetplatform']['name']) !=
'joomla')
{
continue;
}
$targetPlatformVersion =
$update['targetplatform']['version'];
if (!preg_match('/' . $targetPlatformVersion . '/',
$platformVersionMinor))
{
continue;
}
// Get some information from the version number
$updateVersion = $update['version'];
$versionProperties = $this->getVersionProperties($updateVersion,
$jVersion);
if ($versionProperties['upgrade'] == 'none')
{
continue;
}
// The XML files are ill-maintained. Maybe we already have this update?
if (!array_key_exists($updateVersion, $ret))
{
$ret[ $updateVersion ] = array_merge($update, $versionProperties);
}
}
return $ret;
}
/**
* Joomla! has a lousy track record in naming its alpha, beta and release
* candidate releases. The convention used seems to be "what the hell
the
* current package maintainer thinks looks better". This method tries
to
* figure out what was in the mind of the maintainer and translate the
* funky version number to an actual PHP-format version string.
*
* @param string $version The whatever-format version number
*
* @return string A standard formatted version number
*/
public function sanitiseVersion($version)
{
$test = strtolower($version);
$alphaQualifierPosition = strpos($test, 'alpha-');
$betaQualifierPosition = strpos($test, 'beta-');
$betaQualifierPosition2 = strpos($test, '-beta');
$rcQualifierPosition = strpos($test, 'rc-');
$rcQualifierPosition2 = strpos($test, '-rc');
$rcQualifierPosition3 = strpos($test, 'rc');
$devQualifiedPosition = strpos($test, 'dev');
if ($alphaQualifierPosition !== false)
{
$betaRevision = substr($test, $alphaQualifierPosition + 6);
if (!$betaRevision)
{
$betaRevision = 1;
}
$test = substr($test, 0, $alphaQualifierPosition) . '.a' .
$betaRevision;
}
elseif ($betaQualifierPosition !== false)
{
$betaRevision = substr($test, $betaQualifierPosition + 5);
if (!$betaRevision)
{
$betaRevision = 1;
}
$test = substr($test, 0, $betaQualifierPosition) . '.b' .
$betaRevision;
}
elseif ($betaQualifierPosition2 !== false)
{
$betaRevision = substr($test, $betaQualifierPosition2 + 5);
if (!$betaRevision)
{
$betaRevision = 1;
}
$test = substr($test, 0, $betaQualifierPosition2) . '.b' .
$betaRevision;
}
elseif ($rcQualifierPosition !== false)
{
$betaRevision = substr($test, $rcQualifierPosition + 5);
if (!$betaRevision)
{
$betaRevision = 1;
}
$test = substr($test, 0, $rcQualifierPosition) . '.rc' .
$betaRevision;
}
elseif ($rcQualifierPosition2 !== false)
{
$betaRevision = substr($test, $rcQualifierPosition2 + 3);
if (!$betaRevision)
{
$betaRevision = 1;
}
$test = substr($test, 0, $rcQualifierPosition2) . '.rc' .
$betaRevision;
}
elseif ($rcQualifierPosition3 !== false)
{
$betaRevision = substr($test, $rcQualifierPosition3 + 5);
if (!$betaRevision)
{
$betaRevision = 1;
}
$test = substr($test, 0, $rcQualifierPosition3) . '.rc' .
$betaRevision;
}
elseif ($devQualifiedPosition !== false)
{
$betaRevision = substr($test, $devQualifiedPosition + 6);
if (!$betaRevision)
{
$betaRevision = '';
}
$test = substr($test, 0, $devQualifiedPosition) . '.dev' .
$betaRevision;
}
return $test;
}
/**
* Reloads the list of all updates available for the specified Joomla!
version
* from the network.
*
* @param array $sources The enabled sources to look into
* @param string $jVersion The Joomla! version we are checking updates
for
*
* @return array A list of updates for the installed, current, lts and
sts versions
*/
public function getUpdates($sources = array(), $jVersion = null)
{
// Make sure we have a valid list of sources
if (empty($sources) || !is_array($sources))
{
$sources = array();
}
$defaultSources = array('lts' => true, 'sts' =>
true, 'test' => true, 'custom' => '');
$sources = array_merge($defaultSources, $sources);
// Use the current JVERSION if none is specified
if (empty($jVersion))
{
$jVersion = JVERSION;
}
// Get the current branch' min/max versions
$versionParts = explode('.', $jVersion, 4);
$currentMinVersion = $versionParts[0] . '.' . $versionParts[1];
$currentMaxVersion = $versionParts[0] . '.' . $versionParts[1]
. '.9999';
// Retrieve all updates
$allUpdates = array();
foreach ($sources as $source => $value)
{
if (($value === false) || empty($value))
{
continue;
}
switch ($source)
{
case 'lts':
$url = self::$lts_url;
break;
case 'sts':
$url = self::$sts_url;
break;
case 'test':
$url = self::$test_url;
break;
default:
case 'custom':
$url = $value;
break;
}
$url = $this->getUpdateSourceFromCollection($url, $jVersion);
if (!empty($url))
{
$updates = $this->getUpdatesFromExtension($url);
if (!empty($updates))
{
$applicableUpdates = $this->filterApplicableUpdates($updates,
$jVersion);
if (!empty($applicableUpdates))
{
$allUpdates = array_merge($allUpdates, $applicableUpdates);
}
}
}
}
$ret = array(
// Currently installed version (used to reinstall, if available)
'installed' => array(
'version' => '',
'package' => '',
'infourl' => '',
),
// Current branch
'current' => array(
'version' => '',
'package' => '',
'infourl' => '',
),
// Upgrade to STS release
'sts' => array(
'version' => '',
'package' => '',
'infourl' => '',
),
// Upgrade to LTS release
'lts' => array(
'version' => '',
'package' => '',
'infourl' => '',
),
// Upgrade to LTS release
'test' => array(
'version' => '',
'package' => '',
'infourl' => '',
),
);
foreach ($allUpdates as $update)
{
$sections = array();
if ($update['upgrade'] == 'current')
{
$sections[0] = 'installed';
}
elseif (version_compare($update['version'],
$currentMinVersion, 'ge') &&
version_compare($update['version'], $currentMaxVersion,
'le'))
{
$sections[0] = 'current';
}
else
{
$sections[0] = '';
}
$sections[1] = $update['lts'] ? 'lts' :
'sts';
if ($update['testing'])
{
$sections = array('test');
}
foreach ($sections as $section)
{
if (empty($section))
{
continue;
}
$existingVersionForSection = $ret[ $section ]['version'];
if (empty($existingVersionForSection))
{
$existingVersionForSection = '0.0.0';
}
if (version_compare($update['version'],
$existingVersionForSection, 'ge'))
{
$ret[ $section ]['version'] = $update['version'];
$ret[ $section ]['package'] =
$update['downloads'][0]['url'];
$ret[ $section ]['infourl'] =
$update['infourl']['url'];
}
}
}
// Catch the case when the latest current branch version is the installed
version (up to date site)
if (empty($ret['current']['version']) &&
!empty($ret['installed']['version']))
{
$ret['current'] = $ret['installed'];
}
return $ret;
}
}PK��[�R�R�
update.phpnu�[���<?php
/**
* @package FrameworkOnFramework
* @subpackage utils
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba
Ltd. All rights reserved.
* @license GNU General Public License version 2 or later; see
LICENSE.txt
*/
// Protect from unauthorized access
defined('FOF_INCLUDED') or die;
if (version_compare(JVERSION, '2.5.0', 'lt'))
{
jimport('joomla.updater.updater');
}
/**
* A helper Model to interact with Joomla!'s extensions update feature
*/
class FOFUtilsUpdate extends FOFModel
{
/** @var JUpdater The Joomla! updater object */
protected $updater = null;
/** @var int The extension_id of this component */
protected $extension_id = 0;
/** @var string The currently installed version, as reported by the
#__extensions table */
protected $version = 'dev';
/** @var string The machine readable name of the component e.g.
com_something */
protected $component = 'com_foobar';
/** @var string The human readable name of the component e.g. Your
Component's Name. Used for emails. */
protected $componentDescription = 'Foobar';
/** @var string The URL to the component's update XML stream */
protected $updateSite = null;
/** @var string The name to the component's update site (description
of the update XML stream) */
protected $updateSiteName = null;
/** @var string The extra query to append to (commercial) components'
download URLs */
protected $extraQuery = null;
/** @var string The common parameters' key, used for storing data in
the #__akeeba_common table */
protected $commonKey = 'foobar';
/**
* The common parameters table. It's a simple table with key(VARCHAR)
and value(LONGTEXT) fields.
* Here is an example MySQL CREATE TABLE command to make this kind of
table:
*
* CREATE TABLE `#__akeeba_common` (
* `key` varchar(255) NOT NULL,
* `value` longtext NOT NULL,
* PRIMARY KEY (`key`)
* ) DEFAULT COLLATE utf8_general_ci CHARSET=utf8;
*
* @var string
*/
protected $commonTable = '#__akeeba_common';
/**
* Subject of the component update emails
*
* @var string
*/
protected $updateEmailSubject = 'THIS EMAIL IS SENT FROM YOUR SITE
"[SITENAME]" - Update available for [COMPONENT], new version
[VERSION]';
/**
* Body of the component update email
*
* @var string
*/
protected $updateEmailBody= <<< ENDBLOCK
This email IS NOT sent by the authors of [COMPONENT].
It is sent automatically by your own site, [SITENAME].
================================================================================
UPDATE INFORMATION
================================================================================
Your site has determined that there is an updated version of [COMPONENT]
available for download.
New version number: [VERSION]
This email is sent to you by your site to remind you of this fact. The
authors
of the software will never contact you about available updates.
================================================================================
WHY AM I RECEIVING THIS EMAIL?
================================================================================
This email has been automatically sent by a CLI script or Joomla! plugin
you, or
the person who built or manages your site, has installed and explicitly
activated. This script or plugin looks for updated versions of the software
and
sends an email notification to all Super Users. You will receive several
similar
emails from your site, up to 6 times per day, until you either update the
software or disable these emails.
To disable these emails, please contact your site administrator.
If you do not understand what this means, please do not contact the authors
of
the software. They are NOT sending you this email and they cannot help you.
Instead, please contact the person who built or manages your site.
================================================================================
WHO SENT ME THIS EMAIL?
================================================================================
This email is sent to you by your own site, [SITENAME]
ENDBLOCK;
/**
* Public constructor. Initialises the protected members as well. Useful
$config keys:
* update_component The component name, e.g. com_foobar
* update_version The default version if the manifest cache is unreadable
* update_site The URL to the component's update XML stream
* update_extraquery The extra query to append to (commercial)
components' download URLs
* update_sitename The update site's name (description)
*
* @param array $config
*/
public function __construct($config = array())
{
parent::__construct($config);
// Get an instance of the updater class
$this->updater = JUpdater::getInstance();
// Get the component name
if (isset($config['update_component']))
{
$this->component = $config['update_component'];
}
else
{
$this->component = $this->input->getCmd('option',
'');
}
// Get the component description
if (isset($config['update_component_description']))
{
$this->component = $config['update_component_description'];
}
else
{
// Try to auto-translate (hopefully you've loaded the language
files)
$key = strtoupper($this->component);
$description = JText::_($key);
}
// Get the component version
if (isset($config['update_version']))
{
$this->version = $config['update_version'];
}
// Get the common key
if (isset($config['common_key']))
{
$this->commonKey = $config['common_key'];
}
else
{
// Convert com_foobar, pkg_foobar etc to "foobar"
$this->commonKey = substr($this->component, 4);
}
// Get the update site
if (isset($config['update_site']))
{
$this->updateSite = $config['update_site'];
}
// Get the extra query
if (isset($config['update_extraquery']))
{
$this->extraQuery = $config['update_extraquery'];
}
// Get the update site's name
if (isset($config['update_sitename']))
{
$this->updateSiteName = $config['update_sitename'];
}
// Find the extension ID
$db = FOFPlatform::getInstance()->getDbo();
$query = $db->getQuery(true)
->select('*')
->from($db->qn('#__extensions'))
->where($db->qn('type') . ' = ' .
$db->q('component'))
->where($db->qn('element') . ' = ' .
$db->q($this->component));
$db->setQuery($query);
$extension = $db->loadObject();
if (is_object($extension))
{
$this->extension_id = $extension->extension_id;
$data = json_decode($extension->manifest_cache, true);
if (isset($data['version']))
{
$this->version = $data['version'];
}
}
}
/**
* Retrieves the update information of the component, returning an array
with the following keys:
*
* hasUpdate True if an update is available
* version The version of the available update
* infoURL The URL to the download page of the update
*
* @param bool $force Set to true if you want to forcibly
reload the update information
* @param string $preferredMethod Preferred update method:
'joomla' or 'classic'
*
* @return array See the method description for more information
*/
public function getUpdates($force = false, $preferredMethod = null)
{
// Default response (no update)
$updateResponse = array(
'hasUpdate' => false,
'version' => '',
'infoURL' => '',
'downloadURL' => '',
);
if (empty($this->extension_id))
{
return $updateResponse;
}
$updateRecord = $this->findUpdates($force, $preferredMethod);
// If we have an update record in the database return the information
found there
if (is_object($updateRecord))
{
$updateResponse = array(
'hasUpdate' => true,
'version' => $updateRecord->version,
'infoURL' => $updateRecord->infourl,
'downloadURL' => $updateRecord->downloadurl,
);
}
return $updateResponse;
}
/**
* Find the available update record object. If we're at the latest
version it will return null.
*
* Please see getUpdateMethod for information on how the $preferredMethod
is handled and what it means.
*
* @param bool $force Should I forcibly reload the updates
from the server?
* @param string $preferredMethod Preferred update method:
'joomla' or 'classic'
*
* @return \stdClass|null
*/
public function findUpdates($force, $preferredMethod = null)
{
$preferredMethod = $this->getUpdateMethod($preferredMethod);
switch ($preferredMethod)
{
case 'joomla':
return $this->findUpdatesJoomla($force);
break;
default:
case 'classic':
return $this->findUpdatesClassic($force);
break;
}
}
/**
* Gets the update site Ids for our extension.
*
* @return mixed An array of Ids or null if the query failed.
*/
public function getUpdateSiteIds()
{
$db = FOFPlatform::getInstance()->getDbo();
$query = $db->getQuery(true)
->select($db->qn('update_site_id'))
->from($db->qn('#__update_sites_extensions'))
->where($db->qn('extension_id') . ' = ' .
$db->q($this->extension_id));
$db->setQuery($query);
$updateSiteIds = $db->loadColumn(0);
return $updateSiteIds;
}
/**
* Get the currently installed version as reported by the #__extensions
table
*
* @return string
*/
public function getVersion()
{
return $this->version;
}
/**
* Returns the name of the component, e.g. com_foobar
*
* @return string
*/
public function getComponentName()
{
return $this->component;
}
/**
* Returns the human readable component name, e.g. Foobar Component
*
* @return string
*/
public function getComponentDescription()
{
return $this->componentDescription;
}
/**
* Returns the numeric extension ID for the component
*
* @return int
*/
public function getExtensionId()
{
return $this->extension_id;
}
/**
* Returns the update site URL, i.e. the URL to the XML update stream
*
* @return string
*/
public function getUpdateSite()
{
return $this->updateSite;
}
/**
* Returns the human readable description of the update site
*
* @return string
*/
public function getUpdateSiteName()
{
return $this->updateSiteName;
}
/**
* Override the currently installed version as reported by the
#__extensions table
*
* @param string $version
*/
public function setVersion($version)
{
$this->version = $version;
}
/**
* Refreshes the Joomla! update sites for this extension as needed
*
* @return void
*/
public function refreshUpdateSite()
{
// Joomla! 1.5 does not have update sites.
if (version_compare(JVERSION, '1.6.0', 'lt'))
{
return;
}
if (empty($this->extension_id))
{
return;
}
// Remove obsolete update sites that don't match our extension ID
but match our name or update site location
$this->removeObsoleteUpdateSites();
// Create the update site definition we want to store to the database
$update_site = array(
'name' => $this->updateSiteName,
'type' => 'extension',
'location' => $this->updateSite,
'enabled' => 1,
'last_check_timestamp' => 0,
'extra_query' => $this->extraQuery
);
// Get a reference to the db driver
$db = FOFPlatform::getInstance()->getDbo();
// Get the #__update_sites columns
$columns = $db->getTableColumns('#__update_sites', true);
if (version_compare(JVERSION, '3.2.0', 'lt') ||
!array_key_exists('extra_query', $columns))
{
unset($update_site['extra_query']);
}
if (version_compare(JVERSION, '2.5.0', 'lt') ||
!array_key_exists('extra_query', $columns))
{
unset($update_site['last_check_timestamp']);
}
// Get the update sites for our extension
$updateSiteIds = $this->getUpdateSiteIds();
if (empty($updateSiteIds))
{
$updateSiteIds = array();
}
/** @var boolean $needNewUpdateSite Do I need to create a new update
site? */
$needNewUpdateSite = true;
/** @var int[] $deleteOldSites Old Site IDs to delete */
$deleteOldSites = array();
// Loop through all update sites
foreach ($updateSiteIds as $id)
{
$query = $db->getQuery(true)
->select('*')
->from($db->qn('#__update_sites'))
->where($db->qn('update_site_id') . ' = ' .
$db->q($id));
$db->setQuery($query);
$aSite = $db->loadObject();
if (empty($aSite))
{
// Update site is now up-to-date, don't need to refresh it
anymore.
continue;
}
// We have an update site that looks like ours
if ($needNewUpdateSite && ($aSite->name ==
$update_site['name']) && ($aSite->location ==
$update_site['location']))
{
$needNewUpdateSite = false;
$mustUpdate = false;
// Is it enabled? If not, enable it.
if (!$aSite->enabled)
{
$mustUpdate = true;
$aSite->enabled = 1;
}
// Do we have the extra_query property (J 3.2+) and does it match?
if (property_exists($aSite, 'extra_query') &&
isset($update_site['extra_query'])
&& ($aSite->extra_query !=
$update_site['extra_query']))
{
$mustUpdate = true;
$aSite->extra_query = $update_site['extra_query'];
}
// Update the update site if necessary
if ($mustUpdate)
{
$db->updateObject('#__update_sites', $aSite,
'update_site_id', true);
}
continue;
}
// In any other case we need to delete this update site, it's
obsolete
$deleteOldSites[] = $aSite->update_site_id;
}
if (!empty($deleteOldSites))
{
try
{
$obsoleteIDsQuoted = array_map(array($db, 'quote'),
$deleteOldSites);
// Delete update sites
$query = $db->getQuery(true)
->delete('#__update_sites')
->where($db->qn('update_site_id') . ' IN
(' . implode(',', $obsoleteIDsQuoted) . ')');
$db->setQuery($query)->execute();
// Delete update sites to extension ID records
$query = $db->getQuery(true)
->delete('#__update_sites_extensions')
->where($db->qn('update_site_id') . ' IN
(' . implode(',', $obsoleteIDsQuoted) . ')');
$db->setQuery($query)->execute();
}
catch (\Exception $e)
{
// Do nothing on failure
return;
}
}
// Do we still need to create a new update site?
if ($needNewUpdateSite)
{
// No update sites defined. Create a new one.
$newSite = (object)$update_site;
$db->insertObject('#__update_sites', $newSite);
$id = $db->insertid();
$updateSiteExtension = (object)array(
'update_site_id' => $id,
'extension_id' => $this->extension_id,
);
$db->insertObject('#__update_sites_extensions',
$updateSiteExtension);
}
}
/**
* Removes any update sites which go by the same name or the same location
as our update site but do not match the
* extension ID.
*/
public function removeObsoleteUpdateSites()
{
$db = $this->getDbo();
// Get update site IDs
$updateSiteIDs = $this->getUpdateSiteIds();
// Find update sites where the name OR the location matches BUT they are
not one of the update site IDs
$query = $db->getQuery(true)
->select($db->qn('update_site_id'))
->from($db->qn('#__update_sites'))
->where(
'((' . $db->qn('name') . ' = ' .
$db->q($this->updateSiteName) . ') OR ' .
'(' . $db->qn('location') . ' = ' .
$db->q($this->updateSite) . '))'
);
if (!empty($updateSiteIDs))
{
$updateSitesQuoted = array_map(array($db, 'quote'),
$updateSiteIDs);
$query->where($db->qn('update_site_id') . ' NOT IN
(' . implode(',', $updateSitesQuoted) . ')');
}
try
{
$ids = $db->setQuery($query)->loadColumn();
if (!empty($ids))
{
$obsoleteIDsQuoted = array_map(array($db, 'quote'), $ids);
// Delete update sites
$query = $db->getQuery(true)
->delete('#__update_sites')
->where($db->qn('update_site_id') . ' IN
(' . implode(',', $obsoleteIDsQuoted) . ')');
$db->setQuery($query)->execute();
// Delete update sites to extension ID records
$query = $db->getQuery(true)
->delete('#__update_sites_extensions')
->where($db->qn('update_site_id') . ' IN
(' . implode(',', $obsoleteIDsQuoted) . ')');
$db->setQuery($query)->execute();
}
}
catch (\Exception $e)
{
// Do nothing on failure
return;
}
}
/**
* Get the update method we should use, 'joomla' or
'classic'
*
* You can defined the preferred update method: 'joomla' uses
JUpdater whereas 'classic' handles update caching and
* parsing internally. If you are on Joomla! 3.1 or earlier this option is
forced to 'classic' since these old
* Joomla! versions couldn't handle updates of commercial components
correctly (that's why I contributed the fix to
* that problem, the extra_query field that's present in Joomla! 3.2
onwards).
*
* If 'classic' is defined then it will be used in *all* Joomla!
versions. It's the most stable method for fetching
* update information.
*
* @param string $preferred Preferred update method. One of
'joomla' or 'classic'.
*
* @return string
*/
public function getUpdateMethod($preferred = null)
{
$method = $preferred;
// Make sure the update fetch method is valid, otherwise load the
component's "update_method" parameter.
$validMethods = array('joomla', 'classic');
if (!in_array($method, $validMethods))
{
$method =
FOFUtilsConfigHelper::getComponentConfigurationValue($this->component,
'update_method', 'joomla');
}
// We can't handle updates using Joomla!'s extensions updater
in Joomla! 3.1 and earlier
if (($method == 'joomla') && version_compare(JVERSION,
'3.2.0', 'lt'))
{
$method = 'classic';
}
return $method;
}
/**
* Find the available update record object. If we're at the latest
version it will return null.
*
* @param bool $force Should I forcibly reload the updates from the
server?
*
* @return \stdClass|null
*/
protected function findUpdatesJoomla($force = false)
{
$db = FOFPlatform::getInstance()->getDbo();
// If we are forcing the reload, set the last_check_timestamp to 0
// and remove cached component update info in order to force a reload
if ($force)
{
// Find the update site IDs
$updateSiteIds = $this->getUpdateSiteIds();
if (empty($updateSiteIds))
{
return null;
}
// Set the last_check_timestamp to 0
if (version_compare(JVERSION, '2.5.0', 'ge'))
{
$query = $db->getQuery(true)
->update($db->qn('#__update_sites'))
->set($db->qn('last_check_timestamp') . ' =
' . $db->q('0'))
->where($db->qn('update_site_id') .' IN
('.implode(', ', $updateSiteIds).')');
$db->setQuery($query);
$db->execute();
}
// Remove cached component update info from #__updates
$query = $db->getQuery(true)
->delete($db->qn('#__updates'))
->where($db->qn('update_site_id') .' IN
('.implode(', ', $updateSiteIds).')');
$db->setQuery($query);
$db->execute();
}
// Use the update cache timeout specified in com_installer
$timeout = 3600 *
FOFUtilsConfigHelper::getComponentConfigurationValue('com_installer',
'cachetimeout', '6');
// Load any updates from the network into the #__updates table
$this->updater->findUpdates($this->extension_id, $timeout);
// Get the update record from the database
$query = $db->getQuery(true)
->select('*')
->from($db->qn('#__updates'))
->where($db->qn('extension_id') . ' = ' .
$db->q($this->extension_id));
$db->setQuery($query);
try
{
$updateObject = $db->loadObject();
}
catch (Exception $e)
{
return null;
}
if (!is_object($updateObject))
{
return null;
}
$updateObject->downloadurl = '';
JLoader::import('joomla.updater.update');
if (class_exists('JUpdate'))
{
$update = new JUpdate();
$update->loadFromXML($updateObject->detailsurl);
if (isset($update->get('downloadurl')->_data))
{
$url = trim($update->downloadurl->_data);
$extra_query = isset($updateObject->extra_query) ?
$updateObject->extra_query : $this->extraQuery;
if ($extra_query)
{
if (strpos($url, '?') === false)
{
$url .= '?';
}
else
{
$url .= '&';
}
$url .= $extra_query;
}
$updateObject->downloadurl = $url;
}
}
return $updateObject;
}
/**
* Find the available update record object. If we're at the latest
version return null.
*
* @param bool $force Should I forcibly reload the updates from the
server?
*
* @return \stdClass|null
*/
protected function findUpdatesClassic($force = false)
{
$allUpdates = $this->loadUpdatesClassic($force);
if (empty($allUpdates))
{
return null;
}
$bestVersion = '0.0.0';
$bestUpdate = null;
$bestUpdateObject = null;
foreach($allUpdates as $update)
{
if (!isset($update['version']))
{
continue;
}
if (version_compare($bestVersion, $update['version'],
'lt'))
{
$bestVersion = $update['version'];
$bestUpdate = $update;
}
}
// If the current version is newer or equal to the best one, unset
it. Otherwise the user will be always prompted to update
if(version_compare($this->version, $bestVersion,
'ge'))
{
$bestUpdate = null;
$bestVersion = '0.0.0';
}
if (!is_null($bestUpdate))
{
$url = '';
if (isset($bestUpdate['downloads']) &&
isset($bestUpdate['downloads'][0])
&&
isset($bestUpdate['downloads'][0]['url']))
{
$url = $bestUpdate['downloads'][0]['url'];
}
if ($this->extraQuery)
{
if (strpos($url, '?') === false)
{
$url .= '?';
}
else
{
$url .= '&';
}
$url .= $this->extraQuery;
}
$bestUpdateObject = (object)array(
'update_id' => 0,
'update_site_id' => 0,
'extension_id' => $this->extension_id,
'name' => $this->updateSiteName,
'description' => $bestUpdate['description'],
'element' => $bestUpdate['element'],
'type' => $bestUpdate['type'],
'folder' =>
count($bestUpdate['folder']) ? $bestUpdate['folder'][0]
: '',
'client_id' =>
isset($bestUpdate['client']) ? $bestUpdate['client'] :
0,
'version' => $bestUpdate['version'],
'data' => '',
'detailsurl' => $this->updateSite,
'infourl' =>
$bestUpdate['infourl']['url'],
'extra_query' => $this->extraQuery,
'downloadurl' => $url,
);
}
return $bestUpdateObject;
}
/**
* Load all available updates without going through JUpdate
*
* @param bool $force Should I forcibly reload the updates from the
server?
*
* @return array
*/
protected function loadUpdatesClassic($force = false)
{
// Is the cache busted? If it is I set $force = true to make sure I
download fresh updates
if (!$force)
{
// Get the cache timeout. On older Joomla! installations it will always
default to 6 hours.
$timeout = 3600 *
FOFUtilsConfigHelper::getComponentConfigurationValue('com_installer',
'cachetimeout', '6');
// Do I need to check for updates?
$lastCheck = $this->getCommonParameter('lastcheck', 0);
$now = time();
if (($now - $lastCheck) >= $timeout)
{
$force = true;
}
}
// Get the cached JSON-encoded updates list
$rawUpdates = $this->getCommonParameter('allUpdates',
'');
// Am I forced to reload the XML file (explicitly or because the cache is
busted)?
if ($force)
{
// Set the timestamp
$now = time();
$this->setCommonParameter('lastcheck', $now);
// Get all available updates
$updateHelper = new FOFUtilsUpdateExtension();
$updates =
$updateHelper->getUpdatesFromExtension($this->updateSite);
// Save the raw updates list in the database
$rawUpdates = json_encode($updates);
$this->setCommonParameter('allUpdates', $rawUpdates);
}
// Decode the updates list
$updates = json_decode($rawUpdates, true);
// Walk through the updates and find the ones compatible with our Joomla!
and PHP version
$compatibleUpdates = array();
// Get the Joomla! version family (e.g. 2.5)
$jVersion = JVERSION;
$jVersionParts = explode('.', $jVersion);
$jVersionShort = $jVersionParts[0] . '.' . $jVersionParts[1];
// Get the PHP version family (e.g. 5.6)
$phpVersion = PHP_VERSION;
$phpVersionParts = explode('.', $phpVersion);
$phpVersionShort = $phpVersionParts[0] . '.' .
$phpVersionParts[1];
foreach ($updates as $update)
{
// No platform?
if (!isset($update['targetplatform']))
{
continue;
}
// Wrong platform?
if ($update['targetplatform']['name'] !=
'joomla')
{
continue;
}
// Get the target Joomla! version
$targetJoomlaVersion =
$update['targetplatform']['version'];
$targetVersionParts = explode('.', $targetJoomlaVersion);
$targetVersionShort = $targetVersionParts[0] . '.' .
$targetVersionParts[1];
// The target version MUST be in the same Joomla! branch
if ($jVersionShort != $targetVersionShort)
{
continue;
}
// If the target version is major.minor.revision we must make sure our
current JVERSION is AT LEAST equal to that.
if (version_compare($targetJoomlaVersion, JVERSION, 'gt'))
{
continue;
}
// Do I have target PHP versions?
if (isset($update['ars-phpcompat']))
{
$phpCompatible = false;
foreach ($update['ars-phpcompat'] as $entry)
{
// Get the target PHP version family
$targetPHPVersion =
$entry['@attributes']['version'];
$targetPHPVersionParts = explode('.', $targetPHPVersion);
$targetPHPVersionShort = $targetPHPVersionParts[0] . '.' .
$targetPHPVersionParts[1];
// The target PHP version MUST be in the same PHP branch
if ($phpVersionShort != $targetPHPVersionShort)
{
continue;
}
// If the target version is major.minor.revision we must make sure our
current PHP_VERSION is AT LEAST equal to that.
if (version_compare($targetPHPVersion, PHP_VERSION, 'gt'))
{
continue;
}
$phpCompatible = true;
break;
}
if (!$phpCompatible)
{
continue;
}
}
// All checks pass. Add this update to the list of compatible updates.
$compatibleUpdates[] = $update;
}
return $compatibleUpdates;
}
/**
* Get a common parameter from the #__akeeba_common table
*
* @param string $key The key to retrieve
* @param mixed $default The default value in case none is set
*
* @return mixed The saved parameter value (or $default, if nothing is
currently set)
*/
protected function getCommonParameter($key, $default = null)
{
$dbKey = $this->commonKey . '_autoupdate_' . $key;
$db = FOFPlatform::getInstance()->getDbo();
$query = $db->getQuery(true)
->select($db->qn('value'))
->from($db->qn($this->commonTable))
->where($db->qn('key') . ' = ' .
$db->q($dbKey));
$result = $db->setQuery($query)->loadResult();
if (!$result)
{
return $default;
}
return $result;
}
/**
* Set a common parameter from the #__akeeba_common table
*
* @param string $key The key to set
* @param mixed $value The value to set
*
* @return void
*/
protected function setCommonParameter($key, $value)
{
$dbKey = $this->commonKey . '_autoupdate_' . $key;
$db = FOFPlatform::getInstance()->getDbo();
$query = $db->getQuery(true)
->select('COUNT(*)')
->from($db->qn($this->commonTable))
->where($db->qn('key') . ' = ' .
$db->q($dbKey));
$count = $db->setQuery($query)->loadResult();
if ($count)
{
$query = $db->getQuery(true)
->update($db->qn($this->commonTable))
->set($db->qn('value') . ' = ' .
$db->q($value))
->where($db->qn('key') . ' = ' .
$db->q($dbKey));
$db->setQuery($query)->execute();
}
else
{
$data = (object)array(
'key' => $dbKey,
'value' => $value,
);
$db->insertObject($this->commonTable, $data);
}
}
/**
* Proxy to updateComponent(). Required since old versions of our software
had an updateComponent method declared
* private. If we set the updateComponent() method public we cause a fatal
error.
*
* @return string
*/
public function doUpdateComponent()
{
return $this->updateComponent();
}
/**
* Automatically install the extension update under Joomla! 1.5.5 or later
(web) / 3.0 or later (CLI).
*
* @return string The update message
*/
private function updateComponent()
{
$isCli = FOFPlatform::getInstance()->isCli();
$minVersion = $isCli ? '3.0.0' : '1.5.5';
$errorQualifier = $isCli ? ' using an unattended CLI CRON script
' : ' ';
if (version_compare(JVERSION, $minVersion, 'lt'))
{
return "Extension updates{$errorQualifier}only work with Joomla!
$minVersion and later.";
}
try
{
$updatePackagePath = $this->downloadUpdate();
}
catch (Exception $e)
{
return $e->getMessage();
}
// Unpack the downloaded package file
jimport('joomla.installer.helper');
jimport('cms.installer.helper');
$package = JInstallerHelper::unpack($updatePackagePath);
if (!$package)
{
// Clean up
if (JFile::exists($updatePackagePath))
{
JFile::delete($updatePackagePath);
}
return "An error occurred while unpacking the file. Please double
check your Joomla temp-directory setting in Global Configuration.";
}
$installer = new JInstaller;
$installed = $installer->install($package['extractdir']);
// Let's cleanup the downloaded archive and the temp folder
if (JFolder::exists($package['extractdir']))
{
JFolder::delete($package['extractdir']);
}
if (JFile::exists($package['packagefile']))
{
JFile::delete($package['packagefile']);
}
if ($installed)
{
return "Component successfully updated";
}
else
{
return "An error occurred while trying to update the
component";
}
}
/**
* 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;
}
/**
* Gets a file name out of a url
*
* @param string $url URL to get name from
*
* @return mixed String filename or boolean false if failed
*/
private function getFilenameFromURL($url)
{
if (is_string($url))
{
$parts = explode('/', $url);
return $parts[count($parts) - 1];
}
return false;
}
/**
* Proxy to sendNotificationEmail(). Required since old versions of our
software had a sendNotificationEmail method
* declared private. If we set the sendNotificationEmail() method public
we cause a fatal error.
*
* @param string $version The new version of our software
* @param string $email The email address to send the notification
to
*
* @return mixed The result of JMail::send()
*/
public function doSendNotificationEmail($version, $email)
{
try
{
return $this->sendNotificationEmail($version, $email);
}
catch (\Exception $e)
{
// Joomla! 3.5 is buggy
}
}
/**
* Sends an update notification email
*
* @param string $version The new version of our software
* @param string $email The email address to send the notification
to
*
* @return mixed The result of JMail::send()
*/
private function sendNotificationEmail($version, $email)
{
$email_subject = $this->updateEmailSubject;
$email_body = $this->updateEmailBody;
$jconfig = JFactory::getConfig();
$sitename = $jconfig->get('sitename');
$substitutions = array(
'[VERSION]' => $version,
'[SITENAME]' => $sitename,
'[COMPONENT]' => $this->componentDescription,
);
$email_subject = str_replace(array_keys($substitutions),
array_values($substitutions), $email_subject);
$email_body = str_replace(array_keys($substitutions),
array_values($substitutions), $email_body);
$mailer = JFactory::getMailer();
$mailfrom = $jconfig->get('mailfrom');
$fromname = $jconfig->get('fromname');
$mailer->setSender(array( $mailfrom, $fromname ));
$mailer->addRecipient($email);
$mailer->setSubject($email_subject);
$mailer->setBody($email_body);
return $mailer->Send();
}
}
PK��[=��'�'collection.phpnu�[���PK��[�
b/5
5
�'extension.phpnu�[���PK��[kyڰ@�@
H5joomla.phpnu�[���PK��[�R�R�
2vupdate.phpnu�[���PK/��