Home » Php » php – zend gdata and google spreadsheet not connecting

php – zend gdata and google spreadsheet not connecting

Posted by: admin July 12, 2020 Leave a comment

Questions:

ive been using Zend Gdata for a while now, and today im getting an error of

Notice: Undefined offset: ClientLogin.php on line 150

via php, this has been working for a while now, and today without changing anything it stopped working, im guessing some deprecated service on behalf of google with the zend gdata maybe the Zend_Gdata_ClientLogin::getHttpClient( ) method or something, can any one confirm or help me with this issue. the code im using to connect is as follows:

    require_once('Zend/Loader.php');
Zend_Loader::loadClass('Zend_Gdata');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
Zend_Loader::loadClass('Zend_Gdata_Docs');
Zend_Loader::loadClass('Zend_Gdata_Spreadsheets');
require_once 'Zend/Gdata.php';
require_once 'Zend/Gdata/AuthSub.php';
require_once 'Zend/Gdata/Spreadsheets.php';
require_once 'Zend/Gdata/Spreadsheets/DocumentQuery.php';
require_once 'Zend/Gdata/Spreadsheets/ListQuery.php';
require_once 'Zend/Loader.php';


$sourceUser = "myemail";
$sourcePass = "mysuperawesomepassword";
$service = Zend_Gdata_Spreadsheets::AUTH_SERVICE_NAME;
$sourceClient = Zend_Gdata_ClientLogin::getHttpClient($sourceUser, $sourcePass, $service);
$connection = new Zend_Gdata_Spreadsheets($sourceClient);

i am using the zend gdata with the google spreadsheets

also the error points specifically to this line

$sourceClient = Zend_Gdata_ClientLogin::getHttpClient($sourceUser, $sourcePass, $service);

as i said, i was using this for a while now, and nothing has changed on my end

How to&Answers:

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 = '[email protected]om';
        $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!

Answer:

I uses ClientLogin for a server to server application.

needed to switch to oAuth2 in a hurry today. I merged some examples I found to get the authorisation token using a ‘Service account’

function get_token() {
$client_email = '0-1.apps.googleusercontent.com';
$client_email = '[email protected]';
$private_key = file_get_contents('abc.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;
}

I needed to use the developer email not the app email, same email must be added as a user to the spreadsheet

the generated token can then be used with php-google-spreadsheet-client

$accessToken = get_token();

$serviceRequest = new DefaultServiceRequest($accessToken);
ServiceRequestFactory::setInstance($serviceRequest);

$spreadsheetService = new Google\Spreadsheet\SpreadsheetService();
$spreadsheetFeed = $spreadsheetService->getSpreadsheets();

$spreadsheet = $spreadsheetFeed->getByTitle('Hello World');

Answer:

Been stuck with this issue aswell, seems like google’s ClientLogin was finally removed

Important: Do not use ClientLogin for new applications. Instead, use
the more secure OAuth authentication protocol. ClientLogin is a
deprecated authentication protocol and is being turned down on April
20, 2015. At that time, ClientLogin requests will no longer be
answered. If you have existing applications that use ClientLogin, we
encourage you to migrate to OAuth. The ClientLogin support in this
library will be removed in the next major release.

Going to try remake my spreadsheets with OAuth now, this may be the solution: removed cuz no more reputation, will post link into commets

edit; having some troubles with magnetikonline, so gonna try this solution: removed cuz no more reputation, will post link into comments

edit2; /’\ this solution is much better, I must go now, but I’ve got some success with this library, it works much better as far as I see and provide more functionality, try it.

For your problem with token, try https://github.com/asimlqt/php-google-oauth . THis way also worked for me and its much easier, I reveived array with my token info(if u gonna try that token with second library, ur token gonna be array, while u need only $accessToken[‘access_token’] part in order to make $serviceRequest = new DefaultServiceRequest($accessToken);

Another big tutorial I found: http://konstantinshkut.com/blog/2014/11/01/how_to_get_data_from_google_spreadsheet_in_yii_php_application (thats for second solution, asimlqt/php-google-spreadsheet-client), step 6 helps a lot to understand how my file must be looking.

Answer:

I also have had php scripts using Zend for Google Spreadsheets. They have been running great for years, but stopped working today at noon for no reason. What has changed on Google’s side and how to easily fix it?

Answer:

That deprecated ClientLogin, it works again!
It was such a surprise on the eve of the conference Google I / O?
I had to write a self-made solution. Third-party libraries were in basically unusable,
I wrote about 10 methods, I think it is better than the alternatives, which are too complex and cumbersome. You can buy from me))
Not yet ready to put on github)