userId = $userId; $this->userProjects = $userProjects; $this->userIsAdmin = $userIsAdmin; } /** * @param ReportData $report * @param array $parameterValues * * @return string compiled sql query */ public function resolveParameters(ReportData $report, $parameterValues = []) { $compiledQuery = $this->resolveEnvironmentVariables($report); $resolvedReport = $this->resolveInputParameters($report, $parameterValues); $parameters = $resolvedReport->getParameters(); if ($parameters !== null) { foreach ($parameters as $param) { $value = $param->getValue(); $pattern = sprintf('/\{%s\}/', mb_strtoupper($param->getVarname())); $compiledQuery = preg_replace($pattern, $value, $compiledQuery); } } preg_match_all('/{([^{}]+)}/', $compiledQuery, $matches); if (!empty($matches[1])) { throw new UnresolvedParameterException(sprintf('unresolved Variable "%s"', $matches[1][0])); } return $compiledQuery; } /** * @param ReportData $report * @param array $parameterValues * * @return ReportData */ public function resolveInputParameters(ReportData $report, $parameterValues = []) { $params = $report->getParameters(); if ($params === null || count($params) < 1) { return $report; } $resolvedParams = []; foreach ($params as $param) { $varname = strtolower($param->getVarname()); foreach ($parameterValues as $varkey => $varvalue) { if ($varname === strtolower($varkey)) { $resolvedValue = $this->resolveParameterValue($param, $varvalue); $param->setTemporaryValue($resolvedValue); } } $resolvedParams[] = $param; } $report->setParameters(new ReportParameterCollection($resolvedParams)); return $report; } /** * @param ReportData $report * * @return string */ public function resolveEnvironmentVariables(ReportData $report) { $variables = $this->getEnvironMentVariables($report); $compiledQuery = $report->getSqlQuery(); foreach ($variables as $key => $value) { $pattern = sprintf('/\{%s\}/', $key); $compiledQuery = preg_replace($pattern, $value, $compiledQuery); } return $compiledQuery; } /** * @param ReportData $report * * @return array */ public function getEnvironmentVariables(ReportData $report) { $variables = []; if ($this->userId > 0) { $variables['USER_ID'] = $this->userId; $variables['USER_PROJECTS'] = sprintf('(%s)', implode(', ', $this->userProjects)); $variables['USER_ADMIN'] = 0; if ($this->userIsAdmin === true) { $variables['USER_ADMIN'] = 1; } } $variables['REPORT_PROJECT'] = $report->getProjectId(); return $variables; } /** * @param $sql * * @return string[] */ public function findInvalidVariableNames($sqlStatement) { if ( !preg_match_all('/{([^{}]+)}/', $sqlStatement, $matches) || count($matches) < 2 ) { return []; } $errors = []; foreach ($matches[1] as $varname) { if(!preg_match('/^[A-Z_0-9]+$/', $varname)) { $errors[] = $varname; } } return $errors; } /** * @param ReportParameter $parameter * @param mixed $value * * @throws UnresolvedParameterException * * @return mixed */ private function resolveParameterValue(ReportParameter $parameter, $value) { $control_type = $parameter->getControlType(); if ($value === null) { return null; } switch ($control_type) { case self::CONTROL_TYPE_PROJECT: return $this->resolveProject($value); break; case self::CONTROL_TYPE_GROUP: return $this->resolveGroup($value); break; case self::CONTROL_TYPE_ADDRESS: return $this->resolveAddress($value); break; case self::CONTROL_TYPE_ARTICLE: return $this->resolveArticle($value); break; } return $value; } /** * @param string $input * * @return string */ private function resolveProject($input) { $split = explode(' ', $input); if (count($split) < 1) { throw new UnresolvedParameterException('project parameter format incorrect'); } return $split[0]; } /** * @param string $input * * @return string */ private function resolveGroup($input) { $split = explode(' ', $input); if (count($split) < 2) { throw new UnresolvedParameterException('group parameter format incorrect'); } return $split[count($split)-1]; } /** * @param string $input * * @return string */ private function resolveAddress($input) { $split = explode(' ', $input); if (count($split) < 1) { throw new UnresolvedParameterException('address parameter format incorrect'); } return $split[0]; } /** * @param string $input * * @return string */ private function resolveArticle($input) { $split = explode(' ', $input); if (count($split) < 2) { throw new UnresolvedParameterException('article parameter format incorrect'); } return $split[0]; } }