2024-04-16 23:36:57 +02:00
< ? php
2024-05-13 06:14:53 +02:00
namespace App\Services\Upkeep ;
2024-04-16 23:36:57 +02:00
use ReallySimpleJWT\Token ;
2024-06-03 05:33:20 +02:00
use ReallySimpleJWT\Exception\EncodeException ;
2024-06-03 05:00:52 +02:00
use App\Services\Assets\DocService ;
2024-04-16 23:36:57 +02:00
use Carbon\Carbon ;
2024-04-18 22:36:05 +02:00
use function _\find ;
2024-04-16 23:36:57 +02:00
class InitService
{
protected $docs ;
2024-07-10 00:26:01 +02:00
protected $filePaths = [];
2024-04-16 23:36:57 +02:00
public function __construct ( DocService $docService )
{
2024-07-10 00:26:01 +02:00
$this -> docs = $docService ;
$this -> filePaths = [ '../public/assets/images/blog' ,
'../public/assets/images/user' , '../public/assets/video/blog' ,
'../public/assets/docs/blog' , '../public/assets/sound/blog' ];
2024-04-16 23:36:57 +02:00
}
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 ;
2024-06-03 05:33:20 +02:00
} catch ( EncodeException $e ) {
2024-04-16 23:36:57 +02:00
//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
2024-06-03 05:04:42 +02:00
//TODO: Remove hardcoded link and set up init path in settings
2024-04-16 23:36:57 +02:00
$newFolks = json_decode (
2024-06-12 22:53:10 +02:00
file_get_contents ( env ( 'FIPAMO_INIT' ) . '/folks-template.json' ),
2024-04-16 23:36:57 +02:00
true
);
$newSettings = json_decode (
2024-06-12 22:53:10 +02:00
file_get_contents ( env ( 'FIPAMO_INIT' ) . '/settings-template.json' ),
2024-04-16 23:36:57 +02:00
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 \T H:i:sP " );
$newFolks [ 0 ][ 'updated' ] = $now -> format ( " Y-m-d \T H:i:sP " );
//set up settings config
$newSettings [ 'global' ][ 'title' ] = $title ;
//create index file
2024-06-12 22:53:10 +02:00
//TODO: upate path attribute to use env variable
2024-04-16 23:36:57 +02:00
$index = [
2024-09-04 22:32:36 +02:00
'id' => 0 ,
2024-04-16 23:36:57 +02:00
'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 \T H:i:sP " ),
'updated' => $now -> format ( " Y-m-d \T H:i:sP " ),
'deleted' => 'false' ,
'slug' => 'first' ,
'menu' => 'false' ,
'featured' => 'false' ,
'published' => 'true' ,
'content' => " # F**k Yes \n \n If you're seeing this, you're up and running. NICE WORK! \n \n From here, feel free to start dropping pages to your heart's content. \n \n For some tips about using Fipamo, check out the ![docs](https://code.playvicio.us/Are0h/Fipamo/wiki/02-Usage) \n \n All good? Feel free to edit this page to whatever you want! \n \n YOU'RE THE CAPTAIN NOW. " ,
];
//once all files created, write down
2024-06-12 22:53:10 +02:00
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' );
2024-04-16 23:36:57 +02:00
$object = ( object ) $index ;
$this -> docs -> writePages (
'create' ,
'start' ,
2024-06-12 22:53:10 +02:00
env ( 'PAGES_PATH' ) . '/start/index.md' ,
2024-04-16 23:36:57 +02:00
$this -> docs :: objectToMD ( $object )
);
$result = [ 'type' => 'blogInitGood' , 'message' => 'Site Created' ];
return $result ;
}
2024-04-18 22:36:05 +02:00
public function restore ( $request )
{
2024-07-05 21:17:53 +02:00
//content required, so check it
2024-07-10 00:26:01 +02:00
2024-07-05 21:17:53 +02:00
$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 );
2024-07-10 00:26:01 +02:00
if ( $result [ 'type' ] == 'requestLame' ) {
return $result ;
}
2024-07-05 21:17:53 +02:00
//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 );
2024-04-18 22:36:05 +02:00
$found = find ( $folks , [ 'handle' => $request -> restore_member_handle ]);
if ( $found ) {
if ( password_verify ( $request -> restore_member_pass , $found [ 'password' ])) {
2024-04-22 21:11:51 +02:00
//restore assets from previous site
2024-06-12 22:59:07 +02:00
if ( $request -> restore_former_url != '' || $request -> restore_former_url != null ) {
2024-07-05 21:17:53 +02:00
$this -> moveAssets ( $contentZip , $request -> restore_former_url );
2024-06-12 22:59:07 +02:00
}
2024-04-18 22:36:05 +02:00
$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 );
2024-07-05 21:17:53 +02:00
$contentZip -> extractTo ( $tempDir );
2024-04-18 22:36:05 +02:00
//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
2024-06-12 22:53:10 +02:00
if ( ! is_dir ( env ( 'FIPAMO_CONFIG' ))) {
mkdir ( env ( 'FIPAMO_CONFIG' ), 0755 , true );
2024-04-18 22:36:05 +02:00
}
2024-06-12 22:53:10 +02:00
$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' );
2024-04-18 22:36:05 +02:00
//move saved markdown pages
2024-06-12 22:53:10 +02:00
rename ( $tempDir . '/content/pages/' , env ( 'PAGES_PATH' ));
2024-04-18 22:36:05 +02:00
//clean up temp dir and zip file
$this -> docs :: deleteFolder ( $tempDir );
2024-07-05 21:17:53 +02:00
$contentZip -> close ();
unlink ( env ( 'FIPAMO_DIR' ) . '/' . $contentUpload -> getClientOriginalName ());
2024-04-18 22:36:05 +02:00
$result = [
'type' => 'requestGood' ,
2024-07-05 21:17:53 +02:00
'message' => 'Content Restored! Redirecting' ,
2024-04-18 22:36:05 +02:00
];
} else {
$result = [
'type' => 'requestLame' ,
'message' => 'Check that password, champ.' ,
];
}
} else {
$result = [
'type' => 'requestLame' ,
2024-07-10 00:26:01 +02:00
'message' => 'Uh Oh. Check that handle' ,
2024-04-18 22:36:05 +02:00
];
}
};
2024-07-10 00:26:01 +02:00
return $result ;
2024-07-05 21:17:53 +02:00
}
private function restoreFiles ( $filesUpload )
{
$filesUpload -> move ( env ( 'FIPAMO_DIR' ) . '/' , $filesUpload -> getClientOriginalName ());
$filesZip = new \ZipArchive ();
$tempDir = env ( 'FIPAMO_DIR' ) . '/_file_temp' ;
$result = [];
if ( $filesZip -> open ( env ( 'FIPAMO_DIR' ) . '/' . $filesUpload -> getClientOriginalName ()) === true ) {
$filesZip -> extractTo ( $tempDir );
//clear and move dir if present
2024-07-10 00:26:01 +02:00
foreach ( $this -> filePaths as $path ) {
delete_directory ( $path , false );
//non image directories don't exist, so they need to be created
$pathing = explode ( " / " , $path );
if ( $pathing [ 3 ] != 'images' ) {
if ( ! is_dir ( '../public/assets/' . $pathing [ 3 ])) {
mkdir ( '../public/assets/' . $pathing [ 3 ]);
}
}
$tempPath = $tempDir . '/' . substr ( $path , 3 );
if ( is_dir ( $tempPath )) {
rename ( $tempPath , $path );
}
2024-07-05 21:17:53 +02:00
}
$result = [
'type' => 'requestGood' ,
'message' => 'Files & Content Restored! Redirecting' ,
];
}
delete_directory ( $tempDir );
$filesZip -> close ();
unlink ( env ( 'FIPAMO_DIR' ) . '/' . $filesUpload -> getClientOriginalName ());
2024-04-18 22:36:05 +02:00
return $result ;
}
2024-04-22 21:11:51 +02:00
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 ++ ;
}
}
}
}
2024-04-16 23:36:57 +02:00
}