diff --git a/main2.php b/main2.php new file mode 100644 index 0000000..fc2e269 --- /dev/null +++ b/main2.php @@ -0,0 +1,138 @@ + 'Invalid service parameter. Please provide a valid service.', + 'available_services' => [ + 'cams', 'camapi', 'camlist', 'admin', 'camcircle', + 'db', 'fire', 'individualcam', 'lsr', 'nws', + 'powerapi', 'searchapi', 'ohgo', 'power', + 'stormdata', 'warntrack', 'ver', 'update_field', 'mp4', + 'camobs', 'single', 'powerapitest' + ], + 'documentation' => 'See main.php file for detailed documentation on each service.' + ]); +} +?> \ No newline at end of file diff --git a/php/main.php b/php/main.php new file mode 100644 index 0000000..86194a4 --- /dev/null +++ b/php/main.php @@ -0,0 +1,144 @@ + 'Invalid service parameter. Please provide a valid service.', + 'available_services' => [ + 'cams', 'camapi', 'camlist', 'admin', 'camcircle', + 'db', 'fire', 'individualcam', 'lsr', 'nws', + 'powerapi', 'searchapi', 'ohgo', 'power', 'newpower', + 'newpowerapi', 'newpowerapitest', 'newsearchapi', 'newstormdata', + 'stormdata', 'warntrack', 'ver', 'update_field', 'mp4', + 'camobs', 'single', 'powerapitest' + ], + 'documentation' => 'See main.php file for detailed documentation on each service.' + ]); +} +?> \ No newline at end of file diff --git a/php/newpower.php b/php/newpower.php new file mode 100644 index 0000000..b2342b8 --- /dev/null +++ b/php/newpower.php @@ -0,0 +1,25 @@ + $e->getMessage()]); +} finally { + pg_close($dbconn); +} +?> \ No newline at end of file diff --git a/php/newpowerapi.php b/php/newpowerapi.php new file mode 100644 index 0000000..dd56c2a --- /dev/null +++ b/php/newpowerapi.php @@ -0,0 +1,98 @@ + 'FeatureCollection', 'features' => []]); + } + + pg_free_result($result); + } catch (Exception $e) { + http_response_code(500); + die(json_encode(['error' => 'Query execution failed: ' . $e->getMessage()])); + } +} + +// Get current county outages +if (isset($_GET['county'])) { + try { + $query = " + WITH latest_fetch AS ( + SELECT MAX(fetch_time) as max_fetch_time FROM newcountyoutages + ) + SELECT + n.county, + n.state, + n.outages as outage, + n.fetch_time as time, + n.served, + CASE + WHEN n.served > 0 THEN ROUND(CAST((n.outages::FLOAT / n.served) * 100 AS NUMERIC), 2) + ELSE 0 + END as perout + FROM newcountyoutages n, latest_fetch + WHERE n.fetch_time = latest_fetch.max_fetch_time + AND n.cwa = $1 + "; + + $result = pg_query_params($dbconn, $query, ['RLX']); + if ($result === false) { + throw new Exception('Query failed: ' . pg_last_error()); + } + + $results = pg_fetch_all($result) ?: []; + echo json_encode($results); + + pg_free_result($result); + } catch (Exception $e) { + http_response_code(500); + echo json_encode(['error' => 'Query execution failed: ' . $e->getMessage()]); + } +} + +// Note: Other endpoints from the original powerapi.php can be migrated here as needed, +// such as 'states', 'max', 'countyarchive', 'archivepoint', 'svr', 'svrpolys', +// 'powerids', 'poweridsgeojson', and 'polygongeojson'. +// The queries would need to be updated to use the 'newpower' and 'newcountyoutages' tables +// and their corresponding columns (e.g., start_time, geom, fetch_time). + +pg_close($dbconn); +?> \ No newline at end of file diff --git a/php/newpowerapitest.php b/php/newpowerapitest.php new file mode 100644 index 0000000..af20b32 --- /dev/null +++ b/php/newpowerapitest.php @@ -0,0 +1,47 @@ + 0 THEN ROUND(CAST((n.outages::FLOAT / n.served) * 100 AS NUMERIC), 2) + ELSE 0 + END as perout + FROM newcountyoutages n, latest_fetch + WHERE n.fetch_time = latest_fetch.max_fetch_time + AND n.cwa IN ($placeholders) + "; + + $result = pg_query_params($dbconn, $query, $cwas); + if ($result === false) { + throw new Exception('Query failed: ' . pg_last_error()); + } + + $results = pg_fetch_all($result) ?: []; + echo json_encode($results); + + pg_free_result($result); + } catch (Exception $e) { + http_response_code(500); + echo json_encode(['error' => 'Query execution failed: ' . $e->getMessage()]); + } +} + +pg_close($dbconn); +?> \ No newline at end of file diff --git a/php/newsearchapi.php b/php/newsearchapi.php new file mode 100644 index 0000000..7d7909c --- /dev/null +++ b/php/newsearchapi.php @@ -0,0 +1,95 @@ + '')))) { + try { + $query = " + SELECT json_build_object( + 'type', 'FeatureCollection', + 'features', json_agg( + json_build_object( + 'type', 'Feature', + 'geometry', ST_AsGeoJSON(geom)::json, + 'properties', json_build_object( + 'time', start_time, + 'county', county, + 'state', state, + 'outage', outagen, + 'lastchange', last_change, + 'cause', cause + ) + ) + ORDER BY start_time ASC + ) + ) as geojson + FROM newpower + WHERE cwa = $1 AND active = true + "; + + $result = pg_query_params($dbconn, $query, array('RLX')); + if ($result === false) { + throw new Exception('Query failed: ' . pg_last_error()); + } + + $resultArray = pg_fetch_assoc($result); + + if ($resultArray && $resultArray['geojson']) { + echo $resultArray['geojson']; + } else { + echo json_encode(['type' => 'FeatureCollection', 'features' => []]); + } + + pg_free_result($result); + } catch (Exception $e) { + http_response_code(500); + die(json_encode(['error' => 'Query execution failed: ' . $e->getMessage()])); + } +} + +// Get current county outages from newcountyoutages table +if (isset($_GET['county'])) { + try { + $query = " + WITH latest_fetch AS ( + SELECT MAX(fetch_time) as max_fetch_time FROM newcountyoutages + ) + SELECT + n.fetch_time as time, + n.county, + n.state, + n.outages as outage, + n.served + FROM newcountyoutages n, latest_fetch + WHERE n.fetch_time = latest_fetch.max_fetch_time + AND n.cwa = $1 + ORDER BY n.county, n.state + "; + + $result = pg_query_params($dbconn, $query, ['RLX']); + if ($result === false) { + throw new Exception('Query failed: ' . pg_last_error()); + } + + $results = pg_fetch_all($result) ?: []; + echo json_encode($results); + + pg_free_result($result); + } catch (Exception $e) { + http_response_code(500); + echo json_encode(['error' => 'Query execution failed: ' . $e->getMessage()]); + } +} + +// Note: The 'countyarchive', 'archivepoint', and 'svr' endpoints from the original +// searchapi.php can be migrated here. The queries would need to be updated to use +// the 'newpower' and 'newcountyoutages' tables and their corresponding columns +// (e.g., start_time, geom, fetch_time). + +pg_close($dbconn); +?> + + diff --git a/php/newstormdata.php b/php/newstormdata.php new file mode 100644 index 0000000..f3066cf --- /dev/null +++ b/php/newstormdata.php @@ -0,0 +1,141 @@ + $message]); + exit; +} + +/** + * Handles power outage requests for the new schema. + * @param resource $dbconn The database connection. + * @param array $input_data The decoded JSON input data. + */ +function handle_new_power_request($dbconn, $input_data) { + $poly = $input_data['poly'] ?? null; + $start = $input_data['start'] ?? null; + $end = $input_data['end'] ?? null; + + if (!$poly || !$start || !$end) { + send_error(400, 'Missing required fields: poly, start, and end are required for power requests.'); + } + + $query = " + SELECT + SUM(p.outagen) as total_outages, + COUNT(p.id) as outage_events, + SUM(p.peakoutage) as peak_outages + FROM newpower p + WHERE ST_Within(p.geom, ST_GeomFromText($1, 4326)) + AND p.start_time >= $2 + AND p.start_time <= $3 + "; + + try { + $result = pg_query_params($dbconn, $query, [$poly, $start, $end]); + if ($result === false) { + throw new Exception('Database query failed: ' . pg_last_error($dbconn)); + } + $data = pg_fetch_assoc($result); + pg_free_result($result); + + header('Content-Type: application/json'); + echo json_encode($data ?: new stdClass()); // Return empty JSON object if no results + + } catch (Exception $e) { + send_error(500, 'An error occurred while processing the power request.', $e->getMessage()); + } +} + + +if ($_SERVER['REQUEST_METHOD'] === 'POST') { + $input_data = null; + $request_type = null; + $contentType = trim(strtolower($_SERVER['HTTP_CONTENT_TYPE'] ?? $_SERVER['CONTENT_TYPE'] ?? '')); + + if (strpos($contentType, 'application/json') === 0) { + $raw_post_data = file_get_contents('php://input'); + + if ($raw_post_data === false || $raw_post_data === '') { + send_error(400, 'Received empty request body or could not read input.', "Error: Could not read php://input or it was empty."); + } + + $input_data = json_decode($raw_post_data, true); + + if (json_last_error() !== JSON_ERROR_NONE) { + send_error(400, 'Invalid JSON payload received.', 'JSON Decode Error: ' . json_last_error_msg() . " | Raw data snippet: " . substr($raw_post_data, 0, 100)); + } elseif (!is_array($input_data)) { + send_error(400, 'Invalid JSON payload: Expected a JSON object.', "JSON Decode Warning: Result is not an array. Data: " . print_r($input_data, true)); + } else { + $request_type = $input_data['request_type'] ?? null; + } + } else { + send_error(415, 'Unsupported Media Type. This endpoint requires application/json.', "Unsupported Media Type Received: " . $contentType); + } + + if ($request_type === null) { + if (is_array($input_data) && !isset($input_data['request_type'])) { + send_error(400, 'Missing "request_type" field within the request payload.'); + } else { + send_error(400, 'Missing required parameter: request_type (or processing error).'); + } + } + + $dbconn = getDBConnection(); + + switch ($request_type) { + // Retaining legacy endpoints from stormdata.php but pointing to new handlers if needed + // For now, only implementing the 'power' endpoint for the new schema + case 'power': + handle_new_power_request($dbconn, $input_data); + break; + // The 'powernopoly' case from the original file can be implemented here if needed. + // It would be similar to handle_new_power_request but without the ST_Within clause. + + /* + // Legacy endpoints can be added here if they need to be migrated. + case 'ohgo': + // handle_ohgo_request($dbconn, $input_data); + send_error(501, 'The "ohgo" request type is not yet implemented for newstormdata.'); + break; + case 'ohgonopoly': + // handle_ohgo_request_no_poly($dbconn, $input_data); + send_error(501, 'The "ohgonopoly" request type is not yet implemented for newstormdata.'); + break; + case 'wupoly': + // handle_wu_request_poly($dbconn, $input_data); + send_error(501, 'The "wupoly" request type is not yet implemented for newstormdata.'); + break; + case 'campoly': + // handle_cam_request($dbconn, $input_data); + send_error(501, 'The "campoly" request type is not yet implemented for newstormdata.'); + break; + */ + default: + send_error(400, 'Invalid request_type specified: ' . htmlspecialchars($request_type)); + break; + } + + pg_close($dbconn); + +} else { + http_response_code(405); + header('Allow: POST'); + header('Content-Type: application/json; charset=utf-8'); + echo json_encode(['error' => 'Invalid request method. Only POST is allowed.']); + exit; +} +?> + +