From 661ec831dbf2a18ddda73d8b3b7c8f5df85a9cb3 Mon Sep 17 00:00:00 2001 From: saparatayev Date: Thu, 26 Aug 2021 13:05:51 +0500 Subject: [PATCH] added apigenerator plugin --- plugins/ahmadfatoni/apigenerator/Plugin.php | 18 + plugins/ahmadfatoni/apigenerator/Readme.md | 50 +++ .../ahmadfatoni/apigenerator/composer.json | 8 + .../controllers/ApiGeneratorController.php | 336 ++++++++++++++++++ .../apigenerator/controllers/api/readme.txt | 1 + .../apigeneratorcontroller/_list_toolbar.htm | 18 + .../_reorder_toolbar.htm | 3 + .../apigeneratorcontroller/config_form.yaml | 10 + .../apigeneratorcontroller/config_list.yaml | 11 + .../config_reorder.yaml | 4 + .../apigeneratorcontroller/create.htm | 97 +++++ .../apigeneratorcontroller/index.htm | 1 + .../apigeneratorcontroller/preview.htm | 22 ++ .../apigeneratorcontroller/reorder.htm | 8 + .../apigeneratorcontroller/update.htm | 133 +++++++ .../apigenerator/helpers/Helpers.php | 19 + .../ahmadfatoni/apigenerator/lang/en/lang.php | 6 + .../apigenerator/models/ApiGenerator.php | 76 ++++ .../models/apigenerator/columns.yaml | 9 + .../models/apigenerator/fields.yaml | 33 ++ plugins/ahmadfatoni/apigenerator/plugin.yaml | 17 + plugins/ahmadfatoni/apigenerator/routes.php | 8 + .../apigenerator/template/controller.dot | 99 ++++++ .../apigenerator/template/controller.php | 35 ++ .../template/customcontroller.dot | 83 +++++ .../apigenerator/template/route.dot | 3 + .../apigenerator/template/routes.dot | 6 + ...e_create_ahmadfatoni_apigenerator_data.php | 26 ++ .../apigenerator/updates/version.yaml | 15 + 29 files changed, 1155 insertions(+) create mode 100644 plugins/ahmadfatoni/apigenerator/Plugin.php create mode 100644 plugins/ahmadfatoni/apigenerator/Readme.md create mode 100644 plugins/ahmadfatoni/apigenerator/composer.json create mode 100644 plugins/ahmadfatoni/apigenerator/controllers/ApiGeneratorController.php create mode 100644 plugins/ahmadfatoni/apigenerator/controllers/api/readme.txt create mode 100644 plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/_list_toolbar.htm create mode 100644 plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/_reorder_toolbar.htm create mode 100644 plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/config_form.yaml create mode 100644 plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/config_list.yaml create mode 100644 plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/config_reorder.yaml create mode 100644 plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/create.htm create mode 100644 plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/index.htm create mode 100644 plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/preview.htm create mode 100644 plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/reorder.htm create mode 100644 plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/update.htm create mode 100644 plugins/ahmadfatoni/apigenerator/helpers/Helpers.php create mode 100644 plugins/ahmadfatoni/apigenerator/lang/en/lang.php create mode 100644 plugins/ahmadfatoni/apigenerator/models/ApiGenerator.php create mode 100644 plugins/ahmadfatoni/apigenerator/models/apigenerator/columns.yaml create mode 100644 plugins/ahmadfatoni/apigenerator/models/apigenerator/fields.yaml create mode 100644 plugins/ahmadfatoni/apigenerator/plugin.yaml create mode 100644 plugins/ahmadfatoni/apigenerator/routes.php create mode 100644 plugins/ahmadfatoni/apigenerator/template/controller.dot create mode 100644 plugins/ahmadfatoni/apigenerator/template/controller.php create mode 100644 plugins/ahmadfatoni/apigenerator/template/customcontroller.dot create mode 100644 plugins/ahmadfatoni/apigenerator/template/route.dot create mode 100644 plugins/ahmadfatoni/apigenerator/template/routes.dot create mode 100644 plugins/ahmadfatoni/apigenerator/updates/builder_table_create_ahmadfatoni_apigenerator_data.php create mode 100644 plugins/ahmadfatoni/apigenerator/updates/version.yaml diff --git a/plugins/ahmadfatoni/apigenerator/Plugin.php b/plugins/ahmadfatoni/apigenerator/Plugin.php new file mode 100644 index 000000000..575a4fdf1 --- /dev/null +++ b/plugins/ahmadfatoni/apigenerator/Plugin.php @@ -0,0 +1,18 @@ + October CMS plugin to build RESTful APIs. + +## Features + + - Auto generate routes + - Auto Generate Controller (CRUD) + - Support relationship restful API + +## Install +``` +composer require AhmadFatoni.ApiGenerator +``` + +## Usage + +### Form +- API Name : Name of your API module +- Base Endpoint : Base endpoint of your API, ex : api/v1/modulename +- Short Description : Describe your API +- Model : select model that will be created API +- Custom Condition : Build customer response using JSON modeling + +### Custom Condition Example +``` +{ + 'fillable': 'id,title,content', + 'relation': [{ + 'name': 'user', + 'fillable': 'id,first_name' + }, { + 'name': 'categories', + 'fillable': 'id,name + }] +} +``` +* please replace single quote with quote + +## Contribute + +Pull Requests accepted. + +## Contact + +You can communicate with me using [linkedin](https://www.linkedin.com/in/ahmad-fatoni) + +## License +The OctoberCMS platform is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). diff --git a/plugins/ahmadfatoni/apigenerator/composer.json b/plugins/ahmadfatoni/apigenerator/composer.json new file mode 100644 index 000000000..889212022 --- /dev/null +++ b/plugins/ahmadfatoni/apigenerator/composer.json @@ -0,0 +1,8 @@ +{ + "name": "ahmadfatoni/apigenerator-plugin", + "type": "october-plugin", + "description": "None", + "require": { + "composer/installers": "~1.0" + } +} \ No newline at end of file diff --git a/plugins/ahmadfatoni/apigenerator/controllers/ApiGeneratorController.php b/plugins/ahmadfatoni/apigenerator/controllers/ApiGeneratorController.php new file mode 100644 index 000000000..1eea0a4c4 --- /dev/null +++ b/plugins/ahmadfatoni/apigenerator/controllers/ApiGeneratorController.php @@ -0,0 +1,336 @@ +files = $files; + } + + /** + * delete selected data (multiple delete) + * @return [type] [description] + */ + public function index_onDelete() + { + if (($checkedIds = post('checked')) && is_array($checkedIds) && count($checkedIds)) { + + foreach ($checkedIds as $id) { + if ((!$item = ApiGenerator::find($id))) + continue; + $name = $item->name; + if($item->delete()){ + $this->deleteApi($name); + } + } + + Flash::success('Successfully deleted those data.'); + } + + return $this->listRefresh(); + } + + /** + * generate API + * @param Request $request [description] + * @return [type] [description] + */ + public function generateApi(Request $request){ + + $data['model'] = $request->model; + $modelname = explode("\\", $request->model); + $modelname = $modelname[count($modelname)-1]; + $data['modelname'] = $modelname; + $data['controllername'] = str_replace(" ", "", $request->name); + $data['endpoint'] = $request->endpoint; + $data['custom_format'] = $request->custom_format; + + if( strpos($data['controllername'], ".") OR strpos($data['controllername'], "/") ){ + + Flash::success('Failed to create data, invalid API name.'); + return Redirect::to( Backend::url($this->homePage)); + + } + + if( isset($request->id) ){ + $this->deleteApi($request->oldname, 'false'); + } + + $this->files->put(__DIR__ . $this->path . $data['controllername'].'Controller.php', $this->compile($data)); + + $this->files->put(__DIR__ . '/'.'../routes.php', $this->compileRoute($data)); + + return Redirect::to( Backend::url($this->homePage)); + + } + + /** + * delete available API + * @param [type] $name [description] + * @param [type] $redirect [description] + * @return [type] [description] + */ + public function deleteApi($name, $redirect = null){ + + $fileLocation = __DIR__ . $this->path.$name; + $fileLocation = str_replace(".", "", $fileLocation); + + if( ! file_exists($fileLocation.'Controller.php') ){ + + Flash::success('Failed to delete data, invalid file location.'); + return Redirect::to( Backend::url($this->homePage)); + + } + + if( strpos( strtolower($name), 'apigenerator' ) === false){ + $data = []; + + //generate new route + $this->files->put(__DIR__ . '/'.'../routes.php', $this->compileRoute($data)); + + //remove controller + if (file_exists( __DIR__ . $this->path.$name.'Controller.php' )) { + + unlink(__DIR__ . $this->path.$name.'Controller.php'); + + } + + if( $redirect != null ){ + return 'success without redirect'; + } + } + + return Redirect::to( Backend::url($this->homePage)); + + } + + public function updateApi($name){ + + } + + /** + * compile controller from template + * @param [type] $data [description] + * @return [type] [description] + */ + public function compile($data){ + if( $data['custom_format'] != ''){ + + $template = $this->files->get(__DIR__ .'/../template/customcontroller.dot'); + $template = $this->replaceAttribute($template, $data); + $template = $this->replaceCustomAttribute($template, $data); + }else{ + $template = $this->files->get(__DIR__ .'/../template/controller.dot'); + $template = $this->replaceAttribute($template, $data); + } + return $template; + } + + /** + * replace attribute + * @param [type] $template [description] + * @param [type] $data [description] + * @return [type] [description] + */ + public function replaceAttribute($template, $data){ + if( isset( $data['model'] ) ){ + $template = str_replace('{{model}}', $data['model'], $template); + } + $template = str_replace('{{modelname}}', $data['modelname'], $template); + $template = str_replace('{{controllername}}', $data['controllername'], $template); + return $template; + } + + /** + * replace custom attribute + * @param [type] $template [description] + * @param [type] $data [description] + * @return [type] [description] + */ + public function replaceCustomAttribute($template, $data){ + + $arr = str_replace('\t', '', $data['custom_format']); + $arr = json_decode($arr); + $select = str_replace('
', '', $this->compileOpenIndexFunction($data['modelname'], 'index')); + $show = str_replace('
', '', $this->compileOpenIndexFunction($data['modelname'], 'show')); + $fillableParent = ''; + + if( isset($arr->fillable) AND $arr->fillable != null ) { + $fillableParent = $this->compileFillableParent($arr->fillable); + } + + if( isset($arr->relation) AND $arr->relation != null AND is_array($arr->relation) AND count($arr->relation) > 0) { + $select .= str_replace('
', '', $this->compileFillableChild($arr->relation)); + $show .= str_replace('
', '', $this->compileFillableChild($arr->relation)); + } + + $select .= "->select(".$fillableParent.")"; + $show .= "->select(".$fillableParent.")->where('id', '=', \$id)->first();"; + + ( $fillableParent != '') ? $select .= "->get()->toArray();" : $select .= "->toArray();" ; + + $closeFunction = str_replace('
', '', nl2br( + " + return \$this->helpers->apiArrayResponseBuilder(200, 'success', \$data); + }")); + $select .= $closeFunction; + $show .= $closeFunction; + + $template = str_replace('{{select}}', $select, $template); + $template = str_replace('{{show}}', $show, $template); + + return $template; + } + + public function compileOpenIndexFunction($modelname, $type){ + if( $type == 'index'){ + return nl2br(" + public function index(){ + \$data = \$this->".$modelname); + }else{ + return nl2br(" + public function show(\$id){ + \$data = \$this->".$modelname); + } + + } + + public function compileFillableParent($fillable){ + + $fillableParentArr = explode(",", $fillable); + $fillableParent = ''; + + foreach ($fillableParentArr as $key) { + + $fillableParent .= ",'".$key."'"; + + } + + $fillableParent = substr_replace($fillableParent, '', 0 , 1); + + return $fillableParent; + } + + public function compileFillableChild($fillable){ + + $select = "->with(array("; + + foreach ($fillable as $key) { + + $fillableChild = ""; + + if( isset($key->fillable) AND $key->fillable != null ){ + $fillableChildArr = explode(",", $key->fillable); + + + foreach ($fillableChildArr as $key2) { + + $fillableChild .= ",'".$key2."'"; + + } + + $fillableChild = substr_replace($fillableChild, '', 0 , 1); + } + + $select .= nl2br( + " + '".$key->name."'=>function(\$query){ + \$query->select(".$fillableChild."); + },"); + + } + + $select .= " ))"; + + return $select; + } + + public function compileRoute($data){ + + $oldData = ApiGenerator::all(); + $routeList = ""; + + if( count($oldData) > 0 ){ + + $routeList .= $this->parseRouteOldData($oldData, $data); + + } + + if( count($data) > 0 ){ + $data['modelname'] = $data['endpoint']; + if( $data['modelname'][0] == "/" ){ + $data['modelname'] = substr_replace($data['modelname'], '', 0 , 1); + } + $routeList .= $this->parseRoute($data); + } + + $route = $this->files->get(__DIR__ .'/../template/routes.dot'); + $route = str_replace('{{route}}', $routeList, $route); + + return $route; + + } + + public function parseRouteOldData($oldData, $data = null){ + + $routeList = ""; + + if( count($data) == 0 ) $data['modelname']=''; + + foreach ( $oldData as $key ) { + + $modelname = explode("\\", $key->model); + $modelname = $modelname[count($modelname)-1]; + $old['modelname'] = $key->endpoint; + $old['controllername'] = $key->name; + + if( $data['modelname'] != $modelname ){ + + if( $old['modelname'][0] == "/" ){ + $old['modelname'] = substr_replace($old['modelname'], '', 0 , 1); + } + + $routeList .= $this->parseRoute($old); + } + } + + return $routeList; + + } + + public function parseRoute($data){ + + $template = $this->files->get(__DIR__ .'/../template/route.dot'); + $template = $this->replaceAttribute($template, $data); + return $template; + } + + + public static function getAfterFilters() {return [];} + public static function getBeforeFilters() {return [];} + public function callAction($method, $parameters=false) { + return call_user_func_array(array($this, $method), $parameters); + } +} diff --git a/plugins/ahmadfatoni/apigenerator/controllers/api/readme.txt b/plugins/ahmadfatoni/apigenerator/controllers/api/readme.txt new file mode 100644 index 000000000..f972e8de0 --- /dev/null +++ b/plugins/ahmadfatoni/apigenerator/controllers/api/readme.txt @@ -0,0 +1 @@ +api controller here \ No newline at end of file diff --git a/plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/_list_toolbar.htm b/plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/_list_toolbar.htm new file mode 100644 index 000000000..82a362239 --- /dev/null +++ b/plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/_list_toolbar.htm @@ -0,0 +1,18 @@ +
+ + +
diff --git a/plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/_reorder_toolbar.htm b/plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/_reorder_toolbar.htm new file mode 100644 index 000000000..59b78d088 --- /dev/null +++ b/plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/_reorder_toolbar.htm @@ -0,0 +1,3 @@ +
+ +
\ No newline at end of file diff --git a/plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/config_form.yaml b/plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/config_form.yaml new file mode 100644 index 000000000..9317c6bd1 --- /dev/null +++ b/plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/config_form.yaml @@ -0,0 +1,10 @@ +name: ApiGeneratorController +form: $/ahmadfatoni/apigenerator/models/apigenerator/fields.yaml +modelClass: AhmadFatoni\ApiGenerator\Models\ApiGenerator +defaultRedirect: ahmadfatoni/apigenerator/apigeneratorcontroller +create: + redirect: 'ahmadfatoni/apigenerator/apigeneratorcontroller/update/:id' + redirectClose: ahmadfatoni/apigenerator/apigeneratorcontroller +update: + redirect: ahmadfatoni/apigenerator/apigeneratorcontroller + redirectClose: ahmadfatoni/apigenerator/apigeneratorcontroller diff --git a/plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/config_list.yaml b/plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/config_list.yaml new file mode 100644 index 000000000..d36a63f51 --- /dev/null +++ b/plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/config_list.yaml @@ -0,0 +1,11 @@ +list: $/ahmadfatoni/apigenerator/models/apigenerator/columns.yaml +modelClass: AhmadFatoni\ApiGenerator\Models\ApiGenerator +title: ApiGeneratorController +noRecordsMessage: 'backend::lang.list.no_records' +showSetup: true +showCheckboxes: true +toolbar: + buttons: list_toolbar + search: + prompt: 'backend::lang.list.search_prompt' +recordUrl: 'ahmadfatoni/apigenerator/apigeneratorcontroller/update/:id' diff --git a/plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/config_reorder.yaml b/plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/config_reorder.yaml new file mode 100644 index 000000000..70fda7be8 --- /dev/null +++ b/plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/config_reorder.yaml @@ -0,0 +1,4 @@ +title: ApiGeneratorController +modelClass: AhmadFatoni\ApiGenerator\Models\ApiGenerator +toolbar: + buttons: reorder_toolbar diff --git a/plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/create.htm b/plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/create.htm new file mode 100644 index 000000000..22322c523 --- /dev/null +++ b/plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/create.htm @@ -0,0 +1,97 @@ + + + + +fatalError): ?> + + 'layout']) ?> + +
+ formRender() ?> +
+ + + +
+ +
+ + + + + + +

fatalError)) ?>

+

+ + + \ No newline at end of file diff --git a/plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/index.htm b/plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/index.htm new file mode 100644 index 000000000..ea43a3636 --- /dev/null +++ b/plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/index.htm @@ -0,0 +1 @@ +listRender() ?> diff --git a/plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/preview.htm b/plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/preview.htm new file mode 100644 index 000000000..f259af345 --- /dev/null +++ b/plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/preview.htm @@ -0,0 +1,22 @@ + + + + +fatalError): ?> + +
+ formRenderPreview() ?> +
+ + +

fatalError) ?>

+ + +

+ + + +

\ No newline at end of file diff --git a/plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/reorder.htm b/plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/reorder.htm new file mode 100644 index 000000000..9813ab46a --- /dev/null +++ b/plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/reorder.htm @@ -0,0 +1,8 @@ + + + + +reorderRender() ?> \ No newline at end of file diff --git a/plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/update.htm b/plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/update.htm new file mode 100644 index 000000000..dc6594a46 --- /dev/null +++ b/plugins/ahmadfatoni/apigenerator/controllers/apigeneratorcontroller/update.htm @@ -0,0 +1,133 @@ + + + + +fatalError): ?> + + 'layout']) ?> + +
+ formRender() ?> +
+ + +
+ +
+ + + +

fatalError)) ?>

+

+ + + + + + + + \ No newline at end of file diff --git a/plugins/ahmadfatoni/apigenerator/helpers/Helpers.php b/plugins/ahmadfatoni/apigenerator/helpers/Helpers.php new file mode 100644 index 000000000..1145f7f7a --- /dev/null +++ b/plugins/ahmadfatoni/apigenerator/helpers/Helpers.php @@ -0,0 +1,19 @@ + (isset($statusCode)) ? $statusCode : 500, + 'message' => (isset($message)) ? $message : 'error' + ]; + if (count($data) > 0) { + $arr['data'] = $data; + } + + return response()->json($arr, $arr['status_code']); + //return $arr; + + } +} \ No newline at end of file diff --git a/plugins/ahmadfatoni/apigenerator/lang/en/lang.php b/plugins/ahmadfatoni/apigenerator/lang/en/lang.php new file mode 100644 index 000000000..9ade59ec2 --- /dev/null +++ b/plugins/ahmadfatoni/apigenerator/lang/en/lang.php @@ -0,0 +1,6 @@ + [ + 'name' => 'API-Generator', + 'description' => 'Generate API base on Builder Plugin' + ] +]; \ No newline at end of file diff --git a/plugins/ahmadfatoni/apigenerator/models/ApiGenerator.php b/plugins/ahmadfatoni/apigenerator/models/ApiGenerator.php new file mode 100644 index 000000000..531bfd111 --- /dev/null +++ b/plugins/ahmadfatoni/apigenerator/models/ApiGenerator.php @@ -0,0 +1,76 @@ + 'required|unique:ahmadfatoni_apigenerator_data,name|regex:/^[\pL\s\-]+$/u', + 'endpoint' => 'required|unique:ahmadfatoni_apigenerator_data,endpoint', + 'custom_format' => 'json' + ]; + + public $customMessages = [ + 'custom_format.json' => 'Invalid Json Format Custom Condition' + ]; + + /* + * Disable timestamps by default. + * Remove this line if timestamps are defined in the database table. + */ + public $timestamps = false; + + /** + * @var string The database table used by the model. + */ + public $table = 'ahmadfatoni_apigenerator_data'; + + /** + * get model List + * @return [type] [description] + */ + public function getModelOptions(){ + + return ComponentHelper::instance()->listGlobalModels(); + } + + /** + * [setCustomFormatAttribute description] + * @param [type] $value [description] + */ + public function setCustomFormatAttribute($value){ + + $json = str_replace('\t', '', $value); + $json = json_decode($json); + + if( $json != null){ + + if( ! isset($json->fillable) AND ! isset($json->relation) ){ + + return $this->attributes['custom_format'] = 'invalid format'; + + } + + if( isset($json->relation) AND $json->relation != null ){ + foreach ($json->relation as $key) { + if( !isset($key->name) OR $key->name == null ){ + return $this->attributes['custom_format'] = 'invalid format'; + } + } + } + } + + return $this->attributes['custom_format'] = $value; + + } + +} \ No newline at end of file diff --git a/plugins/ahmadfatoni/apigenerator/models/apigenerator/columns.yaml b/plugins/ahmadfatoni/apigenerator/models/apigenerator/columns.yaml new file mode 100644 index 000000000..58ce8eb61 --- /dev/null +++ b/plugins/ahmadfatoni/apigenerator/models/apigenerator/columns.yaml @@ -0,0 +1,9 @@ +columns: + name: + label: 'API NAME' + type: text + searchable: true + sortable: true + endpoint: + label: 'BASE ENDPOINT' + type: text diff --git a/plugins/ahmadfatoni/apigenerator/models/apigenerator/fields.yaml b/plugins/ahmadfatoni/apigenerator/models/apigenerator/fields.yaml new file mode 100644 index 000000000..a8e6e0bce --- /dev/null +++ b/plugins/ahmadfatoni/apigenerator/models/apigenerator/fields.yaml @@ -0,0 +1,33 @@ +fields: + name: + label: 'API Name' + oc.commentPosition: '' + span: auto + placeholder: 'Name of your API' + required: 1 + type: text + endpoint: + label: 'Base Endpoint' + oc.commentPosition: '' + span: auto + placeholder: api/v1/modulename + required: 1 + type: text + description: + label: 'Short Description' + oc.commentPosition: '' + span: auto + placeholder: 'Descript your API' + type: text + model: + label: 'Select Model' + oc.commentPosition: '' + span: auto + required: 1 + type: dropdown + custom_format: + label: 'Custom Condition (Fillable and Relation)' + size: large + oc.commentPosition: '' + span: full + type: textarea diff --git a/plugins/ahmadfatoni/apigenerator/plugin.yaml b/plugins/ahmadfatoni/apigenerator/plugin.yaml new file mode 100644 index 000000000..598021df5 --- /dev/null +++ b/plugins/ahmadfatoni/apigenerator/plugin.yaml @@ -0,0 +1,17 @@ +plugin: + name: 'ahmadfatoni.apigenerator::lang.plugin.name' + description: 'ahmadfatoni.apigenerator::lang.plugin.description' + author: AhmadFatoni + icon: oc-icon-bolt + homepage: '' +navigation: + api-generator: + label: 'API Generator' + url: ahmadfatoni/apigenerator/apigeneratorcontroller + icon: icon-cogs + permissions: + - ahmadfatoni.apigenerator.manage +permissions: + ahmadfatoni.apigenerator.manage: + tab: 'API Generator' + label: 'Manage the API Generator' diff --git a/plugins/ahmadfatoni/apigenerator/routes.php b/plugins/ahmadfatoni/apigenerator/routes.php new file mode 100644 index 000000000..3b728326c --- /dev/null +++ b/plugins/ahmadfatoni/apigenerator/routes.php @@ -0,0 +1,8 @@ + 'fatoni.generate.api', 'uses' => 'AhmadFatoni\ApiGenerator\Controllers\ApiGeneratorController@generateApi')); +Route::post('fatoni/update/api/{id}', array('as' => 'fatoni.update.api', 'uses' => 'AhmadFatoni\ApiGenerator\Controllers\ApiGeneratorController@updateApi')); +Route::get('fatoni/delete/api/{id}', array('as' => 'fatoni.delete.api', 'uses' => 'AhmadFatoni\ApiGenerator\Controllers\ApiGeneratorController@deleteApi')); + +Route::resource('halo', 'AhmadFatoni\ApiGenerator\Controllers\API\haloController', ['except' => ['destroy', 'create', 'edit']]); +Route::get('halo/{id}/delete', ['as' => 'halo.delete', 'uses' => 'AhmadFatoni\ApiGenerator\Controllers\API\haloController@destroy']); \ No newline at end of file diff --git a/plugins/ahmadfatoni/apigenerator/template/controller.dot b/plugins/ahmadfatoni/apigenerator/template/controller.dot new file mode 100644 index 000000000..ff20ea3aa --- /dev/null +++ b/plugins/ahmadfatoni/apigenerator/template/controller.dot @@ -0,0 +1,99 @@ +{{modelname}} = ${{modelname}}; + $this->helpers = $helpers; + } + + public function index(){ + + $data = $this->{{modelname}}->all()->toArray(); + + return $this->helpers->apiArrayResponseBuilder(200, 'success', $data); + } + + public function show($id){ + + $data = $this->{{modelname}}::find($id); + + if ($data){ + return $this->helpers->apiArrayResponseBuilder(200, 'success', [$data]); + } else { + $this->helpers->apiArrayResponseBuilder(404, 'not found', ['error' => 'Resource id=' . $id . ' could not be found']); + } + + } + + public function store(Request $request){ + + $arr = $request->all(); + + while ( $data = current($arr)) { + $this->{{modelname}}->{key($arr)} = $data; + next($arr); + } + + $validation = Validator::make($request->all(), $this->{{modelname}}->rules); + + if( $validation->passes() ){ + $this->{{modelname}}->save(); + return $this->helpers->apiArrayResponseBuilder(201, 'created', ['id' => $this->{{modelname}}->id]); + }else{ + return $this->helpers->apiArrayResponseBuilder(400, 'fail', $validation->errors() ); + } + + } + + public function update($id, Request $request){ + + $status = $this->{{modelname}}->where('id',$id)->update($data); + + if( $status ){ + + return $this->helpers->apiArrayResponseBuilder(200, 'success', 'Data has been updated successfully.'); + + }else{ + + return $this->helpers->apiArrayResponseBuilder(400, 'bad request', 'Error, data failed to update.'); + + } + } + + public function delete($id){ + + $this->{{modelname}}->where('id',$id)->delete(); + + return $this->helpers->apiArrayResponseBuilder(200, 'success', 'Data has been deleted successfully.'); + } + + public function destroy($id){ + + $this->{{modelname}}->where('id',$id)->delete(); + + return $this->helpers->apiArrayResponseBuilder(200, 'success', 'Data has been deleted successfully.'); + } + + + public static function getAfterFilters() {return [];} + public static function getBeforeFilters() {return [];} + public static function getMiddleware() {return [];} + public function callAction($method, $parameters=false) { + return call_user_func_array(array($this, $method), $parameters); + } + +} \ No newline at end of file diff --git a/plugins/ahmadfatoni/apigenerator/template/controller.php b/plugins/ahmadfatoni/apigenerator/template/controller.php new file mode 100644 index 000000000..f78dde065 --- /dev/null +++ b/plugins/ahmadfatoni/apigenerator/template/controller.php @@ -0,0 +1,35 @@ +{{modelname}} = ${{modelname}}; + } + + public static function getAfterFilters() {return [];} + public static function getBeforeFilters() {return [];} + public static function getMiddleware() {return [];} + public function callAction($method, $parameters=false) { + return call_user_func_array(array($this, $method), $parameters); + } + + // public function create(Request $request){ + + // $arr = $request->all(); + + // while ( $data = current($arr)) { + // $this-> + // } + // return json_encode($this->{{modelname}}->store($request)); + + // } +} diff --git a/plugins/ahmadfatoni/apigenerator/template/customcontroller.dot b/plugins/ahmadfatoni/apigenerator/template/customcontroller.dot new file mode 100644 index 000000000..be5cf6ff2 --- /dev/null +++ b/plugins/ahmadfatoni/apigenerator/template/customcontroller.dot @@ -0,0 +1,83 @@ +{{modelname}} = ${{modelname}}; + $this->helpers = $helpers; + } + + {{select}} + + {{show}} + + public function store(Request $request){ + + $arr = $request->all(); + + while ( $data = current($arr)) { + $this->{{modelname}}->{key($arr)} = $data; + next($arr); + } + + $validation = Validator::make($request->all(), $this->{{modelname}}->rules); + + if( $validation->passes() ){ + $this->{{modelname}}->save(); + return $this->helpers->apiArrayResponseBuilder(201, 'created', ['id' => $this->{{modelname}}->id]); + }else{ + return $this->helpers->apiArrayResponseBuilder(400, 'fail', $validation->errors() ); + } + + } + + public function update($id, Request $request){ + + $status = $this->{{modelname}}->where('id',$id)->update($data); + + if( $status ){ + + return $this->helpers->apiArrayResponseBuilder(200, 'success', 'Data has been updated successfully.'); + + }else{ + + return $this->helpers->apiArrayResponseBuilder(400, 'bad request', 'Error, data failed to update.'); + + } + } + + public function delete($id){ + + $this->{{modelname}}->where('id',$id)->delete(); + + return $this->helpers->apiArrayResponseBuilder(200, 'success', 'Data has been deleted successfully.'); + } + + public function destroy($id){ + + $this->{{modelname}}->where('id',$id)->delete(); + + return $this->helpers->apiArrayResponseBuilder(200, 'success', 'Data has been deleted successfully.'); + } + + + public static function getAfterFilters() {return [];} + public static function getBeforeFilters() {return [];} + public static function getMiddleware() {return [];} + public function callAction($method, $parameters=false) { + return call_user_func_array(array($this, $method), $parameters); + } + +} diff --git a/plugins/ahmadfatoni/apigenerator/template/route.dot b/plugins/ahmadfatoni/apigenerator/template/route.dot new file mode 100644 index 000000000..515cb53c9 --- /dev/null +++ b/plugins/ahmadfatoni/apigenerator/template/route.dot @@ -0,0 +1,3 @@ + +Route::resource('{{modelname}}', 'AhmadFatoni\ApiGenerator\Controllers\API\{{controllername}}Controller', ['except' => ['destroy', 'create', 'edit']]); +Route::get('{{modelname}}/{id}/delete', ['as' => '{{modelname}}.delete', 'uses' => 'AhmadFatoni\ApiGenerator\Controllers\API\{{controllername}}Controller@destroy']); \ No newline at end of file diff --git a/plugins/ahmadfatoni/apigenerator/template/routes.dot b/plugins/ahmadfatoni/apigenerator/template/routes.dot new file mode 100644 index 000000000..ddafe5901 --- /dev/null +++ b/plugins/ahmadfatoni/apigenerator/template/routes.dot @@ -0,0 +1,6 @@ + 'fatoni.generate.api', 'uses' => 'AhmadFatoni\ApiGenerator\Controllers\ApiGeneratorController@generateApi')); +Route::post('fatoni/update/api/{id}', array('as' => 'fatoni.update.api', 'uses' => 'AhmadFatoni\ApiGenerator\Controllers\ApiGeneratorController@updateApi')); +Route::get('fatoni/delete/api/{id}', array('as' => 'fatoni.delete.api', 'uses' => 'AhmadFatoni\ApiGenerator\Controllers\ApiGeneratorController@deleteApi')); +{{route}} \ No newline at end of file diff --git a/plugins/ahmadfatoni/apigenerator/updates/builder_table_create_ahmadfatoni_apigenerator_data.php b/plugins/ahmadfatoni/apigenerator/updates/builder_table_create_ahmadfatoni_apigenerator_data.php new file mode 100644 index 000000000..44cdc81e3 --- /dev/null +++ b/plugins/ahmadfatoni/apigenerator/updates/builder_table_create_ahmadfatoni_apigenerator_data.php @@ -0,0 +1,26 @@ +engine = 'InnoDB'; + $table->increments('id'); + $table->string('name'); + $table->string('endpoint'); + $table->string('model'); + $table->string('description')->nullable(); + $table->text('custom_format')->nullable(); + }); + } + + public function down() + { + Schema::dropIfExists('ahmadfatoni_apigenerator_data'); + } +} diff --git a/plugins/ahmadfatoni/apigenerator/updates/version.yaml b/plugins/ahmadfatoni/apigenerator/updates/version.yaml new file mode 100644 index 000000000..966ff307a --- /dev/null +++ b/plugins/ahmadfatoni/apigenerator/updates/version.yaml @@ -0,0 +1,15 @@ +1.0.1: + - 'Initialize plugin.' +1.0.2: + - 'Database implementation' +1.0.3: + - 'add builder plugin on requirements dependency' + - builder_table_create_ahmadfatoni_apigenerator_data.php +1.0.4: + - 'fixing bug on PHP 7' +1.0.5: + - 'fixing bug on request delete data' +1.0.6: + - 'fixing bug on generate endpoint' +1.0.7: + - 'fixing bug on October CMS v1.0.456' \ No newline at end of file