/** * The constructor for the main class. * * @param String $host The ePages host to connect. * @param String $shop The refered ePages shop. * @param String $authToken The authentificaton token to connect via REST. * @param boolean $isssl True, if you use SSL, false if not. Default value is true. */ public static function connect($host, $shop, $authToken, $isssl) { if (!InputValidator::isHost($host) || !InputValidator::isShop($shop) || !InputValidator::isAuthToken($authToken)) { self::$ISCONNECTED = false; return; } self::$HOST = $host; self::$SHOP = $shop; self::$ISSSL = $isssl; self::$AUTHTOKEN = $authToken; self::$ISCONNECTED = true; }
/** * This send function sends a special command to the REST server with additional parameter. * * @author David Pauli <*****@*****.**> * @param String command The path which is requested in the REST client. * @param String[] $postParameter Add specific parameters to the REST server. * @since 0.0.0 * @since 0.0.1 Use HTTPRequestMethod enum. * @since 0.1.0 Allow empty message body if the status code is 204. * @since 0.1.2 Restructure the logging message and fix the PATCH call. * @since 0.1.2 Add error reporting. * @since 0.1.3 Remove isRESTCommand function. * @since 0.2.1 Refactor the complete send method. */ public static function send($command = "", $postParameter = array()) { self::errorReset(); if (!InputValidator::isArray($postParameter)) { Logger::warning("ep6\\RESTClient\\Post parameter (" . $postParameter . ") are not valid."); self::errorSet("RESTC-5"); return null; } if (!self::$ISCONNECTED) { Logger::warning("ep6\\RESTClient\nClient is not connected."); self::errorSet("RESTC-6"); return null; } $protocol = self::$ISSSL ? "https" : "http"; $url = $protocol . "://" . self::$HOST . "/" . self::PATHTOREST . "/" . self::$SHOP . "/" . $command; $headers = array("Accept: " . self::HTTP_ACCEPT, "Content-Type: " . self::HTTP_CONTENT_TYPE_JSON, "User-Agent: " . self::USER_AGENT); // add authentification if there is a token if (InputValidator::isAuthToken(self::$AUTHTOKEN)) { array_push($headers, "Authorization: Bearer " . self::$AUTHTOKEN); } # parse cookies if (!InputValidator::isEmptyArray(self::$COOKIES)) { $cookiesValues = array(); foreach (self::$COOKIES as $key => $value) { array_push($cookiesValues, $key . "=" . $value); } array_push($headers, "Cookie: " . implode("; ", $cookiesValues)); } $curl = curl_init($url); curl_setopt($curl, CURLOPT_FAILONERROR, 1); // show full errors curl_setopt($curl, CURLOPT_FORBID_REUSE, 0); // connection can be opened curl_setopt($curl, CURLOPT_FRESH_CONNECT, 0); // no new connection required curl_setopt($curl, CURLOPT_NOBODY, 0); // show body curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // get response as string curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 0); // no connection timeout curl_setopt($curl, CURLOPT_CONNECTTIMEOUT_MS, 0); // no connection timeout curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_NONE); // cURL will choose the http version curl_setopt($curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_WHATEVER); // understand ipv4 and ipv6 curl_setopt($curl, CURLINFO_HEADER_OUT, 1); // save the header in the log curl_setopt($curl, CURLOPT_HEADER, 1); // get the header if (self::$ISSSL) { curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); // don't check the peer ssl cerrificate curl_setopt($curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTPS); curl_setopt($curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTPS); curl_setopt($curl, CURLOPT_SSLVERSION, 0); // default ssl version } else { curl_setopt($curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTP); curl_setopt($curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP); } switch (self::$HTTP_REQUEST_METHOD) { case HTTPRequestMethod::GET: curl_setopt($curl, CURLOPT_HTTPGET, 1); break; case HTTPRequestMethod::POST: $JSONpostfield = JSONHandler::createJSON($postParameter); curl_setopt($curl, CURLOPT_POST, 1); curl_setopt($curl, CURLOPT_POSTREDIR, 0); // don't post on redirects curl_setopt($curl, CURLOPT_POSTFIELDS, $JSONpostfield); break; case HTTPRequestMethod::PUT: $JSONpostfield = JSONHandler::createJSON($postParameter); array_push($headers, "Content-Length: " . strlen($JSONpostfield)); curl_setopt($curl, CURLOPT_POSTFIELDS, $JSONpostfield); curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT'); break; case HTTPRequestMethod::DELETE: $JSONpostfield = JSONHandler::createJSON($postParameter); curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "DELETE"); curl_setopt($curl, CURLOPT_POSTFIELDS, $JSONpostfield); break; case HTTPRequestMethod::PATCH: $JSONpostfield = "[" . JSONHandler::createJSON($postParameter) . "]"; curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PATCH"); curl_setopt($curl, CURLOPT_POSTFIELDS, $JSONpostfield); break; } curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); $response = curl_exec($curl); $info = curl_getinfo($curl); $error = curl_error($curl); curl_close($curl); # get header and body list($header, $body) = self::explodeResponse($response); $header = trim($header); $content = trim($body); $logMessage = "Request:\n" . "Parameters: " . http_build_query($postParameter) . "\n" . $info["request_header"] . "Response:\n" . "Size (Header/Request): " . $info["header_size"] . "/" . $info["request_size"] . " Bytes\n" . "Time (Total/Namelookup/Connect/Pretransfer/Starttransfer/Redirect): " . $info["total_time"] . " / " . $info["namelookup_time"] . " / " . $info["connect_time"] . " / " . $info["pretransfer_time"] . " / " . $info["starttransfer_time"] . " / " . $info["redirect_time"] . " seconds\n" . $response . "\n"; Logger::notify("ep6\\RESTClient:\n" . $logMessage); # parse header, response code and body self::explodeHeader($header); self::$HTTP_RESPONSE_CODE = (int) $info["http_code"]; if (!InputValidator::isEmpty($content)) { self::$CONTENT = $content; } }
/** * This send function sends a special command to the REST server with additional parameter. * * @author David Pauli <*****@*****.**> * @since 0.0.0 * @since 0.0.1 Use HTTPRequestMethod enum. * @since 0.1.0 Allow empty message body if the status code is 204. * @api * @param String command The path which is requested in the REST client. * @param String[] postfields Add specific parameters to the REST server. * @return mixed[] The returned elements as array. */ public static function send($command, $postfields = array()) { if (!InputValidator::isRESTCommand($command) || !self::$ISCONNECTED || !InputValidator::isArray($postfields)) { return null; } $protocol = self::$ISSSL ? "https" : "http"; $url = $protocol . "://" . self::$HOST . "/" . self::PATHTOREST . "/" . self::$SHOP . "/" . $command; $headers = array("Accept: " . self::HTTP_ACCEPT, "Content-Type: " . self::HTTP_CONTENT_TYPE); if (InputValidator::isAuthToken(self::$AUTHTOKEN)) { array_push($headers, "Authorization: Bearer " . self::$AUTHTOKEN); } $curl = curl_init($url); curl_setopt($curl, CURLOPT_FAILONERROR, 1); // show full errors curl_setopt($curl, CURLOPT_FORBID_REUSE, 0); // connection can be opened curl_setopt($curl, CURLOPT_FRESH_CONNECT, 0); // no new connection required curl_setopt($curl, CURLOPT_NOBODY, 0); // show body curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // get response as string curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 0); // no connection timeout curl_setopt($curl, CURLOPT_CONNECTTIMEOUT_MS, 0); // no connection timeout curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_NONE); // cURL will choose the http version curl_setopt($curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_WHATEVER); // understand ipv4 and ipv6 if (self::$ISSSL) { curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); // don't check the peer ssl cerrificate curl_setopt($curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTPS); curl_setopt($curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTPS); curl_setopt($curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_DEFAULT); // default ssl version } else { curl_setopt($curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTP); curl_setopt($curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP); } switch (self::$HTTP_REQUEST_METHOD) { case HTTPRequestMethod::GET: curl_setopt($curl, CURLOPT_HTTPGET, 1); break; case HTTPRequestMethod::POST: $JSONpostfield = JSONHandler::createJSON($postfields); curl_setopt($curl, CURLOPT_POST, 1); curl_setopt($curl, CURLOPT_POSTREDIR, 0); // don't post on redirects curl_setopt($curl, CURLOPT_POSTFIELDS, $JSONpostfield); break; case HTTPRequestMethod::PUT: $JSONpostfield = JSONHandler::createJSON($postfields); array_push($headers, "Content-Length: " . strlen($JSONpostfield)); curl_setopt($curl, CURLOPT_POSTFIELDS, $JSONpostfield); curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT'); break; case HTTPRequestMethod::DELETE: $JSONpostfield = JSONHandler::createJSON($postfields); curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "DELETE"); curl_setopt($curl, CURLOPT_POSTFIELDS, $JSONpostfield); break; case HTTPRequestMethod::PATCH: $JSONpostfield = JSONHandler::createJSON($postfields); curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PATCH"); curl_setopt($curl, CURLOPT_POSTFIELDS, $JSONpostfield); break; } curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); $response = curl_exec($curl); $info = curl_getinfo($curl); $error = curl_error($curl); curl_close($curl); $logMessage = self::$HTTP_REQUEST_METHOD . " " . $info["url"] . "<br/>" . "<strong>Response</strong>: " . $info["http_code"] . ": <pre>" . htmlspecialchars($response) . "</pre><br/>" . "<strong>Content-Type</strong>: " . $info["content_type"] . "<br/>" . "<strong>Size</strong> (Header/Request): " . $info["header_size"] . "/" . $info["request_size"] . " Bytes<br/>" . "<strong>Time</strong> (Total/Namelookup/Connect/Pretransfer/Starttransfer/Redirect): " . $info["total_time"] . " / " . $info["namelookup_time"] . " / " . $info["connect_time"] . " / " . $info["pretransfer_time"] . " / " . $info["starttransfer_time"] . " / " . $info["redirect_time"] . " seconds<br/>"; Logger::notify("<strong>HTTP-SEND</strong>:<br/>" . $logMessage); // if message body is empty this is allowed with 204 if (!$response && $info["http_code"] != "204") { Logger::error("Error with send REST client: " . $error); return null; } elseif (!in_array($info["http_code"], array("200", "201", "204"))) { Logger::warning("Get wrong response: " . $info["http_code"]); return null; } return JSONHandler::parseJSON($response); }
/** * @group utility */ function testIsAuthToken() { $this->assertFalse(InputValidator::isAuthToken(null)); $this->assertFalse(InputValidator::isAuthToken("")); $this->assertTrue(InputValidator::isAuthToken("SomeString")); }