Air-Quality-Web/logic/Actions/ListDevices.php

100 lines
2.7 KiB
PHP
Raw Permalink Normal View History

2019-01-17 15:39:50 +00:00
<?php
namespace AirQuality\Actions;
use \SBRL\TomlConfig;
use \SBRL\ResponseEncoder;
2019-01-17 15:39:50 +00:00
use \AirQuality\Repositories\IDeviceRepository;
use \AirQuality\ApiResponseSender;
class ListDevices implements IAction {
/** @var TomlConfig */
private $settings;
/** @var IDeviceRepository */
private $device_repo;
2019-06-20 23:02:26 +00:00
/** @var \SBRL\PerformanceCounter */
private $perfcounter;
2019-01-17 15:39:50 +00:00
/** @var ApiResponseSender */
private $sender;
public function __construct(
TomlConfig $in_settings,
IDeviceRepository $in_device_repo,
2019-06-20 23:02:26 +00:00
ApiResponseSender $in_sender,
\SBRL\PerformanceCounter $in_perfcounter) {
2019-01-17 15:39:50 +00:00
$this->settings = $in_settings;
$this->device_repo = $in_device_repo;
$this->sender = $in_sender;
2019-06-20 23:02:26 +00:00
$this->perfcounter = $in_perfcounter;
2019-01-17 15:39:50 +00:00
}
public function handle() : bool {
global $start_time;
// 1: Parse & validate parameters
$only_with_location = !empty($_GET["only-with-location"]);
2019-01-17 15:39:50 +00:00
$format = $_GET["format"] ?? "json";
if(!in_array($format, ["json", "csv"])) {
$this->sender->send_error_plain(406,
"Error: The format '$format' isn't recognised. Valid formats: " . implode(", ", $format) . "."
);
exit;
}
// 2: Pull data from database
2019-06-20 23:02:26 +00:00
$this->perfcounter->start("sql");
2019-01-17 15:39:50 +00:00
$data = $this->device_repo->get_all_devices($only_with_location);
2019-06-20 23:02:26 +00:00
$this->perfcounter->end("sql");
2019-01-17 15:39:50 +00:00
// 2.5: Validate data from database
2019-01-17 15:39:50 +00:00
if(empty($data)) {
$this->sender->send_error_plain(404,
"Error: No devices are currently present in the system.",
2019-06-20 23:02:26 +00:00
[ "x-time-taken: ", $this->perfcounter->render() ]
);
2019-01-17 15:39:50 +00:00
return false;
}
2019-01-17 15:39:50 +00:00
// 3: Serialise data
2019-06-20 23:02:26 +00:00
$this->perfcounter->start("encode");
$response = null;
$response_type = "application/octet-stream";
$response_suggested_filename = "data-" . date(\DateTime::ATOM) . "";
switch($format) {
case "json":
$response_type = "application/json";
$response_suggested_filename .= ".json";
$response = json_encode($data);
break;
case "csv":
$response_type = "text/csv";
$response_suggested_filename .= ".csv";
$response = ResponseEncoder::encode_csv($data);
break;
}
2019-06-20 23:02:26 +00:00
$this->perfcounter->end("encode");
2019-01-17 15:39:50 +00:00
// 4: Send response
// Don't cache for ages, because new devices might get added at any time
// FUTURE: Move last-seen to a different API call if caching becomes critically important?
if($this->settings->get("env.mode") == "production") {
header("cache-control: public, max-age=" . $this->settings->get("cache.max-age-supershort"));
}
2019-01-17 15:39:50 +00:00
header("content-length: " . strlen($response));
header("content-type: $response_type");
header("content-disposition: inline; filename=$response_suggested_filename");
2019-06-20 23:02:26 +00:00
header("x-time-taken: " . $this->perfcounter->render());
2019-01-17 15:39:50 +00:00
echo($response);
return true;
}
}