I am having issues with wp_remote_get in my Wordpress plugin.
What I want to do is call a method inside my main public class with ajax. But the thing is that the call fails when the wp_remote_get function is used in it. It is supposed to do an API call and return the data to the jQuery. When I comment out the wp_remote_get the call works fine and response is given back. Any ideas how can I make this work?
Method that processes the call:
public function countryLookupApiCall() {
if (isset($_POST['action']) && isset($_POST['country'])) {
$country = $_POST['country'];
$apiKey = $this->getApiKey();
$url = $this->url . $country . '/callCharges?apiKey=' . $apiKey . '&response=JSON';
$response = wp_remote_get($url);
echo $response;
die();
}
}
jQuery:
jQuery(document).ready(function() {
jQuery("#countryLookupForm").submit(function(e){
var country = jQuery("#selectCountry").val();
var action = 'countryLookupResponse';
jQuery.ajax ({
type: 'POST',
url: countryLookup.ajaxurl,
dataType: 'json',
data: {action: action, country: country},
success: function(data) {
//do something with this data later on
var result = jQuery.parseJSON(data);
}
});
});
});
Wordpress actions are all registered well because the call works when I don't use the wp_remote_get
EDIT:
The solution was more than simple, I just needed to add e.preventDefault();
You need to add errors checking into your code. This can help you to figure out what is causing the problem.
public function countryLookupApiCall() {
if (isset($_POST['action']) && isset($_POST['country'])) {
$country = $_POST['country'];
$apiKey = $this->getApiKey();
$url = $this->url . $country . '/callCharges?apiKey=' . $apiKey . '&response=JSON';
$response = wp_remote_get($url);
if (is_wp_error($response)) {
$error_code = $response->get_error_code();
$error_message = $response->get_error_message();
$error_data = $response->get_error_data($error_code);
// Process the error here....
}
echo $response;
die();
}
}
Also you are using echo on wp_remote_get result. As defined in documentation wp_remote_get returs WP_Error or array instance. So you should use something like this:
echo $response['body'];
Related
I can't seem to get AJAX POST or GET working with my CAKEPHP site. I am trying to create autocomplete but can't seem to submit or fetch the data using ajax. I can get auto complete working using tags but I cannot display the data from my table. I am not sure what is going wrong if i'm not using the right url or some other problem.
Here is my search.ctp
<?php use Cake\Routing\Router; ?>
<?php echo $this->Form->input('id', ['type' => 'text']); ?>
<script>
$.ajax({
type: "POST",
url: "<?php echo Router::url(array('controller' => 'Invoices', 'action' => 'search')); ?>",
success: function(response) {
$("#id").autocomplete({ source: response });
}
});
</script>
Here is my search function in my InvoicesController.
public function search()
{
$this->loadComponent('RequestHandler');
if ($this->request->is('ajax'))
{
$name = $this->request->query['term'];
$resultArr = $this->Invoices
->find()
->where(
['Invoices.id LIKE' => ($name . '%')],
['Invoices.id' => 'string']
);
$resultsArr = [];
foreach ($resultArr as $result)
{
$resultsArr[] = (strval($result['id']));
}
$this->set('resultsArr', $resultsArr);
// This line is what handles converting your array into json
// To get this to work you must load the request handler
$this->set('_serialize', ['resultsArr']);
}
}
This is the error that is produced when I try to type in an ID.
This is what i want to produce which I have been able to do by using an array in search.ctp
and here is my table I am trying to fetch the IDs from.
There are two methods.
$this->request->query('term');
$_REQUEST['term'];
I want to protect my jquery button from bots without annoying the users, so i thought of adding google's invisible recaptcha to it. However implementation isn't as easy as i though and i can't seem to do it. If anyone can show me how it's done it would be great. PS: I am doing this on a wordpress theme.
This is the documentation:
https://developers.google.com/recaptcha/docs/invisible
Create invisible recaptcha:
https://www.google.com/recaptcha/admin#beta
And this is what i have:
HTML:
<button class="acf-get-content-button">Show Link</button>
<div class="fa" id="acf-content-wrapper" data-id="<?php echo $post_id; ?>"></div>
JS:
<script>
(function($) {
$('.acf-get-content-button').click(function(e) {
e.preventDefault();
$('.fa').addClass('fa-cog fa-spin fa-4x');
var $contentWrapper = $('#acf-content-wrapper');
var postId = $contentWrapper.data('id');
$.ajax({
url: "/public/ajax.php",
type: "POST",
data: {
'post_id': postId
},
})
.done(function(data) {
$('.fa').removeClass('fa-cog fa-spin fa-4x');
$contentWrapper.append(data);
$('.acf-get-content-button').removeClass().addClass('.acf-get-content-button')
});
});
$('.acf-get-content-button').mouseup(function() {
if (event.which == 1) {
$(".acf-get-content-button").hide();
}
});
})(jQuery);
</script>
ajax.php
<?php
define('WP_USE_THEMES', false);
require_once( $_SERVER['DOCUMENT_ROOT'] . '/wp-load.php' );
global $post;
$post_id = $_REQUEST["post_id"];
$content = get_field( 'ebook_link_pdf', $post_id );
echo ($content);
You can use Invisible reCaptcha for WordPress plugin to do it easily if you think coding from scratch is complicated for you. You can also dig into the source code of the plugin to get an idea about the implementation.
This plugin has actions and filters for custom use and these are documented on plugin homepage.
I went ahead to experiment with reCaptcha.
Turns out according to the API, you could use the grecaptcha.getResponse method to submit to your AJAX call. (But Note that this reCaptcha API is still in beta and could change...) Here is a short example:
HTML:
<div id="test-captcha" class="g-recaptcha" data-sitekey=[Your site key]></div>
<button id="load" onclick="go();">Load something</button>
Javascript:
function go()
{
$.ajax({
url: "/captchatest.php",
type: "POST",
data: {
'g-recaptcha-response': grecaptcha.getResponse()
}
}).done(function(data) {
alert(data);
});
}
captchatest.php
<?php
//Used http://stackoverflow.com/a/6609181/7344257
function do_post_request($url, $data)
{
// use key 'http' even if you send the request to https://...
$options = array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($data)
)
);
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
if ($result === FALSE) { /* Handle error */ }
return $result;
}
$error = "";
if ($_SERVER["REQUEST_METHOD"] === "POST")
{
if (!isset($_POST['g-recaptcha-response']))
{
echo "Please do reCaptcha";
exit(0);
}
$data = array("secret" => "6LeUGhYUAAAAABNS5OtOc9vonTlyrtgcQ5VdI7cV",
"response" => $_POST['g-recaptcha-response'],
"remoteip" => $_SERVER["REMOTE_ADDR"] //This is optional.
);
$resp = json_decode(do_post_request("https://www.google.com/recaptcha/api/siteverify", $data));
if (!$resp->success)
{
//use $resp->error-codes to debug error.
echo "Invalid reCaptcha";
exit(0);
}
echo "Received secret code.";
exit(0);
}
?>
I wasn't sure if you could use cURL. So I decided to just stick with the basic PHP code. You would also have to format the errors, but I think you should get the point.
I am using Osclass classified script, trying to alert a message returned by ajax call.
My ajax-test.php file which is saved in my theme folder contains
<?php
$name = $_GET["name"];
echo "I am " . $name
?>
and my JavaScript function code is
function findName() {
var name = "Jhon";
$.ajax({
method: "POST",
// url: "oc-content/themes/bender/ajax-test.php",
url: 'http://127.0.0.1/osclass/index.php?page=ajax&action=custom&ajaxfile=ajax-test.php',
data: { name : name },
success: function (data) {
alert(data);
},
})
}
Anybody tell me what am I doing wrong? it alerts
{"error" => "ajaxFile doesn't exist"}
Note: It works fine with commented line of code
You are using
> method: "POST",
in ajax then why are you using GET ?
$name = $_GET["name"];
Using Post to getting value for it.
$name = $_POST["name"];
Unfortunatelyn, that's not exactly how the ajax.php custom action works.
First, page=ajax&action=custom doesn't work with themes, only with plugins since it will search ajaxfile inside the plugins folder by doing something like this:
$filePath = osc_plugins_path() . $ajaxfile; // eg. /oc-content/plugins/$ajaxfile
You then have to pass in ajaxfile the name of the plugin to work. If you were using the Madhouse Messenger plugin, you would do something like:
page=ajax&action=custom&ajaxfile=madhouse_messenger/main.php
However, since 3.3, when using page=ajax&action=custom, you do not use the ajaxfile param anymore but the route param. You can take a look at how routes work here and some examples of routes here.
in your theme functions.php
add something like this:
//name of your custom ajax request
$my_custom_ajax_request_name = 'doSomethingCool';
osc_add_hook('ajax_' . $my_custom_ajax_request_name, $my_custom_ajax_request_name);
function doSomethingCool()
{
// set default response
$response = [
'status' => false,
'msg' => 'Default Error Message...',
];
// token protection
// read more about csrf token:
// https://dev.osclass.org/2013/02/19/make-your-plugins-more-secure-with-anti-csrf-functions/
osc_csrf_check();
// get request parameters
$param1 = Params::getParam('param1');
$param2 = Params::getParam('param2');
// do some logic here ex: check if user is logged in
if (osc_is_web_user_logged_in()) {
$response['status'] = true;
$response['msg'] = 'User is logged in. ;-) ' . $param1 . ' ' . $param2 . '! ' . osc_logged_user_name();
} else {
$response['status'] = false;
$response['msg'] = 'User is not logged in. :-(';
}
// return json response
header('Content-Type: application/json');
echo json_encode($response);
exit;
}
some where in your template files like header.php, footer.php or everything else you need it...
<a data-param1="hello" data-param2="world" href="#" id="make-an-ajax-request">
Make an AJAX Request!
</a>
<script>
//here we hold some usefull info for easy access
var mySite = window.mySite || {};
mySite.base_url = '<?php echo osc_base_url(true); ?>';
mySite.csrf_token = '<?php echo osc_csrf_token_url(); ?>';
$(function(){
$('#make-an-ajax-request').on('click', function(e){
e.preventDefault();
// name of our custom ajax hook
var ajax_hook = 'doSomethingCool';
// get parameters
var param1 = $(this).data('param1');
var param2 = $(this).data('param2');
// build axjxa url
var url = mySite.base_url + '?page=ajax&action=runhook&hook='+ajax_hook+'&'+mySite.csrf_token;
//build data
var data = {
param1 : param1,
param2 : param2
};
$.ajax({
type: 'POST',
dataType: 'json',
data: data,
url: url
}).done(function (data) {
console.log(data);
if (data.status) {
} else {
}
});
});
});
</script>
OSCLASS WAY
to note that the current osclass way of doing an ajax request from a theme page is to call the
http://example.com/?page=ajax&action=runhook&hook=MY_HOOK_FUNCTION_NAME
and register it like osc_add_hook('ajax_MY_HOOK_FUNCTION_NAME',
'MY_HOOK_FUNCTION_NAME'); optionally but very recommended is the use
of the csrf token that you can implement like i have done for url or
by calling the osc_csrf_token_form() directly into your form.
NON OSCLASS WAY
just create a file in your theme or everywhere you want and make sure to put this into it <?php require_once __DIR__ . RELATIVE_PATH_TO_OC_LOAD_FILE . 'oc-load.php'; ?> then build your logic into it.
I have a function in php that need an id and i need to add a variable in my ajax url the id
PHP Code:
function get_json_selected($purpose)
{
//echo $this->input->post("ids");
$ids = explode(",", $this->input->post("ids"));
$site_url = site_url($this->router->class);
if ($purpose == "EQUIPEMENT"){
$this->db->select(
'a.id,
a.manufacturer,
a.description,
a.serial_no,
a.part_no,
a.status,
a.availability,
getReturnStatus(a.id) as return_status',
FALSE
);
$this->db->where_in('a.id', array_unique($ids));
$result = $this->db->get("equipments a")->result_array();
echo json_encode(array("spares" => $result));
} else {
$this->db->select(
'a.id,
a.manufacturer,
a.description,
a.serial_no,
a.part_no,
a.status,
a.availability,
getReturnStatus(a.id) as return_status',
FALSE
);
$this->db->where_in('a.id', array_unique($ids));
$result = $this->db->get($this->active_table." a")->result_array();
echo json_encode(array("spares" => $result));
}
}
Ajax Code:
this is just example of the variable of id.
$purpose = "EQUIPMENT"; // how can i add this php variable to ajax url
url: "<?=site_url('equip_request/get_json_selected');?>", // this is the current code how can i add id in this url
or is this code right?
url: "<?=site_url('equip_request/get_json_selected/'.$purpose);?>"
var purpose = '<?php echo json_encode($purpose); ?>';
url: 'example.php?=' + purpose;
+ is the concatenator in javascript. hope this helps. spend plenty of time and add plenty of security to echoing that var into javascript. else you could find yourself viction of xss.
I would get a json (make from a db query) from a external script javascript.
my model:
<?php
defined('_JEXEC') or die();
jimport( 'joomla.application.component.modelList' );
class MediastoreModelList extends JModelList
{
function getListQuery()
{
$db = JFactory::getDBO();
$query = $db->getQuery(true);
$query->select('id, type, designation', 'marque', 'prix');
$query->from('produits');
return $query;
}
}
my controller:
<?PHP
defined('_JEXEC') or die('Restricted access');
jimport('joomla.application.component.controller');
class MediastoreController extends JController
{
public function getJson() {
$model = getModel();
$data = $model.getListQuery();
$document = JFactory::getDocument();
$document->setMimeEncoding('application/json');
JResponse::setHeader('Content-Disposition','attachment;filename="result.json"');
echo json_encode($data);
}
}
my javascript:
$.getJSON( "http://mediastore.dev/index.php?option=com_mediastore&task=getJson", function(data) {
console.log(data);
});
but the getJSON fails.
What's wrong ?
Thanks
Your controller code will throw PHP errors. It has to look like:
public function getJson() {
$model = $this->getModel();
$data = $model->getItems();
$document = JFactory::getDocument();
$document->setMimeEncoding('application/json');
echo json_encode($data);
JFactory::getApplication()->close();
}
Try to put the controller action to lowercase. I would also replace the $ with jQuery in your ajax call.
To see what is actually in the response of the ajax call I suggest to use firebug or the chrome developer console which will display the whole response and then you will find out very quick where the problem is.