Added Other AP

This commit is contained in:
dev-chiefworks
2022-04-26 11:30:34 -04:00
parent 5e006a6a21
commit 47f4fad75c
251 changed files with 29298 additions and 4 deletions
+28
View File
@@ -0,0 +1,28 @@
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /SAVVY/geofencearea/
#RewriteBase /
#Checks to
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]
</IfModule>
<IfModule !mod_rewrite.c>
# If we don't have mod_rewrite installed, all 404's
# can be sent to index.php, and everything works as normal.
# Submitted by: ElliotHaughin
ErrorDocument 404 /index.php
</IfModule>
#Header add Access-Control-Allow-Origin "*"
#Header add Access-Control-Expose-Headers "Access-Control-Allow-Origin"
#Header add Access-Control-Allow-Headers "Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With"
#Header add Access-Control-Allow-Methods "POST, GET, PUT, DELETE, OPTIONS"
#Header add Content-type "application/json"
@@ -0,0 +1,211 @@
<?php
class AddressToArea
{
public static function get($db, $address_id, $city, $country)
{
$message = null;
$address_id = (int) $address_id;
$city_id = (int) $city;
$country_code = pg_escape_string($country);
$result_areas = [];
$postal_areas = [];
$radius_areas = [];
$plygon_areas = [];
// Step 1: Load address
$q = "SELECT * FROM address WHERE id=${address_id}";
$r = pg_query($db, $q);
if ($r && pg_num_rows($r)) {
$address = pg_fetch_assoc($r);
} else {
return [null, "Address was not found"];
}
// Step 2: Load areas for the city and country
$q = "SELECT *
FROM geofence_area
WHERE "
. (!empty($city_id) ? "city_id = ${city_id} AND" : '') .
" country='${country_code}'";
$r = pg_query($db, $q);
if ($r && pg_num_rows($r)) {
while ($f = pg_fetch_assoc($r)) {
if ($f["type"] == "postal") {
$postal_areas[] = $f;
}
if ($f["type"] == "radius") {
$radius_areas[] = $f;
}
if ($f["type"] == "polygon") {
$plygon_areas[] = $f;
}
$raw_areas[] = $f;
}
} else {
return [null, pg_last_error()];
}
if (count($postal_areas) < 1 && count($radius_areas) < 1 && count($plygon_areas) < 1) {
return [null, "No areas defined for the city/country"];
}
$result_areas = AddressToArea::getAreasForAddress($db, $address, $postal_areas, $radius_areas, $plygon_areas);
return [$result_areas, $message];
}
public static function getAreasForAddress($db, $address, $postal_areas, $radius_areas, $plygon_areas)
{
$result_areas = [];
// Process postal codes
if (count($postal_areas) > 0) {
foreach ($postal_areas as $area) {
$boundaries = json_decode($area["boundaries"], true);
$codes = $boundaries["postal_code"];
// if postal is not empty
if (!empty($address["postal"])) {
foreach ($codes as $code) {
if ($code != "" && $code == substr($address["postal"], 0, strlen($code))) {
$result_areas[] = $area;
break;
}
}
// if postal is empty
} else if ($address["latitude"] != 0 && $address["longitude"] != 0) {
$radius = 10; // 10Km
$postals = self::getPostalFromLatLng($db, $address["latitude"], $address["longitude"], $radius);
$flag = false;
foreach ($postals as $postal) {
if ($flag) {
break;
}
foreach ($codes as $code) {
if ($code != "" && $code == substr($postal, 0, strlen($code))) {
$result_areas[] = $area;
$flag = true;
break;
}
}
}
}
}
}
// Process radius
if ($address["latitude"] != 0 && $address["longitude"] != 0 && count($radius_areas) > 0) {
foreach ($radius_areas as $area) {
$boundaries = json_decode($area["boundaries"], true);
if (isset($boundaries['radius'])) {
$radius = $boundaries['radius'];
// query to check if belongs to a radius area
$query = "SELECT ST_DWithin('" . $area['location'] . "', ST_SetSRID(ST_Point (" . $address["longitude"] . ", " . $address["latitude"] . "), 4326)::geography, ${radius}) as iscorrect";
$data = pg_fetch_all(pg_query($db, $query));
if ($data[0]['iscorrect'] == "t") {
$result_areas[] = $area;
}
}
}
}
// Process polygon
if ($address["latitude"] != 0 && $address["longitude"] != 0 && count($plygon_areas) > 0) {
foreach ($plygon_areas as $area) {
$boundaries = json_decode($area["boundaries"], true);
if (isset($boundaries['polygon'])) {
$polygon = $boundaries['polygon'];
$polygonCoords = [];
foreach ($polygon as $coord) {
$polygonCoords[] = "$coord[0] $coord[1]";
}
$polygonCoordsString = implode(",", $polygonCoords);
// query to check if belongs to a polygon area
$query = "SELECT ST_Contains(ST_GeomFromText('POLYGON((${polygonCoordsString}))', 4326), ST_SetSRID(ST_Point (" . $address["longitude"] . ", " . $address["latitude"] . "), 4326)) as iscorrect";
$data = pg_fetch_all(pg_query($db, $query));
if ($data[0]['iscorrect'] == "t") {
$result_areas[] = $area;
}
}
}
}
return $result_areas;
}
/**
* get postal array from latitude, longitude
*/
public static function getPostalFromLatLng($db, float $latitude, float $longitude, int $distance_in_km): array
{
$earth_radius = 6371;
$km_per_degree_lat = 111.2;
$pi = 3.14 / 180;
$query = " SELECT postal FROM (
SELECT
CASE
WHEN
$latitude = address.latitude AND $longitude = address.longitude THEN 0
ELSE
$earth_radius * acos(
cos( radians( {$latitude}) )
* cos( radians( address.latitude ) )
* cos( radians( address.longitude ) - radians( {$longitude} ) )
+ sin( radians( {$latitude}) )
* sin( radians( address.latitude ) ) )
END AS distance
, *
FROM address
WHERE
address.postal IS NOT NULL
AND address.latitude BETWEEN " . ($latitude - ($distance_in_km / $km_per_degree_lat)) .
" AND " . ($latitude + ($distance_in_km / $km_per_degree_lat));
$delta = round($distance_in_km / ($km_per_degree_lat * COS(deg2rad($longitude))), 10);
// Bounding box for speed - latitude within range (longtitude to km not linear)
if (cos($longitude * $pi) > 0) {
$from = $longitude - $delta;
$to = $longitude + $delta;
$query .=
" AND address.longitude" .
" BETWEEN " . $from .
" AND " . $to;
} else {
$from = $longitude + $delta;
$to = $longitude - $delta;
$query .=
" AND address.longitude" .
" BETWEEN " . $from .
" AND " . $to;
}
// distance limit for circle
$query .= " ) address
WHERE distance < " . $distance_in_km;
$rs = pg_query($db, $query);
if (!$rs) {
throw new Exception(pg_last_error($db));
}
return pg_fetch_all($rs) ? array_column(pg_fetch_all($rs), 'postal') : [];
}
}
// vi:ts=2
@@ -0,0 +1,76 @@
<?php
class AddressToAreaApi extends Api {
public $apiName = 'addresstoarea';
public function __construct($requestUri, $encryption=true) {
$encryption = false; // We do not need encryption for this class
parent::__construct($requestUri, $encryption);
//$this->encryption = $encryption;
}
/**
* @OA\Get(
* path="/SAVVY/geofencearea/api/addresstoarea?address_id={address_id}",
* security={{"token": {}}},
* summary="Geocode address id to a geofence area",
* @OA\Response(
* response="200",
* description="area list address belongs to",
* @OA\JsonContent(
* type="object"
* )
* )
* )
*/
public function indexAction() {
$message = 'No areas found';
$address_id = $this->requestParams['address_id'] ?? 0;
$city = $this->requestParams['city'] ?? 0;
$country = $this->requestParams['country'] ?? '';
try {
if ($address_id<1) {
throw new Exception("Invalid address ID");
}
if (!in_array(strtoupper($country), ['SG','US']) ) { // Singapore and USA only for now
throw new Exception("Invalid country");
}
$db = new Db();
list($res, $err) = AddressToArea::get( $db->getConnect(), $address_id, $city, $country );
return $this->response(
[
"areas" => $res,
"error" => $err
], 200 );
} catch (Exception $e) {
$message = $e->getMessage();
}
return $this->response(
[
"areas" => NULL,
"error" => $message
], 404);
}
public function viewAction() {
}
public function createAction() {
}
public function updateAction() {
}
public function deleteAction() {
}
}
@@ -0,0 +1,244 @@
<?php
class GeofenceAreaApi extends Api
{
public $apiName = 'geofencearea';
/**
* @OA\Get(
* path="/v1/geofencearea/api/geofencearea/countryApi",
* summary="Get list of countries",
* @OA\Response(
* response="200",
* description="return all geofence area countries",
* @OA\JsonContent(
* type="object"
* )
* )
* )
*/
public function countryApi()
{
$db = new Db();
$result = GeofenceAreaModel::getCountryListWithoutPagination($db->getConnect());
return $this->response($result, 200);
}
/**
* @OA\Get(
* path="/v1/geofencearea/api/geofencearea/cityApi?country_code={country_code}",
* summary="Get list of cities",
* @OA\Response(
* response="200",
* description="city data",
* @OA\JsonContent(
* type="object"
* )
* )
* )
*/
public function cityApi()
{
$db = new Db();
$searchParams = $this->requestParams;
$result = GeofenceAreaModel::getCityListWithoutPagination($db->getConnect(), $searchParams);
return $this->response($result, 200);
}
/**
* @OA\Get(
* path="/v1/geofencearea/api/geofencearea/boundariesApi?city_id={city_id}&country_code={country_code}",
* summary="Get list of GPS areas by city and country_code",
* @OA\Response(
* response="200",
* description="area data",
* @OA\JsonContent(
* type="object"
* )
* )
* )
*/
public function boundariesApi()
{
$db = new Db();
$searchParams = $this->requestParams;
$result = GeofenceAreaModel::getAreaListWithoutPagination($db->getConnect(), $searchParams);
return $this->response($result, 200);
}
/**
* @OA\Get(
* path="/v1/geofencearea/api/geofencearea/tripsApi?from_area_id={from_area_id}&to_area_id={to_area_id}&transport_provider_id={transport_provider_id}",
* summary="Get list of trips between areas (filter by transport_provider_id)",
* @OA\Response(
* response="200",
* description="trip data",
* @OA\JsonContent(
* type="object"
* )
* )
* )
*/
public function tripsApi()
{
$db = new Db();
$searchParams = $this->requestParams;
$startAreaId = $searchParams['from_area_id'] ?? null;
$endAreaId = $searchParams['to_area_id'] ?? null;
if (!$startAreaId || !$endAreaId) {
$result = [
'success' => false,
'message' => 'missing parameter values (from_area_id and to_area_id parameter are required).'
];
return $this->response($result, 200);
}
$result = GeofenceAreaModel::getTripListBetweenArea($db->getConnect(), $startAreaId, $endAreaId, $searchParams);
return $this->response($result, 200);
}
/**
* @OA\Get(
* path="/v1/geofencearea/api/geofencearea/priceComparisonApi?from_area_id={from_area_id}&to_area_id={to_area_id}",
* summary="Compare price between areas (group by transport_provider_id)",
* @OA\Response(
* response="200",
* description="data",
* @OA\JsonContent(
* type="object"
* )
* )
* )
*/
public function priceComparisonApi()
{
$db = new Db();
$searchParams = $this->requestParams;
$startAreaId = $searchParams['from_area_id'] ?? null;
$endAreaId = $searchParams['to_area_id'] ?? null;
if (!$startAreaId || !$endAreaId) {
$result = [
'success' => false,
'message' => 'missing parameter values (from_area_id and to_area_id parameter are required).'
];
return $this->response($result, 200);
}
$data = GeofenceAreaModel::priceComparison($db->getConnect(), $startAreaId, $endAreaId);
$result = [
'success' => true,
'data' => $data ?: []
];
return $this->response($result, 200);
}
/**
* @OA\Get(
* path="/v1/geofencearea/api/geofencearea/priceComparisonFromAreasToOneDestinationApi?from_area_id_list=3,4,5,2,7&to_area_id=9",
* summary="Compare price from list of areas to one destination (group by transport_provider_id)",
* @OA\Response(
* response="200",
* description="data",
* @OA\JsonContent(
* type="object"
* )
* )
* )
*/
public function priceComparisonFromAreasToOneDestinationApi()
{
$db = new Db();
$searchParams = $this->requestParams;
// with params format fo ....&from_area_id_list=2,3,4,5,8,9&to_area_id=15
$startAreaIdList = $searchParams['from_area_id_list'] ?? null;
$endAreaId = $searchParams['to_area_id'] ?? null;
if (!$startAreaIdList || !$endAreaId) {
$result = [
'success' => false,
'message' => 'missing parameter values (from_area_id_list and to_area_id parameter are required).'
];
return $this->response($result, 200);
}
// convert from_area_id_list=2,3,4,5,8,9 => [2,3,4,5,8,9]
$startAreaIdList = explode(',', $startAreaIdList);
$data = [];
foreach ($startAreaIdList as $startAreaId) {
$data[] = GeofenceAreaModel::priceComparison($db->getConnect(), $startAreaId, $endAreaId);
}
$result = [
'success' => true,
'data' => $data ?: []
];
return $this->response($result, 200);
}
public function indexAction()
{
}
public function viewAction()
{
}
public function createAction()
{
}
public function updateAction()
{
}
public function deleteAction()
{
}
protected function getAction()
{
$method = $this->method;
switch ($method) {
case 'GET':
$pos = strpos($this->requestUri[0], '?');
if ($pos !== false && $pos == 0) {
// We want to get "all"
$this->requestUri[0] = "all" . $this->requestUri[0];
}
$tok = strtok($this->requestUri[0], '?');
if ($tok === false || $tok == 'all') {
return 'indexAction';
} else {
return $tok;
}
break;
case 'POST':
return 'createAction';
break;
case 'PUT':
return 'updateAction';
break;
case 'DELETE':
return 'deleteAction';
break;
default:
return null;
}
}
}
@@ -0,0 +1,619 @@
<?php
class GeofenceAreaModel
{
public static function getCountryListWithPagination($db, $page = 1, $perPage = 10)
{
$offset = ($page - 1) * $perPage;
if ($offset < 0) {
$offset = 0;
}
$query_total = "SELECT count(*) FROM geofence_area_country";
$query = "SELECT
id, country as country_code, latitude, longitude, location, radius
FROM
geofence_area_country
ORDER BY
id desc limit '" . pg_escape_string($perPage) . "' offset '" . pg_escape_string($offset) . "'";
$rs = pg_query($db, $query);
$rs_total = pg_query($db, $query_total);
$data = pg_fetch_all($rs);
return [
'success' => true,
'data' => !empty($data) ? $data : [],
'total' => pg_fetch_result($rs_total, 'count'),
'page' => $page,
];
}
public static function getCountryListWithoutPagination($db)
{
$query = "SELECT
id, country as country_code, latitude, longitude, location, radius
FROM
geofence_area_country
ORDER BY
id desc";
$rs = pg_query($db, $query);
$data = pg_fetch_all($rs);
return [
'success' => true,
'data' => !empty($data) ? $data : []
];
}
public static function getCityListWithPagination($db, $page = 1, $perPage = 10)
{
$offset = ($page - 1) * $perPage;
if ($offset < 0) {
$offset = 0;
}
$query_total = "SELECT count(*) FROM geofence_area_city";
$query = "SELECT
id, city, country as country_code, latitude, longitude, location, radius
FROM
geofence_area_city
ORDER BY
id desc limit '" . pg_escape_string($perPage) . "' offset '" . pg_escape_string($offset) . "'";
$rs = pg_query($db, $query);
$rs_total = pg_query($db, $query_total);
$data = pg_fetch_all($rs);
return [
'success' => true,
'data' => !empty($data) ? $data : [],
'total' => pg_fetch_result($rs_total, 'count'),
'page' => $page,
];
}
public static function getCityListWithoutPagination($db, $search = [])
{
$_self = new self;
$query = "SELECT
id, city, country as country_code,
latitude, longitude, location,
radius
FROM
geofence_area_city";
$whereQuery = '';
$order = " ORDER BY id desc";
if (!empty($search["country_code"])) {
$condition = " LOWER(country) = '" . pg_escape_string(strtolower($search["country_code"])) . "'";
$whereQuery = $_self->checkCondition($condition, $whereQuery);
$query .= $whereQuery;
}
if (!empty($search["latitude"]) &&
!empty($search["longitude"]) &&
!empty($search["radius"])) {
$earth_radius = 6371;
$km_per_degree_lat = 111.2;
$pi = 3.14/180;
$latitude = $search["latitude"];
$longitude = $search["longitude"];
$distance_in_km = $search["radius"];
$query = " SELECT id
, city
, country as country_code
, latitude
, longitude
, location
, radius
FROM (
SELECT (
$earth_radius * acos(
cos( radians( {$latitude}) )
* cos( radians( latitude ) )
* cos( radians( longitude ) - radians( {$longitude} ) )
+ sin( radians( {$latitude}) )
* sin( radians( latitude ) ))
) AS distance
, id
, city
, country
, latitude
, longitude
, location
, radius
FROM geofence_area_city
WHERE
latitude BETWEEN " . ($latitude - ($distance_in_km / $km_per_degree_lat)) .
" AND " . ($latitude + ($distance_in_km / $km_per_degree_lat));
$delta = round($distance_in_km / ($km_per_degree_lat * COS(deg2rad($longitude))), 10);
// Bounding box for speed - latitude within range (longtitude to km not linear)
if(cos($longitude * $pi) > 0) {
$from = $longitude - $delta;
$to = $longitude + $delta;
$query .=
" AND longitude" .
" BETWEEN " . $from .
" AND " . $to;
} else {
$from = $longitude + $delta;
$to = $longitude - $delta;
$query .=
" AND longitude" .
" BETWEEN " . $from .
" AND " . $to;
}
// distance limit for circle
$query .= " ) geofence_area_city
WHERE distance < " . $distance_in_km;
}
$query .= $order;
$rs = pg_query($db, $query);
$data = pg_fetch_all($rs);
return [
'success' => true,
'data' => !empty($data) ? $data : []
];
}
public static function getAreaListWithPagination($db, $page = 1, $perPage = 10, $search = [])
{
$_self = new self;
$offset = ($page - 1) * $perPage;
if ($offset < 0) {
$offset = 0;
}
$whereQuery = '';
if (isset($search["city_id"])) {
$condition = " geofence_area_city.id = '" . pg_escape_string($search["city_id"]) . "'";
$whereQuery = $_self->checkCondition($condition, $whereQuery);
}
$query_total = "SELECT count(*)
FROM
geofence_area
JOIN geofence_area_city ON geofence_area_city.id = geofence_area.city_id " . $whereQuery;
$query = "SELECT
geofence_area.id, geofence_area.name, geofence_area_city.city, geofence_area.country as country_code, geofence_area.latitude, geofence_area.longitude,
geofence_area.location, geofence_area.type, geofence_area.boundaries
FROM
geofence_area
JOIN geofence_area_city ON geofence_area_city.id = geofence_area.city_id
" . $whereQuery . "
ORDER BY
id desc limit '" . pg_escape_string($perPage) . "' offset '" . pg_escape_string($offset) . "'";
$rs = pg_query($db, $query);
$rs_total = pg_query($db, $query_total);
$data = pg_fetch_all($rs);
return [
'success' => true,
'data' => !empty($data) ? $data : [],
'total' => pg_fetch_result($rs_total, 'count'),
'page' => $page,
];
}
public static function getAreaListWithoutPagination($db, $search = [])
{
$_self = new self;
$whereQuery = '';
if (!empty($search["city_id"])) {
$condition = " geofence_area_city.id = '" . pg_escape_string($search["city_id"]) . "'";
$whereQuery = $_self->checkCondition($condition, $whereQuery);
}
if (!empty($search["country_code"])) {
$condition = " LOWER(geofence_area.country) = '" . pg_escape_string(strtolower($search["country_code"])) . "'";
$whereQuery = $_self->checkCondition($condition, $whereQuery);
}
$query = "SELECT
geofence_area.id, geofence_area.name, geofence_area_city.city, geofence_area.country as country_code, geofence_area.latitude, geofence_area.longitude,
geofence_area.location, geofence_area.type, geofence_area.boundaries
FROM
geofence_area
JOIN geofence_area_city ON geofence_area_city.id = geofence_area.city_id
" . $whereQuery . "
ORDER BY
id desc";
$rs = pg_query($db, $query);
$data = pg_fetch_all($rs);
return [
'success' => true,
'data' => !empty($data) ? $data : []
];
}
public static function getTripListBetweenArea($db, $startAreaId, $endAreaId, $search = [])
{
$_self = new self;
$whereQuery = '';
if (!empty($search["transport_provider_id"])) {
$condition = " parsedemail_item.transport_provider_id = '" . pg_escape_string($search["transport_provider_id"]) . "'";
$whereQuery = $_self->checkCondition($condition, $whereQuery);
}
// 1) Define geofenced areas, get list of areas
$startArea = $_self->getArea($db, $startAreaId);
$endArea = $_self->getArea($db, $endAreaId);
if (!$startArea || !$endArea) {
return [
'success' => false,
'message' => 'Can not find area.'
];
}
// 2. Select trips where "from" falls into origin area and "to" falls into destination area
$startBoundaries = json_decode($startArea['boundaries'], true);
$endBoundaries = json_decode($endArea['boundaries'], true);
if ($startArea['type'] === 'radius') {
if (isset($startBoundaries['radius'])) {
$radius = $startBoundaries['radius'];
$condition = " ST_DWithin('" . $startArea['location'] . "', startAddr.geometry, " . $radius . ") ";
$whereQuery = $_self->checkCondition($condition, $whereQuery);
} else {
return [
'success' => false,
'message' => 'Missing radius in boundaries field.'
];
}
} else if ($startArea['type'] === 'postal') {
if (is_array($startBoundaries) && array_key_exists("postal_code",$startBoundaries) && is_array($startBoundaries["postal_code"]) && count($startBoundaries["postal_code"]) > 0) {
$condition = "";
foreach ($startBoundaries['postal_code'] as $code) {
if ($condition != "") {
$condition .= " OR ";
}
$condition .= " LEFT(startAddr.postal, " . strlen($code) . ") = '${code}' ";
}
$condition = "(${condition})";
$whereQuery = $_self->checkCondition($condition, $whereQuery);
} else {
return [
'success' => false,
'message' => 'Missing postal_code in boundaries field.'
];
}
} else if ($startArea['type'] === 'polygon') {
if (isset($startBoundaries['polygon'])) {
$polygon = $startBoundaries['polygon'];
$polygonCoords = [];
foreach ($polygon as $coord) {
$polygonCoords[] = "$coord[0] $coord[1]";
}
$polygonCoordsString = implode(",", $polygonCoords);
$condition = " ST_Contains(ST_GeomFromText('POLYGON((${polygonCoordsString}))', 4326), startAddr.geometry::geometry) ";
$whereQuery = $_self->checkCondition($condition, $whereQuery);
} else {
return [
'success' => false,
'message' => 'Missing polygon in boundaries field.'
];
}
}
if ($endArea['type'] === 'radius') {
if (isset($endBoundaries['radius'])) {
$radius = $endBoundaries['radius'];
$condition = " ST_DWithin('" . $endArea['location'] . "', endAddr.geometry, " . $radius . ") ";
$whereQuery = $_self->checkCondition($condition, $whereQuery);
} else {
return [
'success' => false,
'message' => 'Missing radius in boundaries field.'
];
}
} else if ($endArea['type'] === 'postal') {
if (is_array($endBoundaries) && array_key_exists("postal_code",$endBoundaries) && is_array($endBoundaries["postal_code"]) && count($endBoundaries["postal_code"]) > 0) {
$condition = "";
foreach ($endBoundaries['postal_code'] as $code) {
if ($condition != "") {
$condition .= " OR ";
}
$condition .= " LEFT(endAddr.postal, " . strlen($code) . ") = '${code}' ";
}
$condition = "(${condition})";
$whereQuery = $_self->checkCondition($condition, $whereQuery);
} else {
return [
'success' => false,
'message' => 'Missing postal_code in boundaries field.'
];
}
} else if ($endArea['type'] === 'polygon') {
if (isset($endBoundaries['polygon'])) {
$polygon = $endBoundaries['polygon'];
$polygonCoords = [];
foreach ($polygon as $coord) {
$polygonCoords[] = "$coord[0] $coord[1]";
}
$polygonCoordsString = implode(",", $polygonCoords);
$condition = " ST_Contains(ST_GeomFromText('POLYGON((${polygonCoordsString}))', 4326), endAddr.geometry::geometry) ";
$whereQuery = $_self->checkCondition($condition, $whereQuery);
} else {
return [
'success' => false,
'message' => 'Missing polygon in boundaries field.'
];
}
}
// only get trips within last year
$numberOfDays = 365;
$condition = " parsedemail_item.travel_date BETWEEN NOW() - INTERVAL '" . $numberOfDays . " days' AND NOW() ";
$whereQuery = $_self->checkCondition($condition, $whereQuery);
$tripQuery =
"SELECT
parsedemail_item.id as trip_id, parsedemail_item.transport_provider_id, startAddr.address as start_address, endAddr.address as end_address
FROM
parsedemail_item
JOIN address AS startAddr ON (startAddr.id = parsedemail_item.location_start_id AND transport_provider_id IS NOT NULL
AND LOWER(startAddr.country) = '" . strtolower($startArea['country_code']) . "')
JOIN address AS endAddr ON (endAddr.id = parsedemail_item.location_end_id
AND LOWER(endAddr.country) = '" . strtolower($endArea['country_code']) . "')
" . $whereQuery;
$data = pg_fetch_all(pg_query($db, $tripQuery));
$result = [
'from_area' => $startArea,
'to_area' => $endArea,
'trip_list' => $data ?: []
];
return [
'success' => true,
'data' => $result ?: []
];
}
public static function priceComparison($db, $startAreaId, $endAreaId)
{
$_self = new self;
// 1) Define geofenced areas, get list of areas
$startArea = $_self->getArea($db, $startAreaId);
$endArea = $_self->getArea($db, $endAreaId);
if (!$startArea || !$endArea) {
return [
'success' => false,
'message' => 'Can not find area.'
];
}
$tripQuery = "SELECT ROUND(SUM(average_total)/SUM(average_count), 2) as avg_price, transport_provider_id";
$tripQuery.= " FROM geofence_area_average_quotes ";
$tripQuery.= " WHERE area_start_id=${startAreaId} AND area_end_id=${endAreaId}";
$tripQuery.= " GROUP BY transport_provider_id";
$data = pg_fetch_all(pg_query($db, $tripQuery));
error_log($tripQuery);
$result = [
'from_area' => $startArea,
'to_area' => $endArea,
'price_comparison' => $data ?: []
];
return $result;
}
public static function priceComparisonOld($db, $startAreaId, $endAreaId)
{
$_self = new self;
// 1) Define geofenced areas, get list of areas
$startArea = $_self->getArea($db, $startAreaId);
$endArea = $_self->getArea($db, $endAreaId);
if (!$startArea || !$endArea) {
return [
'success' => false,
'message' => 'Can not find area.'
];
}
// 2. Select trips where "from" falls into origin area and "to" falls into destination area
$whereQuery = '';
$startBoundaries = json_decode($startArea['boundaries'], true);
$endBoundaries = json_decode($endArea['boundaries'], true);
if ($startArea['type'] === 'radius') {
if (isset($startBoundaries['radius'])) {
$radius = $startBoundaries['radius'];
$condition = " ST_DWithin('" . $startArea['location'] . "', startAddr.geometry, " . $radius . ") ";
$whereQuery = $_self->checkCondition($condition, $whereQuery);
} else {
return [
'success' => false,
'message' => 'Missing radius in boundaries field.'
];
}
} else if ($startArea['type'] === 'postal') {
if (is_array($startBoundaries) && array_key_exists("postal_code",$startBoundaries) && is_array($startBoundaries["postal_code"]) && count($startBoundaries["postal_code"]) > 0) {
$condition = "";
foreach ($startBoundaries['postal_code'] as $code) {
if ($condition != "") {
$condition .= " OR ";
}
$condition .= " LEFT(startAddr.postal, " . strlen($code) . ") = '${code}' ";
}
$condition = "(${condition})";
$whereQuery = $_self->checkCondition($condition, $whereQuery);
} else {
return [
'success' => false,
'message' => 'Missing postal_code in boundaries field.'
];
}
} else if ($startArea['type'] === 'polygon') {
if (isset($startBoundaries['polygon'])) {
$polygon = $startBoundaries['polygon'];
$polygonCoords = [];
foreach ($polygon as $coord) {
$polygonCoords[] = "$coord[0] $coord[1]";
}
$polygonCoordsString = implode(",", $polygonCoords);
$condition = " ST_Contains(ST_GeomFromText('POLYGON((${polygonCoordsString}))', 4326), startAddr.geometry::geometry) ";
$whereQuery = $_self->checkCondition($condition, $whereQuery);
} else {
return [
'success' => false,
'message' => 'Missing polygon in boundaries field.'
];
}
}
if ($endArea['type'] === 'radius') {
if (isset($endBoundaries['radius'])) {
$radius = $endBoundaries['radius'];
$condition = " ST_DWithin('" . $endArea['location'] . "', endAddr.geometry, " . $radius . ") ";
$whereQuery = $_self->checkCondition($condition, $whereQuery);
} else {
return [
'success' => false,
'message' => 'Missing radius in boundaries field.'
];
}
} else if ($endArea['type'] === 'postal') {
if (is_array($endBoundaries) && array_key_exists("postal_code",$endBoundaries) && is_array($endBoundaries["postal_code"]) && count($endBoundaries["postal_code"]) > 0) {
$condition = "";
foreach ($endBoundaries['postal_code'] as $code) {
if ($condition != "") {
$condition .= " OR ";
}
$condition .= " LEFT(endAddr.postal, " . strlen($code) . ") = '${code}' ";
}
$condition = "(${condition})";
$whereQuery = $_self->checkCondition($condition, $whereQuery);
} else {
return [
'success' => false,
'message' => 'Missing postal_code in boundaries field.'
];
}
} else if ($endArea['type'] === 'polygon') {
if (isset($endBoundaries['polygon'])) {
$polygon = $endBoundaries['polygon'];
$polygonCoords = [];
foreach ($polygon as $coord) {
$polygonCoords[] = "$coord[0] $coord[1]";
}
$polygonCoordsString = implode(",", $polygonCoords);
$condition = " ST_Contains(ST_GeomFromText('POLYGON((${polygonCoordsString}))', 4326), endAddr.geometry::geometry) ";
$whereQuery = $_self->checkCondition($condition, $whereQuery);
} else {
return [
'success' => false,
'message' => 'Missing polygon in boundaries field.'
];
}
}
// 3. Filter pricing by transport_provider_id and calculate average within last year
// only get trips within last year
$numberOfDays = 365;
$condition = " parsedemail_item.travel_date BETWEEN NOW() - INTERVAL '" . $numberOfDays . " days' AND NOW() ";
$whereQuery = $_self->checkCondition($condition, $whereQuery);
$tripQuery =
"SELECT
ROUND(AVG(parsedemail_item.cost), 2) as avg_price, parsedemail_item.transport_provider_id
FROM
parsedemail_item
JOIN address AS startAddr ON (startAddr.id = parsedemail_item.location_start_id AND transport_provider_id IS NOT NULL
AND LOWER(startAddr.country) = '" . strtolower($startArea['country_code']) . "')
JOIN address AS endAddr ON (endAddr.id = parsedemail_item.location_end_id
AND LOWER(endAddr.country) = '" . strtolower($endArea['country_code']) . "')
" . $whereQuery . "
GROUP BY parsedemail_item.transport_provider_id
";
$data = pg_fetch_all(pg_query($db, $tripQuery));
$result = [
'from_area' => $startArea,
'to_area' => $endArea,
'price_comparison' => $data ?: []
];
return $result;
}
private function checkCondition($condition, $query)
{
if (strpos($query, 'WHERE') === false) {
$query .= " WHERE $condition";
} else {
$query .= " AND $condition";
}
return $query;
}
public static function getArea($db, $id)
{
$query = "SELECT
geofence_area.id, geofence_area.name, geofence_area.country as country_code, geofence_area.latitude, geofence_area.longitude,
geofence_area.location, geofence_area.type, geofence_area.boundaries
FROM
geofence_area
WHERE
geofence_area.id = $id
LIMIT 1
";
$rs = pg_query($db, $query);
$data = pg_fetch_assoc($rs);
return $data;
}
}
@@ -0,0 +1,149 @@
<?php
class HourlyAverages {
public static function get($db, $from_address, $to_address, $city, $country) {
$message = NULL;
$city_id = (int)$city;
$country_code = pg_escape_string($country);
$from_areas = [];
$to_areas = [];
$postal_areas = [];
$radius_areas = [];
$plygon_areas = [];
// Load areas for the city and country
$q = "SELECT * FROM geofence_area WHERE city_id=${city_id} AND country='${country_code}'";
$r = pg_query($db, $q);
if ($r && pg_num_rows($r)) {
while ($f=pg_fetch_assoc($r)) {
if ($f["type"]=="postal") {
$postal_areas[] = $f;
}
if ($f["type"]=="radius") {
$radius_areas[] = $f;
}
if ($f["type"]=="polygon") {
$plygon_areas[] = $f;
}
$raw_areas[] = $f;
}
} else {
return [NULL,pg_last_error()];
}
if (count($postal_areas)<1 && count($radius_areas)<1 && count($plygon_areas)<1) {
return [NULL,"No areas defined for the city"];
}
$from_areas = AddressToArea::getAreasForAddress($db,$from_address,$postal_areas,$radius_areas,$plygon_areas);
if (!is_array($from_areas) || count($from_areas)<1) {
return [NULL,"Cannot geocode from address to an area"];
}
$to_areas = AddressToArea::getAreasForAddress($db,$to_address,$postal_areas,$radius_areas,$plygon_areas);
if (!is_array($to_areas) || count($to_areas)<1) {
return [NULL,"Cannot geocode to address to an area"];
}
$data = [];
$q = "SELECT * FROM geofence_area_average_quotes ";
$q.= " WHERE area_start_id=".$from_areas[0]["id"]." AND area_end_id=".$to_areas[0]["id"];
$q.= " ORDER BY transport_provider_id, hour";
$r = pg_query($db, $q);
if ($r && pg_num_rows($r)) {
while ($f=pg_fetch_assoc($r)) {
if (!array_key_exists($f['transport_provider_id'],$data)) {
$data[$f['transport_provider_id']] = [];
}
$data[$f['transport_provider_id']][$f['hour']] = $f;
}
}
$certainty = HourlyAverages::calculateCertainty($data);
$result_areas = [
'from_areas' => $from_areas,
'to_areas' => $to_areas,
'hourlyaverages' => $data,
'certainty' => $certainty
];
return [$result_areas, $message];
}
public static function calculateCertainty($data) {
$vendors = []; // Vendors to process
$hours = []; // Transposition matrix
$Pi = []; // Certainity by vendor (current hour)
$Wi = []; // Weight by vendor (current hour)
$Si = []; // Sum by vendor per hout
$Ri = []; // Certainty per hour
foreach ($data as $key=>$val) {
$vendors[] = $key;
$Pi[$key] = 0;
$Wi[$key] = 0;
}
for ($i=0; $i<24; $i++) {
$hours[$i] = [];
$Si[$i] = 0;
$Ri[$i] = 0;
foreach ($vendors as $vendor) {
$hours[$i][$vendor] = NULL;
}
}
foreach ($data as $key=>$val) {
foreach ($val as $hour=>$f) {
$hours[$f['hour']][$f['transport_provider_id']] = [
'average_cost' => $f['average_cost'],
'average_total' => $f['average_total'],
'average_count' => $f['average_count']
];
$Si[$f['hour']] += $f['average_count'];
}
}
for ($i=0; $i<24; $i++) {
$d = $hours[$i];
foreach ($d as $vendor=>$f) {
if ($f===NULL) {
$Pi[$vendor] = 0;
} else {
if ($f['average_count']<10) {
$Pi[$vendor] = 0;
} else {
$Pi[$vendor] = 1-10/$f['average_count'];
}
if ($Si[$i]!==0) {
$Wi[$vendor] = $f['average_count']/$Si[$i];
} else {
$Wi[$vendor] = 0;
}
}
$Ri[$i] += 100.0 * $Pi[$vendor] * $Wi[$vendor];
}
}
return $Ri;
}
public static function getCityInfo($db, $cityId) {
$result = [];
$q = "SELECT gac.city, gac.country, atz.timezone
FROM geofence_area_city gac
LEFT JOIN address_view av on address_search @@ to_tsquery('simple', array_to_string(string_to_array(gac.city, ' '), ':* & ') || ':* & ' || gac.country)
LEFT JOIN address_timezone atz on av.timezone = atz.id
WHERE gac.id =${cityId}
LIMIT 1
";
$r = pg_query( $db, $q );
if ( $r && pg_num_rows( $r ) && $f = pg_fetch_assoc( $r ) ) {
$result = $f;
}
return $result;
}
}
// vi:ts=2
@@ -0,0 +1,223 @@
<?php
class HourlyAveragesApi extends Api {
public $apiName = 'hourlyaverages';
public function __construct($requestUri, $encryption=true) {
$encryption = false; // We do not need encryption for this class
parent::__construct($requestUri, $encryption);
//$this->encryption = $encryption;
}
/**
* @OA\Get(
* path="/SAVVY/geofencearea/api/addresstoarea?address_id={address_id}",
* security={{"token": {}}},
* summary="Geocode address id to a geofence area",
* @OA\Response(
* response="200",
* description="area list address belongs to",
* @OA\JsonContent(
* type="object"
* )
* )
* )
*/
public function indexAction() {
$message = 'No hourly data found';
$from_address = $this->requestParams['from_address'] ?? '';
$to_address = $this->requestParams['to_address'] ?? '';
$country = $this->requestParams['country'] ?? '';
$city = $this->requestParams['city'] ?? 0;
$member_id = $this->requestParams['member_id'] ?? 0;
$from_lat = $this->requestParams['from_lat'] ?? '';
$from_lng = $this->requestParams['from_lng'] ?? '';
$to_lat = $this->requestParams['to_lat'] ?? '';
$to_lng = $this->requestParams['to_lng'] ?? '';
$from_postal_code = $this->requestParams['from_postal_code'] ?? null;
$to_postal_code = $this->requestParams['to_postal_code'] ?? null;
try {
if ($from_address==="") {
throw new Exception("Invalid from address");
}
if ($to_address==="") {
throw new Exception("Invalid to address");
}
if ($city<1) {
throw new Exception("Invalid city");
}
if (!in_array(strtoupper($country), ['SG','US']) ) { // Singapore and USA only for now
throw new Exception("Invalid country");
}
// Get city info by ID
$db = new Db();
$cityInfo = HourlyAverages::getCityInfo($db->getConnect(), $city);
if (count($cityInfo) == 0) {
throw new Exception("Couldn't get information for city with id=${city}");
}
$timeZoneId = $cityInfo['timezone'];
$cityName = $cityInfo['city'];
// Step 1: geocode the addresses
if ($from_lat && $from_lng) {
$fAddress = [
'address' => $from_address,
'geocode' => [
'message' => '',
'latitude' => $from_lat,
'longitude' => $from_lng,
'address' => $from_address,
'postal' => $from_postal_code,
'timeZoneId' => $timeZoneId,
'city' => $cityName,
'city_lat' => $from_lat,
'city_lng' => $from_lng,
'country' => $country,
'id' => null
],
'error' => null
];
} else {
list($fAddress, $err) = $this->geocode($from_address,$country,(int)$member_id);
if (!is_array($fAddress) || !array_key_exists('geocode',$fAddress) || !is_array($fAddress['geocode'])
|| !array_key_exists('id',$fAddress['geocode']) || $fAddress['geocode']['id']<1) {
throw new Exception("Failed to geocode from address".json_encode($fAddress));
}
$fAddress['geocode']['longitude'] = $fAddress['geocode']['lng'];
$fAddress['geocode']['latitude'] = $fAddress['geocode']['lat'];
}
if ($to_lat && $to_lng) {
$tAddress = [
'address' => $to_address,
'geocode' => [
'message' => '',
'latitude' => $to_lat,
'longitude' => $to_lng,
'address' => $to_address,
'postal' => $to_postal_code,
'timeZoneId' => $timeZoneId,
'city' => $cityName,
'city_lat' => $to_lat,
'city_lng' => $to_lng,
'country' => $country,
'id' => null
],
'error' => null
];
} else {
list($tAddress, $err) = $this->geocode($to_address,$country,(int)$member_id);
if (!is_array($tAddress) || !array_key_exists('geocode',$tAddress) || !is_array($tAddress['geocode'])
|| !array_key_exists('id',$tAddress['geocode']) || $tAddress['geocode']['id']<1) {
throw new Exception("Failed to geocode to address");
}
$tAddress['geocode']['longitude'] = $tAddress['geocode']['lng'];
$tAddress['geocode']['latitude'] = $tAddress['geocode']['lat'];
}
list($res, $err) = HourlyAverages::get( $db->getConnect(), $fAddress['geocode'], $tAddress['geocode'], $city, $country );
if (!is_array($res) || count($res)<1) {
throw new Exception($err!==""?$err:"Failed to get hourly averages");
}
$result = [
'city' => $city,
'country' => $country,
'member_id' => $member_id,
'from_address' => $fAddress,
'to_address' => $tAddress,
'data' => $res
];
return $this->response(
[
"hourlyaverages" => $result,
"error" => $err
], 200 );
} catch (Exception $e) {
$message = $e->getMessage();
}
return $this->response(
[
"hourlyaverages" => NULL,
"error" => $message
], 404);
}
public function viewAction() {
}
public function createAction() {
}
public function updateAction() {
}
public function deleteAction() {
}
protected function geocode($address, $country, $member_id=0) {
global $httpAuthToken, $savvyext;
$encryptionAlg = $savvyext->cfgReadChar('encryption.algorithm');
$encryptionKey = $savvyext->cfgReadChar('encryption.key');
$encryptionIV = $savvyext->cfgReadChar('encryption.iv');
$baseURL = $savvyext->cfgReadChar('system.api_url');
$in = [
'address' => $address,
'member_id' => $member_id,
'country' => $country
];
$data = http_build_query($in);
$url = $baseURL . "/trips/api/geocode/?".$data;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_VERBOSE, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Authorization: Server-Token ' . $httpAuthToken)
);
$body = curl_exec($ch);
$result = json_decode($body,true);
$payload = openssl_decrypt(
hex2bin(
$result['payload']
),
$encryptionAlg,
$encryptionKey,
OPENSSL_RAW_DATA,
$encryptionIV
);
return [json_decode($payload,true),$body];
}
}
@@ -0,0 +1,27 @@
<?php
class PopularDestinations {
public static function get($db, $country, $city, $limit=10) {
$city_id = (int)$city;
$country_code = pg_escape_string($country);
$q = "SELECT a.id AS attraction_id,a.attraction,a.active,a.address_id,a.city_id,b.* ";
$q.= " FROM tourist_attraction a, address b ";
$q.= " WHERE b.id=a.address_id AND b.country='SG' AND a.city_id=1 AND a.active='t' ";
$q.= " ORDER BY a.attraction";
$r = pg_query($db, $q);
if ($r && pg_num_rows($r)) {
$result = [];
while ($f=pg_fetch_assoc($r)) {
$result[] = $f;
}
return [$result, NULL];
}
return [NULL,pg_last_error()];
}
}
// vi:ts=2
@@ -0,0 +1,73 @@
<?php
class PopularDestinationsApi extends Api {
public $apiName = 'populardestinations';
public function __construct($requestUri, $encryption=true) {
$encryption = false; // We do not need encryption for this class
parent::__construct($requestUri, $encryption);
//$this->encryption = $encryption;
}
/**
* @OA\Get(
* path="/SAVVY/geofencearea/api/populardestinations?city={city_id}&country={country_code}",
* security={{"token": {}}},
* summary="Get list of popular destinations by city id and country code",
* @OA\Response(
* response="200",
* description="city list",
* @OA\JsonContent(
* type="object"
* )
* )
* )
*/
public function indexAction() {
$message = 'No popular destinations found';
$city = $this->requestParams['city'] ?? 0;
$country = $this->requestParams['country'] ?? '';
try {
if ($city<1) {
throw new Exception("Invalid city");
}
if ($country!='SG') {
throw new Exception("Invalid country");
}
$db = new Db();
list($res, $err) = PopularDestinations::get( $db->getConnect(), $country, $city );
return $this->response(
[
"destinations" => $res,
"error" => $err
], 200 );
} catch (Exception $e) {
$message = $e->getMessage();
}
return $this->response(
[
"destinations" => NULL,
"error" => $message
], 404);
}
public function viewAction() {
}
public function createAction() {
}
public function updateAction() {
}
public function deleteAction() {
}
}
+85
View File
@@ -0,0 +1,85 @@
<?php
#require_once('../../../adminsavvy/vendor/autoload.php');
$profile = getenv("SAVVY_PROFILE");
if ($profile) {
require_once("../../core/backend.${profile}.php");
} else {
require_once( '../../core/backend.php' );
}
require_once '../common/Api.php';
require_once '../common/Db.php';
require_once 'AddressToArea.php';
require_once 'AddressToAreaApi.php';
require_once 'GeofenceAreaModel.php';
require_once 'GeofenceAreaApi.php';
require_once 'HourlyAverages.php';
require_once 'HourlyAveragesApi.php';
require_once 'PopularDestinations.php';
require_once 'PopularDestinationsApi.php';
$httpAuthToken = $savvyext->cfgReadChar('system.oauth2_token');
header("Access-Control-Allow-Origin: *");
header("Access-Control-Expose-Headers: Access-Control-Allow-Origin");
header("Access-Control-Allow-Headers: Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With, client_id");
header("Access-Control-Allow-Methods: POST, GET, PUT, DELETE, OPTIONS");
header('Content-type: application/json');
if ("OPTIONS" === $_SERVER['REQUEST_METHOD']) {
exit();
}
$headers = getallheaders();
if ((!isset($headers["Authorization"]) || substr($headers["Authorization"], -strlen($httpAuthToken)) != $httpAuthToken) &&
(!isset($headers["authorization"]) || substr($headers["authorization"], -strlen($httpAuthToken)) != $httpAuthToken)) {
header('HTTP/1.1 401 Unauthorized');
header('Status: 401 Unauthorized');
echo "{\"status\":\"Missing authorization\"}";
exit();
}
try {
if (strpos($_SERVER['REQUEST_URI'], '/api/') === false) {
throw new Exception("Invalid API request");
}
$requestUri = explode('/', trim($_SERVER['REQUEST_URI'], '/'));
while (array_shift($requestUri) !== 'api') {
}
;
if ($requestUri[0] == 'addresstoarea') {
$api = new AddressToAreaApi($requestUri, false);
} else if ($requestUri[0] == 'geofencearea') {
$api = new geofenceAreaApi($requestUri, false);
} else if ($requestUri[0] == 'hourlyaverages') {
$api = new HourlyAveragesApi($requestUri, false);
} else if ($requestUri[0] == 'populardestinations') {
$api = new PopularDestinationsApi($requestUri, false);
} else {
echo json_encode(array('error' => 'Invalid API request'));
}
echo $api->run();
} catch (Exception $e) {
echo json_encode(array('error' => $e->getMessage()));
}
/**
* @OA\Info(
* title="Geofence Area Endpoint API",
* version="1.0",
* @OA\Contact(
* email="support@float.sg"
* )
* )
*/
/**
* @OA\SecurityScheme(
* securityScheme="token",
* type="apiKey",
* name="Authorization",
* in="header"
* )
*/
@@ -0,0 +1,135 @@
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
/*
| -------------------------------------------------------------------
| AUTO-LOADER
| -------------------------------------------------------------------
| This file specifies which systems should be loaded by default.
|
| In order to keep the framework as light-weight as possible only the
| absolute minimal resources are loaded by default. For example,
| the database is not connected to automatically since no assumption
| is made regarding whether you intend to use it. This file lets
| you globally define which systems you would like loaded with every
| request.
|
| -------------------------------------------------------------------
| Instructions
| -------------------------------------------------------------------
|
| These are the things you can load automatically:
|
| 1. Packages
| 2. Libraries
| 3. Drivers
| 4. Helper files
| 5. Custom config files
| 6. Language files
| 7. Models
|
*/
/*
| -------------------------------------------------------------------
| Auto-load Packages
| -------------------------------------------------------------------
| Prototype:
|
| $autoload['packages'] = array(APPPATH.'third_party', '/usr/local/shared');
|
*/
$autoload['packages'] = array();
/*
| -------------------------------------------------------------------
| Auto-load Libraries
| -------------------------------------------------------------------
| These are the classes located in system/libraries/ or your
| application/libraries/ directory, with the addition of the
| 'database' library, which is somewhat of a special case.
|
| Prototype:
|
| $autoload['libraries'] = array('database', 'email', 'session');
|
| You can also supply an alternative library name to be assigned
| in the controller:
|
| $autoload['libraries'] = array('user_agent' => 'ua');
*/
$autoload['libraries'] = array('session', 'template');
/*
| -------------------------------------------------------------------
| Auto-load Drivers
| -------------------------------------------------------------------
| These classes are located in system/libraries/ or in your
| application/libraries/ directory, but are also placed inside their
| own subdirectory and they extend the CI_Driver_Library class. They
| offer multiple interchangeable driver options.
|
| Prototype:
|
| $autoload['drivers'] = array('cache');
|
| You can also supply an alternative property name to be assigned in
| the controller:
|
| $autoload['drivers'] = array('cache' => 'cch');
|
*/
$autoload['drivers'] = array();
/*
| -------------------------------------------------------------------
| Auto-load Helper Files
| -------------------------------------------------------------------
| Prototype:
|
| $autoload['helper'] = array('url', 'file');
*/
$autoload['helper'] = array('redirect', 'get_class_name', 'api');
/*
| -------------------------------------------------------------------
| Auto-load Config files
| -------------------------------------------------------------------
| Prototype:
|
| $autoload['config'] = array('config1', 'config2');
|
| NOTE: This item is intended for use ONLY if you have created custom
| config files. Otherwise, leave it blank.
|
*/
$autoload['config'] = array('jwt');
/*
| -------------------------------------------------------------------
| Auto-load Language files
| -------------------------------------------------------------------
| Prototype:
|
| $autoload['language'] = array('lang1', 'lang2');
|
| NOTE: Do not include the "_lang" part of your file. For example
| "codeigniter_lang.php" would be referenced as array('codeigniter');
|
*/
$autoload['language'] = array();
/*
| -------------------------------------------------------------------
| Auto-load Models
| -------------------------------------------------------------------
| Prototype:
|
| $autoload['model'] = array('first_model', 'second_model');
|
| You can also supply an alternative model name to be assigned
| in the controller:
|
| $autoload['model'] = array('first_model' => 'first');
*/
$autoload['model'] = array();
Binary file not shown.

After

Width:  |  Height:  |  Size: 665 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 B

@@ -0,0 +1,60 @@
<!-- HTML for static distribution bundle build -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Swagger UI</title>
<link rel="stylesheet" type="text/css" href="swagger-ui.css" >
<link rel="icon" type="image/png" href="favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="favicon-16x16.png" sizes="16x16" />
<style>
html
{
box-sizing: border-box;
overflow: -moz-scrollbars-vertical;
overflow-y: scroll;
}
*,
*:before,
*:after
{
box-sizing: inherit;
}
body
{
margin:0;
background: #fafafa;
}
</style>
</head>
<body>
<div id="swagger-ui"></div>
<script src="swagger-ui-bundle.js"> </script>
<script src="swagger-ui-standalone-preset.js"> </script>
<script>
window.onload = function() {
// Begin Swagger UI call region
const ui = SwaggerUIBundle({
url: "../swagger.php",
dom_id: '#swagger-ui',
deepLinking: true,
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout"
})
// End Swagger UI call region
window.ui = ui
}
</script>
</body>
</html>
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,6 @@
<?php
require('../../../adminsavvy/vendor/autoload.php');
$openapi = \OpenApi\scan('.');
header('Content-Type: application/json');
echo $openapi->toJson();
?>