sanitizer = $sanitizer; $this->logger = $logger; } /** * Sort the QUERY parts of the requested URL. * This is in place because these are stored as part of the URL in the database and used for forwarding to another page. * This is done because sometimes different query parts result in a completely different page. Therefore we have to * take into account the query part of the URL (?query=part) when looking for a page to redirect to. * * Here we sort the query parts so that the same request will always look the same. * * @param array $urlParts * @return string */ public function sortQueryString(array $urlParts): string { if (!array_key_exists('query', $urlParts) || $urlParts['query'] == '') { return ''; } $queryParts = array(); parse_str($urlParts['query'], $queryParts); ksort($queryParts); $sanitized = $this->sanitizer->sanitizeUrlComponent($queryParts); $queryParts = is_array($sanitized) ? $sanitized : $queryParts; $built = http_build_query($queryParts, '', '&', PHP_QUERY_RFC3986); $decoded = rawurldecode($built); return $this->sanitizer->normalizeUrlString($decoded, array('decode' => false)); } /** * We have to remove any 'p=##' because it will cause a 404 otherwise. * * @param string $queryString * @return string */ public function removePageIDFromQueryString($queryString) { $queryParts = array(); parse_str($queryString, $queryParts); if (array_key_exists('p', $queryParts)) { unset($queryParts['p']); } $sanitized = $this->sanitizer->sanitizeUrlComponent($queryParts); $queryParts = is_array($sanitized) ? $sanitized : $queryParts; $built = http_build_query($queryParts, '', '&', PHP_QUERY_RFC3986); $decoded = rawurldecode($built); return $this->sanitizer->normalizeUrlString($decoded, array('decode' => false)); } /** * First urldecode then json_decode the data, then return it. * All of this encoding and decoding is so that [] characters are supported. * * @param string $data * @return mixed */ public function decodeComplicatedData($data) { $dataDecoded = urldecode((string)$data); // JSON.stringify escapes single quotes and json_decode does not want them to be escaped. $dataStripped = str_replace("\'", "'", $dataDecoded); $fixedData = json_decode($dataStripped, true); $jsonErrorNumber = json_last_error(); if ($jsonErrorNumber != 0) { $errorMsg = json_last_error_msg(); $lastMessagePart = ", Decoded: " . $dataDecoded; if ($dataStripped != null && mb_strlen($dataStripped) > 1) { $lastMessagePart = ", Stripped: " . $dataStripped; } $logger = $this->resolveLogger(); if ($logger !== null) { $logger->errorMessage("Error " . $jsonErrorNumber . " parsing JSON in " . __CLASS__ . "->" . __FUNCTION__ . "(). Error message: " . $errorMsg . $lastMessagePart); } } return $fixedData; } /** @return ABJ_404_Solution_Logging|null */ private function resolveLogger() { if ($this->logger !== null) { return $this->logger; } if (function_exists('abj_service_optional')) { $resolved = abj_service_optional('logging'); if ($resolved instanceof ABJ_404_Solution_Logging) { return $resolved; } } return null; } }