Reputation: 63
I have used Zend Gdata for several years now.
However, today when my unchanged code executes the following command
$query = $this->gp->newAlbumQuery();
I receive the following error
exception 'Zend_Gdata_App_HttpException' with message 'Expected response code 200, got 403 Authorization required' in /shared/zend/ZendFramework-1.12.13/library/Zend/Gdata/App.php:717 Stack trace: #0 /shared/zend/ZendFramework-1.12.13/library/Zend/Gdata.php(221): Zend_Gdata_App->performHttpRequest('GET', 'https://picasaw...', Array, NULL, NULL, NULL) #1 /shared/zend/ZendFramework-1.12.13/library/Zend/Gdata/App.php(883): Zend_Gdata->performHttpRequest('GET', 'https://picasaw...', Array)
I thought it would be because authentication had failed. I checked and my credentials are all fine and the following authenticates successfully without an exception
$client = Zend_Gdata_ClientLogin::getHttpClient($this->config['username'],
$this->config['password'],
Zend_Gdata_Photos::AUTH_SERVICE_NAME);
I saw that Zend Gdata is still on version 1.12.13. However there is a recent release date of 20/05/2015. So i did an update using this new release. But the error is still the same.
So all i know is that i am authenticated, but the newAlbumQuery
method is raising the above exception.
Is anyone else experiencing this problem with Zend Gdata? Has anyone found a fix or workaround?
Upvotes: 3
Views: 1915
Reputation: 66
In the end I'm ending with something like this(very raw code so far, but enought for those who's seaching for solution. You need php google spreadsheet client of https://github.com/asimlqt/php-google-spreadsheet-client). Thats tiny example of inserting one row to my spreadsheet (sorry about my code, but showing just working example) Thanks for bram brambring showing better way to authorization - answer by bram brambring
<?php
/*
* Google Spreadsheet class to work with google spreadsheets obviously ;D [using OAuth 2.0, as Zend Gdata is not anymore working]
*/
require_once('/Google/Spreadsheet/ServiceRequestInterface.php');
require_once('/Google/Spreadsheet/DefaultServiceRequest.php');
require_once('/Google/Spreadsheet/ServiceRequestFactory.php');
require_once('/Google/Spreadsheet/Spreadsheet.php');
require_once('/Google/Spreadsheet/SpreadsheetFeed.php');
require_once('/Google/Spreadsheet/SpreadsheetService.php');
require_once('/Google/Spreadsheet/Exception.php');
require_once('/Google/Spreadsheet/UnauthorizedException.php');
require_once('/Google/Spreadsheet/Spreadsheet.php');
require_once('/Google/Spreadsheet/Util.php');
require_once('/Google/Spreadsheet/Worksheet.php');
require_once('/Google/Spreadsheet/WorksheetFeed.php');
require_once('/Google/Spreadsheet/ListFeed.php');
require_once('/Google/Spreadsheet/ListEntry.php');
require_once('/Google/Spreadsheet/CellFeed.php');
require_once('/Google/Spreadsheet/CellEntry.php');
require_once('/Google/Config.php');
require_once('/Google/Client.php');
require_once('/Google/Auth/Abstract.php');
require_once('/Google/Auth/OAuth2.php');
require_once('/Google/Http/Request.php');
require_once('/Google/Utils.php');
require_once('/Google/IO/Abstract.php');
require_once('/Google/IO/Curl.php');
require_once('/Google/Http/CacheParser.php');
require_once('/Google/Logger/Abstract.php');
require_once('/Google/Logger/Null.php');
require_once('/Google/Exception.php');
require_once('/Google/Auth/Exception.php');
require_once('/Google/Auth/AssertionCredentials.php');
require_once('/Google/Cache/Abstract.php');
require_once('/Google/Cache/File.php');
require_once('/Google/Signer/Abstract.php');
require_once('/Google/Signer/P12.php');
use Google\Spreadsheet\DefaultServiceRequest;
use Google\Spreadsheet\ServiceRequestFactory;
class Google_Spreadsheet
{
private $default = array(
'worksheetCols' => 12,
'worksheetRows' => 25
);
private $spreadsheetKey;
private $spreadsheetName;
private $worksheetName;
private $spreadsheetFeed;
public $initialized = true;
public function __construct($spreadsheetKey, $worksheetName, $spreadsheetName = '')
{
$this->spreadsheetKey = $spreadsheetKey;
$this->worksheetName = $worksheetName;
$this->spreadsheetName = $spreadsheetName;
$this->initialized = $this->initialize();
return true;
}
private function getToken() {
$client_email = '318977712937456456454656563tcfjblgoi@developer.gserviceaccount.com';
$private_key = file_get_contents('API Project-f10e456456b60.p12');
$scopes = array('https://spreadsheets.google.com/feeds');
$credentials = new Google_Auth_AssertionCredentials(
$client_email,
$scopes,
$private_key,
'notasecret', // Default P12 password
'http://oauth.net/grant_type/jwt/1.0/bearer' // Default grant type
);
$client = new Google_Client();
$client->setAssertionCredentials($credentials);
if ($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion();
}
$tokenData = json_decode($client->getAccessToken());
return $tokenData->access_token;
}
public function initialize(/*$reInitialized = false*/)
{
// load OAuth2 token data - exit if false
$tokenData = $this->getToken();
$serviceRequest = new DefaultServiceRequest($tokenData);
ServiceRequestFactory::setInstance($serviceRequest);
$spreadsheetService = new Google\Spreadsheet\SpreadsheetService();
try {
$spreadsheetFeed = $spreadsheetService->getSpreadsheets();
} catch (\Google\Spreadsheet\UnauthorizedException $e) {
Google_Spreadsheet::warnAdmin($e->getMessage());
return false;
}
$this->spreadsheetFeed = $spreadsheetFeed;
return true;
}
public function insertRow($rowData, $default_fields = array()) {
$spreadsheetFeed = $this->spreadsheetFeed;
$spreadsheet = $this->spreadsheetKey ? $spreadsheetFeed->getByKey($this->spreadsheetKey) : $spreadsheetFeed->getByTitle($this->spreadsheetName);
if(!$spreadsheet && !empty($this->spreadsheetName)) {
$spreadsheet = $spreadsheetFeed->getByTitle($this->spreadsheetName);
}
if(!$spreadsheet) {
Google_Spreadsheet::warnAdmin('No spreadsheet', serialize($rowData));
return false;
}
$worksheetFeed = $spreadsheet->getWorksheets();
$worksheet = $worksheetFeed->getByTitle($this->worksheetName);
if(!$worksheet) {
//create worksheet if not exist
$worksheet = $spreadsheet->addWorksheet($this->worksheetName, $this->default['worksheetRows'], $this->default['worksheetCols']);
$cellFeed = $worksheet->getCellFeed();
for( $i= 1 ; $i <= $this->default['worksheetCols']; $i++ ) {
if(isset($default_fields[$i])) {
$cellFeed->editCell(1, $i, $default_fields[$i]);
}
else {
$cellFeed->editCell(1, $i, "head");
}
$cellFeed->editCell(2,$i,"content");
}
}
if(!$worksheet) {
Google_Spreadsheet::warnAdmin('No worksheet', serialize($rowData));
return false;
}
$listFeed = $worksheet->getListFeed();
$data = array();
foreach ($listFeed->getEntries() as $entry) {
$values = $entry->getValues();
$data[] = $values;
break; //only first row needed, as we need keys
}
$keys = array();
if(!count($data)) {
Google_Spreadsheet::warnAdmin('No data', serialize($rowData));
return false;
}
foreach ($data[0] as $key => $value) {
$keys[] = $key;
}
$newRow = array();
$count = 0;
foreach($keys as $key) {
if(isset($rowData[$count])) {
$newRow["$key"] = $rowData[$count];
}
else {
$newRow["$key"] = '';
}
$count++;
}
$listFeed->insert($newRow);
return true;
}
static function warnAdmin($reason = '', $content = '') {
//temporal function to warn myself about all the stuff happening wrong :)
}
}
And in main model I'm using:
$spreadsheet = new Google_Spreadsheet("spreadsheet name or ID", $worksheetname, "My spreadsheet name");
if(!$spreadsheet->initialized) {
Google_Spreadsheet::warnAdmin('cannot initialize spreadsheet', serialize($rowValues));
}
if(!$spreadsheet->initialized || !$spreadsheet->insertRow($rowValues, $this->default_fields)) {
Google_Spreadsheet::warnAdmin('failed to insert row ');
}
@Edit, thanks to bram brambring for his token solution, seems more easier than my. Working like a charm now, I hope his way it gonna refresh token normally. THANK YOU DUDE!
Upvotes: 0
Reputation: 838
I ran into the same issue. My app is one only I use so here's how I replaced the ClientLogin with OAuth for my own user in my own application.
I wrote a Zend client class that uses OAuth. It's linked here: https://gist.github.com/monkbroc/4251effc7912b9764ca1
The main difficulty is performing the OAuth process the first time to get a refresh token that the Zend OAuthClient will transform to an access token which can be used for requests, but expires after an hour. The Gist above lists the steps I took.
Upvotes: 1
Reputation: 117016
Zend_Gdata uses ClientLogin which was deprecated as of April 20, 2012 and turned off on April 20 2015. This code will not longer work you need to switch to using Oauth2.
Upvotes: 2