Akaunting/app/Utilities/Versions.php

297 lines
8.2 KiB
PHP
Raw Normal View History

2017-09-14 19:21:00 +00:00
<?php
namespace App\Utilities;
2025-12-07 16:30:31 +00:00
use App\Models\Module\Module;
2017-09-14 19:21:00 +00:00
use App\Traits\SiteApi;
2025-12-07 16:30:31 +00:00
use App\Traits\Jobs;
use App\Jobs\Install\DisableModule;
use App\Jobs\Install\UninstallModule;
2023-04-28 21:52:12 +00:00
use App\Utilities\Date;
2020-03-12 12:13:03 +00:00
use GrahamCampbell\Markdown\Facades\Markdown;
2020-02-21 08:45:37 +00:00
use Illuminate\Support\Arr;
2023-04-28 21:52:12 +00:00
use Illuminate\Support\Facades\Cache;
2017-09-14 19:21:00 +00:00
class Versions
{
2025-12-07 16:30:31 +00:00
use SiteApi, Jobs;
2017-09-14 19:21:00 +00:00
public static function changelog()
{
$output = '';
$url = 'https://api.github.com/repos/akaunting/akaunting/releases';
$http = new \GuzzleHttp\Client(['verify' => false]);
$json = $http->get($url, ['timeout' => 30])->getBody()->getContents();
if (empty($json)) {
return $output;
}
$releases = json_decode($json);
foreach ($releases as $release) {
2017-11-23 20:28:35 +00:00
if (version_compare($release->tag_name, version('short'), '<=')) {
2017-09-14 19:21:00 +00:00
continue;
}
if ($release->prerelease == true) {
continue;
}
if (empty($release->body)) {
continue;
}
2024-08-07 12:47:44 +00:00
if (empty($output)) {
$output .= '<div class="mx-6">';
} else {
$output .= '<div class="mx-6 my-6">';
}
$output .= ' <div class="mb-4">';
$output .= ' <h2>';
$output .= ' <span class="rounded-xl bg-green px-3 py-2 text-base font-medium text-white ring-1 ring-inset ring-green">';
$output .= $release->tag_name;
$output .= ' </span>';
$output .= ' </h2>';
$output .= ' </div>';
$output .= Markdown::convertToHtml($release->body);
2017-09-14 19:21:00 +00:00
2024-08-07 12:47:44 +00:00
$output .= '</div>';
2017-09-14 19:21:00 +00:00
$output .= '<hr>';
}
return $output;
}
2020-02-21 08:45:37 +00:00
public static function latest($alias)
{
$versions = static::all($alias);
2023-04-25 06:46:22 +00:00
if (empty($versions[$alias])) {
return static::getVersionByAlias($alias);
2020-02-21 08:45:37 +00:00
}
2023-04-25 06:46:22 +00:00
return $versions[$alias];
2020-02-21 08:45:37 +00:00
}
public static function all($modules = null)
2017-09-14 19:21:00 +00:00
{
2023-10-08 22:06:37 +00:00
return Cache::remember('versions', Date::now()->addHours(6), function () use ($modules) {
$info = Info::all();
2017-09-14 19:21:00 +00:00
2023-10-08 22:06:37 +00:00
$versions = [];
2017-09-14 19:21:00 +00:00
2023-10-08 22:06:37 +00:00
// Check core first
2025-07-21 12:20:05 +00:00
try {
$url = 'core/version/' . $info['akaunting'] . '/' . $info['php'] . '/' . $info['mysql'] . '/' . $info['companies'];
} catch (\Exception $e) {
// Handle exception
2025-07-21 12:26:25 +00:00
report('Error fetching core version: ( $info = ' . json_encode($info) . ')' . $e->getMessage());
2025-07-21 12:20:05 +00:00
return $versions;
}
2017-09-14 19:21:00 +00:00
2023-10-08 22:06:37 +00:00
# Installed modules start
$modules = Arr::wrap($modules);
2017-09-14 19:21:00 +00:00
2023-10-08 22:06:37 +00:00
$installed_modules = [];
$module_version = '?modules=';
2020-02-21 08:45:37 +00:00
2023-10-08 22:06:37 +00:00
foreach ($modules as $module) {
if (is_string($module)) {
$module = module($module);
}
2023-04-25 08:44:36 +00:00
2023-10-08 22:06:37 +00:00
if (! $module instanceof \Akaunting\Module\Module) {
continue;
}
2023-04-25 06:46:22 +00:00
2023-10-08 22:06:37 +00:00
$alias = $module->get('alias');
2023-04-25 06:46:22 +00:00
2023-10-08 22:06:37 +00:00
$installed_modules[] = $alias;
}
2023-04-25 06:46:22 +00:00
2023-10-08 22:06:37 +00:00
$module_version .= implode(',', $installed_modules);
2023-04-25 06:46:22 +00:00
2023-10-08 22:06:37 +00:00
$url .= $module_version;
# Installed modules end
2023-04-25 06:46:22 +00:00
2023-10-08 22:06:37 +00:00
$versions['core'] = static::getLatestVersion($url, $info['akaunting']);
2020-02-21 08:45:37 +00:00
2023-10-08 22:06:37 +00:00
// Then modules
foreach ($modules as $module) {
if (is_string($module)) {
$module = module($module);
}
2020-02-21 08:45:37 +00:00
2023-10-08 22:06:37 +00:00
if (! $module instanceof \Akaunting\Module\Module) {
continue;
}
2017-09-14 19:21:00 +00:00
2023-10-08 22:06:37 +00:00
$alias = $module->get('alias');
$version = $module->get('version');
2017-09-14 19:21:00 +00:00
2023-10-08 22:06:37 +00:00
$url = 'apps/' . $alias . '/version/' . $version . '/' . $info['akaunting'];
2017-09-14 19:21:00 +00:00
2023-10-08 22:06:37 +00:00
$versions[$alias] = static::getLatestVersion($url, $version);
}
2017-09-14 19:21:00 +00:00
2023-10-08 22:06:37 +00:00
return $versions;
});
2017-09-14 19:21:00 +00:00
}
public static function getVersionByAlias($alias)
{
$info = Info::all();
// Check core first
$url = 'core/version/' . $info['akaunting'] . '/' . $info['php'] . '/' . $info['mysql'] . '/' . $info['companies'];
$version = $info['akaunting'];
if ($alias != 'core') {
$version = module($alias) ? module($alias)->get('version') : '1.0.0';
$url = 'apps/' . $alias . '/version/' . $version . '/' . $info['akaunting'];
}
// Get data from cache
$versions = Cache::get('versions', []);
$versions[$alias] = static::getLatestVersion($url, $version);
2023-10-03 08:06:08 +00:00
Cache::put('versions', $versions, Date::now()->addHours(6));
return $versions[$alias];
}
2020-12-23 23:16:00 +00:00
public static function getLatestVersion($url, $latest)
2017-09-14 19:21:00 +00:00
{
2023-04-25 06:46:22 +00:00
$version = new \stdClass();
$version->can_update = true;
$version->latest = $latest;
$version->errors = false;
$version->message = '';
2025-12-07 16:30:31 +00:00
$version->subscription = null;
2023-04-25 06:46:22 +00:00
if (! $body = static::getResponseBody('GET', $url, ['timeout' => 10])) {
return $version;
2017-10-27 06:38:55 +00:00
}
2017-09-14 19:21:00 +00:00
2023-04-25 06:46:22 +00:00
if (! is_object($body)) {
return $version;
2017-09-14 19:21:00 +00:00
}
2023-04-25 06:46:22 +00:00
$version->can_update = $body->success;
$version->latest = $body->data->latest;
$version->errors = $body->errors;
$version->message = $body->message;
2025-12-07 16:30:31 +00:00
$version->subscription = $body->data?->subscription ?? null;
2023-04-25 06:46:22 +00:00
return $version;
2017-09-14 19:21:00 +00:00
}
2020-12-23 23:16:00 +00:00
2025-12-07 16:30:31 +00:00
public static function enforceSubscriptionStatus($alias, $version): void
{
if (! $version->subscription) {
return;
}
if ($version->subscription->expired_at > Date::now()->startOfDay()) {
return;
}
$status = 'active';
switch ($version->subscription->status) {
case 'expired':
case 'canceled':
$status = 'disabled';
break;
case 'chargeback':
case 'not_paid':
case 'none':
case 'refund':
$status = 'uninstalled';
break;
default:
// Do nothing
break;
}
if ($status == 'active') {
return;
}
$module_companies = Module::allCompanies()->alias($alias)->get();
foreach ($module_companies as $module) {
switch ($status) {
case 'disabled':
dispatch(new DisableModule($alias, $module->company_id));
2025-12-07 16:30:31 +00:00
break;
case 'uninstalled':
dispatch(new UninstallModule($alias, $module->company_id));
2025-12-07 16:30:31 +00:00
break;
default:
// Do nothing
break;
}
}
}
2020-12-23 23:16:00 +00:00
public static function getUpdates()
{
2023-10-08 22:06:37 +00:00
return Cache::remember('updates', Date::now()->addHours(6), function () {
$updates = [];
2020-12-23 23:16:00 +00:00
2023-10-08 22:06:37 +00:00
$modules = module()->all();
2020-12-23 23:16:00 +00:00
2023-10-08 22:06:37 +00:00
$versions = static::all($modules);
2020-12-23 23:16:00 +00:00
2023-10-08 22:06:37 +00:00
foreach ($versions as $alias => $latest_version) {
if ($alias == 'core') {
$installed_version = version('short');
} else {
$module = module($alias);
2020-12-23 23:16:00 +00:00
2023-10-08 22:06:37 +00:00
if (! $module instanceof \Akaunting\Module\Module) {
continue;
}
2020-12-23 23:16:00 +00:00
2023-10-08 22:06:37 +00:00
$installed_version = $module->get('version');
2020-12-23 23:16:00 +00:00
}
2023-10-08 22:06:37 +00:00
if (version_compare($installed_version, $latest_version->latest, '>=')) {
continue;
}
2020-12-23 23:16:00 +00:00
2023-10-08 22:06:37 +00:00
$updates[$alias] = $latest_version;
2020-12-23 23:16:00 +00:00
}
2023-10-08 22:06:37 +00:00
return $updates;
});
2020-12-23 23:16:00 +00:00
}
2022-03-02 09:02:34 +00:00
public static function shouldUpdate($listener_version, $old_version, $new_version): bool
{
// Don't update if "listener" is same or lower than "old" version
if (version_compare($listener_version, $old_version, '<=')) {
return false;
}
// Don't update if "listener" is higher than "new" version
if (version_compare($listener_version, $new_version, '>')) {
return false;
}
return true;
}
}