How to create category in Disqus - php

I need to creating some categories in Disqus. I tried to do it by Javascript but it cannot do because require POST request but JSONP only work with GET request. After that, I tried to use CURL in server-side, there are my code
public function createDisqusCategory($title, $forum)
{
$access_token = ACCESS_TOKEN;
$secret_key = SECRET_KEY;
$public_key = PUBLIC_KEY;
$url = 'https://disqus.com/api/3.0/categories/create.json';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER,array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "access_token=$access_token&api_secret=$secret_key&api_key=$public_key&forum=$forum&title=$title");
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
and it response {"code": 22, "response": "You do not have admin privileges on forum '...'"}
How can I solve this problem?

Does your application have Default access set to "Read, write and manage forums"? If not, you'll either need to add a "scope" parameter to your POSTFIELDS, or set default access to manage forums in your application settings. Here's our documentation on scopes: http://disqus.com/api/docs/permissions/
On another note, categories in Disqus are limited to use with the API, so it's not useful in any way unless you're querying comments/threads using a custom script. If you are, I'd also advise keeping it to about 5 categories maximum, or else it can really slow down queries.

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.

PHP Curl Reuse Optimization

So currently I am working with a REST API provided by a third party tool that requires me to make thousands of requests per run of my script.
For the most part, everything works well the only issue is that it takes some time. Now that the logic is finished and complete, I am looking to improve the performance of the script by playing with the CURL requests.
Some notes:
Using a third party app (like POSTMAN) I get a faster response on
average per request ~ 600ms(POSTMAN) vs 1300ms(PHP Curl). I was kind of able to achieve this rate which means I think I have the best optimization I can get
I am currently using curl_multi in other parts of my script, but the
part I am currently targeting has one CURL request depend on the
return value of another.
These are all GET requests, I have POST,PUT,DELETE, and PATCH, but
those are used rather sparingly so the area I am targeting are the
linear GET requests.
I have done some research and for the most part everyone recommends using curl_mutli as the default, but I can't really do that as the requests are chained. I was looking at the PHP documentation and I thought about going past my basic GET request and adding some more options.
Original Code
So below is my first simplistic take, creates a new curl object, sets the request type, transfer, header, credentials, and SSL verification (Needed this to bypass the third part tool moving to a cloud instance). For the specific query I was testing this ran at about ~1460ms
(From test code below = 73sec/50runs = 1.46seconds)
function executeGET($getUrl)
{
/* Curl Options */
$ch = curl_init($this->URL . $getUrl);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_USERPWD, /*INSERT CREDENTIALS*/);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
/* Result handling and processing */
$result = curl_exec($ch);
return $result;
}
First Attempt at optimization
Next I started going through already posted stack overflow questions and the PHP documentation to look at different CURL options to see what would affect the request. The first thing I found was the IP resolve, I forced that to default to IPV4 and that sped it up by ~ 100ms. The big one however was the encoding which sped it up by about ~300ms.
(From test code below = 57sec/50runs = 1.14seconds)
function executeGET($getUrl)
{
/* Curl Options */
$ch = curl_init($this->URL . $getUrl);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_USERPWD, /*INSERT CREDENTIALS*/);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 ); //NEW
curl_setopt($ch, CURLOPT_ENCODING, ''); //NEW
/* Result handling and processing */
$result = curl_exec($ch);
return $result;
}
Re-using same curl object
The last part I decided to try was using a single curl object but just changing the URL before each request. My logic was that all the options were the same I was just querying a different endpoint. So I merged the newly discovered options for IPRESOLVE and the ENCODING along with the re-use and this is what I got in its most striped down version.
(From test code below = 32sec/50runs = 0.64seconds)
private $ch = null;
function executeREUSEGET($getUrl)
{
/* Curl Options */
if ($this->ch == null) {
$this->ch = curl_init();
curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($this->ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($this->ch, CURLOPT_USERPWD, /*INSERT CREDENTIALS*/);
curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, false); //Needed to bypass SSL for multi calls
curl_setopt($this->ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 ); //NEW
curl_setopt($this->ch, CURLOPT_ENCODING, '');
}
curl_setopt($this->ch, CURLOPT_URL, $this->URL . $getUrl);
/* Result handling and processing */
$result = curl_exec($this->ch);
return $result;
}
Testing Code
Reuse GET taken in seconds is: 32
Normal GET(with extra options) taken in seconds is: 58
Normal GET taken in seconds is: 73
$common = new Common();
$startTime = time();
for ($x = 0; $x < 50; $x++){
$r = $common->executeREUSEGET('MY_COMPLEX_QUERY');
}
echo 'Time taken in seconds is: '.(time()-$startTime);
$startTime = time();
for ($x = 0; $x < 50; $x++){
$r = $common->executeGET('MY_COMPLEX_QUERY');
}
echo 'Reuse taken in seconds is: '.(time()-$startTime);
Conclusion
This was my thought process when going my code and trying to speed up my request to more closely match what I was receiving using POSTMAN. I was hoping to get some feedback on what I can improve on to speed up these specific GET requests or if there is even anything else I can do?
EDIT: I didn't really do much testing with the curl_multi in terms of optimization, but now that I have my default GET request down under a second, would it be better to convert those curl_multi into my executeReuseGet? The difference is when I use curl_multi I just need the data, none of it depends on previous input like my executeGets.

Reading Displaying and Filtering Woocommerce JSON data from API curl request through PHP

I am relatively new to PHP and the wonderful world of API's. To set the scenario for you, we have 12 online stores all on different domains, some on different servers, all localised to local languages etc. All of them are running Wordpress with Woocommerce 2.3.13.
I am currently trying to make a 'web app' type of dashboard that calls Woocommerce data via API and displays it in a friendly manner from all of the stores. I am using PHP/HTML to display the data, I have so far managed to get the orders count for each site without issue. However now I am looking to delve a little more in to the reporting and get some sales figures and various other bits.
To achieve the order count display I have used the following code:
<?php
$data = array();
$data_string = json_encode($data);
$username = 'ck_111111111111'; // Add your own Consumer Key here
$password = 'cs_111111111111'; // Add your own Consumer Secret here
$ch = curl_init('https://example.com/wc-api/v2/orders/count/?consumer_key='.$username.'&consumer_secret='.$password);
curl_setopt($ch, CURLOPT_USERPWD, $username . ":" . $password);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data_string))
);
$result = curl_exec($ch);
$result = json_decode($result,true);
echo $result['count'];
curl_close($ch);
?>
This displays the order count for that particular woocommerce store. No problem.
But now I would really like to get sales reports, I have tried adding in the date filters on the url, but when putting the date filter on the end of url like this
$ch = curl_init('https://tinywaist.co.uk/wc-api/v2/orders/count/sales?filter[date_min]=2015-01-18&filter[date_max]=2015-01-21?consumer_key='.$username.'&consumer_secret='.$password);
I don't get anything back at all.
I have been trying various manipulations on the above code to achieve what I need, I have searched high and low to find a solution to this. What I am really not grasping is how to call specific data from the Woocommerce API and display it on the front end as an array, orders count is as far as I have got.
I have read, re read and re read again the Woocommerce REST API docs, but just cannot seem understand how to apply what I am reading in to a curl command within the PHP.
If you need any more info to help please just ask, I am bald, but if I had hair, I would be tearing it out!
Thanks in advance!
From this tutorial it appears that date_min and date_max are not the correct filters. The tutorial says this is the correct approach for getting the orders in January 2014.
$ curl
https://www.skyverge.com/wc-api/v1/orders?filter[created_at_min]=2014-01-01&filter[created_at_max]=2014-01-31
For anyone looking for the answer to my question I will repost the CURL request I am using.
The documentation on Woocommerce REST API is pretty poor and lacking in quantity!
$data = array();
$data_string = json_encode($data);
$username = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
$password = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
$ch = curl_init('https://example.com/wc-api/v2/orders/?filter[period]=year&filter[status]=processing&consumer_key='.$username.'&consumer_secret='.$password);
curl_setopt($ch, CURLOPT_USERPWD, $username . ":" . $password);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data_string))
);
I am now having issues with parsing the JSON data coming out, but that is another story!

login to dropbox with curl ( user login )

Am trying to log in to Dropbox as a user using cURL and PHP.
$ch = curl_init();
$data = array(
't'=>'hxdlvCcN7SKKcfKCvpEO8-s2',
'lhs_type'=>'anywhere',
'login_email'=>'myemail#mail.com',
'password'=>'mypass',
'login_submit'=>1,
'remember_me'=>'on',
'login_submit_dummy'=>'Sign in'
);
// set cURL options and execute
curl_setopt($ch, CURLOPT_URL, "https://www.dropbox.com/login?lhs_type=anywhere");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS,http_build_query($data));
$request_token_response = curl_exec($ch);
var_dump($request_token_response );
I get 403 page with this text:
It seems you tried to do something we can't verify. Did you log into a different Dropbox account in a different window? Try clicking here to go back to the page you came from, or just go home.
What am I doing wrong?
It is possible, and there's a current class available to make it easy. https://github.com/jakajancar/DropboxUploader/
It's as easy as
require 'DropboxUploader.php';
$uploader = new DropboxUploader('email#address.com', 'password');
The $uploader->loggedin will return if you are logged in or not.
I think you'll find that the 't' value can only be used once. You need to call for a fresh one each time you go to log in.
If you look at the class suggested in the other post, you will see that it does just that.

To get around the ajax 'same origin policy', code for a PHP ajax request forwarder?

I want to bypass the ajax same-origin policy by having a php page on my site that basically acts like a JSON proxy. Eg i make an ajax request like this:
mysite.com/myproxy.php?url=blah.com/api.json&a=1&b=2
It then makes a request to:
blah.com/api.json?a=1&b=2
And returns the JSON (or whatever) result to the original requester.
Now i assume i'd be stupidly reinventing the wheel if i wrote this php code (plus i don't know php!) - is there some pre-existing code to do this? I'm sure i'm not the only one who's butted my head up against the same-origin policy before.
Oh yeah JSONP isn't an option for this particular api.
Thanks all
Okay, here's something -
Slap this into a php script, call it like this
script.php?url=blah
post the contents you want posted to the server.
<?php
$curlPost = http_build_query($_POST);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $_GET['url']);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);
$data = curl_exec($ch);
curl_close($ch);
echo json_encode($data);
?>
Now this script is a bit too open for my liking, so to increase security I would recommend that you add a list of domains to a white list.
So add this to the top:
$whitelist = array('http://www.google.com','http://www.ajax.com');
$list = array();
foreach($whitelist as $w)
$list[] = parse_url($w,PHP_URL_HOST);
$url = $_GET['url'];
$url = pathinfo($url,PHP_URL_HOST);
if(!in_array($url, $list)) die('no access to that domain');

Categories