PHP and Google API (BigQuery to be Specific) [duplicate] - php

This question already has answers here:
Bigquery + PHP examples
(4 answers)
Closed 8 years ago.
I am currently trying to develop some sort of a web app and I need it to be able to execute queries on a table that has over ~50,000,000 Rows.
I thought about using Google BigQuery for this matter but I am having problems using their API.
I've searched the whole internet for the past 3 hours and I couldn't find a way to get an authentication and execute a query with PHP only. For authentication I found a way using javascript but that will not be good for me. I need it to be server sided only.
The whole php google api documention seems outdated for me.
Thanks in advanced, Sagi.

Here is a sample code that works for us:
session_start();
define('PROJECT_ID', 'edited');
define('DATASET_ID', 'edited');
define('API_KEY', 'edited');
$client_id = 'edited';
$service_account_name = 'edited';
$key_file_location = '.ssh/privatekey-bigquery.p12';
$service_token_file_location = 'bigquery_current_service_token.json';
set_include_path("google-api-php/src/" . PATH_SEPARATOR . get_include_path());
require_once 'google-api-php/src/Google/Client.php';
require_once 'google-api-php/src/Google/Service/Bigquery.php';
$client = new Google_Client();
$client->setApplicationName("Client_Library_Examples");
//$client->setDeveloperKey(API_KEY);
if (!is_file($service_token_file_location)) {
if (!is_writable($service_token_file_location)) {
#chmod($service_token_file_location, 0777);
if (!is_writable($service_token_file_location)) {
die('Service token file is not writable: ' . $service_token_file_location);
}
}
file_put_contents($service_token_file_location, '');
} else {
if (!is_writable($service_token_file_location)) {
#chmod($service_token_file_location, 0777);
if (!is_writable($service_token_file_location)) {
die('Service token file is not writable: ' . $service_token_file_location);
}
}
}
$service_token = #file_get_contents($service_token_file_location);
if (!empty($service_token)) {
$client->setAccessToken($service_token);
}
if (!file_exists($key_file_location)) {
die('Key file is missing: ' . $key_file_location);
}
$key = file_get_contents($key_file_location);
$cred = new Google_Auth_AssertionCredentials(
$service_account_name, array(
'https://www.googleapis.com/auth/bigquery',
), $key
);
$client->setAssertionCredentials($cred);
if ($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($cred);
}
$service_token = $client->getAccessToken();
file_put_contents($service_token_file_location, $service_token);
// start using $client

Related

php server google drive download file in background

I need form PHP level, in background without user interaction login on google drive and get files list. I found similar topic and code for question working, but is required handly login, where I need login from php in background.
In second post with code for possibly login witout user interaction, but I don't know where is bug.
My code PHP:
<?php
require_once 'vendor/autoload.php';
require_once 'src/Google_Client.php';
require_once 'src/contrib/Google_DriveService.php';
require_once 'src/auth/Google_AssertionCredentials.php';
$client_email = 'xxxxxx#xxxxxxxxxxxxx.xxx.gserviceaccount.com';
$private_key = file_get_contents('key.p12');
$user_to_impersonate = 'xxxxxxxxxxxxxxx#gmail.com';
$scopes = array('https://www.googleapis.com/auth/drive');
$credentials = new Google_AssertionCredentials(
$client_email,
$scopes,
$private_key,
'notasecret', // Default P12 password
'http://oauth.net/grant_type/jwt/1.0/bearer', // Default grant type
$user_to_impersonate
);
$client = new Google_Client();
$client->setAssertionCredentials($credentials);
if ($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion();
}
$service = new Google_Service_Drive($client);
$files = $service->files->listFiles();
echo "count files=".count($files)."<br>";
foreach( $files as $item ) {
echo "title=".$item['title']."<br>";
}
?>
Vendor directory I get from this instruction, and other files I get from this GitHub
I had problem with function Google_Auth_AssertionCredentials, PHP hasn't file with this function. I found that file src/auth/Google_AssertionCredentials.php has similar function Google_AssertionCredentials. I included Google_AssertionCredentials.php file and changed function name.
In finally I have new error:
PHP Fatal error: Cannot call constructor in
\google_drive\vendor\google\apiclient-services\src\Google\Service\Drive.php
on line 75
I don't know what doing again. I tried many other metod for login on google drive, eg. load file list GET method with API_KEY, or via json file.
As result I want get file list, download them. edit and upload.
Any sugestions?
EDIT:
I have part sucess. I found liblary this, and them work with this code:
<?php
function retrieveAllFiles($service) {
$result = array();
$pageToken = NULL;
do {
try {
$parameters = array();
if ($pageToken) {
$parameters['pageToken'] = $pageToken;
}
$files = $service->files->listFiles($parameters);
$result = array_merge($result, $files->getItems());
$pageToken = $files->getNextPageToken();
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
$pageToken = NULL;
}
} while ($pageToken);
return $result;
}
session_start();
require_once '/google-api-php-client/autoload.php';
$client_email = 'xxxx#xxxxx.iam.gserviceaccount.com';
$user_to_impersonate = 'xxxxxx#gmail.com';
$private_key = file_get_contents('key.p12');
$scopes = array('https://www.googleapis.com/auth/drive');
$credentials = new Google_Auth_AssertionCredentials(
$client_email,
$scopes,
$private_key,
'notasecret', // Default P12 password
'http://oauth.net/grant_type/jwt/1.0/bearer',
$user_to_impersonate
);
$client = new Google_Client();
if(isset($_SESSION['service_token'])==false && $_SESSION['service_token']=='') {
$client->setAssertionCredentials($credentials);
if ($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($credentials);
}
$_SESSION['service_token'] = $client->getAccessToken();
}
if(isset($_SESSION['service_token']) && $_SESSION['service_token']) {
$client->setAccessToken($_SESSION['service_token']);
if ($client->isAccessTokenExpired()) {
$client->refreshToken($client->getRefreshToken());
$_SESSION['service_token'] = $client->getAccessToken();
}
$service = new Google_Service_Drive($client);
print_r(retrieveAllFiles($service));
}
?>
And in result I have only one file [originalFilename] => Getting started, this is PDF, but I don't see this file on Gogle dirve. On google drive I uploaded file: README.md.
I'm not sure, but maybe this file is on ` 'xxxx#xxxxx.iam.gserviceaccount.com' and script not logged to 'xxxxxx#gmail.com'?

How to access user data with Google Webmaster Tools API

I'm just starting to use the api libraries from google and I'm having some trouble accessing to user data. For experimentation I used code from a previos question in this field.
My code executes a petition for the google search console api but it returns an empty array. I autorized the service account from the admin console (https://developers.google.com/identity/protocols/OAuth2ServiceAccount) so I don't know why doesn't it return anything.
set_include_path(get_include_path() . PATH_SEPARATOR . '$path/google-api-php-client-master/src');
require_once realpath('$path/google-api-php-client-master/src/Google/autoload.php');
$client_id = "my-client-id";
$service_account_name = "my-service-account-name#developer.gserviceaccount.com";
$key_file_location = "privatekey.p12";
$client = new Google_Client();
$client->setApplicationName("WMtools_application");
$service = new Google_Service_Webmasters($client);
if (isset($_SESSION['service_token'])) {
$client->setAccessToken($_SESSION['service_token']);
}
$key = file_get_contents($key_file_location);
$cred = new Google_Auth_AssertionCredentials(
$service_account_name,
array('https://www.googleapis.com/auth/webmasters.readonly'),
$key
);
try{
$client->setAssertionCredentials($cred);
if ($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($cred);
}
$_SESSION['service_token'] = $client->getAccessToken();
}catch(Exception $e){
echo "Exception captured", $e->getMessage(), "\n";
}
try{
$results = $service->sites->listSites();
$siteList = $results->siteEntry;
var_dump($siteList);
}catch(Exception $e2){
echo "No results", $e2->getMessage(), "\n";
}
I solved the problem. The case is that i have delegated domain-wide authority to my service account and I didn't include in my petition to the API the user email from whom I want to access the data. To solve It just need to add it to the google_Auth_AssertionCredentials this way:
$cred = new Google_Auth_AssertionCredentials(
$service_account_name,
array('https://www.googleapis.com/auth/webmasters.readonly'),
$key
);
$cred->sub = $service_account_user_email; //example#google.com

Bad Request while accesing Gmail API

I'm trying to connect to Gmail but server says:
Uncaught exception 'Google_Service_Exception' with message 'Error calling
GET https://www.googleapis.com/gmail/v1/users/{test}%40gmail.com/messages:
(400) Bad Request' in C:\...\google-api-php-client\src\Google\Http\REST.php on line 110
I can't seem to find the problem. Here's the code:
$google_accounts = $this->getGoogleAccounts();
if (count($google_accounts) > 0) {
require_once $_SERVER['DOCUMENT_ROOT'] . '/include/google-api-php-client/src/Google/autoload.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/include/google-api-php-client/src/Google/Client.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/include/google-api-php-client/src/Google/Service/Gmail.php';
$scopes = array(
'https://mail.google.com',
'https://www.googleapis.com/auth/gmail.readonly',
'https://www.googleapis.com/auth/gmail.modify',
);
$key_file_location = $_SERVER['DOCUMENT_ROOT'] . '/include/google-api-php-client/src/keys/';
foreach ($google_accounts as $one_account) {
if (!empty($one_account->client_id) && !empty($one_account->service_mail) && !empty($one_account->key_file)) {var_dump($one_account);
$key = file_get_contents($key_file_location . $one_account->key_file);
$client = new Google_Client();
$cred = new Google_Auth_AssertionCredentials($one_account->service_mail, $scopes, $key);
$client->setAssertionCredentials($cred);
$client->setClientId($one_account->client_id);
$client->setAccessType('offline_access');
$service = new Google_Service_Gmail($client);
$opt_param = array();
$messagesResponse = $service->users_messages->listUsersMessages($one_account->login, $opt_param);
var_dump($messagesResponse);
}
}
return $list;
}
else {
return false;
}
You need to add:
$cred->sub = $userEmail;
right after creating $cred where $userEmail is the email address of the user you are trying to impersonate. For reference, see the Google Drive Service Account documentation which uses a different scope and API call but is otherwise similar to what you'd want to do with Gmail API.

Bigquery API php authorization

I'm trying to get access bigquery api using PHP library, but I always have this error:
Fatal error: Uncaught exception 'Google_Service_Exception' with message 'Error calling GET https://www.googleapis.com/bigquery/v2/projects/primeval-shadow-571/datasets/Test/tables: (401) Login Required' in ...
I have a web application, that needs to get some data from table in bigquery. The Remote account is not mine, but it was created by some guy (and I don't have login and pass to log in), who gave me the .json file which included thoose parameters:
auth_uri,
client_secret,
token_uri,
client_email,
client_x509_cert_url,
client_id and
auth_provider_x509_cert_url.
Here is my php code:
<?php
require_once 'Google/Client.php';
require_once 'Google/Service/Bigquery.php';
$client = new Google_Client();
$client->setAuthConfigFile('google-config.json');
$service = new Google_Service_Bigquery($client);
$service->tables->listTables('primeval-shadow-571', 'Test');
But finally I got error that's above.
Can anybody tell me where am I wrong?
P.S. I just started work with google api two days ago, so I'm just beginning learn it.
Thanks a lot.
Here is a sample code that works for us:
session_start();
define('PROJECT_ID', 'edited');
define('DATASET_ID', 'edited');
define('API_KEY', 'edited');
$client_id = 'edited';
$service_account_name = 'edited';
$key_file_location = '.ssh/privatekey-bigquery.p12';
$service_token_file_location = 'bigquery_current_service_token.json';
set_include_path("google-api-php/src/" . PATH_SEPARATOR . get_include_path());
require_once 'google-api-php/src/Google/Client.php';
require_once 'google-api-php/src/Google/Service/Bigquery.php';
$client = new Google_Client();
$client->setApplicationName("Client_Library_Examples");
//$client->setDeveloperKey(API_KEY);
if (!is_file($service_token_file_location)) {
if (!is_writable($service_token_file_location)) {
#chmod($service_token_file_location, 0777);
if (!is_writable($service_token_file_location)) {
die('Service token file is not writable: ' . $service_token_file_location);
}
}
file_put_contents($service_token_file_location, '');
} else {
if (!is_writable($service_token_file_location)) {
#chmod($service_token_file_location, 0777);
if (!is_writable($service_token_file_location)) {
die('Service token file is not writable: ' . $service_token_file_location);
}
}
}
$service_token = #file_get_contents($service_token_file_location);
if (!empty($service_token)) {
$client->setAccessToken($service_token);
}
if (!file_exists($key_file_location)) {
die('Key file is missing: ' . $key_file_location);
}
$key = file_get_contents($key_file_location);
$cred = new Google_Auth_AssertionCredentials(
$service_account_name, array(
'https://www.googleapis.com/auth/bigquery',
), $key
);
$client->setAssertionCredentials($cred);
if ($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($cred);
}
$service_token = $client->getAccessToken();
file_put_contents($service_token_file_location, $service_token);
// start using $client

PHP Google Cloud Storage

I'm trying to use Google Cloud Storage in my PHP project - but not on the AppEngine platform. All the links and tutorials I found always use the AppEngine platform and therefor can use the gs:// links. Does anyone know how to connect and for example list objects in a bucket - or at least connect to the storage trough php without AppEngine?
try this code:
set_include_path("../src/" . PATH_SEPARATOR . get_include_path());
require_once 'Google/Client.php';
require_once("Google/Service/Storage.php");
$client_id = '<client-id>'; //Client ID
$service_account_name = '<service_account_name(email)>'; //Email Address
$key_file_location = 'key.p12'; //your key.p12 file
echo pageHeader("Service Account Access");
if ($client_id == '<YOUR_CLIENT_ID>'
|| !strlen($service_account_name)
|| !strlen($key_file_location)) {
echo missingServiceAccountDetailsWarning();
}
$client = new Google_Client();
$client->setApplicationName("<your application name>");
$service = new Google_Service_Storage($client);
if (isset($_SESSION['service_token'])) {
$client->setAccessToken($_SESSION['service_token']);
}
$key = file_get_contents($key_file_location);
$cred = new Google_Auth_AssertionCredentials(
$service_account_name,
array('https://www.googleapis.com/auth/devstorage.full_control'),
$key
);
$client->setAssertionCredentials($cred);
if($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($cred);
}
$_SESSION['service_token'] = $client->getAccessToken();
$acl = new Google_Service_Storage_ObjectAccessControl();
$acl->setEntity('allUsers');
$acl->setRole('READER');
$acl->setBucket('<your bucket name>');
$acl->setObject('your object name');
$service = new Google_Service_Storage($client);
$return_value = $service->objects->get('<bucket_name>','<object-name>');
You can use the JSON api.
To see it in action go here:
https://developers.google.com/apis-explorer/#p/storage/v1/storage.objects.list
Then enable OAuth2 in the top right and fill in your bucket name to see an example request and response.

Categories