Lines 77.61% 104 / 134
Methods 73.33% 11 / 15
Classes 0.00% 0 / 1
Name Lines Methods CRAP
 readResponse 97.14% 34 / 35 0.00% 0 / 1 3
 handleDownloadRequest 87.50% 7 / 8 0.00% 0 / 1 2.01
 renderHtmlResponse 100.00% 19 / 19 100.00% 1 / 1 2
 [BO\Zmsstatistic\BaseController] __invoke 100.00% 5 / 5 100.00% 1 / 1 2
 [BO\Zmsstatistic\Helper\Access] initAccessRights 100.00% 6 / 6 100.00% 1 / 1 4
 [BO\Zmsstatistic\Helper\Access] readWorkstation 100.00% 2 / 2 100.00% 1 / 1 1
 [BO\Zmsstatistic\Helper\Access] readDepartment 100.00% 5 / 5 100.00% 1 / 1 2
 [BO\Zmsstatistic\Helper\Access] readOrganisation 100.00% 5 / 5 100.00% 1 / 1 2
 [BO\Zmsstatistic\Helper\Access] readOwner 100.00% 5 / 5 100.00% 1 / 1 2
 [BO\Zmsstatistic\Helper\Access] validateAccessRights 100.00% 3 / 3 100.00% 1 / 1 1
 [BO\Zmsstatistic\Helper\Access] validateAccess 100.00% 4 / 4 100.00% 1 / 1 7
 [BO\Zmsstatistic\Helper\Access] validateScope 66.66% 2 / 3 0.00% 0 / 1 4.59
 [BO\Zmsstatistic\Helper\Access] isPathWithoutScope 100.00% 5 / 5 100.00% 1 / 1 4
 [BO\Zmsstatistic\Helper\Access] testLogin 0.00% 0 / 27 0.00% 0 / 1 42
 [BO\Zmsstatistic\Helper\Access] exceptionTemplateExists 100.00% 2 / 2 100.00% 1 / 1 1
16class ReportRequestIndex extends BaseController
17{
18    protected int $resolveLevel = 2;
19
20    /**
21     * @SuppressWarnings(Param)
22     * @return ResponseInterface
23     */
24    #[\Override]
25    public function readResponse(
26        RequestInterface $request,
27        ResponseInterface $response,
28        array $args
29    ): mixed {
30        /** @var \Psr\Http\Message\ServerRequestInterface $request */
31        $validator = $request->getAttribute('validator');
32        $reportRequestService = new ReportRequestService();
33        $reportHelper = new ReportHelper();
34
35        $selectedScopes = $reportHelper->extractSelectedScopes(
36            $validator->getParameter('scopes')->isArray()->getValue() ?? []
37        );
38
39        $workstationScopeId = $reportHelper->getWorkstationScopeId($this->workstation);
40        $scopeIds = $reportHelper->resolveScopeIdParam($selectedScopes, $workstationScopeId);
41
42        $requestPeriod = $workstationScopeId !== null
43            ? $reportRequestService->getRequestPeriod((string) $workstationScopeId)
44            : null;
45
46        $dateRange = $reportHelper->extractDateRange(
47            $validator->getParameter('from')->isString()->getValue(),
48            $validator->getParameter('to')->isString()->getValue()
49        );
50
51        $exchangeRequest = $reportRequestService->getExchangeRequestData($scopeIds, $dateRange, $args);
52
53        $type = $validator->getParameter('type')->isString()->getValue();
54        if ($type) {
55            return $this->handleDownloadRequest(
56                $request,
57                $response,
58                $args,
59                $exchangeRequest,
60                $dateRange,
61                $selectedScopes,
62                $reportRequestService
63            );
64        }
65
66        return $this->renderHtmlResponse(
67            $response,
68            $args,
69            $requestPeriod,
70            $dateRange,
71            $exchangeRequest,
72            $selectedScopes
73        );
74    }
75
76    /**
77     * Handle download request and return Excel file
78     */
79    private function handleDownloadRequest(
80        RequestInterface $request,
81        ResponseInterface $response,
82        array $args,
83        mixed $exchangeRequest,
84        array|null $dateRange,
85        array $selectedScopes = [],
86        ReportRequestService|null $reportRequestService = null
87    ): ResponseInterface {
88        if ($reportRequestService === null) {
89            $reportRequestService = new ReportRequestService();
90        }
91
92        $args = $reportRequestService->prepareDownloadArgs($args, $exchangeRequest, $dateRange, $selectedScopes);
93
94        $args['scope'] = $this->workstation->getScope();
95        $args['department'] = $this->department;
96        $args['organisation'] = $this->organisation;
97
98        /** @var mixed $container */
99        $container = \App::$slim->getContainer();
100        return (new Download\RequestReport($container))->readResponse($request, $response, $args);
101    }
102
103    /**
104     * Render HTML response for the report page
105     */
106    private function renderHtmlResponse(
107        ResponseInterface $response,
108        array $args,
109        mixed $requestPeriod,
110        array|null $dateRange,
111        mixed $exchangeRequest,
112        array $selectedScopes = []
113    ): ResponseInterface {
114        return Render::withHtml(
115            $response,
116            'page/reportRequestIndex.twig',
117            array(
118                'title' => 'Dienstleistungsstatistik Standort',
119                'activeScope' => 'active',
120                'menuActive' => 'request',
121                'department' => $this->department,
122                'organisation' => $this->organisation,
123                'requestPeriod' => $requestPeriod,
124                'showAll' => 1,
125                'period' => isset($args['period']) ? $args['period'] : null,
126                'dateRange' => $dateRange,
127                'exchangeRequest' => $exchangeRequest,
128                'source' => ['entity' => 'RequestIndex'],
129                'selectedScopeIds' => $selectedScopes,
130                'workstation' => $this->workstation->getArrayCopy()
131            )
132        );
133    }
134}

Inherited from BO\Zmsstatistic\BaseController

20    public function __invoke(RequestInterface $request, ResponseInterface $response, array $args)
21    {
22        $request = $this->initRequest($request);
23        if ($this->withAccess) {
24            $this->initAccessRights($request);
25        }
26        $noCacheResponse = \BO\Slim\Render::withLastModified($response, time(), '0');
27        return $this->readResponse($request, $noCacheResponse, $args);
28    }

Inherited from BO\Zmsstatistic\Helper\Access

33    protected function initAccessRights(RequestInterface $request): void
34    {
35        $this->workstation = $this->readWorkstation();
36        if ($this->workstation && isset($this->workstation->scope['id']) && $this->workstation->scope['id'] > 0) {
37            $this->department = $this->readDepartment();
38            $this->organisation = $this->readOrganisation();
39            $this->owner = $this->readOwner();
40        }
41        $this->validateAccessRights($request);
42    }
44    protected function readWorkstation(): mixed
45    {
46        $workstation = \App::http()->readGetResult('/workstation/', ['resolveReferences' => $this->resolveLevel]);
47        return $workstation->getEntity();
48    }
50    protected function readDepartment(): mixed
51    {
52        if ($this->workstation->getUseraccount()->hasPermissions(['statistic'])) {
53            return \App::http()
54                ->readGetResult('/scope/' . $this->workstation->scope['id'] . '/department/')
55                ->getEntity();
56        }
57        return null;
58    }
60    protected function readOrganisation(): mixed
61    {
62        if ($this->workstation->getUseraccount()->isSuperUser()) {
63            return \App::http()
64                ->readGetResult('/department/' . $this->department->getId() . '/organisation/')
65                ->getEntity();
66        }
67        return null;
68    }
70    protected function readOwner(): mixed
71    {
72        if ($this->workstation->getUseraccount()->isSuperUser()) {
73            return \App::http()
74                ->readGetResult('/organisation/' . $this->organisation->getId() . '/owner/')
75                ->getEntity();
76        }
77        return null;
78    }
80    protected function validateAccessRights(RequestInterface $request): void
81    {
82        $path = $request->getUri()->getPath();
83        $this->validateAccess($path);
84        $this->validateScope($path);
85    }
87    protected function validateAccess(string $path): void
88    {
89        if (
90            (false !== strpos($path, 'owner') && ! $this->owner) ||
91            (false !== strpos($path, 'organisation') && ! $this->organisation) ||
92            (false !== strpos($path, 'department') && ! $this->department)
93        ) {
94            throw new UserAccountAccessRightsFailed();
95        }
96    }
98    protected function validateScope(string $path): void
99    {
100        if (
101            $this->isPathWithoutScope($path)
102            && (! isset($this->workstation['scope']) || ! isset($this->workstation['scope']['id']))
103        ) {
104            throw new WorkstationMissingScope();
105        }
106    }
108    protected function isPathWithoutScope(string $path): bool
109    {
110        // TODO: refactor to integrate these access rules in the controller to make them visible
111        return (false === strpos($path, 'select')
112            && false === strpos($path, 'warehouse')
113            && false === strpos($path, 'logout')
114            && false === strpos($path, 'report')
115        );
116    }
121    protected function testLogin(mixed $input): mixed
122    {
123        $userAccount = new Useraccount(array(
124            'id' => $input['loginName'],
125            'password' => $input['password'],
126            'departments' => array('id' => 0) // required in schema validation
127        ));
128        try {
129            /** @var Workstation $workstation */
130            $workstation = \App::http()->readPostResult('/workstation/login/', $userAccount)->getEntity();
131            return $workstation;
132        } catch (\BO\Zmsclient\Exception $exception) {
133            $template = TwigExceptionHandler::getExceptionTemplate($exception);
134            if ('BO\Zmsentities\Exception\SchemaValidation' == $exception->template) {
135                $exceptionData = [
136                  'template' => 'exception/bo/zmsbackend/useraccount/exception/invalidcredentials.twig'
137                ];
138                $exceptionData['data']['password']['messages'] = [
139                    'Der Nutzername oder das Passwort wurden falsch eingegeben'
140                ];
141            } elseif ('BO\Zmsbackend\Useraccount\Exception\UserAlreadyLoggedIn' == $exception->template) {
142                Auth::setKey($exception->data['authkey'], time() + \App::SESSION_DURATION);
143                throw $exception;
144            } elseif (
145                '' != $exception->template
146                && $this->exceptionTemplateExists($template)
147            ) {
148                $exceptionData = [
149                  'template' => $template,
150                  'data' => $exception->data
151                ];
152            } else {
153                throw $exception;
154            }
155        }
156        return $exceptionData;
157    }
159    protected function exceptionTemplateExists(string $template): bool
160    {
161        /** @var mixed $container */
162        $container = \App::$slim->getContainer();
163        return $container->get('view')->getLoader()->exists($template);
164    }