Google BigQuery - Automating a Cron Job - php

Using PHP, I am able to run BigQuery manually but I need BigQuery to run as an automatic cron job (without Gmail login). How would I accomplish this? Thanks.

You need to create a service account in the developer console, than you will be able to use from code. Here is a code that we have in our cron files.
properly creates a Google_Client using https://github.com/google/google-api-php-client
runs a job async
displays the running job ID and status
You need to have:
service account created (something like ...#developer.gserviceaccount.com)
your key file (.p12)
service_token_file_location (writable path to store the JSON from the handshake, it will be valid for 1h)
code sample:
function getGoogleClient($data = null) {
global $service_token_file_location, $key_file_location, $service_account_name;
$client = new Google_Client();
$client->setApplicationName("Client_Library_Examples");
$old_service_token = null;
$service_token = #file_get_contents($service_token_file_location);
$client->setAccessToken($service_token);
$key = file_get_contents($key_file_location);
$cred = new Google_Auth_AssertionCredentials(
$service_account_name, array(
'https://www.googleapis.com/auth/bigquery',
'https://www.googleapis.com/auth/devstorage.full_control'
), $key
);
$client->setAssertionCredentials($cred);
if ($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($cred);
$service_token = $client->getAccessToken();
}
return $client;
}
$client = getGoogleClient();
$bq = new Google_Service_Bigquery($client);
/**
* #see https://developers.google.com/bigquery/docs/reference/v2/jobs#resource
*/
$job = new Google_Service_Bigquery_Job();
$config = new Google_Service_Bigquery_JobConfiguration();
$config->setDryRun(false);
$queryConfig = new Google_Service_Bigquery_JobConfigurationQuery();
$config->setQuery($queryConfig);
$job->setConfiguration($config);
$destinationTable = new Google_Service_Bigquery_TableReference();
$destinationTable->setDatasetId(DATASET_ID);
$destinationTable->setProjectId(PROJECT_ID);
$destinationTable->setTableId('table1');
$queryConfig->setDestinationTable($destinationTable);
$sql = "select * from publicdata:samples.github_timeline limit 10";
$queryConfig->setQuery($sql);
try {
// print_r($job);
// exit;
$job = $bq->jobs->insert(PROJECT_ID, $job);
$status = new Google_Service_Bigquery_JobStatus();
$status = $job->getStatus();
// print_r($status);
if ($status->count() != 0) {
$err_res = $status->getErrorResult();
die($err_res->getMessage());
}
} catch (Google_Service_Exception $e) {
echo $e->getMessage();
exit;
}
//print_r($job);
$jr = $job->getJobReference();
//var_dump($jr);
$jobId = $jr['jobId'];
if ($status)
$state = $status['state'];
echo 'JOBID:' . $jobId . " ";
echo 'STATUS:' . $state;
You can grab the results with:
$res = $bq->jobs->getQueryResults(PROJECT_ID, $_GET['jobId'], array('timeoutMs' => 1000));
if (!$res->jobComplete) {
echo "Job not yet complete";
exit;
}
echo "<p>Total rows: " . $res->totalRows . "</p>\r\n";
//see the results made it as an object ok
//print_r($res);
$rows = $res->getRows();
$r = new Google_Service_Bigquery_TableRow();
$a = array();
foreach ($rows as $r) {
$r = $r->getF();
$temp = array();
foreach ($r as $v) {
$temp[] = $v->v;
}
$a[] = $temp;
}
print_r($a);
You can see here the classes that you can use for your other BigQuery calls. When you read the file, please know that file is being generated from other sources, hence it looks strange for PHP, and you need to learn reading it in order to be able to use the methods from it.
https://github.com/google/google-api-php-client/blob/master/src/Google/Service/Bigquery.php
like:
Google_Service_Bigquery_TableRow
Also check out the questions tagged with [php] and [google-bigquery]
https://stackoverflow.com/questions/tagged/google-bigquery+php

Related

square payment form php check customer exists in directory and make payment

Am new to Square Payment Form using PHP and trying to do following steps
Check If customer Exists in Directory
If Customer Does not exist - create new customer and collect CUSTOMER_ID
MAKE PAYMENT & get Payment ID
Couple of time this script worked by started getting Maximum execution time of 30 seconds exceeded AND created multiple customer entries in directory and payment failed
PS : am using GOTO to loop and ENV file for credentials
Any help will be appreciated in advance
print_r($_POST);
$booknow = $_POST;
require 'vendor/autoload.php';
use Dotenv\Dotenv;
use Square\Models\Money;
use Square\Models\CreatePaymentRequest;
use Square\Exceptions\ApiException;
use Square\SquareClient;
use Square\Environment;
use SquareConnect\ApiClient;
use Square\Models\CreateCustomerRequest;
$idem = UUID::v4();
$sname = explode(' ', $_POST["cname"]);
$sname0 = $sname[0];
$sname1 = $sname[1];
$cphone = $_POST["cphone"];
//$cphone = '9848848450';
$cemailid = $_POST["cemailid"];
$ifare = ($_POST["ifare"] * 100);
$xnote = $_POST["note"];
//echo '<br><br>fare : ' . $ifare . '<br><br>';
$dotenv = Dotenv::create(__DIR__);
$dotenv->load();
$upper_case_environment = strtoupper(getenv('ENVIRONMENT'));
$access_token = getenv($upper_case_environment.'_ACCESS_TOKEN');
//print_r($access_token);
//echo '<br><br><br>';
$client = new SquareClient([
'accessToken' => $access_token,
'environment' => getenv('ENVIRONMENT')
]);
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
error_log('Received a non-POST request');
echo 'Request not allowed';
http_response_code(405);
return;
}
$nonce = $_POST['nonce'];
if (is_null($nonce)) {
echo 'Invalid card data';
http_response_code(422);
return;
}
searchCustomers: ///search customers
$phone_number = new \Square\Models\CustomerTextFilter();
$phone_number->setFuzzy($cphone);
$filter = new \Square\Models\CustomerFilter();
$filter->setPhoneNumber($phone_number);
$query = new \Square\Models\CustomerQuery();
$query->setFilter($filter);
$body = new \Square\Models\SearchCustomersRequest();
$body->setQuery($query);
$api_response = $client->getCustomersApi()->searchCustomers($body);
if ($api_response->isSuccess()) {
$rmn = $api_response->getBody();
$stx = json_decode($rmn,true);
echo '<br><br>';
echo '# of arrays : ' . count($stx);
if(count($stx) != 0){
//echo '<br><br>';
$cust_id = $stx["customers"][0]["id"];
//echo "Customer ID : " . $cust_id;
goto makePayment;
//goto end;
} else {
//echo 'user do not exists';
/// new customer - start
$body1 = new \Square\Models\CreateCustomerRequest();
$body1->setIdempotencyKey($idem);
$body1->setGivenName($sname0);
$body1->setFamilyName($sname1);
$body1->setEmailAddress($cemailid);
$body1->setPhoneNumber($cphone);
$api_response = $client->getCustomersApi()->createCustomer($body1);
if ($api_response->isSuccess()) {
$result = $api_response->getResult();
goto searchCustomers;
} else {
$errors = $api_response->getErrors();
}
/// new customer - end
}
} else {
echo '<br><br>sorry not found!<bR><br>';
}
goto end;
makePayment:
$amount_money = new \Square\Models\Money();
$amount_money->setAmount($ifare);
$amount_money->setCurrency('USD');
$body = new \Square\Models\CreatePaymentRequest(
'cnon:card-nonce-ok',
$idem,
$amount_money
);
$body->setCustomerId($cust_id);
$body->setNote($xnote);
$api_response = $client->getPaymentsApi()->createPayment($body);
if ($api_response->isSuccess()) {
$result = $api_response->getResult();
$srt = json_encode($result);
echo '<br><br>';
echo "PAYEMNT SUCCESSUFLL <BR><br><br>";
//print_r($srt);
goto end;
} else {
$errors = $api_response->getErrors();
echo 'payment FAILEDDDDDDDDDD';
}
goto end;
end:

Calendar Event not Insert

I have to work on google Calendar Insert API Without Login ...When I run this function that time did not event create On my account but it's function return "SUCCESS"
Also it Authentication is good. If you know please find a solution for that Question..thanks
XAMPP Localhost
require_once ('C:/xampp/htdocs/java_google/google-api-
php/src/Google/autoload.php');
$client_id = 'XXXXX'; //Client ID
$service_account_name = 'XXXXXX'; //Email Address
$key_file_location = 'C:/xampp/htdocs/java_google/java-new-257718-
70d76ac18661.p12'; //key.p12
$client = new Google_Client(); //AUTHORIZE OBJECTS
$client->setApplicationName("Java New");
//INSTATIATE NEEDED OBJECTS (In this case, for freeBusy query, and Create
New Event)
$service = new Google_Service_Calendar($client);
$id = new Google_Service_Calendar_FreeBusyRequestItem($client);
$item = new Google_Service_Calendar_FreeBusyRequest($client);
$event = new Google_Service_Calendar_Event($client);
$startT = new Google_Service_Calendar_EventDateTime($client);
$endT = new Google_Service_Calendar_EventDateTime($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/calendar'),
$key
);
$client->setAssertionCredentials($cred);
if ($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($cred);
}
$_SESSION['service_token'] = $client->getAccessToken();
global $service;
global $event;
global $startT;
global $endT;
$calendarId = 'primary';
$summary = 'primary test test';
$location = 'chennai';
$description = 'chennai123';
$date = '2019-11-04T13:22:07+01:00';
$start = '2019-11-04T13:22:07+01:00';
$end = '2019-11-04T13:22:08+01:00';
$startT->setTimeZone("Europe/Rome");
$startT->setDateTime($date);
$endT->setTimeZone("Europe/Rome");
$endT->setDateTime($end);
$event->setSummary($summary);
$event->setLocation($location);
$event->setDescription($description);
$event->setStart($startT);
$event->setEnd($startT);
$insert = $service->events->insert($calendarId, $event);
if($insert) {
echo 'sucess';
return true;
}
Please Add Below Line On your Code
$scope = new Google_Service_Calendar_AclRuleScope($client);
$rule = new Google_Service_Calendar_AclRule($client);
$scope->setType('user');
$scope->setValue( 'your Email' );
$rule->setRole( 'owner' );
$rule->setScope( $scope );
$result = $service->acl->insert('primary', $rule);

PHP create User in moodle via Webservice

I want so connect an external website with a moodle-system. I've already set up the webService and created a token to get access.
I've followed http://www.rumours.co.nz/manuals/using_moodle_web_services.htm set up but in contrast i wanted to realise the connection via REST as in https://github.com/moodlehq/sample-ws-clients/find/master
My approach is to have a moodle class which will handle the data exchange. In first place i just wanted to try to create some new hard coded Users via the webService but it fails with the Moodle-Response:
"invalidrecord Can not find data record in database table external_functions. "
Which seems to me as if i the call was successfully but moodle has a problem to find the "core_user_create_users" function. I've checked the local moodle Database and in the table external_functions is an entry for "core_user_create_users" so i'm kind of confused where moodle doesn't know what to do.
Thats my class:
require_once (DOCUMENT_ROOT.'/tcm/api/moodle/curl.php');
class Moodle {
private $token;
private $domainName; // 'local.moodle.dev';
private $serverUrl;
public function __construct($token, $domainName) {
$this->token = $token;
$this->domainName = $domainName;
$this->serverUrl = $this->domainName . '/webservice/rest/server.php' . '?wstoken=' . $this->token;
echo "initialize Service: $this->serverUrl </br>";
}
public function createUser() {
$functionName = 'core_user_create_users';
/// PARAMETERS - NEED TO BE CHANGED IF YOU CALL A DIFFERENT FUNCTION
$user1 = new stdClass();
$user1->username = 'testusername1';
$user1->password = 'testpassword1';
$user1->firstname = 'testfirstname1';
$user1->lastname = 'testlastname1';
$user1->email = 'testemail1#moodle.com';
$user1->auth = 'manual';
$user1->idnumber = 'testidnumber1';
$user1->lang = 'en';
$user1->theme = 'standard';
$user1->timezone = '-12.5';
$user1->mailformat = 0;
$user1->description = 'Hello World!';
$user1->city = 'testcity1';
$user1->country = 'au';
$preferencename1 = 'preference1';
$preferencename2 = 'preference2';
$user1->preferences = array(
array('type' => $preferencename1, 'value' => 'preferencevalue1'),
array('type' => $preferencename2, 'value' => 'preferencevalue2'));
$user2 = new stdClass();
$user2->username = 'testusername2';
$user2->password = 'testpassword2';
$user2->firstname = 'testfirstname2';
$user2->lastname = 'testlastname2';
$user2->email = 'testemail2#moodle.com';
$user2->timezone = 'Pacific/Port_Moresby';
$users = array($user1, $user2);
$params = array('users' => $users);
/// REST CALL
$serverurl = $this->serverUrl . '&wsfunction=' . $functionName;
require_once (DOCUMENT_ROOT.'/tcm/api/moodle/curl.php');
$curl = new curl;
//if rest format == 'xml', then we do not add the param for backward compatibility with Moodle < 2.2
$restformat = "json";
$resp = $curl->post($serverurl . $restformat, $params);
//print_r($resp);
echo '</br>*************Server Response*************</br>';
var_dump($resp);
}
}
I'm using the curl class from the same github-project which i posted above - moodle is linkng to it in their Documentation..
docs.moodle.org/dev/Creating_a_web_service_client
The entry point of my call is hardcoded right now:
<?php
include_once (DOCUMENT_ROOT.'/tcm/api/moodle/moodle.php');
//entry point of code
if (isset($_POST)){
//token and domain would be in $_POST
$bla = new Moodle('0b5a1e98061c5f7fb70fc3b42af6bfc4', 'local.moodle.dev');
$bla->createUser();
}
Does anyone know how to solve the "invalidrecord Can not find data record in database table external_functions" error or has a different approach/suggestion how i can create my users remotely??
Thanks in advance
I got it finally working with the following code:
class Moodle {
private $token; //'0b5a1e98061c5f7fb70fc3b42af6bfc4';
private $domainName; // 'http://local.moodle.dev';
private $serverUrl;
public $error;
public function __construct($token, $domainName) {
$this->token = $token;
$this->domainName = $domainName;
$this->serverUrl = $this->domainName . '/webservice/rest/server.php' . '?wstoken=' . $this->token;
echo "initialize Service: $this->serverUrl </br>";
}
public function createUser() {
$functionName = 'core_user_create_users';
$user1 = new stdClass();
$user1->username = 'testusername1';
$user1->password = 'Uk3#0d5w';
$user1->firstname = 'testfirstname1';
$user1->lastname = 'testlastname1';
$user1->email = 'testemail1#moodle.com';
$user1->auth = 'manual';
$user1->idnumber = '';
$user1->lang = 'en';
$user1->timezone = 'Australia/Sydney';
$user1->mailformat = 0;
$user1->description = '';
$user1->city = '';
$user1->country = 'AU'; //list of abrevations is in yourmoodle/lang/en/countries
$preferencename1 = 'auth_forcepasswordchange';
$user1->preferences = array(
array('type' => $preferencename1, 'value' => 'true')
);
$users = array($user1);
$params = array('users' => $users);
/// REST CALL
$restformat = "json";
$serverurl = $this->serverUrl . '&wsfunction=' . $functionName. '&moodlewsrestformat=' . $restformat;
require_once (DOCUMENT_ROOT . '/tcm/api/moodle/curl.php');
$curl = new curl();
$resp = $curl->post($serverurl, $params);
echo '</br>************************** Server Response createUser()**************************</br></br>';
echo $serverurl . '</br></br>';
var_dump($resp);
}
}
Info:
For all moodle beginners.. Activating the moodle Debug messages helps a bit. You'll receive an additional error information in the response returned form the server.
Moodle -> Site Administration -> Development -> Debugging -> Debug Messages
Select: DEVELOPER:extra Moodle debug messages for developers

BigQuery example for current Google API in PHP

All the question about examples are like 2 years old, and I can't find ANY working example for current API client version (https://github.com/google/google-api-php-client). Every single one is missing something or throwing exception....
Could anybody provide working example? There is no documentation AT ALL, anywhere.
This is the most working one:
<?php
require_once 'inc/google-api/autoload.php'; // or wherever autoload.php is located
$client = new Google_Client();
$client->setApplicationName("whatever");
$client->setDeveloperKey("some key");
$service = new Google_Service_Bigquery($client);
$postBody = "[
'datasetReference' => [
'datasetId' => $datasetId,
'projectId' => $projectId,
],
'friendlyName' => $name,
'description' => $description,
'access' => [
['role' => 'READER', 'specialGroup' => 'projectReaders'],
['role' => 'WRITER', 'specialGroup' => 'projectWriters'],
['role' => 'OWNER', 'specialGroup' => 'projectOwners'],
],
]";
$dataset = $service->datasets->insert($projectId, new Google_Dataset($postBody));
$postBody = "[
'tableReference' => [
'projectId' => 'test_project_id',
'datasetId' => 'test_data_set',
'tableId' => 'test_data_table'
]
]";
$table = $service->tables->insert($projectId, $datasetId, new Google_Table($postBody));
?>
But I am getting Fatal errors about Google_Dataset and Google_Table not defined...
Here is a code that
properly creates a Google_Client
runs a job async
displays the running job ID and status
You need to have:
service account created (something like ...#developer.gserviceaccount.com)
your key file (.p12)
service_token_file_location (writable path to store the JSON from the handshake, it will be valid for 1h)
code sample:
function getGoogleClient($data = null) {
global $service_token_file_location, $key_file_location, $service_account_name;
$client = new Google_Client();
$client->setApplicationName("Client_Library_Examples");
$old_service_token = null;
$service_token = #file_get_contents($service_token_file_location);
$client->setAccessToken($service_token);
$key = file_get_contents($key_file_location);
$cred = new Google_Auth_AssertionCredentials(
$service_account_name, array(
'https://www.googleapis.com/auth/bigquery',
'https://www.googleapis.com/auth/devstorage.full_control'
), $key
);
$client->setAssertionCredentials($cred);
if ($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($cred);
$service_token = $client->getAccessToken();
}
return $client;
}
$client = getGoogleClient();
$bq = new Google_Service_Bigquery($client);
/**
* #see https://developers.google.com/bigquery/docs/reference/v2/jobs#resource
*/
$job = new Google_Service_Bigquery_Job();
$config = new Google_Service_Bigquery_JobConfiguration();
$config->setDryRun(false);
$queryConfig = new Google_Service_Bigquery_JobConfigurationQuery();
$config->setQuery($queryConfig);
$job->setConfiguration($config);
$destinationTable = new Google_Service_Bigquery_TableReference();
$destinationTable->setDatasetId(DATASET_ID);
$destinationTable->setProjectId(PROJECT_ID);
$destinationTable->setTableId('table1');
$queryConfig->setDestinationTable($destinationTable);
$sql = "select * from publicdata:samples.github_timeline limit 10";
$queryConfig->setQuery($sql);
try {
// print_r($job);
// exit;
$job = $bq->jobs->insert(PROJECT_ID, $job);
$status = new Google_Service_Bigquery_JobStatus();
$status = $job->getStatus();
// print_r($status);
if ($status->count() != 0) {
$err_res = $status->getErrorResult();
die($err_res->getMessage());
}
} catch (Google_Service_Exception $e) {
echo $e->getMessage();
exit;
}
//print_r($job);
$jr = $job->getJobReference();
//var_dump($jr);
$jobId = $jr['jobId'];
if ($status)
$state = $status['state'];
echo 'JOBID:' . $jobId . " ";
echo 'STATUS:' . $state;
You can grab the results with:
$res = $bq->jobs->getQueryResults(PROJECT_ID, $_GET['jobId'], array('timeoutMs' => 1000));
if (!$res->jobComplete) {
echo "Job not yet complete";
exit;
}
echo "<p>Total rows: " . $res->totalRows . "</p>\r\n";
//see the results made it as an object ok
//print_r($res);
$rows = $res->getRows();
$r = new Google_Service_Bigquery_TableRow();
$a = array();
foreach ($rows as $r) {
$r = $r->getF();
$temp = array();
foreach ($r as $v) {
$temp[] = $v->v;
}
$a[] = $temp;
}
print_r($a);
You can see here the classes that you can use for your other BigQuery calls. When you read the file, please know that file is being generated from other sources, hence it looks strange for PHP, and you need to learn reading it in order to be able to use the methods from it.
https://github.com/google/google-api-php-client/blob/master/src/Google/Service/Bigquery.php
like:
Google_Service_Bigquery_TableRow

Google Drive API - Call to a member function on a non-object when trying to update a file

I am trying to access and update a file in my Google Drive with PHP. Everything goes fine until I try to call $file_to_update->setTitle("NEW TITLE").
I can download the file's metadata, but I can't update anything.
require_once 'google-api-php-client/Google_Client.php';
require_once 'google-api-php-client/contrib/Google_DriveService.php';
$client = new Google_Client();
// Get your credentials from the console
$client->setClientId('');
$client->setClientSecret('');
$client->setRedirectUri('');
$client->setScopes(array(''));
$service = new Google_DriveService($client);
$authUrl = $client->createAuthUrl();
//Request authorization
print "Please visit:\n$authUrl\n\n";
print "Please enter the auth code:\n";
$authCode = trim(fgets(STDIN));
// Exchange authorization code for access token
$accessToken = $client->authenticate($authCode);
$client->setAccessToken($accessToken);
retrieveAllFiles($service);
function retrieveAllFiles($service) {
$result = array();
$pageToken = NULL;
do {
try {
$parameters = array();
if ($pageToken) {
$parameters['pageToken'] = $pageToken;
}
$files = $service->files->listFiles($parameters);
$fileIDs = array();
$file = ($files[items]);
foreach($file as $f){
array_push($fileIDs, $f["id"]);
print $f["id"]."\n";
}
$str = $fileIDs[1];
$file_to_update = $service->files->get($str);
$file_to_update->setTitle("NEW TITLE");
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
$pageToken = NULL;
}
} while ($pageToken);
return $result;
}
Your call to $service->files->get($str) is not returning object.
if you check at function:
public function get($fileId, $optParams = array()) {
$params = array('fileId' => $fileId);
$params = array_merge($params, $optParams);
$data = $this->__call('get', array($params));
if ($this->useObjects()) {
return new Google_DriveFile($data);
} else {
return $data;
}
}
It checks if you want to work with objects, or not:
$this->useObjects()
You need to configure 'use_objects' to 'true' in your api config.php file, it is set to 'false' by default.
'use_objects' => false,

Categories