Why is Easyuniv REST API not Handling Errors? - php

I am writing a REST API and currently testing some things. I am trying to make it send an error response when it does not find anything in the database.
The part that is running (because i am testing currently by just entering the url into my browser) is below:
else if ($request->getHttpAccept() === 'xml')
{
if(isset($data['s']) && isset($data['n'])) {
$id = $db->getAlcoholIDByNameSize($data['n'], $data['s']);
$prices = $db->pricesByAlcohol($id);
}
if(isset($id)) {
$resData = array();
if(!empty($prices)) {
foreach($prices as $p) {
$store = $db->store($p['store']);
array_push($resData, array('storeID' => $p['store'], 'store_name' => $store['name'], 'store_gps' => $store['gps'], 'price' => round($p['price'], 2)));
}
RestUtils::sendResponse(200, json_encode($resData), 'application/json');
} else {
RestUtils::sendResponse(204, 'error', 'application/json');
}
} else {
RestUtils::sendResponse(204, 'error', 'application/json');
}
//RestUtils::sendResponse(501, "xml response not implemented", 'application/xml');
}
everything works fine if the queries return something to be stored in $id and $prices. If they do not exist in the database, however, it tries to load the page, and then goes back to the previous page you were on. You can see the behavior by going to:
http://easyuniv.com/API/alc/coorsa/2 <-- works
http://easyuniv.com/API/alc/coors/3 <-- works
http://easyuniv.com/API/alc/coorsa/5 <-- doesn't work(or anything else, the two above are the only ones)
here is my sendResponse function:
public static function sendResponse($status = 200, $body = '', $content_type = 'text/html')
{
$status_header = 'HTTP/1.1 ' . $status . ' ' . RestUtils::getStatusCodeMessage($status);
// set the status
header($status_header);
// set the content type
header('Content-type: ' . $content_type);
// pages with body are easy
if($body !== '')
{
$temp = json_decode($body);
$body = json_encode(array('result' => array('status' => $status, 'message' => RestUtils::getStatusCodeMessage($status)), 'data' => $temp));
// send the body
echo $body;
exit;
}
// we need to create the body if none is passed
else
{
$body = "else".json_encode(array('result' => array('status' => $status, 'message' => RestUtils::getStatusCodeMessage($status))));
echo $body;
exit;
}
}
I have tried debugging using echos but I cant seem to narrow down what the issue is. Any help would be appreciated, thanks.

The problem is that when there is no appropriate data found in the data base you are returning HTTP 204 which is telling the browser there is absolutely nothing for it to display. This is not true in your case.
You still want to output the message that there was nothing found.
To fix you need to replace the two instances of 204 in your code with 200.
I modified tested your code using: Note, nothing will display as is. To get the message to display change 204 to 200 in the $status_header variable.
<?php
$status_header = 'HTTP/1.1 204';
// set the status
header($status_header);
// set the content type
header('Content-type: text/html');
echo "Can you see me???";
?>
Note: When testing this always close the tab and use a fresh tab for each call or else it will look like it is loading data from the previous call, like you have explained.

Related

PHP wordpress wp_safe_remote_post write server response to text file

In Wordpress (PHP) i'm using Contact Form 7 (CF7) as the UI and sending the data via an API with the function on_submit below. Would like to have the success or fail response data logged to make sure everything is working so thought i'd write that to a simple text file using the function custom_logs. It does write to the text file but then the process never continues on to the CF7 plugin to indicate the POST was a success or fail, it just hangs after hitting submit on the UI side. I believe something about writing to the file is interrupting the flow and then is just stops from CF7's POV. I rarely write anything in PHP so not 100% sure what the issue is? Anyone have an idea how to solve it, I can't find anything. Thanks
function on_submit( $form, &$abort, $submission )
{
$data = $submission->get_posted_data();
$firstname = sanitize_text_field($data['first-name']);
$response = wp_safe_remote_post("https://www.api.com", [
'body' => json_encode([
'firstname' => $firstname,
]),
]);
if ( is_wp_error($response) ) {
$abort = TRUE;
$body = wp_remote_retrieve_body($response);
$result = json_decode($body);
$submission->set_response($result->error);
$submission->set_status('api_failed');
} else {
$abort = FALSE;
$body_success = wp_remote_retrieve_body($response);
$result_success = json_decode($body_success);
custom_logs("WP API: " . $result_success);
}
}
add_action('wpcf7_before_send_mail', 'on_submit', 10, 3);
function custom_logs($message) {
if(is_array($message)) {
$message = json_encode($message);
}
$file = fopen("custom_logs.log","a");
echo fwrite($file, "\n" . date('Y-m-d h:i:s') . " :: " . $message);
fclose($file);
}

Where is the echo command for a HTTP request?

I might be asking the wrong question here, but I cant seem to figure out where this is coming form. I am using both the HTTP Request2 and NET URL2 libraries in order to send some GET request to the Vuforia web services. This all works fine, but everytime I send a request, it also shows said request on screen.
GET d41d8cd98f00b204e9800998ecf8427e Mon, 09 Dec 2019 22:49:52 GMT /summary/ba2246f8cd29466899c69b8d05af09a1
The code that I use to get the above text appear on screen is as follows.
Main code:
<?php if(sizeof($items) > 0){
foreach($items as $item){
echo '<tr>';
echo'<td>'.$item['itemid'].'</td>';
echo'<td>'.$item['name'].'</td>';
echo'<td>'.$item['surname'].'</td>';
echo'<td>'.$item['phone'].'</td>';
$recos = $targetdata = json_decode(CheckVuforiaTarget("ba2246f8cd29466899c69b8d05af09a1"), true);
echo'<td>'.$recos['current_month_recos'].'</td>';
}
} else echo '<tr><td>Geen kandidaten</td></tr>';?>
Script holding the CheckVuforiaTarget function:
function CheckVuforiaTarget($vuforiaid){
$vuforiaTargetTracker = new TargetTracker($vuforiaid);
$response = $vuforiaTargetTracker->TargetTracker();
return ($response);
//print_r($vuforiaResult);
}
TargetTracker class:
<?php
require_once 'HTTP/Request2.php';
require_once 'SignatureBuilder.php';
// See the Vuforia Web Services Developer API Specification - https://developer.vuforia.com/resources/dev-guide/retrieving-target-cloud-database
// The DeleteTarget sample demonstrates how to delete a target from its Cloud Database using the target's target id.
// * note that targets cannot be 'Processing' and must be inactive to be deleted.
class TargetTracker{
//Server Keys
private $access_key = "...";
private $secret_key = "...";
private $url = "https://vws.vuforia.com";
private $requestPath = "/summary/";
private $request;
private $targetId = "";
public function __construct($targetId) {
$this->targetId = $targetId;
}
function TargetTracker(){
$this->requestPath = $this->requestPath . $this->targetId;
return $this->execTargetTracker();
}
public function execTargetTracker(){
$this->request = new HTTP_Request2();
$this->request->setMethod( HTTP_Request2::METHOD_GET );
$this->request->setConfig(array('ssl_verify_peer' => false));
$this->request->setURL( $this->url . $this->requestPath );
$this->setHeaders();
try {
$response = $this->request->send();
if (200 == $response->getStatus()) {
return $response->getBody();
} else {
//echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' .
// $response->getReasonPhrase(). ' ' . $response->getBody();
return $response->getBody();
}
} catch (HTTP_Request2_Exception $e) {
return $e->getMessage();
}
}
private function setHeaders(){
$sb = new SignatureBuilder();
$date = new DateTime("now", new DateTimeZone("GMT"));
// Define the Date field using the proper GMT format
$this->request->setHeader('Date', $date->format("D, d M Y H:i:s") . " GMT" );
// Generate the Auth field value by concatenating the public server access key w/ the private query signature for this request
$this->request->setHeader("Authorization" , "VWS " . $this->access_key . ":" . $sb->tmsSignature( $this->request , $this->secret_key ));
}
}
?>
Both HTTP/Request2.php(and everything it came with) and SignatureBuilder.php are both default scripts/classes I've downloaded from the internet without altering them.
Now with my basic understanding of PHP, i've tried to find anything related to an echo or whatever command would show this on screen, but I can't seem to find it.
Does someone have some pointers for me, so I can figure out the source?
Thanks in advance!
The code you provided has no echo/print output that would explain the message you see. The echo/print statement must be somewhere else.

Why my second call on url doesn't work (Laravel,Guzzle)?

This is a function where i call 2 api, from first i get client_id which i used in second url. Problem is that after i call second url my page is loading without end.
Page image
public function getDevices(){
$route='http://localhost:8000/api/devices';
$device= new Client();
$answer= $device->request('GET', $route);
$body = $answer->getBody();
$status = 'true';
$message = 'Data found!';
$final= json_decode($body);
$id_array = array();
foreach ($finalas $item) {
// Add each id value in your array
$id_array[]= $item->clientId;
}
foreach($id_array as $my_id) {
$answer2= $client->request('GET', 'http://localhost:8080/api/devices/deviceAvailability/' . $my_id );
$body2 = $response2->getBody();
$final2= json_decode($body2);
}
return view('new.home', ['clients' => $final, 'status'=> $final2]);
I think
return view('new.home', ['clients' => $final, 'status'=> $final2])
is wrong. Because $final is decoded variable, maybe $final contains several types of variables.
In php, you can not set parameter that contains several types of variables.
Please do like that.
return view('new.home', ['clients' => $body, 'status'=> $final2]);
That's because json encoded variable is only a string.
I want your result.

PHP script receives GET instead of POST REQUEST

I am using PHP with XAMPP and Dialogflow to create a chat interface. In a simple intent(question) in Dialogflow, I have created a webhook to XAMPP regarding the question 'Who is X' (e.g. Paul, George). Therefore , I place a POST REQUEST in order to have access to the json form of this question in DIalogflow so that I can answer it as I want to. Specifically, the ultimate goal of this is to retrieve some data from a MySQL database in phpMyAdmin about this question and respond for example that 'X is a developer' or 'X is a financial analyst'. This is why wrote a php script which is the following:
<?php
$method = $_SERVER['REQUEST_METHOD'];
// Process when it is POST method
if ($method == 'POST') {
$requestBody = file_get_contents('php://input');
$json = json_decode($requestBody);
$text = $json->result->parameters;
switch($text) {
case 'given-name':
$name = $text->given-name;
$speech = $name . 'is a developer';
break;
default:
$speech = 'Sorry I did not get this. Can you repeat please?';
}
$response = new \stdClass();
$response->speech = "";
$response->displayText = "";
$respone->source = "webhook";
echo json_encode($response);
}
else
{
echo "Method not allowed";
}
?>
However, the output of this program is: Method not allowed.
Paradoxically enough $method has the value 'GET' so it identifies a GET REQUEST while Dialogflow explicitly states at the webhook page that
Your web service will receive a POST request from Dialogflow in the
form of the response to a user query matched by intents with webhook
enabled.
Hence I am wondering: why my php script cannot see and process the POST REQUEST from Dialogflow?
P.S. Questions close to mine are the following: Form sends GET instead of POST, Why is $_SERVER['REQUEST_METHOD'] always GET?.
It doesn't work because $_SERVER['REQUEST_METHOD'] == "GET" by default.
So you program execute the 'else' condition.
You need to submit a request with the POST method to change this value.
You can use
<form method="POST">
[...]
</form>
in your HTML, or
$.ajax({
url : "ajax_url.php",
type : 'POST',
data : 'data='+data,
[...]
});
in your AJAX JS code for example
Here i am doing same like you from below code your Query will be resolved,
index.php
<?php
require 'get_enews.php';
function processMessage($input) {
$action = $input["result"]["action"];
switch($action){
case 'getNews':
$param = $input["result"]["parameters"]["number"];
getNews($param);
break;
default :
sendMessage(array(
"source" => "RMC",
"speech" => "I am not able to understand. what do you want ?",
"displayText" => "I am not able to understand. what do you want ?",
"contextOut" => array()
));
}
}
function sendMessage($parameters) {
header('Content-Type: application/json');
$data = str_replace('\/','/',json_encode($parameters));
echo $data;
}
$input = json_decode(file_get_contents('php://input'), true);
if (isset($input["result"]["action"])) {
processMessage($input);
}
?>
get_enews.php
<?php
function getNews($param){
require 'config.php';
$getNews="";
$Query="SELECT link FROM public.news WHERE year='$param'";
$Result=pg_query($con,$Query);
if(isset($Result) && !empty($Result) && pg_num_rows($Result) > 0){
$row=pg_fetch_assoc($Result);
$getNews= "Here is details that you require - Link: " . $row["link"];
$arr=array(
"source" => "RMC",
"speech" => $getNews,
"displayText" => $getNews,
);
sendMessage($arr);
}else{
$arr=array(
"source" => "RMC",
"speech" => "No year matched in database.",
"displayText" => "No year matched in database.",
);
sendMessage($arr);
}
}
?>
php://input is a read-only stream that allows you to read raw data from the request body. In the case of POST requests, it is preferable to use php://input

get json and see if there is not found

i want the php script to be able the get json using Unirest php
<?php
require_once 'src/Unirest.php';
$word = 'Cartoon newttork';
// return: convert-spaces-to-underscore-and-lowercase-with-php
$word = str_replace(' ', '_', strtolower($word));
// These code snippets use an open-source library.
$response = Unirest\Request::get("https://od-api.oxforddictionaries.com:443/api/v1/entries/en/$word",
array(
"Accept" => "application/json", // accept app as json
"app_id" => "xxxxx", // app id found in dashboard
"app_key" => "xxxxxx" //app key also found in dashboard
)
);
$word_name = $response->body;
if ($word_name === "Not Found") {
echo "Not Found";
}
?>
i want is to be something like this
$word_name = $response->body;
if ($word_name === "Not Found") {
echo "Not Found";
}
P.S if you have another php http client that is better write it down also

Categories