Getting undefined array key when using curl - php

I'm building a simple domain availability checker using the Godaddy api.
I'm using Laravel 9 for the application.
It gives back available and already registered results, but if I add a string without domain extension like: somename
so no .com or.org etc. then I get an ("Undefined array key "available") error message.
On my view file I only have a simple form with one input field where the user can enter the domain name to be checked.
In my controller I validate the input:
$validator = Validator::make($request->all(), [
'userDomain' => ['required', 'string', 'max:191']
]);
I also have my API keys and base url stored in variables:
$API_KEY_OTE = "apikey";
$API_SECRET_OTE = "apisecret";
$OTE_BASE_URL = "https://api.ote-godaddy.com";
Then I remove some unwanted characters from the input
$request->userDomain = str_replace('www.', '', $request->userDomain);
$request->userDomain = str_replace('http://', '', $request->userDomain);
$request->userDomain = str_replace('https://', '', $request->userDomain);
I put together the url for curl like this:
$url = $OTE_BASE_URL . "/v1/domains/available?domain=" . $request->userDomain;
Then I have the curl settings like this:
$header = array(
'Authorization: sso-key '.$API_KEY_OTE.':'.$API_SECRET_OTE.''
);
$ch = curl_init();
$timeout = 60;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,false);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$result = curl_exec($ch);
curl_close($ch);
$checkDomain = json_decode($result, true);
Then i check the result with a series of if / else if statements:
if($checkDomain['available'] == 1 || $checkDomain['available'] == true) {
return redirect()->back()->with('successMsg', 'The domain name ' . $request->userDomain . ' is available! Click here to register it on Godaddy!');
} else if($checkDomain['available'] == '' || $checkDomain['available'] == 0 || $checkDomain['available'] == false) {
return redirect()->back()->with('failureMsg', 'Sorry! The domain name ' . $request->userDomain . ' is already registered! Try a different name.');
}
else if($checkDomain['code']) {
return redirect()->back()->with('failureMsg', $checkDomain['fields'][0]['message']);
} else {
return redirect()->back()->with('failureMsg', 'Please enter a valid domain name!');
}
This is a successful response body that comes from godaddy:
{
"available": true,
"currency": "USD",
"definitive": true,
"domain": "string",
"period": 0,
"price": 0
}
and this is an invalid response body:
{
"code": "string",
"fields": [
{
"code": "string",
"message": "string",
"path": "string",
"pathRelated": "string"
}
],
"message": "string"
}

You must first check if it's error response or success response, only then try to use one of it's keys:
if (isset($checkDomain['available'])) {
if (!empty($checkDomain['available'])) {
return redirect()->back()->with('successMsg', 'The domain name ' . $request->userDomain . ' is available! Click here to register it on Godaddy!');
}
return redirect()->back()->with('failureMsg', 'Sorry! The domain name ' . $request->userDomain . ' is already registered! Try a different name.');
} elseif (isset($checkDomain['code'])) {
return redirect()->back()->with('failureMsg', $checkDomain['fields'][0]['message']);
}
return redirect()->back()->with('failureMsg', 'Please enter a valid domain name!');

Related

Illegal string offset 'name', code worked with example json response

I'm currently working on a website to control my SmartBulbs at home via a webpage. To do so I use the provided API.
I tried my code with an example json response from the manufacturers website. Everything worked fine and all the lights listed in the example response where represented by divs with the names of the lights.
When I tried my code at home (called the API like in the code) I got a valid response but I also got an error which stated Illegal string offset 'label'. What am I doing wrong?
Everything worked fine when I used the example response. The response when I use the API looks the same for me. Shouldn't it also work then?
You can find everything down below. If you need some mor information just ask :)
php code
function get_lights(){
$link = "https://api.lifx.com/v1/lights/all";
$authToken = "I inserted my token here and got a valid response";
$ch = curl_init($link);
$headers = array('Authorization: Bearer ' . $authToken);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, $headers);
$response = curl_exec($ch);
$json = json_decode($response, true);
$html = null;
foreach($json as $object)
{
$html.= '<div class="element" onclick="get_info();">' . $object['label'] . '</div>';
}
return $html;
}
example response
[
{
"id": "d3b2f2d97452",
"uuid": "8fa5f072-af97-44ed-ae54-e70fd7bd9d20",
"label": "Left Lamp",
"connected": true,
"power": "on",
"color": {
"hue": 250.0,
"saturation": 0.5,
"kelvin": 3500
},
"infrared": "1.0",
"brightness": 0.5,
"group": {
"id": "1c8de82b81f445e7cfaafae49b259c71",
"name": "Lounge"
},
"location": {
"id": "1d6fe8ef0fde4c6d77b0012dc736662c",
"name": "Home"
},
"last_seen": "2015-03-02T08:53:02.867+00:00",
"seconds_since_seen": 0.002869418,
"product": {
"name": "LIFX+ A19",
"company": "LIFX",
"identifier": "lifx_plus_a19",
"capabilities": {
"has_color": true,
"has_variable_color_temp": true,
"has_ir": true,
"has_multizone": false
}
}
}
]
my API response
[
{
"id":"d073d513bfd6",
"uuid":"02ea5835-9dc2-4323-84f3-3b825419008d",
"label":"MainLight",
"connected":true,
"power":"on",
"color":{
"hue":27.581597619592586,
"saturation":0.0,
"kelvin":2500
},
"zones":null,
"brightness":0.49999237048905165,
"group":{
"id":"d5aa0e1180293e0af56607cbe47f4940",
"name":"MyRoom"
},
"location":{
"id":"451e4b376a38062cdd10c54ab2698975",
"name":"My Home"
},
"product":{
"name":"Color 1000",
"identifier":"lifx_color_a19",
"company":"LIFX",
"capabilities":{
"has_color":true,
"has_variable_color_temp":true,
"has_ir":false,
"has_multizone":false
}
},
"infrared":null,
"last_seen":"2017-02-18T21:40:58.164+00:00",
"seconds_since_seen":0.001675218
}
]
You're setting the wrong option for your cURL handle:
$ch = curl_init($link);
$headers = array('Authorization: Bearer ' . $authToken);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);

Create new user using the Freshdesk API in PHP

This is my code:
$contact_data = json_encode(array(
"name" => "Jimmy Jimmy",
"email" => "jimmy#example.com",
"phone" => "555-555-555",
"mobile" => "312-312-213"
));
$url = $domain."api/v2/contacts";
$ch = curl_init($url);
$header[] = "Content-type: application/json";
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_USERPWD, "$apiKey");
curl_setopt($ch, CURLOPT_POSTFIELDS, $contact_data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$server_output = curl_exec($ch);
$info = curl_getinfo($ch);
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$headers = substr($server_output, 0, $header_size);
$response = substr($server_output, $header_size);
if($info['http_code'] == 201) {
echo "Contact created successfully, the response is given below \n";
echo "Response Headers are \n";
echo $headers."\n";
echo "Response Body \n";
echo "$response \n";
} else {
if($info['http_code'] == 404) {
echo "Error, Please check the end point \n";
} else {
echo "Error, HTTP Status Code : " . $info['http_code'] . "\n";
echo "Headers are ".$headers."\n";
echo "Response is ".$response;
}
}
curl_close($ch);
When I executed this piece of code , I received this errors message:
Response is {"description":"Validation failed","errors":[{"field":"last_name","message":"It should be a/an String","code":"missing_field"},{"field":"life_cycle_status","message":"It should be a/an String","code":"missing_field"}]}
The documentation nothing mentioned about these fields : last_name & life_cycle_status to create a new contact in freshdesk. Any idea what am i doing wrong ? thx
[UPDATE]
$contact_data = json_encode(array(
"name" => "Jimmy Jimmy",
"email" => "jimmy#example.com",
"phone" => "555-555-555",
"mobile" => "312-312-213"
"life_cycle_status" => "asdasdsa",
"last_name" =>"dasdasdad"
));
With these new items, I got this message error:
Response is {"description":"Validation failed","errors":[{"field":"life_cycle_status","message":"Unexpected/invalid field in request","code":"invalid_field"},{"field":"last_name","message":"Unexpected/invalid field in request","code":"invalid_field"}]}
These fields are not default for the Freshdesk Contact entity but are, probably, defined as required in the backend (Check Admin > Customer fields in the backend of Freshdesk)
This means we have to define them as custom_fields as indicated in the Freshdesk API documentation here.
This means your POST array would look something like this
$contact_data = json_encode(array(
'name' => 'Jimmy Jimmy',
'email' => 'jimmy#example.com',
'custom_fields' => [
// put all your custom fields here
'last_name' => 'Jimmy',
'life_cycle_status' => 'value'
]
));
Well you already have the answer - you did read that error message yes?
Response:
{
"description": "Validation failed",
"errors":[
{
"field":"last_name",
"message":"It should be a/an String",
"code":"missing_field"
},
{
"field":"life_cycle_status",
"message":"It should be a/an String",
"code":"missing_field"
}
]
}
Meaning:
last_name and life_cycle_status both need to be a String and cannot be empty.

VAT Number Validation Function Not Working

I'm trying to write a vat number validation function which checks a vat number to see if it's valid.
Currently i've got this
function tep_check_vatnum($countries_id, $vatnum) {
$country = tep_get_countries_with_iso_codes($countries_id);
$iso = $country['countries_iso_code_2'];
if($iso == "GB"){
return false;
} else {
$url = "http://isvat.appspot.com/$iso/$vatnum";
$session = curl_init();
curl_setopt($session, CURLOPT_URL, $url);
// curl_setopt($session, CURLOPT_HTTPGET, 1);
// curl_setopt($session, CURLOPT_HEADER, false);
// curl_setopt($session, CURLOPT_HTTPHEADER, array('Accept: application/xml', 'Content-Type: application/xml'));
curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($session);
//echo "<!-- NOTE:" . $response . "-->";
curl_close($session);
if($response == "true"){
return true;
} else {
return false;
}
}
}
The service i'm using http://isvat.appspot.com is working, But it's not working.
EDIT
Hmm no luck. By not working, it keeps giving me an error saying the vat number isn't valid. On the create account form i've got this code.
<?php echo tep_draw_input_field('vatnum', '', 'class="input"') . ' ' . (tep_not_null(ENTRY_COMPANY_TEXT) ? '<span class="inputRequirement">' . ENTRY_COMPANY_TEXT . '</span>': ''); ?>
if (is_numeric($country) == false) {
$error = true;
$messageStack->add('create_account', ENTRY_COUNTRY_ERROR);
} else {
if(strlen($vatnum) != 0){
if(is_numeric($vatnum) == false || tep_check_vatnum($country, $vatnum) == false){
$error = true;
$messageStack->add('create_account', "VAT Number is not a valid EU, non-UK VAT no.");
}
}
I guess there might be a problem invoking cURL. The good news is, you probably don't need to. ;) Give this a try:
function tep_check_vatnum($countries_id, $vatnum) {
$country = tep_get_countries_with_iso_codes($countries_id);
$iso = $country['countries_iso_code_2'];
if($iso == "GB"){
return false;
} else {
$url = "http://isvat.appspot.com/$iso/$vatnum";
$context = stream_context_create(array(
'http' => array(
'proxy' => 'http://PROXY_IP:PROXY_PORT'
),
));
$fp = fopen($url,'r',$context);
$response = fgets($fp);
fclose($fp);
//echo "<!-- NOTE:" . $response . "-->";
if($response == "true"){
return true;
} else {
return false;
}
}
}
It should work even if you don't have the cURL extension enabled.
Edit: As Michas said, it is difficult to find the problem with your original code without knowing what you mean by "not working". You could try to get some more information about the problem by stating error_reporting(E_ALL) or curl_error($session).
Possible causes: cURL is not installed or configured correctly or a proxy or firewall is blocking your request. While the code I suggested would eliminate the first one, the second one might also apply using it, depending on your settings.
Edit 2: Added simple proxy configuration

OAuth2 integration with ExactOnline

I am trying to integrate our app with Exact Online website using OAuth2,or more specifically i am trying to create hour registration which should include "Employee","Project","Hours","Hours type".
function registerTime($access_token_for_data) {
//$dataToFilterAccounts = array('$filter' => 'IsSales eq true');
$dataToRetrieveFromEmployees = array('$select' => 'ID');
// $queryToFilterAccounts = http_build_query($dataToFilterAccounts);
$queryToRetrieveFromEmployees = http_build_query($dataToRetrieveFromEmployees);
// $dataToFilterItems = array('$filter' =>'IsSalesItem eq true');
$dataToRetrieveProjects = array('$select' => 'ID');
//$queryToFilterItems = http_build_query($dataToFilterItems);
$queryToRetrieveProjects = http_build_query($dataToRetrieveProjects);
$urlProjects = 'https://start.exactonline.nl/api/v1/638842/project/Projects';
$urlEmployees = 'https://start.exactonline.nl/api/v1/638842/payroll/Employees';
$curlProjects = curl_init($urlProjects);
$curlEmployees = curl_init($urlEmployees);
$headers = array(
'Authorization: Bearer ' . $access_token_for_data,
'Accept: application/json',
'Content-type: application/json'
);
curl_setopt($curlProjects, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curlProjects, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curlProjects, CURLOPT_URL, $urlProjects . '?' . $queryToRetrieveProjects);
curl_setopt($curlProjects, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($curlEmployees, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curlEmployees, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curlEmployees, CURLOPT_URL, $urlEmployees . '?' . $queryToRetrieveFromEmployees);
curl_setopt($curlEmployees, CURLOPT_CUSTOMREQUEST, 'GET');
$resultProjects = curl_exec($curlProjects);
$resultEmployees = curl_exec($curlEmployees);
$projectsData = json_decode($resultProjects, true);
$projectID = $projectsData["d"]["results"]["0"]["ID"];
$employeesData = json_decode($resultEmployees, true);
$employeeID = $employeesData["d"]["results"]["0"]["ID"];
curl_close($curlProjects);
curl_close($curlEmployees);
$urlTimeTransaction = 'https://start.exactonline.nl/api/v1/638842/project/TimeTransactions';
$curlTimeTransacation = curl_init($urlTimeTransaction);
$content = json_encode(array("Project" => $projectID, "Employee" => $employeeI));
curl_setopt($curlTimeTransacation, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curlTimeTransacation, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curlTimeTransacation, CURLOPT_POST, true);
curl_setopt($curlTimeTransacation, CURLOPT_POSTFIELDS, $content);
$createdTimeTransaction = curl_exec($curlTimeTransacation);
$status = curl_getinfo($curlTimeTransacation, CURLINFO_HTTP_CODE);
if ($status != 201) {
die("Error: call to URL $curlTimeTransacation failed with status $status, response $createdTimeTransaction, curl_error " . curl_error($curlTimeTransacation) . ", curl_errno " . curl_errno($curlTimeTransacation));
}
echo "HTTP status $status creating time registartion<br/><br/>";
curl_close($curlTimeTransacation);
}
And this is the error i get
Error: call to URL Resource id #56 failed with status 500, response { "error": { "code": "", "message": { "lang": "", "value": "Mandatory: Employee\r\nMandatory: Hours\r\nMandatory: Hour type" } } }, curl_error , curl_errno 0
But when i try to include any of these mandatroy fileds i get:
Error: call to URL Resource id #56 failed with status 400, response { "error": { "code": "", "message": { "lang": "", "value": "Error processing request stream. The property name 'Hours' specified for type 'Exact.Web.Api.Models.TimeTransaction' is not valid." } } }, curl_error , curl_errno 0
please note that /api/v1/638842 contains your division ID. You might want to change that into a variable.
Regarding your problem: please note that the error messages contain text to be consumed by humans. The actual technical names can be different. I always do it the other way around: I query the existing data and look at all fields, and then I know what to send. You can use the Query Tool for Exact Online in the app center of Exact to do the query on REST api of Exact Online (but I am biased because involved).
As Guido pointed out correctly, there is no field named Hours in the TimeTransaction on projects, there is a field named Hours on the manufacturing TimeTransaction. This is a little confusing, especially since the error message isn't very clear.
You need to set Quantity on TimeTransactions in order to specify the hours on a project's time transaction.

php- curl isn't working

Here is my code, I have two cURL statements in the same program. The first one uses $ch and second uses $ch1. The problem is first one is getting executed and showing the output but second one does nothing.
<?php
include ('DBconnect.php');
if (isset($_POST['submit'])) {
$verified = "1";
$error = array();
if (empty($_POST['name'])) {
$error[] = 'I am sure you have a name!';
}
else {
$name = $_POST['name'];
}
if (empty($_POST['phone'])) {
$error[] = 'Please enter your phone number with country code';
}
else {
$Phone = $_POST['phone'];
}
if (empty($_POST['Password'])) {
$error[] = 'Please choose a password ';
}
else {
$Password = $_POST['Password'];
}
if (empty($error)) //send to Database if there's no error '
{ // If everything's OK...
// Make sure the phone number is available:
$query_verify_phone = "SELECT * FROM members WHERE Phone ='$Phone'";
$result_verify_phone = mysqli_query($dbc, $query_verify_phone);
if (!$result_verify_phone) { //if the Query Failed ,similar to if($result_verify_phone==false)
echo ' Database Error Occured ';
}
if (mysqli_num_rows($result_verify_phone) == 0) { // IF no previous user is using this phone number.
$query_insert_user = "INSERT INTO `members` ( `Name`, `Phone`, `Password`, `Verified`) VALUES ( '$name', '$Phone', '$Password', '$verified')";
$result_insert_user = mysqli_query($dbc, $query_insert_user);
if (!$result_insert_user) {
echo 'Query Failed ';
}
if (mysqli_affected_rows($dbc) == 1) { //If the Insert Query was successfull.
$customerToken = "TOKEN HERE";
$clientTransactionId = rand(55555, 77777);
$duration = "180";
$countryCode = "91";
$z2vToken = "TOKEN HERE";
$postData = array(
'customerToken' => $customerToken,
'clientTransactionId' => $clientTransactionId,
'callerid' => $Phone,
'duration' => $duration,
'countryCode' => $countryCode,
'z2vToken' => $z2vToken,
);
// create post body
$post_body = '';
foreach($postData as $key => $value) {
$post_body.= urlencode($key) . '=' . urlencode($value) . '&';
}
$post_body = rtrim($post_body, '&');
// Initialize CURL data to send via POST to the API
// FIRST ONE CURL REQUEST- WORKING
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://www.zipdial.com/z2v/startTransaction.action");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_body);
// Execute CURL command and return into variable ch
$string = curl_exec($ch);
curl_close($ch);
$json = json_decode($string);
// now the json has been decoded
// echo "Please do a missed call on: ";
// echo "<img src=' ".$json->img."'>";
$pf = 'fl' . uniqid();
$un = uniqid($pf);
$fpl = 'img' . $un . '.png';
file_put_contents($fpl, file_get_contents($json->img));
Everything above goes fine but the second curl request is not working:
// EVERYTHING ABOVE GOES FINE. BELOW IS SECOND REQUEST- NOT WORKING
$url = "https://api.idolondemand.com/1/api/sync/ocrdocument/v1";
$post = array(
'apikey' => "MY KEY HERE",
'url' => "http://site.ext/users/$fpl",
'mode' => "document_photo"
);
$ch1 = curl_init();
curl_setopt($ch1, CURLOPT_URL, $url);
curl_setopt($ch1, CURLOPT_POST, 1);
curl_setopt($ch1, CURLOPT_POSTFIELDS, $post);
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, 1);
$ocr = curl_exec($ch1);
$jsonocr = json_decode($ocr, true);
$textblock = $jsonocr['text'][0];
echo '<div class="success">Please give a missed call to ' . $textblock['text'] . ' from your registered phone number to activate account. </div>';
curl_close($ch1);
}
else { // If it did not run OK.
echo '<div class="errormsgbox">You could not be registered due to a system error. We apologize for any inconvenience.</div>';
}
}
else { // The phone number is not available.
echo '<div class="errormsgbox" >That phone number has already been registered. </div>';
}
}
else { //If the "error" array contains error msg , display them
echo '<div class="errormsgbox"> <ol>';
foreach($error as $key => $values) {
echo ' <li>' . $values . '</li>';
}
echo '</ol></div>';
}
mysqli_close($dbc); //Close the DB Connection
} // End of the main Submit conditional.
?>
I can make request to second curl request manually from my browser and it works but it isn't working here. What's wrong?
I think you get this error when you dump curl_error($ch1) :
Unknown SSL protocol error in connection to api.idolondemand.com
You can add this line when you curl https if you have no sensitive transiting data :
curl_setopt($ch1, CURLOPT_SSL_VERIFYPEER, false);
Here is the code which works for me :
$ch1 = curl_init();
curl_setopt($ch1, CURLOPT_URL, $url);
curl_setopt($ch1, CURLOPT_POST, 1);
curl_setopt($ch1, CURLOPT_POSTFIELDS, $post);
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch1, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch1, CURLOPT_SSL_VERIFYHOST, 1);
$ocr = curl_exec($ch1);
var_dump($ocr);
var_dump(curl_error($ch1));
When I do this, I get :
string(97) "{ "message": "Unknown API key", "detail": { "error": 2002, "key": "MY KEY HERE" } }" string(0) ""
I have set VERIFYPEER to false and VERIFYHOST to 1 and it worked.

Categories