Skip to content

Commit 41207f5

Browse files
committed
import & export schema json/zip
1 parent def9c96 commit 41207f5

File tree

3 files changed

+475
-2
lines changed

3 files changed

+475
-2
lines changed

src/Schema/controller.php

+355
Original file line numberDiff line numberDiff line change
@@ -588,3 +588,358 @@
588588

589589
$this->package('global')->redirect($redirect);
590590
});
591+
592+
/**
593+
* Process the Model Export
594+
*
595+
* @param Request $request
596+
* @param Response $response`
597+
*/
598+
$this->get('/admin/system/schema/export', function($request, $response) {
599+
//get the name
600+
$name = $request->getStage('name');
601+
//get the config path
602+
$path = $this->package('global')->path('config') . '/schema/';
603+
//default redirect
604+
$redirect = '/admin/system/schema/search';
605+
606+
//specific schema?
607+
if (!is_null($name)) {
608+
//determine the file
609+
$file = $path . $name . '.php';
610+
611+
//file does not exists?
612+
if (!file_exists($file)) {
613+
//add a flash
614+
$this->package('global')->flash('Not Found', 'error');
615+
return $this->package('global')->redirect($redirect);
616+
}
617+
618+
//get the filename
619+
$filename = str_replace('.php', '.json', basename($file));
620+
621+
//prepare response
622+
$response
623+
->addHeader('Content-Encoding', 'UTF-8')
624+
->addHeader('Content-Type', 'text/html; charset=UTF-8')
625+
->addHeader('Content-Disposition', 'attachment; filename=' . $filename);
626+
627+
//include the php file
628+
$content = json_encode(include($file), JSON_PRETTY_PRINT);
629+
630+
//return content
631+
return $response->setContent($content);
632+
}
633+
634+
//check if ZipArchive is installed
635+
if (!class_exists('ZipArchive')) {
636+
//add a flash
637+
$this->package('global')->flash('ZipArchive module not found', 'error');
638+
return $this->package('global')->redirect($redirect);
639+
}
640+
641+
//create zip archive
642+
$zip = new ZipArchive();
643+
//create temporary file
644+
$tmp = sys_get_temp_dir() . '/schema.zip';
645+
646+
//try to open
647+
if (!$zip->open($tmp, ZipArchive::CREATE | ZipArchive::OVERWRITE)) {
648+
//add a flash
649+
$this->package('global')->flash('Failed to create archive', 'error');
650+
return $this->package('global')->redirect($redirect);
651+
}
652+
653+
//create an empty directory
654+
$zip->addEmptyDir('schema');
655+
656+
//collect all .php files and add it
657+
foreach(glob($path . '*.php') as $file) {
658+
//determin json filename
659+
$name = str_replace('.php', '.json', basename($file));
660+
//read the content
661+
$content = json_encode(include($file), JSON_PRETTY_PRINT);
662+
663+
//add the content to zip
664+
$zip->addFromString('schema/' . $name, $content);
665+
}
666+
667+
//close
668+
$zip->close();
669+
670+
//check if file exists
671+
if (!file_exists($tmp)) {
672+
//add a flash
673+
$this->package('global')->flash('Failed to create archive', 'error');
674+
return $this->package('global')->redirect($redirect);
675+
}
676+
677+
//prepare response
678+
$response
679+
->addHeader('Content-Type', 'application/zip')
680+
->addHeader('Content-Transfer-Encoding', 'Binary')
681+
->addHeader('Content-Disposition', 'attachment; filename=' . basename($tmp))
682+
->addHeader('Content-Length', filesize($tmp));
683+
684+
return $response->setContent(file_get_contents($tmp));
685+
});
686+
687+
/**
688+
* Render the Model Import
689+
*
690+
* @param Request $request
691+
* @param Response $response
692+
*/
693+
$this->get('/admin/system/schema/import', function($request, $response) {
694+
//----------------------------//
695+
// 1. Prepare Data
696+
$data = ['item' => $request->getPost()];
697+
698+
//if this is a return back from processing
699+
//this form and it's because of an error
700+
if ($response->isError()) {
701+
//pass the error messages to the template
702+
$response->setFlash(json_encode($response->getValidation()), 'error');
703+
$data['errors'] = $response->getValidation();
704+
}
705+
706+
//add CSRF
707+
$this->trigger('csrf-load', $request, $response);
708+
$data['csrf'] = $response->getResults('csrf');
709+
710+
//----------------------------//
711+
// 2. Render Template
712+
//set the class name
713+
$class = 'page-admin-system-schema-import page-admin';
714+
715+
//determine the action
716+
$data['action'] = 'import';
717+
718+
//determine the title
719+
$data['title'] = $this->package('global')->translate('Import System Schema');
720+
721+
$template = __DIR__ . '/template';
722+
if (is_dir($response->getPage('template_root'))) {
723+
$template = $response->getPage('template_root');
724+
}
725+
726+
$partials = __DIR__ . '/template';
727+
if (is_dir($response->getPage('partials_root'))) {
728+
$partials = $response->getPage('partials_root');
729+
}
730+
731+
//render the body
732+
$body = $this
733+
->package('cradlephp/cradle-system')
734+
->template(
735+
'import',
736+
$data,
737+
[],
738+
$template,
739+
$partials
740+
);
741+
742+
//if we only want the body
743+
if ($request->getStage('render') === 'body') {
744+
return;
745+
}
746+
747+
//set content
748+
$response
749+
->setPage('title', $data['title'])
750+
->setPage('class', $class)
751+
->setContent($body);
752+
}, 'admin-render-page');
753+
754+
/**
755+
* Process the Model Import
756+
*
757+
* @param Request $request
758+
* @param Response $response
759+
*/
760+
$this->post('/admin/system/schema/import', function($request, $response) {
761+
//get the content
762+
$schema = $request->getStage('schema');
763+
//get the config path
764+
$config = $this->package('global')->path('config') . '/schema/';
765+
//get the type
766+
$type = substr($schema, 5, strpos($schema, ';base64') - 5);
767+
//get the route
768+
$route = '/admin/system/schema/import';
769+
//get the redirect
770+
$redirect = '/admin/system/schema/search';
771+
772+
//invalid file?
773+
if ($type !== 'application/json' && $type !== 'application/zip') {
774+
$response->setError(true, 'Invalid File');
775+
return $this->routeTo('get', $route, $request, $response);
776+
}
777+
778+
//decode the content
779+
$content = base64_decode(
780+
substr($schema, strpos($schema, ';base64,') + 8)
781+
);
782+
783+
//json file?
784+
if ($type === 'application/json') {
785+
//parse the content
786+
$content = json_decode($content, true);
787+
788+
//if not name or is not an array
789+
if (!is_array($content) || !isset($content['name'])) {
790+
$response->setError(true, 'Invalid Schema');
791+
return $this->routeTo('get', $route, $request, $response);
792+
}
793+
794+
//create payload
795+
$payload = $this->makePayload();
796+
797+
//set schema to stage
798+
$payload['request']->setStage($content);
799+
//cleanup
800+
$payload['request']->removeStage('schema');
801+
802+
//trigger update
803+
if (file_exists(sprintf('%s%s.%s', $config, $content['name'], 'php'))) {
804+
$this->trigger('system-schema-update', $payload['request'], $payload['response']);
805+
806+
//trigger create
807+
} else {
808+
$this->trigger('system-schema-create', $payload['request'], $payload['response']);
809+
}
810+
811+
//error?
812+
if ($payload['response']->isError()) {
813+
$response
814+
->set('json', 'validation', [
815+
$content['name'] => [
816+
'message' => $payload['response']->getMessage(),
817+
'validation' => $payload['response']->getValidation()
818+
]
819+
])
820+
->setError(true, $payload['response']->getMessage());
821+
822+
return $this->routeTo('get', $route, $request, $response);
823+
}
824+
825+
//record logs
826+
$this->log(
827+
sprintf(
828+
'imported schema: %s',
829+
$content['name']
830+
),
831+
$request,
832+
$response,
833+
'import',
834+
'schema',
835+
$content['name']
836+
);
837+
838+
//it was good
839+
//add a flash
840+
$this->package('global')->flash('System Schema was Imported', 'success');
841+
//redirect
842+
return $this->package('global')->redirect($redirect);
843+
}
844+
845+
//get temporary folder
846+
$tmp = sys_get_temp_dir();
847+
//create temporary zip
848+
$file = sprintf('%s/%s.zip', $tmp, uniqid());
849+
850+
//create temporary zip file
851+
file_put_contents($file, $content);
852+
853+
//check if ZipArchive is installed
854+
if (!class_exists('ZipArchive')) {
855+
$response->setError(true, 'ZipArchive module not found');
856+
return $this->routeTo('get', $route, $request, $response);
857+
}
858+
859+
//open zip archive
860+
$zip = new ZipArchive();
861+
862+
//try to open
863+
if (!$zip->open($file)) {
864+
$response->setError(true, 'Failed to parse archive');
865+
return $this->routeTo('get', $route, $request, $response);
866+
}
867+
868+
//errors
869+
$errors = [];
870+
871+
//loop through files
872+
for($i = 0; $i < $zip->numFiles; $i++){
873+
//get the filename
874+
$filename = $zip->getNameIndex($i);
875+
876+
//root or not under schema?
877+
if ($filename === 'schema/'
878+
|| strpos($filename , 'schema/') === false) {
879+
continue;
880+
}
881+
882+
//parse the content of each filename
883+
$content = json_decode($zip->getFromName($filename), true);
884+
//create payload
885+
$payload = $this->makePayload();
886+
887+
//skip if schema doesn't have name or is not an array
888+
if (!isset($content['name']) || !is_array($content)) {
889+
continue;
890+
}
891+
892+
//set the content
893+
$payload['request']->setStage($content);
894+
//cleanup
895+
$payload['request']->removeStage('schema');
896+
897+
//trigger update
898+
if (file_exists(sprintf('%s%s.%s', $config, $content['name'], 'php'))) {
899+
$this->trigger('system-schema-update', $payload['request'], $payload['response']);
900+
901+
//trigger create
902+
} else {
903+
$this->trigger('system-schema-create', $payload['request'], $payload['response']);
904+
}
905+
906+
//error?
907+
if ($payload['response']->isError()) {
908+
//set the message and validation
909+
$errors[$content['name']] = array(
910+
'message' => $payload['response']->getMessage(),
911+
'validation' => $payload['response']->getValidation()
912+
);
913+
914+
continue;
915+
}
916+
917+
//record logs
918+
$this->log(
919+
sprintf(
920+
'imported schema: %s',
921+
$content['name']
922+
),
923+
$request,
924+
$response,
925+
'import',
926+
'schema',
927+
$content['name']
928+
);
929+
}
930+
931+
//errors?
932+
if (!empty($errors)) {
933+
$response
934+
->set('json', 'validation', $errors)
935+
->setError(true, 'Invalid Parameters');
936+
937+
return $this->routeTo('get', $route, $request, $response);
938+
}
939+
940+
//it was good
941+
//add a flash
942+
$this->package('global')->flash('System Schema was Imported', 'success');
943+
//redirect
944+
return $this->package('global')->redirect($redirect);
945+
});

0 commit comments

Comments
 (0)