checkAccess(); $data = $this->fetchData($request); $report = $this->previewReportProvider->get($data); if (!in_array($report->getType(), [Report::TYPE_GRID, Report::TYPE_JOINT_GRID])) { throw new BadRequest("Bad report type."); } $where = $request->getParsedBody()->where ?? null; $whereItem = null; if ($where) { $whereItem = WhereItem::fromRawAndGroup(self::normalizeWhere($where)); } // Passing the user is important. $result = $this->service->reportRunGridOrJoint($report, $whereItem, $this->user); return ResponseComposer::json($result->toRaw()); } /** * @throws BadRequest */ private function fetchData(Request $request): stdClass { $data = $request->getParsedBody()->data ?? null; if (!$data instanceof stdClass) { throw new BadRequest("No data."); } return $data; } /** * @throws BadRequest */ private static function normalizeWhere(mixed $where): mixed { try { return Json::decode(Json::encode($where), true); } catch (JsonException) { throw new BadRequest("Bad where"); } } /** * @throws Forbidden */ private function checkAccess(): void { if (!$this->acl->checkScope(Report::ENTITY_TYPE, AclTable::ACTION_CREATE)) { throw new Forbidden("No 'create' access."); } if ($this->user->isPortal()) { throw new Forbidden("No access from portal."); } } }