/** * Serialize array to JSON string. * * @param array $args * @return string * @throws GraphCommons\Util\JsonException */ public function serialize(...$args) : string { $json = new Json($this->unserialize()); if ($json->hasError()) { $jsonError = $json->getError(); throw new JsonException(sprintf('JSON error: code(%d) message(%s)', $jsonError['code'], $jsonError['message']), $jsonError['code']); } return (string) $json->encode($args); }
/** * Set body. * * @param mixed $body * @return self */ public final function setBody($body) : self { switch ($this->contentType) { // handle xml @todo case ContentType::XML: break; // handle json // handle json case ContentType::JSON: $json = new Json($body); // simply check for pretty print $app = app(); if (is_in($app->request->params->get['pp'], ['1', 'true'])) { $body = $json->encode(JSON_PRETTY_PRINT); } else { $body = $json->encode(); } if ($json->hasError()) { throw new JsonException($json->getErrorMessage(), $json->getErrorCode()); } break; // handle html // handle html case ContentType::HTML: // check for page title if ($pageTitle = get_global('page.title')) { $body = preg_replace('~<title>(.*?)</title>~s', '<title>' . html_encode($pageTitle) . '</title>', $body, 1); } // check page description if ($pageDescription = get_global('page.description')) { $body = preg_replace('~<meta\\s+name="description"\\s+content="(.*?)">~', '<meta\\s+name="description"\\s+content="' . html_encode($pageDescription) . '">', $body, 1); } break; } // can gzip? if (!empty($this->gzipOptions)) { $this->gzip->setData($body); if ($this->gzip->isDataMinlenOK()) { $body = $this->gzip->encode(); $this->setHeader('Vary', 'Accept-Encoding'); $this->setHeader('Content-Encoding', 'gzip'); } } // content length $this->setContentLength(strlen($body)); $this->body = $body; return $this; }
/** * Create a signal collection from JSON string. * * @param string $json * @return GraphCommons\Graph\SignalCollection * @throws GraphCommons\Util\JsonException, \InvalidArgumentException */ public static final function fromJson(string $json) : SignalCollection { $json = new Json($json); if ($json->hasError()) { $jsonError = $json->getError(); throw new JsonException(sprintf('JSON error: code(%d) message(%s)', $jsonError['code'], $jsonError['message']), $jsonError['code']); } $data = $json->decode(true); if (!isset($data['signals'])) { throw new \InvalidArgumentException("'signals' field is required!"); } $array = array(); foreach ($data['signals'] as $i => $signal) { if (!isset($signal['action'])) { throw new \InvalidArgumentException("Signal 'action' and 'parameters' fields are required!"); } $array[$i]['action'] = Signal::detectAction(Util::arrayPick($signal, 'action')); foreach ($signal as $key => $value) { $array[$i]['parameters'][$key] = $value; } } return self::fromArray($array); }
/** * Serialize request body as JSON. * * @param GraphCommons\Graph\Graph|array $body * @return string * @throws GraphCommons\Util\JsonException */ private final function serializeBody($body) : string { // check body if lib's object if (is_object($body) && method_exists($body, 'serialize')) { return $body->serialize(); } $json = new Json($body); if ($json->hasError()) { $jsonError = $json->getError(); throw new JsonException(sprintf('JSON error: code(%d) message(%s)', $jsonError['code'], $jsonError['message']), $jsonError['code']); } return (string) $json->encode(); }
/** * Set body. * @param any $body * @return self */ public final function setBody($body) : self { switch ($this->body->content->getType()) { case BodyContent::TYPE_XML: // @todo break; case BodyContent::TYPE_JSON: $json = new Json($body); $body = $json->encode(); if ($json->hasError()) { throw new JsonException($json->getErrorMessage(), $json->getErrorCode()); } break; } // gzip if (!empty($this->gzipOptions)) { $this->gzip->setData($body); if ($this->gzip->checkDataMinlen()) { $body = $this->gzip->encode(); $this->setHeader('Vary', 'Accept-Encoding'); $this->setHeader('Content-Encoding', 'gzip'); } } $this->body->content->setData($body); $this->body->content->setLength(strlen($body)); return $this; }
/** * Perform a request. * * @param string $uri * @param array $uriParams * @param string $body * @param array $headers * @return GraphCommons\Http\Response * @throws \InvalidArgumentException, * GraphCommons\Http\Exception\Request, GraphCommons\Util\JsonException */ public final function request(string $uri, array $uriParams = null, string $body = '', array $headers = null) : Response { // match for a valid request i.e: GET /foo preg_match('~^([a-z]+)\\s+(/.*)~i', $uri, $match); if (!isset($match[1], $match[2])) { throw new \InvalidArgumentException('Usage: <REQUEST METHOD> <REQUEST URI>'); } $uri = sprintf('%s/%s/%s', $this->graphCommons->apiUrl, $this->graphCommons->apiVersion, trim($match[2])); $uri = preg_replace('~(^|[^:])//+~', '\\1/', trim($uri, '/')); $this->request->setMethod($match[1])->setUri($uri, (array) $uriParams); if (!empty($headers)) { foreach ($headers as $key => $value) { $this->request->setHeader(trim($key), $value); } } $requestMethod = $this->request->getMethod(); if ($requestMethod == Request::METHOD_POST || $requestMethod == Request::METHOD_PUT) { // set body stuff $body = trim($body); $bodyLength = strlen($body); $this->request->setBody($body); $this->request->setBodyLength($bodyLength); // set content headers stuff $this->request->setHeader('Content-Type', 'application/json'); $this->request->setHeader('Content-Length', (string) $bodyLength); } $result = $this->request->send(); if ($result === null) { $fail = $this->request->getFail(); throw new RequestException(sprintf('HTTP error: code(%d) message(%s)', $fail['code'], $fail['message']), $fail['code']); } unset($headers, $body); // split headers/body pairs @(list($headers, $body) = explode("\r\n\r\n", $result, 2)); if (!isset($headers)) { throw new ResponseException('No headers received from server!'); } if (!isset($body)) { throw new ResponseException('No body received from server!'); } // parse response headers $headers = Util::parseResponseHeaders($headers); if (isset($headers['status'])) { $this->response->setStatus($headers['status']); $this->response->setStatusCode($headers['status_code']); $this->response->setStatusText($headers['status_text']); } $this->response->setHeaders($headers); $this->response->setBody($body); $json = new Json($body); // render response body $bodyData = $json->decode(true); if ($json->hasError()) { $jsonError = $json->getError(); throw new JsonException(sprintf('JSON error: code(%d) message(%s)', $jsonError['code'], $jsonError['message']), $jsonError['code']); } $this->response->setBodyData($bodyData); return $this->response; }