Version checks are now asynchronous

master
Mike Koch 7 years ago
parent 84f491bd40
commit 73b3a01bc0

@ -355,86 +355,121 @@ $modsForHesk_settings = mfh_getSettings();
<td class="text-right">
<?php echo $hesklang['v']; ?>:
</td>
<?php
$cellClass = '';
if ($hesk_settings['check_updates']) {
$latest = hesk_checkVersion();
if ($latest === true) {
$cellClass = 'success';
} elseif ($latest != -1) {
$cellClass = 'warning';
}
}
?>
<td class="pad-right-10 <?php echo $cellClass; ?>">
<td class="pad-right-10" id="hesk-version-status">
<?php echo $hesk_settings['hesk_version']; ?>
<?php
if ($hesk_settings['check_updates']) {
if ($latest === true) {
echo ' - <span class="green">' . $hesklang['hud'] . '</span> ';
} elseif ($latest != -1) {
// Is this a beta/dev version?
if (strpos($hesk_settings['hesk_version'], 'beta') || strpos($hesk_settings['hesk_version'], 'dev') || strpos($hesk_settings['hesk_version'], 'RC')) {
echo ' <span class="dark-orange">' . $hesklang['beta'] . '</span> '; ?> <a
href="https://www.hesk.com/update.php?v=<?php echo $hesk_settings['hesk_version']; ?>"
target="_blank"><?php echo $hesklang['check4updates']; ?></a><?php
} else {
echo ' - <span class="dark-orange bold">' . $hesklang['hnw'] . '</span> '; ?> <a
href="https://www.hesk.com/update.php?v=<?php echo $hesk_settings['hesk_version']; ?>"
target="_blank"><?php echo $hesklang['getup']; ?></a><?php
}
} else {
?> - <a
href="https://www.hesk.com/update.php?v=<?php echo $hesk_settings['hesk_version']; ?>"
target="_blank"><?php echo $hesklang['check4updates']; ?></a><?php
}
} else {
?> - <a
<?php if ($hesk_settings['check_updates']) : ?>
-
<i class="spinner fa fa-spin fa-spinner"></i>
<span class="up-to-date green" style="display: none">
<?php echo $hesklang['hud']; ?>
</span>
<span class="beta-version orange" style="display: none">
<?php echo $hesklang['beta']; ?>
<a href="https://www.hesk.com/update.php?v=<?php echo $hesk_settings['hesk_version']; ?>"
target="_blank"><?php echo $hesklang['check4updates']; ?></a>
</span>
<span class="update-available orange" style="display: none">
<?php echo $hesklang['hnw']; ?>
<a href="https://www.hesk.com/update.php?v=<?php echo $hesk_settings['hesk_version']; ?>"
target="_blank">
<?php echo $hesklang['getup']; ?>
</a>
</span>
<a class="response-error" href="https://www.hesk.com/update.php?v=<?php echo $hesk_settings['hesk_version']; ?>"
target="_blank" style="display: none"><?php echo $hesklang['check4updates']; ?></a>
<script>
var heskUrl = $('p#hesk-path').text();
var $versionStatus = $('#hesk-version-status');
$.ajax({
url: heskUrl + 'api/v1-public/hesk-version',
method: 'GET',
success: function(data) {
if ('<?php echo $hesk_settings['hesk_version']; ?>' === data.version) {
$versionStatus.addClass('success');
$versionStatus.find('.up-to-date').show();
} else if (<?php echo strpos($hesk_settings['hesk_version'], 'beta') ||
strpos($hesk_settings['hesk_version'], 'dev') ||
strpos($hesk_settings['hesk_version'], 'RC') ? 'true' : 'false'; ?>) {
$versionStatus.addClass('warning');
$versionStatus.find('.beta-version').show();
} else {
$versionStatus.addClass('warning');
$versionStatus.find('.update-available').show();
}
},
error: function() {
$versionStatus.find('.response-error').show();
},
complete: function(data) {
$versionStatus.find('.spinner').hide();
}
});
</script>
<?php else: ?>
- <a
href="https://www.hesk.com/update.php?v=<?php echo $hesk_settings['hesk_version']; ?>"
target="_blank"><?php echo $hesklang['check4updates']; ?></a><?php
}
?>
target="_blank"><?php echo $hesklang['check4updates']; ?></a>
<?php endif; ?>
</td>
</tr>
<tr>
<td class="text-right pad-up-5">
<?php echo $hesklang['mods_for_hesk_version']; ?>:
</td>
<?php
$cellClass = '';
if ($hesk_settings['check_updates']) {
$latest = hesk_checkMfhVersion($modsForHeskVersion);
if ($latest === true) {
$cellClass = 'success';
} elseif ($latest != -1) {
$cellClass = 'warning';
}
}
?>
<td class="pad-right-10 pad-up-5 <?php echo $cellClass; ?>">
<td class="pad-right-10 pad-up-5" id="mfh-version-status">
<?php echo $modsForHeskVersion; ?>
<?php
if ($hesk_settings['check_updates']) {
if (strpos($modsForHeskVersion, 'beta') || strpos($modsForHeskVersion, 'dev') || strpos($modsForHeskVersion, 'RC')) {
echo ' <span class="dark-orange">' . $hesklang['beta'] . '</span> '; ?> <a
href="https://mods-for-hesk.mkochcs.com/versioncheck.php?v=<?php echo $modsForHeskVersion; ?>"
target="_blank"><?php echo $hesklang['check4updates']; ?></a><?php
} elseif ($latest === true) {
echo ' - <span class="green">' . $hesklang['mfh_up_to_date'] . '</span>';
} else {
?> - <a href="https://mods-for-hesk.mkochcs.com" target="_blank"
class="orange bold"><?php echo $hesklang['hnw']; ?></a>
<?php
}
} else {
?> - <a
href="https://mods-for-hesk.mkochcs.com/versioncheck.php?version=<?php echo $modsForHeskVersion; ?>"
<?php if ($hesk_settings['check_updates']) : ?>
-
<i class="spinner fa fa-spin fa-spinner"></i>
<span class="up-to-date green" style="display: none">
<?php echo $hesklang['mfh_up_to_date']; ?>
</span>
<span class="beta-version orange" style="display: none">
<?php echo $hesklang['beta']; ?>
<a href="https://www.mods-for-hesk.com/versioncheck.php?v=<?php echo $modsForHeskVersion; ?>"
target="_blank"><?php echo $hesklang['check4updates']; ?></a>
</span>
<span class="update-available" style="display: none">
<a class="orange" href="https://www.mods-for-hesk.com/versioncheck.php?version=<?php echo $hesk_settings['hesk_version']; ?>"
target="_blank">
<?php echo $hesklang['hnw']; ?>
</a>
</span>
<a class="response-error" href="https://www.hesk.com/update.php?version=<?php echo $hesk_settings['hesk_version']; ?>"
target="_blank" style="display: none"><?php echo $hesklang['check4updates']; ?></a>
<?php else: ?>
- <a
href="https://www.mods-for-hesk.com/versioncheck.php?version=<?php echo $modsForHeskVersion; ?>"
target="_blank"><?php echo $hesklang['check4updates']; ?></a>
<?php
}
?>
<?php endif; ?>
<script>
var heskUrl = $('p#hesk-path').text();
var $mfhVersionStatus = $('#mfh-version-status');
$.ajax({
url: heskUrl + 'api/v1-public/mods-for-hesk-version',
method: 'GET',
success: function(data) {
if ('<?php echo $modsForHeskVersion; ?>' === data.version) {
$mfhVersionStatus.addClass('success');
$mfhVersionStatus.find('.up-to-date').show();
} else if (<?php echo strpos($modsForHeskVersion, 'beta') ||
strpos($modsForHeskVersion, 'dev') ||
strpos($modsForHeskVersion, 'RC') ? 'true' : 'false'; ?>) {
$mfhVersionStatus.addClass('warning');
$mfhVersionStatus.find('.beta-version').show();
} else {
$mfhVersionStatus.addClass('warning');
$mfhVersionStatus.find('.update-available').show();
}
},
error: function() {
$mfhVersionStatus.find('.response-error').show();
},
complete: function(data) {
$mfhVersionStatus.find('.spinner').hide();
}
});
</script>
</td>
</tr>
<tr>
@ -3935,130 +3970,6 @@ $modsForHesk_settings = mfh_getSettings();
}
function hesk_checkVersion()
{
global $hesk_settings;
if ($latest = hesk_getLatestVersion()) {
if (strlen($latest) > 12) {
return -1;
} elseif ($latest == $hesk_settings['hesk_version']) {
return true;
} else {
return $latest;
}
} else {
return -1;
}
} // END hesk_checkVersion()
function hesk_getLatestVersion()
{
global $hesk_settings;
// Do we have a cached version file?
if (file_exists(HESK_PATH . $hesk_settings['cache_dir'] . '/__latest.txt')) {
if (preg_match('/^(\d+)\|([\d.]+)+$/', @file_get_contents(HESK_PATH . $hesk_settings['cache_dir'] . '/__latest.txt'), $matches) && (time() - intval($matches[1])) < 3600) {
return $matches[2];
}
}
// No cached file or older than 3600 seconds, try to get an update
$hesk_version_url = 'https://hesk.com/version';
// Try using cURL
if (function_exists('curl_init')) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $hesk_version_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 6);
$latest = curl_exec($ch);
curl_close($ch);
return hesk_cacheLatestVersion($latest);
}
// Try using a simple PHP function instead
if ($latest = @file_get_contents($hesk_version_url)) {
return hesk_cacheLatestVersion($latest);
}
// Can't check automatically, will need a manual check
return false;
} // END hesk_getLatestVersion()
function hesk_cacheLatestVersion($latest)
{
global $hesk_settings;
@file_put_contents(HESK_PATH . $hesk_settings['cache_dir'] . '/__latest.txt', time() . '|' . $latest);
return $latest;
} // END hesk_cacheLatestVersion()
function hesk_checkMfhVersion($currentVersion)
{
if ($latest = hesk_getMfhLatestVersion()) {
if (strlen($latest) > 12) {
return -1;
} elseif ($latest == $currentVersion) {
return true;
} else {
return $latest;
}
} else {
return -1;
}
}
function hesk_getMfhLatestVersion()
{
global $hesk_settings;
// Do we have a cached version file?
if (file_exists(HESK_PATH . $hesk_settings['cache_dir'] . '/__latest-mfh.txt')) {
if (preg_match('/^(\d+)\|([\d.]+)+$/', @file_get_contents(HESK_PATH . $hesk_settings['cache_dir'] . '/__latest-mfh.txt'), $matches) && (time() - intval($matches[1])) < 3600) {
return $matches[2];
}
}
// No cached file or older than 3600 seconds, try to get an update
$hesk_version_url = 'http://mods-for-hesk.mkochcs.com/latestversion.php';
// Try using cURL
if (function_exists('curl_init')) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $hesk_version_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 6);
$latest = curl_exec($ch);
curl_close($ch);
return hesk_cacheMfhLatestVersion($latest);
}
// Try using a simple PHP function instead
if ($latest = file_get_contents($hesk_version_url)) {
return hesk_cacheMfhLatestVersion($latest);
}
// Can't check automatically, will need a manual check
return false;
}
function hesk_cacheMfhLatestVersion($latest)
{
global $hesk_settings;
@file_put_contents(HESK_PATH . $hesk_settings['cache_dir'] . '/__latest-mfh.txt', time() . '|' . $latest);
return $latest;
}
function hesk_testLanguage($return_options = 0)
{
global $hesk_settings, $hesklang, $modsForHesk_settings;

@ -0,0 +1,56 @@
<?php
namespace Controllers\System;
class HeskVersionController {
static function getHeskVersion() {
global $hesk_settings;
return self::getLatestVersion('__latest.txt', 'https://www.hesk.com/version', $hesk_settings);
}
static function getModsForHeskVersion() {
global $hesk_settings;
return self::getLatestVersion('__latest-mfh.txt', 'https://www.mods-for-hesk.com/latestversion.php', $hesk_settings);
}
private static function getLatestVersion($fileName, $url, $hesk_settings) {
if (file_exists(__DIR__ . '/../../../' . $hesk_settings['cache_dir'] . '/' . $fileName) &&
preg_match('/^(\d+)\|([\d.]+)+$/',
@file_get_contents(__DIR__ . '/../../../' . $hesk_settings['cache_dir'] . '/' . $fileName), $matches) &&
(time() - intval($matches[1])) < 3600) {
return output(array('version' => $matches[2]));
}
// Try using cURL
if (function_exists('curl_init')) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 6);
$latest = curl_exec($ch);
curl_close($ch);
self::cacheLatestVersion($latest, $fileName, $hesk_settings);
return output(array('version' => $latest));
}
// Try using a simple PHP function instead
if ($latest = @file_get_contents($url)) {
self::cacheLatestVersion($latest, $fileName, $hesk_settings);
return output(array('version' => $latest));
}
// Can't check automatically, will need a manual check
return http_response_code(408);
}
private static function cacheLatestVersion($latest, $fileName, $hesk_settings) {
@file_put_contents(__DIR__ . '/../../../' . $hesk_settings['cache_dir'] . '/' . $fileName,
time() . '|' . $latest);
}
}

@ -15,26 +15,37 @@ function handle404() {
), 404);
}
function before() {
if (defined('HESK_DEMO') && $_SERVER['REQUEST_METHOD'] !== 'GET') {
function globalBefore() {
if (defined('HESK_DEMO') && $_SERVER['REQUEST_METHOD'] === 'GET') {
print_error('Demo Mode', 'Only read-only commands are available in demo mode!', null, 401);
die();
}
}
function internalHandler() {
buildUserContextFromSession();
}
function authTokenHandler() {
assertApiIsEnabled();
$token = \BusinessLogic\Helpers::getHeader('X-AUTH-TOKEN');
buildUserContext($token);
}
function internalOrAuthHandler() {
$internalUse = \BusinessLogic\Helpers::getHeader('X-INTERNAL-CALL');
if ($internalUse === 'true') {
buildUserContextFromSession();
} elseif (preg_match('/\/v1\/tickets\/.+\/attachments\/\d+/', $_SERVER['PATH_INFO'])) {
//-- TODO Clean this up
return;
internalHandler();
} else {
assertApiIsEnabled();
$token = \BusinessLogic\Helpers::getHeader('X-AUTH-TOKEN');
buildUserContext($token);
authTokenHandler();
}
}
function publicHandler() {
//-- No-op
}
function assertApiIsEnabled() {
global $applicationContext, $hesk_settings;
@ -172,34 +183,55 @@ function fatalErrorShutdownHandler() {
}
}
Link::before('before');
Link::before('globalBefore');
Link::all(array(
// Categories
'/v1/categories' => [\Controllers\Categories\CategoryController::class . '::printAllCategories'],
'/v1/categories/{i}' => \Controllers\Categories\CategoryController::class,
'/v1/categories' => action(\Controllers\Categories\CategoryController::class . '::printAllCategories'),
'/v1/categories/{i}' => action(\Controllers\Categories\CategoryController::class),
// Tickets
'/v1/tickets' => \Controllers\Tickets\CustomerTicketController::class,
'/v1/tickets' => action(\Controllers\Tickets\CustomerTicketController::class),
// Tickets - Staff
'/v1/staff/tickets/{i}' => \Controllers\Tickets\StaffTicketController::class,
'/v1/staff/tickets/{i}' => action(\Controllers\Tickets\StaffTicketController::class),
// Attachments
'/v1/tickets/{a}/attachments/{i}' => \Controllers\Attachments\PublicAttachmentController::class . '::getRaw',
'/v1/staff/tickets/{i}/attachments' => \Controllers\Attachments\StaffTicketAttachmentsController::class,
'/v1/staff/tickets/{i}/attachments/{i}' => \Controllers\Attachments\StaffTicketAttachmentsController::class,
'/v1/tickets/{a}/attachments/{i}' => action(\Controllers\Attachments\PublicAttachmentController::class . '::getRaw'),
'/v1/staff/tickets/{i}/attachments' => action(\Controllers\Attachments\StaffTicketAttachmentsController::class),
'/v1/staff/tickets/{i}/attachments/{i}' => action(\Controllers\Attachments\StaffTicketAttachmentsController::class),
// Statuses
'/v1/statuses' => \Controllers\Statuses\StatusController::class,
'/v1/statuses' => action(\Controllers\Statuses\StatusController::class),
// Settings
'/v1/settings' => \Controllers\Settings\SettingsController::class,
'/v1/settings' => action(\Controllers\Settings\SettingsController::class),
/* Internal use only routes */
// Resend email response
'/v1-internal/staff/tickets/{i}/resend-email' => \Controllers\Tickets\ResendTicketEmailToCustomerController::class,
'/v1-internal/staff/tickets/{i}/resend-email' =>
action(\Controllers\Tickets\ResendTicketEmailToCustomerController::class, SecurityHandler::INTERNAL),
// Custom Navigation
'/v1-internal/custom-navigation/all' => \Controllers\Navigation\CustomNavElementController::class . '::getAll',
'/v1-internal/custom-navigation' => \Controllers\Navigation\CustomNavElementController::class,
'/v1-internal/custom-navigation/{i}' => \Controllers\Navigation\CustomNavElementController::class,
'/v1-internal/custom-navigation/{i}/sort/{s}' => \Controllers\Navigation\CustomNavElementController::class . '::sort',
'/v1-internal/custom-navigation/all' =>
action(\Controllers\Navigation\CustomNavElementController::class . '::getAll', SecurityHandler::INTERNAL),
'/v1-internal/custom-navigation' =>
action(\Controllers\Navigation\CustomNavElementController::class, SecurityHandler::INTERNAL),
'/v1-internal/custom-navigation/{i}' =>
action(\Controllers\Navigation\CustomNavElementController::class, SecurityHandler::INTERNAL),
'/v1-internal/custom-navigation/{i}/sort/{s}' =>
action(\Controllers\Navigation\CustomNavElementController::class . '::sort', SecurityHandler::INTERNAL),
'/v1-public/hesk-version' =>
action(\Controllers\System\HeskVersionController::class . '::getHeskVersion', SecurityHandler::OPEN),
'/v1-public/mods-for-hesk-version' =>
action(\Controllers\System\HeskVersionController::class . '::getModsForHeskVersion', SecurityHandler::OPEN),
// Any URL that doesn't match goes to the 404 handler
'404' => 'handle404'
));
));
function action($class, $securityHandler = SecurityHandler::AUTH_TOKEN) {
return [$class, $class, $securityHandler];
}
class SecurityHandler {
const OPEN = 'publicHandler';
const INTERNAL = 'internalHandler';
const AUTH_TOKEN = 'authTokenHandler';
const INTERNAL_OR_AUTH_TOKEN = 'internalOrAuthHandler';
}
Loading…
Cancel
Save