FEATURE: Restore to default

plugged in a new feature that will allow the site to be reset to its
default state, clearing out all content and configurations to start
fresh
This commit is contained in:
ro 2024-07-02 17:09:27 -06:00
parent 4723db98d5
commit bc7b1fe7ec
No known key found for this signature in database
GPG key ID: 29B551CDBD4D3B50
8 changed files with 144 additions and 7 deletions

View file

@ -1,6 +1,6 @@
<?php <?php
function delete_directory($dirPath) function delete_directory($dirPath, $catch = true)
{ {
if (is_dir($dirPath)) { if (is_dir($dirPath)) {
$objects = new DirectoryIterator($dirPath); $objects = new DirectoryIterator($dirPath);
@ -15,7 +15,11 @@ function delete_directory($dirPath)
} }
rmdir($dirPath); rmdir($dirPath);
} else { } else {
throw new Exception(__FUNCTION__ . '(dirPath): dirPath is not a directory!'); if ($catch) {
throw new Exception(__FUNCTION__ . '(dirPath): dirPath is not a directory!');
} else {
//just keep going
}
} }
} }

View file

@ -5,14 +5,17 @@ namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use App\Services\UpKeep\InitService; use App\Services\UpKeep\InitService;
use App\Services\UpKeep\ResetService;
class InitAPIController extends Controller class InitAPIController extends Controller
{ {
protected $init; protected $init;
protected $reset;
public function __construct(InitService $initService) public function __construct(InitService $initService, ResetService $resetService)
{ {
$this->init = $initService; $this->init = $initService;
$this->reset = $resetService;
} }
//init stuff //init stuff
@ -27,4 +30,10 @@ class InitAPIController extends Controller
$result = $this->init->restore($request); $result = $this->init->restore($request);
return response()->json($result)->header('Content-Type', 'application/json'); return response()->json($result)->header('Content-Type', 'application/json');
} }
public function setupReset(Request $request)
{
$result = $this->reset->site($request);
return response()->json($result)->header('Content-Type', 'application/json');
}
} }

View file

@ -22,6 +22,7 @@ use App\Services\Data\SortingService;
//Upkeep Services //Upkeep Services
use App\Services\Upkeep\MaintenanceService; use App\Services\Upkeep\MaintenanceService;
use App\Services\Upkeep\InitService; use App\Services\Upkeep\InitService;
use App\Services\Upkeep\ResetService;
class FipamoServiceProvider extends ServiceProvider class FipamoServiceProvider extends ServiceProvider
{ {
@ -92,6 +93,10 @@ class FipamoServiceProvider extends ServiceProvider
$this->app->bind(InitService::class, function ($app) { $this->app->bind(InitService::class, function ($app) {
return new InitService(new DocService()); return new InitService(new DocService());
}); });
$this->app->bind(ResetService::class, function ($app) {
return new ResetService();
});
} }
/** /**

View file

@ -0,0 +1,70 @@
<?php
namespace App\Services\Upkeep;
class ResetService
{
private $protectedItems = ['assets', '.htaccess', 'index.php', 'robots.txt'];
public function __construct()
{
}
public function site()
{
$response = [];
try {
$this->clearPublicAssets();
$this->clearPublicRoot();
$this->clearContent();
session()->flush();
$response = [
'message' => "PUBLIC CLEARED",
'type' => "COOL",
];
} catch (\Throwable $e) {
$response = [
'message' => "RESET NOT COMPLETED",
'error' => $e,
'type' => "ERROR",
];
}
return $response;
}
private function clearContent()
{
$contentDir = env('FIPAMO_DIR');
delete_directory($contentDir . '/pages', false);
delete_directory($contentDir . '/config', false);
}
private function clearPublicAssets()
{
delete_directory('../public/assets/docs', false);
delete_directory('../public/assets/video', false);
delete_directory('../public/assets/css/theme', false);
delete_directory('../public/assets/scripts/theme', false);
delete_directory('../public/assets/images/blog', false);
delete_directory('../public/assets/images/user', false);
}
private function clearPublicRoot()
{
$publicItems = glob('../public/*');
$response = [];
foreach ($publicItems as $path) {
$item = explode('/', $path);
if (in_array($item[2], $this->protectedItems)) {
//protected item do nothing
} else {
if (is_file($path)) {
unlink($path);
} else {
delete_directory($path);
}
}
}
}
}

View file

@ -10,6 +10,7 @@ export const CONTENT_TYPE_FORM = 'x-www-form-urlencoded';
export const API_STATUS = '/api/v1/status'; export const API_STATUS = '/api/v1/status';
export const API_INIT = '/api/v1/init'; export const API_INIT = '/api/v1/init';
export const API_RESTORE = '/api/v1/restore'; export const API_RESTORE = '/api/v1/restore';
export const API_RESET = '/api/v1/reset';
export const API_GET_SECRET = '/api/v1/get-secret'; export const API_GET_SECRET = '/api/v1/get-secret';
export const API_RESET_PASS = '/api/v1/reset-password'; export const API_RESET_PASS = '/api/v1/reset-password';
export const API_CREATE_BACKUP = '/api/v1/backup/create'; export const API_CREATE_BACKUP = '/api/v1/backup/create';
@ -123,6 +124,29 @@ class MaintenanceManager {
}); });
}); });
} }
/**
* Promise method for restoring site to default state
*/
reset(data) {
return new Promise((resolve, reject) => {
this._request(
API_RESET,
null,
TASK_SITE_INIT,
REQUEST_TYPE_POST,
CONTENT_TYPE_JSON,
data
)
.then(result => {
resolve(result);
})
.catch(err => {
reject(err);
});
});
}
/** /**
* Promise method for creating a zip back up of current site. For local use only. * Promise method for creating a zip back up of current site. For local use only.
*/ */

View file

@ -90,6 +90,31 @@ export default class SettingsIndex {
} }
}); });
//handle site reset
document.getElementById('reset-to-default').addEventListener('click', e => {
if (
confirm(
'You are about to restore the site to its default state!\n' +
'This cannot be undone, so please confirm.'
)
) {
this.mm
.reset()
.then(r => {
if (r.type == 'COOL') {
window.location = '/';
} else {
notify.alert(r.message, true);
}
})
.catch(() => {
//console.log(err)
});
} else {
// Do nothing!
}
});
//handle tabs //handle tabs
let tabBtn = document.querySelectorAll('.tab-button'); let tabBtn = document.querySelectorAll('.tab-button');
let tabs = document.querySelectorAll('.section-tab'); let tabs = document.querySelectorAll('.section-tab');

View file

@ -117,7 +117,6 @@
<span>COMING SOON</span> <span>COMING SOON</span>
</div> </div>
--> -->
<!-- TODO: Reset site to defualt
<div class="option-container"> <div class="option-container">
<svg id="nav-menu-icon" class="icon"> <svg id="nav-menu-icon" class="icon">
<use id="nav-menu-icon" xlink:href="/assets/images/global/sprite.svg#entypo-back-in-time"/> <use id="nav-menu-icon" xlink:href="/assets/images/global/sprite.svg#entypo-back-in-time"/>
@ -125,9 +124,8 @@
<button id="reset-to-default"> <button id="reset-to-default">
<span>RESET TO DEFAULT</span> <span>RESET TO DEFAULT</span>
</button> </button>
<span>COMING SOON</span> <span>Restores site to default state. !CANNOT UNDO!</span>
</div> </div>
-->s
</div> </div>
</section> </section>
<section id="site-themes" class="section-tab hide"> <section id="site-themes" class="section-tab hide">

View file

@ -35,5 +35,7 @@ Route::get("/v1/backup/download", [SettingsAPIController::class, 'downloadBackup
//init //init
Route::post("/v1/init", [InitAPIController::class, 'setupFresh']); Route::post("/v1/init", [InitAPIController::class, 'setupFresh']);
Route::post("/v1/restore", [InitAPIController::class, 'setupRestore']); Route::post("/v1/restore", [InitAPIController::class, 'setupRestore']);
Route::post("/v1/reset", [InitAPIController::class, 'setupReset']);
//mail //mail
Route::post("/v1/mailer", [MailAPIController::class, 'sendNotify']); Route::post("/v1/mailer", [MailAPIController::class, 'sendNotify']);