SensorDataController.php in farmOS 2.x
File
modules/asset/sensor/src/Controller/SensorDataController.php
View source
<?php
namespace Drupal\farm_sensor\Controller;
use Drupal\asset\Entity\AssetInterface;
use Drupal\Component\Serialization\Json;
use Drupal\Core\Controller\ControllerBase;
use Drupal\data_stream\DataStreamTypeManager;
use Drupal\jsonapi\Exception\UnprocessableHttpEntityException;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class SensorDataController extends ControllerBase {
protected $basicDataStream;
public function __construct(DataStreamTypeManager $data_stream_type_manager) {
$this->basicDataStream = $data_stream_type_manager
->createInstance('basic');
}
public static function create(ContainerInterface $container) {
return new static($container
->get('plugin.manager.data_stream_type'));
}
public function uuid(Request $request, string $uuid) {
$sensor_assets = $this
->entityTypeManager()
->getStorage('asset')
->loadByProperties([
'type' => 'sensor',
'uuid' => $uuid,
]);
if (empty($sensor_assets)) {
throw new NotFoundHttpException();
}
$asset = reset($sensor_assets);
return $this
->handleAssetRequest($asset, $request);
}
protected function handleAssetRequest(AssetInterface $asset, Request $request) {
$data_streams = $asset
->get('data_stream')
->referencedEntities();
$basic_data_streams = array_filter($data_streams, function ($data_stream) {
return $data_stream
->bundle() === 'basic';
});
$method = $request
->getMethod();
switch ($method) {
case Request::METHOD_GET:
if (!$asset
->get('public')->value && !$this
->requestHasValidPrivateKey($asset, $request)) {
throw new AccessDeniedHttpException();
}
$params = $request->query
->all();
$max_limit = 100000;
$limit = $max_limit;
if (isset($params['limit'])) {
$limit = $params['limit'];
if ($limit > $max_limit) {
throw new UnprocessableHttpEntityException();
}
}
$params['limit'] = $limit;
$data = $this->basicDataStream
->storageGetMultiple($basic_data_streams, $params);
return JsonResponse::create($data);
case Request::METHOD_POST:
if (!$this
->requestHasValidPrivateKey($asset, $request)) {
throw new AccessDeniedHttpException();
}
$data = Json::decode($request
->getContent());
$unique_names = $this
->getUniqueNamedValues($data);
$existing_names = array_map(function ($data_stream) {
return $data_stream
->label();
}, $basic_data_streams);
foreach ($unique_names as $name) {
if (!in_array($name, $existing_names)) {
$basic_data_streams[] = $this
->createDataStream($asset, $name);
}
}
foreach ($basic_data_streams as $data_stream) {
$this->basicDataStream
->storageSave($data_stream, $data);
}
return Response::create('', Response::HTTP_CREATED);
}
throw new MethodNotAllowedHttpException($this->basicDataStream
->apiAllowedMethods());
}
protected function requestHasValidPrivateKey(AssetInterface $asset, Request $request) {
$private_key = $asset
->get('private_key')->value;
return $private_key == $request
->get('private_key', '');
}
protected function getUniqueNamedValues(array $data) : array {
$names = [];
if (is_array(reset($data))) {
foreach ($data as $point) {
$names = array_unique(array_merge($names, $this
->getUniqueNamedValues($point)));
}
return $names;
}
foreach ($data as $key => $value) {
if ($key !== 'timestamp') {
$names[] = $key;
}
}
return array_unique($names);
}
protected function createDataStream(AssetInterface $asset, string $name) {
$new_data_stream = $this
->entityTypeManager()
->getStorage('data_stream')
->create([
'type' => 'basic',
'name' => $name,
]);
$new_data_stream
->save();
$data_stream_field = $asset
->get('data_stream');
$data_stream_field
->appendItem($new_data_stream);
$asset
->save();
return $new_data_stream;
}
}