I'm trying to make Youtube v3 Data API work on my website.
I shamelessly copied this code from google's code samples, and it is not working. The error message showed is this:
An client error occurred: All cacheable requests must have creation dates.
I previously had issues with API keys as I forgot almost everything about APIs in general and I just thought this sample would have been useful to remember things. I managed to generate the appropriate key and now I know for sure it isn't the real problem.
Sadly Google didn't find posts related to this issue, except two links to the actual Php Library that I implemented in my site to make everything work. By looking at it closely I noticed a developer comment that could be useful.
$rawDate = $resp->getResponseHeader('date');
$parsedDate = strtotime($rawDate);
if (empty($rawDate) || false == $parsedDate) {
// We can't default this to now, as that means future cache reads
// will always pass with the logic below, so we will require a
// date be injected if not supplied.
throw new Google_Exception("All cacheable requests must have creation dates.");
}
I can understand english pretty well but I really don't know what to do now.
I even tried to add some sort of date in the request in my code, but it isn't working (you can laugh):
// Call the search.list method to retrieve results matching the specified
// query term.
$searchResponse = $youtube->search->listSearch('id,snippet', array(
'q' => $_GET['q'],
'maxResults' => $_GET['maxResults'],
'date' => strtotime(),
));
An client error occurred: (list) unknown parameter: 'date'
Any tips? Thank you in advance
EDIT: I know, this PHP library is currently in beta, but there must be some workaround.
EDIT 2: I found a temporary work around. I inverted the logic gate of that 'if' in the Php Library and now it works. But I don't like doing this, and I won't mark this as solved. At least if you know the reason of the bug please explain it to me, I'm really interested.
Related
I am trying to make a test transaction using my Laravel 7 app and Authorize.net.
After submitting the sample data, I'm getting:
The element 'createTransactionRequest' in namespace 'AnetApi/xml/v1/schema/AnetApiSchema.xsd' has invalid child element 'clientId' in namespace 'AnetApi/xml/v1/schema/AnetApiSchema.xsd'. List of possible elements expected: 'merchantAuthentication' in namespace 'AnetApi/xml/v1/schema/AnetApiSchema.xsd'.
Anyone know what's causing this error or how to fix it?
Well, I'll answer my own question since it might help others. The problem is the error message in the Authorize.net response is really vague.
Kurt Friars' comment was helpful, since it pointed me in the right direction. As for Mansour Hamcherif's suggestion, the merchantAuthentication object was set in my app, it just didn't have the right values, so it wasn't that.
The solution for me was setting the proper values to setName() and setTransactionKey(). The previous developer who had worked on this project had left values and the credentials had expired. I did a Linux text search for "setTransactionKey", which lead me to the correct PHP file where I need to set:
$merchantAuthentication = new AnetAPI\MerchantAuthenticationType();
$merchantAuthentication->setName('EnterYourLoginNameHere');
$merchantAuthentication->setTransactionKey('EnterYourTransactionKey');
After that, I cleared all of my Laravel app's caches as well as my browser's caches, did a hard reload, tried a transaction again and it worked! I got:
This transaction has been approved., Transaction ID: **********.
You may want to check the log for the raw request, it's likely the merchantAuthentication object has not been set, if you are using the PHP SDK I recommend checking the SimpleCodeConstants.php file and make sure your merchant credentials constants are set.
For example, if I set my merchant credentials to NULL, I get the same E00003 error as a result of sending the following raw request:
{"createTransactionRequest":{"merchantAuthentication":[],"clientId":"sdk-php-2.0.0-ALPHA", ...}
I'm a bit confused about how errors are handled in Wordpress's REST API. In their examples, they suggest using WP_Error to return errors, but WP_REST_Response has the HTTP status code as a second parameter, which makes it shorter and somewhat cleaner to my taste.
So I'm comparing this way of returning an error:
return new WP_REST_Response(array('error' => 'Error message.'), 400);
With this one:
return new WP_Error('rest_custom_error', 'Error message.', array('status' => 400));
With the first option, I can have just the error text in my response and it's enough for me. So the response would look like so:
{"error":"Error message."}
With the second one it's more detailed:
{"code":"rest_custom_error","message":"Error message.","data":{"status":403}}
But I also need to specify the error code (first parameter), which doesn't give any advantage to my front-end implementation. Other than the syntax, I'm curious about differences in performance, security and future-proof factors.
So is there any reason to prefer one over the other than personal preferences?
I do as follows:
WP_REST_Response // Used when endpoint code runs just fine but needs to
// tell the client about some other downstream error (e.g. 4xx)
WP_Error // Used when endpoint code has an issue and needs to tell you
// it didn't compute or couldn't find resources etc (e.g. 5xx)
As far as I can tell, WordPress changes the status codes of the responses in unpredictable ways. This is dumb. For instance, if you create a WP_REST_RESPONSE with status 400, it actually sends it as status 200 with "status:400" as data in the body.
What I do:
Just use PHP response functions:
http_response_code(400);
exit;
If you tell me I'm wrong, please explain the benefit of using these two function wrappers. I see the benefit if you work for Automattic and are creating regressions in core itself. If you're a plugin or theme dev, [and you're assuming core works] these functions should be avoided as having no use.
So I'm building this small REST API for a part of a website so I can load comments asynchronously, after the main content has loaded. But every time my dataset goes above 25 entries the variable where I store the comments becomes completely inaccessible.
This is exactly the database find operation I'm doing:
// A nice default before responding
$response = array('status'=>'error','message'=>'Request incomplete');
// [...] Some validation stuff
// $response is perfectly accessible here
$response = $this->Comment->find(
'threaded',
array(
'conditions' => array(
'Comment.object_class' => $query['object_class'],
'Comment.object_id' => $query['object_id'] ,
'Comment.status' => 'approved'
),
'order' => 'Comment.created ASC'
// No limits, I need all the comments
)
);
// $response is not accessible anymore
// So my JSON response below comes absolutely empty;
$this->set('response',$response);
$this->set('_serialize',array('response'));
By the time I use $this->set('_serialize',array('response')); to be able to send the JSON response the $comments variable is still inaccessible, so my response comes back empty, at 0 length, which of course is pretty bothersome and very confusing.
I've experienced this problem before and have found that it solves by requesting a limited set of entries, but in this case I need the entire comment list, don't wanna do several requests and kill the purpose. Is there a limit to what Cake can retrieve from the database and keep usable in the Controllers? Am I missing something here?
I also tried "manually " doing a json_encode($response); but since the problem is that the $response var is inaccessible/empty then of course it fails as well.
The json response does work for some 25 comments or less, but many of the website entries have more comments than that, up to 100 comments! How can I solve this weird issue?
So after souting the Internet in search of a concrete answer and ending up in the #cakephp IRC channel, a very kind fellow suggested my data may have some encoding mistakes.
Turns out he was correct about it, and the comments table still had some comments that were encoded as latin1. Back in the day I moved the database to utf8, but it was just a charset change, not an actual text encoding conversion for every entry.
After a quick search I found this post which instructs you about how to move loads of data from latin1 to utf8 with three simple cli lines.
I hope this serves someone else that may encouter this issue and doesn't know what to do about it :)
Thanks to those who commented on the question.
I've read up on the Core Reporting docs, I've gone through different tutorials, and none of this makes sense.
Just from the point of trying to replicate demos, I'm still lost. The simple, SIMPLE demo I'm working with asks for this 0Auth 2.0 info:
// $client->setClientId('insert_your_oauth2_client_id');
// $client->setClientSecret('insert_your_oauth2_client_secret');
// $client->setRedirectUri('insert_your_oauth2_redirect_uri');
// $client->setDeveloperKey('insert_your_developer_key');
The JSON file I downloaded from https://code.google.com/apis/console?api=analytics, supplies some of that info:
{
"web":{
"auth_uri":"https://accounts.google.com/o/oauth2/auth",
"token_uri":"https://accounts.google.com/o/oauth2/token",
"client_email":"*********#developer.gserviceaccount.com",
"redirect_uris":["https://www.**********.com/oauth2callback"],
"client_x509_cert_url":"https://www.googleapis.com/robot/v1/metadata/x509/**********#developer.gserviceaccount.com",
"client_id":"**********.apps.googleusercontent.com",
"auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs",
"javascript_origins":["https://www.**********.com"]
}
}
CliendId and RedirectUri, got it, no prob. ClientSecret and DeveloperKey? I don't even see those listed ANYWHERE. I assume it could mean the Public and Private keys that you download, but even then, I have no idea how to access the PKCS #12 file or whatever that is.
I am hopelessly lost and the google documentation just keeps pulling me around in circles and never mentions what these pieces are and how to get them.
I didn't do anything to fix this. It just started working one day. I assume it was some kind of bug with Google's API that they got around to fixing, but I never found any other instances of the bug in other forums or help sites.
I'm using the Zend framework and the openid selector from http://code.google.com/p/openid-selector/ - however I find I can't login using sites like Google and Yahoo as they use direct identity based login system whereby one is just redirected to a url as opposed to entering a unique url of their own for authentication.
I've checked out many options and hacks but none of them seem to work. How can i get this to work here btw - how is it implemented at stack overflow? I could really use all the help here guys..
Edit
Well the issue here is that from what I have noticed is that the Zend OpenID class doesn't support OpenID 2.0 the thing is that a typical open ID providor gives you a unique url such as your-name.openid-providor.com or openid-providor.com/your-name and the Zend OpenId class just parses through that url and then redirects you to the providor website where upon authentication you are redirected back.
In the case of Yahoo and google - you don't enter a unique url instead you are redirected to the providors login site and upon login and authentication you are redirected back - so basically whats happeining is that the zend_openID object when it parses to tell who the providor is it fails to tell from the general url itself. Like when you click on teh Google link it redirects you to https://www.google.com/accounts/o8/id
Its more an issue with the zend openid object here and there isn't any help on zend related forums - so I was wondering if someone had already hacked or had an alteration I could make to the class to accomplish this. Sorry if I'm missing something but I'm kinda new to this and programming with open ID and have just started to get my feet wet.
Thanks for the follow up - I did check into RPX a while back and they do have a php class but I wasnt able to check it out plus I really just want to for now get the code selector used as on stackoverflow to work with Yahoo and Google authentication. There has to be some kind of way to tweak the parsing which the Zend OpenID class uses as it runs a series of regular expression checks to make a discovery.
Little late to the game but I was able to get this working with some hacks I found around the interwebs.
First. Yahoo. To get Yahoo working all I had to do was change the JavaScript to use me.yahoo.com instead of just yahoo.com and it worked perfectly with the version of the Zend Framework I'm using. Unfortunately Google still wasn't, so some hacking was in order.
All of these changes go in Zend/OpenId/Consumer.php
First, in the _discovery method add the following on the series of preg_match checks that starts at around line 740.
} else if (preg_match('/<URI>([^<]+)<\/URI>/i', $response, $r)) {
$version = 2.0;
$server = $r[1];
I added this right before the return false; statement that's in the else {} block.
Second, in the _checkId method you'll need to add 3 new blocks (I haven't dug around enough to know what causes each of these three cases to be called, so I covered all to be on the safe side.
Inside the $version <= 2.0 block, you'll find an if/else if/else block. In the first if statement ($this->_session !== null) add this to the end:
if ($server == 'https://www.google.com/accounts/o8/ud') {
$this->_session->identity = 'http://specs.openid.net/auth/2.0/identifier_select';
$this->_session->claimed_id = 'http://specs.openid.net/auth/2.0/identifier_select';
}
In the else if (defined('SID') block add this to the end:
if ($server == 'https://www.google.com/accounts/o8/ud') {
$_SESSION['zend_openid']['identity'] = 'http://specs.openid.net/auth/2.0/identifier_select';
$_SESSION['zend_openid']['claimed_id'] = 'http://specs.openid.net/auth/2.0/identifier_select';
}
And then after the else block (so outside the if/else if/else block all together, but still inside the $version <= 2.0 block) add this:
if ($server == 'https://www.google.com/accounts/o8/ud') {
$params['openid.identity'] = 'http://specs.openid.net/auth/2.0/identifier_select';
$params['openid.claimed_id'] = 'http://specs.openid.net/auth/2.0/identifier_select';
}
Link to the bug in Zend Framework Issue Tracker
I need to use Google's OpenID stuff, and I tried Steven's code and couldn't get it to work as-is. I've made some modifications.
The _discovery change method is still the same:
Zend/OpenId/Consumer.php, line 765, add:
} else if (preg_match('/<URI>([^<]+)<\/URI>/i', $response, $r)) {
$version = 2.0;
$server = $r[1];
The rest is different, though:
Zend/OpenId/Consumer.php, line 859 (after making the above change), add:
if (stristr($server, 'https://www.google.com/') !== false) {
$id = 'http://specs.openid.net/auth/2.0/identifier_select';
$claimedId = 'http://specs.openid.net/auth/2.0/identifier_select';
}
This is right before:
$params['openid.identity'] = $id;
$params['openid.claimed_id'] = $claimedId;
And to get it to return the ID, once authorized:
Zend/Auth/Adapter/OpenId.php, line 278:
if(isset($_REQUEST['openid_identity']))
{
$this->_id = $_REQUEST['openid_identity'];
$id = $this->_id;
}
This is right before:
return new Zend_Auth_Result(
Zend_Auth_Result::SUCCESS,
$id,
array("Authentication successful"));
Note that I have not thoroughly tested this code. The code below is even more shakey.
I have spent more time and I've gotten it to work with my Google Apps domain with the following changes, in addition to the above:
Zend/OpenId/Consumer.php, line 734
$discovery_url = $id;
if(strpos($discovery_url, '/', strpos($discovery_url, '//')+2) !== false) {
$discovery_url = substr($discovery_url, 0, strpos($discovery_url, '/', strpos($discovery_url, '//')+2));
}
$discovery_url .= '/.well-known/host-meta';
$response = $this->_httpRequest($discovery_url, 'GET', array(), $status);
if ($status === 200 && is_string($response)) {
if (preg_match('/Link: <([^><]+)>/i', $response, $r)) {
$id = $r[1];
}
}
This is right after:
/* TODO: OpenID 2.0 (7.3) XRI and Yadis discovery */
I believe that was the only change I had to make. I'm pretty sure there's supposed to be some checking involved with the above for security reasons, but I haven't looked far enough into it to see what they would be.
Going over all the advice provided - I've decided to ditch using the zend_openid class [ sorry about that zend ] and instead I've switched to using JanRains OpenID library. Its taken a few hours to get it up and running with my project but atleast its working like a breeze. Had to make a lot of hacking and a bit of code spill over to get it working but its worth it.
I couldn't use any of Zend adapters with Zend-Auth to settle this new code library in as the library did the authentication on its own. SO I hacked and made a generic adapter that just returned a filled zend_result set to the Auth object thus I authenticate using my library and merely store the result in the Auth object pulling a bit of a fast one one the Zend-Auth object rather than have to rewrite my code again.
The library is available at http://openidenabled.com/php-openid/
Thanks for all the help guys.
I'm dealing with similar issues. I'm planning on using RPX now with Zend Framework. Maybe I'll write an adapter. Just to let you know.
Info: 'RPS now' provides an all-in-one interface and UI for user registration with
facebook
Google
Yahoo
mySpaceID
Windows LiveID
OpenID
aol
I'm pretty sure that Yahoo only works with OpenID 2.0. If you want to support Yahoo users, you're going to have to upgrade to a library with 2.0 support. That's going to be a matter of more than tweaking some parsing.
Did you check out the manual -- Zend_OpenId_Consumer basics? Check out 38.2.2 on that page and let me know if this helps, because it should.
Specifically, I don't know if Google offers OpenID. I know that Yahoo worked because I've tried it a while back.
Thanks for the information. I started by using JanRain's library, but I have problems with getting Simple Registration to work: I have not succeeded in getting any data that way. And there is no documentation on using Attribute Exchange. :(
So, I found and was trying Zend/OpenId, but had the same problem as you: no Yahoo!, Google and who knows what else support. Reading this, it seems I'll have to get back to JanRain; RPX is not an option in my case as it's a third party service.