| Server IP : 104.26.4.103 / Your IP : 216.73.216.4 Web Server : nginx/1.27.1 System : Linux in-5 5.15.0-143-generic #153-Ubuntu SMP Fri Jun 13 19:10:45 UTC 2025 x86_64 User : arabianexpress ( 1872) PHP Version : 8.0.30 Disable Function : exec,passthru,shell_exec,system,proc_open,popen,parse_ini_file,show_source MySQL : OFF | cURL : ON | WGET : OFF | Perl : OFF | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : /storage/v9321/leapdubai/public_html/wp-content/plugins/kirki/app/Services/ |
Upload File : |
<?php
namespace Kirki\App\Services;
defined('ABSPATH') || exit;
use Exception;
use Kirki\App\Constants\GlobalDataKeys;
use Kirki\App\DTO\Apps\AppDTO;
use Kirki\App\DTO\Apps\InstalledAppDTO;
use Kirki\App\Supports\Facades\GlobalData;
use Kirki\App\Supports\FileHandler;
use Kirki\App\Supports\FilterHooks;
use Kirki\Framework\Supports\Facades\DB;
use Kirki\Framework\Supports\Facades\File;
use Kirki\Framework\Supports\Facades\Http;
use Throwable;
use function Kirki\Framework\collection;
class AppsService
{
/**
* @return AppDTO[]
*/
public function get_all_apps()
{
$apps = Http::get(KIRKI_APPS_BASE_URL . '/apps.json', [
'sslverify' => false
]);
if ($apps->failed()) {
throw new Exception(esc_html__('Failed to get apps.', 'kirki'));
}
return AppDTO::from_list($apps->json());
}
/**
* @return InstalledAppDTO[]
*/
public function get_installed_apps()
{
$apps = GlobalData::get(GlobalDataKeys::INSTALLED_APPS);
return InstalledAppDTO::from_list(is_array($apps) ? $apps : []);
}
/**
* @return array
*/
public function get_app_settings(string $app_slug)
{
$settings = GlobalData::get(GlobalDataKeys::APP_SETTINGS . $app_slug) ?? [];
return FilterHooks::kirki_apps_configuration($app_slug, $settings);
}
/**
* @param string $app_slug
* @param array $settings
* @return array
*/
public function save_app_settings(string $app_slug, array $settings)
{
GlobalData::update(GlobalDataKeys::APP_SETTINGS . $app_slug, $settings);
return $settings;
}
public function install_app(AppDTO $payload)
{
$app_slug = preg_replace('/[^a-zA-Z0-9\-]/', '', $payload->slug);
$src = $payload->src;
$version = $payload->version;
$installed_apps = $this->get_installed_apps();
$is_already_installed = collection($installed_apps)->some(function(InstalledAppDTO $app) use ($app_slug) {
return $app->app_slug === $app_slug;
});
if ($is_already_installed) {
throw new Exception(esc_html__('This app is already installed. Please check the kirki-apps directory in wp-content folders.', 'kirki'));
}
// Define the remote zip URL and generate a unique file name
$remote_zip_url = KIRKI_APPS_BASE_URL . $src;
$file_name_new = uniqid('', true) . '.zip'; // 'random.ext'
$zip_file_path = FileHandler::download_zip_from_remote($remote_zip_url, $file_name_new);
if ($zip_file_path === false) {
throw new Exception(esc_html__('Failed to download the app zip file. Please check the remote URL.', 'kirki'));
}
// Get the WordPress wp-content directory
$base_upload_dir = WP_CONTENT_DIR; // Absolute path to 'uploads'
$temp_folder_path = $base_upload_dir . '/kirki-apps';
if (!File::is_writable($base_upload_dir)) {
File::delete($zip_file_path);
throw new Exception(esc_html__('The wp-content directory is not writable. Please check folder permissions.', 'kirki'));
}
if (File::missing($base_upload_dir)) {
if (!File::make_dir($temp_folder_path)) {
File::delete($zip_file_path);
throw new Exception(esc_html__('Failed to create directory: kirki-apps. Please check folder permissions.', 'kirki'));
}
}
$result = FileHandler::extract_zip_file($zip_file_path, $temp_folder_path);
if ($result === false) {
File::delete($zip_file_path);
throw new Exception(esc_html__('Failed to extract the app zip file. Please ensure the file is valid.', 'kirki'));
}
try {
$installed_apps = collection($installed_apps)->push(InstalledAppDTO::from_array([
'app_slug' => $app_slug,
'version' => $version,
]))->map(fn(InstalledAppDTO $app) => $app->to_array())->to_array();
GlobalData::update(GlobalDataKeys::INSTALLED_APPS, $installed_apps);
File::delete($zip_file_path);
return [
'app_slug' => $app_slug,
'version' => $version
];
} catch (Throwable $throwable) {
File::delete($zip_file_path);
throw new Exception(
sprintf(
/* translators: 1: error message */
esc_html__('An error occurred during the app installation: %s', 'kirki'),
esc_html($throwable->getMessage())
)
);
}
}
public function update_app(AppDTO $payload)
{
$app_slug = preg_replace('/[^a-zA-Z0-9\-]/', '', $payload->slug);
$src = $payload->src;
$new_version = $payload->version;
$installed_apps = $this->get_installed_apps();
if (empty($installed_apps)) {
throw new Exception(esc_html__('No apps are currently installed.', 'kirki'));
}
$is_installed = collection($installed_apps)->some(function(InstalledAppDTO $app) use ($app_slug) {
return $app->app_slug === $app_slug;
});
if (!$is_installed) {
throw new Exception(esc_html__('App not found in installed apps.', 'kirki'));
}
$base_upload_dir = WP_CONTENT_DIR;
$apps_folder = $base_upload_dir . '/kirki-apps';
$app_folder = $apps_folder . '/' . $app_slug;
$backup_folder = $app_folder . '_backup_' . time();
// Create backup of current app
if (!File::move($app_folder, $backup_folder)) {
throw new Exception(esc_html__('Failed to create backup of current app version.', 'kirki'));
}
$remote_zip_url = KIRKI_APPS_BASE_URL . $src;
$file_name_new = uniqid( '', true ) . '.zip';
$zip_file_path = FileHandler::download_zip_from_remote($remote_zip_url, $file_name_new);
if ($zip_file_path === false) {
// Restore backup
File::move($backup_folder, $app_folder);
throw new Exception(esc_html__('Failed to download the new app version.', 'kirki'));
}
$result = FileHandler::extract_zip_file($zip_file_path, $apps_folder);
File::delete($zip_file_path);
if ($result === false) {
// Restore backup
File::move($backup_folder, $app_folder);
throw new Exception(esc_html__('Failed to extract the new app version.', 'kirki'));
}
try {
$installed_apps = collection($installed_apps)->map(function(InstalledAppDTO $app) use ($app_slug, $new_version) {
if ($app->app_slug === $app_slug) {
$app->version = $new_version;
}
return $app->to_array();
})->to_array();
GlobalData::update(GlobalDataKeys::INSTALLED_APPS, $installed_apps);
} catch (Throwable $throwable) {
if (File::exists($app_folder)) {
File::delete($app_folder);
}
if (File::exists($backup_folder)) {
File::move($backup_folder, $app_folder);
}
throw new Exception(
sprintf(
/* translators: 1: error message */
esc_html__('An error occurred during the app update: %s', 'kirki'),
esc_html($throwable->getMessage())
)
);
}
File::delete($backup_folder);
return [
'app_slug' => $app_slug,
'version' => $new_version
];
}
public function delete_app(string $app_slug)
{
$installed_apps = $this->get_installed_apps();
if (empty($installed_apps)) {
throw new Exception(esc_html__('No apps are currently installed.', 'kirki'));
}
$is_installed = collection($installed_apps)->some(function(InstalledAppDTO $app) use ($app_slug) {
return $app->app_slug === $app_slug;
});
if (!$is_installed) {
throw new Exception(esc_html__('App not found in installed apps.', 'kirki'));
}
$base_upload_dir = WP_CONTENT_DIR; // Absolute path to 'uploads'
$app_folder = $base_upload_dir . '/kirki-apps/' . $app_slug;
$installed_apps = collection($installed_apps)->filter(function(InstalledAppDTO $app) use ($app_slug) {
return $app->app_slug !== $app_slug;
})->map(fn(InstalledAppDTO $app) => $app->to_array())->values()->to_array();
DB::begin_transaction();
try {
GlobalData::update(GlobalDataKeys::INSTALLED_APPS, $installed_apps);
$this->save_app_settings($app_slug, []);
if (!File::delete($app_folder)) {
throw new Exception(esc_html__('Failed to delete the app folder.', 'kirki'));
}
DB::commit();
return true;
} catch (Throwable $throwable) {
DB::rollback();
throw new Exception(
sprintf(
/* translators: 1: error message */
esc_html__('An error occurred during the app deletion: %s', 'kirki'),
esc_html($throwable->getMessage())
)
);
}
}
}