ro
234453b900
the back up process did not include saving document and video assets so that needed to be updated to save all of those references along with images once that was done, the restore process had to be updated to look for docs and videos and create the corresponding directories to move them too the script responsible for moving those assets was also streamlined so a seperate process was not needed for each asset type. the last update date in the settings template was displaying incorrectly, so that was fixed as well.
218 lines
8.6 KiB
PHP
218 lines
8.6 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use ReallySimpleJWT\Token;
|
|
use ReallySimpleJWT\Exception\BuildException;
|
|
use Carbon\Carbon;
|
|
|
|
use function _\find;
|
|
|
|
class InitService
|
|
{
|
|
protected $docs;
|
|
|
|
public function __construct(DocService $docService)
|
|
{
|
|
$this->docs = $docService;
|
|
}
|
|
|
|
private static function validSecret($length)
|
|
{
|
|
$alphanum = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
$special = '*&!@%^#$';
|
|
$alphabet = $alphanum . $special;
|
|
$random = openssl_random_pseudo_bytes($length);
|
|
$alphabet_length = strlen($alphabet);
|
|
$string = '';
|
|
for ($i = 0; $i < $length; ++$i) {
|
|
$string .= $alphabet[ord($random[$i]) % $alphabet_length];
|
|
}
|
|
//secret needs to be a valid token
|
|
if ($length == 12) {
|
|
try {
|
|
$secret = Token::create(12, $string, time() + 3600, 'localhost');
|
|
return $string;
|
|
} catch (BuildException $e) {
|
|
//bad secret, so try agiain
|
|
return self::validSecret(12);
|
|
}
|
|
|
|
if (Token::validate($key, $string)) {
|
|
return $string;
|
|
} else {
|
|
return self::validSecret(12);
|
|
}
|
|
}
|
|
}
|
|
|
|
public function fresh($body)
|
|
{
|
|
//grab template files
|
|
$newFolks = json_decode(
|
|
file_get_contents('../content/config/init/folks-template.json'),
|
|
true
|
|
);
|
|
$newSettings = json_decode(
|
|
file_get_contents('../content/config/init/settings-template.json'),
|
|
true
|
|
);
|
|
//get form values
|
|
//$body = $request->getParsedBody();
|
|
$handle = $body->new_member_handle;
|
|
$email = $body->new_member_email;
|
|
$pass = $body->new_member_pass;
|
|
$title = $body->new_member_title;
|
|
|
|
$now = Carbon::now();
|
|
//setup folks config
|
|
$hash = password_hash($pass, PASSWORD_DEFAULT);
|
|
$newFolks[0]['id'] = 0;
|
|
$newFolks[0]['handle'] = $handle;
|
|
$newFolks[0]['email'] = $email;
|
|
$newFolks[0]['password'] = $hash;
|
|
$newFolks[0]['key'] = password_hash($email, PASSWORD_DEFAULT);
|
|
$newFolks[0]['secret'] = self::validSecret(12);
|
|
$newFolks[0]['role'] = 'hnic';
|
|
$newFolks[0]['created'] = $now->format("Y-m-d\TH:i:sP");
|
|
$newFolks[0]['updated'] = $now->format("Y-m-d\TH:i:sP");
|
|
//set up settings config
|
|
$newSettings['global']['title'] = $title;
|
|
|
|
//create index file
|
|
$index = [
|
|
'id' => 1,
|
|
'uuid' => createUUID(),
|
|
'title' => 'FIRST!',
|
|
'imageList' => '/assets/images/global/default-bg.jpg',
|
|
'fileList' => '',
|
|
'path' => 'content/pages/start',
|
|
'layout' => 'index',
|
|
'tags' => 'start, welcome',
|
|
'author' => $handle,
|
|
'created' => $now->format("Y-m-d\TH:i:sP"),
|
|
'updated' => $now->format("Y-m-d\TH:i:sP"),
|
|
'deleted' => 'false',
|
|
'slug' => 'first',
|
|
'menu' => 'false',
|
|
'featured' => 'false',
|
|
'published' => 'true',
|
|
'content' => "# F**k Yes \n\nIf you're seeing this, you're up and running. NICE WORK!\n\nFrom here, feel free to start dropping pages to your heart's content.\n\nFor some tips about using Fipamo, check out the ![docs](https://code.playvicio.us/Are0h/Fipamo/wiki/02-Usage)\n\nAll good? Feel free to edit this page to whatever you want!\n\nYOU'RE THE CAPTAIN NOW.",
|
|
];
|
|
|
|
//once all files created, write down
|
|
$this->docs->writeSettings($newSettings, '../content/config/settings.json');
|
|
$this->docs->writeSettings($newFolks, '../content/config/folks.json');
|
|
$this->docs->writeSettings([], '../content/config/tags.json');
|
|
$object = (object) $index;
|
|
|
|
$this->docs->writePages(
|
|
'create',
|
|
'start',
|
|
'../content/pages/start/index.md',
|
|
$this->docs::objectToMD($object)
|
|
);
|
|
|
|
$result = ['type' => 'blogInitGood', 'message' => 'Site Created'];
|
|
|
|
return $result;
|
|
}
|
|
|
|
public function restore($request)
|
|
{
|
|
$file = $request->file('backup-upload');
|
|
$file->move('../content' . '/', $file->getClientOriginalName());
|
|
$zip = new \ZipArchive();
|
|
$result = [];
|
|
$tempDir = '../content/_temp';
|
|
if ($zip->open('../content' . '/' . $file->getClientOriginalName()) === true) {
|
|
$folks = json_decode($zip->getFromName('config/folks.json'), true);
|
|
$found = find($folks, ['handle' => $request->restore_member_handle]);
|
|
if ($found) {
|
|
if (password_verify($request->restore_member_pass, $found['password'])) {
|
|
//restore assets from previous site
|
|
$this->moveAssets($zip, $request->restore_former_url);
|
|
$newFolks = [];
|
|
if (!isset($found['secret'])) {
|
|
$found['secret'] = self::validSecret(12);
|
|
}
|
|
array_push($newFolks, $found);
|
|
//make temp folder and dump file in there
|
|
mkdir($tempDir, 0755, true);
|
|
$zip->extractTo($tempDir);
|
|
//load up old config file
|
|
$newConfig = json_decode(
|
|
file_get_contents($tempDir . '/config/settings.json'),
|
|
true
|
|
);
|
|
//check for key, add if not there
|
|
if (!isset($newConfig['global']['externalAPI'])) {
|
|
$newConfig['global']['externalAPI'] = 'false';
|
|
}
|
|
//make dir and write new config files
|
|
if (!is_dir('../content/config/')) {
|
|
mkdir('../content/config/', 0755, true);
|
|
}
|
|
$this->docs->writeSettings($newConfig, '../content/config/settings.json');
|
|
$this->docs->writeSettings($newFolks, '../content/config/folks.json');
|
|
rename($tempDir . '/config/tags.json', '../content/config/tags.json');
|
|
//move saved markdown pages
|
|
rename($tempDir . '/content/pages/', '../content/pages');
|
|
//clean up temp dir and zip file
|
|
$this->docs::deleteFolder($tempDir);
|
|
$zip->close();
|
|
unlink('../content/' . $file->getClientOriginalName());
|
|
$result = [
|
|
'type' => 'requestGood',
|
|
'message' => 'Site Restored! Redirecting',
|
|
];
|
|
} else {
|
|
$result = [
|
|
'type' => 'requestLame',
|
|
'message' => 'Check that password, champ.',
|
|
];
|
|
}
|
|
} else {
|
|
$result = [
|
|
'type' => 'requestLame',
|
|
'message' => 'Could not open backup. RATS!',
|
|
];
|
|
}
|
|
};
|
|
return $result;
|
|
}
|
|
|
|
private function moveAssets($zip, $url)
|
|
{
|
|
$assetFail = 0;
|
|
$assetList = [];
|
|
array_push($assetList, json_decode($zip->getFromName('assets/blog_images.json'), true));
|
|
array_push($assetList, json_decode($zip->getFromName('assets/user_images.json'), true));
|
|
array_push($assetList, json_decode($zip->getFromName('assets/blog_docs.json'), true));
|
|
array_push($assetList, json_decode($zip->getFromName('assets/blog_videos.json'), true));
|
|
foreach ($assetList as $list) {
|
|
foreach ($list as $asset) {
|
|
$path = explode('/', $asset['path']);
|
|
$type = $path[3];
|
|
$section = $path[4];
|
|
$year = $path[5];
|
|
$month = $path[6];
|
|
$blogDir = '../public/assets/' . $type . '/' . $section . '/' . $year . '/' . $month;
|
|
if (!is_dir($blogDir)) {
|
|
mkdir($blogDir, 0755, true);
|
|
}
|
|
$externalPath = '/assets/' . $type . '/' . $section . '/' . $year . '/' . $month;
|
|
$asset_url = $url . $externalPath . '/' . $asset['file'];
|
|
try {
|
|
file_put_contents(
|
|
$asset['path'] . '/' . $asset['file'],
|
|
file_get_contents($asset_url)
|
|
);
|
|
} catch (\Throwable $e) {
|
|
$assetFail++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|