mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-05-24 02:14:21 -04:00
Implement Fractal API output
This commit is contained in:
parent
6c874274b6
commit
8ae8300785
@ -8,12 +8,14 @@ use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class AccountController extends Controller
|
||||
class AccountController extends BaseController
|
||||
{
|
||||
use DispatchesJobs;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->middleware('guest');
|
||||
}
|
||||
|
||||
|
160
app/Http/Controllers/BaseController.php
Normal file
160
app/Http/Controllers/BaseController.php
Normal file
@ -0,0 +1,160 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Transformers\ArraySerializer;
|
||||
use App\Transformers\EntityTransformer;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Input;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use League\Fractal\Manager;
|
||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||
use League\Fractal\Resource\Collection;
|
||||
use League\Fractal\Resource\Item;
|
||||
use League\Fractal\Serializer\JsonApiSerializer;
|
||||
|
||||
class BaseController extends Controller
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->manager = new Manager();
|
||||
|
||||
if ($include = request()->input('include')) {
|
||||
$this->manager->parseIncludes($include);
|
||||
}
|
||||
|
||||
$this->serializer = request()->input('serializer') ?: EntityTransformer::API_SERIALIZER_ARRAY;
|
||||
|
||||
if ($this->serializer === EntityTransformer::API_SERIALIZER_JSON) {
|
||||
$this->manager->setSerializer(new JsonApiSerializer());
|
||||
} else {
|
||||
$this->manager->setSerializer(new ArraySerializer());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected function errorResponse($response, $httpErrorCode = 400)
|
||||
{
|
||||
$error['error'] = $response;
|
||||
$error = json_encode($error, JSON_PRETTY_PRINT);
|
||||
$headers = self::getApiHeaders();
|
||||
|
||||
return response()->make($error, $httpErrorCode, $headers);
|
||||
}
|
||||
|
||||
protected function listResponse($query)
|
||||
{
|
||||
$transformer = new $this->entityTransformer(Input::get('serializer'));
|
||||
|
||||
$includes = $transformer->getDefaultIncludes();
|
||||
$includes = $this->getRequestIncludes($includes);
|
||||
|
||||
$query->with($includes);
|
||||
|
||||
$data = $this->createCollection($query, $transformer, $this->entityType);
|
||||
|
||||
return $this->response($data);
|
||||
}
|
||||
|
||||
protected function createCollection($query, $transformer, $entityType)
|
||||
{
|
||||
|
||||
if ($this->serializer && $this->serializer != EntityTransformer::API_SERIALIZER_JSON) {
|
||||
$entityType = null;
|
||||
}
|
||||
|
||||
if (is_a($query, "Illuminate\Database\Eloquent\Builder")) {
|
||||
$limit = Input::get('per_page', 20);
|
||||
|
||||
$paginator = $query->paginate($limit);
|
||||
$query = $paginator->getCollection();
|
||||
$resource = new Collection($query, $transformer, $entityType);
|
||||
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
|
||||
} else {
|
||||
$resource = new Collection($query, $transformer, $entityType);
|
||||
}
|
||||
|
||||
return $this->manager->createData($resource)->toArray();
|
||||
}
|
||||
|
||||
protected function response($response)
|
||||
{
|
||||
$index = request()->input('index') ?: 'data';
|
||||
|
||||
if ($index == 'none') {
|
||||
unset($response['meta']);
|
||||
} else {
|
||||
$meta = isset($response['meta']) ? $response['meta'] : null;
|
||||
$response = [
|
||||
$index => $response,
|
||||
];
|
||||
|
||||
if ($meta) {
|
||||
$response['meta'] = $meta;
|
||||
unset($response[$index]['meta']);
|
||||
}
|
||||
}
|
||||
|
||||
$response = json_encode($response, JSON_PRETTY_PRINT);
|
||||
$headers = self::getApiHeaders();
|
||||
|
||||
return response()->make($response, 200, $headers);
|
||||
}
|
||||
|
||||
protected function itemResponse($item)
|
||||
{
|
||||
|
||||
$transformer = new $this->entityTransformer(Input::get('serializer'));
|
||||
|
||||
$data = $this->createItem($item, $transformer, $this->entityType);
|
||||
|
||||
return $this->response($data);
|
||||
}
|
||||
|
||||
protected function createItem($data, $transformer, $entityType)
|
||||
{
|
||||
if ($this->serializer && $this->serializer != EntityTransformer::API_SERIALIZER_JSON) {
|
||||
$entityType = null;
|
||||
}
|
||||
|
||||
$resource = new Item($data, $transformer, $entityType);
|
||||
|
||||
return $this->manager->createData($resource)->toArray();
|
||||
}
|
||||
|
||||
public static function getApiHeaders($count = 0)
|
||||
{
|
||||
return [
|
||||
'Content-Type' => 'application/json',
|
||||
//'Access-Control-Allow-Origin' => '*',
|
||||
//'Access-Control-Allow-Methods' => 'GET',
|
||||
//'Access-Control-Allow-Headers' => 'Origin, Content-Type, Accept, Authorization, X-Requested-With',
|
||||
//'Access-Control-Allow-Credentials' => 'true',
|
||||
'X-Total-Count' => $count,
|
||||
'X-Muudeo-Version' => config('ninja.api_version'),
|
||||
//'X-Rate-Limit-Limit' - The number of allowed requests in the current period
|
||||
//'X-Rate-Limit-Remaining' - The number of remaining requests in the current period
|
||||
//'X-Rate-Limit-Reset' - The number of seconds left in the current period,
|
||||
];
|
||||
}
|
||||
|
||||
protected function getRequestIncludes($data)
|
||||
{
|
||||
$included = request()->input('include');
|
||||
$included = explode(',', $included);
|
||||
|
||||
foreach ($included as $include) {
|
||||
if ($include == 'clients') {
|
||||
$data[] = 'clients.contacts';
|
||||
} elseif ($include == 'tracks') {
|
||||
$data[] = 'tracks.comments';
|
||||
$data[] = 'tracks.tags';
|
||||
} elseif ($include) {
|
||||
$data[] = $include;
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
@ -22,16 +22,20 @@ use App\Repositories\ClientRepository;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
use App\Transformers\ClientTransformer;
|
||||
|
||||
/**
|
||||
* Class ClientController
|
||||
* @package App\Http\Controllers
|
||||
*/
|
||||
class ClientController extends Controller
|
||||
class ClientController extends BaseController
|
||||
{
|
||||
use MakesHash;
|
||||
|
||||
protected $entityType = Client::class;
|
||||
|
||||
protected $entityTransformer = ClientTransformer::class;
|
||||
|
||||
/**
|
||||
* @var ClientRepository
|
||||
*/
|
||||
@ -43,6 +47,7 @@ class ClientController extends Controller
|
||||
*/
|
||||
public function __construct(ClientRepository $clientRepo)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->clientRepo = $clientRepo;
|
||||
|
||||
@ -53,9 +58,11 @@ class ClientController extends Controller
|
||||
*/
|
||||
public function index(ClientFilters $filters)
|
||||
{
|
||||
$clients = Client::filter($filters)->get();
|
||||
$clients = Client::filter($filters);
|
||||
|
||||
return response()->json($clients);
|
||||
return $this->listResponse($clients);
|
||||
|
||||
// return response()->json($clients);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -6,8 +6,16 @@ namespace App\Http\Controllers;
|
||||
* Class ClientStatementController
|
||||
* @package App\Http\Controllers
|
||||
*/
|
||||
class ClientStatementController extends Controller
|
||||
class ClientStatementController extends BaseController
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
parent::__construct();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a client statement view for a given
|
||||
* client_id.
|
||||
|
@ -15,7 +15,7 @@ use Illuminate\Support\Facades\Hash;
|
||||
* Class CompanyController
|
||||
* @package App\Http\Controllers
|
||||
*/
|
||||
class CompanyController extends Controller
|
||||
class CompanyController extends BaseController
|
||||
{
|
||||
use DispatchesJobs;
|
||||
|
||||
@ -24,7 +24,9 @@ class CompanyController extends Controller
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('guest');
|
||||
|
||||
parent::__construct();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -8,15 +8,19 @@ use Illuminate\Http\Request;
|
||||
* Class ContactController
|
||||
* @package App\Http\Controllers
|
||||
*/
|
||||
class ContactController extends Controller
|
||||
class ContactController extends BaseController
|
||||
{
|
||||
/**
|
||||
* ContactController constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->middleware('auth:contact');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* show dashboard.
|
||||
*
|
||||
|
@ -3,7 +3,7 @@
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
|
||||
class DashboardController extends Controller
|
||||
class DashboardController extends BaseController
|
||||
{
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
|
@ -4,8 +4,16 @@ namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class InvoiceController extends Controller
|
||||
class InvoiceController extends BaseController
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
parent::__construct();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
|
@ -8,8 +8,15 @@ use Illuminate\Http\Request;
|
||||
* Class SettingsController
|
||||
* @package App\Http\Controllers
|
||||
*/
|
||||
class SettingsController extends Controller
|
||||
class SettingsController extends BaseController
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
parent::__construct();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
|
@ -9,8 +9,15 @@ use Illuminate\Support\Facades\Cache;
|
||||
* Class TranslationController
|
||||
* @package App\Http\Controllers
|
||||
*/
|
||||
class TranslationController extends Controller
|
||||
class TranslationController extends BaseController
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
parent::__construct();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
|
@ -9,9 +9,14 @@ use Illuminate\Http\Request;
|
||||
* Class UserController
|
||||
* @package App\Http\Controllers
|
||||
*/
|
||||
class UserController extends Controller
|
||||
class UserController extends BaseController
|
||||
{
|
||||
use VerifiesUserEmail;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
parent::__construct();
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -4,8 +4,15 @@ namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class UserProfileController extends Controller
|
||||
class UserProfileController extends BaseController
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
parent::__construct();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
|
@ -22,7 +22,7 @@ class SetDb
|
||||
$error['error'] = ['message' => 'Database could not be set'];
|
||||
|
||||
|
||||
if( $request->header('X-API-TOKEN') && ($user = CompanyToken::whereRaw("BINARY `token`= ?",[$request->header('X-API-TOKEN')])->first()->user ) && config('ninja.db.multi_db_enabled'))
|
||||
if( $request->header('X-API-TOKEN') && (CompanyToken::whereRaw("BINARY `token`= ?",[$request->header('X-API-TOKEN')])->first()) && config('ninja.db.multi_db_enabled'))
|
||||
{
|
||||
|
||||
if(! MultiDB::findAndSetDb($request->header('X-API-TOKEN')))
|
||||
|
@ -1,14 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace App\Ninja\Transformers;
|
||||
namespace App\Transformers;
|
||||
|
||||
use Auth;
|
||||
use League\Fractal\TransformerAbstract;
|
||||
|
||||
class EntityTransformer extends TransformerAbstract
|
||||
{
|
||||
protected $serializer;
|
||||
|
||||
const API_SERIALIZER_ARRAY = 'array';
|
||||
const API_SERIALIZER_JSON = 'json';
|
||||
|
||||
public function __construct($serializer = null)
|
||||
{
|
||||
$this->serializer = $serializer;
|
||||
@ -16,7 +18,7 @@ class EntityTransformer extends TransformerAbstract
|
||||
|
||||
protected function includeCollection($data, $transformer, $entityType)
|
||||
{
|
||||
if ($this->serializer && $this->serializer != API_SERIALIZER_JSON) {
|
||||
if ($this->serializer && $this->serializer != self::API_SERIALIZER_JSON) {
|
||||
$entityType = null;
|
||||
}
|
||||
|
||||
@ -25,24 +27,13 @@ class EntityTransformer extends TransformerAbstract
|
||||
|
||||
protected function includeItem($data, $transformer, $entityType)
|
||||
{
|
||||
if ($this->serializer && $this->serializer != API_SERIALIZER_JSON) {
|
||||
if ($this->serializer && $this->serializer != self::API_SERIALIZER_JSON) {
|
||||
$entityType = null;
|
||||
}
|
||||
|
||||
return $this->item($data, $transformer, $entityType);
|
||||
}
|
||||
|
||||
protected function getTimestamp($date)
|
||||
{
|
||||
if (method_exists($date, 'getTimestamp')) {
|
||||
return $date->getTimestamp();
|
||||
} elseif (is_string($date)) {
|
||||
return strtotime($date);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function getDefaultIncludes()
|
||||
{
|
||||
return $this->defaultIncludes;
|
||||
@ -50,14 +41,6 @@ class EntityTransformer extends TransformerAbstract
|
||||
|
||||
protected function getDefaults($entity)
|
||||
{
|
||||
$data = [
|
||||
'is_owner' => (bool) (Auth::check() && Auth::user()->owns($entity)),
|
||||
];
|
||||
|
||||
if ($entity->relationLoaded('user')) {
|
||||
$data['user_id'] = (int) $entity->user->public_id + 1;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,7 @@
|
||||
"laravel/framework": "5.7.*",
|
||||
"laravel/socialite": "^3.1",
|
||||
"laravel/tinker": "^1.0",
|
||||
"league/fractal": "^0.17.0",
|
||||
"nwidart/laravel-modules": "^4.0",
|
||||
"predis/predis": "^1.1",
|
||||
"webpatser/laravel-countries": "dev-master#75992ad",
|
||||
|
@ -7,6 +7,7 @@ return [
|
||||
'site_url' => env('APP_URL', 'https://v2.invoiceninja.com'),
|
||||
'app_domain' => env('APP_DOMAIN', 'invoiceninja.com'),
|
||||
'app_version' => '0.1',
|
||||
'api_version' => '0.1',
|
||||
'terms_version' => '1.0.1',
|
||||
'app_env' => env('APP_ENV', 'development'),
|
||||
'api_secret' => env('API_SECRET', ''),
|
||||
|
Loading…
x
Reference in New Issue
Block a user