session = null; } 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; } // TODO: type hint entity manager protected function checkAPIKey($em, $api_key) { // find the api key (session id) $session = $em->getRepository(MobileSession::class)->find($api_key); if ($session == null) return null; return $session; } protected function checkParamsAndKey(Request $req, $em, $params) { // returns APIResult object $res = new APIResult(); // check for api_key in query string $api_key = $req->query->get('api_key'); if (empty($api_key)) { $res->setError(true) ->setErrorMessage('Missing API key'); return $res; } // check missing parameters $missing = $this->checkMissingParameters($req, $params); if (count($missing) > 0) { $miss_string = implode(', ', $missing); $res->setError(true) ->setErrorMessage('Missing parameter(s): ' . $miss_string); return $res; } // check api key $sess = $this->checkAPIKey($em, $req->query->get('api_key')); if ($sess == null) { $res->setError(true) ->setErrorMessage('Invalid API Key'); return $res; } // store session $this->session = $sess; return $res; } 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->setError(true) ->setErrorMessage('Missing parameter(s): ' . $params); return $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 $res->getReturnResponse(); } public function confirmNumber(Request $req) { // check parameters $required_params = [ 'phone_number', ]; // check required parameters and api key $em = $this->getDoctrine()->getManager(); $res = $this->checkParamsAndKey($req, $em, $required_params); if ($res->isError()) return $res->getReturnResponse(); // phone number $phone_number = $req->request->get('phone_number'); // TODO: spam protection // TODO: validate phone number // TODO: generate code and save // use '123456' for now $code = '123456'; $this->session->setConfirmCode($code) ->setPhoneNumber($phone_number); $em->flush(); // TODO: send sms to number // response return $res->getReturnResponse(); } public function validateCode(Request $req) { // check parameters $required_params = [ 'code', ]; // check required parameters and api key $em = $this->getDoctrine()->getManager(); $res = $this->checkParamsAndKey($req, $em, $required_params); if ($res->isError()) return $res->getReturnResponse(); // code is wrong $code = $req->request->get('code'); if ($this->session->getConfirmCode() != $code) { $res->setError(true) ->setErrorMessage('Wrong confirm code'); return $res->getReturnResponse(); } // set confirm date $date = new DateTime(); $this->session->setDateConfirmed($date) ->setConfirmed(); $em->flush(); // response return $res->getReturnResponse(); } public function getInfo(Request $req) { // check required parameters and api key $required_params = []; $em = $this->getDoctrine()->getManager(); $res = $this->checkParamsAndKey($req, $em, $required_params); if ($res->isError()) return $res->getReturnResponse(); // if no customer found $cust = $this->session->getCustomer(); if ($cust == null) { $data = [ 'first_name' => '', 'last_name' => '', ]; $res->setData($data); return $res->getReturnResponse(); } // send back customer details $data = [ 'first_name' => $cust->getFirstName(), 'last_name' => $cust->getLastName(), ]; $res->setData($data); return $res->getReturnResponse(); } public function updateInfo(Request $req) { // check required parameters and api key $required_params = [ 'first_name', 'last_name', ]; $em = $this->getDoctrine()->getManager(); $res = $this->checkParamsAndKey($req, $em, $required_params); if ($res->isError()) return $res->getReturnResponse(); // create new customer if it's not there $cust = $this->session->getCustomer(); if ($cust == null) { $cust = new Customer(); $em->persist($cust); $this->session->setCustomer($cust); } $cust->setFirstName($req->request->get('first_name')) ->setLastName($req->request->get('last_name')) ->setConfirmed($this->session->isConfirmed()); $em->flush(); return $res->getReturnResponse(); } public function getStatus(Request $req) { // check required parameters and api key $required_params = []; $em = $this->getDoctrine()->getManager(); $res = $this->checkParamsAndKey($req, $em, $required_params); if ($res->isError()) return $res->getReturnResponse(); // set data $data = []; if ($this->session->isConfirmed()) $data['status'] = 'confirmed'; else $data['status'] = 'unconfirmed'; $res->setData($data); return $res->getReturnResponse(); } public function listVehicleManufacturers(Request $req) { // check required parameters and api key $required_params = []; $em = $this->getDoctrine()->getManager(); $res = $this->checkParamsAndKey($req, $em, $required_params); if ($res->isError()) return $res->getReturnResponse(); // get manufacturer list $mfgs = $em->getRepository(VehicleManufacturer::class)->findBy([], ['name' => 'asc']); $mfg_list = []; foreach ($mfgs as $mfg) { $mfg_list[] = [ 'id' => $mfg->getID(), 'name' => $mfg->getName(), ]; } $data = [ 'manufacturers' => $mfg_list ]; $res->setData($data); return $res->getReturnResponse(); } public function listVehicleMakes(Request $req, $mfg_id) { // check required parameters and api key $required_params = []; $em = $this->getDoctrine()->getManager(); $res = $this->checkParamsAndKey($req, $em, $required_params); if ($res->isError()) return $res->getReturnResponse(); // get manufacturer $mfg = $em->getRepository(VehicleManufacturer::class)->find($mfg_id); if ($mfg == null) { $res->setError(true) ->setErrorMessage('Invalid vehicle manufacturer id'); return $res->getReturnResponse(); } // get makes $vehicles = $mfg->getVehicles(); $vlist = []; foreach ($vehicles as $v) { $vlist[] = [ 'id' => $v->getID(), 'make' => $v->getMake() . ' ' . $v->getModelYearFrom() . '-' . $v->getModelYearTo(), ]; } $data = [ 'manufacturer' => [ 'id' => $mfg->getID(), 'name' => $mfg->getName(), ], 'makes' => $vlist, ]; $res->setData($data); return $res->getReturnResponse(); } protected function checkVehicleRequirements(Request $req) { // check required parameters and api key $required_params = [ 'make_id', 'name', 'plate_num', 'model_year', 'color', 'condition', 'fuel_type', ]; $em = $this->getDoctrine()->getManager(); $res = $this->checkParamsAndKey($req, $em, $required_params); if ($res->isError()) return $res; // TODO: check valid plate number // TODO: check valid fuel type (gas / diesel) // TODO: check current battery id // TODO: check condition (brand new / second-hand) // TODO: check is_motolite and is_active (1 or 0) // TODO: check warranty expiration date (YYYYMMDD) // TODO: check model year coverage if it fits in between return $res; } protected function setCustomerVehicleObject(Request $req, APIResult $res, CustomerVehicle $cv) { $em = $this->getDoctrine()->getManager(); // check customer $cust = $this->session->getCustomer(); if ($cust == null) { $res->setError(true) ->setErrorMessage('No customer information found'); return $res; } // get vehicle $vehicle = $em->getRepository(Vehicle::class)->find($req->request->get('make_id')); if ($vehicle == null) { $res->setError(true) ->setErrorMessage('Invalid vehicle make id'); return $res; } $cv->setCustomer($cust) ->setVehicle($vehicle) ->setName($req->request->get('name')) ->setPlateNumber($req->request->get('plate_num')) ->setModelYear($req->request->get('model_year')) ->setColor($req->request->get('color')) ->setFuelType($req->request->get('fuel_type')) ->setStatusCondition($req->request->get('condition')); // set warranty code and expiration // TODO: check warranty requirements if (!empty($req->request->get('wty_code'))) $cv->setWarrantyCode($req->request->get('wty_code')); if (!empty($req->request->get('wty_expire'))) $cv->setWarrantyExpiration(new DateTime($req->request->get('wty_expire'))); // TODO: get current battery // is motolite if ($req->request->get('is_motolite') == 0) $cv->setHasMotoliteBattery(false); else $cv->setHasMotoliteBattery(true); // is active if ($req->request->get('is_active') == 0) $cv->setActive(false); else $cv->setActive(true); // save $em->persist($cv); $em->flush(); // data $data = [ 'cv_id' => $cv->getID() ]; $res->setData($data); return $res; } public function addVehicle(Request $req) { // check requirements $res = $this->checkVehicleRequirements($req); if ($res->isError()) return $res->getReturnResponse(); // customer vehicle $cv = new CustomerVehicle(); $res = $this->setCustomerVehicleObject($req, $res, $cv); return $res->getReturnResponse(); } public function updateVehicle(Request $req, $id) { // check requirements $res = $this->checkVehicleRequirements($req); if ($res->isError()) return $res->getReturnResponse(); // get customer vehicle $em = $this->getDoctrine()->getManager(); $cv = $em->getRepository(CustomerVehicle::class)->find($id); // check if it exists if ($cv == null) { $res->setError(true) ->setErrorMessage('Vehicle does not exist'); return $res->getReturnResponse(); } // check if it's owned by customer if ($cv->getCustomer()->getID() != $this->session->getCustomer()->getID()) { $res->setError(true) ->setErrorMessage('Invalid vehicle'); return $res->getReturnResponse(); } $res = $this->setCustomerVehicleObject($req, $res, $cv); return $res->getReturnResponse(); } public function listVehicles(Request $req) { // check required parameters and api key $required_params = []; $em = $this->getDoctrine()->getManager(); $res = $this->checkParamsAndKey($req, $em, $required_params); if ($res->isError()) return $res->getReturnResponse(); // customer $cust = $this->session->getCustomer(); if ($cust == null) { $res->setError(true) ->setErrorMessage('No customer information found'); return $res->getReturnResponse(); } // vehicles $cv_list = []; $cvs = $cust->getVehicles(); foreach ($cvs as $cv) { $battery_id = null; if ($cv->getCurrentBattery() != null) $battery_id = $cv->getCurrentBattery()->getID(); $wty_ex = null; if ($cv->getWarrantyExpiration() != null) $wty_ex = $cv->getWarrantyExpiration()->format('Y-m-d'); $cv_list[] = [ 'id' => $cv->getID(), 'mfg_id' => $cv->getVehicle()->getManufacturer()->getID(), 'make_id' => $cv->getVehicle()->getID(), 'name' => $cv->getName(), 'plate_num' => $cv->getPlateNumber(), 'model_year' => $cv->getModelYear(), 'color' => $cv->getColor(), 'condition' => $cv->getStatusCondition(), 'fuel_type' => $cv->getFuelType(), 'wty_code' => $cv->getWarrantyCode(), 'wty_expire' => $wty_ex, 'curr_batt_id' => $battery_id, 'is_motolite' => $cv->hasMotoliteBattery() ? 1 : 0, 'is_active' => $cv->isActive() ? 1 : 0, ]; } // data $data = [ 'vehicles' => $cv_list ]; $res->setData($data); return $res->getReturnResponse(); } public function listPromos(Request $req) { // check required parameters and api key $required_params = []; $em = $this->getDoctrine()->getManager(); $res = $this->checkParamsAndKey($req, $em, $required_params); if ($res->isError()) return $res->getReturnResponse(); return $res->getReturnResponse(); } public function getCompatibleBatteries(Request $req, $vid) { // check required parameters and api key $required_params = []; $em = $this->getDoctrine()->getManager(); $res = $this->checkParamsAndKey($req, $em, $required_params); if ($res->isError()) return $res->getReturnResponse(); // get vehicle $vehicle = $em->getRepository(Vehicle::class)->find($vid); if ($vehicle == null) { $res->setError(true) ->setErrorMessage('Invalid vehicle'); return $res->getReturnResponse(); } // batteries $batt_list = []; $batts = $vehicle->getBatteries(); foreach ($batts as $batt) { $batt_list[] = [ 'id' => $batt->getID(), 'mfg_id' => $batt->getManufacturer()->getID(), 'mfg_name' => $batt->getManufacturer()->getName(), 'model_id' => $batt->getModel()->getID(), 'model_name' => $batt->getModel()->getName(), 'size_id' => $batt->getSize()->getID(), 'size_name' => $batt->getSize()->getName(), 'price' => $batt->getSellingPrice(), 'wty_private' => $batt->getWarrantyPrivate(), 'wty_commercial' => $batt->getWarrantyCommercial(), ]; } // data $data = [ 'vehicle' => [ 'id' => $vehicle->getID(), 'mfg_id' => $vehicle->getManufacturer()->getID(), 'mfg_name' => $vehicle->getManufacturer()->getName(), 'make' => $vehicle->getMake(), 'model_year_from' => $vehicle->getModelYearFrom(), 'model_year_to' => $vehicle->getModelYearTo(), ], 'batteries' => $batt_list, ]; $res->setData($data); return $res->getReturnResponse(); } public function requestJobOrder(Request $req) { // check required parameters and api key $required_params = []; $em = $this->getDoctrine()->getManager(); $res = $this->checkParamsAndKey($req, $em, $required_params); if ($res->isError()) return $res->getReturnResponse(); return $res->getReturnResponse(); } public function getEstimate(Request $req) { // check required parameters and api key $required_params = []; $em = $this->getDoctrine()->getManager(); $res = $this->checkParamsAndKey($req, $em, $required_params); if ($res->isError()) return $res->getReturnResponse(); return $res->getReturnResponse(); } }