Last active
September 8, 2015 13:51
-
-
Save ClaudioVarandas/f1898433dbf383975239 to your computer and use it in GitHub Desktop.
ApiController - Base api controller
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Api\v1; | |
use Apilog; | |
use Config; | |
use Input; | |
use League\Fractal; | |
use League\Fractal\Pagination\Cursor; | |
use League\Fractal\Resource\Collection; | |
use League\Fractal\Resource\Item; | |
use League\Fractal\Serializer\DataArraySerializer; | |
use Monolog\Handler\StreamHandler; | |
use Monolog\Logger; | |
use Request; | |
use User; | |
/** | |
* Class ApiController | |
* | |
* @package Api\v1 | |
*/ | |
class ApiController extends \BaseController | |
{ | |
/** | |
* @var \Illuminate\Database\Eloquent\Model|null|static | |
*/ | |
protected $apikey; | |
/** | |
* The Fractal Manager | |
* | |
* @var Fractal\Manager | |
*/ | |
protected $fractal; | |
/** | |
* @var array | |
*/ | |
protected $requiredHeaders; | |
/** | |
* @var array | |
*/ | |
protected $requiredMobileHeaders; | |
/** | |
* The restapi.php endpoint | |
* | |
* @var string | |
*/ | |
protected $apiEndpoint = '1.0'; | |
/** | |
* Map of fields for the resources | |
* Key = external field in camelCase | |
* Value = internal field in snake_case | |
* | |
* @var array | |
*/ | |
protected $fieldsMap = []; | |
/** | |
* Create a new resource instance | |
* | |
* @param FractalManager|Fractal\Manager $fractal | |
*/ | |
public function __construct(Fractal\Manager $fractal) | |
{ | |
/** @var ApiRequestService $apiRequestService */ | |
$apiRequestService = \App::make('***\Services\Api\ApiRequestService'); | |
$this->requiredHeaders = $apiRequestService->getRequiredHeaders(); | |
$this->requiredMobileHeaders = $apiRequestService->getRequiredMobileHeaders(); | |
// disable session for API methods | |
Config::set('session.driver', 'array'); | |
$this->beforeFilter('@filterHeaders'); | |
$this->beforeFilter('@filterHandleLanguageHeader'); | |
if (Config::get('restapi.logging')) { | |
$this->afterFilter('@filterLog'); | |
} | |
$this->fractal = $fractal; | |
$this->fractal->setSerializer(new DataArraySerializer()); | |
if (Input::has('include')) { | |
$this->fractal->parseIncludes(Input::get('include')); | |
#$this->fractal->setRequestedScopes(explode(',', Input::get('include'))); | |
} | |
} | |
/** | |
* Process a item | |
* | |
* @param mixed $item | |
* @param mixed $callback | |
* @param mixed $meta | |
* | |
* @return array | |
*/ | |
public function processItem($item, $callback, $meta = []) | |
{ | |
$resource = new Item($item, $callback); | |
foreach ($meta as $metaKey => $metaValue) { | |
$resource->setMetaValue($metaKey, $metaValue); | |
} | |
$rootScope = $this->fractal->createData($resource); | |
return $rootScope->toArray(); | |
} | |
/** | |
* Process a collection of items through Fractal | |
* | |
* @param mixed $collection | |
* @param mixed $callback | |
* @param \League\Fractal\Pagination\Cursor $cursor | |
* @param mixed $meta | |
* | |
* @return array | |
*/ | |
public function processCollection($collection, $callback, Cursor $cursor = null, $meta = []) | |
{ | |
$resource = new Collection($collection, $callback); | |
foreach ($meta as $metaKey => $metaValue) { | |
$resource->setMetaValue($metaKey, $metaValue); | |
} | |
if (!is_null($cursor)) { | |
$resource->setCursor($cursor); | |
} | |
$rootScope = $this->fractal->createData($resource); | |
return $rootScope->toArray(); | |
} | |
/** | |
* Process a collection with simple transformer | |
* | |
* @access public | |
* | |
* @param \Illuminate\Support\Collection $collection Collection of items to be transformed | |
* @param Transformer $transformer Transformer to be applied | |
* | |
* @return \Illuminate\Support\Collection A collection of transformed items | |
* @since 1.2.0 | |
*/ | |
public function processCollectionSimple($collection, Transformer $transformer, $listing = false) | |
{ | |
$returnData = new \Illuminate\Support\Collection(); | |
foreach ($collection as $collectionItem) { | |
if (!$listing) { | |
$returnData->push($transformer->transformSimple($collectionItem)); | |
} else { | |
$returnData->push($transformer->transformListing($collectionItem)); | |
} | |
} | |
return $returnData; | |
} | |
/** | |
* Process an item with simple transformer | |
* | |
* @access public | |
* | |
* @param Entity $item Item to be transformed | |
* @param Transformer $transformer Transformer to be applied | |
* | |
* @return array The transformed item | |
* @since 1.2.0 | |
*/ | |
public function processItemSimple(Entity $item, Transformer $transformer) | |
{ | |
return $transformer->transformSimple($item); | |
} | |
################ | |
### FILTERS #### | |
################ | |
/** | |
* Filter the request headers | |
* | |
* @return \Illuminate\Http\JsonResponse | |
*/ | |
public function filterHeaders() | |
{ | |
/** @var ApiRequestService $apiRequestService */ | |
$apiRequestService = \App::make('***\Services\Api\ApiRequestService'); | |
// Validate required headers | |
if (!$apiRequestService->isValidRequiredHeaders()) { | |
return ApiResponseService::respondHeadersRequired($apiRequestService->getMissingRequiredHeaders()); | |
} | |
// Validate platform type | |
if (!$apiRequestService->isValidPlatform()) { | |
$platformTypeHeaderName = $apiRequestService::HEADER_X_PLATFORM_TYPE; | |
return ApiResponseService::respondHeadersInvalid([$platformTypeHeaderName => 'Unsupported platform']); | |
} | |
// Validate app code | |
if (!$apiRequestService->isValidApp()) { | |
$appCodeHeaderName = $apiRequestService::HEADER_X_APP_CODE; | |
return ApiResponseService::respondHeadersInvalid([$appCodeHeaderName => 'Invalid application code']); | |
} | |
// Validate device headers (family and os) | |
if ($apiRequestService->isMobile()) { | |
if (!$apiRequestService->isValidDeviceFamily()) { | |
$deviceFamilyHeaderName = $apiRequestService::HEADER_X_DEVICE_FAMILY; | |
return ApiResponseService::respondHeadersInvalid([$deviceFamilyHeaderName => 'Invalid device family']); | |
} | |
if (!$apiRequestService->isValidDeviceOs()) { | |
$deviceOsHeaderName = $apiRequestService::HEADER_X_DEVICE_FAMILY; | |
return ApiResponseService::respondHeadersInvalid([$deviceOsHeaderName => 'Invalid device os']); | |
} | |
} | |
} | |
/** | |
* Do the log of the request | |
* | |
* @param mixed $route The requested route | |
* @param mixed $request The request | |
*/ | |
public function filterLog($route, $request) | |
{ | |
$routeAction = $route->getAction(); | |
$input = $request->all(); #\Input::all(); | |
// disable saving of password in plain text on DB | |
if (isset($input['password']) && $input['password'] != '') { | |
$input['password'] = 'password'; | |
} | |
if (isset($input['password_confirmation']) && $input['password_confirmation'] != '') { | |
$input['password_confirmation'] = 'password'; | |
} | |
/** @var \***\Services\Api\ApiRequestService $apiRequestService */ | |
$apiRequestService = \App::make('***\Services\Api\ApiRequestService'); | |
/** @var \***\Services\UserService $userService */ | |
$userService = \App::make('***\Services\UserService'); | |
$user = $userService->getCurrentUser(); | |
if ($user) { | |
$logUserId = $user->id; | |
} | |
$uri = explode('?', Request::getRequestUri()); | |
### Log this API request ### | |
// create a log channel | |
$log = new Logger('api_requests'); | |
$log->pushHandler(new StreamHandler(storage_path('logs') . '/' . 'api_requests' . date('Y-m-d') . '.log', | |
Logger::INFO)); | |
$logUserId = isset($logUserId) ? $logUserId : 'GUEST'; | |
$logAppName = $apiRequestService->getAppName(); | |
$logAction = $routeAction['controller']; | |
$logMethod = $request->method(); | |
$logEndpoint = $uri[0]; | |
$logParams = http_build_query($input); | |
$logIp = $request->ip(); | |
// add records to the log | |
$log->addInfo($logIp . '-' . $logUserId . '-' . $logAppName . '-' . $logEndpoint . '-' . $logAction . '-' . $logMethod . '-' . urldecode($logParams)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment