<?php
/**
* Created by PhpStorm.
* User: marija
* Date: 15.1.18.
* Time: 15.42
*/
namespace LaunchPad\Bundle\LaunchPadBundle\Api\Controller;
use Doctrine\Common\Annotations\AnnotationReader;
use LaunchPad\Bundle\LaunchPadBundle\Base\Entity\User\User;
use Gedmo\Translator\TranslationInterface;
use LaunchPad\Bundle\LaunchPadBundle\Base\Exception\MissingApiParamsException;
use LaunchPad\Bundle\LaunchPadBundle\Base\Service\AppNormalizerService;
use LaunchPad\Bundle\LaunchPadBundle\Base\Service\BaseService;
//use BoBoFin\Base\Serializer\Normalizer\BoBoFinNormalizer;
use LaunchPad\Bundle\LaunchPadBundle\Base\Serializer\Normalizer\AppNormalizer;
use LaunchPad\Bundle\LaunchPadBundle\Base\Controller\BaseController;
use LaunchPad\Bundle\LaunchPadBundle\Base\Service\Stats\Apple\AppleReportService;
use LaunchPad\Bundle\LaunchPadBundle\Base\Service\Translation\TranslationService;
use LaunchPad\Bundle\LaunchPadBundle\Base\Service\User\UserPermissionService;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;
/**
* Class BaseApiController
* @package LaunchPad\Api\Controller
*/
class BaseApiController extends BaseController
{
/** @var array */
protected $data = [];
/** @var BaseService */
private $baseService;
/** @var AppNormalizerService */
private $appNormalizerService;
// /**
// * @Route("", name="api_root")
// *
// */
// public function indexAction(Request $request)
// {
// $apiDefinitions = $this->getParameter('api');
//
// $scheme = $request->query->get('scheme');
//
// if(!$scheme) {
// return $this->render(
// "@WebsiteTemplates/swagger/index.html.twig",
// [
// 'definitions' => $apiDefinitions
// ]
// );
// }
//
// return $this->render(
// "@WebsiteTemplates/swagger/ui.html.twig",
// [
// 'url' => '/api/definition?scheme=' . urlencode($scheme)
// ]
// );
// }
//
// /**
// * @Route("/definition", name="api_definition")
// * @param Request $request
// * @return Response
// */
// public function apiDefinitionAction(Request $request)
// {
// $scheme = $request->query->get('scheme');
//
// // dump($scheme);
// $apiDefinitions = $this->getParameter('api');
//
// $selectedDefinition = null;
//
// foreach($apiDefinitions as $definition) {
// if($definition['name'] == $scheme) {
// $selectedDefinition = $definition;
// break;
// }
// }
//
// $openapi = \OpenApi\scan($selectedDefinition['paths']);
// header('Content-Type: application/json');
// return new Response($openapi->toJson());
// }
/**
* Set BaseApiService
*
* @param BaseService $baseService
*/
public function setBaseApiService(BaseService $baseService)
{
$this->baseService = $baseService;
}
/**
* Set BaseApiService
*
* @param AppNormalizerService $appNormalizerService
*/
public function setAppNormalizerService(AppNormalizerService $appNormalizerService)
{
$this->appNormalizerService = $appNormalizerService;
}
/**
* Return json success response
*
* @param array $data
* @param null $message
* @param array $groups
* @return JsonResponse
* @throws \Doctrine\Common\Annotations\AnnotationException
* @throws \Symfony\Component\Serializer\Exception\ExceptionInterface
*/
protected function success($data = null, $message = null, $groups = [])
{
if (is_string($data) && empty($message)) {
$message = $data;
$data = null;
}
return $this->jsonOutput([
'success' => true,
'data' => $data,
'message' => $message
], 200, $groups);
}
/**
* Return json failure response
*
* @param null $data
* @param null $message
* @param array $groups
* @return JsonResponse
* @throws \Doctrine\Common\Annotations\AnnotationException
* @throws \Symfony\Component\Serializer\Exception\ExceptionInterface
*/
protected function failure($data = null, $message = null, $groups = [])
{
if (is_string($data) && empty($message)) {
$message = $data;
$data = null;
}
return $this->jsonOutput([
'success' => false,
'data' => $data,
'message' => $message
], 200, $groups);
}
/**
* Return JSON error response
*
* @param null $type
* @param array $data
* @param null $message
* @param int $code
* @return JsonResponse
* @throws \Doctrine\Common\Annotations\AnnotationException
* @throws \Symfony\Component\Serializer\Exception\ExceptionInterface
*/
protected function jsonError($type = null, $data = null, $message = null, $code = 200)
{
if (is_string($data) && empty($message)) {
$message = $data;
$data = null;
}
return $this->jsonOutput([
'success' => false,
'data' => $data,
'code' => $code,
'errors' => [
[
'type' => $type,
'message' => $message,
]
]
]);
}
/**
* Return Invalid field
*
* @param $field
* @param $message
* @return JsonResponse
* @throws \Doctrine\Common\Annotations\AnnotationException
* @throws \Symfony\Component\Serializer\Exception\ExceptionInterface
*/
protected function invalidField($field, $message)
{
$type = 'validation_error';
return $this->invalidFields([
compact('field', 'message', 'type')
]);
}
/**
* Return Invalid fields
*
* @param $fields
* @return JsonResponse
* @throws \Doctrine\Common\Annotations\AnnotationException
* @throws \Symfony\Component\Serializer\Exception\ExceptionInterface
*/
protected function invalidFields($fields)
{
return $this->jsonOutput([
'success' => false,
'code' => 200,
'errors' => $fields
]);
}
/**
* Return JSON output
*
* @param $data
* @param int $code
* @param array $groups
* @return JsonResponse
* @throws \Doctrine\Common\Annotations\AnnotationException
* @throws \Symfony\Component\Serializer\Exception\ExceptionInterface
*/
private function jsonOutput($data, $code = 200, $groups = [])
{
$encoders = array(new JsonEncoder());
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
$normalizer = new AppNormalizer(
$classMetadataFactory,
null,
null,
null,
$this->appNormalizerService
);
$normalizers = array(new DateTimeNormalizer(), $normalizer, new GetSetMethodNormalizer());
$normalizers[1]->setCircularReferenceHandler(function ($object) {
return $object->getId();
});
$serializer = new Serializer($normalizers, $encoders);
if ($groups) {
$data = $serializer->normalize($data, 'json', ['groups' => $groups]);
$data = $serializer->serialize($data, 'json', ['groups' => $groups]);
} else {
$data = $serializer->serialize($data, 'json');
}
return new JsonResponse($data, $code, [], true);
}
/**
* Require post params
*
* @param array $requiredParameters Array of required parameters.
*
* @throws \Doctrine\Common\Annotations\AnnotationException
* @throws MissingApiParamsException
*/
protected function requirePostParams($requiredParameters)
{
if (empty($this->data)) {
$currentRequest = $this->get('request_stack')->getCurrentRequest();
$this->data = $currentRequest->request->all();
}
$postData = $this->data;
$errors = [];
foreach ($requiredParameters as $requiredParameter) {
if (is_array($requiredParameter)) {
$intersectingKeys = array_intersect_key(
array_flip($requiredParameter),
$postData
);
if (empty($intersectingKeys)) {
$errors[] = [
'fields' => implode(', ', $requiredParameter),
'message' => 'One of following is required '. implode('or ', $requiredParameter),
'type' => 'validation_error'
];
}
continue;
}
if (!array_key_exists($requiredParameter, $postData)) {
$errors[] = [
'field' => $requiredParameter,
'message' => 'This value is required',
'type' => 'validation_error'
];
}
}
if (!empty($errors)) {
throw new MissingApiParamsException('Missing params!', $errors);
}
}
/**
* Terminate with response
*
* @param Response $response
*/
private function terminateWithResponse(Response $response)
{
$request = $this->get('request_stack')->getCurrentRequest();
$response->headers->set('Access-Control-Allow-Origin', '*');
$response->headers->set('Access-Control-Allow-Methods', 'OPTIONS,GET,POST,PUT,PATCH,DELETE');
$response->send();
$this->get('kernel')->terminate($request, $response);
exit();
}
/**
*
* @param $id
* @param array $parameters
* @param null $domain
* @param null $locale
* @return string
*/
public function translate($id, array $parameters = array(), $domain = null, $locale = null)
{
$this->get('translator')->trans($id, $parameters, $domain, $locale);
}
/**
* Get full base url
*
* @return string
*/
protected function getFullBaseUrl()
{
return $this->get('request_stack')->getCurrentRequest()->getSchemeAndHttpHost();
}
/**
* Check if user is logged in
*
* @return bool
*/
protected function isLoggedIn()
{
try {
return $this->get('security.authorization_checker')->isGranted('ROLE_USER');
} catch (\Exception $e) {
return false;
}
}
/**
* Check if authenticated user is admin
*
* @return bool
*/
protected function isAdmin()
{
try {
return $this->get('security.authorization_checker')->isGranted('ROLE_ADMIN');
} catch (\Exception $e) {
return false;
}
}
/**
* Set data in controller
*
* @param $data
*/
public function setData($data)
{
$this->data = $data;
}
/**
* Validate post params
*
* @param $fields
*/
public function validatePostParams($fields)
{
$data = $this->data;
$request = $this->get('request_stack')->getCurrentRequest();
$form = $this->createFormBuilder();
foreach($fields as $field) {
}
}
/**
* Get pagination params
*
* @return array
*/
public function getPaginationParams($defaultOffset = 0, $defaultLimit = 20)
{
if(isset($this->data['offset'])){
$offset = $this->data['offset'];
}else{
$offset = $defaultOffset;
}
if(isset($this->data['limit'])){
$limit = $this->data['limit'];
}else{
$limit = $defaultLimit;
}
return compact('offset', 'limit');
}
/**
* Validate request
*
* @param $validatorClass
* @return mixed $validatorClass
* @throws MissingApiParamsException
*/
protected function validateRequest($validatorClass)
{
return $this->baseService->validateRequest($validatorClass, $this->data);
}
}