Add routes and initial controller for API calls

This commit is contained in:
Kendrick Chan 2018-01-28 05:18:56 +08:00
parent 99d9d9482a
commit f5cce11738
3 changed files with 365 additions and 0 deletions

76
config/routes/api.yaml Normal file
View file

@ -0,0 +1,76 @@
# api
api_register:
path: /api/register
controller: App\Controller\APIController::register
methods: [POST]
api_confirm:
path: /api/number_confirm
controller: App\Controller\APIController::confirmNumber
methods: [GET,POST]
api_validate:
path: /api/code_validate
controller: App\Controller\APIController::validateCode
methods: [POST]
api_info_get:
path: /api/info
controller: App\Controller\APIController::getInfo
methods: [GET]
api_info_update:
path: /api/info
controller: App\Controller\APIController::updateInfo
methods: [POST]
api_status:
path: /api/status
controller: App\Controller\APIController::getStatus
methods: [GET]
api_vehicle_mfg_list:
path: /api/vehicle/mfgs
controller: App\Controller\APIController::listVehicleManufacturers
methods: [GET]
api_vehicle_make_list:
path: /api/vehicle/mfgs/{id}/makes
controller: App\Controller\APIController::listVehicleMakes
methods: [GET]
api_cust_vehicle_add:
path: /api/vehicles
controller: App\Controller\APIController::addVehicle
methods: [POST]
api_cust_vehicle_update:
path: /api/vehicles/{id}
controller: App\Controller\APIController::updateVehicle
methods: [POST]
api_cust_vehicle_list:
path: /api/vehicles
controller: App\Controller\APIController::listVehicles
methods: [GET]
api_promo_list:
path: /api/promos
controller: App\Controller\APIController::listPromos
methods: [GET]
api_battery_list:
path: /api/vehicles/{id}/compatible_batteries
controller: App\Controller\APIController::getCompatibleBatteries
methods: [GET]
api_jo_request:
path: /api/job_order
controller: App\Controller\APIController::requestJobOrder
methods: [POST]
api_estimate:
path: /api/estimate
controller: App\Controller\APIController::getEstimate
methods: [POST]

View file

@ -0,0 +1,223 @@
<?php
namespace App\Controller;
use App\Ramcar\BaseController;
use Doctrine\ORM\Query;
use Doctrine\ORM\QueryBuilder;
use Doctrine\DBAL\DBALException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use App\Ramcar\APIResult;
use App\Entity\MobileSession;
use DateTime;
class APIController extends BaseController
{
protected function checkMissingParameters(Request $req, $params = [])
{
$missing = [];
// check if parameters are there
foreach ($params as $param)
{
if ($req->getMethod() == 'GET')
{
$check = $req->query->get($param);
if (empty($check))
$missing[] = $param;
}
else if ($req->getMethod() == 'POST')
{
$check = $req->request->get($param);
if (empty($check))
$missing[] = $param;
}
else
return $params;
}
return $missing;
}
protected function checkAPIKey($em, $api_key)
{
// find the api key (session id)
$session = $em->getRepository(MobileSession::class)->find($api_key);
if ($session == null)
return false;
return $session;
}
public function register(Request $req)
{
$res = new APIResult();
// confirm parameters
$required_params = [
'phone_model',
'os_type',
'os_version',
'device_push_id'
];
$missing = $this->checkMissingParameters($req, $required_params);
if (count($missing) > 0)
{
$params = implode(', ', $missing);
$res->setErrorFlag(true)
->setErrorMessage('Missing parameter(s): ' . $params);
return $this->json($res->getReturnResponse());
}
$em = $this->getDoctrine()->getManager();
// retry until we get a unique id
while (true)
{
try
{
// instantiate session
$sess = new MobileSession();
$sess->setPhoneModel($req->request->get('phone_model'))
->setOSType($req->request->get('os_type'))
->setOSVersion($req->request->get('os_version'))
->setDevicePushID($req->request->get('device_push_id'));
// reopen in case we get an exception
if (!$em->isOpen())
{
$em = $em->create(
$em->getConnection(),
$em->getConfiguration()
);
}
// save
$em->persist($sess);
$em->flush();
}
catch (DBALException $e)
{
error_log($e->getMessage());
// delay one second and try again
sleep(1);
continue;
}
break;
}
// return data
$data = [
'session_id' => $sess->getID()
];
$res->setData($data);
// response
return $this->json($res->getReturnResponse());
}
public function confirmNumber(Request $req)
{
$res = new APIResult();
// check parameters
$required_params = [
'api_key',
'phone_number',
];
$missing = $this->checkMissingParameters($req, $required_params);
if (count($missing) > 0)
{
$params = implode(', ', $missing);
$res->setErrorFlag(true)
->setErrorMessage('Missing parameter(s): ' . $params);
return $this->json($res->getReturnResponse());
}
// check api key
$em = $this->getDoctrine()->getManager();
$sess = $this->checkAPIKey($em, $req->request->get('api_key'));
if (!$sess)
{
$res->setErrorFlag(true)
->setErrorMessage('Invalid API Key');
return $this->json($res->getReturnResponse());
}
// phone number
$phone_number = $req->request->get('phone_number');
// TODO: validate phone number
// TODO: generate code and save
// use '123456' for now
$code = '123456';
$sess->setConfirmCode($code)
->setPhoneNumber($phone_number);
$em->flush();
// TODO: send sms to number
// response
return $this->json($res->getReturnResponse());
}
public function validateCode(Request $req)
{
$res = new APIResult();
// check parameters
$required_params = [
'api_key',
'code',
];
$missing = $this->checkMissingParameters($req, $required_params);
if (count($missing) > 0)
{
$params = implode(', ', $missing);
$res->setErrorFlag(true)
->setErrorMessage('Missing parameter(s): ' . $params);
return $this->json($res->getReturnResponse());
}
// check api key
$em = $this->getDoctrine()->getManager();
$sess = $this->checkAPIKey($em, $req->request->get('api_key'));
if (!$sess)
{
$res->setErrorFlag(true)
->setErrorMessage('Invalid API Key');
return $this->json($res->getReturnResponse());
}
$code = $req->request->get('code');
// code is wrong
if ($sess->getConfirmCode() != $code)
{
$res->setErrorFlag(true)
->setErrorMessage('Wrong confirm code');
return $this->json($res->getReturnResponse());
}
// set confirm date
$date = new DateTime();
$sess->setDateConfirmed($date)
->setConfirmed();
$em->flush();
// response
return $this->json($res->getReturnResponse());
}
}

66
src/Ramcar/APIResult.php Normal file
View file

@ -0,0 +1,66 @@
<?php
namespace App\Ramcar;
class APIResult
{
protected $err_flag;
protected $err_message;
protected $data;
public function __construct()
{
$this->err_flag = false;
$this->err_message = '';
$this->data = [];
}
public function setErrorFlag($flag = true)
{
$this->err_flag = $flag;
return $this;
}
public function isError()
{
return $this->err_flag;
}
public function setErrorMessage($message)
{
$this->err_message = $message;
return $this;
}
public function getErrorMessage()
{
return $this->err_message;
}
public function setData($data)
{
$this->data = $data;
return $this;
}
public function getData()
{
return $this->data;
}
public function getReturnResponse()
{
if ($this->isError())
$status = 'error';
else
$status = 'success';
return [
'error' => [
'status' => $status,
'message' => $this->err_message
],
'data' => $this->data
];
}
}