plugin installer

This commit is contained in:
Ibnu Maksum 2024-06-12 17:02:52 +07:00
parent 6a4ac274d1
commit ba0cc20708
No known key found for this signature in database
GPG Key ID: 7FC82848810579E5
4 changed files with 182 additions and 72 deletions

5
.gitignore vendored
View File

@ -40,3 +40,8 @@ system/lan/**
!system/lan/english.json !system/lan/english.json
!system/lan/country.json !system/lan/country.json
*.zip *.zip
system/devices/**
!system/devices/readme.md
!system/devices/Radius.php
!system/devices/MikrotikPppoe.php
!system/devices/MikrotikHotspot.php

View File

@ -33,6 +33,83 @@ if (file_exists($cache) && time() - filemtime($cache) < (24 * 60 * 60)) {
$json = json_decode($data, true); $json = json_decode($data, true);
} }
switch ($action) { switch ($action) {
case 'dlinstall':
if (!is_writeable($CACHE_PATH)) {
r2(U . "pluginmanager", 'e', 'Folder cache/ is not writable');
}
if (!is_writeable($PLUGIN_PATH)) {
r2(U . "pluginmanager", 'e', 'Folder plugin/ is not writable');
}
if (!is_writeable($DEVICE_PATH)) {
r2(U . "pluginmanager", 'e', 'Folder devices/ is not writable');
}
if (!is_writeable($UI_PATH . DIRECTORY_SEPARATOR . 'themes')) {
r2(U . "pluginmanager", 'e', 'Folder themes/ is not writable');
}
$cache = $CACHE_PATH . DIRECTORY_SEPARATOR . 'installer' . DIRECTORY_SEPARATOR;
if (!file_exists($cache)) {
mkdir($cache);
}
if (file_exists($_FILES['zip_plugin']['tmp_name'])) {
$zip = new ZipArchive();
$zip->open($_FILES['zip_plugin']['tmp_name']);
$zip->extractTo($cache);
$zip->close();
unlink($_FILES['zip_plugin']['tmp_name']);
//moving
if (file_exists($cache . 'plugin')) {
File::copyFolder($cache . 'plugin' . DIRECTORY_SEPARATOR, $PLUGIN_PATH . DIRECTORY_SEPARATOR);
}
if (file_exists($cache . 'paymentgateway')) {
File::copyFolder($cache . 'paymentgateway' . DIRECTORY_SEPARATOR, $PAYMENTGATEWAY_PATH . DIRECTORY_SEPARATOR);
}
if (file_exists($cache . 'theme')) {
File::copyFolder($cache . 'theme' . DIRECTORY_SEPARATOR, $UI_PATH . DIRECTORY_SEPARATOR . 'themes' . DIRECTORY_SEPARATOR);
}
if (file_exists($cache . 'device')) {
File::copyFolder($cache . 'device' . DIRECTORY_SEPARATOR, $DEVICE_PATH . DIRECTORY_SEPARATOR);
}
//Cleaning
File::deleteFolder($cache);
r2(U . "pluginmanager", 's', 'Installation success');
} else if (_post('gh_url', '') != '') {
$ghUrl = _post('gh_url', '');
$plugin = basename($ghUrl);
$file = $cache . $plugin . '.zip';
$fp = fopen($file, 'w+');
$ch = curl_init($ghUrl . '/archive/refs/heads/master.zip');
curl_setopt($ch, CURLOPT_POST, 0);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_exec($ch);
curl_close($ch);
fclose($fp);
$zip = new ZipArchive();
$zip->open($file);
$zip->extractTo($cache);
$zip->close();
$folder = $cache . DIRECTORY_SEPARATOR . $plugin . '-main' . DIRECTORY_SEPARATOR;
if (file_exists($folder . 'plugin')) {
File::copyFolder($folder . 'plugin' . DIRECTORY_SEPARATOR, $PLUGIN_PATH . DIRECTORY_SEPARATOR);
}
if (file_exists($folder . 'paymentgateway')) {
File::copyFolder($folder . 'paymentgateway' . DIRECTORY_SEPARATOR, $PAYMENTGATEWAY_PATH . DIRECTORY_SEPARATOR);
}
if (file_exists($folder . 'theme')) {
File::copyFolder($folder . 'theme' . DIRECTORY_SEPARATOR, $UI_PATH . DIRECTORY_SEPARATOR . 'themes' . DIRECTORY_SEPARATOR);
}
if (file_exists($folder . 'device')) {
File::copyFolder($folder . 'device' . DIRECTORY_SEPARATOR, $DEVICE_PATH . DIRECTORY_SEPARATOR);
}
File::deleteFolder($cache);
r2(U . "pluginmanager", 's', 'Installation success');
} else {
r2(U . 'pluginmanager', 'e', 'Nothing Installed');
}
break;
case 'delete': case 'delete':
if (!is_writeable($CACHE_PATH)) { if (!is_writeable($CACHE_PATH)) {
r2(U . "pluginmanager", 'e', 'Folder cache/ is not writable'); r2(U . "pluginmanager", 'e', 'Folder cache/ is not writable');
@ -180,17 +257,17 @@ function scanAndRemovePath($source, $target)
$files = scandir($source); $files = scandir($source);
foreach ($files as $file) { foreach ($files as $file) {
if (is_file($source . $file)) { if (is_file($source . $file)) {
if(file_exists($target.$file)){ if (file_exists($target . $file)) {
unlink($target . $file); unlink($target . $file);
} }
} else if (is_dir($source . $file) && !in_array($file, ['.', '..'])) { } else if (is_dir($source . $file) && !in_array($file, ['.', '..'])) {
scanAndRemovePath($source. $file. DIRECTORY_SEPARATOR, $target. $file. DIRECTORY_SEPARATOR); scanAndRemovePath($source . $file . DIRECTORY_SEPARATOR, $target . $file . DIRECTORY_SEPARATOR);
if(file_exists($target.$file)){ if (file_exists($target . $file)) {
rmdir($target . $file); rmdir($target . $file);
} }
} }
} }
if(file_exists($target)){ if (file_exists($target)) {
rmdir($target); rmdir($target);
} }
} }

View File

@ -635,5 +635,6 @@
"": "", "": "",
"Device": "Device", "Device": "Device",
"Expired_Internet_Plan": "Expired Internet Plan", "Expired_Internet_Plan": "Expired Internet Plan",
"When_Expired__customer_will_be_move_to_selected_internet_plan": "When Expired, customer will be move to selected internet plan" "When_Expired__customer_will_be_move_to_selected_internet_plan": "When Expired, customer will be move to selected internet plan",
"Plugin_Installer": "Plugin Installer"
} }

View File

@ -1,7 +1,32 @@
{include file="sections/header.tpl"} {include file="sections/header.tpl"}
<div class="row">
<div class="col-sm-12"> <form method="post" enctype="multipart/form-data" onsubmit="return confirm('Warning, installing unknown source can damage your server, continue?')" action="{$_url}pluginmanager/dlinstall">
<div class="panel panel-primary panel-hovered"> <div class="panel panel-primary panel-hovered">
<div class="panel-heading">
{Lang::T('Plugin Installer')}
<div class="btn-group pull-right">
<a class="btn btn-warning btn-xs" title="save" href="https://github.com/hotspotbilling/phpnuxbill/wiki/Installing-Plugin-or-Payment-Gateway" target="_blank"><span
class="glyphicon glyphicon-info-sign" aria-hidden="true"></span></a>
</div>
</div>
<div class="panel-body row">
<div class="form-group col-md-4">
<label>Upload Zip Plugin/Theme/Device</label>
<input type="file" name="zip_plugin" accept="application/zip" onchange="this.submit()">
</div>
<div class="form-group col-md-7">
<label>Github url</label>
<input type="url" class="form-control" name="gh_url" placeholder="https://github.com/username/repository">
</div>
<div class="col-md-1">
<br>
<button type="submit" class="btn btn-primary">Install</button>
</div>
</div>
</div>
</form>
<div class="panel panel-primary panel-hovered">
<div class="panel-heading">{Lang::T('Plugin')}</div> <div class="panel-heading">{Lang::T('Plugin')}</div>
<div class="panel-body row"> <div class="panel-body row">
{foreach $plugins as $plugin} {foreach $plugins as $plugin}
@ -23,21 +48,23 @@
class="glyphicon glyphicon-align-left"></i> Source</a> class="glyphicon glyphicon-align-left"></i> Source</a>
</div> </div>
<div class="btn-group btn-group-justified" role="group" aria-label="..."> <div class="btn-group btn-group-justified" role="group" aria-label="...">
<a href="{$_url}pluginmanager/delete/plugin/{$plugin['id']}" onclick="return confirm('{Lang::T('Delete')}?')" class="btn btn-danger"><i <a href="{$_url}pluginmanager/delete/plugin/{$plugin['id']}"
onclick="return confirm('{Lang::T('Delete')}?')" class="btn btn-danger"><i
class="glyphicon glyphicon-trash"></i> Delete</a> class="glyphicon glyphicon-trash"></i> Delete</a>
<a {if $zipExt } href="{$_url}pluginmanager/install/plugin/{$plugin['id']}" <a {if $zipExt } href="{$_url}pluginmanager/install/plugin/{$plugin['id']}"
onclick="return confirm('Installing plugin will take some time to complete, do not close the page while it loading to install the plugin')" onclick="return confirm('Installing plugin will take some time to complete, do not close the page while it loading to install the plugin')"
{else} href="#" onclick="alert('PHP ZIP extension is not installed')" {else} href="#" onclick="alert('PHP ZIP extension is not installed')"
{/if} style="color: black;" {/if}
class="btn btn-success"><i class="glyphicon glyphicon-circle-arrow-down"></i> Install</a> style="color: black;" class="btn btn-success"><i
class="glyphicon glyphicon-circle-arrow-down"></i> Install</a>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
{/foreach} {/foreach}
</div> </div>
</div> </div>
<div class="panel panel-primary panel-hovered"> <div class="panel panel-primary panel-hovered">
<div class="panel-heading">{Lang::T('Payment Gateway')}</div> <div class="panel-heading">{Lang::T('Payment Gateway')}</div>
<div class="panel-body row"> <div class="panel-body row">
{foreach $pgs as $pg} {foreach $pgs as $pg}
@ -59,14 +86,14 @@
<a {if $zipExt } href="{$_url}pluginmanager/install/payment/{$pg['id']}" <a {if $zipExt } href="{$_url}pluginmanager/install/payment/{$pg['id']}"
onclick="return confirm('Installing plugin will take some time to complete, do not close the page while it loading to install the plugin')" onclick="return confirm('Installing plugin will take some time to complete, do not close the page while it loading to install the plugin')"
{else} href="#" onclick="alert('PHP ZIP extension is not available')" {else} href="#" onclick="alert('PHP ZIP extension is not available')"
{/if} style="color: black;" {/if}
class="btn btn-success"><i class="glyphicon glyphicon-circle-arrow-down"></i> Install</a> style="color: black;" class="btn btn-success"><i
class="glyphicon glyphicon-circle-arrow-down"></i> Install</a>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
{/foreach} {/foreach}
</div> </div>
</div> </div>
</div>
{include file="sections/footer.tpl"} {include file="sections/footer.tpl"}