Current Directory: /home/astoriaah/www/old15/administrator/components/com_sh404sef/helpers
Viewing File: /home/astoriaah/www/old15/administrator/components/com_sh404sef/helpers/updates.php
<?php
/**
* sh404SEF - SEO extension for Joomla!
*
* @author Yannick Gaultier
* @copyright (c) Yannick Gaultier 2014
* @package sh404SEF
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL
* @version 4.4.4.1791
* @date 2014-07-01
*/
// Security check to ensure this file is being included by a parent file.
if (!defined('_JEXEC'))
die('Direct Access to this location is not allowed.');
class Sh404sefHelperUpdates
{
private static $_endPoint = 'http://u1.weeblr.com/public/direct/sh404sef/legacy';
private static $_configEndPoint = 'http://u1.weeblr.com/public/direct/sh404sef/config';
private static $_product = 'sh404sef';
private static $_updateFile = 'sh404sef_updates.xml';
private static $_config = 'sh404sef_config.xml';
private static $_devConfig = 'sh404sef_config_dev.xml';
// store whether doing a forced update. Reason to store it
// is to keep _doCheck() method w/o any parameters
// as this would otherwise prevent caching from operating
// normally
private static $_forced = array();
/**
* Obtain update information, as stored in cache
* by checkForUpdates
*
*/
public static function getUpdatesInfos($forced = false)
{
// store whether doing a forced check for updates
self::$_forced['updates'] = $forced;
// get cache object
$cache = JFactory::getCache('sh404sef_updates');
$cache->setLifetime(1440); // cache result for 24 hours
$cache->setCaching(1); // force caching on
// empty cache if we are going to look for updates
if ($forced)
{
// clean our cache
$cache->clean('sh404sef_updates');
}
$response = $cache->call(array('Sh404sefHelperUpdates', '_doCheck'));
// find out whether we should update
$response = self::_updateRequired($response);
// return response, either dummy or from cache
return $response;
}
/**
* Obtain remote configuration info
*
*/
public static function getRemoteConfig($forced = false)
{
// store whether doing a forced check for updates
self::$_forced['rconfig'] = $forced;
// get cache object
$cache = JFactory::getCache('sh404sef_rconfig');
$cache->setLifetime(60); // cache result for an hour
$cache->setCaching(1); // force caching on
// empty cache if we are going to look for updates
if ($forced)
{
// clean our cache
$cache->clean('sh404sef_rconfig');
}
$response = $cache->call(array('Sh404sefHelperUpdates', '_doRemoteConfig'));
// return response, either dummy or from cache
return $response;
}
public static function _doCheck()
{
// if not set to auto check and not forced to do so
// when user click on "check updates" button
// we don't actually try to get updates info
$sefConfig = &Sh404sefFactory::getConfig();
// prepare a default response object
$response = new stdClass();
$response->status = true;
$response->statusMessage = JText::_('COM_SH404SEF_CLICK_TO_CHECK_UPDATES');
$response->current = 0;
$response->note = '';
$response->changelogLink = '';
$response->minVersionToUpgrade = 0;
$response->maxVersionToUpgrade = 0;
$response->shouldUpdate = false;
$response->excludes = array();
// check if allowed to auto check, w/o user clicking on button
if (!$sefConfig->autoCheckNewVersion && empty(self::$_forced['updates']))
{
return $response;
}
// get an http client
$hClient = new Zendshl_Http_Client;
$hClient->setConfig(array('maxredirects' => 0, 'timeout' => 10));
// find where to call ...
$remoteConfig = self::getRemoteConfig($forced = false);
// hardcoded default update server
$defaultServers = array(array('url' => self::$_endPoint . '/' . self::$_updateFile));
// try to read from remote, central, configuration file
$remoteServers = empty($remoteConfig->config['updateservers']) ? array() : $remoteConfig->config['updateservers'];
// merge default and remote
$servers = array_merge($remoteServers, $defaultServers);
// check for urls in both defaults and remote
$serverList = array();
foreach ($servers as $server)
{
if(!empty($server['url']))
{
$serverList[] = JString::trim(($server['url']));
}
}
$serverList = array_unique($serverList);
// now iterate over server list, until we find one that responds
foreach ($serverList as $server)
{
$response->status = true;
// actually place a call to find about available updates
try
{
$hClient->setUri($server);
}
catch (Exception $e)
{
// move to next update server in list
$response->status = false;
continue;
}
// request file content
$adapters = array('Zendshl_Http_Client_Adapter_Curl', 'Zendshl_Http_Client_Adapter_Socket');
$rawResponse = null;
foreach ($adapters as $adapter)
{
try
{
$hClient->setAdapter($adapter);
$rawResponse = $hClient->request();
break;
}
catch (Exception $e)
{
// we failed, let's try another method
}
}
// (un)set flag if we have a response
if (empty($rawResponse))
{
$response->status = false;
$msg = 'unknown code';
$response->statusMessage = JText::sprintf('COM_SH404SEF_COULD_NOT_CHECK_FOR_NEW_VERSION', $msg);
}
else if (!is_object($rawResponse) || $rawResponse->isError())
{
$response->status = false;
$msg = method_exists($rawResponse, 'getStatus') ? $rawResponse->getStatus() : 'unknown code';
$response->statusMessage = JText::sprintf('COM_SH404SEF_COULD_NOT_CHECK_FOR_NEW_VERSION', $msg);
}
else
{
// communication was fine, check the file type
$type = $rawResponse->getHeader('Content-type');
if (strtolower($type) != 'text/xml' && strtolower($type) != 'application/xml')
{
$response->status = false;
$response->statusMessage = JText::sprintf('COM_SH404SEF_COULD_NOT_CHECK_FOR_NEW_VERSION', $rawResponse->getStatus());
}
}
// if there was a valid response, break out of
// loop over available update servers
if ($response->status)
{
break;
}
}
// if we were not able to contact any update server
// return this
if (!$response->status)
{
return $response;
}
try
{
// get an xml object and parse the response
$xml = new SimpleXMLElement($rawResponse->getBody());
// into our response object
// first version of version check used an xml file that could only hold one
// version data set. So we only iterate over the "update" group if it exists
if (empty($xml->update))
{
$response = self::_readUpdateInformation($xml, $response);
}
else
{
foreach ($xml->update as $updateRecord)
{
$product = (string) $updateRecord->product[0];
// only use if this update record is for us
if (strtolower($product) == strtolower(self::$_product))
{
$response = self::_readUpdateInformation($updateRecord, $response);
// find if user should update
$response = self::_updateRequired($response);
// if found an update, break out
if ($response->shouldUpdate)
{
break;
}
}
}
}
}
catch (Exception $e)
{
}
// check if this is a valid information file
return $response;
}
protected static function _readUpdateInformation($updateRecord, $response)
{
$response->current = (string) $updateRecord->current[0];
$response->note = (string) $updateRecord->note[0];
$response->changelogLink = (string) $updateRecord->changelogLink[0];
$response->downloadLink = (string) $updateRecord->downloadLink[0];
$response->minVersionToUpgrade = (string) $updateRecord->minVersionToUpgrade[0];
$response->maxVersionToUpgrade = (string) $updateRecord->maxVersionToUpgrade[0];
$rawExcludes = $updateRecord->exclude;
$response->excludes = array();
if (!empty($rawExcludes))
{
foreach ($rawExcludes as $exclude)
{
$response->excludes[] = (string) $exclude;
}
}
return $response;
}
public static function _doRemoteConfig()
{
// if not set to auto check and not forced to do so
// when user click on "check updates" button
// we don't actually try to get updates info
$sefConfig = &Sh404sefFactory::getConfig();
// prepare a default response object
$response = new stdClass();
$response->status = true;
$response->config = array();
// check if allowed to read central configuration file
if (!$sefConfig->canReadRemoteConfig)
{
return $response;
}
// get an http client
$hClient = new Zendshl_Http_Client;
// request file content
$adapters = array('Zendshl_Http_Client_Adapter_Curl', 'Zendshl_Http_Client_Adapter_Socket');
$rawResponse = null;
foreach ($adapters as $adapter)
{
try
{
// set params
//$hClient->setUri( self::$_configEndPoint . '/' . self::$_devConfig);
$hClient->setUri(self::$_configEndPoint . '/' . self::$_config);
$hClient->setConfig(array('maxredirects' => 0, 'timeout' => 10));
$hClient->setAdapter($adapter);
$rawResponse = $hClient->request();
break;
}
catch (Exception $e)
{
// we failed, let's try another method
}
}
// return if error
if (empty($rawResponse))
{
$response->status = false;
return $response;
}
if (!is_object($rawResponse) || $rawResponse->isError())
{
$response->status = false;
return $response;
}
// check the file
$type = $rawResponse->getHeader('Content-type');
if (strtolower($type) != 'text/xml' && strtolower($type) != 'application/xml')
{
$response->status = false;
return $response;
}
// should be OK then
$response->status = true;
// get an xml object and parse the response
$rawConfig = simplexml_load_string($rawResponse->getBody());
// into our response object
$response->config = array();
if (!empty($rawConfig))
{
foreach ($rawConfig->config as $configName => $configElement)
{
foreach ($configElement as $configKey => $values)
{
if (is_string($values))
{
$response->config[$configKey] = $values;
}
else
{
$counter = 0;
foreach ($values as $arrayName => $arrayValues)
{
$children = $arrayValues->children();
$attr = (string) $arrayValues->attributes();
$id = empty($attr) ? $counter : $attr;
$count = count($children);
if ($count > 0)
{
foreach ($arrayValues as $key => $value)
{
$response->config[$configKey][$id][$key] = (string) $value;
}
}
else
{
$response->config[$configKey][] = (string) $arrayValues;
}
$counter++;
}
}
}
}
}
// check if this is a valid information file
return $response;
}
/**
* Use response object from request to update info server
* to find if an update is required
*
* @param object $response
*/
private static function _updateRequired($response)
{
// get configuration
$sefConfig = &Sh404sefFactory::getConfig();
// compare versions
$response->shouldUpdate = version_compare($sefConfig->version, $response->current, '<');
$response->shouldUpdate = $response->shouldUpdate && version_compare($sefConfig->version, $response->minVersionToUpgrade, 'ge');
$response->shouldUpdate = $response->shouldUpdate
&& (empty($response->maxVersionToUpgrade) || version_compare($sefConfig->version, $response->maxVersionToUpgrade, '<'));
if ($response->shouldUpdate)
{
// check specific versions exclusion list
$response->shouldUpdate = $response->shouldUpdate && !in_array($sefConfig->version, $response->excludes);
}
// build status message based on result of should update calculation
$newVersionText = version_compare(JVERSION, '3.0.0', 'ge') ? 'COM_SH404SEF_NEW_VERSION_AVAILABLE_NO_HTML' : 'COM_SH404SEF_NEW_VERSION_AVAILABLE';
$response->statusMessage = $response->shouldUpdate ? JText::sprintf($newVersionText)
: (JText::sprintf('COM_SH404SEF_YOU_ARE_UP_TO_DATE'));
// return whatever we found
return $response;
}
}