added apigenerator plugin

This commit is contained in:
saparatayev 2021-08-26 13:05:51 +05:00
parent 423713d7e9
commit 661ec831db
29 changed files with 1155 additions and 0 deletions

View File

@ -0,0 +1,18 @@
<?php namespace AhmadFatoni\ApiGenerator;
use System\Classes\PluginBase;
class Plugin extends PluginBase
{
public $require = [
'RainLab.Builder'
];
public function registerComponents()
{
}
public function registerSettings()
{
}
}

View File

@ -0,0 +1,50 @@
# API Generator
> 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).

View File

@ -0,0 +1,8 @@
{
"name": "ahmadfatoni/apigenerator-plugin",
"type": "october-plugin",
"description": "None",
"require": {
"composer/installers": "~1.0"
}
}

View File

@ -0,0 +1,336 @@
<?php namespace AhmadFatoni\ApiGenerator\Controllers;
use Backend\Classes\Controller;
use AhmadFatoni\ApiGenerator\Models\ApiGenerator;
use BackendMenu;
use Backend;
use Illuminate\Http\Request;
use Illuminate\Filesystem\Filesystem;
use Redirect;
use Flash;
class ApiGeneratorController extends Controller
{
public $implement = ['Backend\Behaviors\ListController','Backend\Behaviors\FormController','Backend\Behaviors\ReorderController'];
public $listConfig = 'config_list.yaml';
public $formConfig = 'config_form.yaml';
public $reorderConfig = 'config_reorder.yaml';
protected $path = "/api/";
private $homePage = 'ahmadfatoni/apigenerator/apigeneratorcontroller';
protected $files;
public $requiredPermissions = ['ahmadfatoni.apigenerator.manage'];
public function __construct(Filesystem $files)
{
parent::__construct();
BackendMenu::setContext('AhmadFatoni.ApiGenerator', 'api-generator');
$this->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('<br />', '', $this->compileOpenIndexFunction($data['modelname'], 'index'));
$show = str_replace('<br />', '', $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('<br />', '', $this->compileFillableChild($arr->relation));
$show .= str_replace('<br />', '', $this->compileFillableChild($arr->relation));
}
$select .= "->select(".$fillableParent.")";
$show .= "->select(".$fillableParent.")->where('id', '=', \$id)->first();";
( $fillableParent != '') ? $select .= "->get()->toArray();" : $select .= "->toArray();" ;
$closeFunction = str_replace('<br />', '', 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);
}
}

View File

@ -0,0 +1 @@
api controller here

View File

@ -0,0 +1,18 @@
<div data-control="toolbar">
<a href="<?= Backend::url('ahmadfatoni/apigenerator/apigeneratorcontroller/create') ?>" class="btn btn-primary oc-icon-plus"><?= e(trans('backend::lang.form.create')) ?></a>
<button
class="btn btn-default oc-icon-trash-o"
disabled="disabled"
onclick="$(this).data('request-data', {
checked: $('.control-list').listWidget('getChecked')
})"
data-request="onDelete"
data-request-confirm="<?= e(trans('backend::lang.list.delete_selected_confirm')) ?>"
data-trigger-action="enable"
data-trigger=".control-list input[type=checkbox]"
data-trigger-condition="checked"
data-request-success="$(this).prop('disabled', true)"
data-stripe-load-indicator>
<?= e(trans('backend::lang.list.delete_selected')) ?>
</button>
</div>

View File

@ -0,0 +1,3 @@
<div data-control="toolbar">
<a href="<?= Backend::url('ahmadfatoni/apigenerator/apigeneratorcontroller') ?>" class="btn btn-primary oc-icon-caret-left"><?= e(trans('backend::lang.form.return_to_list')) ?></a>
</div>

View File

@ -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

View File

@ -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'

View File

@ -0,0 +1,4 @@
title: ApiGeneratorController
modelClass: AhmadFatoni\ApiGenerator\Models\ApiGenerator
toolbar:
buttons: reorder_toolbar

View File

@ -0,0 +1,97 @@
<?php Block::put('breadcrumb') ?>
<ul>
<li><a href="<?= Backend::url('ahmadfatoni/apigenerator/apigeneratorcontroller') ?>">ApiListController</a></li>
<li><?= e($this->pageTitle) ?></li>
</ul>
<?php Block::endPut() ?>
<?php if (!$this->fatalError): ?>
<?= Form::open(['class' => 'layout']) ?>
<div class="layout-row">
<?= $this->formRender() ?>
</div>
<div class="modal fade" id="modal-id">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">Custom Condition</h4>
</div>
<div class="modal-body">
<?php
$data = '{
"fillable": "id,title,content",
"relation": [{
"name": "user",
"fillable": "id,first_name"
}, {
"name": "categories",
"fillable": "id,name"
}]
}';
echo $data ;
?>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<div class="form-buttons">
<div class="loading-indicator-container">
<button
type="submit"
data-request="onSave"
data-request-success="saveData()"
data-hotkey="ctrl+s, cmd+s"
data-load-indicator="<?= e(trans('backend::lang.form.saving')) ?>"
class="btn btn-primary">
<?= e(trans('backend::lang.form.create')) ?>
</button>
<a data-toggle="modal" href='#modal-id'>
<button type="button" class="btn btn-default">
Example Custom Condition
</button>
</a>
<a href="<?= Backend::url('ahmadfatoni/apigenerator/apigeneratorcontroller') ?>" class="btn btn-warning">Cancel</a>
</div>
</div>
<?= Form::close() ?>
<form method="post" id="generate" accept-charset="utf-8" action="<?= route('fatoni.generate.api') ?>" style="display:none">
<input type='text' name='name' id="name">
<input type='text' name='model' id="model">
<input type='text' name='custom_format' id="custom_format">
<input type='text' name='endpoint' id="endpoint">
<button
type="submit"
class="btn btn-primary" name="send" id="send">
send
</button>
</form>
<?php else: ?>
<p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
<p><a href="<?= Backend::url('ahmadfatoni/apigenerator/apigeneratorcontroller') ?>" class="btn btn-default"><?= e(trans('backend::lang.form.return_to_list')) ?></a></p>
<?php endif ?>
<script type="text/javascript">
function saveData(){
document.getElementById('name').value = document.getElementById('Form-field-ApiGenerator-name').value;
document.getElementById('model').value = document.getElementById('Form-field-ApiGenerator-model').value;
document.getElementById('custom_format').value = document.getElementById('Form-field-ApiGenerator-custom_format').value;
document.getElementById('endpoint').value = document.getElementById('Form-field-ApiGenerator-endpoint').value;
document.getElementById('send').click();
}
</script>

View File

@ -0,0 +1 @@
<?= $this->listRender() ?>

View File

@ -0,0 +1,22 @@
<?php Block::put('breadcrumb') ?>
<ul>
<li><a href="<?= Backend::url('ahmadfatoni/apigenerator/apigeneratorcontroller') ?>">ApiGeneratorController</a></li>
<li><?= e($this->pageTitle) ?></li>
</ul>
<?php Block::endPut() ?>
<?php if (!$this->fatalError): ?>
<div class="form-preview">
<?= $this->formRenderPreview() ?>
</div>
<?php else: ?>
<p class="flash-message static error"><?= e($this->fatalError) ?></p>
<?php endif ?>
<p>
<a href="<?= Backend::url('ahmadfatoni/apigenerator/apigeneratorcontroller') ?>" class="btn btn-default oc-icon-chevron-left">
<?= e(trans('backend::lang.form.return_to_list')) ?>
</a>
</p>

View File

@ -0,0 +1,8 @@
<?php Block::put('breadcrumb') ?>
<ul>
<li><a href="<?= Backend::url('ahmadfatoni/apigenerator/apigeneratorcontroller') ?>">ApiGeneratorController</a></li>
<li><?= e($this->pageTitle) ?></li>
</ul>
<?php Block::endPut() ?>
<?= $this->reorderRender() ?>

View File

@ -0,0 +1,133 @@
<?php Block::put('breadcrumb') ?>
<ul>
<li><a href="<?= Backend::url('ahmadfatoni/apigenerator/apigeneratorcontroller') ?>">ApiListController</a></li>
<li><?= e($this->pageTitle) ?></li>
</ul>
<?php Block::endPut() ?>
<?php if (!$this->fatalError): ?>
<?= Form::open(['class' => 'layout']) ?>
<div class="layout-row">
<?= $this->formRender() ?>
</div>
<div class="modal fade" id="modal-id">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">Custom Condition</h4>
</div>
<div class="modal-body">
<?php
$data = '{
"fillable": "id,title,content",
"relation": [{
"name": "user",
"fillable": "id,first_name"
}, {
"name": "categories",
"fillable": "id,name"
}]
}';
echo $data ;
?>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<div class="form-buttons">
<div class="loading-indicator-container">
<button
type="submit"
data-request="onSave"
data-request-success="saveData()"
data-request-data="redirect:0"
data-hotkey="ctrl+s, cmd+s"
data-load-indicator="<?= e(trans('backend::lang.form.saving')) ?>"
class="btn btn-primary">
<?= e(trans('backend::lang.form.save')) ?>
</button>
<a href="<?= Backend::url('ahmadfatoni/apigenerator/apigeneratorcontroller') ?>" class="btn btn-warning"><div id="cancel">Cancel</div></a>
<button
type="button"
class="oc-icon-trash-o btn-icon danger pull-right"
data-request="onDelete"
data-request-success="delData()"
data-load-indicator="<?= e(trans('backend::lang.form.deleting')) ?>"
data-request-confirm="<?= e(trans('backend::lang.form.confirm_delete')) ?>">
</button>
<a data-toggle="modal" href='#modal-id'>
<button type="button" class="btn btn-default">
Example Custom Condition
</button>
</a>
</div>
</div>
<?= Form::close() ?>
<?php else: ?>
<p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
<p><a href="<?= Backend::url('ahmadfatoni/apigenerator/apigeneratorcontroller') ?>" class="btn btn-default"><?= e(trans('backend::lang.form.return_to_list')) ?></a></p>
<?php endif ?>
<form method="get" id="del" style="display:none" action="<?= route('fatoni.delete.api', ['id'=> $this->widget->form->data->attributes['name'] ]) ?>">
<button
type="submit"
class="btn btn-primary" name="send" id="send">
send
</button>
</form>
<form method="post" id="generate" accept-charset="utf-8" action="<?= route('fatoni.generate.api') ?>" style="display:none">
<input type='text' name='id' id="id" value="<?= $this->widget->form->data->attributes['id'] ?>">
<input type='text' name='name' id="name">
<input type='text' name='endpoint' id="endpoint">
<input type='text' name='oldname' id="oldname" value="<?= $this->widget->form->data->attributes['name'] ?>">
<input type='text' name='oldmodel' id="oldmodel" value="<?= $this->widget->form->data->attributes['model'] ?>">
<input type='text' name='oldendpoint' id="oldendpoint" value="<?= $this->widget->form->data->attributes['endpoint'] ?>">
<textarea name='oldcustom_format' id="oldcustom_format"><?= $this->widget->form->data->attributes['custom_format'] ?></textarea>
<input type='text' name='model' id="model">
<input type='text' name='custom_format' id="custom_format">
<button
type="submit"
class="btn btn-primary" name="save" id="save">
send
</button>
</form>
<script type="text/javascript">
function delData(){
document.getElementById('send').click();
}
</script>
<script type="text/javascript">
function saveData(){
document.getElementById('name').value = document.getElementById('Form-field-ApiGenerator-name').value;
document.getElementById('model').value = document.getElementById('Form-field-ApiGenerator-model').value;
document.getElementById('custom_format').value = document.getElementById('Form-field-ApiGenerator-custom_format').value;
document.getElementById('endpoint').value = document.getElementById('Form-field-ApiGenerator-endpoint').value;
if (
document.getElementById('name').value != document.getElementById('oldname').value ||
document.getElementById('Form-field-ApiGenerator-model').value != document.getElementById('oldmodel').value ||
document.getElementById('Form-field-ApiGenerator-custom_format').value != document.getElementById('oldcustom_format').value ||
document.getElementById('Form-field-ApiGenerator-endpoint').value != document.getElementById('oldendpoint').value
){
document.getElementById('save').click();
}else{
document.getElementById('cancel').click();
}
}
</script>

View File

@ -0,0 +1,19 @@
<?php namespace AhmadFatoni\ApiGenerator\Helpers;
Class Helpers {
public function apiArrayResponseBuilder($statusCode = null, $message = null, $data = [])
{
$arr = [
'status_code' => (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;
}
}

View File

@ -0,0 +1,6 @@
<?php return [
'plugin' => [
'name' => 'API-Generator',
'description' => 'Generate API base on Builder Plugin'
]
];

View File

@ -0,0 +1,76 @@
<?php namespace AhmadFatoni\ApiGenerator\Models;
use Model, Log;
use RainLab\Builder\Classes\ComponentHelper;
/**
* Model
*/
class ApiGenerator extends Model
{
use \October\Rain\Database\Traits\Validation;
/*
* Validation
*/
public $rules = [
'name' => '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;
}
}

View File

@ -0,0 +1,9 @@
columns:
name:
label: 'API NAME'
type: text
searchable: true
sortable: true
endpoint:
label: 'BASE ENDPOINT'
type: text

View File

@ -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

View File

@ -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'

View File

@ -0,0 +1,8 @@
<?php
Route::post('fatoni/generate/api', array('as' => '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']);

View File

@ -0,0 +1,99 @@
<?php namespace AhmadFatoni\ApiGenerator\Controllers\API;
use Cms\Classes\Controller;
use BackendMenu;
use Illuminate\Http\Request;
use AhmadFatoni\ApiGenerator\Helpers\Helpers;
use Illuminate\Support\Facades\Validator;
use {{model}};
class {{controllername}}Controller extends Controller
{
protected ${{modelname}};
protected $helpers;
public function __construct({{modelname}} ${{modelname}}, Helpers $helpers)
{
parent::__construct();
$this->{{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);
}
}

View File

@ -0,0 +1,35 @@
<?php namespace AhmadFatoni\ApiGenerator\Controllers\API;
use Cms\Classes\Controller;
use BackendMenu;
use Illuminate\Http\Request;
use {{model}};
class ApiListController extends Controller
{
protected ${{modelname}};
public function __construct({{modelname}} ${{modelname}})
{
parent::__construct();
$this->{{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));
// }
}

View File

@ -0,0 +1,83 @@
<?php namespace AhmadFatoni\ApiGenerator\Controllers\API;
use Cms\Classes\Controller;
use BackendMenu;
use Illuminate\Http\Request;
use AhmadFatoni\ApiGenerator\Helpers\Helpers;
use {{model}};
class {{controllername}}Controller extends Controller
{
protected ${{modelname}};
protected $helpers;
public function __construct({{modelname}} ${{modelname}}, Helpers $helpers)
{
parent::__construct();
$this->{{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);
}
}

View File

@ -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']);

View File

@ -0,0 +1,6 @@
<?php
Route::post('fatoni/generate/api', array('as' => '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}}

View File

@ -0,0 +1,26 @@
<?php namespace AhmadFatoni\ApiGenerator\Updates;
use Schema;
use October\Rain\Database\Updates\Migration;
class BuilderTableCreateAhmadfatoniApigeneratorData extends Migration
{
public function up()
{
Schema::create('ahmadfatoni_apigenerator_data', function($table)
{
$table->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');
}
}

View File

@ -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'