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 (EncodeException $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 //TODO: Remove hardcoded link and set up init path in settings $newFolks = json_decode( file_get_contents(env('FIPAMO_INIT') . '/folks-template.json'), true ); $newSettings = json_decode( file_get_contents(env('FIPAMO_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 //TODO: upate path attribute to use env variable $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 mkdir(env('FIPAMO_CONFIG'), 0755, true); $this->docs->writeSettings($newSettings, env('FIPAMO_CONFIG') . '/settings.json'); $this->docs->writeSettings($newFolks, env('FIPAMO_CONFIG') . '/folks.json'); $this->docs->writeSettings([], env('FIPAMO_CONFIG') . '/tags.json'); $object = (object) $index; $this->docs->writePages( 'create', 'start', env('PAGES_PATH') . '/start/index.md', $this->docs::objectToMD($object) ); $result = ['type' => 'blogInitGood', 'message' => 'Site Created']; return $result; } public function restore($request) { //content required, so check it $result = []; $contentArchive = $request->file('backup-content-upload'); $fileArchive = $request->file('backup-files-upload'); if ($contentArchive == null || $contentArchive == '') { return $result = [ 'type' => 'requestLame', 'message' => 'Content Archive EMPTY', ]; } $result = $this->restoreContent($contentArchive, $request); //file upload is optional, so if it's present, restore it if ($fileArchive != null || $fileArchive != '') { $result = $this->restoreFiles($fileArchive); } return $result; } private function restoreContent($contentUpload, $request) { $contentUpload->move(env('FIPAMO_DIR') . '/', $contentUpload->getClientOriginalName()); $contentZip = new \ZipArchive(); $result = []; $tempDir = env('FIPAMO_DIR') . '/_temp'; if ($contentZip->open(env('FIPAMO_DIR') . '/' . $contentUpload->getClientOriginalName()) === true) { $folks = json_decode($contentZip->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 if ($request->restore_former_url != '' || $request->restore_former_url != null) { $this->moveAssets($contentZip, $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); $contentZip->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(env('FIPAMO_CONFIG'))) { mkdir(env('FIPAMO_CONFIG'), 0755, true); } $this->docs->writeSettings($newConfig, env('FIPAMO_CONFIG') . '/settings.json'); $this->docs->writeSettings($newFolks, env('FIPAMO_CONFIG') . '/folks.json'); rename($tempDir . '/config/tags.json', env('FIPAMO_CONFIG') . '/tags.json'); //move saved markdown pages rename($tempDir . '/content/pages/', env('PAGES_PATH')); //clean up temp dir and zip file $this->docs::deleteFolder($tempDir); $contentZip->close(); unlink(env('FIPAMO_DIR') . '/' . $contentUpload->getClientOriginalName()); $result = [ 'type' => 'requestGood', 'message' => 'Content Restored! Redirecting', ]; } else { $result = [ 'type' => 'requestLame', 'message' => 'Check that password, champ.', ]; } } else { $result = [ 'type' => 'requestLame', 'message' => 'Could not open backup. RATS!', ]; } }; } private function restoreFiles($filesUpload) { $filesUpload->move(env('FIPAMO_DIR') . '/', $filesUpload->getClientOriginalName()); $filesZip = new \ZipArchive(); $tempDir = env('FIPAMO_DIR') . '/_file_temp'; $result = []; //images path for blog and user $blogImagePath = '../public/assets/images/blog'; $userImagePath = '../public/assets/images/user'; if ($filesZip->open(env('FIPAMO_DIR') . '/' . $filesUpload->getClientOriginalName()) === true) { $filesZip->extractTo($tempDir); //clear and move dir if present delete_directory($blogImagePath, false); if (is_dir($tempDir . '/public/assets/images/blog')) { rename($tempDir . '/public/assets/images/blog', $blogImagePath); } delete_directory($userImagePath, false); if (is_dir($tempDir . '/public/assets/images/user')) { rename($tempDir . '/public/assets/images/user', $userImagePath); } $result = [ 'type' => 'requestGood', 'message' => 'Files & Content Restored! Redirecting', ]; } delete_directory($tempDir); $filesZip->close(); unlink(env('FIPAMO_DIR') . '/' . $filesUpload->getClientOriginalName()); 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++; } } } } }