Web Interfaces of PROSUME

SSPController.php 9.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. <?php
  2. namespace App\Controller;
  3. use App\Utility\EprosumeModel;
  4. use App\Utility\WalletEprosumeModel;
  5. use Cake\Core\Configure;
  6. use Cake\Http\Exception\ForbiddenException;
  7. use Cake\Http\Exception\NotFoundException;
  8. use Cake\View\Exception\MissingTemplateException;
  9. abstract class SSPController extends AppController
  10. {
  11. protected $EprosumeModel = null;
  12. protected $WalletEprosumeModel = null;
  13. public function initialize()
  14. {
  15. parent::initialize();
  16. $this->EprosumeModel = new EprosumeModel();
  17. $this->WalletEprosumeModel = new WalletEprosumeModel();
  18. }
  19. protected function doSetPrice($prosumer, $buyPrice, $sellPrice)
  20. {
  21. $this->autoRender = false;
  22. if(
  23. !in_array($prosumer, $this->WalletEprosumeModel->getProsumers(1))
  24. ||
  25. !is_numeric($buyPrice)
  26. ||
  27. !is_numeric($sellPrice)
  28. ) {
  29. return $this->response->withStatus(400);
  30. }
  31. $results = $this->WalletEprosumeModel->setPrice($prosumer, $buyPrice, $sellPrice);
  32. if(empty($results)) {
  33. return $this->response->withStatus(502);
  34. } else {
  35. $this->EprosumeModel->setPrice($prosumer, $buyPrice, $sellPrice);
  36. return $this->response = $this->response
  37. ->withStatus(200)
  38. ->withType('application/json')
  39. ;
  40. }
  41. }
  42. protected function doTransfer($from, $prosumer, $amount, $asset, $memo)
  43. {
  44. $this->autoRender = false;
  45. if(
  46. !in_array($from, $this->WalletEprosumeModel->getProsumers(1))
  47. ||
  48. !in_array($prosumer, $this->WalletEprosumeModel->getProsumers(1))
  49. ||
  50. $from == $prosumer
  51. ||
  52. !is_numeric($amount)
  53. ||
  54. !in_array($asset, $this->EprosumeModel->getAssetsType())
  55. ||
  56. !is_string($memo)
  57. ) {
  58. return $this->response->withStatus(400);
  59. }
  60. $results = $this->WalletEprosumeModel->transfer($from, $prosumer, $amount, $asset, $memo);
  61. if(empty($results)) {
  62. return $this->response->withStatus(502);
  63. } else {
  64. return $this->response
  65. ->withStatus(200)
  66. ->withType('application/json')
  67. ;
  68. }
  69. }
  70. public function blocks() {
  71. $qs = $this->request->getAttribute('params')["?"] ?? [];
  72. $asset = $qs["asset"] ?? null;
  73. $date_from = $qs["from"] ?? (new \DateTime())->sub(new \DateInterval("P1D"))->format("Y-m-d H:i:s");
  74. $date_to = $qs["to"] ?? (new \DateTime())->format("Y-m-d H:i:s");
  75. $meter = $qs["meter"] ?? null;
  76. $filters = [
  77. 'date_from' => $date_from,
  78. 'date_to' => $date_to,
  79. 'meter' => $meter,
  80. 'asset' => $asset,
  81. ];
  82. $asset && $filters['asset'] = $asset;
  83. $meter && $filters['meter'] = $meter;
  84. $blocks = $this->EprosumeModel->blocksList(
  85. $filters
  86. );
  87. return $blocks
  88. ? $this->response
  89. ->withStatus(200)
  90. ->withType('application/json')
  91. ->withStringBody(
  92. $this->jsonEncodeGenerator($blocks)
  93. )
  94. : $this->response
  95. ->withStatus(200)
  96. ->withType('application/json')
  97. ->withStringBody(
  98. $this->jsonEncodeGenerator([])
  99. )
  100. ;
  101. }
  102. public function balances() {
  103. $qs = $this->request->getAttribute('params')["?"] ?? [];
  104. $date_from = $qs["from"] ?? (new \DateTime())->sub(new \DateInterval("P1D"))->format("Y-m-d H:i:s");
  105. $date_to = $qs["to"] ?? (new \DateTime())->format("Y-m-d H:i:s");
  106. $meter = $qs["meter"] ?? null;
  107. $balances = $this->EprosumeModel->balanceHistory($date_from, $date_to, $meter);
  108. return $balances
  109. ? $this->response
  110. ->withStatus(200)
  111. ->withType('application/json')
  112. ->withStringBody(
  113. $this->jsonEncodeGenerator($balances)
  114. )
  115. : $this->response
  116. ->withStatus(200)
  117. ->withType('application/json')
  118. ->withStringBody(
  119. $this->jsonEncodeGenerator([])
  120. )
  121. ;
  122. }
  123. public function charts($type, $meter_name) {
  124. $qs = $this->request->getAttribute('params')["?"] ?? $queryString;
  125. $period = $qs['period'] ?? 0;
  126. $from = $qs['from'] ?? null;
  127. $to = $qs['to'] ?? null;
  128. $data = $this->EprosumeModel->charts($type, $meter_name, $from, $to, $period);
  129. return $data
  130. ? $this->response
  131. ->withStatus(200)
  132. ->withType('application/json')
  133. ->withStringBody(
  134. $this->jsonEncodeGenerator($data)
  135. )
  136. : $this->response
  137. ->withStatus(200)
  138. ->withType('application/json')
  139. ->withStringBody(
  140. $this->jsonEncodeGenerator([])
  141. )
  142. ;
  143. }
  144. protected function SSPResponse($dataset, $user_meter_id=null, array $queryString = [])
  145. {
  146. $this->autoRender = false;
  147. $qs = $this->request->getAttribute('params')["?"] ?? $queryString;
  148. $format = $qs["format"] ?? "json";
  149. if(
  150. $format == "csv"
  151. ) {
  152. unset($qs["start"], $qs["length"]);
  153. }
  154. $qs["user_meter_id"] = $user_meter_id;
  155. $results = $this->EprosumeModel->dataTableSSP(
  156. $dataset,
  157. $qs["user_meter_id"],
  158. ($qs["draw"] ?? 1),
  159. ($qs["columns"] ?? [["data"=>"timestamp"]]),
  160. ($qs["order"] ?? [["column"=>0,"dir"=>"desc"]]),
  161. ($qs["start"] ?? null),
  162. ($qs["length"] ?? null),
  163. ($qs["search"] ?? null),
  164. ($qs["meter"] ?? null),
  165. ($qs["txid"] ?? null),
  166. ($qs["from"] ?? null),
  167. ($qs["to"] ?? null),
  168. ($qs["period"] ?? null)
  169. );
  170. if($format == "json") {
  171. $dataString = $this->jsonEncodeGenerator($results["data"]);
  172. if( $this->request->is('ajax') ) {
  173. $draw = $results["draw"];
  174. $recordsFiltered = $results["recordsFiltered"];
  175. $recordsTotal = $results["recordsTotal"];
  176. $body = $this->setDataTableResponse($dataString, $recordsTotal, $recordsFiltered, $draw);
  177. } else {
  178. $body = $dataString;
  179. }
  180. $this->response = $this->response
  181. ->withStatus(200)
  182. ->withType('application/json')
  183. ->withStringBody($body);
  184. return $this->response;
  185. } else if($format == "csv") {
  186. $csvFileHandle = $this->csvTmpFileGenerator($results["data"], $qs["columns"]);
  187. $csvFilePath = stream_get_meta_data($csvFileHandle)['uri'];
  188. $csvContent = file_get_contents($csvFilePath);
  189. return $this->response
  190. ->withType("text/csv")
  191. ->withDownload("eProsume_export_".$dataset."_".date("YmdHis").".csv")
  192. ->withLength(strlen($csvContent))
  193. ->withStringBody($csvContent);
  194. }
  195. return null;
  196. }
  197. protected function getRequestInput() {
  198. return array_map(
  199. function($v) {
  200. return filter_var($v, FILTER_SANITIZE_STRING);
  201. },
  202. json_decode($this->request->input(), true) ?? []
  203. );
  204. }
  205. protected function jsonEncodeGenerator(iterable $generator)
  206. {
  207. $memory_limit = 5 * 1024 * 1024;
  208. $fp = fopen("php://temp", 'r+');
  209. fputs($fp, '[');
  210. foreach ($generator as $key => $value) {
  211. if(is_null($value)) {
  212. continue;
  213. }
  214. if ($key != 0) {
  215. fputs($fp, ',');
  216. }
  217. fputs($fp, json_encode($value));
  218. }
  219. fputs($fp, ']');
  220. rewind($fp);
  221. return stream_get_contents($fp);
  222. }
  223. protected function csvTmpFileGenerator(iterable $generator, array $columns)
  224. {
  225. $memory_limit = 5 * 1024 * 1024;
  226. $fp = tmpfile();
  227. foreach ($columns as $column) {
  228. fputs($fp, (empty($column["name"]) ? $column["data"] : $column["name"]) );
  229. fputs($fp, ";");
  230. }
  231. fputs($fp, PHP_EOL);
  232. foreach ($generator as $key => $row) {
  233. if(is_null($row)) {
  234. continue;
  235. }
  236. if ($key != 0) {
  237. fputs($fp, PHP_EOL);
  238. }
  239. foreach($row as $k=>$value) {
  240. if($k=="id") {
  241. continue;
  242. }
  243. fputs($fp, $value);
  244. fputs($fp, ";");
  245. }
  246. }
  247. return $fp;
  248. }
  249. protected function setDataTableResponse($dataString, $recordsTotal, $recordsFiltered, $draw)
  250. {
  251. $memory_limit = 5 * 1024 * 1024;
  252. $fp = fopen("php://temp", 'r+');
  253. fputs($fp, '{');
  254. fputs($fp, '"draw": '.$draw.',');
  255. fputs($fp, '"recordsTotal": '.$recordsTotal.',');
  256. fputs($fp, '"recordsFiltered": '.$recordsFiltered.',');
  257. fputs($fp, '"data": '.$dataString);
  258. fputs($fp, '}');
  259. rewind($fp);
  260. return stream_get_contents($fp);
  261. }
  262. }