updated site request
This commit is contained in:
parent
fe2ed7befc
commit
b8018dd804
@ -10,10 +10,10 @@ class UpdateFinished
|
|||||||
|
|
||||||
public $alias;
|
public $alias;
|
||||||
|
|
||||||
public $old;
|
|
||||||
|
|
||||||
public $new;
|
public $new;
|
||||||
|
|
||||||
|
public $old;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new event instance.
|
* Create a new event instance.
|
||||||
*
|
*
|
||||||
@ -21,10 +21,10 @@ class UpdateFinished
|
|||||||
* @param $old
|
* @param $old
|
||||||
* @param $new
|
* @param $new
|
||||||
*/
|
*/
|
||||||
public function __construct($alias, $old, $new)
|
public function __construct($alias, $new, $old)
|
||||||
{
|
{
|
||||||
$this->alias = $alias;
|
$this->alias = $alias;
|
||||||
$this->old = $old;
|
|
||||||
$this->new = $new;
|
$this->new = $new;
|
||||||
|
$this->old = $old;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,17 +2,16 @@
|
|||||||
|
|
||||||
namespace App\Traits;
|
namespace App\Traits;
|
||||||
|
|
||||||
|
use App\Models\Module\Module as Model;
|
||||||
|
use App\Models\Module\Module;
|
||||||
use App\Traits\SiteApi;
|
use App\Traits\SiteApi;
|
||||||
use App\Utilities\Console;
|
use App\Utilities\Console;
|
||||||
use App\Utilities\Info;
|
use App\Utilities\Info;
|
||||||
use App\Models\Module\Module as Model;
|
|
||||||
use App\Models\Module\Module;
|
|
||||||
use Artisan;
|
use Artisan;
|
||||||
use Cache;
|
use Cache;
|
||||||
use Date;
|
use Date;
|
||||||
use File;
|
use File;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use GuzzleHttp\Exception\RequestException;
|
|
||||||
use ZipArchive;
|
use ZipArchive;
|
||||||
|
|
||||||
trait Modules
|
trait Modules
|
||||||
@ -27,15 +26,13 @@ trait Modules
|
|||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
$response = static::getRemote('token/check', 'POST', $data);
|
if (!$response = static::getResponse('POST', 'token/check', $data)) {
|
||||||
|
return false;
|
||||||
if ($response && ($response->getStatusCode() == 200)) {
|
|
||||||
$result = json_decode($response->getBody());
|
|
||||||
|
|
||||||
return ($result->success) ? true : false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
$result = json_decode($response->getBody());
|
||||||
|
|
||||||
|
return $result->success ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get All Modules
|
// Get All Modules
|
||||||
@ -48,7 +45,7 @@ trait Modules
|
|||||||
return $items;
|
return $items;
|
||||||
}
|
}
|
||||||
|
|
||||||
$items = $this->remote('apps/items');
|
$items = static::getResponseData('GET', 'apps/items');
|
||||||
|
|
||||||
Cache::put('apps.items', $items, Date::now()->addHour());
|
Cache::put('apps.items', $items, Date::now()->addHour());
|
||||||
|
|
||||||
@ -65,7 +62,7 @@ trait Modules
|
|||||||
return $item;
|
return $item;
|
||||||
}
|
}
|
||||||
|
|
||||||
$item = $this->remote('apps/' . $alias);
|
$item = static::getResponseData('GET', 'apps/' . $alias);
|
||||||
|
|
||||||
Cache::put('apps.' . $alias, $item, Date::now()->addHour());
|
Cache::put('apps.' . $alias, $item, Date::now()->addHour());
|
||||||
|
|
||||||
@ -81,7 +78,7 @@ trait Modules
|
|||||||
return $documentation;
|
return $documentation;
|
||||||
}
|
}
|
||||||
|
|
||||||
$documentation = $this->remote('apps/docs/' . $alias);
|
$documentation = static::getResponseData('GET', 'apps/docs/' . $alias);
|
||||||
|
|
||||||
Cache::put('apps.docs.' . $alias, $documentation, Date::now()->addHour());
|
Cache::put('apps.docs.' . $alias, $documentation, Date::now()->addHour());
|
||||||
|
|
||||||
@ -97,7 +94,7 @@ trait Modules
|
|||||||
return $reviews;
|
return $reviews;
|
||||||
}
|
}
|
||||||
|
|
||||||
$reviews = $this->remote('apps/' . $alias . '/reviews', 'GET', $data);
|
$reviews = static::getResponseData('GET', 'apps/' . $alias . '/reviews', $data);
|
||||||
|
|
||||||
Cache::put('apps.' . $alias . '.reviews', $reviews, Date::now()->addHour());
|
Cache::put('apps.' . $alias . '.reviews', $reviews, Date::now()->addHour());
|
||||||
|
|
||||||
@ -113,7 +110,7 @@ trait Modules
|
|||||||
return $categories;
|
return $categories;
|
||||||
}
|
}
|
||||||
|
|
||||||
$categories = $this->remote('apps/categories');
|
$categories = static::getResponseData('GET', 'apps/categories');
|
||||||
|
|
||||||
Cache::put('apps.categories', $categories, Date::now()->addHour());
|
Cache::put('apps.categories', $categories, Date::now()->addHour());
|
||||||
|
|
||||||
@ -129,7 +126,7 @@ trait Modules
|
|||||||
return $category;
|
return $category;
|
||||||
}
|
}
|
||||||
|
|
||||||
$category = $this->remote('apps/categories/' . $alias, 'GET', $data);
|
$category = static::getResponseData('GET', 'apps/categories/' . $alias, $data);
|
||||||
|
|
||||||
Cache::put('apps.categories.' . $alias, $category, Date::now()->addHour());
|
Cache::put('apps.categories.' . $alias, $category, Date::now()->addHour());
|
||||||
|
|
||||||
@ -145,7 +142,7 @@ trait Modules
|
|||||||
return $vendors;
|
return $vendors;
|
||||||
}
|
}
|
||||||
|
|
||||||
$vendors = $this->remote('apps/vendors');
|
$vendors = static::getResponseData('GET', 'apps/vendors');
|
||||||
|
|
||||||
Cache::put('apps.vendors', $vendors, Date::now()->addHour());
|
Cache::put('apps.vendors', $vendors, Date::now()->addHour());
|
||||||
|
|
||||||
@ -161,7 +158,7 @@ trait Modules
|
|||||||
return $vendor;
|
return $vendor;
|
||||||
}
|
}
|
||||||
|
|
||||||
$vendor = $this->remote('apps/vendors/' . $alias, 'GET', $data);
|
$vendor = static::getResponseData('GET', 'apps/vendors/' . $alias, $data);
|
||||||
|
|
||||||
Cache::put('apps.vendors.' . $alias, $vendor, Date::now()->addHour());
|
Cache::put('apps.vendors.' . $alias, $vendor, Date::now()->addHour());
|
||||||
|
|
||||||
@ -170,7 +167,7 @@ trait Modules
|
|||||||
|
|
||||||
public function getMyModules($data = [])
|
public function getMyModules($data = [])
|
||||||
{
|
{
|
||||||
return $this->remote('apps/my', 'GET', $data);
|
return static::getResponseData('GET', 'apps/my', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getInstalledModules($data = [])
|
public function getInstalledModules($data = [])
|
||||||
@ -216,7 +213,7 @@ trait Modules
|
|||||||
return $pre_sale;
|
return $pre_sale;
|
||||||
}
|
}
|
||||||
|
|
||||||
$pre_sale = $this->remote('apps/pre_sale', 'GET', $data);
|
$pre_sale = static::getResponseData('GET', 'apps/pre_sale', $data);
|
||||||
|
|
||||||
Cache::put('apps.pre_sale', $pre_sale, Date::now()->addHour());
|
Cache::put('apps.pre_sale', $pre_sale, Date::now()->addHour());
|
||||||
|
|
||||||
@ -232,7 +229,7 @@ trait Modules
|
|||||||
return $paid;
|
return $paid;
|
||||||
}
|
}
|
||||||
|
|
||||||
$paid = $this->remote('apps/paid', 'GET', $data);
|
$paid = static::getResponseData('GET', 'apps/paid', $data);
|
||||||
|
|
||||||
Cache::put('apps.paid', $paid, Date::now()->addHour());
|
Cache::put('apps.paid', $paid, Date::now()->addHour());
|
||||||
|
|
||||||
@ -248,7 +245,7 @@ trait Modules
|
|||||||
return $new;
|
return $new;
|
||||||
}
|
}
|
||||||
|
|
||||||
$new = $this->remote('apps/new', 'GET', $data);
|
$new = static::getResponseData('GET', 'apps/new', $data);
|
||||||
|
|
||||||
Cache::put('apps.new', $new, Date::now()->addHour());
|
Cache::put('apps.new', $new, Date::now()->addHour());
|
||||||
|
|
||||||
@ -264,7 +261,7 @@ trait Modules
|
|||||||
return $free;
|
return $free;
|
||||||
}
|
}
|
||||||
|
|
||||||
$free = $this->remote('apps/free', 'GET', $data);
|
$free = static::getResponseData('GET', 'apps/free', $data);
|
||||||
|
|
||||||
Cache::put('apps.free', $free, Date::now()->addHour());
|
Cache::put('apps.free', $free, Date::now()->addHour());
|
||||||
|
|
||||||
@ -280,7 +277,7 @@ trait Modules
|
|||||||
return $featured;
|
return $featured;
|
||||||
}
|
}
|
||||||
|
|
||||||
$featured = $this->remote('apps/featured', 'GET', $data);
|
$featured = static::getResponseData('GET', 'apps/featured', $data);
|
||||||
|
|
||||||
Cache::put('apps.featured', $featured, Date::now()->addHour());
|
Cache::put('apps.featured', $featured, Date::now()->addHour());
|
||||||
|
|
||||||
@ -289,63 +286,62 @@ trait Modules
|
|||||||
|
|
||||||
public function getSearchModules($data = [])
|
public function getSearchModules($data = [])
|
||||||
{
|
{
|
||||||
return $this->remote('apps/search', 'GET', $data);
|
return static::getResponseData('GET', 'apps/search', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getCoreVersion()
|
public function getCoreVersion()
|
||||||
{
|
{
|
||||||
$data['query'] = Info::all();
|
$data['query'] = Info::all();
|
||||||
|
|
||||||
$response = static::getRemote('core/version', 'GET', $data);
|
if (!$response = static::getResponse('GET', 'core/version', $data)) {
|
||||||
|
return [];
|
||||||
if ($response && ($response->getStatusCode() == 200)) {
|
|
||||||
return $response->json();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return [];
|
return $response->json();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function downloadModule($path)
|
public function downloadModule($path)
|
||||||
{
|
{
|
||||||
$response = static::getRemote($path);
|
if (!$response = static::getResponse('GET', $path)) {
|
||||||
|
|
||||||
if ($response && ($response->getStatusCode() == 200)) {
|
|
||||||
$file = $response->getBody()->getContents();
|
|
||||||
|
|
||||||
$path = 'temp-' . md5(mt_rand());
|
|
||||||
$temp_path = storage_path('app/temp') . '/' . $path;
|
|
||||||
|
|
||||||
$file_path = $temp_path . '/upload.zip';
|
|
||||||
|
|
||||||
// Create tmp directory
|
|
||||||
if (!File::isDirectory($temp_path)) {
|
|
||||||
File::makeDirectory($temp_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add content to the Zip file
|
|
||||||
$uploaded = is_int(file_put_contents($file_path, $file)) ? true : false;
|
|
||||||
|
|
||||||
if (!$uploaded) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$data = [
|
|
||||||
'path' => $path
|
|
||||||
];
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'success' => true,
|
'success' => false,
|
||||||
'error' => false,
|
'error' => true,
|
||||||
'message' => null,
|
'message' => null,
|
||||||
'data' => $data,
|
'data' => null,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$file = $response->getBody()->getContents();
|
||||||
|
|
||||||
|
$path = 'temp-' . md5(mt_rand());
|
||||||
|
$temp_path = storage_path('app/temp') . '/' . $path;
|
||||||
|
|
||||||
|
$file_path = $temp_path . '/upload.zip';
|
||||||
|
|
||||||
|
// Create tmp directory
|
||||||
|
if (!File::isDirectory($temp_path)) {
|
||||||
|
File::makeDirectory($temp_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add content to the Zip file
|
||||||
|
$uploaded = is_int(file_put_contents($file_path, $file)) ? true : false;
|
||||||
|
|
||||||
|
if (!$uploaded) {
|
||||||
|
return [
|
||||||
|
'success' => false,
|
||||||
|
'error' => true,
|
||||||
|
'message' => null,
|
||||||
|
'data' => null,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'success' => false,
|
'success' => true,
|
||||||
'error' => true,
|
'error' => false,
|
||||||
'message' => null,
|
'message' => null,
|
||||||
'data' => null,
|
'data' => [
|
||||||
|
'path' => $path,
|
||||||
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -518,26 +514,12 @@ trait Modules
|
|||||||
|
|
||||||
$data = [];
|
$data = [];
|
||||||
|
|
||||||
$url = 'apps/suggestions';
|
if (!$suggestions = static::getResponseData('GET', 'apps/suggestions')) {
|
||||||
|
return $data;
|
||||||
$response = static::getRemote($url, 'GET', ['timeout' => 30, 'referer' => true]);
|
|
||||||
|
|
||||||
// Exception
|
|
||||||
if ($response instanceof RequestException) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bad response
|
foreach ($suggestions as $suggestion) {
|
||||||
if (!$response || ($response->getStatusCode() != 200)) {
|
$data[$suggestion->path] = $suggestion;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$suggestions = json_decode($response->getBody())->data;
|
|
||||||
|
|
||||||
if ($suggestions) {
|
|
||||||
foreach ($suggestions as $suggestion) {
|
|
||||||
$data[$suggestion->path] = $suggestion;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Cache::put('suggestions', $data, Date::now()->addHour(6));
|
Cache::put('suggestions', $data, Date::now()->addHour(6));
|
||||||
@ -556,22 +538,10 @@ trait Modules
|
|||||||
|
|
||||||
$data = [];
|
$data = [];
|
||||||
|
|
||||||
$url = 'apps/notifications';
|
if (!$notifications = static::getResponse('GET', 'apps/notifications')) {
|
||||||
|
return $data;
|
||||||
$response = static::getRemote($url, 'GET', ['timeout' => 30, 'referer' => true]);
|
|
||||||
|
|
||||||
// Exception
|
|
||||||
if ($response instanceof RequestException) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bad response
|
|
||||||
if (!$response || ($response->getStatusCode() != 200)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$notifications = json_decode($response->getBody())->data;
|
|
||||||
|
|
||||||
foreach ($notifications as $notification) {
|
foreach ($notifications as $notification) {
|
||||||
$data[$notification->path][] = $notification;
|
$data[$notification->path][] = $notification;
|
||||||
}
|
}
|
||||||
@ -612,15 +582,4 @@ trait Modules
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function remote($path, $method = 'GET', $data = [])
|
|
||||||
{
|
|
||||||
$response = static::getRemote($path, $method, $data);
|
|
||||||
|
|
||||||
if ($response && ($response->getStatusCode() == 200)) {
|
|
||||||
return json_decode($response->getBody())->data;
|
|
||||||
}
|
|
||||||
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -7,31 +7,60 @@ use GuzzleHttp\Exception\RequestException;
|
|||||||
|
|
||||||
trait SiteApi
|
trait SiteApi
|
||||||
{
|
{
|
||||||
|
public static $base_uri = 'https://api.akaunting.com/';
|
||||||
|
|
||||||
protected static function getRemote($path, $method = 'GET', $data = [])
|
protected static function siteApiRequest($method, $path, $extra_data = [])
|
||||||
{
|
{
|
||||||
$base = 'https://api.akaunting.com/';
|
$client = new Client(['verify' => false, 'base_uri' => static::$base_uri]);
|
||||||
|
|
||||||
$client = new Client(['verify' => false, 'base_uri' => $base]);
|
|
||||||
|
|
||||||
$headers['headers'] = [
|
$headers['headers'] = [
|
||||||
'Authorization' => 'Bearer ' . setting('apps.api_key'),
|
'Authorization' => 'Bearer ' . setting('apps.api_key'),
|
||||||
'Accept' => 'application/json',
|
'Accept' => 'application/json',
|
||||||
'Referer' => url('/'),
|
'Referer' => url('/'),
|
||||||
'Akaunting' => version('short'),
|
'Akaunting' => version('short'),
|
||||||
'Language' => language()->getShortCode()
|
'Language' => language()->getShortCode(),
|
||||||
];
|
];
|
||||||
|
|
||||||
$data['http_errors'] = false;
|
$data = array_merge([
|
||||||
|
'timeout' => 30,
|
||||||
|
'referer' => true,
|
||||||
|
'http_errors' => false,
|
||||||
|
], $extra_data);
|
||||||
|
|
||||||
$data = array_merge($data, $headers);
|
$options = array_merge($data, $headers);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$result = $client->request($method, $path, $data);
|
$response = $client->request($method, $path, $options);
|
||||||
} catch (RequestException $e) {
|
} catch (RequestException $e) {
|
||||||
$result = $e;
|
$response = $e;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getResponse($method, $path, $data = [])
|
||||||
|
{
|
||||||
|
$response = static::siteApiRequest($method, $path, $data);
|
||||||
|
|
||||||
|
if (!$response || ($response instanceof RequestException) || ($response->getStatusCode() != 200)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getResponseData($method, $path, $data = [])
|
||||||
|
{
|
||||||
|
if (!$response = static::getResponse($method, $path, $data)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$body = json_decode($response->getBody());
|
||||||
|
|
||||||
|
if (!is_object($body)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $body->data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,13 +5,13 @@ namespace App\Utilities;
|
|||||||
use App\Events\Install\UpdateCopied;
|
use App\Events\Install\UpdateCopied;
|
||||||
use App\Events\Install\UpdateDownloaded;
|
use App\Events\Install\UpdateDownloaded;
|
||||||
use App\Events\Install\UpdateUnzipped;
|
use App\Events\Install\UpdateUnzipped;
|
||||||
|
use App\Utilities\Console;
|
||||||
use App\Traits\SiteApi;
|
use App\Traits\SiteApi;
|
||||||
|
use Artisan;
|
||||||
use Cache;
|
use Cache;
|
||||||
use Date;
|
use Date;
|
||||||
use File;
|
use File;
|
||||||
use ZipArchive;
|
use ZipArchive;
|
||||||
use Artisan;
|
|
||||||
use GuzzleHttp\Exception\RequestException;
|
|
||||||
|
|
||||||
class Updater
|
class Updater
|
||||||
{
|
{
|
||||||
@ -38,10 +38,7 @@ class Updater
|
|||||||
$url = 'apps/' . $alias . '/download/' . $new . '/' . $info['akaunting'] . '/' . $info['token'];
|
$url = 'apps/' . $alias . '/download/' . $new . '/' . $info['akaunting'] . '/' . $info['token'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$response = static::getRemote($url, 'GET', ['timeout' => 50, 'track_redirects' => true]);
|
if (!$response = static::getResponse('GET', $url, ['timeout' => 50, 'track_redirects' => true])) {
|
||||||
|
|
||||||
// Exception
|
|
||||||
if (!$response || ($response instanceof RequestException) || ($response->getStatusCode() != 200)) {
|
|
||||||
throw new \Exception(trans('modules.errors.download', ['module' => $alias]));
|
throw new \Exception(trans('modules.errors.download', ['module' => $alias]));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,7 +47,7 @@ class Updater
|
|||||||
$path = 'temp-' . md5(mt_rand());
|
$path = 'temp-' . md5(mt_rand());
|
||||||
$temp_path = storage_path('app/temp') . '/' . $path;
|
$temp_path = storage_path('app/temp') . '/' . $path;
|
||||||
|
|
||||||
$file_path = $temp_path . '/update.zip';
|
$file_path = $temp_path . '/upload.zip';
|
||||||
|
|
||||||
// Create tmp directory
|
// Create tmp directory
|
||||||
if (!File::isDirectory($temp_path)) {
|
if (!File::isDirectory($temp_path)) {
|
||||||
@ -73,7 +70,7 @@ class Updater
|
|||||||
{
|
{
|
||||||
$temp_path = storage_path('app/temp') . '/' . $path;
|
$temp_path = storage_path('app/temp') . '/' . $path;
|
||||||
|
|
||||||
$file = $temp_path . '/update.zip';
|
$file = $temp_path . '/upload.zip';
|
||||||
|
|
||||||
// Unzip the file
|
// Unzip the file
|
||||||
$zip = new ZipArchive();
|
$zip = new ZipArchive();
|
||||||
|
@ -6,7 +6,6 @@ use App\Traits\SiteApi;
|
|||||||
use Cache;
|
use Cache;
|
||||||
use Date;
|
use Date;
|
||||||
use Parsedown;
|
use Parsedown;
|
||||||
use GuzzleHttp\Exception\RequestException;
|
|
||||||
|
|
||||||
class Versions
|
class Versions
|
||||||
{
|
{
|
||||||
@ -89,28 +88,14 @@ class Versions
|
|||||||
|
|
||||||
public static function getLatestVersion($url, $latest)
|
public static function getLatestVersion($url, $latest)
|
||||||
{
|
{
|
||||||
$response = static::getRemote($url, 'GET', ['timeout' => 10, 'referer' => true]);
|
if (!$data = static::getResponseData('GET', $url, ['timeout' => 10])) {
|
||||||
|
|
||||||
// Exception
|
|
||||||
if ($response instanceof RequestException) {
|
|
||||||
return $latest;
|
return $latest;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bad response
|
if (!is_object($data)) {
|
||||||
if (!$response || ($response->getStatusCode() != 200)) {
|
|
||||||
return $latest;
|
return $latest;
|
||||||
}
|
}
|
||||||
|
|
||||||
$content = json_decode($response->getBody());
|
return $data->latest;
|
||||||
|
|
||||||
// Empty response
|
|
||||||
if (!is_object($content) || !is_object($content->data)) {
|
|
||||||
return $latest;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the latest version
|
|
||||||
$latest = $content->data->latest;
|
|
||||||
|
|
||||||
return $latest;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user