How do you use curl within wordpress plugins? - php

I'm creating a wordpress plugin and I'm having trouble getting a cURL call to function correctly.
Lets say I have a page www.domain.com/wp-admin/admin.php?page=orders
Within the orders page I have a function that looks to see if a button was clicked and if so it needs to do a cURL call to the same page (www.domain.com/wp-admin/admin.php?page=orders&dosomething=true) to kick off a different function. The reason I'm doing it this way is so I can have this cURL call be async.
I'm not getting any errors, but I'm also not getting any response back. If I change my url to google.com or example.com I will get a response. Is there an authentication issue or something of that nature possibly?
My code looks something like this.. I'm using gets, echos, and not doing async just for the ease of testing.
if(isset($_POST['somebutton']))
{
curlRequest("http://www.domain.com/wp-admin/admin.php?page=orders&dosomething=true");
}
if($_GET['dosomething'] == "true")
{
echo("do something");
exit;
}
function curlRequest($url) {
$ch=curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($ch);
return($response);
}

You're not supposed to use CURL in WordPress Plugins.
Instead use the wp_ function for issuing HTTP requests, e.g.
function wp_plugin_event_handler () {
$url = 'http://your-end-point';
$foo = 'bar';
$post_data = array(
'email' => urlencode($foo));
$result = wp_remote_post( $url, array( 'body' => $post_data ) );
}
add_action("wp_plugin_event", "wp_plugin_event_handler");
In the past I've run into issues where WordPress plugins event handlers would hang with CURL. Using the WP_ functions instead worked as expected.

The admin section of the blog is password-protected, of course. You'll need to pass authentication data. Look up http authentication for details. Look specifically here:
http://www.php.net/manual/en/function.curl-setopt.php
You'll want to set the CURLOPT_USERPWD option and possibly CURLOPT_HTTPAUTH.

Related

send a pageview event via Measurement Protocol to a GA4 property

How can I send a pageview event via Measurement Protocol to a GA4 property with PHP?
This is how I'm doing, but inside my Google Analytics 4 property I can't see any traffic.
$data = array(
'api_secret' => 'XXXX-YYYYY',
'measurement_id' => 'G-12345678',
'client_id' => gen_uuid(), // generates a random id
'events' => array(
'name' => 'page_view',
'params' => array(),
)
);
$url = 'https://www.google-analytics.com/mp/collect';
$content = http_build_query($data);
$content = utf8_encode($content);
$ch = curl_init();
curl_setopt($ch,CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_HTTPHEADER,array('Content-type: application/x-www-form-urlencoded'));
curl_setopt($ch,CURLOPT_HTTP_VERSION,CURL_HTTP_VERSION_1_1);
curl_setopt($ch,CURLOPT_POST, TRUE);
curl_setopt($ch,CURLOPT_POSTFIELDS, $content);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_exec($ch);
curl_close($ch);
I'm working on registering pageviews to track API usage right now, here's what I've found:
XTOTHEL is right about setting the content type to content/json above. In addition to specifying the content type you also have to send JSON data as the CURLOPT_POSTFIELDS data.
Also per their specification the api_secret and measurement_id need to be part of the URI: https://developers.google.com/analytics/devguides/collection/protocol/ga4/sending-events?client_type=gtag#required_parameters
Lastly, you can use debug mode to validate your responses and figure out what's going on now by simply changing the URL to google-analytics.com/debug/mp/collect
Here's the code I'm working with right now:
//retrieve or generate GA tracking id
if (empty($_COOKIE['_cid'])) {
setcookie('_cid', vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex(random_bytes(16)), 4)));
}
$data = '{"client_id":"'.$_COOKIE['_cid'].'","events":[{"name":"load_endpoint","params":{"page_location":"'.$request->fullUrl().'"}}]}';
echo '<pre>';
print_r($data);
$measurement_id = 'G-xxxxx';
$api_secret = 'xxxx';
$url = 'https://www.google-analytics.com/debug/mp/collect?api_secret='.$api_secret.'&measurement_id='.$measurement_id;
$ch = curl_init();
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
This works to a certain extent. Currently it's registering the page view as a custom event instead of an actual pageview though. I'm still trying to figure out how to get them to come through as page views.
Follow up
After a little more debugging I figured out page views are actually working, they just weren't showing up in some of the views. The fix for that was to add page_title into the params:
$data = '
{
"client_id": "'.$_COOKIE['_cid'].'",
"events": [
{
"name": "page_view",
"params": {
"page_location": "'.$request->fullUrl().'",
"page_title": "'.$request->path().'"
}
}
]
}
';
A few extra notes for whoever comes next:
Debug mode did return some useful validation errors for invalid top-level parameters (client_id, events) - but it didn't return errors for anything inside of the "params" for events. IE - i put "page_asdtitle" instead of "page_title" and it accepted it just fine.
None of the tests I sent through actually showed up in the debug panel while using debug mode. I suspect this is because of the data propagation delay, it's probably not loading realtime data.
Using a JSON validator can help. Make sure you use objects and arrays where GA tells you to.
If you get stuck figuring out why your PHP code doesn't work, write the code as a browser event in JavaScript and run it in your browser. There's tons of examples on how to do that. From there, you can use Dev Tools -> Network to inspect the request. If you right click on the google analytics request to the 'collect' endpoint you'll see an option to Copy Request as CURL. Put that into a text editor and compare it to what your PHP code is sending.
To ACTUALLY test this without the massive propagation delay you can login to Google Analytics, go to Reports -> Realtime, and you should see your data show up within 30-60 seconds if it's working. Realtime data will NOT show up if you're using the /debug/ endpoint though.

Getting multiple http response codes using cURL?

Please take a look at this sample code:
function http_response($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, TRUE);
curl_setopt($ch, CURLOPT_NOBODY, TRUE); // remove body
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$head = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
echo $httpCode ;
}
this code will print the httpCode of the given url. I have couple of questions:
Can I get rid of some setopt() lines here and still getting httpCode?
What about if I want to check multiple urls at the same time? Can I modify the code to do that?
Can I do the same functionality in a simpler way using libraries different than cURL?
Thanks :)
You should be able to remove CURLOPT_HEADER and CURLOPT_NOBODY and still get the same result.
You could do that like this:
$urls = array(
'http://google.com',
'http://facebook.com'
);
$status = array();
foreach($urls as $url){
$status[$url] = http_response($url);
}
Try print_r($status); after this and you'll see the result.
You could do this with file_get_contents and $http_response_header, to learn more: http://www.php.net/manual/en/reserved.variables.httpresponseheader.php I would however recommend using cURL anyway.
*2. to check multiple urls you have to use this function in a loop, in any programming language 1 response from a server = 1 connection to that server. If you want to use 1 function to get responses from multiple servers you can always pass an array to the function and do the loop inside the function
*3. you can try this way:
function get_contents() {
file_get_contents("http://example.com");
var_dump($http_response_header);
}
get_contents();

Scraping a Webpage for Results Using PHP cURL - Post Not Working

I'm new to using cURL, but from what I have read, the following should post the variables to the page, then print the result. The result prints, but it doesn't seem like the POST variables went because no results are generated. FireBug doesn't show anything going either. Any ideas what I'm doing wrong?
Thanks for your help!
// create curl resource
$ch = curl_init();
// set url
curl_setopt($ch, CURLOPT_URL, "http://butlercountyclerk.org/bcc-11112005/ForeclosureSearch.aspx");
$data = array(
'Search:btnSearch' => 'Search',
'Search:ddlMonth' => '1',
'Search:ddlYear' => '2011'
);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
//return the transfer as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// $output contains the output string
$output = curl_exec($ch);
// close curl resource to free up system resources
curl_close($ch);
echo $output;
Based on the coding of the site, it appears that you're missing a number of variables. Take for example, the actual post request made to the search page:
__VIEWSTATE=dDwtMjk2Mjk5NzczO3Q8O2w8aTwxPjs+O2w8dDw7bDxpPDE+Oz47bDx0PDtsPGk8Mz47aTwxOT47PjtsPHQ8dDw7cDxsPGk8MD47aTwxPjtpPDI+O2k8Mz47aTw0PjtpPDU+Oz47bDxwPDIwMDY7MjAwNj47cDwyMDA3OzIwMDc+O3A8MjAwODsyMDA4PjtwPDIwMDk7MjAwOT47cDwyMDEwOzIwMTA+O3A8MjAxMTsyMDExPjs+Pjs+Ozs+O3Q8QDA8Ozs7Ozs7Ozs7Oz47Oz47Pj47Pj47Pj47PmVlaXw5JK161vti9TC+QMdeTNQI&Search:ddlMonth=1&Search:ddlYear=2011&Search:txtCompanyName=&Search:txtLastName=&Search:txtCaseNumber=&Search:btnSearch=Search
This is post-feeding though URLDecode by the way. What this means though, is that your array of 3 values is missing data. At the very least, I'd suspect that Search:btnSearch=Search is missing, and would suggest that you implement all fields into your POST request.

How to integrate a symfony website with whmcs

I'm trying to find a way to integrate my website, coded using Symfony with my billing system, WHMCS.
The first thing I tried was creating a new symfony module called whmcs and in that module, I was using ob_start/require_once/ob_get_contents to retreive the page but it kept resulting in a blank page, without any error in the logs or anywhere else. Since this was going to be a navigation nightmare anyway, I gave up on that idea.
My second idea was to take advantage of the WHMCS hooks system. So far, it worked except for one thing. I have no idea how to call my layout.php file. Here is my current code:
function getSymfonyLayout()
{
require_once($_SERVER['DOCUMENT_ROOT'].'/../config/ProjectConfiguration.class.php');
$configuration = ProjectConfiguration::getApplicationConfiguration('frontend', 'prod', true);
$context = sfContext::createInstance($configuration);
$context->getRequest()->setRelativeUrlRoot('');
$context->getInstance()->getConfiguration()->loadHelpers('Partial');
echo get_partial("global/header");
}
add_hook("ClientAreaPage",1,"getSymfonyLayout");
My issue here is that, while the header does load, there is no meta, no css, no javascript. Those settings are saved in my view.yml file and partials don't load that file.
I need to find a way to do something like echo get_layout("layout"); or echo get_methodaction("whmcs", "index");
It's probably something silly but I've been going thru wikis, forums and my symfony book and I just can't find the code I need to use.
Try to use curl
$url = 'your symfony url';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $query_string);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$data = curl_exec($ch);
echo $data;
The code above sends a curl request to the url $url
$query_string is the data you are going to post to the page if needed
$query_string = "";
foreach ($postfields AS $k => $v)
$query_string .= "$k=" . urlencode($v) . "&";
$query_string = trim($query_string, '&');
where $postfields is an array of the parameters to send
Additionally you can send a cross domain ajax request (if you're using jQuery you just set the $.ajax option dataType to jsonp) and that would load only the content part of the action (stylesheets and javascripts are not included)
In your action method, use:
$output = $this->getController()->getPresentationFor("module", "action");
This will render the output of the specified module and action into $output; see http://www.symfony-project.org/api/1_2/sfController#method_getpresentationfor for details

Post to another page within a PHP script

How can I make a post request to a different php page within a php script? I have one front end computer as the html page server, but when the user clicks a button, I want a backend server to do the processing and then send the information back to the front end server to show the user. I was saying that I can have a php page on the back end computer and it will send the information back to the front end. So once again, how can I do a POST request to another php page, from a php page?
Possibly the easiest way to make PHP perform a POST request is to use cURL, either as an extension or simply shelling out to another process. Here's a post sample:
// where are we posting to?
$url = 'http://foo.com/script.php';
// what post fields?
$fields = array(
'field1' => $field1,
'field2' => $field2,
);
// build the urlencoded data
$postvars = http_build_query($fields);
// open connection
$ch = curl_init();
// set the url, number of POST vars, POST data
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, count($fields));
curl_setopt($ch, CURLOPT_POSTFIELDS, $postvars);
// execute post
$result = curl_exec($ch);
// close connection
curl_close($ch);
Also check out Zend_Http set of classes in the Zend framework, which provides a pretty capable HTTP client written directly in PHP (no extensions required).
2014 EDIT - well, it's been a while since I wrote that. These days it's worth checking Guzzle which again can work with or without the curl extension.
Assuming your php install has the CURL extension, it is probably the easiest way (and most complete, if you wish).
Sample snippet:
//set POST variables
$url = 'http://domain.com/get-post.php';
$fields = array(
'lname'=>urlencode($last_name),
'fname'=>urlencode($first_name),
'email'=>urlencode($email)
);
//url-ify the data for the POST
foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
rtrim($fields_string,'&');
//open connection
$ch = curl_init();
//set the url, number of POST vars, POST data
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, count($fields));
curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);
//execute post
$result = curl_exec($ch);
//close connection
curl_close($ch);
Credits go to http://php.dzone.com.
Also, don't forget to visit the appropriate page(s) in the PHP Manual
index.php
$url = 'http://[host]/test.php';
$json = json_encode(['name' => 'Jhonn', 'phone' => '128000000000']);
$options = ['http' => [
'method' => 'POST',
'header' => 'Content-type:application/json',
'content' => $json
]];
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
test.php
$raw = file_get_contents('php://input');
$data = json_decode($raw, true);
echo $data['name']; // Jhonn
For PHP processing, look into cURL. It will allow you to call pages on your back end and retrieve data from it. Basically you would do something like this:
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_URL,$fetch_url);
curl_setopt ($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt ($ch,CURLOPT_USERAGENT, $user_agent;
curl_setopt ($ch,CURLOPT_CONNECTTIMEOUT,60);
$response = curl_exec ( $ch );
curl_close($ch);
You can also look into the PHP HTTP Extension.
Like the rest of the users say it is easiest to do this with CURL.
If curl isn't available for you then maybe
http://netevil.org/blog/2006/nov/http-post-from-php-without-curl
If that isn't possible you could write sockets yourself
http://petewarden.typepad.com/searchbrowser/2008/06/how-to-post-an.html
For those using cURL, note that CURLOPT_POST option is taken as a boolean value, so there's actually no need to set it to the number of fields you are POSTing.
Setting CURLOPT_POST to TRUE (i.e. any integer except zero) will just tell cURL to encode the data as application/x-www-form-urlencoded, although I bet this is not strictly necessary when you're passing a urlencoded string as CURLOPT_POSTFIELDS, since cURL should already tell the encoding by the type of the value (string vs array) which this latter option is set to.
Also note that, since PHP 5, you can use the http_build_query function to make PHP urlencode the fields array for you, like this:
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($fields));
Solution is in target="_blank" like this:
http://www.ozzu.com/website-design-forum/multiple-form-submit-actions-t25024.html
edit form like this:
<form method="post" action="../booking/step1.php" onsubmit="doubleSubmit(this)">
And use this script:
<script type="text/javascript">
<!--
function doubleSubmit(f)
{
// submit to action in form
f.submit();
// set second action and submit
f.target="_blank";
f.action="../booking/vytvor.php";
f.submit();
return false;
}
//-->
</script>
Although not ideal, if the cURL option doesn't do it for you, may be try using shell_exec();
CURL method is very popular so yes it is good to use it. You could also explain more those codes with some extra comments because starters could understand them.

Categories